if_mib_impl.c
Go to the documentation of this file.
1 /**
2  * @file if_mib_impl.c
3  * @brief Interfaces Group MIB module implementation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SNMP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "mibs/mib_common.h"
37 #include "mibs/if_mib_module.h"
38 #include "mibs/if_mib_impl.h"
39 #include "core/crypto.h"
40 #include "encoding/asn1.h"
41 #include "encoding/oid.h"
42 #include "debug.h"
43 
44 //Check TCP/IP stack configuration
45 #if (IF_MIB_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief Interfaces Group MIB module initialization
50  * @return Error code
51  **/
52 
54 {
55  uint_t i;
56 
57  //Debug message
58  TRACE_INFO("Initializing IF-MIB base...\r\n");
59 
60  //Clear Interfaces Group MIB base
61  osMemset(&ifMibBase, 0, sizeof(ifMibBase));
62 
63  //ifNumber object
65 
66  //Extension to the interface table
67  for(i = 0; i < NET_INTERFACE_COUNT; i++)
68  {
69  //ifLinkUpDownTrapEnable object
71  //ifPromiscuousMode object
73  //ifConnectorPresent object
75  }
76 
77  //Successful processing
78  return NO_ERROR;
79 }
80 
81 
82 /**
83  * @brief Set ifEntry object value
84  * @param[in] object Pointer to the MIB object descriptor
85  * @param[in] oid Object identifier (object name and instance identifier)
86  * @param[in] oidLen Length of the OID, in bytes
87  * @param[in] value Object value
88  * @param[in] valueLen Length of the object value, in bytes
89  * @param[in] commit This flag tells whether the changes shall be committed
90  * to the MIB base
91  * @return Error code
92  **/
93 
94 error_t ifMibSetIfEntry(const MibObject *object, const uint8_t *oid,
95  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
96 {
97  //Not implemented
98  return ERROR_WRITE_FAILED;
99 }
100 
101 
102 /**
103  * @brief Get ifEntry object value
104  * @param[in] object Pointer to the MIB object descriptor
105  * @param[in] oid Object identifier (object name and instance identifier)
106  * @param[in] oidLen Length of the OID, in bytes
107  * @param[out] value Object value
108  * @param[in,out] valueLen Length of the object value, in bytes
109  * @return Error code
110  **/
111 
112 error_t ifMibGetIfEntry(const MibObject *object, const uint8_t *oid,
113  size_t oidLen, MibVariant *value, size_t *valueLen)
114 {
115  error_t error;
116  size_t n;
117  uint_t index;
118  IfMibIfEntry *entry;
119  NetInterface *interface;
120  NetInterface *physicalInterface;
121 
122  //Point to the instance identifier
123  n = object->oidLen;
124 
125  //ifIndex is used as instance identifier
126  error = mibDecodeIndex(oid, oidLen, &n, &index);
127  //Invalid instance identifier?
128  if(error)
129  return error;
130 
131  //Sanity check
132  if(n != oidLen)
134 
135  //Check index range
136  if(index < 1 || index > NET_INTERFACE_COUNT)
138 
139  //Point to the underlying interface
140  interface = &netInterface[index - 1];
141  //Point to the interface table entry
142  entry = &ifMibBase.ifTable[index - 1];
143 
144  //Point to the physical interface
145  physicalInterface = nicGetPhysicalInterface(interface);
146 
147  //ifIndex object?
148  if(!osStrcmp(object->name, "ifIndex"))
149  {
150  //Get object value
151  value->integer = index;
152  }
153  //ifDescr object?
154  else if(!osStrcmp(object->name, "ifDescr"))
155  {
156  //Retrieve the length of the interface name
157  n = osStrlen(interface->name);
158 
159  //Make sure the buffer is large enough to hold the entire object
160  if(*valueLen >= n)
161  {
162  //Copy object value
163  osMemcpy(value->octetString, interface->name, n);
164  //Return object length
165  *valueLen = n;
166  }
167  else
168  {
169  //Report an error
170  error = ERROR_BUFFER_OVERFLOW;
171  }
172  }
173  //ifType object?
174  else if(!osStrcmp(object->name, "ifType"))
175  {
176 #if (ETH_VLAN_SUPPORT == ENABLED)
177  //VLAN interface?
178  if(interface->vlanId != 0)
179  {
180  //Layer 2 virtual LAN using 802.1Q
181  value->integer = IF_MIB_IF_TYPE_L2_VLAN;
182  }
183  else
184 #endif
185  {
186  //Sanity check
187  if(physicalInterface->nicDriver != NULL)
188  {
189  //Get interface type
190  switch(physicalInterface->nicDriver->type)
191  {
192  //Ethernet interface
193  case NIC_TYPE_ETHERNET:
195  break;
196  //PPP interface
197  case NIC_TYPE_PPP:
198  value->integer = IF_MIB_IF_TYPE_PPP;
199  break;
200  //IEEE 802.15.4 WPAN interface
201  case NIC_TYPE_6LOWPAN:
203  break;
204  //Unknown interface type
205  default:
206  value->integer = IF_MIB_IF_TYPE_OTHER;
207  break;
208  }
209  }
210  else
211  {
212  //Unknown interface type
213  value->integer = IF_MIB_IF_TYPE_OTHER;
214  }
215  }
216  }
217  //ifMtu object?
218  else if(!osStrcmp(object->name, "ifMtu"))
219  {
220  //Get interface MTU
221  if(physicalInterface->nicDriver != NULL)
222  {
223  value->integer = physicalInterface->nicDriver->mtu;
224  }
225  else
226  {
227  value->integer = 0;
228  }
229  }
230  //ifSpeed object?
231  else if(!osStrcmp(object->name, "ifSpeed"))
232  {
233  //Get interface's current bandwidth
234  value->gauge32 = interface->linkSpeed;
235  }
236 #if (ETH_SUPPORT == ENABLED)
237  //ifPhysAddress object?
238  else if(!osStrcmp(object->name, "ifPhysAddress"))
239  {
240  NetInterface *logicalInterface;
241 
242  //Point to the logical interface
243  logicalInterface = nicGetLogicalInterface(interface);
244 
245  //Make sure the buffer is large enough to hold the entire object
246  if(*valueLen >= sizeof(MacAddr))
247  {
248  //Copy object value
249  macCopyAddr(value->octetString, &logicalInterface->macAddr);
250  //Return object length
251  *valueLen = sizeof(MacAddr);
252  }
253  else
254  {
255  //Report an error
256  error = ERROR_BUFFER_OVERFLOW;
257  }
258  }
259 #endif
260  //ifAdminStatus object?
261  else if(!osStrcmp(object->name, "ifAdminStatus"))
262  {
263  //Check whether the interface is enabled for operation
264  if(physicalInterface->nicDriver != NULL)
265  {
266  value->integer = IF_MIB_IF_ADMIN_STATUS_UP;
267  }
268  else
269  {
271  }
272  }
273  //ifOperStatus object?
274  else if(!osStrcmp(object->name, "ifOperStatus"))
275  {
276  //Get the current operational state of the interface
277  if(interface->linkState)
278  {
279  value->integer = IF_MIB_IF_OPER_STATUS_UP;
280  }
281  else
282  {
284  }
285  }
286  //ifLastChange object?
287  else if(!osStrcmp(object->name, "ifLastChange"))
288  {
289  //Get object value
290  value->timeTicks = entry->ifLastChange;
291  }
292  //ifInOctets object?
293  else if(!osStrcmp(object->name, "ifInOctets"))
294  {
295  //Get object value
296  value->counter32 = entry->ifInOctets;
297  }
298  //ifInUcastPkts object?
299  else if(!osStrcmp(object->name, "ifInUcastPkts"))
300  {
301  //Get object value
302  value->counter32 = entry->ifInUcastPkts;
303  }
304  //ifInDiscards object?
305  else if(!osStrcmp(object->name, "ifInDiscards"))
306  {
307  //Get object value
308  value->counter32 = entry->ifInDiscards;
309  }
310  //ifInErrors object?
311  else if(!osStrcmp(object->name, "ifInErrors"))
312  {
313  //Get object value
314  value->counter32 = entry->ifInErrors;
315  }
316  //ifInUnknownProtos object?
317  else if(!osStrcmp(object->name, "ifInUnknownProtos"))
318  {
319  //Get object value
320  value->counter32 = entry->ifInUnknownProtos;
321  }
322  //ifOutOctets object?
323  else if(!osStrcmp(object->name, "ifOutOctets"))
324  {
325  //Get object value
326  value->counter32 = entry->ifOutOctets;
327  }
328  //ifOutUcastPkts object?
329  else if(!osStrcmp(object->name, "ifOutUcastPkts"))
330  {
331  //Get object value
332  value->counter32 = entry->ifOutUcastPkts;
333  }
334  //ifOutDiscards object?
335  else if(!osStrcmp(object->name, "ifOutDiscards"))
336  {
337  //Get object value
338  value->counter32 = entry->ifOutDiscards;
339  }
340  //ifOutErrors object?
341  else if(!osStrcmp(object->name, "ifOutErrors"))
342  {
343  //Get object value
344  value->counter32 = entry->ifOutErrors;
345  }
346  //Unknown object?
347  else
348  {
349  //The specified object does not exist
350  error = ERROR_OBJECT_NOT_FOUND;
351  }
352 
353  //Return status code
354  return error;
355 }
356 
357 
358 /**
359  * @brief Get next ifEntry object
360  * @param[in] object Pointer to the MIB object descriptor
361  * @param[in] oid Object identifier
362  * @param[in] oidLen Length of the OID, in bytes
363  * @param[out] nextOid OID of the next object in the MIB
364  * @param[out] nextOidLen Length of the next object identifier, in bytes
365  * @return Error code
366  **/
367 
368 error_t ifMibGetNextIfEntry(const MibObject *object, const uint8_t *oid,
369  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
370 {
371  error_t error;
372  size_t n;
373  uint_t index;
374 
375  //Make sure the buffer is large enough to hold the OID prefix
376  if(*nextOidLen < object->oidLen)
377  return ERROR_BUFFER_OVERFLOW;
378 
379  //Copy OID prefix
380  osMemcpy(nextOid, object->oid, object->oidLen);
381 
382  //Loop through network interfaces
383  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
384  {
385  //Append the instance identifier to the OID prefix
386  n = object->oidLen;
387 
388  //ifIndex is used as instance identifier
389  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
390  //Any error to report?
391  if(error)
392  return error;
393 
394  //Check whether the resulting object identifier lexicographically
395  //follows the specified OID
396  if(oidComp(nextOid, n, oid, oidLen) > 0)
397  {
398  //Save the length of the resulting object identifier
399  *nextOidLen = n;
400  //Next object found
401  return NO_ERROR;
402  }
403  }
404 
405  //The specified OID does not lexicographically precede the name
406  //of some object
407  return ERROR_OBJECT_NOT_FOUND;
408 }
409 
410 
411 /**
412  * @brief Set ifXEntry object value
413  * @param[in] object Pointer to the MIB object descriptor
414  * @param[in] oid Object identifier (object name and instance identifier)
415  * @param[in] oidLen Length of the OID, in bytes
416  * @param[in] value Object value
417  * @param[in] valueLen Length of the object value, in bytes
418  * @param[in] commit This flag tells whether the changes shall be committed
419  * to the MIB base
420  * @return Error code
421  **/
422 
423 error_t ifMibSetIfXEntry(const MibObject *object, const uint8_t *oid,
424  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
425 {
426  //Not implemented
427  return ERROR_WRITE_FAILED;
428 }
429 
430 
431 /**
432  * @brief Get ifXEntry object value
433  * @param[in] object Pointer to the MIB object descriptor
434  * @param[in] oid Object identifier (object name and instance identifier)
435  * @param[in] oidLen Length of the OID, in bytes
436  * @param[out] value Object value
437  * @param[in,out] valueLen Length of the object value, in bytes
438  * @return Error code
439  **/
440 
441 error_t ifMibGetIfXEntry(const MibObject *object, const uint8_t *oid,
442  size_t oidLen, MibVariant *value, size_t *valueLen)
443 {
444  error_t error;
445  size_t n;
446  uint_t index;
447  IfMibIfXEntry *entry;
448  NetInterface *interface;
449 
450  //Point to the instance identifier
451  n = object->oidLen;
452 
453  //ifIndex is used as instance identifier
454  error = mibDecodeIndex(oid, oidLen, &n, &index);
455  //Invalid instance identifier?
456  if(error)
457  return error;
458 
459  //Sanity check
460  if(n != oidLen)
462 
463  //Check index range
464  if(index < 1 || index > NET_INTERFACE_COUNT)
466 
467  //Point to the underlying interface
468  interface = &netInterface[index - 1];
469  //Point to the interface table entry
470  entry = &ifMibBase.ifXTable[index - 1];
471 
472  //ifName object?
473  if(!osStrcmp(object->name, "ifName"))
474  {
475  //Retrieve the length of the interface name
476  n = osStrlen(interface->name);
477 
478  //Make sure the buffer is large enough to hold the entire object
479  if(*valueLen >= n)
480  {
481  //Copy object value
482  osMemcpy(value->octetString, interface->name, n);
483  //Return object length
484  *valueLen = n;
485  }
486  else
487  {
488  //Report an error
489  error = ERROR_BUFFER_OVERFLOW;
490  }
491  }
492  //ifInMulticastPkts object?
493  else if(!osStrcmp(object->name, "ifInMulticastPkts"))
494  {
495  //Get object value
496  value->counter32 = entry->ifInMulticastPkts;
497  }
498  //ifInBroadcastPkts object?
499  else if(!osStrcmp(object->name, "ifInBroadcastPkts"))
500  {
501  //Get object value
502  value->counter32 = entry->ifInBroadcastPkts;
503  }
504  //ifOutMulticastPkts object?
505  else if(!osStrcmp(object->name, "ifOutMulticastPkts"))
506  {
507  //Get object value
508  value->counter32 = entry->ifOutMulticastPkts;
509  }
510  //ifOutBroadcastPkts object?
511  else if(!osStrcmp(object->name, "ifOutBroadcastPkts"))
512  {
513  //Get object value
514  value->counter32 = entry->ifOutBroadcastPkts;
515  }
516  //ifHCInOctets object?
517  else if(!osStrcmp(object->name, "ifHCInOctets"))
518  {
519  //Get object value
520  value->counter64 = entry->ifHCInOctets;
521  }
522  //ifHCInUcastPkts object?
523  else if(!osStrcmp(object->name, "ifHCInUcastPkts"))
524  {
525  //Get object value
526  value->counter64 = entry->ifHCInUcastPkts;
527  }
528  //ifHCInMulticastPkts object?
529  else if(!osStrcmp(object->name, "ifHCInMulticastPkts"))
530  {
531  //Get object value
532  value->counter64 = entry->ifHCInMulticastPkts;
533  }
534  //ifHCInBroadcastPkts object?
535  else if(!osStrcmp(object->name, "ifHCInBroadcastPkts"))
536  {
537  //Get object value
538  value->counter64 = entry->ifHCInBroadcastPkts;
539  }
540  //ifHCOutOctets object?
541  else if(!osStrcmp(object->name, "ifHCOutOctets"))
542  {
543  //Get object value
544  value->counter64 = entry->ifHCOutOctets;
545  }
546  //ifHCOutUcastPkts object?
547  else if(!osStrcmp(object->name, "ifHCOutUcastPkts"))
548  {
549  //Get object value
550  value->counter64 = entry->ifHCOutUcastPkts;
551  }
552  //ifHCOutMulticastPkts object?
553  else if(!osStrcmp(object->name, "ifHCOutMulticastPkts"))
554  {
555  //Get object value
556  value->counter64 = entry->ifHCOutMulticastPkts;
557  }
558  //ifHCOutBroadcastPkts object?
559  else if(!osStrcmp(object->name, "ifHCOutBroadcastPkts"))
560  {
561  //Get object value
562  value->counter64 = entry->ifHCOutBroadcastPkts;
563  }
564  //ifLinkUpDownTrapEnable object?
565  else if(!osStrcmp(object->name, "ifLinkUpDownTrapEnable"))
566  {
567  //Get object value
568  value->integer = entry->ifLinkUpDownTrapEnable;
569  }
570  //ifHighSpeed object?
571  else if(!osStrcmp(object->name, "ifHighSpeed"))
572  {
573  //Get interface's current bandwidth
574  value->gauge32 = interface->linkSpeed / 1000000;
575  }
576  //ifPromiscuousMode object?
577  else if(!osStrcmp(object->name, "ifPromiscuousMode"))
578  {
579  //Get object value
580  value->integer = entry->ifPromiscuousMode;
581  }
582  //ifConnectorPresent object?
583  else if(!osStrcmp(object->name, "ifConnectorPresent"))
584  {
585  //Get object value
586  value->integer = entry->ifConnectorPresent;
587  }
588  //ifAlias object?
589  else if(!osStrcmp(object->name, "ifAlias"))
590  {
591  //On the first instantiation of an interface, the value of ifAlias
592  //associated with that interface is the zero-length string
593  *valueLen = 0;
594  }
595  //ifCounterDiscontinuityTime object?
596  else if(!osStrcmp(object->name, "ifCounterDiscontinuityTime"))
597  {
598  //Get object value
599  value->timeTicks = 0;
600  }
601  //Unknown object?
602  else
603  {
604  //The specified object does not exist
605  error = ERROR_OBJECT_NOT_FOUND;
606  }
607 
608  //Return status code
609  return error;
610 }
611 
612 
613 /**
614  * @brief Get next ifXEntry object
615  * @param[in] object Pointer to the MIB object descriptor
616  * @param[in] oid Object identifier
617  * @param[in] oidLen Length of the OID, in bytes
618  * @param[out] nextOid OID of the next object in the MIB
619  * @param[out] nextOidLen Length of the next object identifier, in bytes
620  * @return Error code
621  **/
622 
623 error_t ifMibGetNextIfXEntry(const MibObject *object, const uint8_t *oid,
624  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
625 {
626  error_t error;
627  size_t n;
628  uint_t index;
629 
630  //Make sure the buffer is large enough to hold the OID prefix
631  if(*nextOidLen < object->oidLen)
632  return ERROR_BUFFER_OVERFLOW;
633 
634  //Copy OID prefix
635  osMemcpy(nextOid, object->oid, object->oidLen);
636 
637  //Loop through network interfaces
638  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
639  {
640  //Append the instance identifier to the OID prefix
641  n = object->oidLen;
642 
643  //ifIndex is used as instance identifier
644  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
645  //Any error to report?
646  if(error)
647  return error;
648 
649  //Check whether the resulting object identifier lexicographically
650  //follows the specified OID
651  if(oidComp(nextOid, n, oid, oidLen) > 0)
652  {
653  //Save the length of the resulting object identifier
654  *nextOidLen = n;
655  //Next object found
656  return NO_ERROR;
657  }
658  }
659 
660  //The specified OID does not lexicographically precede the name
661  //of some object
662  return ERROR_OBJECT_NOT_FOUND;
663 }
664 
665 
666 /**
667  * @brief Set ifStackEntry object value
668  * @param[in] object Pointer to the MIB object descriptor
669  * @param[in] oid Object identifier (object name and instance identifier)
670  * @param[in] oidLen Length of the OID, in bytes
671  * @param[in] value Object value
672  * @param[in] valueLen Length of the object value, in bytes
673  * @param[in] commit This flag tells whether the changes shall be committed
674  * to the MIB base
675  * @return Error code
676  **/
677 
678 error_t ifMibSetIfStackEntry(const MibObject *object, const uint8_t *oid,
679  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
680 {
681  //Not implemented
682  return ERROR_WRITE_FAILED;
683 }
684 
685 
686 /**
687  * @brief Get ifStackEntry object value
688  * @param[in] object Pointer to the MIB object descriptor
689  * @param[in] oid Object identifier (object name and instance identifier)
690  * @param[in] oidLen Length of the OID, in bytes
691  * @param[out] value Object value
692  * @param[in,out] valueLen Length of the object value, in bytes
693  * @return Error code
694  **/
695 
696 error_t ifMibGetIfStackEntry(const MibObject *object, const uint8_t *oid,
697  size_t oidLen, MibVariant *value, size_t *valueLen)
698 {
699  error_t error;
700  size_t n;
701  uint_t index;
702  uint_t higherLayer;
703  uint_t lowerLayer;
704 
705  //Point to the instance identifier
706  n = object->oidLen;
707 
708  //ifStackHigherLayer is used as 1st instance identifier
709  error = mibDecodeIndex(oid, oidLen, &n, &higherLayer);
710  //Invalid instance identifier?
711  if(error)
712  return error;
713 
714  //ifStackLowerLayer is used as 2nd instance identifier
715  error = mibDecodeIndex(oid, oidLen, &n, &lowerLayer);
716  //Invalid instance identifier?
717  if(error)
718  return error;
719 
720  //Sanity check
721  if(n != oidLen)
723 
724  //Loop through network interfaces
725  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
726  {
727  //Check higher and lower sub-layers
728  if(higherLayer == 0 && lowerLayer == index)
729  {
730  break;
731  }
732  else if(higherLayer == index && lowerLayer == 0)
733  {
734  break;
735  }
736  }
737 
738  //No matching interface?
739  if(index > NET_INTERFACE_COUNT)
741 
742  //ifStackStatus object?
743  if(!osStrcmp(object->name, "ifStackStatus"))
744  {
745  //status of the relationship between the two sub-layers
746  value->integer = MIB_ROW_STATUS_ACTIVE;
747  }
748  //Unknown object?
749  else
750  {
751  //The specified object does not exist
752  error = ERROR_OBJECT_NOT_FOUND;
753  }
754 
755  //Return status code
756  return error;
757 }
758 
759 
760 /**
761  * @brief Get next ifStackEntry object
762  * @param[in] object Pointer to the MIB object descriptor
763  * @param[in] oid Object identifier
764  * @param[in] oidLen Length of the OID, in bytes
765  * @param[out] nextOid OID of the next object in the MIB
766  * @param[out] nextOidLen Length of the next object identifier, in bytes
767  * @return Error code
768  **/
769 
770 error_t ifMibGetNextIfStackEntry(const MibObject *object, const uint8_t *oid,
771  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
772 {
773  error_t error;
774  uint_t k;
775  size_t n;
776  uint_t index;
777  uint_t higherLayer;
778  uint_t lowerLayer;
779 
780  //Make sure the buffer is large enough to hold the OID prefix
781  if(*nextOidLen < object->oidLen)
782  return ERROR_BUFFER_OVERFLOW;
783 
784  //Copy OID prefix
785  osMemcpy(nextOid, object->oid, object->oidLen);
786 
787  //two rows exist even for an interface which has no others stacked
788  //on top or below it
789  for(k = 0; k < 2; k++)
790  {
791  //Loop through network interfaces
792  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
793  {
794  //Append the instance identifier to the OID prefix
795  n = object->oidLen;
796 
797  //Higher and lower sub-layers
798  if(k == 0)
799  {
800  higherLayer = 0;
801  lowerLayer = index;
802  }
803  else
804  {
805  higherLayer = index;
806  lowerLayer = 0;
807  }
808 
809  //ifStackHigherLayer is used as 1st instance identifier
810  error = mibEncodeIndex(nextOid, *nextOidLen, &n, higherLayer);
811  //Any error to report?
812  if(error)
813  return error;
814 
815  //ifStackLowerLayer is used as 2nd instance identifier
816  error = mibEncodeIndex(nextOid, *nextOidLen, &n, lowerLayer);
817  //Any error to report?
818  if(error)
819  return error;
820 
821  //Check whether the resulting object identifier lexicographically
822  //follows the specified OID
823  if(oidComp(nextOid, n, oid, oidLen) > 0)
824  {
825  //Save the length of the resulting object identifier
826  *nextOidLen = n;
827  //Next object found
828  return NO_ERROR;
829  }
830  }
831  }
832 
833  //The specified OID does not lexicographically precede the name
834  //of some object
835  return ERROR_OBJECT_NOT_FOUND;
836 }
837 
838 
839 /**
840  * @brief Set ifRcvAddressEntry object value
841  * @param[in] object Pointer to the MIB object descriptor
842  * @param[in] oid Object identifier (object name and instance identifier)
843  * @param[in] oidLen Length of the OID, in bytes
844  * @param[in] value Object value
845  * @param[in] valueLen Length of the object value, in bytes
846  * @param[in] commit This flag tells whether the changes shall be committed
847  * to the MIB base
848  * @return Error code
849  **/
850 
851 error_t ifMibSetIfRcvAddressEntry(const MibObject *object, const uint8_t *oid,
852  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
853 {
854  //Not implemented
855  return ERROR_WRITE_FAILED;
856 }
857 
858 
859 /**
860  * @brief Get ifRcvAddressEntry object value
861  * @param[in] object Pointer to the MIB object descriptor
862  * @param[in] oid Object identifier (object name and instance identifier)
863  * @param[in] oidLen Length of the OID, in bytes
864  * @param[out] value Object value
865  * @param[in,out] valueLen Length of the object value, in bytes
866  * @return Error code
867  **/
868 
869 error_t ifMibGetIfRcvAddressEntry(const MibObject *object, const uint8_t *oid,
870  size_t oidLen, MibVariant *value, size_t *valueLen)
871 {
872 #if (ETH_SUPPORT == ENABLED)
873  error_t error;
874  uint_t i;
875  size_t n;
876  uint_t index;
877  MacAddr macAddr;
878  NetInterface *interface;
879  NetInterface *logicalInterface;
880 
881  //Point to the instance identifier
882  n = object->oidLen;
883 
884  //ifIndex is used as 1st instance identifier
885  error = mibDecodeIndex(oid, oidLen, &n, &index);
886  //Invalid instance identifier?
887  if(error)
888  return error;
889 
890  //ifRcvAddressAddress is used as 2nd instance identifier
891  error = mibDecodePhysAddr(oid, oidLen, &n, &macAddr);
892  //Invalid instance identifier?
893  if(error)
894  return error;
895 
896  //Sanity check
897  if(n != oidLen)
899 
900  //Check index range
901  if(index < 1 || index > NET_INTERFACE_COUNT)
903 
904  //Point to the underlying interface
905  interface = &netInterface[index - 1];
906  //Point to the logical interface
907  logicalInterface = nicGetLogicalInterface(interface);
908 
909  //Initialize status code
910  error = ERROR_INSTANCE_NOT_FOUND;
911 
912  //Interface MAC address?
913  if(macCompAddr(&macAddr, &logicalInterface->macAddr))
914  {
915  //The MAC address is acceptable
916  error = NO_ERROR;
917  }
918  //Broadcast address?
919  else if(macCompAddr(&macAddr, &MAC_BROADCAST_ADDR))
920  {
921  //The MAC address is acceptable
922  error = NO_ERROR;
923  }
924  //Multicast address?
925  else if(macIsMulticastAddr(&macAddr))
926  {
927  //Go through the MAC filter table
928  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
929  {
930  //Valid entry?
931  if(interface->macAddrFilter[i].refCount > 0)
932  {
933  //Check whether the MAC address matches a relevant multicast address
934  if(macCompAddr(&macAddr, &interface->macAddrFilter[i].addr))
935  {
936  //The MAC address is acceptable
937  error = NO_ERROR;
938  }
939  }
940  }
941  }
942 
943  //Check whether the MAC address is acceptable
944  if(!error)
945  {
946  //ifRcvAddressStatus object?
947  if(!osStrcmp(object->name, "ifRcvAddressStatus"))
948  {
949  //Get object value
950  value->integer = MIB_ROW_STATUS_ACTIVE;
951  }
952  //ifRcvAddressType object?
953  else if(!osStrcmp(object->name, "ifRcvAddressType"))
954  {
955  //Get object value
956  if(macCompAddr(&macAddr, &logicalInterface->macAddr) ||
957  macCompAddr(&macAddr, &MAC_BROADCAST_ADDR))
958  {
959  //The entry is not volatile
961  }
962  else
963  {
964  //The entry is volatile
966  }
967  }
968  //Unknown object?
969  else
970  {
971  //The specified object does not exist
972  error = ERROR_OBJECT_NOT_FOUND;
973  }
974  }
975 
976  //Return status code
977  return error;
978 #else
979  //Not implemented
980  return ERROR_OBJECT_NOT_FOUND;
981 #endif
982 }
983 
984 
985 /**
986  * @brief Get next ifRcvAddressEntry object
987  * @param[in] object Pointer to the MIB object descriptor
988  * @param[in] oid Object identifier
989  * @param[in] oidLen Length of the OID, in bytes
990  * @param[out] nextOid OID of the next object in the MIB
991  * @param[out] nextOidLen Length of the next object identifier, in bytes
992  * @return Error code
993  **/
994 
995 error_t ifMibGetNextIfRcvAddressEntry(const MibObject *object, const uint8_t *oid,
996  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
997 {
998 #if (ETH_SUPPORT == ENABLED)
999  error_t error;
1000  int_t i;
1001  size_t n;
1002  uint_t index;
1003  uint_t curIndex;
1004  bool_t acceptable;
1005  MacAddr macAddr;
1006  MacAddr curMacAddr;
1007  NetInterface *interface;
1008  NetInterface *logicalInterface;
1009 
1010  //Initialize variables
1011  index = 0;
1012  macAddr = MAC_UNSPECIFIED_ADDR;
1013 
1014  //Make sure the buffer is large enough to hold the OID prefix
1015  if(*nextOidLen < object->oidLen)
1016  return ERROR_BUFFER_OVERFLOW;
1017 
1018  //Copy OID prefix
1019  osMemcpy(nextOid, object->oid, object->oidLen);
1020 
1021  //Loop through network interfaces
1022  for(curIndex = 1; curIndex <= NET_INTERFACE_COUNT; curIndex++)
1023  {
1024  //Point to the underlying interface
1025  interface = &netInterface[curIndex - 1];
1026  //Point to the logical interface
1027  logicalInterface = nicGetLogicalInterface(interface);
1028 
1029  //Go through the MAC filter table
1030  for(i = -2; i < MAC_ADDR_FILTER_SIZE; i++)
1031  {
1032  if(i == -2)
1033  {
1034  //Get interface MAC address
1035  curMacAddr = logicalInterface->macAddr;
1036  }
1037  else if(i == -1)
1038  {
1039  //Get broadcast address
1040  curMacAddr = MAC_BROADCAST_ADDR;
1041  }
1042  else
1043  {
1044  //Get multicast address
1045  if(interface->macAddrFilter[i].refCount > 0)
1046  {
1047  curMacAddr = interface->macAddrFilter[i].addr;
1048  }
1049  else
1050  {
1051  curMacAddr = MAC_UNSPECIFIED_ADDR;
1052  }
1053  }
1054 
1055  //Valid MAC address?
1056  if(!macCompAddr(&curMacAddr, &MAC_UNSPECIFIED_ADDR))
1057  {
1058  //Append the instance identifier to the OID prefix
1059  n = object->oidLen;
1060 
1061  //ifIndex is used as 1st instance identifier
1062  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curIndex);
1063  //Invalid instance identifier?
1064  if(error)
1065  return error;
1066 
1067  //ifRcvAddressAddress is used as 2nd instance identifier
1068  error = mibEncodePhysAddr(nextOid, *nextOidLen, &n, &curMacAddr);
1069  //Invalid instance identifier?
1070  if(error)
1071  return error;
1072 
1073  //Check whether the resulting object identifier lexicographically
1074  //follows the specified OID
1075  if(oidComp(nextOid, n, oid, oidLen) > 0)
1076  {
1077  //Perform lexicographic comparison
1078  if(index == 0)
1079  {
1080  acceptable = TRUE;
1081  }
1082  else if(curIndex < index)
1083  {
1084  acceptable = TRUE;
1085  }
1086  else if(curIndex > index)
1087  {
1088  acceptable = FALSE;
1089  }
1090  else if(osMemcmp(&curMacAddr, &macAddr, sizeof(MacAddr)) < 0)
1091  {
1092  acceptable = TRUE;
1093  }
1094  else
1095  {
1096  acceptable = FALSE;
1097  }
1098 
1099  //Save the closest object identifier that follows the specified
1100  //OID in lexicographic order
1101  if(acceptable)
1102  {
1103  macAddr = curMacAddr;
1104  index = curIndex;
1105  }
1106  }
1107  }
1108  }
1109  }
1110 
1111  //The specified OID does not lexicographically precede the name
1112  //of some object?
1113  if(index == 0)
1114  return ERROR_OBJECT_NOT_FOUND;
1115 
1116  //Append the instance identifier to the OID prefix
1117  n = object->oidLen;
1118 
1119  //ifIndex is used as 1st instance identifier
1120  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
1121  //Invalid instance identifier?
1122  if(error)
1123  return error;
1124 
1125  //ifRcvAddressAddress is used as 2nd instance identifier
1126  error = mibEncodePhysAddr(nextOid, *nextOidLen, &n, &macAddr);
1127  //Invalid instance identifier?
1128  if(error)
1129  return error;
1130 
1131  //Save the length of the resulting object identifier
1132  *nextOidLen = n;
1133  //Next object found
1134  return NO_ERROR;
1135 #else
1136  //Not implemented
1137  return ERROR_OBJECT_NOT_FOUND;
1138 #endif
1139 }
1140 
1141 #endif
ASN.1 (Abstract Syntax Notation One)
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
General definitions for cryptographic algorithms.
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRITE_FAILED
Definition: error.h:221
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:255
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:256
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:53
const MacAddr MAC_BROADCAST_ADDR
Definition: ethernet.c:55
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:133
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
#define macCopyAddr(destMacAddr, srcMacAddr)
Definition: ethernet.h:127
MacAddr
Definition: ethernet.h:195
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
error_t ifMibSetIfXEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ifXEntry object value.
Definition: if_mib_impl.c:423
error_t ifMibSetIfRcvAddressEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ifRcvAddressEntry object value.
Definition: if_mib_impl.c:851
error_t ifMibSetIfStackEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ifStackEntry object value.
Definition: if_mib_impl.c:678
error_t ifMibGetNextIfRcvAddressEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ifRcvAddressEntry object.
Definition: if_mib_impl.c:995
error_t ifMibGetIfEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ifEntry object value.
Definition: if_mib_impl.c:112
error_t ifMibGetNextIfStackEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ifStackEntry object.
Definition: if_mib_impl.c:770
error_t ifMibGetIfStackEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ifStackEntry object value.
Definition: if_mib_impl.c:696
error_t ifMibInit(void)
Interfaces Group MIB module initialization.
Definition: if_mib_impl.c:53
error_t ifMibGetNextIfEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ifEntry object.
Definition: if_mib_impl.c:368
error_t ifMibGetNextIfXEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ifXEntry object.
Definition: if_mib_impl.c:623
error_t ifMibGetIfXEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ifXEntry object value.
Definition: if_mib_impl.c:441
error_t ifMibGetIfRcvAddressEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ifRcvAddressEntry object value.
Definition: if_mib_impl.c:869
error_t ifMibSetIfEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ifEntry object value.
Definition: if_mib_impl.c:94
Interfaces Group MIB module implementation.
IfMibBase ifMibBase
Interfaces Group MIB base.
Definition: if_mib_module.c:59
Interfaces Group MIB module.
@ IF_MIB_IF_ADMIN_STATUS_DOWN
Definition: if_mib_module.h:93
@ IF_MIB_IF_ADMIN_STATUS_UP
Definition: if_mib_module.h:92
@ IF_MIB_IF_LINK_UP_DOWN_TRAP_DISABLED
@ IF_MIB_RCV_ADDRESS_TYPE_NON_VOLATILE
@ IF_MIB_RCV_ADDRESS_TYPE_VOLATILE
@ IF_MIB_IF_OPER_STATUS_DOWN
@ IF_MIB_IF_OPER_STATUS_UP
@ IF_MIB_IF_TYPE_L2_VLAN
Definition: if_mib_module.h:78
@ IF_MIB_IF_TYPE_ETHERNET_CSMACD
Definition: if_mib_module.h:68
@ IF_MIB_IF_TYPE_PPP
Definition: if_mib_module.h:70
@ IF_MIB_IF_TYPE_IEEE_802_15_4
Definition: if_mib_module.h:82
@ IF_MIB_IF_TYPE_OTHER
Definition: if_mib_module.h:67
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
error_t mibEncodePhysAddr(uint8_t *oid, size_t maxOidLen, size_t *pos, const MacAddr *macAddr)
Encode instance identifier (physical address)
Definition: mib_common.c:596
error_t mibDecodeIndex(const uint8_t *oid, size_t oidLen, size_t *pos, uint_t *index)
Decode instance identifier (index)
Definition: mib_common.c:64
error_t mibDecodePhysAddr(const uint8_t *oid, size_t oidLen, size_t *pos, MacAddr *macAddr)
Decode instance identifier (physical address)
Definition: mib_common.c:625
error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos, uint_t index)
Encode instance identifier (index)
Definition: mib_common.c:47
Common definitions for MIB modules.
#define MibObject
Definition: mib_common.h:46
@ MIB_TRUTH_VALUE_TRUE
Definition: mib_common.h:91
@ MIB_TRUTH_VALUE_FALSE
Definition: mib_common.h:92
@ MIB_ROW_STATUS_ACTIVE
Definition: mib_common.h:103
MibVariant
Definition: mib_common.h:196
TCP/IP stack core.
#define NET_INTERFACE_COUNT
Definition: net.h:113
#define NetInterface
Definition: net.h:36
#define netInterface
Definition: net_legacy.h:199
NetInterface * nicGetLogicalInterface(NetInterface *interface)
Retrieve logical interface.
Definition: nic.c:52
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:84
@ NIC_TYPE_6LOWPAN
6LoWPAN interface
Definition: nic.h:87
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
@ NIC_TYPE_PPP
PPP interface.
Definition: nic.h:84
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osStrcmp(s1, s2)
Definition: os_port.h:171
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define osStrlen(s)
Definition: os_port.h:165
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
IfMibIfXEntry ifXTable[NET_INTERFACE_COUNT]
int32_t ifNumber
IfMibIfEntry ifTable[NET_INTERFACE_COUNT]
Interfaces table entry.
uint32_t ifOutDiscards
uint32_t ifOutErrors
uint32_t ifLastChange
uint32_t ifOutOctets
uint32_t ifOutUcastPkts
uint32_t ifInUnknownProtos
uint32_t ifInErrors
uint32_t ifInUcastPkts
uint32_t ifInOctets
uint32_t ifInDiscards
Extension to the interface table.
uint32_t ifInBroadcastPkts
uint64_t ifHCInOctets
uint32_t ifOutMulticastPkts
uint64_t ifHCOutBroadcastPkts
uint64_t ifHCInBroadcastPkts
uint32_t ifInMulticastPkts
int32_t ifPromiscuousMode
int32_t ifLinkUpDownTrapEnable
uint64_t ifHCInUcastPkts
int32_t ifConnectorPresent
uint32_t ifOutBroadcastPkts
uint64_t ifHCOutMulticastPkts
uint64_t ifHCInMulticastPkts
uint64_t ifHCOutUcastPkts
uint64_t ifHCOutOctets
uint8_t value[]
Definition: tcp.h:369