ip_mib_impl.c
Go to the documentation of this file.
1 /**
2  * @file ip_mib_impl.c
3  * @brief IP 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 "ipv4/ipv4.h"
37 #include "ipv4/arp.h"
38 #include "ipv6/ipv6.h"
39 #include "ipv6/ipv6_misc.h"
40 #include "ipv6/ndp_cache.h"
41 #include "ipv6/ndp_router_adv.h"
42 #include "mibs/mib_common.h"
43 #include "mibs/ip_mib_module.h"
44 #include "mibs/ip_mib_impl.h"
45 #include "core/crypto.h"
46 #include "encoding/asn1.h"
47 #include "encoding/oid.h"
48 #include "debug.h"
49 
50 //Check TCP/IP stack configuration
51 #if (IP_MIB_SUPPORT == ENABLED)
52 
53 
54 /**
55  * @brief IP MIB module initialization
56  * @return Error code
57  **/
58 
60 {
61  //Debug message
62  TRACE_INFO("Initializing IP-MIB base...\r\n");
63 
64  //Clear IP MIB base
65  memset(&ipMibBase, 0, sizeof(ipMibBase));
66 
67  //ipAddressSpinLock object
69 
70 #if (IPV4_SUPPORT == ENABLED)
71  //ipForwarding object
73  //ipDefaultTTL object
75  //ipReasmTimeout object
77 #endif
78 
79 #if (IPV6_SUPPORT == ENABLED)
80  //ipv6IpForwarding object
82  //ipv6IpDefaultHopLimit object
84 
85  //ipv6RouterAdvertSpinLock object
87 #endif
88 
89  //Successful processing
90  return NO_ERROR;
91 }
92 
93 
94 /**
95  * @brief Set ipv4InterfaceEntry object value
96  * @param[in] object Pointer to the MIB object descriptor
97  * @param[in] oid Object identifier (object name and instance identifier)
98  * @param[in] oidLen Length of the OID, in bytes
99  * @param[in] value Object value
100  * @param[in] valueLen Length of the object value, in bytes
101  * @param[in] commit This flag tells whether the changes shall be committed
102  * to the MIB base
103  * @return Error code
104  **/
105 
106 error_t ipMibSetIpv4InterfaceEntry(const MibObject *object, const uint8_t *oid,
107  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
108 {
109  //Not implemented
110  return ERROR_WRITE_FAILED;
111 }
112 
113 
114 /**
115  * @brief Get ipv4InterfaceEntry object value
116  * @param[in] object Pointer to the MIB object descriptor
117  * @param[in] oid Object identifier (object name and instance identifier)
118  * @param[in] oidLen Length of the OID, in bytes
119  * @param[out] value Object value
120  * @param[in,out] valueLen Length of the object value, in bytes
121  * @return Error code
122  **/
123 
124 error_t ipMibGetIpv4InterfaceEntry(const MibObject *object, const uint8_t *oid,
125  size_t oidLen, MibVariant *value, size_t *valueLen)
126 {
127  error_t error;
128  size_t n;
129  uint_t index;
130 
131  //Point to the instance identifier
132  n = object->oidLen;
133 
134  //ipv4InterfaceIfIndex is used as instance identifier
135  error = mibDecodeIndex(oid, oidLen, &n, &index);
136  //Invalid instance identifier?
137  if(error)
138  return error;
139 
140  //Sanity check
141  if(n != oidLen)
143 
144  //Check index range
145  if(index < 1 || index > NET_INTERFACE_COUNT)
147 
148 #if (IPV4_SUPPORT == ENABLED)
149  //ipv4InterfaceReasmMaxSize object?
150  if(!strcmp(object->name, "ipv4InterfaceReasmMaxSize"))
151  {
152  //Get object value
154  }
155  //ipv4InterfaceEnableStatus object?
156  else if(!strcmp(object->name, "ipv4InterfaceEnableStatus"))
157  {
158  //Get object value
159  value->integer = IP_MIB_IP_STATUS_UP;
160  }
161  //ipv4InterfaceRetransmitTime object?
162  else if(!strcmp(object->name, "ipv4InterfaceRetransmitTime"))
163  {
164  //Get object value
165  value->unsigned32 = ARP_REQUEST_TIMEOUT;
166  }
167  else
168 #endif
169  //Unknown object?
170  {
171  //The specified object does not exist
172  error = ERROR_OBJECT_NOT_FOUND;
173  }
174 
175  //Return status code
176  return error;
177 }
178 
179 
180 /**
181  * @brief Get next ipv4InterfaceEntry object
182  * @param[in] object Pointer to the MIB object descriptor
183  * @param[in] oid Object identifier
184  * @param[in] oidLen Length of the OID, in bytes
185  * @param[out] nextOid OID of the next object in the MIB
186  * @param[out] nextOidLen Length of the next object identifier, in bytes
187  * @return Error code
188  **/
189 
190 error_t ipMibGetNextIpv4InterfaceEntry(const MibObject *object, const uint8_t *oid,
191  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
192 {
193  error_t error;
194  size_t n;
195  uint_t index;
196 
197  //Make sure the buffer is large enough to hold the OID prefix
198  if(*nextOidLen < object->oidLen)
199  return ERROR_BUFFER_OVERFLOW;
200 
201  //Copy OID prefix
202  memcpy(nextOid, object->oid, object->oidLen);
203 
204  //Loop through network interfaces
205  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
206  {
207  //Append the instance identifier to the OID prefix
208  n = object->oidLen;
209 
210  //ifIndex is used as instance identifier
211  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
212  //Any error to report?
213  if(error)
214  return error;
215 
216  //Check whether the resulting object identifier lexicographically
217  //follows the specified OID
218  if(oidComp(nextOid, n, oid, oidLen) > 0)
219  {
220  //Save the length of the resulting object identifier
221  *nextOidLen = n;
222  //Next object found
223  return NO_ERROR;
224  }
225  }
226 
227  //The specified OID does not lexicographically precede the name
228  //of some object
229  return ERROR_OBJECT_NOT_FOUND;
230 }
231 
232 
233 /**
234  * @brief Set ipv6InterfaceEntry object value
235  * @param[in] object Pointer to the MIB object descriptor
236  * @param[in] oid Object identifier (object name and instance identifier)
237  * @param[in] oidLen Length of the OID, in bytes
238  * @param[in] value Object value
239  * @param[in] valueLen Length of the object value, in bytes
240  * @param[in] commit This flag tells whether the changes shall be committed
241  * to the MIB base
242  * @return Error code
243  **/
244 
245 error_t ipMibSetIpv6InterfaceEntry(const MibObject *object, const uint8_t *oid,
246  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
247 {
248  //Not implemented
249  return ERROR_WRITE_FAILED;
250 }
251 
252 
253 /**
254  * @brief Get ipv6InterfaceEntry object value
255  * @param[in] object Pointer to the MIB object descriptor
256  * @param[in] oid Object identifier (object name and instance identifier)
257  * @param[in] oidLen Length of the OID, in bytes
258  * @param[out] value Object value
259  * @param[in,out] valueLen Length of the object value, in bytes
260  * @return Error code
261  **/
262 
263 error_t ipMibGetIpv6InterfaceEntry(const MibObject *object, const uint8_t *oid,
264  size_t oidLen, MibVariant *value, size_t *valueLen)
265 {
266  error_t error;
267  size_t n;
268  uint_t index;
269  NetInterface *interface;
270 
271  //Point to the instance identifier
272  n = object->oidLen;
273 
274  //ipv6InterfaceIfIndex is used as instance identifier
275  error = mibDecodeIndex(oid, oidLen, &n, &index);
276  //Invalid instance identifier?
277  if(error)
278  return error;
279 
280  //Sanity check
281  if(n != oidLen)
283 
284  //Check index range
285  if(index < 1 || index > NET_INTERFACE_COUNT)
287 
288  //Point to the underlying interface
289  interface = &netInterface[index - 1];
290 
291 #if (IPV6_SUPPORT == ENABLED)
292  //ipv6InterfaceReasmMaxSize object?
293  if(!strcmp(object->name, "ipv6InterfaceReasmMaxSize"))
294  {
295  //Get object value
296  value->unsigned32 = IPV6_MAX_FRAG_DATAGRAM_SIZE;
297  }
298  //ipv6InterfaceIdentifier object?
299  else if(!strcmp(object->name, "ipv6InterfaceIdentifier"))
300  {
301  //Make sure the buffer is large enough to hold the entire object
302  if(*valueLen >= sizeof(Eui64))
303  {
304  NetInterface *logicalInterface;
305 
306  //Point to the logical interface
307  logicalInterface = nicGetLogicalInterface(interface);
308 
309  //Copy object value
310  eui64CopyAddr(value->octetString, &logicalInterface->eui64);
311  //Return object length
312  *valueLen = sizeof(Eui64);
313  }
314  else
315  {
316  //Report an error
317  error = ERROR_BUFFER_OVERFLOW;
318  }
319  }
320  //ipv6InterfaceEnableStatus object?
321  else if(!strcmp(object->name, "ipv6InterfaceEnableStatus"))
322  {
323  //Get object value
324  value->integer = IP_MIB_IP_STATUS_UP;
325  }
326  //ipv6InterfaceReachableTime object?
327  else if(!strcmp(object->name, "ipv6InterfaceReachableTime"))
328  {
329  //Get object value
330  value->unsigned32 = interface->ndpContext.reachableTime;
331  }
332  //ipv6InterfaceRetransmitTime object?
333  else if(!strcmp(object->name, "ipv6InterfaceRetransmitTime"))
334  {
335  //Get object value
336  value->unsigned32 = interface->ndpContext.retransTimer;
337  }
338  //ipv6InterfaceForwarding object?
339  else if(!strcmp(object->name, "ipv6InterfaceForwarding"))
340  {
341  //Get object value
342  if(interface->ipv6Context.isRouter)
344  else
346  }
347  else
348 #endif
349  //Unknown object?
350  {
351  //The specified object does not exist
352  error = ERROR_OBJECT_NOT_FOUND;
353  }
354 
355  //Return status code
356  return error;
357 }
358 
359 
360 /**
361  * @brief Get next ipv6InterfaceEntry object
362  * @param[in] object Pointer to the MIB object descriptor
363  * @param[in] oid Object identifier
364  * @param[in] oidLen Length of the OID, in bytes
365  * @param[out] nextOid OID of the next object in the MIB
366  * @param[out] nextOidLen Length of the next object identifier, in bytes
367  * @return Error code
368  **/
369 
370 error_t ipMibGetNextIpv6InterfaceEntry(const MibObject *object, const uint8_t *oid,
371  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
372 {
373  error_t error;
374  size_t n;
375  uint_t index;
376 
377  //Make sure the buffer is large enough to hold the OID prefix
378  if(*nextOidLen < object->oidLen)
379  return ERROR_BUFFER_OVERFLOW;
380 
381  //Copy OID prefix
382  memcpy(nextOid, object->oid, object->oidLen);
383 
384  //Loop through network interfaces
385  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
386  {
387  //Append the instance identifier to the OID prefix
388  n = object->oidLen;
389 
390  //ifIndex is used as instance identifier
391  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
392  //Any error to report?
393  if(error)
394  return error;
395 
396  //Check whether the resulting object identifier lexicographically
397  //follows the specified OID
398  if(oidComp(nextOid, n, oid, oidLen) > 0)
399  {
400  //Save the length of the resulting object identifier
401  *nextOidLen = n;
402  //Next object found
403  return NO_ERROR;
404  }
405  }
406 
407  //The specified OID does not lexicographically precede the name
408  //of some object
409  return ERROR_OBJECT_NOT_FOUND;
410 }
411 
412 
413 /**
414  * @brief Get ipSystemStatsEntry 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 ipMibGetIpSystemStatsEntry(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 version;
430 
431  //Point to the instance identifier
432  n = object->oidLen;
433 
434  //ipSystemStatsIPVersion is used as instance identifier
435  error = mibDecodeIndex(oid, oidLen, &n, &version);
436  //Invalid instance identifier?
437  if(error)
438  return error;
439 
440  //Sanity check
441  if(n != oidLen)
443 
444 #if (IPV4_SUPPORT == ENABLED)
445  //IPv4 version?
447  {
448  //Point to the IPv4 statistics table entry
449  entry = &ipMibBase.ipv4SystemStats;
450  }
451  else
452 #endif
453 #if (IPV6_SUPPORT == ENABLED)
454  //IPv6 version?
456  {
457  //Point to the IPV6 statistics table entry
458  entry = &ipMibBase.ipv6SystemStats;
459  }
460  else
461 #endif
462  //Invalid IP version?
463  {
464  //No statistics available
465  entry = NULL;
466  }
467 
468  //Sanity check
469  if(entry != NULL)
470  {
471  //ipSystemStatsInReceives object?
472  if(!strcmp(object->name, "ipSystemStatsInReceives"))
473  value->counter32 = entry->ipSystemStatsInReceives;
474  //ipSystemStatsHCInReceives object?
475  else if(!strcmp(object->name, "ipSystemStatsHCInReceives"))
476  value->counter64 = entry->ipSystemStatsHCInReceives;
477  //ipSystemStatsInOctets object?
478  else if(!strcmp(object->name, "ipSystemStatsInOctets"))
479  value->counter32 = entry->ipSystemStatsInOctets;
480  //ipSystemStatsHCInOctets object?
481  else if(!strcmp(object->name, "ipSystemStatsHCInOctets"))
482  value->counter64 = entry->ipSystemStatsHCInOctets;
483  //ipSystemStatsInHdrErrors object?
484  else if(!strcmp(object->name, "ipSystemStatsInHdrErrors"))
485  value->counter32 = entry->ipSystemStatsInHdrErrors;
486  //ipSystemStatsInNoRoutes object?
487  else if(!strcmp(object->name, "ipSystemStatsInNoRoutes"))
488  value->counter32 = entry->ipSystemStatsInNoRoutes;
489  //ipSystemStatsInAddrErrors object?
490  else if(!strcmp(object->name, "ipSystemStatsInAddrErrors"))
491  value->counter32 = entry->ipSystemStatsInAddrErrors;
492  //ipSystemStatsInUnknownProtos object?
493  else if(!strcmp(object->name, "ipSystemStatsInUnknownProtos"))
494  value->counter32 = entry->ipSystemStatsInUnknownProtos;
495  //ipSystemStatsInTruncatedPkts object?
496  else if(!strcmp(object->name, "ipSystemStatsInTruncatedPkts"))
497  value->counter32 = entry->ipSystemStatsInTruncatedPkts;
498  //ipSystemStatsInForwDatagrams object?
499  else if(!strcmp(object->name, "ipSystemStatsInForwDatagrams"))
500  value->counter32 = entry->ipSystemStatsInForwDatagrams;
501  //ipSystemStatsHCInForwDatagrams object?
502  else if(!strcmp(object->name, "ipSystemStatsHCInForwDatagrams"))
503  value->counter64 = entry->ipSystemStatsHCInForwDatagrams;
504  //ipSystemStatsReasmReqds object?
505  else if(!strcmp(object->name, "ipSystemStatsReasmReqds"))
506  value->counter32 = entry->ipSystemStatsReasmReqds;
507  //ipSystemStatsReasmOKs object?
508  else if(!strcmp(object->name, "ipSystemStatsReasmOKs"))
509  value->counter32 = entry->ipSystemStatsReasmOKs;
510  //ipSystemStatsReasmFails object?
511  else if(!strcmp(object->name, "ipSystemStatsReasmFails"))
512  value->counter32 = entry->ipSystemStatsReasmFails;
513  //ipSystemStatsInDiscards object?
514  else if(!strcmp(object->name, "ipSystemStatsInDiscards"))
515  value->counter32 = entry->ipSystemStatsInDiscards;
516  //ipSystemStatsInDelivers object?
517  else if(!strcmp(object->name, "ipSystemStatsInDelivers"))
518  value->counter32 = entry->ipSystemStatsInDelivers;
519  //ipSystemStatsHCInDelivers object?
520  else if(!strcmp(object->name, "ipSystemStatsHCInDelivers"))
521  value->counter64 = entry->ipSystemStatsHCInDelivers;
522  //ipSystemStatsOutRequests object?
523  else if(!strcmp(object->name, "ipSystemStatsOutRequests"))
524  value->counter32 = entry->ipSystemStatsOutRequests;
525  //ipSystemStatsHCOutRequests object?
526  else if(!strcmp(object->name, "ipSystemStatsHCOutRequests"))
527  value->counter64 = entry->ipSystemStatsHCOutRequests;
528  //ipSystemStatsOutNoRoutes object?
529  else if(!strcmp(object->name, "ipSystemStatsOutNoRoutes"))
530  value->counter32 = entry->ipSystemStatsOutNoRoutes;
531  //ipSystemStatsOutForwDatagrams object?
532  else if(!strcmp(object->name, "ipSystemStatsOutForwDatagrams"))
533  value->counter32 = entry->ipSystemStatsOutForwDatagrams;
534  //ipSystemStatsHCOutForwDatagrams object?
535  else if(!strcmp(object->name, "ipSystemStatsHCOutForwDatagrams"))
536  value->counter64 = entry->ipSystemStatsHCOutForwDatagrams;
537  //ipSystemStatsOutDiscards object?
538  else if(!strcmp(object->name, "ipSystemStatsOutDiscards"))
539  value->counter32 = entry->ipSystemStatsOutDiscards;
540  //ipSystemStatsOutFragReqds object?
541  else if(!strcmp(object->name, "ipSystemStatsOutFragReqds"))
542  value->counter32 = entry->ipSystemStatsOutFragReqds;
543  //ipSystemStatsOutFragOKs object?
544  else if(!strcmp(object->name, "ipSystemStatsOutFragOKs"))
545  value->counter32 = entry->ipSystemStatsOutFragOKs;
546  //ipSystemStatsOutFragFails object?
547  else if(!strcmp(object->name, "ipSystemStatsOutFragFails"))
548  value->counter32 = entry->ipSystemStatsOutFragFails;
549  //ipSystemStatsOutFragCreates object?
550  else if(!strcmp(object->name, "ipSystemStatsOutFragCreates"))
551  value->counter32 = entry->ipSystemStatsOutFragCreates;
552  //ipSystemStatsOutTransmits object?
553  else if(!strcmp(object->name, "ipSystemStatsOutTransmits"))
554  value->counter32 = entry->ipSystemStatsOutTransmits;
555  //ipSystemStatsHCOutTransmits object?
556  else if(!strcmp(object->name, "ipSystemStatsHCOutTransmits"))
557  value->counter64 = entry->ipSystemStatsHCOutTransmits;
558  //ipSystemStatsOutOctets object?
559  else if(!strcmp(object->name, "ipSystemStatsOutOctets"))
560  value->counter32 = entry->ipSystemStatsOutOctets;
561  //ipSystemStatsHCOutOctets object?
562  else if(!strcmp(object->name, "ipSystemStatsHCOutOctets"))
563  value->counter64 = entry->ipSystemStatsHCOutOctets;
564  //ipSystemStatsInMcastPkts object?
565  else if(!strcmp(object->name, "ipSystemStatsInMcastPkts"))
566  value->counter32 = entry->ipSystemStatsInMcastPkts;
567  //ipSystemStatsHCInMcastPkts object?
568  else if(!strcmp(object->name, "ipSystemStatsHCInMcastPkts"))
569  value->counter64 = entry->ipSystemStatsHCInMcastPkts;
570  //ipSystemStatsInMcastOctets object?
571  else if(!strcmp(object->name, "ipSystemStatsInMcastOctets"))
572  value->counter32 = entry->ipSystemStatsInMcastOctets;
573  //ipSystemStatsHCInMcastOctets object?
574  else if(!strcmp(object->name, "ipSystemStatsHCInMcastOctets"))
575  value->counter64 = entry->ipSystemStatsHCInMcastOctets;
576  //ipSystemStatsOutMcastPkts object?
577  else if(!strcmp(object->name, "ipSystemStatsOutMcastPkts"))
578  value->counter32 = entry->ipSystemStatsOutMcastPkts;
579  //ipSystemStatsHCOutMcastPkts object?
580  else if(!strcmp(object->name, "ipSystemStatsHCOutMcastPkts"))
581  value->counter64 = entry->ipSystemStatsHCOutMcastPkts;
582  //ipSystemStatsOutMcastOctets object?
583  else if(!strcmp(object->name, "ipSystemStatsOutMcastOctets"))
584  value->counter32 = entry->ipSystemStatsOutMcastOctets;
585  //ipSystemStatsHCOutMcastOctets object?
586  else if(!strcmp(object->name, "ipSystemStatsHCOutMcastOctets"))
587  value->counter64 = entry->ipSystemStatsHCOutMcastOctets;
588  //ipSystemStatsInBcastPkts object?
589  else if(!strcmp(object->name, "ipSystemStatsInBcastPkts"))
590  value->counter32 = entry->ipSystemStatsInBcastPkts;
591  //ipSystemStatsHCInBcastPkts object?
592  else if(!strcmp(object->name, "ipSystemStatsHCInBcastPkts"))
593  value->counter64 = entry->ipSystemStatsHCInBcastPkts;
594  //ipSystemStatsOutBcastPkts object?
595  else if(!strcmp(object->name, "ipSystemStatsOutBcastPkts"))
596  value->counter32 = entry->ipSystemStatsOutBcastPkts;
597  //ipSystemStatsHCOutBcastPkts object?
598  else if(!strcmp(object->name, "ipSystemStatsHCOutBcastPkts"))
599  value->counter64 = entry->ipSystemStatsHCOutBcastPkts;
600  //ipSystemStatsDiscontinuityTime object?
601  else if(!strcmp(object->name, "ipSystemStatsDiscontinuityTime"))
602  value->timeTicks = entry->ipSystemStatsDiscontinuityTime;
603  //ipSystemStatsRefreshRate object?
604  else if(!strcmp(object->name, "ipSystemStatsRefreshRate"))
605  value->unsigned32 = entry->ipSystemStatsRefreshRate;
606  //Unknown object?
607  else
608  error = ERROR_OBJECT_NOT_FOUND;
609  }
610  else
611  {
612  //Report an error
613  error = ERROR_INSTANCE_NOT_FOUND;
614  }
615 
616  //Return status code
617  return error;
618 }
619 
620 
621 /**
622  * @brief Get next ipSystemStatsEntry object
623  * @param[in] object Pointer to the MIB object descriptor
624  * @param[in] oid Object identifier
625  * @param[in] oidLen Length of the OID, in bytes
626  * @param[out] nextOid OID of the next object in the MIB
627  * @param[out] nextOidLen Length of the next object identifier, in bytes
628  * @return Error code
629  **/
630 
631 error_t ipMibGetNextIpSystemStatsEntry(const MibObject *object, const uint8_t *oid,
632  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
633 {
634  error_t error;
635  size_t n;
636  uint_t version;
637 
638  //Make sure the buffer is large enough to hold the OID prefix
639  if(*nextOidLen < object->oidLen)
640  return ERROR_BUFFER_OVERFLOW;
641 
642  //Copy OID prefix
643  memcpy(nextOid, object->oid, object->oidLen);
644 
645  //IP version-neutral table
647  {
648 #if (IPV4_SUPPORT == DISABLED)
649  //IPv4 version?
651  {
652  //IPv4 is not implemented
653  continue;
654  }
655 #endif
656 #if (IPV6_SUPPORT == DISABLED)
657  //IPv6 version?
659  {
660  //IPv6 is not implemented
661  continue;
662  }
663 #endif
664 
665  //Append the instance identifier to the OID prefix
666  n = object->oidLen;
667 
668  //ipSystemStatsIPVersion is used as instance identifier
669  error = mibEncodeIndex(nextOid, *nextOidLen, &n, version);
670  //Any error to report?
671  if(error)
672  return error;
673 
674  //Check whether the resulting object identifier lexicographically
675  //follows the specified OID
676  if(oidComp(nextOid, n, oid, oidLen) > 0)
677  {
678  //Save the length of the resulting object identifier
679  *nextOidLen = n;
680  //Next object found
681  return NO_ERROR;
682  }
683  }
684 
685  //The specified OID does not lexicographically precede the name
686  //of some object
687  return ERROR_OBJECT_NOT_FOUND;
688 }
689 
690 
691 /**
692  * @brief Get ipIfStatsEntry object value
693  * @param[in] object Pointer to the MIB object descriptor
694  * @param[in] oid Object identifier (object name and instance identifier)
695  * @param[in] oidLen Length of the OID, in bytes
696  * @param[out] value Object value
697  * @param[in,out] valueLen Length of the object value, in bytes
698  * @return Error code
699  **/
700 
701 error_t ipMibGetIpIfStatsEntry(const MibObject *object, const uint8_t *oid,
702  size_t oidLen, MibVariant *value, size_t *valueLen)
703 {
704  error_t error;
705  size_t n;
706  uint_t version;
707  uint_t index;
708  IpMibIpIfStatsEntry *entry;
709 
710  //Point to the instance identifier
711  n = object->oidLen;
712 
713  //ipIfStatsIPVersion is used as 1st instance identifier
714  error = mibDecodeIndex(oid, oidLen, &n, &version);
715  //Invalid instance identifier?
716  if(error)
717  return error;
718 
719  //ipIfStatsIfIndex is used as 2nd instance identifier
720  error = mibDecodeIndex(oid, oidLen, &n, &index);
721  //Invalid instance identifier?
722  if(error)
723  return error;
724 
725  //Sanity check
726  if(n != oidLen)
728 
729  //Check index range
730  if(index < 1 || index > NET_INTERFACE_COUNT)
732 
733 #if (IPV4_SUPPORT == ENABLED)
734  //IPv4 version?
736  {
737  //Point to the IPv4 statistics table entry
738  entry = &ipMibBase.ipv4IfStatsTable[index - 1];
739  }
740  else
741 #endif
742 #if (IPV6_SUPPORT == ENABLED)
743  //IPv6 version?
745  {
746  //Point to the IPv6 statistics table entry
747  entry = &ipMibBase.ipv6IfStatsTable[index - 1];
748  }
749  else
750 #endif
751  //Invalid IP version?
752  {
753  //No statistics available
754  entry = NULL;
755  }
756 
757  //Sanity check
758  if(entry != NULL)
759  {
760  //ipIfStatsInReceives object?
761  if(!strcmp(object->name, "ipIfStatsInReceives"))
762  value->counter32 = entry->ipIfStatsInReceives;
763  //ipIfStatsHCInReceives object?
764  else if(!strcmp(object->name, "ipIfStatsHCInReceives"))
765  value->counter64 = entry->ipIfStatsHCInReceives;
766  //ipIfStatsInOctets object?
767  else if(!strcmp(object->name, "ipIfStatsInOctets"))
768  value->counter32 = entry->ipIfStatsInOctets;
769  //ipIfStatsHCInOctets object?
770  else if(!strcmp(object->name, "ipIfStatsHCInOctets"))
771  value->counter64 = entry->ipIfStatsHCInOctets;
772  //ipIfStatsInHdrErrors object?
773  else if(!strcmp(object->name, "ipIfStatsInHdrErrors"))
774  value->counter32 = entry->ipIfStatsInHdrErrors;
775  //ipIfStatsInNoRoutes object?
776  else if(!strcmp(object->name, "ipIfStatsInNoRoutes"))
777  value->counter32 = entry->ipIfStatsInNoRoutes;
778  //ipIfStatsInAddrErrors object?
779  else if(!strcmp(object->name, "ipIfStatsInAddrErrors"))
780  value->counter32 = entry->ipIfStatsInAddrErrors;
781  //ipIfStatsInUnknownProtos object?
782  else if(!strcmp(object->name, "ipIfStatsInUnknownProtos"))
783  value->counter32 = entry->ipIfStatsInUnknownProtos;
784  //ipIfStatsInTruncatedPkts object?
785  else if(!strcmp(object->name, "ipIfStatsInTruncatedPkts"))
786  value->counter32 = entry->ipIfStatsInTruncatedPkts;
787  //ipIfStatsInForwDatagrams object?
788  else if(!strcmp(object->name, "ipIfStatsInForwDatagrams"))
789  value->counter32 = entry->ipIfStatsInForwDatagrams;
790  //ipIfStatsHCInForwDatagrams object?
791  else if(!strcmp(object->name, "ipIfStatsHCInForwDatagrams"))
792  value->counter64 = entry->ipIfStatsHCInForwDatagrams;
793  //ipIfStatsReasmReqds object?
794  else if(!strcmp(object->name, "ipIfStatsReasmReqds"))
795  value->counter32 = entry->ipIfStatsReasmReqds;
796  //ipIfStatsReasmOKs object?
797  else if(!strcmp(object->name, "ipIfStatsReasmOKs"))
798  value->counter32 = entry->ipIfStatsReasmOKs;
799  //ipIfStatsReasmFails object?
800  else if(!strcmp(object->name, "ipIfStatsReasmFails"))
801  value->counter32 = entry->ipIfStatsReasmFails;
802  //ipIfStatsInDiscards object?
803  else if(!strcmp(object->name, "ipIfStatsInDiscards"))
804  value->counter32 = entry->ipIfStatsInDiscards;
805  //ipIfStatsInDelivers object?
806  else if(!strcmp(object->name, "ipIfStatsInDelivers"))
807  value->counter32 = entry->ipIfStatsInDelivers;
808  //ipIfStatsHCInDelivers object?
809  else if(!strcmp(object->name, "ipIfStatsHCInDelivers"))
810  value->counter64 = entry->ipIfStatsHCInDelivers;
811  //ipIfStatsOutRequests object?
812  else if(!strcmp(object->name, "ipIfStatsOutRequests"))
813  value->counter32 = entry->ipIfStatsOutRequests;
814  //ipIfStatsHCOutRequests object?
815  else if(!strcmp(object->name, "ipIfStatsHCOutRequests"))
816  value->counter64 = entry->ipIfStatsHCOutRequests;
817  //ipIfStatsOutForwDatagrams object?
818  else if(!strcmp(object->name, "ipIfStatsOutForwDatagrams"))
819  value->counter32 = entry->ipIfStatsOutForwDatagrams;
820  //ipIfStatsHCOutForwDatagrams object?
821  else if(!strcmp(object->name, "ipIfStatsHCOutForwDatagrams"))
822  value->counter64 = entry->ipIfStatsHCOutForwDatagrams;
823  //ipIfStatsOutDiscards object?
824  else if(!strcmp(object->name, "ipIfStatsOutDiscards"))
825  value->counter32 = entry->ipIfStatsOutDiscards;
826  //ipIfStatsOutFragReqds object?
827  else if(!strcmp(object->name, "ipIfStatsOutFragReqds"))
828  value->counter32 = entry->ipIfStatsOutFragReqds;
829  //ipIfStatsOutFragOKs object?
830  else if(!strcmp(object->name, "ipIfStatsOutFragOKs"))
831  value->counter32 = entry->ipIfStatsOutFragOKs;
832  //ipIfStatsOutFragFails object?
833  else if(!strcmp(object->name, "ipIfStatsOutFragFails"))
834  value->counter32 = entry->ipIfStatsOutFragFails;
835  //ipIfStatsOutFragCreates object?
836  else if(!strcmp(object->name, "ipIfStatsOutFragCreates"))
837  value->counter32 = entry->ipIfStatsOutFragCreates;
838  //ipIfStatsOutTransmits object?
839  else if(!strcmp(object->name, "ipIfStatsOutTransmits"))
840  value->counter32 = entry->ipIfStatsOutTransmits;
841  //ipIfStatsHCOutTransmits object?
842  else if(!strcmp(object->name, "ipIfStatsHCOutTransmits"))
843  value->counter64 = entry->ipIfStatsHCOutTransmits;
844  //ipIfStatsOutOctets object?
845  else if(!strcmp(object->name, "ipIfStatsOutOctets"))
846  value->counter32 = entry->ipIfStatsOutOctets;
847  //ipIfStatsHCOutOctets object?
848  else if(!strcmp(object->name, "ipIfStatsHCOutOctets"))
849  value->counter64 = entry->ipIfStatsHCOutOctets;
850  //ipIfStatsInMcastPkts object?
851  else if(!strcmp(object->name, "ipIfStatsInMcastPkts"))
852  value->counter32 = entry->ipIfStatsInMcastPkts;
853  //ipIfStatsHCInMcastPkts object?
854  else if(!strcmp(object->name, "ipIfStatsHCInMcastPkts"))
855  value->counter64 = entry->ipIfStatsHCInMcastPkts;
856  //ipIfStatsInMcastOctets object?
857  else if(!strcmp(object->name, "ipIfStatsInMcastOctets"))
858  value->counter32 = entry->ipIfStatsInMcastOctets;
859  //ipIfStatsHCInMcastOctets object?
860  else if(!strcmp(object->name, "ipIfStatsHCInMcastOctets"))
861  value->counter64 = entry->ipIfStatsHCInMcastOctets;
862  //ipIfStatsOutMcastPkts object?
863  else if(!strcmp(object->name, "ipIfStatsOutMcastPkts"))
864  value->counter32 = entry->ipIfStatsOutMcastPkts;
865  //ipIfStatsHCOutMcastPkts object?
866  else if(!strcmp(object->name, "ipIfStatsHCOutMcastPkts"))
867  value->counter64 = entry->ipIfStatsHCOutMcastPkts;
868  //ipIfStatsOutMcastOctets object?
869  else if(!strcmp(object->name, "ipIfStatsOutMcastOctets"))
870  value->counter32 = entry->ipIfStatsOutMcastOctets;
871  //ipIfStatsHCOutMcastOctets object?
872  else if(!strcmp(object->name, "ipIfStatsHCOutMcastOctets"))
873  value->counter64 = entry->ipIfStatsHCOutMcastOctets;
874  //ipIfStatsInBcastPkts object?
875  else if(!strcmp(object->name, "ipIfStatsInBcastPkts"))
876  value->counter32 = entry->ipIfStatsInBcastPkts;
877  //ipIfStatsHCInBcastPkts object?
878  else if(!strcmp(object->name, "ipIfStatsHCInBcastPkts"))
879  value->counter64 = entry->ipIfStatsHCInBcastPkts;
880  //ipIfStatsOutBcastPkts object?
881  else if(!strcmp(object->name, "ipIfStatsOutBcastPkts"))
882  value->counter32 = entry->ipIfStatsOutBcastPkts;
883  //ipIfStatsHCOutBcastPkts object?
884  else if(!strcmp(object->name, "ipIfStatsHCOutBcastPkts"))
885  value->counter64 = entry->ipIfStatsHCOutBcastPkts;
886  //ipIfStatsDiscontinuityTime object?
887  else if(!strcmp(object->name, "ipIfStatsDiscontinuityTime"))
888  value->timeTicks = entry->ipIfStatsDiscontinuityTime;
889  //ipIfStatsRefreshRate object?
890  else if(!strcmp(object->name, "ipIfStatsRefreshRate"))
891  value->unsigned32 = entry->ipIfStatsRefreshRate;
892  //Unknown object?
893  else
894  error = ERROR_OBJECT_NOT_FOUND;
895  }
896  else
897  {
898  //Report an error
899  error = ERROR_INSTANCE_NOT_FOUND;
900  }
901 
902  //Return status code
903  return error;
904 }
905 
906 
907 /**
908  * @brief Get next ipIfStatsEntry object
909  * @param[in] object Pointer to the MIB object descriptor
910  * @param[in] oid Object identifier
911  * @param[in] oidLen Length of the OID, in bytes
912  * @param[out] nextOid OID of the next object in the MIB
913  * @param[out] nextOidLen Length of the next object identifier, in bytes
914  * @return Error code
915  **/
916 
917 error_t ipMibGetNextIpIfStatsEntry(const MibObject *object, const uint8_t *oid,
918  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
919 {
920  error_t error;
921  size_t n;
922  uint_t version;
923  uint_t index;
924 
925  //Make sure the buffer is large enough to hold the OID prefix
926  if(*nextOidLen < object->oidLen)
927  return ERROR_BUFFER_OVERFLOW;
928 
929  //Copy OID prefix
930  memcpy(nextOid, object->oid, object->oidLen);
931 
932  //IP version-neutral table
934  {
935 #if (IPV4_SUPPORT == DISABLED)
936  //IPv4 version?
938  {
939  //IPv4 is not implemented
940  continue;
941  }
942 #endif
943 #if (IPV6_SUPPORT == DISABLED)
944  //IPv6 version?
946  {
947  //IPv6 is not implemented
948  continue;
949  }
950 #endif
951 
952  //Loop through network interfaces
953  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
954  {
955  //Append the instance identifier to the OID prefix
956  n = object->oidLen;
957 
958  //ipIfStatsIPVersion is used as 1st instance identifier
959  error = mibEncodeIndex(nextOid, *nextOidLen, &n, version);
960  //Any error to report?
961  if(error)
962  return error;
963 
964  //ipIfStatsIfIndex is used as 2nd instance identifier
965  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
966  //Any error to report?
967  if(error)
968  return error;
969 
970  //Check whether the resulting object identifier lexicographically
971  //follows the specified OID
972  if(oidComp(nextOid, n, oid, oidLen) > 0)
973  {
974  //Save the length of the resulting object identifier
975  *nextOidLen = n;
976  //Next object found
977  return NO_ERROR;
978  }
979  }
980  }
981 
982  //The specified OID does not lexicographically precede the name
983  //of some object
984  return ERROR_OBJECT_NOT_FOUND;
985 }
986 
987 
988 /**
989  * @brief Get ipAddressPrefixEntry object value
990  * @param[in] object Pointer to the MIB object descriptor
991  * @param[in] oid Object identifier (object name and instance identifier)
992  * @param[in] oidLen Length of the OID, in bytes
993  * @param[out] value Object value
994  * @param[in,out] valueLen Length of the object value, in bytes
995  * @return Error code
996  **/
997 
998 error_t ipMibGetIpAddressPrefixEntry(const MibObject *object, const uint8_t *oid,
999  size_t oidLen, MibVariant *value, size_t *valueLen)
1000 {
1001  error_t error;
1002  uint_t i;
1003  size_t n;
1004  uint_t index;
1005  IpAddr prefix;
1006  uint32_t prefixLen;
1007  NetInterface *interface;
1008 
1009  //Point to the instance identifier
1010  n = object->oidLen;
1011 
1012  //ipAddressPrefixIfIndex is used as 1st instance identifier
1013  error = mibDecodeIndex(oid, oidLen, &n, &index);
1014  //Invalid instance identifier?
1015  if(error)
1016  return error;
1017 
1018  //ipAddressPrefixType and ipAddressPrefixPrefix are used as
1019  //2nd and 3rd instance identifiers
1020  error = mibDecodeIpAddr(oid, oidLen, &n, &prefix);
1021  //Invalid instance identifier?
1022  if(error)
1023  return error;
1024 
1025  //ipAddressPrefixLength is used as 4th instance identifier
1026  error = mibDecodeUnsigned32(oid, oidLen, &n, &prefixLen);
1027  //Invalid instance identifier?
1028  if(error)
1029  return error;
1030 
1031  //Sanity check
1032  if(n != oidLen)
1033  return ERROR_INSTANCE_NOT_FOUND;
1034 
1035  //Check index range
1036  if(index < 1 || index > NET_INTERFACE_COUNT)
1037  return ERROR_INSTANCE_NOT_FOUND;
1038 
1039  //Point to the underlying interface
1040  interface = &netInterface[index - 1];
1041 
1042 #if (IPV4_SUPPORT == ENABLED)
1043  //IPv4 prefix?
1044  if(prefix.length == sizeof(Ipv4Addr))
1045  {
1046  Ipv4AddrEntry *entry;
1047 
1048  //Loop through the list of IPv4 addresses assigned to the interface
1049  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
1050  {
1051  //Point to the current entry
1052  entry = &interface->ipv4Context.addrList[i];
1053 
1054  //Valid IPv4 address?
1055  if(entry->state == IPV4_ADDR_STATE_VALID)
1056  {
1057  //Compare prefix length against the specified value
1059  {
1060  //Check subnet mask
1061  if((entry->addr & entry->subnetMask) == prefix.ipv4Addr)
1062  {
1063  break;
1064  }
1065  }
1066  }
1067  }
1068 
1069  //Any matching entry found?
1070  if(i < IPV4_ADDR_LIST_SIZE)
1071  {
1072  //ipAddressPrefixOrigin object?
1073  if(!strcmp(object->name, "ipAddressPrefixOrigin"))
1074  {
1075  //The origin of this prefix
1077  }
1078  //ipAddressPrefixOnLinkFlag object?
1079  else if(!strcmp(object->name, "ipAddressPrefixOnLinkFlag"))
1080  {
1081  //This flag indicates whether this prefix can be used for on-link
1082  //determination
1083  value->integer = MIB_TRUTH_VALUE_TRUE;
1084  }
1085  //ipAddressPrefixAutonomousFlag object?
1086  else if(!strcmp(object->name, "ipAddressPrefixAutonomousFlag"))
1087  {
1088  //This flag indicates whether this prefix can be used for autonomous
1089  //address configuration
1090  value->integer = MIB_TRUTH_VALUE_FALSE;
1091  }
1092  //ipAddressPrefixAdvPreferredLifetime object?
1093  else if(!strcmp(object->name, "ipAddressPrefixAdvPreferredLifetime"))
1094  {
1095  //Remaining length of time, in seconds, that this prefix will
1096  //continue to be preferred
1097  value->unsigned32 = UINT32_MAX;
1098  }
1099  //ipAddressPrefixAdvValidLifetime object?
1100  else if(!strcmp(object->name, "ipAddressPrefixAdvValidLifetime"))
1101  {
1102  //Remaining length of time, in seconds, that this prefix will
1103  //continue to be valid
1104  value->unsigned32 = UINT32_MAX;
1105  }
1106  //Unknown object?
1107  else
1108  {
1109  //The specified object does not exist
1110  error = ERROR_OBJECT_NOT_FOUND;
1111  }
1112  }
1113  else
1114  {
1115  //Report an error
1116  error = ERROR_INSTANCE_NOT_FOUND;
1117  }
1118  }
1119  else
1120 #endif
1121 #if (IPV6_SUPPORT == ENABLED)
1122  //IPv6 prefix?
1123  if(prefix.length == sizeof(Ipv6Addr))
1124  {
1125  Ipv6PrefixEntry *entry;
1126 
1127  //Loop through the IPv6 prefix list
1128  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
1129  {
1130  //Point to the current entry
1131  entry = &interface->ipv6Context.prefixList[i];
1132 
1133  //Check whether the prefix is valid
1134  if(entry->validLifetime > 0)
1135  {
1136  //Compare prefix length against the specified value
1137  if(entry->prefixLen == prefixLen)
1138  {
1139  //Check whether the current entry matches the specified prefix
1140  if(ipv6CompPrefix(&entry->prefix, &prefix.ipv6Addr, prefixLen))
1141  {
1142  break;
1143  }
1144  }
1145  }
1146  }
1147 
1148  //Any matching entry found?
1149  if(i < IPV6_PREFIX_LIST_SIZE)
1150  {
1151  //ipAddressPrefixOrigin object?
1152  if(!strcmp(object->name, "ipAddressPrefixOrigin"))
1153  {
1154  //The origin of this prefix
1155  if(entry->permanent)
1157  else
1159  }
1160  //ipAddressPrefixOnLinkFlag object?
1161  else if(!strcmp(object->name, "ipAddressPrefixOnLinkFlag"))
1162  {
1163  //This flag indicates whether this prefix can be used for on-link
1164  //determination
1165  if(entry->onLinkFlag)
1166  value->integer = MIB_TRUTH_VALUE_TRUE;
1167  else
1168  value->integer = MIB_TRUTH_VALUE_FALSE;
1169  }
1170  //ipAddressPrefixAutonomousFlag object?
1171  else if(!strcmp(object->name, "ipAddressPrefixAutonomousFlag"))
1172  {
1173  //This flag indicates whether this prefix can be used for autonomous
1174  //address configuration
1175  if(entry->autonomousFlag)
1176  value->integer = MIB_TRUTH_VALUE_TRUE;
1177  else
1178  value->integer = MIB_TRUTH_VALUE_FALSE;
1179  }
1180  //ipAddressPrefixAdvPreferredLifetime object?
1181  else if(!strcmp(object->name, "ipAddressPrefixAdvPreferredLifetime"))
1182  {
1183  //Remaining length of time, in seconds, that this prefix will
1184  //continue to be preferred
1185  if(entry->preferredLifetime == INFINITE_DELAY)
1186  value->unsigned32 = UINT32_MAX;
1187  else
1188  value->unsigned32 = entry->preferredLifetime / 1000;
1189  }
1190  //ipAddressPrefixAdvValidLifetime object?
1191  else if(!strcmp(object->name, "ipAddressPrefixAdvValidLifetime"))
1192  {
1193  //Remaining length of time, in seconds, that this prefix will
1194  //continue to be valid
1195  if(entry->validLifetime == INFINITE_DELAY)
1196  value->unsigned32 = UINT32_MAX;
1197  else
1198  value->unsigned32 = entry->validLifetime / 1000;
1199  }
1200  //Unknown object?
1201  else
1202  {
1203  //The specified object does not exist
1204  error = ERROR_OBJECT_NOT_FOUND;
1205  }
1206  }
1207  else
1208  {
1209  //Report an error
1210  error = ERROR_INSTANCE_NOT_FOUND;
1211  }
1212  }
1213  else
1214 #endif
1215  //Invalid prefix?
1216  {
1217  //Report an error
1218  error = ERROR_INSTANCE_NOT_FOUND;
1219  }
1220 
1221  //Return status code
1222  return error;
1223 }
1224 
1225 
1226 /**
1227  * @brief Get next ipAddressPrefixEntry object
1228  * @param[in] object Pointer to the MIB object descriptor
1229  * @param[in] oid Object identifier
1230  * @param[in] oidLen Length of the OID, in bytes
1231  * @param[out] nextOid OID of the next object in the MIB
1232  * @param[out] nextOidLen Length of the next object identifier, in bytes
1233  * @return Error code
1234  **/
1235 
1237  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
1238 {
1239  error_t error;
1240  uint_t i;
1241  size_t n;
1242  uint_t index;
1243  uint_t curIndex;
1244  uint_t length;
1245  uint_t curLength;
1246  bool_t acceptable;
1247  IpAddr prefix;
1248  IpAddr curPrefix;
1249  NetInterface *interface;
1250 
1251  //Initialize variables
1252  index = 0;
1254  length = 0;
1255 
1256  //Make sure the buffer is large enough to hold the OID prefix
1257  if(*nextOidLen < object->oidLen)
1258  return ERROR_BUFFER_OVERFLOW;
1259 
1260  //Copy OID prefix
1261  memcpy(nextOid, object->oid, object->oidLen);
1262 
1263 #if (IPV4_SUPPORT == ENABLED)
1264  //Loop through network interfaces
1265  for(curIndex = 1; curIndex <= NET_INTERFACE_COUNT; curIndex++)
1266  {
1267  Ipv4AddrEntry *entry;
1268 
1269  //Point to the current interface
1270  interface = &netInterface[curIndex - 1];
1271 
1272  //Loop through the list of IPv4 addresses assigned to the interface
1273  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
1274  {
1275  //Point to the current entry
1276  entry = &interface->ipv4Context.addrList[i];
1277 
1278  //Valid subnet mask?
1279  if(entry->state == IPV4_ADDR_STATE_VALID &&
1281  {
1282  //Retrieve current prefix
1283  curPrefix.length = sizeof(Ipv4Addr);
1284  curPrefix.ipv4Addr = entry->addr & entry->subnetMask;
1285  curLength = ipv4GetPrefixLength(entry->subnetMask);
1286 
1287  //Append the instance identifier to the OID prefix
1288  n = object->oidLen;
1289 
1290  //ipAddressPrefixIfIndex is used as 1st instance identifier
1291  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curIndex);
1292  //Any error to report?
1293  if(error)
1294  return error;
1295 
1296  //ipAddressPrefixType and ipAddressPrefixPrefix are used as
1297  //2nd and 3rd instance identifiers
1298  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curPrefix);
1299  //Invalid instance identifier?
1300  if(error)
1301  return error;
1302 
1303  //ipAddressPrefixLength is used as 4th instance identifier
1304  error = mibEncodeUnsigned32(nextOid, *nextOidLen, &n, curLength);
1305  //Any error to report?
1306  if(error)
1307  return error;
1308 
1309  //Check whether the resulting object identifier lexicographically
1310  //follows the specified OID
1311  if(oidComp(nextOid, n, oid, oidLen) > 0)
1312  {
1313  //Perform lexicographic comparison
1314  if(index == 0)
1315  acceptable = TRUE;
1316  else if(curIndex < index)
1317  acceptable = TRUE;
1318  else if(curIndex > index)
1319  acceptable = FALSE;
1320  else if(mibCompIpAddr(&curPrefix, &prefix) < 0)
1321  acceptable = TRUE;
1322  else if(mibCompIpAddr(&curPrefix, &prefix) > 0)
1323  acceptable = FALSE;
1324  else if(curLength < length)
1325  acceptable = TRUE;
1326  else
1327  acceptable = FALSE;
1328 
1329  //Save the closest object identifier that follows the specified
1330  //OID in lexicographic order
1331  if(acceptable)
1332  {
1333  index = curIndex;
1334  prefix = curPrefix;
1335  length = curLength;
1336  }
1337  }
1338  }
1339  }
1340  }
1341 #endif
1342 
1343 #if (IPV6_SUPPORT == ENABLED)
1344  //Loop through network interfaces
1345  for(curIndex = 1; curIndex <= NET_INTERFACE_COUNT; curIndex++)
1346  {
1347  Ipv6PrefixEntry *entry;
1348 
1349  //Point to the current interface
1350  interface = &netInterface[curIndex - 1];
1351 
1352  //Loop through the IPv6 prefix list
1353  for(i = 0; i < IPV6_PREFIX_LIST_SIZE; i++)
1354  {
1355  //Point to the current entry
1356  entry = &interface->ipv6Context.prefixList[i];
1357 
1358  //Check whether the prefix is valid
1359  if(entry->validLifetime > 0)
1360  {
1361  //Retrieve current prefix
1362  curPrefix.length = sizeof(Ipv6Addr);
1363  curPrefix.ipv6Addr = entry->prefix;
1364  curLength = entry->prefixLen;
1365 
1366  //Append the instance identifier to the OID prefix
1367  n = object->oidLen;
1368 
1369  //ipAddressPrefixIfIndex is used as 1st instance identifier
1370  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curIndex);
1371  //Any error to report?
1372  if(error)
1373  return error;
1374 
1375  //ipAddressPrefixType and ipAddressPrefixPrefix are used as
1376  //2nd and 3rd instance identifiers
1377  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curPrefix);
1378  //Invalid instance identifier?
1379  if(error)
1380  return error;
1381 
1382  //ipAddressPrefixLength is used as 4th instance identifier
1383  error = mibEncodeUnsigned32(nextOid, *nextOidLen, &n, curLength);
1384  //Any error to report?
1385  if(error)
1386  return error;
1387 
1388  //Check whether the resulting object identifier lexicographically
1389  //follows the specified OID
1390  if(oidComp(nextOid, n, oid, oidLen) > 0)
1391  {
1392  //Perform lexicographic comparison
1393  if(index == 0)
1394  acceptable = TRUE;
1395  else if(curIndex < index)
1396  acceptable = TRUE;
1397  else if(curIndex > index)
1398  acceptable = FALSE;
1399  else if(mibCompIpAddr(&curPrefix, &prefix) < 0)
1400  acceptable = TRUE;
1401  else if(mibCompIpAddr(&curPrefix, &prefix) > 0)
1402  acceptable = FALSE;
1403  else if(curLength < length)
1404  acceptable = TRUE;
1405  else
1406  acceptable = FALSE;
1407 
1408  //Save the closest object identifier that follows the specified
1409  //OID in lexicographic order
1410  if(acceptable)
1411  {
1412  index = curIndex;
1413  prefix = curPrefix;
1414  length = curLength;
1415  }
1416  }
1417  }
1418  }
1419  }
1420 #endif
1421 
1422  //The specified OID does not lexicographically precede the name
1423  //of some object?
1424  if(index == 0)
1425  return ERROR_OBJECT_NOT_FOUND;
1426 
1427  //Append the instance identifier to the OID prefix
1428  n = object->oidLen;
1429 
1430  //ipAddressPrefixIfIndex is used as 1st instance identifier
1431  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
1432  //Any error to report?
1433  if(error)
1434  return error;
1435 
1436  //ipAddressPrefixType and ipAddressPrefixPrefix are used as
1437  //2nd and 3rd instance identifiers
1438  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &prefix);
1439  //Invalid instance identifier?
1440  if(error)
1441  return error;
1442 
1443  //ipAddressPrefixLength is used as 4th instance identifier
1444  error = mibEncodeUnsigned32(nextOid, *nextOidLen, &n, length);
1445  //Any error to report?
1446  if(error)
1447  return error;
1448 
1449  //Save the length of the resulting object identifier
1450  *nextOidLen = n;
1451  //Next object found
1452  return NO_ERROR;
1453 }
1454 
1455 
1456 /**
1457  * @brief Set ipAddressSpinLock object value
1458  * @param[in] object Pointer to the MIB object descriptor
1459  * @param[in] oid Object identifier (object name and instance identifier)
1460  * @param[in] oidLen Length of the OID, in bytes
1461  * @param[in] value Object value
1462  * @param[in] valueLen Length of the object value, in bytes
1463  * @param[in] commit This flag tells whether the changes shall be committed
1464  * to the MIB base
1465  * @return Error code
1466  **/
1467 
1468 error_t ipMibSetIpAddressSpinLock(const MibObject *object, const uint8_t *oid,
1469  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
1470 {
1471  //Test and increment spin lock
1473  value->integer, commit);
1474 }
1475 
1476 
1477 /**
1478  * @brief Get ipAddressSpinLock object value
1479  * @param[in] object Pointer to the MIB object descriptor
1480  * @param[in] oid Object identifier (object name and instance identifier)
1481  * @param[in] oidLen Length of the OID, in bytes
1482  * @param[out] value Object value
1483  * @param[in,out] valueLen Length of the object value, in bytes
1484  * @return Error code
1485  **/
1486 
1487 error_t ipMibGetIpAddressSpinLock(const MibObject *object, const uint8_t *oid,
1488  size_t oidLen, MibVariant *value, size_t *valueLen)
1489 {
1490  //Get the current value of the spin lock
1491  value->integer = ipMibBase.ipAddressSpinLock;
1492 
1493  //Return status code
1494  return NO_ERROR;
1495 }
1496 
1497 
1498 /**
1499  * @brief Set ipAddressEntry object value
1500  * @param[in] object Pointer to the MIB object descriptor
1501  * @param[in] oid Object identifier (object name and instance identifier)
1502  * @param[in] oidLen Length of the OID, in bytes
1503  * @param[in] value Object value
1504  * @param[in] valueLen Length of the object value, in bytes
1505  * @param[in] commit This flag tells whether the changes shall be committed
1506  * to the MIB base
1507  * @return Error code
1508  **/
1509 
1510 error_t ipMibSetIpAddressEntry(const MibObject *object, const uint8_t *oid,
1511  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
1512 {
1513  //Not implemented
1514  return ERROR_WRITE_FAILED;
1515 }
1516 
1517 
1518 /**
1519  * @brief Get ipAddressEntry object value
1520  * @param[in] object Pointer to the MIB object descriptor
1521  * @param[in] oid Object identifier (object name and instance identifier)
1522  * @param[in] oidLen Length of the OID, in bytes
1523  * @param[out] value Object value
1524  * @param[in,out] valueLen Length of the object value, in bytes
1525  * @return Error code
1526  **/
1527 
1528 error_t ipMibGetIpAddressEntry(const MibObject *object, const uint8_t *oid,
1529  size_t oidLen, MibVariant *value, size_t *valueLen)
1530 {
1531  error_t error;
1532  uint_t i;
1533  size_t n;
1534  uint_t index;
1535  IpAddr ipAddr;
1536  NetInterface *interface;
1537 
1538  //Point to the instance identifier
1539  n = object->oidLen;
1540 
1541  //ipAddressAddrType and ipAddressAddr are used as instance identifiers
1542  error = mibDecodeIpAddr(oid, oidLen, &n, &ipAddr);
1543  //Invalid instance identifier?
1544  if(error)
1545  return error;
1546 
1547  //Sanity check
1548  if(n != oidLen)
1549  return ERROR_INSTANCE_NOT_FOUND;
1550 
1551 #if (IPV4_SUPPORT == ENABLED)
1552  //IPv4 address?
1553  if(ipAddr.length == sizeof(Ipv4Addr))
1554  {
1555  Ipv4AddrEntry *entry;
1556 
1557  //Loop through network interfaces
1558  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
1559  {
1560  //Point to the current interface
1561  interface = &netInterface[index - 1];
1562 
1563  //Loop through the list of IPv4 addresses assigned to the interface
1564  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
1565  {
1566  //Point to the current entry
1567  entry = &interface->ipv4Context.addrList[i];
1568 
1569  //Compare the current address against the IP address used as
1570  //instance identifier
1571  if(entry->state == IPV4_ADDR_STATE_VALID &&
1572  entry->addr == ipAddr.ipv4Addr)
1573  {
1574  break;
1575  }
1576  }
1577 
1578  //IPv4 address found?
1579  if(i < IPV4_ADDR_LIST_SIZE)
1580  break;
1581  }
1582 
1583  //IPv4 address found?
1584  if(index <= NET_INTERFACE_COUNT)
1585  {
1586  //ipAddressIfIndex object?
1587  if(!strcmp(object->name, "ipAddressIfIndex"))
1588  {
1589  //Index value that uniquely identifies the interface to which
1590  //this entry is applicable
1591  value->integer = index;
1592  }
1593  //ipAddressType object?
1594  else if(!strcmp(object->name, "ipAddressType"))
1595  {
1596  //Type of IP address
1597  value->integer = IP_MIB_ADDR_TYPE_UNICAST;
1598  }
1599  //ipAddressPrefix object?
1600  else if(!strcmp(object->name, "ipAddressPrefix"))
1601  {
1602  IpAddr prefix;
1603  uint_t length;
1604 
1605  //OID of the ipAddressPrefixOrigin object
1606  const uint8_t ipAddressPrefixOriginOid[] = {43, 6, 1, 2, 1, 4, 32, 1, 5};
1607 
1608  //Retrieve current prefix
1609  prefix.length = sizeof(Ipv4Addr);
1610  prefix.ipv4Addr = entry->addr & entry->subnetMask;
1612 
1613  //Build a pointer to the row in the prefix table to which this
1614  //address belongs
1615  n = sizeof(ipAddressPrefixOriginOid);
1616 
1617  //Make sure the buffer is large enough to hold the OID prefix
1618  if(*valueLen < n)
1619  return ERROR_BUFFER_OVERFLOW;
1620 
1621  //Copy OID prefix
1622  memcpy(value->oid, ipAddressPrefixOriginOid, n);
1623 
1624  //ipAddressPrefixIfIndex is used as 1st instance identifier
1625  error = mibEncodeIndex(value->oid, *valueLen, &n, index);
1626  //Any error to report?
1627  if(error)
1628  return error;
1629 
1630  //ipAddressPrefixType and ipAddressPrefixPrefix are used as
1631  //2nd and 3rd instance identifiers
1632  error = mibEncodeIpAddr(value->oid, *valueLen, &n, &prefix);
1633  //Invalid instance identifier?
1634  if(error)
1635  return error;
1636 
1637  //ipAddressPrefixLength is used as 4th instance identifier
1638  error = mibEncodeUnsigned32(value->oid, *valueLen, &n, length);
1639  //Any error to report?
1640  if(error)
1641  return error;
1642 
1643  //Return object length
1644  *valueLen = n;
1645  }
1646  //ipAddressOrigin object?
1647  else if(!strcmp(object->name, "ipAddressOrigin"))
1648  {
1649 #if (AUTO_IP_SUPPORT == ENABLED)
1650  //Address chosen by the system at random?
1651  if(interface->autoIpContext != NULL &&
1652  interface->autoIpContext->running)
1653  {
1654  //Origin of the address
1655  value->integer = IP_MIB_ADDR_ORIGIN_RANDOM;
1656  }
1657  else
1658 #endif
1659 #if (DHCP_CLIENT_SUPPORT == ENABLED)
1660  //Address assigned to this system by a DHCP server?
1661  if(interface->dhcpClientContext != NULL &&
1662  interface->dhcpClientContext->running)
1663  {
1664  //Origin of the address
1665  value->integer = IP_MIB_ADDR_ORIGIN_DHCP;
1666  }
1667  else
1668 #endif
1669  //Manually configured address?
1670  {
1671  //Origin of the address
1672  value->integer = IP_MIB_ADDR_ORIGIN_MANUAL;
1673  }
1674  }
1675  //ipAddressStatus object?
1676  else if(!strcmp(object->name, "ipAddressStatus"))
1677  {
1678  //Status of the IP address
1679  if(entry->state == IPV4_ADDR_STATE_VALID)
1681  else if(entry->state == IPV4_ADDR_STATE_TENTATIVE)
1683  else
1684  value->integer = IP_MIB_ADDR_STATUS_UNKNOWN;
1685  }
1686  //ipAddressCreated object?
1687  else if(!strcmp(object->name, "ipAddressCreated"))
1688  {
1689  //Get object value
1690  value->timeTicks = 0;
1691  }
1692  //ipAddressLastChanged object?
1693  else if(!strcmp(object->name, "ipAddressLastChanged"))
1694  {
1695  //Get object value
1696  value->timeTicks = 0;
1697  }
1698  //ipAddressRowStatus object?
1699  else if(!strcmp(object->name, "ipAddressRowStatus"))
1700  {
1701  //Get object value
1702  value->integer = MIB_ROW_STATUS_ACTIVE;
1703  }
1704  //ipAddressStorageType object?
1705  else if(!strcmp(object->name, "ipAddressStorageType"))
1706  {
1707  //Get object value
1708  value->integer = MIB_STORAGE_TYPE_VOLATILE;
1709  }
1710  //Unknown object?
1711  else
1712  {
1713  //The specified object does not exist
1714  error = ERROR_OBJECT_NOT_FOUND;
1715  }
1716  }
1717  else
1718  {
1719  //Report an error
1720  error = ERROR_INSTANCE_NOT_FOUND;
1721  }
1722  }
1723  else
1724 #endif
1725 #if (IPV6_SUPPORT == ENABLED)
1726  //IPv6 address?
1727  if(ipAddr.length == sizeof(Ipv6Addr))
1728  {
1729  Ipv6AddrEntry *entry;
1730 
1731  //Loop through network interfaces
1732  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
1733  {
1734  //Point to the current interface
1735  interface = &netInterface[index - 1];
1736 
1737  //Loop through the list of IPv6 addresses assigned to the interface
1738  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
1739  {
1740  //Point to the current entry
1741  entry = &interface->ipv6Context.addrList[i];
1742 
1743  //Compare the current address against the IP address used as
1744  //instance identifier
1745  if(entry->state != IPV6_ADDR_STATE_INVALID &&
1746  ipv6CompAddr(&entry->addr, &ipAddr.ipv6Addr))
1747  {
1748  break;
1749  }
1750  }
1751 
1752  //IPv6 address found?
1753  if(i < IPV6_ADDR_LIST_SIZE)
1754  break;
1755  }
1756 
1757  //IPv6 address found?
1758  if(index <= NET_INTERFACE_COUNT)
1759  {
1760  //ipAddressIfIndex object?
1761  if(!strcmp(object->name, "ipAddressIfIndex"))
1762  {
1763  //Index value that uniquely identifies the interface to which
1764  //this entry is applicable
1765  value->integer = index;
1766  }
1767  //ipAddressType object?
1768  else if(!strcmp(object->name, "ipAddressType"))
1769  {
1770  //Type of IP address
1771  value->integer = IP_MIB_ADDR_TYPE_UNICAST;
1772  }
1773  //ipAddressPrefix object?
1774  else if(!strcmp(object->name, "ipAddressPrefix"))
1775  {
1776  //Unknown OID
1777  const uint8_t unknownOid[] = {0};
1778 
1779  //Make sure the buffer is large enough to hold the OID prefix
1780  if(*valueLen < sizeof(unknownOid))
1781  return ERROR_BUFFER_OVERFLOW;
1782 
1783  //Copy OID prefix
1784  memcpy(value->oid, unknownOid, sizeof(unknownOid));
1785  //Return object length
1786  *valueLen = sizeof(unknownOid);
1787  }
1788  //ipAddressOrigin object?
1789  else if(!strcmp(object->name, "ipAddressOrigin"))
1790  {
1791  //Origin of the address
1792  value->integer = IP_MIB_ADDR_ORIGIN_MANUAL;
1793  }
1794  //ipAddressStatus object?
1795  else if(!strcmp(object->name, "ipAddressStatus"))
1796  {
1797  //Status of the IP address
1798  if(entry->state == IPV6_ADDR_STATE_PREFERRED)
1800  else if(entry->state == IPV6_ADDR_STATE_DEPRECATED)
1802  else if(entry->state == IPV6_ADDR_STATE_TENTATIVE)
1804  else
1805  value->integer = IP_MIB_ADDR_STATUS_UNKNOWN;
1806  }
1807  //ipAddressCreated object?
1808  else if(!strcmp(object->name, "ipAddressCreated"))
1809  {
1810  //Get object value
1811  value->timeTicks = 0;
1812  }
1813  //ipAddressLastChanged object?
1814  else if(!strcmp(object->name, "ipAddressLastChanged"))
1815  {
1816  //Get object value
1817  value->timeTicks = 0;
1818  }
1819  //ipAddressRowStatus object?
1820  else if(!strcmp(object->name, "ipAddressRowStatus"))
1821  {
1822  //Get object value
1823  value->integer = MIB_ROW_STATUS_ACTIVE;
1824  }
1825  //ipAddressStorageType object?
1826  else if(!strcmp(object->name, "ipAddressStorageType"))
1827  {
1828  //Get object value
1829  value->integer = MIB_STORAGE_TYPE_VOLATILE;
1830  }
1831  //Unknown object?
1832  else
1833  {
1834  //The specified object does not exist
1835  error = ERROR_OBJECT_NOT_FOUND;
1836  }
1837  }
1838  else
1839  {
1840  //Report an error
1841  error = ERROR_INSTANCE_NOT_FOUND;
1842  }
1843  }
1844  else
1845 #endif
1846  //Invalid IP address?
1847  {
1848  //Report an error
1849  error = ERROR_INSTANCE_NOT_FOUND;
1850  }
1851 
1852  //Return status code
1853  return error;
1854 }
1855 
1856 
1857 /**
1858  * @brief Get next ipAddressEntry object
1859  * @param[in] object Pointer to the MIB object descriptor
1860  * @param[in] oid Object identifier
1861  * @param[in] oidLen Length of the OID, in bytes
1862  * @param[out] nextOid OID of the next object in the MIB
1863  * @param[out] nextOidLen Length of the next object identifier, in bytes
1864  * @return Error code
1865  **/
1866 
1867 error_t ipMibGetNextIpAddressEntry(const MibObject *object, const uint8_t *oid,
1868  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
1869 {
1870  error_t error;
1871  uint_t i;
1872  size_t n;
1873  uint_t index;
1874  bool_t acceptable;
1875  IpAddr ipAddr;
1876  IpAddr curIpAddr;
1877  NetInterface *interface;
1878 
1879  //Initialize variable
1881 
1882  //Make sure the buffer is large enough to hold the OID prefix
1883  if(*nextOidLen < object->oidLen)
1884  return ERROR_BUFFER_OVERFLOW;
1885 
1886  //Copy OID prefix
1887  memcpy(nextOid, object->oid, object->oidLen);
1888 
1889 #if (IPV4_SUPPORT == ENABLED)
1890  //Loop through network interfaces
1891  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
1892  {
1893  Ipv4AddrEntry *entry;
1894 
1895  //Point to the current interface
1896  interface = &netInterface[index - 1];
1897 
1898  //Loop through the list of IPv4 addresses assigned to the interface
1899  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
1900  {
1901  //Point to the current entry
1902  entry = &interface->ipv4Context.addrList[i];
1903 
1904  //Valid IPv4 address?
1905  if(entry->state == IPV4_ADDR_STATE_VALID)
1906  {
1907  //Get current address
1908  curIpAddr.length = sizeof(Ipv4Addr);
1909  curIpAddr.ipv4Addr = entry->addr;
1910 
1911  //Append the instance identifier to the OID prefix
1912  n = object->oidLen;
1913 
1914  //ipAddressAddrType and ipAddressAddr are used as instance identifiers
1915  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curIpAddr);
1916  //Any error to report?
1917  if(error)
1918  return error;
1919 
1920  //Check whether the resulting object identifier lexicographically
1921  //follows the specified OID
1922  if(oidComp(nextOid, n, oid, oidLen) > 0)
1923  {
1924  //Perform lexicographic comparison
1925  if(ipAddr.length == 0)
1926  acceptable = TRUE;
1927  else if(mibCompIpAddr(&curIpAddr, &ipAddr) < 0)
1928  acceptable = TRUE;
1929  else
1930  acceptable = FALSE;
1931 
1932  //Save the closest object identifier that follows the specified
1933  //OID in lexicographic order
1934  if(acceptable)
1935  ipAddr = curIpAddr;
1936  }
1937  }
1938  }
1939  }
1940 #endif
1941 
1942 #if (IPV6_SUPPORT == ENABLED)
1943  //Loop through network interfaces
1944  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
1945  {
1946  Ipv6AddrEntry *entry;
1947 
1948  //Point to the current interface
1949  interface = &netInterface[index - 1];
1950 
1951  //Loop through the list of IPv6 addresses assigned to the interface
1952  for(i = 0; i < IPV6_ADDR_LIST_SIZE; i++)
1953  {
1954  //Point to the current entry
1955  entry = &interface->ipv6Context.addrList[i];
1956 
1957  //Valid IPv6 address?
1958  if(entry->state != IPV6_ADDR_STATE_INVALID)
1959  {
1960  //Get current address
1961  curIpAddr.length = sizeof(Ipv6Addr);
1962  curIpAddr.ipv6Addr = entry->addr;
1963 
1964  //Append the instance identifier to the OID prefix
1965  n = object->oidLen;
1966 
1967  //ipAddressAddrType and ipAddressAddr are used as instance identifiers
1968  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curIpAddr);
1969  //Any error to report?
1970  if(error)
1971  return error;
1972 
1973  //Check whether the resulting object identifier lexicographically
1974  //follows the specified OID
1975  if(oidComp(nextOid, n, oid, oidLen) > 0)
1976  {
1977  //Perform lexicographic comparison
1978  if(ipAddr.length == 0)
1979  acceptable = TRUE;
1980  else if(mibCompIpAddr(&curIpAddr, &ipAddr) < 0)
1981  acceptable = TRUE;
1982  else
1983  acceptable = FALSE;
1984 
1985  //Save the closest object identifier that follows the specified
1986  //OID in lexicographic order
1987  if(acceptable)
1988  ipAddr = curIpAddr;
1989  }
1990  }
1991  }
1992  }
1993 #endif
1994 
1995  //The specified OID does not lexicographically precede the name
1996  //of some object?
1997  if(ipAddr.length == 0)
1998  return ERROR_OBJECT_NOT_FOUND;
1999 
2000  //Append the instance identifier to the OID prefix
2001  n = object->oidLen;
2002 
2003  //ipAddressAddrType and ipAddressAddr are used as instance identifiers
2004  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &ipAddr);
2005  //Any error to report?
2006  if(error)
2007  return error;
2008 
2009  //Save the length of the resulting object identifier
2010  *nextOidLen = n;
2011  //Next object found
2012  return NO_ERROR;
2013 }
2014 
2015 
2016 /**
2017  * @brief Set ipNetToPhysicalEntry object value
2018  * @param[in] object Pointer to the MIB object descriptor
2019  * @param[in] oid Object identifier (object name and instance identifier)
2020  * @param[in] oidLen Length of the OID, in bytes
2021  * @param[in] value Object value
2022  * @param[in] valueLen Length of the object value, in bytes
2023  * @param[in] commit This flag tells whether the changes shall be committed
2024  * to the MIB base
2025  * @return Error code
2026  **/
2027 
2028 error_t ipMibSetIpNetToPhysicalEntry(const MibObject *object, const uint8_t *oid,
2029  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
2030 {
2031  //Not implemented
2032  return ERROR_WRITE_FAILED;
2033 }
2034 
2035 
2036 /**
2037  * @brief Get ipNetToPhysicalEntry object value
2038  * @param[in] object Pointer to the MIB object descriptor
2039  * @param[in] oid Object identifier (object name and instance identifier)
2040  * @param[in] oidLen Length of the OID, in bytes
2041  * @param[out] value Object value
2042  * @param[in,out] valueLen Length of the object value, in bytes
2043  * @return Error code
2044  **/
2045 
2046 error_t ipMibGetIpNetToPhysicalEntry(const MibObject *object, const uint8_t *oid,
2047  size_t oidLen, MibVariant *value, size_t *valueLen)
2048 {
2049  error_t error;
2050  size_t n;
2051  uint_t index;
2052  IpAddr ipAddr;
2053  NetInterface *interface;
2054 
2055  //Point to the instance identifier
2056  n = object->oidLen;
2057 
2058  //ipNetToPhysicalIfIndex is used as 1st instance identifier
2059  error = mibDecodeIndex(oid, oidLen, &n, &index);
2060  //Invalid instance identifier?
2061  if(error)
2062  return error;
2063 
2064  //ipNetToPhysicalNetAddressType and ipNetToPhysicalNetAddress are
2065  //used as 2nd and 3rd instance identifiers
2066  error = mibDecodeIpAddr(oid, oidLen, &n, &ipAddr);
2067  //Invalid instance identifier?
2068  if(error)
2069  return error;
2070 
2071  //Sanity check
2072  if(n != oidLen)
2073  return ERROR_INSTANCE_NOT_FOUND;
2074 
2075  //Check index range
2076  if(index < 1 || index > NET_INTERFACE_COUNT)
2077  return ERROR_INSTANCE_NOT_FOUND;
2078 
2079  //Point to the network interface
2080  interface = &netInterface[index - 1];
2081 
2082 #if (IPV4_SUPPORT == ENABLED)
2083  //IPv4 address?
2084  if(ipAddr.length == sizeof(Ipv4Addr))
2085  {
2086  ArpCacheEntry *entry;
2087 
2088  //Search the ARP cache for the specified IPv4 address
2089  entry = arpFindEntry(interface, ipAddr.ipv4Addr);
2090 
2091  //Check whether a matching entry has been found
2092  if(entry != NULL)
2093  {
2094  //ipNetToPhysicalPhysAddress object?
2095  if(!strcmp(object->name, "ipNetToPhysicalPhysAddress"))
2096  {
2097  //Make sure the buffer is large enough to hold the entire object
2098  if(*valueLen >= sizeof(MacAddr))
2099  {
2100  //Copy object value
2101  macCopyAddr(value->octetString, &entry->macAddr);
2102  //Return object length
2103  *valueLen = sizeof(MacAddr);
2104  }
2105  else
2106  {
2107  //Report an error
2108  error = ERROR_BUFFER_OVERFLOW;
2109  }
2110  }
2111  //ipNetToPhysicalLastUpdated object?
2112  else if(!strcmp(object->name, "ipNetToPhysicalLastUpdated"))
2113  {
2114  //Get object value
2115  value->timeTicks = entry->timestamp / 10;
2116  }
2117  //ipNetToPhysicalType object?
2118  else if(!strcmp(object->name, "ipNetToPhysicalType"))
2119  {
2120  //Get object value
2122  }
2123  //ipNetToPhysicalState object?
2124  else if(!strcmp(object->name, "ipNetToPhysicalState"))
2125  {
2126  //Get object value
2128  }
2129  //ipNetToPhysicalRowStatus object?
2130  else if(!strcmp(object->name, "ipNetToPhysicalRowStatus"))
2131  {
2132  //Get object value
2133  value->integer = MIB_ROW_STATUS_ACTIVE;
2134  }
2135  //Unknown object?
2136  else
2137  {
2138  //The specified object does not exist
2139  error = ERROR_OBJECT_NOT_FOUND;
2140  }
2141  }
2142  else
2143  {
2144  //Report an error
2145  error = ERROR_INSTANCE_NOT_FOUND;
2146  }
2147  }
2148  else
2149 #endif
2150 #if (IPV6_SUPPORT == ENABLED)
2151  //IPv6 address?
2152  if(ipAddr.length == sizeof(Ipv6Addr))
2153  {
2154  NdpNeighborCacheEntry *entry;
2155 
2156  //Search the Neighbor cache for the specified IPv6 address
2157  entry = ndpFindNeighborCacheEntry(interface, &ipAddr.ipv6Addr);
2158 
2159  //Check whether a matching entry has been found
2160  if(entry != NULL)
2161  {
2162  //ipNetToPhysicalPhysAddress object?
2163  if(!strcmp(object->name, "ipNetToPhysicalPhysAddress"))
2164  {
2165  //Make sure the buffer is large enough to hold the entire object
2166  if(*valueLen >= sizeof(MacAddr))
2167  {
2168  //Copy object value
2169  macCopyAddr(value->octetString, &entry->macAddr);
2170  //Return object length
2171  *valueLen = sizeof(MacAddr);
2172  }
2173  else
2174  {
2175  //Report an error
2176  error = ERROR_BUFFER_OVERFLOW;
2177  }
2178  }
2179  //ipNetToPhysicalLastUpdated object?
2180  else if(!strcmp(object->name, "ipNetToPhysicalLastUpdated"))
2181  {
2182  //Get object value
2183  value->timeTicks = entry->timestamp / 10;
2184  }
2185  //ipNetToPhysicalType object?
2186  else if(!strcmp(object->name, "ipNetToPhysicalType"))
2187  {
2188  //Get object value
2190  }
2191  //ipNetToPhysicalState object?
2192  else if(!strcmp(object->name, "ipNetToPhysicalState"))
2193  {
2194  //Get object value
2195  if(entry->state == NDP_STATE_INCOMPLETE)
2197  else if(entry->state == NDP_STATE_REACHABLE)
2199  else if(entry->state == NDP_STATE_STALE)
2201  else if(entry->state == NDP_STATE_DELAY)
2203  else if(entry->state == NDP_STATE_PROBE)
2205  else
2207  }
2208  //ipNetToPhysicalRowStatus object?
2209  else if(!strcmp(object->name, "ipNetToPhysicalRowStatus"))
2210  {
2211  //Get object value
2212  value->integer = MIB_ROW_STATUS_ACTIVE;
2213  }
2214  //Unknown object?
2215  else
2216  {
2217  //The specified object does not exist
2218  error = ERROR_OBJECT_NOT_FOUND;
2219  }
2220  }
2221  else
2222  {
2223  //Report an error
2224  error = ERROR_INSTANCE_NOT_FOUND;
2225  }
2226  }
2227  else
2228 #endif
2229  //Invalid IP address?
2230  {
2231  //Report an error
2232  error = ERROR_INSTANCE_NOT_FOUND;
2233  }
2234 
2235  //Return status code
2236  return error;
2237 }
2238 
2239 
2240 /**
2241  * @brief Get next ipNetToPhysicalEntry object
2242  * @param[in] object Pointer to the MIB object descriptor
2243  * @param[in] oid Object identifier
2244  * @param[in] oidLen Length of the OID, in bytes
2245  * @param[out] nextOid OID of the next object in the MIB
2246  * @param[out] nextOidLen Length of the next object identifier, in bytes
2247  * @return Error code
2248  **/
2249 
2251  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
2252 {
2253  error_t error;
2254  uint_t i;
2255  size_t n;
2256  uint_t index;
2257  uint_t curIndex;
2258  bool_t acceptable;
2259  IpAddr ipAddr;
2260  IpAddr curIpAddr;
2261  NetInterface *interface;
2262 
2263  //Initialize variables
2264  index = 0;
2266 
2267  //Make sure the buffer is large enough to hold the OID prefix
2268  if(*nextOidLen < object->oidLen)
2269  return ERROR_BUFFER_OVERFLOW;
2270 
2271  //Copy OID prefix
2272  memcpy(nextOid, object->oid, object->oidLen);
2273 
2274  //Loop through network interfaces
2275  for(curIndex = 1; curIndex <= NET_INTERFACE_COUNT; curIndex++)
2276  {
2277  //Point to the current interface
2278  interface = &netInterface[curIndex - 1];
2279 
2280 #if (IPV4_SUPPORT == ENABLED)
2281  //Loop through ARP cache entries
2282  for(i = 0; i < ARP_CACHE_SIZE; i++)
2283  {
2284  ArpCacheEntry *entry;
2285 
2286  //Point to the current entry
2287  entry = &interface->arpCache[i];
2288 
2289  //Valid entry?
2290  if(entry->state != ARP_STATE_NONE)
2291  {
2292  //Get current IP address
2293  curIpAddr.length = sizeof(Ipv4Addr);
2294  curIpAddr.ipv4Addr = entry->ipAddr;
2295 
2296  //Append the instance identifier to the OID prefix
2297  n = object->oidLen;
2298 
2299  //ipNetToPhysicalIfIndex is used as 1st instance identifier
2300  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curIndex);
2301  //Any error to report?
2302  if(error)
2303  return error;
2304 
2305  //ipNetToPhysicalNetAddressType and ipNetToPhysicalNetAddress are
2306  //used as 2nd and 3rd instance identifiers
2307  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curIpAddr);
2308  //Any error to report?
2309  if(error)
2310  return error;
2311 
2312  //Check whether the resulting object identifier lexicographically
2313  //follows the specified OID
2314  if(oidComp(nextOid, n, oid, oidLen) > 0)
2315  {
2316  //Perform lexicographic comparison
2317  if(index == 0)
2318  acceptable = TRUE;
2319  else if(curIndex < index)
2320  acceptable = TRUE;
2321  else if(curIndex > index)
2322  acceptable = FALSE;
2323  else if(mibCompIpAddr(&curIpAddr, &ipAddr) < 0)
2324  acceptable = TRUE;
2325  else
2326  acceptable = FALSE;
2327 
2328  //Save the closest object identifier that follows the specified
2329  //OID in lexicographic order
2330  if(acceptable)
2331  {
2332  index = curIndex;
2333  ipAddr = curIpAddr;
2334  }
2335  }
2336  }
2337  }
2338 #endif
2339 
2340 #if (IPV6_SUPPORT == ENABLED)
2341  //Loop through Neighbor cache entries
2342  for(i = 0; i < NDP_NEIGHBOR_CACHE_SIZE; i++)
2343  {
2344  NdpNeighborCacheEntry *entry;
2345 
2346  //Point to the current entry
2347  entry = &interface->ndpContext.neighborCache[i];
2348 
2349  //Valid entry?
2350  if(entry->state != NDP_STATE_NONE)
2351  {
2352  //Get current IP address
2353  curIpAddr.length = sizeof(Ipv6Addr);
2354  curIpAddr.ipv6Addr = entry->ipAddr;
2355 
2356  //Append the instance identifier to the OID prefix
2357  n = object->oidLen;
2358 
2359  //ipNetToPhysicalIfIndex is used as 1st instance identifier
2360  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curIndex);
2361  //Any error to report?
2362  if(error)
2363  return error;
2364 
2365  //ipNetToPhysicalNetAddressType and ipNetToPhysicalNetAddress are
2366  //used as 2nd and 3rd instance identifiers
2367  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curIpAddr);
2368  //Any error to report?
2369  if(error)
2370  return error;
2371 
2372  //Check whether the resulting object identifier lexicographically
2373  //follows the specified OID
2374  if(oidComp(nextOid, n, oid, oidLen) > 0)
2375  {
2376  //Perform lexicographic comparison
2377  if(index == 0)
2378  acceptable = TRUE;
2379  else if(curIndex < index)
2380  acceptable = TRUE;
2381  else if(curIndex > index)
2382  acceptable = FALSE;
2383  else if(mibCompIpAddr(&curIpAddr, &ipAddr) < 0)
2384  acceptable = TRUE;
2385  else
2386  acceptable = FALSE;
2387 
2388  //Save the closest object identifier that follows the specified
2389  //OID in lexicographic order
2390  if(acceptable)
2391  {
2392  index = curIndex;
2393  ipAddr = curIpAddr;
2394  }
2395  }
2396  }
2397  }
2398 #endif
2399  }
2400 
2401  //The specified OID does not lexicographically precede the name
2402  //of some object?
2403  if(index == 0)
2404  return ERROR_OBJECT_NOT_FOUND;
2405 
2406  //Append the instance identifier to the OID prefix
2407  n = object->oidLen;
2408 
2409  //ipNetToPhysicalIfIndex is used as 1st instance identifier
2410  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
2411  //Any error to report?
2412  if(error)
2413  return error;
2414 
2415  //ipNetToPhysicalNetAddressType and ipNetToPhysicalNetAddress are
2416  //used as 2nd and 3rd instance identifiers
2417  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &ipAddr);
2418  //Any error to report?
2419  if(error)
2420  return error;
2421 
2422  //Save the length of the resulting object identifier
2423  *nextOidLen = n;
2424  //Next object found
2425  return NO_ERROR;
2426 }
2427 
2428 
2429 /**
2430  * @brief Get ipv6ScopeZoneIndexEntry object value
2431  * @param[in] object Pointer to the MIB object descriptor
2432  * @param[in] oid Object identifier (object name and instance identifier)
2433  * @param[in] oidLen Length of the OID, in bytes
2434  * @param[out] value Object value
2435  * @param[in,out] valueLen Length of the object value, in bytes
2436  * @return Error code
2437  **/
2438 
2440  size_t oidLen, MibVariant *value, size_t *valueLen)
2441 {
2442  error_t error;
2443  size_t n;
2444  uint_t index;
2445 
2446  //Point to the instance identifier
2447  n = object->oidLen;
2448 
2449  //ipv6ScopeZoneIndexIfIndex is used as instance identifier
2450  error = mibDecodeIndex(oid, oidLen, &n, &index);
2451  //Invalid instance identifier?
2452  if(error)
2453  return error;
2454 
2455  //Sanity check
2456  if(n != oidLen)
2457  return ERROR_INSTANCE_NOT_FOUND;
2458 
2459  //Check index range
2460  if(index < 1 || index > NET_INTERFACE_COUNT)
2461  return ERROR_INSTANCE_NOT_FOUND;
2462 
2463  //ipv6ScopeZoneIndexLinkLocal object?
2464  if(!strcmp(object->name, "ipv6ScopeZoneIndexLinkLocal"))
2465  value->unsigned32 = index;
2466  //ipv6ScopeZoneIndex3 object?
2467  else if(!strcmp(object->name, "ipv6ScopeZoneIndex3"))
2468  value->unsigned32 = 0;
2469  //ipv6ScopeZoneIndexAdminLocal object?
2470  else if(!strcmp(object->name, "ipv6ScopeZoneIndexAdminLocal"))
2471  value->unsigned32 = 0;
2472  //ipv6ScopeZoneIndexSiteLocal object?
2473  else if(!strcmp(object->name, "ipv6ScopeZoneIndexSiteLocal"))
2474  value->unsigned32 = 0;
2475  //ipv6ScopeZoneIndex6 object?
2476  else if(!strcmp(object->name, "ipv6ScopeZoneIndex6"))
2477  value->unsigned32 = 0;
2478  //ipv6ScopeZoneIndex7 object?
2479  else if(!strcmp(object->name, "ipv6ScopeZoneIndex7"))
2480  value->unsigned32 = 0;
2481  //ipv6ScopeZoneIndexOrganizationLocal object?
2482  else if(!strcmp(object->name, "ipv6ScopeZoneIndexOrganizationLocal"))
2483  value->unsigned32 = 0;
2484  //ipv6ScopeZoneIndex9 object?
2485  else if(!strcmp(object->name, "ipv6ScopeZoneIndex9"))
2486  value->unsigned32 = 0;
2487  //ipv6ScopeZoneIndexA object?
2488  else if(!strcmp(object->name, "ipv6ScopeZoneIndexA"))
2489  value->unsigned32 = 0;
2490  //ipv6ScopeZoneIndexB object?
2491  else if(!strcmp(object->name, "ipv6ScopeZoneIndexB"))
2492  value->unsigned32 = 0;
2493  //ipv6ScopeZoneIndexC object?
2494  else if(!strcmp(object->name, "ipv6ScopeZoneIndexC"))
2495  value->unsigned32 = 0;
2496  //ipv6ScopeZoneIndexD object?
2497  else if(!strcmp(object->name, "ipv6ScopeZoneIndexD"))
2498  value->unsigned32 = 0;
2499  //Unknown object?
2500  else
2501  error = ERROR_OBJECT_NOT_FOUND;
2502 
2503  //Return status code
2504  return error;
2505 }
2506 
2507 
2508 /**
2509  * @brief Get next ipv6ScopeZoneIndexEntry object
2510  * @param[in] object Pointer to the MIB object descriptor
2511  * @param[in] oid Object identifier
2512  * @param[in] oidLen Length of the OID, in bytes
2513  * @param[out] nextOid OID of the next object in the MIB
2514  * @param[out] nextOidLen Length of the next object identifier, in bytes
2515  * @return Error code
2516  **/
2517 
2519  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
2520 {
2521  error_t error;
2522  size_t n;
2523  uint_t index;
2524 
2525  //Make sure the buffer is large enough to hold the OID prefix
2526  if(*nextOidLen < object->oidLen)
2527  return ERROR_BUFFER_OVERFLOW;
2528 
2529  //Copy OID prefix
2530  memcpy(nextOid, object->oid, object->oidLen);
2531 
2532  //Loop through network interfaces
2533  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
2534  {
2535  //Append the instance identifier to the OID prefix
2536  n = object->oidLen;
2537 
2538  //ipv6ScopeZoneIndexIfIndex is used as instance identifier
2539  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
2540  //Any error to report?
2541  if(error)
2542  return error;
2543 
2544  //Check whether the resulting object identifier lexicographically
2545  //follows the specified OID
2546  if(oidComp(nextOid, n, oid, oidLen) > 0)
2547  {
2548  //Save the length of the resulting object identifier
2549  *nextOidLen = n;
2550  //Next object found
2551  return NO_ERROR;
2552  }
2553  }
2554 
2555  //The specified OID does not lexicographically precede the name
2556  //of some object
2557  return ERROR_OBJECT_NOT_FOUND;
2558 }
2559 
2560 
2561 /**
2562  * @brief Get ipDefaultRouterEntry object value
2563  * @param[in] object Pointer to the MIB object descriptor
2564  * @param[in] oid Object identifier (object name and instance identifier)
2565  * @param[in] oidLen Length of the OID, in bytes
2566  * @param[out] value Object value
2567  * @param[in,out] valueLen Length of the object value, in bytes
2568  * @return Error code
2569  **/
2570 
2571 error_t ipMibGetIpDefaultRouterEntry(const MibObject *object, const uint8_t *oid,
2572  size_t oidLen, MibVariant *value, size_t *valueLen)
2573 {
2574  error_t error;
2575  uint_t i;
2576  size_t n;
2577  uint_t index;
2578  IpAddr ipAddr;
2579  NetInterface *interface;
2580 
2581  //Point to the instance identifier
2582  n = object->oidLen;
2583 
2584  //ipDefaultRouterAddress and ipDefaultRouterAddressType are used
2585  //as 1st and 2nd instance identifiers
2586  error = mibDecodeIpAddr(oid, oidLen, &n, &ipAddr);
2587  //Invalid instance identifier?
2588  if(error)
2589  return error;
2590 
2591  //ipDefaultRouterIfIndex is used as 3rd instance identifier
2592  error = mibDecodeIndex(oid, oidLen, &n, &index);
2593  //Invalid instance identifier?
2594  if(error)
2595  return error;
2596 
2597  //Sanity check
2598  if(n != oidLen)
2599  return ERROR_INSTANCE_NOT_FOUND;
2600 
2601  //Check index range
2602  if(index < 1 || index > NET_INTERFACE_COUNT)
2603  return ERROR_INSTANCE_NOT_FOUND;
2604 
2605  //Point to the network interface
2606  interface = &netInterface[index - 1];
2607 
2608 #if (IPV4_SUPPORT == ENABLED)
2609  //IPv4 address?
2610  if(ipAddr.length == sizeof(Ipv4Addr))
2611  {
2612  Ipv4AddrEntry *entry;
2613 
2614  //Loop through the list of default gateways
2615  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
2616  {
2617  //Point to the current entry
2618  entry = &interface->ipv4Context.addrList[i];
2619 
2620  //Check whether the specified IPv4 address matches any default gateway
2621  if(entry->state == IPV4_ADDR_STATE_VALID &&
2622  entry->defaultGateway != ipAddr.ipv4Addr)
2623  {
2624  break;
2625  }
2626  }
2627 
2628  //Valid gateway address?
2629  if(i <= IPV4_ADDR_LIST_SIZE)
2630  {
2631  //ipDefaultRouterLifetime object?
2632  if(!strcmp(object->name, "ipDefaultRouterLifetime"))
2633  {
2634  //Get object value
2635  value->unsigned32 = UINT16_MAX;
2636  }
2637  //ipDefaultRouterPreference object?
2638  else if(!strcmp(object->name, "ipDefaultRouterPreference"))
2639  {
2640  //Get object value
2641  value->integer = 0;
2642  }
2643  //Unknown object?
2644  else
2645  {
2646  //The specified object does not exist
2647  error = ERROR_OBJECT_NOT_FOUND;
2648  }
2649  }
2650  else
2651  {
2652  //Report an error
2653  error = ERROR_INSTANCE_NOT_FOUND;
2654  }
2655  }
2656  else
2657 #endif
2658 #if (IPV6_SUPPORT == ENABLED)
2659  //IPv6 address?
2660  if(ipAddr.length == sizeof(Ipv6Addr))
2661  {
2662  Ipv6RouterEntry *entry;
2663 
2664  //Loop through the Default Router List
2665  for(i = 0; i < IPV6_ROUTER_LIST_SIZE; i++)
2666  {
2667  //Point to the current entry
2668  entry = &interface->ipv6Context.routerList[i];
2669 
2670  //Check the lifetime associated with the default router
2671  if(entry->lifetime)
2672  {
2673  //Check whether the specified IPv6 address matches any default router
2674  if(ipv6CompAddr(&entry->addr, &ipAddr.ipv6Addr))
2675  {
2676  break;
2677  }
2678  }
2679  }
2680 
2681  //Valid router address?
2682  if(i <= IPV6_ROUTER_LIST_SIZE)
2683  {
2684  //ipDefaultRouterLifetime object?
2685  if(!strcmp(object->name, "ipDefaultRouterLifetime"))
2686  {
2687  //Get object value
2688  if(entry->lifetime == INFINITE_DELAY)
2689  value->unsigned32 = UINT16_MAX;
2690  else
2691  value->unsigned32 = entry->lifetime / 1000;
2692  }
2693  //ipDefaultRouterPreference object?
2694  else if(!strcmp(object->name, "ipDefaultRouterPreference"))
2695  {
2696  //Get object value
2699  else if(entry->preference == NDP_ROUTER_SEL_PREFERENCE_MEDIUM)
2701  else if(entry->preference == NDP_ROUTER_SEL_PREFERENCE_HIGH)
2703  else
2705  }
2706  //Unknown object?
2707  else
2708  {
2709  //The specified object does not exist
2710  error = ERROR_OBJECT_NOT_FOUND;
2711  }
2712  }
2713  else
2714  {
2715  //Report an error
2716  error = ERROR_INSTANCE_NOT_FOUND;
2717  }
2718  }
2719  else
2720 #endif
2721  //Invalid IP address?
2722  {
2723  //Report an error
2724  error = ERROR_INSTANCE_NOT_FOUND;
2725  }
2726 
2727  //Return status code
2728  return error;
2729 }
2730 
2731 
2732 /**
2733  * @brief Get next ipDefaultRouterEntry object
2734  * @param[in] object Pointer to the MIB object descriptor
2735  * @param[in] oid Object identifier
2736  * @param[in] oidLen Length of the OID, in bytes
2737  * @param[out] nextOid OID of the next object in the MIB
2738  * @param[out] nextOidLen Length of the next object identifier, in bytes
2739  * @return Error code
2740  **/
2741 
2743  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
2744 {
2745  error_t error;
2746  uint_t i;
2747  size_t n;
2748  uint_t index;
2749  uint_t curIndex;
2750  bool_t acceptable;
2751  IpAddr ipAddr;
2752  IpAddr curIpAddr;
2753  NetInterface *interface;
2754 
2755  //Initialize variables
2756  index = 0;
2758 
2759  //Make sure the buffer is large enough to hold the OID prefix
2760  if(*nextOidLen < object->oidLen)
2761  return ERROR_BUFFER_OVERFLOW;
2762 
2763  //Copy OID prefix
2764  memcpy(nextOid, object->oid, object->oidLen);
2765 
2766 #if (IPV4_SUPPORT == ENABLED)
2767  //Loop through network interfaces
2768  for(curIndex = 1; curIndex <= NET_INTERFACE_COUNT; curIndex++)
2769  {
2770  Ipv4AddrEntry *entry;
2771 
2772  //Point to the current interface
2773  interface = &netInterface[curIndex - 1];
2774 
2775  //Loop through the list of default gateways
2776  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
2777  {
2778  //Point to the current entry
2779  entry = &interface->ipv4Context.addrList[i];
2780 
2781  //Check whether the gateway address is valid
2782  if(entry->state == IPV4_ADDR_STATE_VALID &&
2784  {
2785  //Get the IP address of the default gateway
2786  curIpAddr.length = sizeof(Ipv4Addr);
2787  curIpAddr.ipv4Addr = entry->defaultGateway;
2788 
2789  //Append the instance identifier to the OID prefix
2790  n = object->oidLen;
2791 
2792  //ipDefaultRouterAddress and ipDefaultRouterAddressType are
2793  //used as 1st and 2nd instance identifiers
2794  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curIpAddr);
2795  //Any error to report?
2796  if(error)
2797  return error;
2798 
2799  //ipDefaultRouterIfIndex is used as 3rd instance identifier
2800  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curIndex);
2801  //Any error to report?
2802  if(error)
2803  return error;
2804 
2805  //Check whether the resulting object identifier lexicographically
2806  //follows the specified OID
2807  if(oidComp(nextOid, n, oid, oidLen) > 0)
2808  {
2809  //Perform lexicographic comparison
2810  if(index == 0)
2811  acceptable = TRUE;
2812  else if(mibCompIpAddr(&curIpAddr, &ipAddr) < 0)
2813  acceptable = TRUE;
2814  else if(mibCompIpAddr(&curIpAddr, &ipAddr) > 0)
2815  acceptable = FALSE;
2816  else if(curIndex < index)
2817  acceptable = TRUE;
2818  else
2819  acceptable = FALSE;
2820 
2821  //Save the closest object identifier that follows the specified
2822  //OID in lexicographic order
2823  if(acceptable)
2824  {
2825  index = curIndex;
2826  ipAddr = curIpAddr;
2827  }
2828  }
2829  }
2830  }
2831  }
2832 #endif
2833 
2834 #if (IPV6_SUPPORT == ENABLED)
2835  //Loop through network interfaces
2836  for(curIndex = 1; curIndex <= NET_INTERFACE_COUNT; curIndex++)
2837  {
2838  Ipv6RouterEntry *entry;
2839 
2840  //Point to the current interface
2841  interface = &netInterface[curIndex - 1];
2842 
2843  //Loop through the Default Router List
2844  for(i = 0; i < IPV6_ROUTER_LIST_SIZE; i++)
2845  {
2846  //Point to the current entry
2847  entry = &interface->ipv6Context.routerList[i];
2848 
2849  //Check the lifetime associated with the default router
2850  if(entry->lifetime)
2851  {
2852  //Get the IP address of the default gateway
2853  curIpAddr.length = sizeof(Ipv6Addr);
2854  curIpAddr.ipv6Addr = entry->addr;
2855 
2856  //Append the instance identifier to the OID prefix
2857  n = object->oidLen;
2858 
2859  //ipDefaultRouterAddress and ipDefaultRouterAddressType are
2860  //used as 1st and 2nd instance identifiers
2861  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &curIpAddr);
2862  //Any error to report?
2863  if(error)
2864  return error;
2865 
2866  //ipDefaultRouterIfIndex is used as 3rd instance identifier
2867  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curIndex);
2868  //Any error to report?
2869  if(error)
2870  return error;
2871 
2872  //Check whether the resulting object identifier lexicographically
2873  //follows the specified OID
2874  if(oidComp(nextOid, n, oid, oidLen) > 0)
2875  {
2876  //Perform lexicographic comparison
2877  if(index == 0)
2878  acceptable = TRUE;
2879  else if(mibCompIpAddr(&curIpAddr, &ipAddr) < 0)
2880  acceptable = TRUE;
2881  else if(mibCompIpAddr(&curIpAddr, &ipAddr) > 0)
2882  acceptable = FALSE;
2883  else if(curIndex < index)
2884  acceptable = TRUE;
2885  else
2886  acceptable = FALSE;
2887 
2888  //Save the closest object identifier that follows the specified
2889  //OID in lexicographic order
2890  if(acceptable)
2891  {
2892  index = curIndex;
2893  ipAddr = curIpAddr;
2894  }
2895  }
2896  }
2897  }
2898  }
2899 #endif
2900 
2901  //The specified OID does not lexicographically precede the name
2902  //of some object?
2903  if(index == 0)
2904  return ERROR_OBJECT_NOT_FOUND;
2905 
2906  //Append the instance identifier to the OID prefix
2907  n = object->oidLen;
2908 
2909  //ipDefaultRouterAddress and ipDefaultRouterAddressType are
2910  //used as 1st and 2nd instance identifiers
2911  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &ipAddr);
2912  //Any error to report?
2913  if(error)
2914  return error;
2915 
2916  //ipDefaultRouterIfIndex is used as 3rd instance identifier
2917  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
2918  //Any error to report?
2919  if(error)
2920  return error;
2921 
2922  //Save the length of the resulting object identifier
2923  *nextOidLen = n;
2924  //Next object found
2925  return NO_ERROR;
2926 }
2927 
2928 
2929 /**
2930  * @brief Set ipv6RouterAdvertSpinLock object value
2931  * @param[in] object Pointer to the MIB object descriptor
2932  * @param[in] oid Object identifier (object name and instance identifier)
2933  * @param[in] oidLen Length of the OID, in bytes
2934  * @param[in] value Object value
2935  * @param[in] valueLen Length of the object value, in bytes
2936  * @param[in] commit This flag tells whether the changes shall be committed
2937  * to the MIB base
2938  * @return Error code
2939  **/
2940 
2942  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
2943 {
2944 #if (IPV6_SUPPORT == ENABLED)
2945  //Test and increment spin lock
2947  value->integer, commit);
2948 #else
2949  //Not implemented
2950  return ERROR_WRITE_FAILED;
2951 #endif
2952 }
2953 
2954 
2955 /**
2956  * @brief Get ipv6RouterAdvertSpinLock object value
2957  * @param[in] object Pointer to the MIB object descriptor
2958  * @param[in] oid Object identifier (object name and instance identifier)
2959  * @param[in] oidLen Length of the OID, in bytes
2960  * @param[out] value Object value
2961  * @param[in,out] valueLen Length of the object value, in bytes
2962  * @return Error code
2963  **/
2964 
2966  size_t oidLen, MibVariant *value, size_t *valueLen)
2967 {
2968 #if (IPV6_SUPPORT == ENABLED)
2969  //Get the current value of the spin lock
2971 
2972  //Return status code
2973  return NO_ERROR;
2974 #else
2975  //Not implemented
2976  return ERROR_OBJECT_NOT_FOUND;
2977 #endif
2978 }
2979 
2980 
2981 /**
2982  * @brief Set ipv6RouterAdvertEntry object value
2983  * @param[in] object Pointer to the MIB object descriptor
2984  * @param[in] oid Object identifier (object name and instance identifier)
2985  * @param[in] oidLen Length of the OID, in bytes
2986  * @param[in] value Object value
2987  * @param[in] valueLen Length of the object value, in bytes
2988  * @param[in] commit This flag tells whether the changes shall be committed
2989  * to the MIB base
2990  * @return Error code
2991  **/
2992 
2993 error_t ipMibSetIpv6RouterAdvertEntry(const MibObject *object, const uint8_t *oid,
2994  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
2995 {
2996  //Not implemented
2997  return ERROR_WRITE_FAILED;
2998 }
2999 
3000 
3001 /**
3002  * @brief Get ipv6RouterAdvertEntry object value
3003  * @param[in] object Pointer to the MIB object descriptor
3004  * @param[in] oid Object identifier (object name and instance identifier)
3005  * @param[in] oidLen Length of the OID, in bytes
3006  * @param[out] value Object value
3007  * @param[in,out] valueLen Length of the object value, in bytes
3008  * @return Error code
3009  **/
3010 
3011 error_t ipMibGetIpv6RouterAdvertEntry(const MibObject *object, const uint8_t *oid,
3012  size_t oidLen, MibVariant *value, size_t *valueLen)
3013 {
3014  error_t error;
3015 
3016 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED)
3017  size_t n;
3018  uint_t index;
3019  NdpRouterAdvContext *routerAdvContext;
3020 
3021  //Point to the instance identifier
3022  n = object->oidLen;
3023 
3024  //ipv6RouterAdvertIfIndex is used as instance identifier
3025  error = mibDecodeIndex(oid, oidLen, &n, &index);
3026  //Invalid instance identifier?
3027  if(error)
3028  return error;
3029 
3030  //Sanity check
3031  if(n != oidLen)
3032  return ERROR_INSTANCE_NOT_FOUND;
3033 
3034  //Check index range
3035  if(index < 1 || index > NET_INTERFACE_COUNT)
3036  return ERROR_INSTANCE_NOT_FOUND;
3037 
3038  //Point to the RA service context
3039  routerAdvContext = netInterface[index - 1].ndpRouterAdvContext;
3040 
3041  //Any RA service instantiated?
3042  if(routerAdvContext != NULL)
3043  {
3044  //ipv6RouterAdvertSendAdverts object?
3045  if(!strcmp(object->name, "ipv6RouterAdvertSendAdverts"))
3046  {
3047  //This flag indicates whether the router sends periodic router
3048  //advertisements and responds to router solicitations on this
3049  //interface
3050  if(routerAdvContext->running)
3051  value->integer = MIB_TRUTH_VALUE_TRUE;
3052  else
3053  value->integer = MIB_TRUTH_VALUE_FALSE;
3054  }
3055  //ipv6RouterAdvertMaxInterval object?
3056  else if(!strcmp(object->name, "ipv6RouterAdvertMaxInterval"))
3057  {
3058  //Maximum time allowed between sending unsolicited router
3059  //advertisements from this interface
3060  value->unsigned32 = routerAdvContext->settings.maxRtrAdvInterval;
3061  }
3062  //ipv6RouterAdvertMinInterval object?
3063  else if(!strcmp(object->name, "ipv6RouterAdvertMinInterval"))
3064  {
3065  //Minimum time allowed between sending unsolicited router
3066  //advertisements from this interface
3067  value->unsigned32 = routerAdvContext->settings.minRtrAdvInterval;
3068  }
3069  //ipv6RouterAdvertManagedFlag object?
3070  else if(!strcmp(object->name, "ipv6RouterAdvertManagedFlag"))
3071  {
3072  //Value to be placed into the Managed Address Configuration flag
3073  //field in router advertisements sent from this interface
3074  if(routerAdvContext->settings.managedFlag)
3075  value->integer = MIB_TRUTH_VALUE_TRUE;
3076  else
3077  value->integer = MIB_TRUTH_VALUE_FALSE;
3078  }
3079  //ipv6RouterAdvertOtherConfigFlag object?
3080  else if(!strcmp(object->name, "ipv6RouterAdvertOtherConfigFlag"))
3081  {
3082  //Value to be placed into the Other Configuration flag field in
3083  //router advertisements sent from this interface
3084  if(routerAdvContext->settings.otherConfigFlag)
3085  value->integer = MIB_TRUTH_VALUE_TRUE;
3086  else
3087  value->integer = MIB_TRUTH_VALUE_FALSE;
3088  }
3089  //ipv6RouterAdvertLinkMTU object?
3090  else if(!strcmp(object->name, "ipv6RouterAdvertLinkMTU"))
3091  {
3092  //Value to be placed in the MTU option sent by the router on this
3093  //interface
3094  value->unsigned32 = routerAdvContext->settings.linkMtu;
3095  }
3096  //ipv6RouterAdvertReachableTime object?
3097  else if(!strcmp(object->name, "ipv6RouterAdvertReachableTime"))
3098  {
3099  //Value to be placed in the Reachable Time field in router
3100  //advertisement messages sent from this interface
3101  value->unsigned32 = routerAdvContext->settings.reachableTime;
3102  }
3103  //ipv6RouterAdvertRetransmitTime object?
3104  else if(!strcmp(object->name, "ipv6RouterAdvertRetransmitTime"))
3105  {
3106  //Value to be placed in the Retrans Timer field in router
3107  //advertisements sent from this interface
3108  value->unsigned32 = routerAdvContext->settings.retransTimer;
3109  }
3110  //ipv6RouterAdvertCurHopLimit object?
3111  else if(!strcmp(object->name, "ipv6RouterAdvertCurHopLimit"))
3112  {
3113  //Value to be placed in the Cur Hop Limit field in router
3114  //advertisements sent from this interface
3115  value->unsigned32 = routerAdvContext->settings.curHopLimit;
3116  }
3117  //ipv6RouterAdvertDefaultLifetime object?
3118  else if(!strcmp(object->name, "ipv6RouterAdvertDefaultLifetime"))
3119  {
3120  //Value to be placed in the Router Lifetime field of router
3121  //advertisements sent from this interface
3122  value->unsigned32 = routerAdvContext->settings.defaultLifetime;
3123  }
3124  //ipv6RouterAdvertRowStatus object?
3125  else if(!strcmp(object->name, "ipv6RouterAdvertRowStatus"))
3126  {
3127  //Status of this conceptual row
3128  value->integer = MIB_ROW_STATUS_ACTIVE;
3129  }
3130  //Unknown object?
3131  else
3132  {
3133  //The specified object does not exist
3134  error = ERROR_OBJECT_NOT_FOUND;
3135  }
3136  }
3137  else
3138  {
3139  //Report an error
3140  error = ERROR_INSTANCE_NOT_FOUND;
3141  }
3142 #else
3143  //Not implemented
3144  error = ERROR_OBJECT_NOT_FOUND;
3145 #endif
3146 
3147  //Return status code
3148  return error;
3149 }
3150 
3151 
3152 /**
3153  * @brief Get next ipv6RouterAdvertEntry object
3154  * @param[in] object Pointer to the MIB object descriptor
3155  * @param[in] oid Object identifier
3156  * @param[in] oidLen Length of the OID, in bytes
3157  * @param[out] nextOid OID of the next object in the MIB
3158  * @param[out] nextOidLen Length of the next object identifier, in bytes
3159  * @return Error code
3160  **/
3161 
3163  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
3164 {
3165 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED)
3166  error_t error;
3167  size_t n;
3168  uint_t index;
3169 
3170  //Make sure the buffer is large enough to hold the OID prefix
3171  if(*nextOidLen < object->oidLen)
3172  return ERROR_BUFFER_OVERFLOW;
3173 
3174  //Copy OID prefix
3175  memcpy(nextOid, object->oid, object->oidLen);
3176 
3177  //Loop through network interfaces
3178  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
3179  {
3180  //Any RA service instantiated?
3181  if(netInterface[index - 1].ndpRouterAdvContext != NULL)
3182  {
3183  //Append the instance identifier to the OID prefix
3184  n = object->oidLen;
3185 
3186  //ipv6RouterAdvertIfIndex is used as instance identifier
3187  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
3188  //Any error to report?
3189  if(error)
3190  return error;
3191 
3192  //Check whether the resulting object identifier lexicographically
3193  //follows the specified OID
3194  if(oidComp(nextOid, n, oid, oidLen) > 0)
3195  {
3196  //Save the length of the resulting object identifier
3197  *nextOidLen = n;
3198  //Next object found
3199  return NO_ERROR;
3200  }
3201  }
3202  }
3203 #endif
3204 
3205  //The specified OID does not lexicographically precede the name
3206  //of some object
3207  return ERROR_OBJECT_NOT_FOUND;
3208 }
3209 
3210 
3211 /**
3212  * @brief Get icmpStatsEntry object value
3213  * @param[in] object Pointer to the MIB object descriptor
3214  * @param[in] oid Object identifier (object name and instance identifier)
3215  * @param[in] oidLen Length of the OID, in bytes
3216  * @param[out] value Object value
3217  * @param[in,out] valueLen Length of the object value, in bytes
3218  * @return Error code
3219  **/
3220 
3221 error_t ipMibGetIcmpStatsEntry(const MibObject *object, const uint8_t *oid,
3222  size_t oidLen, MibVariant *value, size_t *valueLen)
3223 {
3224  error_t error;
3225  size_t n;
3226  uint_t version;
3227  IpMibIcmpStatsEntry *entry;
3228 
3229  //Point to the instance identifier
3230  n = object->oidLen;
3231 
3232  //icmpStatsIPVersion is used as instance identifier
3233  error = mibDecodeIndex(oid, oidLen, &n, &version);
3234  //Invalid instance identifier?
3235  if(error)
3236  return error;
3237 
3238  //Sanity check
3239  if(n != oidLen)
3240  return ERROR_INSTANCE_NOT_FOUND;
3241 
3242 #if (IPV4_SUPPORT == ENABLED)
3243  //IPv4 version?
3244  if(version == INET_VERSION_IPV4)
3245  {
3246  //Point to the ICMP statistics table entry
3247  entry = &ipMibBase.icmpStats;
3248  }
3249  else
3250 #endif
3251 #if (IPV6_SUPPORT == ENABLED)
3252  //IPv6 version?
3253  if(version == INET_VERSION_IPV6)
3254  {
3255  //Point to the ICMPv6 statistics table entry
3256  entry = &ipMibBase.icmpv6Stats;
3257  }
3258  else
3259 #endif
3260  //Invalid IP version?
3261  {
3262  //No statistics available
3263  entry = NULL;
3264  }
3265 
3266  //Sanity check
3267  if(entry != NULL)
3268  {
3269  //icmpStatsInMsgs object?
3270  if(!strcmp(object->name, "icmpStatsInMsgs"))
3271  value->counter32 = entry->icmpStatsInMsgs;
3272  //icmpStatsInErrors object?
3273  else if(!strcmp(object->name, "icmpStatsInErrors"))
3274  value->counter32 = entry->icmpStatsInErrors;
3275  //icmpStatsOutMsgs object?
3276  else if(!strcmp(object->name, "icmpStatsOutMsgs"))
3277  value->counter32 = entry->icmpStatsOutMsgs;
3278  //icmpStatsOutErrors object?
3279  else if(!strcmp(object->name, "icmpStatsOutErrors"))
3280  value->counter32 = entry->icmpStatsOutErrors;
3281  //Unknown object?
3282  else
3283  error = ERROR_OBJECT_NOT_FOUND;
3284  }
3285  else
3286  {
3287  //Report an error
3288  error = ERROR_INSTANCE_NOT_FOUND;
3289  }
3290 
3291  //Return status code
3292  return error;
3293 }
3294 
3295 
3296 /**
3297  * @brief Get next icmpStatsEntry object
3298  * @param[in] object Pointer to the MIB object descriptor
3299  * @param[in] oid Object identifier
3300  * @param[in] oidLen Length of the OID, in bytes
3301  * @param[out] nextOid OID of the next object in the MIB
3302  * @param[out] nextOidLen Length of the next object identifier, in bytes
3303  * @return Error code
3304  **/
3305 
3306 error_t ipMibGetNextIcmpStatsEntry(const MibObject *object, const uint8_t *oid,
3307  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
3308 {
3309  error_t error;
3310  size_t n;
3311  uint_t version;
3312 
3313  //Make sure the buffer is large enough to hold the OID prefix
3314  if(*nextOidLen < object->oidLen)
3315  return ERROR_BUFFER_OVERFLOW;
3316 
3317  //Copy OID prefix
3318  memcpy(nextOid, object->oid, object->oidLen);
3319 
3320  //IP version-neutral table
3322  {
3323 #if (IPV4_SUPPORT == DISABLED)
3324  //IPv4 version?
3325  if(version == INET_VERSION_IPV4)
3326  {
3327  //IPv4 is not implemented
3328  continue;
3329  }
3330 #endif
3331 #if (IPV6_SUPPORT == DISABLED)
3332  //IPv6 version?
3333  if(version == INET_VERSION_IPV6)
3334  {
3335  //IPv6 is not implemented
3336  continue;
3337  }
3338 #endif
3339 
3340  //Append the instance identifier to the OID prefix
3341  n = object->oidLen;
3342 
3343  //ipSystemStatsIPVersion is used as instance identifier
3344  error = mibEncodeIndex(nextOid, *nextOidLen, &n, version);
3345  //Any error to report?
3346  if(error)
3347  return error;
3348 
3349  //Check whether the resulting object identifier lexicographically
3350  //follows the specified OID
3351  if(oidComp(nextOid, n, oid, oidLen) > 0)
3352  {
3353  //Save the length of the resulting object identifier
3354  *nextOidLen = n;
3355  //Next object found
3356  return NO_ERROR;
3357  }
3358  }
3359 
3360  //The specified OID does not lexicographically precede the name
3361  //of some object
3362  return ERROR_OBJECT_NOT_FOUND;
3363 }
3364 
3365 
3366 /**
3367  * @brief Get icmpMsgStatsEntry object value
3368  * @param[in] object Pointer to the MIB object descriptor
3369  * @param[in] oid Object identifier (object name and instance identifier)
3370  * @param[in] oidLen Length of the OID, in bytes
3371  * @param[out] value Object value
3372  * @param[in,out] valueLen Length of the object value, in bytes
3373  * @return Error code
3374  **/
3375 
3376 error_t ipMibGetIcmpMsgStatsEntry(const MibObject *object, const uint8_t *oid,
3377  size_t oidLen, MibVariant *value, size_t *valueLen)
3378 {
3379  error_t error;
3380  size_t n;
3381  uint_t version;
3382  uint_t type;
3383  IpMibIcmpMsgStatsEntry *entry;
3384 
3385  //Point to the instance identifier
3386  n = object->oidLen;
3387 
3388  //icmpMsgStatsIPVersion is used as 1st instance identifier
3389  error = mibDecodeIndex(oid, oidLen, &n, &version);
3390  //Invalid instance identifier?
3391  if(error)
3392  return error;
3393 
3394  //icmpMsgStatsType is used as 2nd instance identifier
3395  error = mibDecodeIndex(oid, oidLen, &n, &type);
3396  //Invalid instance identifier?
3397  if(error)
3398  return error;
3399 
3400  //Sanity check
3401  if(n != oidLen)
3402  return ERROR_INSTANCE_NOT_FOUND;
3403 
3404  //Check icmpMsgStatsType value
3405  if(type >= 256)
3406  return ERROR_INSTANCE_NOT_FOUND;
3407 
3408 #if (IPV4_SUPPORT == ENABLED)
3409  //IPv4 version?
3410  if(version == INET_VERSION_IPV4)
3411  {
3412  //Point to the ICMP message statistics table entry
3413  entry = &ipMibBase.icmpMsgStatsTable;
3414  }
3415  else
3416 #endif
3417 #if (IPV6_SUPPORT == ENABLED)
3418  //IPv6 version?
3419  if(version == INET_VERSION_IPV6)
3420  {
3421  //Point to the ICMPv6 message statistics table entry
3422  entry = &ipMibBase.icmpv6MsgStatsTable;
3423  }
3424  else
3425 #endif
3426  //Invalid IP version?
3427  {
3428  //No statistics available
3429  entry = NULL;
3430  }
3431 
3432  //Sanity check
3433  if(entry != NULL)
3434  {
3435  //icmpMsgStatsInPkts object?
3436  if(!strcmp(object->name, "icmpMsgStatsInPkts"))
3437  value->counter32 = entry->icmpMsgStatsInPkts[type];
3438  //icmpMsgStatsOutPkts object?
3439  else if(!strcmp(object->name, "icmpMsgStatsOutPkts"))
3440  value->counter32 = entry->icmpMsgStatsOutPkts[type];
3441  //Unknown object?
3442  else
3443  error = ERROR_OBJECT_NOT_FOUND;
3444  }
3445  else
3446  {
3447  //Report an error
3448  error = ERROR_INSTANCE_NOT_FOUND;
3449  }
3450 
3451  //Return status code
3452  return error;
3453 }
3454 
3455 
3456 /**
3457  * @brief Get next icmpMsgStatsEntry object
3458  * @param[in] object Pointer to the MIB object descriptor
3459  * @param[in] oid Object identifier
3460  * @param[in] oidLen Length of the OID, in bytes
3461  * @param[out] nextOid OID of the next object in the MIB
3462  * @param[out] nextOidLen Length of the next object identifier, in bytes
3463  * @return Error code
3464  **/
3465 
3466 error_t ipMibGetNextIcmpMsgStatsEntry(const MibObject *object, const uint8_t *oid,
3467  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
3468 {
3469  error_t error;
3470  size_t n;
3471  uint_t version;
3472  uint_t type;
3473  IpMibIcmpMsgStatsEntry *table;
3474 
3475  //Make sure the buffer is large enough to hold the OID prefix
3476  if(*nextOidLen < object->oidLen)
3477  return ERROR_BUFFER_OVERFLOW;
3478 
3479  //Copy OID prefix
3480  memcpy(nextOid, object->oid, object->oidLen);
3481 
3482  //IP version-neutral table
3484  {
3485 #if (IPV4_SUPPORT == ENABLED)
3486  //IPv4 version?
3487  if(version == INET_VERSION_IPV4)
3488  {
3489  //ICMP statistics table
3490  table = &ipMibBase.icmpMsgStatsTable;
3491  }
3492  else
3493 #endif
3494 #if (IPV6_SUPPORT == ENABLED)
3495  //IPv6 version?
3496  if(version == INET_VERSION_IPV6)
3497  {
3498  //ICMPv6 statistics table
3499  table = &ipMibBase.icmpv6MsgStatsTable;
3500  }
3501  else
3502 #endif
3503  //Invalid IP version?
3504  {
3505  //No statistics available
3506  table = NULL;
3507  }
3508 
3509  //Sanity check
3510  if(table != NULL)
3511  {
3512  //The system should track each ICMP type value
3513  for(type = 0; type < 256; type++)
3514  {
3515  //a given row need not be instantiated unless an ICMP message of
3516  //that type has been processed
3517  if(table->icmpMsgStatsInPkts[type] != 0 ||
3518  table->icmpMsgStatsOutPkts[type] != 0)
3519  {
3520  //Append the instance identifier to the OID prefix
3521  n = object->oidLen;
3522 
3523  //icmpMsgStatsIPVersion is used as 1st instance identifier
3524  error = mibEncodeIndex(nextOid, *nextOidLen, &n, version);
3525  //Any error to report?
3526  if(error)
3527  return error;
3528 
3529  //icmpMsgStatsType is used as 2nd instance identifier
3530  error = mibEncodeIndex(nextOid, *nextOidLen, &n, type);
3531  //Any error to report?
3532  if(error)
3533  return error;
3534 
3535  //Check whether the resulting object identifier lexicographically
3536  //follows the specified OID
3537  if(oidComp(nextOid, n, oid, oidLen) > 0)
3538  {
3539  //Save the length of the resulting object identifier
3540  *nextOidLen = n;
3541  //Next object found
3542  return NO_ERROR;
3543  }
3544  }
3545  }
3546  }
3547  }
3548 
3549  //The specified OID does not lexicographically precede the name
3550  //of some object
3551  return ERROR_OBJECT_NOT_FOUND;
3552 }
3553 
3554 #endif
@ IPV6_ADDR_STATE_TENTATIVE
An address whose uniqueness on a link is being verified.
Definition: ipv6.h:172
error_t ipMibGetIpAddressPrefixEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipAddressPrefixEntry object value.
Definition: ip_mib_impl.c:998
@ IP_MIB_ROUTER_PREFERENCE_MEDIUM
error_t ipMibGetIpDefaultRouterEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipDefaultRouterEntry object value.
Definition: ip_mib_impl.c:2571
NdpNeighborCacheEntry * ndpFindNeighborCacheEntry(NetInterface *interface, const Ipv6Addr *ipAddr)
Search the Neighbor cache for a given IPv6 address.
Definition: ndp_cache.c:106
IPv6 (Internet Protocol Version 6)
error_t ipMibGetNextIpSystemStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipSystemStatsEntry object.
Definition: ip_mib_impl.c:631
uint32_t ipIfStatsInDelivers
@ INET_VERSION_IPV6
Definition: mib_common.h:166
@ IP_MIB_ROUTER_PREFERENCE_RESERVED
uint8_t length
Definition: dtls_misc.h:149
uint32_t ipIfStatsInOctets
uint32_t ipSystemStatsOutMcastOctets
systime_t lifetime
Router lifetime.
Definition: ipv6.h:437
@ IP_MIB_PREFIX_ORIGIN_MANUAL
Per-message ICMP statistics.
uint64_t ipIfStatsHCInMcastPkts
error_t mibEncodeIpAddr(uint8_t *oid, size_t maxOidLen, size_t *pos, const IpAddr *ipAddr)
Encode instance identifier (IP address)
Definition: mib_common.c:757
int bool_t
Definition: compiler_port.h:49
error_t ipMibSetIpv6RouterAdvertSpinLock(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipv6RouterAdvertSpinLock object value.
Definition: ip_mib_impl.c:2941
uint64_t ipIfStatsHCOutMcastPkts
@ NDP_ROUTER_SEL_PREFERENCE_MEDIUM
Definition: ndp.h:236
uint32_t ipIfStatsOutOctets
error_t ipMibGetIpAddressEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipAddressEntry object value.
Definition: ip_mib_impl.c:1528
@ IP_MIB_ADDR_STATUS_TENTATIVE
Ipv4Addr addr
IPv4 address.
Definition: ipv4.h:312
uint64_t ipIfStatsHCInBcastPkts
IpMibIcmpMsgStatsEntry icmpMsgStatsTable
uint32_t ipSystemStatsInUnknownProtos
uint32_t ipSystemStatsOutMcastPkts
int32_t ipv6RouterAdvertSpinLock
__start_packed struct @109 Eui64
EUI-64 identifier.
@ NDP_STATE_STALE
Definition: ndp.h:252
uint32_t ipSystemStatsOutTransmits
NdpRouterAdvSettings settings
RA service settings.
uint32_t icmpMsgStatsOutPkts[256]
error_t ipMibInit(void)
IP MIB module initialization.
Definition: ip_mib_impl.c:59
int32_t ipAddressSpinLock
IP network address.
Definition: ip.h:71
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:140
uint32_t icmpStatsInMsgs
error_t ipMibGetNextIcmpStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next icmpStatsEntry object.
Definition: ip_mib_impl.c:3306
@ IP_MIB_ADDR_TYPE_UNICAST
Definition: ip_mib_module.h:87
uint32_t ipIfStatsReasmFails
OID (Object Identifier)
systime_t preferredLifetime
Preferred lifetime.
Definition: ipv6.h:424
uint32_t ipSystemStatsInForwDatagrams
error_t ipMibGetIpSystemStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipSystemStatsEntry object value.
Definition: ip_mib_impl.c:423
uint64_t ipSystemStatsHCInMcastOctets
int32_t ipReasmTimeout
@ NDP_ROUTER_SEL_PREFERENCE_LOW
Definition: ndp.h:239
error_t ipMibGetIpAddressSpinLock(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipAddressSpinLock object value.
Definition: ip_mib_impl.c:1487
const IpAddr IP_ADDR_UNSPECIFIED
Definition: ip.c:46
uint32_t ipIfStatsInNoRoutes
#define TRUE
Definition: os_port.h:50
#define NDP_NEIGHBOR_CACHE_SIZE
Definition: ndp.h:53
Ipv6Addr addr
IPv6 address.
Definition: ipv6.h:401
@ ARP_STATE_NONE
Definition: arp.h:128
uint64_t ipIfStatsHCOutRequests
uint16_t version
Definition: dtls_misc.h:172
error_t ipMibGetNextIpAddressEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipAddressEntry object.
Definition: ip_mib_impl.c:1867
@ IP_MIB_NET_TO_PHYS_STATE_PROBE
uint32_t ipSystemStatsInDelivers
bool_t running
This flag tells whether the RA service is running.
@ MIB_TRUTH_VALUE_TRUE
Definition: mib_common.h:91
uint64_t ipSystemStatsHCInOctets
bool_t autonomousFlag
Autonomous flag.
Definition: ipv6.h:422
uint32_t ipSystemStatsOutFragCreates
uint64_t ipIfStatsHCInForwDatagrams
Neighbor cache entry.
Definition: ndp.h:544
uint64_t ipSystemStatsHCOutRequests
systime_t validLifetime
Valid lifetime.
Definition: ipv6.h:423
uint32_t ipSystemStatsInReceives
@ IP_MIB_ADDR_ORIGIN_RANDOM
@ IP_MIB_NET_TO_PHYS_STATE_UNKNOWN
#define NET_INTERFACE_COUNT
Definition: net.h:109
uint32_t ipIfStatsOutBcastPkts
__start_packed struct @205 MibVariant
Variant data type.
uint32_t ipSystemStatsReasmFails
ICMP statistics.
Ipv4AddrState state
IPv4 address state.
Definition: ipv4.h:313
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
uint_t ipv4GetPrefixLength(Ipv4Addr mask)
Calculate prefix length for a given subnet mask.
Definition: ipv4_misc.c:587
uint64_t ipSystemStatsHCOutTransmits
error_t ipMibGetNextIpv4InterfaceEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipv4InterfaceEntry object.
Definition: ip_mib_impl.c:190
Ipv6Addr prefix
IPv6 prefix information.
Definition: ipv6.h:419
@ NDP_STATE_NONE
Definition: ndp.h:249
uint32_t ipSystemStatsRefreshRate
#define IPV4_MAX_FRAG_DATAGRAM_SIZE
Definition: ipv4_frag.h:62
Ipv6Addr addr
Router address.
Definition: ipv6.h:436
Ipv6Addr prefix
error_t ipMibGetIcmpStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get icmpStatsEntry object value.
Definition: ip_mib_impl.c:3221
uint64_t ipIfStatsHCInReceives
uint32_t ipSystemStatsInMcastOctets
@ IP_MIB_IP_FORWARDING_ENABLED
Definition: ip_mib_module.h:65
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
ArpCacheEntry * arpFindEntry(NetInterface *interface, Ipv4Addr ipAddr)
Search the ARP cache for a given IPv4 address.
Definition: arp.c:152
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:101
#define IPV6_DEFAULT_HOP_LIMIT
Definition: ipv6.h:59
uint32_t ipSystemStatsInTruncatedPkts
uint32_t ipSystemStatsOutNoRoutes
uint32_t icmpStatsOutMsgs
int32_t ipv6IpForwarding
uint32_t ipSystemStatsReasmReqds
#define macCopyAddr(destMacAddr, srcMacAddr)
Definition: ethernet.h:104
@ IPV6_ADDR_STATE_INVALID
An address that is not assigned to any interface.
Definition: ipv6.h:171
uint64_t ipSystemStatsHCOutBcastPkts
int32_t ipv6IpDefaultHopLimit
Router advertisement service.
uint32_t ipIfStatsInReceives
uint64_t ipSystemStatsHCOutOctets
systime_t timestamp
Timestamp to manage entry lifetime.
Definition: ndp.h:550
uint32_t ipIfStatsOutForwDatagrams
uint32_t ipIfStatsReasmOKs
int_t mibCompIpAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: mib_common.c:903
uint32_t ipSystemStatsReasmOKs
#define FALSE
Definition: os_port.h:46
NetInterface netInterface[NET_INTERFACE_COUNT]
Definition: net.c:79
#define ARP_CACHE_SIZE
Definition: arp.h:46
Ipv4Addr defaultGateway
Default gateway.
Definition: ipv4.h:316
uint32_t ipSystemStatsDiscontinuityTime
uint32_t ipSystemStatsOutFragReqds
uint64_t ipSystemStatsHCInForwDatagrams
uint64_t ipSystemStatsHCOutForwDatagrams
MacAddr macAddr
Link layer address associated with the IPv6 address.
Definition: ndp.h:548
@ IP_MIB_PREFIX_ORIGIN_ROUTER_ADV
error_t ipMibGetIcmpMsgStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get icmpMsgStatsEntry object value.
Definition: ip_mib_impl.c:3376
uint32_t ipIfStatsOutFragReqds
char_t type
uint64_t ipSystemStatsHCInMcastPkts
error_t
Error codes.
Definition: error.h:42
@ IPV4_ADDR_STATE_TENTATIVE
An address whose uniqueness on a link is being verified.
Definition: ipv4.h:190
@ IP_MIB_ADDR_STATUS_PREFERRED
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:251
uint64_t ipSystemStatsHCOutMcastPkts
error_t ipMibGetNextIpv6RouterAdvertEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipv6RouterAdvertEntry object.
Definition: ip_mib_impl.c:3162
#define eui64CopyAddr(destEui64Addr, srcEui64Addr)
Definition: ethernet.h:113
MacAddr macAddr
Definition: arp.h:187
uint32_t ipSystemStatsOutBcastPkts
uint32_t ipIfStatsRefreshRate
Prefix list entry.
Definition: ipv6.h:417
uint64_t ipIfStatsHCOutMcastOctets
error_t ipMibSetIpv6InterfaceEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipv6InterfaceEntry object value.
Definition: ip_mib_impl.c:245
error_t ipMibGetIpNetToPhysicalEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipNetToPhysicalEntry object value.
Definition: ip_mib_impl.c:2046
uint8_t preference
Preference value.
Definition: ipv6.h:438
uint32_t ipSystemStatsInHdrErrors
uint32_t ipIfStatsOutRequests
error_t ipMibGetNextIpDefaultRouterEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipDefaultRouterEntry object.
Definition: ip_mib_impl.c:2742
@ IP_MIB_NET_TO_PHYS_STATE_INCOMPLETE
#define NetInterface
Definition: net.h:36
uint32_t ipSystemStatsOutDiscards
@ IP_MIB_ADDR_ORIGIN_DHCP
uint32_t ipSystemStatsInBcastPkts
@ IP_MIB_NET_TO_PHYS_STATE_REACHABLE
uint64_t ipIfStatsHCInDelivers
@ NDP_STATE_DELAY
Definition: ndp.h:253
error_t ipMibGetIpv6RouterAdvertSpinLock(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipv6RouterAdvertSpinLock object value.
Definition: ip_mib_impl.c:2965
General definitions for cryptographic algorithms.
#define IPV6_MAX_FRAG_DATAGRAM_SIZE
Definition: ipv6_frag.h:69
IP MIB module implementation.
Helper functions for IPv6.
uint32_t ipSystemStatsInMcastPkts
uint8_t oid[1]
Definition: mib_common.h:186
uint32_t ipSystemStatsOutFragFails
IpMibBase ipMibBase
IP MIB base.
Definition: ip_mib_module.c:60
IpMibIpIfStatsEntry ipv4IfStatsTable[NET_INTERFACE_COUNT]
uint64_t ipSystemStatsHCInBcastPkts
error_t ipMibGetNextIpv6InterfaceEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipv6InterfaceEntry object.
Definition: ip_mib_impl.c:370
__start_packed struct @179 Ipv6Addr
IPv6 network address.
uint32_t ipIfStatsDiscontinuityTime
#define TRACE_INFO(...)
Definition: debug.h:94
error_t ipMibGetIpv6InterfaceEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipv6InterfaceEntry object value.
Definition: ip_mib_impl.c:263
#define IPV4_ADDR_LIST_SIZE
Definition: ipv4.h:63
error_t ipMibSetIpv6RouterAdvertEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipv6RouterAdvertEntry object value.
Definition: ip_mib_impl.c:2993
#define IPV4_FRAG_TIME_TO_LIVE
Definition: ipv4_frag.h:69
@ NDP_STATE_INCOMPLETE
Definition: ndp.h:250
uint32_t icmpStatsInErrors
Neighbor and destination cache management.
size_t length
Definition: ip.h:73
uint64_t ipSystemStatsHCOutMcastOctets
uint32_t ipSystemStatsOutOctets
@ IP_MIB_NET_TO_PHYS_STATE_STALE
IpMibIpSystemStatsEntry ipv6SystemStats
ArpState state
Definition: arp.h:185
IPv4 address entry.
Definition: ipv4.h:310
int32_t ipDefaultTTL
error_t ipMibGetNextIpNetToPhysicalEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipNetToPhysicalEntry object.
Definition: ip_mib_impl.c:2250
@ NDP_STATE_REACHABLE
Definition: ndp.h:251
@ IP_MIB_ROUTER_PREFERENCE_LOW
uint32_t ipIfStatsInTruncatedPkts
int32_t netGetRandRange(int32_t min, int32_t max)
Get a random value in the specified range.
Definition: net.c:1841
#define IPV4_DEFAULT_TTL
Definition: ipv4.h:56
bool_t onLinkFlag
On-link flag.
Definition: ipv6.h:421
bool_t permanent
Permanently assigned prefix.
Definition: ipv6.h:425
uint8_t prefixLen
RA service context.
@ MIB_TRUTH_VALUE_FALSE
Definition: mib_common.h:92
@ MIB_ROW_STATUS_ACTIVE
Definition: mib_common.h:103
Ipv4Addr ipv4Addr
Definition: ip.h:77
uint8_t prefixLen
IPv6 prefix length.
Definition: ipv6.h:420
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
Ipv4Addr subnetMask
Subnet mask.
Definition: ipv4.h:315
error_t ipMibSetIpNetToPhysicalEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipNetToPhysicalEntry object value.
Definition: ip_mib_impl.c:2028
Ipv6Addr ipAddr
Unicast IPv6 address.
Definition: ndp.h:547
error_t ipMibGetIpv6ScopeZoneIndexEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipv6ScopeZoneIndexEntry object value.
Definition: ip_mib_impl.c:2439
error_t ipMibGetNextIcmpMsgStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next icmpMsgStatsEntry object.
Definition: ip_mib_impl.c:3466
uint32_t ipSystemStatsOutFragOKs
Default router list entry.
Definition: ipv6.h:434
IPv6 address entry.
Definition: ipv6.h:399
@ NDP_ROUTER_SEL_PREFERENCE_HIGH
Definition: ndp.h:237
System-wide IP statistics.
@ IP_MIB_ROUTER_PREFERENCE_HIGH
uint32_t ipSystemStatsInOctets
error_t ipMibSetIpAddressEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipAddressEntry object value.
Definition: ip_mib_impl.c:1510
uint64_t ipIfStatsHCInOctets
Common definitions for MIB modules.
uint8_t n
uint64_t ipSystemStatsHCInReceives
#define IPV6_ROUTER_LIST_SIZE
Definition: ipv6.h:87
error_t ipMibGetIpIfStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipIfStatsEntry object value.
Definition: ip_mib_impl.c:701
error_t ipMibGetIpv4InterfaceEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipv4InterfaceEntry object value.
Definition: ip_mib_impl.c:124
IP MIB module.
@ ERROR_WRITE_FAILED
Definition: error.h:219
uint32_t icmpMsgStatsInPkts[256]
#define IPV6_ADDR_LIST_SIZE
Definition: ipv6.h:66
NdpState state
Reachability state.
Definition: ndp.h:546
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:250
uint64_t ipIfStatsHCOutForwDatagrams
uint32_t ipSystemStatsOutForwDatagrams
error_t ipMibGetNextIpv6ScopeZoneIndexEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipv6ScopeZoneIndexEntry object.
Definition: ip_mib_impl.c:2518
uint32_t ipIfStatsOutFragOKs
uint64_t ipIfStatsHCOutBcastPkts
uint32_t ipSystemStatsInDiscards
uint64_t ipIfStatsHCOutOctets
@ IP_MIB_IP_STATUS_UP
Definition: ip_mib_module.h:76
IpMibIpIfStatsEntry ipv6IfStatsTable[NET_INTERFACE_COUNT]
int32_t ipForwarding
systime_t timestamp
Definition: arp.h:188
@ INET_VERSION_IPV4
Definition: mib_common.h:165
IpMibIcmpStatsEntry icmpStats
uint32_t ipIfStatsInUnknownProtos
#define MibObject
Definition: mib_common.h:46
IpMibIcmpMsgStatsEntry icmpv6MsgStatsTable
ARP cache entry.
Definition: arp.h:183
bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2, size_t length)
Compare IPv6 address prefixes.
Definition: ipv6_misc.c:1208
error_t mibDecodeIpAddr(const uint8_t *oid, size_t oidLen, size_t *pos, IpAddr *ipAddr)
Decode instance identifier (IP address)
Definition: mib_common.c:835
@ MIB_STORAGE_TYPE_VOLATILE
Definition: mib_common.h:119
error_t mibDecodeUnsigned32(const uint8_t *oid, size_t oidLen, size_t *pos, uint32_t *value)
Decode instance identifier (unsigned 32-bit integer)
Definition: mib_common.c:111
uint32_t ipIfStatsInAddrErrors
error_t ipMibGetNextIpIfStatsEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipIfStatsEntry object.
Definition: ip_mib_impl.c:917
uint32_t ipIfStatsInForwDatagrams
error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos, uint_t index)
Encode instance identifier (index)
Definition: mib_common.c:47
Per-interface IP statistics.
@ IPV4_ADDR_STATE_VALID
An address assigned to an interface whose use is unrestricted.
Definition: ipv4.h:191
@ IP_MIB_IP_FORWARDING_DISABLED
Definition: ip_mib_module.h:66
error_t mibTestAndIncSpinLock(int32_t *spinLock, int32_t value, bool_t commit)
Test and increment spin lock.
Definition: mib_common.c:941
error_t mibEncodeUnsigned32(uint8_t *oid, size_t maxOidLen, size_t *pos, uint32_t value)
Encode instance identifier (unsigned 32-bit integer)
Definition: mib_common.c:94
IPv4 (Internet Protocol Version 4)
uint64_t ipIfStatsHCOutTransmits
@ IPV6_ADDR_STATE_PREFERRED
An address assigned to an interface whose use is unrestricted.
Definition: ipv6.h:173
uint32_t ipIfStatsOutDiscards
Ipv6AddrState state
IPv6 address state.
Definition: ipv6.h:402
uint32_t ipIfStatsOutMcastOctets
Ipv6Addr ipv6Addr
Definition: ip.h:80
#define IPV6_PREFIX_LIST_SIZE
Definition: ipv6.h:80
uint8_t value[]
Definition: dtls_misc.h:150
uint32_t ipIfStatsOutFragFails
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint32_t ipIfStatsReasmReqds
uint32_t ipSystemStatsInNoRoutes
uint64_t ipSystemStatsHCInDelivers
NetInterface * nicGetLogicalInterface(NetInterface *interface)
Retrieve logical interface.
Definition: nic.c:52
@ IP_MIB_ADDR_ORIGIN_MANUAL
Definition: ip_mib_module.h:99
@ IPV6_ADDR_STATE_DEPRECATED
An address assigned to an interface whose use is discouraged.
Definition: ipv6.h:174
error_t ipMibGetNextIpAddressPrefixEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipAddressPrefixEntry object.
Definition: ip_mib_impl.c:1236
uint32_t ipIfStatsInDiscards
uint32_t ipIfStatsInMcastPkts
@ IP_MIB_NET_TO_PHYS_TYPE_DYNAMIC
@ IP_MIB_NET_TO_PHYS_STATE_DELAY
#define ARP_REQUEST_TIMEOUT
Definition: arp.h:67
uint32_t ipIfStatsInMcastOctets
uint32_t ipSystemStatsInAddrErrors
ARP (Address Resolution Protocol)
@ NDP_STATE_PROBE
Definition: ndp.h:254
error_t ipMibSetIpv4InterfaceEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipv4InterfaceEntry object value.
Definition: ip_mib_impl.c:106
error_t ipMibGetIpv6RouterAdvertEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipv6RouterAdvertEntry object value.
Definition: ip_mib_impl.c:3011
@ IP_MIB_ADDR_STATUS_DEPRECATED
uint8_t ipAddr[4]
Definition: mib_common.h:187
error_t ipMibSetIpAddressSpinLock(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipAddressSpinLock object value.
Definition: ip_mib_impl.c:1468
Ipv4Addr ipAddr
Definition: arp.h:186
uint32_t ipSystemStatsOutRequests
@ IP_MIB_ADDR_STATUS_UNKNOWN
uint32_t ipIfStatsOutTransmits
@ NO_ERROR
Success.
Definition: error.h:44
uint32_t ipIfStatsInHdrErrors
uint32_t ipIfStatsInBcastPkts
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
uint32_t ipIfStatsOutMcastPkts
#define INFINITE_DELAY
Definition: os_port.h:74
uint32_t icmpStatsOutErrors
uint32_t ipIfStatsOutFragCreates
uint64_t ipIfStatsHCInMcastOctets
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:104
__start_packed struct @108 MacAddr
MAC address.
IpMibIpSystemStatsEntry ipv4SystemStats
IpMibIcmpStatsEntry icmpv6Stats