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