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