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