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