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