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