mib2_impl_ip.c
Go to the documentation of this file.
1 /**
2  * @file mib2_impl_ip.c
3  * @brief MIB-II module implementation (IP group)
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/arp_cache.h"
37 #include "mibs/mib_common.h"
38 #include "mibs/mib2_module.h"
39 #include "mibs/mib2_impl.h"
40 #include "mibs/mib2_impl_ip.h"
41 #include "core/crypto.h"
42 #include "encoding/asn1.h"
43 #include "encoding/oid.h"
44 #include "debug.h"
45 
46 //Check TCP/IP stack configuration
47 #if (MIB2_SUPPORT == ENABLED && MIB2_IP_GROUP_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Get ipInReceives object value
52  * @param[in] object Pointer to the MIB object descriptor
53  * @param[in] oid Object identifier (object name and instance identifier)
54  * @param[in] oidLen Length of the OID, in bytes
55  * @param[out] value Object value
56  * @param[in,out] valueLen Length of the object value, in bytes
57  * @return Error code
58  **/
59 
60 error_t mib2GetIpInReceives(const MibObject *object, const uint8_t *oid,
61  size_t oidLen, MibVariant *value, size_t *valueLen)
62 {
63  NetContext *context;
64 
65  //Point to the TCP/IP stack context
66  context = netGetDefaultContext();
67 
68  //Total number of input datagrams received from interfaces, including those
69  //received in error
70  value->counter32 = (uint32_t) context->ipv4SystemStats.inReceives;
71 
72  //Return status code
73  return NO_ERROR;
74 }
75 
76 
77 /**
78  * @brief Get ipInHdrErrors object value
79  * @param[in] object Pointer to the MIB object descriptor
80  * @param[in] oid Object identifier (object name and instance identifier)
81  * @param[in] oidLen Length of the OID, in bytes
82  * @param[out] value Object value
83  * @param[in,out] valueLen Length of the object value, in bytes
84  * @return Error code
85  **/
86 
87 error_t mib2GetIpInHdrErrors(const MibObject *object, const uint8_t *oid,
88  size_t oidLen, MibVariant *value, size_t *valueLen)
89 {
90  NetContext *context;
91 
92  //Point to the TCP/IP stack context
93  context = netGetDefaultContext();
94 
95  //Number of input datagrams discarded due to errors in their IP headers,
96  //including bad checksums, version number mismatch, other format errors,
97  //time-to-live exceeded, errors discovered in processing their IP options,
98  //etc
99  value->counter32 = context->ipv4SystemStats.inHdrErrors;
100 
101  //Return status code
102  return NO_ERROR;
103 }
104 
105 
106 /**
107  * @brief Get ipInAddrErrors object value
108  * @param[in] object Pointer to the MIB object descriptor
109  * @param[in] oid Object identifier (object name and instance identifier)
110  * @param[in] oidLen Length of the OID, in bytes
111  * @param[out] value Object value
112  * @param[in,out] valueLen Length of the object value, in bytes
113  * @return Error code
114  **/
115 
116 error_t mib2GetIpInAddrErrors(const MibObject *object, const uint8_t *oid,
117  size_t oidLen, MibVariant *value, size_t *valueLen)
118 {
119  NetContext *context;
120 
121  //Point to the TCP/IP stack context
122  context = netGetDefaultContext();
123 
124  //Number of input datagrams discarded because the IP address in their IP
125  //header's destination field was not a valid address to be received at this
126  //entity
127  value->counter32 = context->ipv4SystemStats.inAddrErrors;
128 
129  //Return status code
130  return NO_ERROR;
131 }
132 
133 
134 /**
135  * @brief Get ipForwDatagrams object value
136  * @param[in] object Pointer to the MIB object descriptor
137  * @param[in] oid Object identifier (object name and instance identifier)
138  * @param[in] oidLen Length of the OID, in bytes
139  * @param[out] value Object value
140  * @param[in,out] valueLen Length of the object value, in bytes
141  * @return Error code
142  **/
143 
144 error_t mib2GetIpForwDatagrams(const MibObject *object, const uint8_t *oid,
145  size_t oidLen, MibVariant *value, size_t *valueLen)
146 {
147  NetContext *context;
148 
149  //Point to the TCP/IP stack context
150  context = netGetDefaultContext();
151 
152  //Number of input datagrams for which this entity was not their final IP
153  //destination, as a result of which an attempt was made to find a route to
154  //forward them to that final destination
155  value->counter32 = (uint32_t) context->ipv4SystemStats.inForwDatagrams;
156 
157  //Return status code
158  return NO_ERROR;
159 }
160 
161 
162 /**
163  * @brief Get ipInUnknownProtos object value
164  * @param[in] object Pointer to the MIB object descriptor
165  * @param[in] oid Object identifier (object name and instance identifier)
166  * @param[in] oidLen Length of the OID, in bytes
167  * @param[out] value Object value
168  * @param[in,out] valueLen Length of the object value, in bytes
169  * @return Error code
170  **/
171 
172 error_t mib2GetIpInUnknownProtos(const MibObject *object, const uint8_t *oid,
173  size_t oidLen, MibVariant *value, size_t *valueLen)
174 {
175  NetContext *context;
176 
177  //Point to the TCP/IP stack context
178  context = netGetDefaultContext();
179 
180  //Number of locally-addressed datagrams received successfully but discarded
181  //because of an unknown or unsupported protocol
182  value->counter32 = context->ipv4SystemStats.inUnknownProtos;
183 
184  //Return status code
185  return NO_ERROR;
186 }
187 
188 
189 /**
190  * @brief Get ipInDiscards object value
191  * @param[in] object Pointer to the MIB object descriptor
192  * @param[in] oid Object identifier (object name and instance identifier)
193  * @param[in] oidLen Length of the OID, in bytes
194  * @param[out] value Object value
195  * @param[in,out] valueLen Length of the object value, in bytes
196  * @return Error code
197  **/
198 
199 error_t mib2GetIpInDiscards(const MibObject *object, const uint8_t *oid,
200  size_t oidLen, MibVariant *value, size_t *valueLen)
201 {
202  NetContext *context;
203 
204  //Point to the TCP/IP stack context
205  context = netGetDefaultContext();
206 
207  //Number of input IP datagrams for which no problems were encountered to
208  //prevent their continued processing, but which were discarded
209  value->counter32 = context->ipv4SystemStats.inDiscards;
210 
211  //Return status code
212  return NO_ERROR;
213 }
214 
215 
216 /**
217  * @brief Get ipInDelivers object value
218  * @param[in] object Pointer to the MIB object descriptor
219  * @param[in] oid Object identifier (object name and instance identifier)
220  * @param[in] oidLen Length of the OID, in bytes
221  * @param[out] value Object value
222  * @param[in,out] valueLen Length of the object value, in bytes
223  * @return Error code
224  **/
225 
226 error_t mib2GetIpInDelivers(const MibObject *object, const uint8_t *oid,
227  size_t oidLen, MibVariant *value, size_t *valueLen)
228 {
229  NetContext *context;
230 
231  //Point to the TCP/IP stack context
232  context = netGetDefaultContext();
233 
234  //Total number of input datagrams successfully delivered to IP user-protocols
235  value->counter32 = (uint32_t) context->ipv4SystemStats.inDelivers;
236 
237  //Return status code
238  return NO_ERROR;
239 }
240 
241 
242 /**
243  * @brief Get ipOutRequests object value
244  * @param[in] object Pointer to the MIB object descriptor
245  * @param[in] oid Object identifier (object name and instance identifier)
246  * @param[in] oidLen Length of the OID, in bytes
247  * @param[out] value Object value
248  * @param[in,out] valueLen Length of the object value, in bytes
249  * @return Error code
250  **/
251 
252 error_t mib2GetIpOutRequests(const MibObject *object, const uint8_t *oid,
253  size_t oidLen, MibVariant *value, size_t *valueLen)
254 {
255  NetContext *context;
256 
257  //Point to the TCP/IP stack context
258  context = netGetDefaultContext();
259 
260  //Total number of IP datagrams which local IP user-protocols supplied to IP
261  //in requests for transmission
262  value->counter32 = (uint32_t) context->ipv4SystemStats.outRequests;
263 
264  //Return status code
265  return NO_ERROR;
266 }
267 
268 
269 /**
270  * @brief Get ipOutDiscards object value
271  * @param[in] object Pointer to the MIB object descriptor
272  * @param[in] oid Object identifier (object name and instance identifier)
273  * @param[in] oidLen Length of the OID, in bytes
274  * @param[out] value Object value
275  * @param[in,out] valueLen Length of the object value, in bytes
276  * @return Error code
277  **/
278 
279 error_t mib2GetIpOutDiscards(const MibObject *object, const uint8_t *oid,
280  size_t oidLen, MibVariant *value, size_t *valueLen)
281 {
282  NetContext *context;
283 
284  //Point to the TCP/IP stack context
285  context = netGetDefaultContext();
286 
287  //Number of output IP datagrams for which no problem was encountered to
288  //prevent their transmission to their destination, but which were discarded
289  value->counter32 = context->ipv4SystemStats.outDiscards;
290 
291  //Return status code
292  return NO_ERROR;
293 }
294 
295 
296 /**
297  * @brief Get ipOutNoRoutes object value
298  * @param[in] object Pointer to the MIB object descriptor
299  * @param[in] oid Object identifier (object name and instance identifier)
300  * @param[in] oidLen Length of the OID, in bytes
301  * @param[out] value Object value
302  * @param[in,out] valueLen Length of the object value, in bytes
303  * @return Error code
304  **/
305 
306 error_t mib2GetIpOutNoRoutes(const MibObject *object, const uint8_t *oid,
307  size_t oidLen, MibVariant *value, size_t *valueLen)
308 {
309  NetContext *context;
310 
311  //Point to the TCP/IP stack context
312  context = netGetDefaultContext();
313 
314  //Number of IP datagrams discarded because no route could be found to
315  //transmit them to their destination
316  value->counter32 = context->ipv4SystemStats.outNoRoutes;
317 
318  //Return status code
319  return NO_ERROR;
320 }
321 
322 
323 /**
324  * @brief Get ipReasmReqds object value
325  * @param[in] object Pointer to the MIB object descriptor
326  * @param[in] oid Object identifier (object name and instance identifier)
327  * @param[in] oidLen Length of the OID, in bytes
328  * @param[out] value Object value
329  * @param[in,out] valueLen Length of the object value, in bytes
330  * @return Error code
331  **/
332 
333 error_t mib2GetIpReasmReqds(const MibObject *object, const uint8_t *oid,
334  size_t oidLen, MibVariant *value, size_t *valueLen)
335 {
336  NetContext *context;
337 
338  //Point to the TCP/IP stack context
339  context = netGetDefaultContext();
340 
341  //Number of IP fragments received which needed to be reassembled at this
342  //entity
343  value->counter32 = context->ipv4SystemStats.reasmReqds;
344 
345  //Return status code
346  return NO_ERROR;
347 }
348 
349 
350 /**
351  * @brief Get ipReasmOKs object value
352  * @param[in] object Pointer to the MIB object descriptor
353  * @param[in] oid Object identifier (object name and instance identifier)
354  * @param[in] oidLen Length of the OID, in bytes
355  * @param[out] value Object value
356  * @param[in,out] valueLen Length of the object value, in bytes
357  * @return Error code
358  **/
359 
360 error_t mib2GetIpReasmOKs(const MibObject *object, const uint8_t *oid,
361  size_t oidLen, MibVariant *value, size_t *valueLen)
362 {
363  NetContext *context;
364 
365  //Point to the TCP/IP stack context
366  context = netGetDefaultContext();
367 
368  //Number of IP datagrams successfully reassembled
369  value->counter32 = context->ipv4SystemStats.reasmOKs;
370 
371  //Return status code
372  return NO_ERROR;
373 }
374 
375 
376 /**
377  * @brief Get ipReasmFails object value
378  * @param[in] object Pointer to the MIB object descriptor
379  * @param[in] oid Object identifier (object name and instance identifier)
380  * @param[in] oidLen Length of the OID, in bytes
381  * @param[out] value Object value
382  * @param[in,out] valueLen Length of the object value, in bytes
383  * @return Error code
384  **/
385 
386 error_t mib2GetIpReasmFails(const MibObject *object, const uint8_t *oid,
387  size_t oidLen, MibVariant *value, size_t *valueLen)
388 {
389  NetContext *context;
390 
391  //Point to the TCP/IP stack context
392  context = netGetDefaultContext();
393 
394  //Number of failures detected by the IP reassembly algorithm
395  value->counter32 = context->ipv4SystemStats.reasmFails;
396 
397  //Return status code
398  return NO_ERROR;
399 }
400 
401 
402 /**
403  * @brief Get ipFragOKs object value
404  * @param[in] object Pointer to the MIB object descriptor
405  * @param[in] oid Object identifier (object name and instance identifier)
406  * @param[in] oidLen Length of the OID, in bytes
407  * @param[out] value Object value
408  * @param[in,out] valueLen Length of the object value, in bytes
409  * @return Error code
410  **/
411 
412 error_t mib2GetIpFragOKs(const MibObject *object, const uint8_t *oid,
413  size_t oidLen, MibVariant *value, size_t *valueLen)
414 {
415  NetContext *context;
416 
417  //Point to the TCP/IP stack context
418  context = netGetDefaultContext();
419 
420  //Number of IP datagrams that have been successfully fragmented at this
421  //entity
422  value->counter32 = context->ipv4SystemStats.outFragOKs;
423 
424  //Return status code
425  return NO_ERROR;
426 }
427 
428 
429 /**
430  * @brief Get ipFragFails object value
431  * @param[in] object Pointer to the MIB object descriptor
432  * @param[in] oid Object identifier (object name and instance identifier)
433  * @param[in] oidLen Length of the OID, in bytes
434  * @param[out] value Object value
435  * @param[in,out] valueLen Length of the object value, in bytes
436  * @return Error code
437  **/
438 
439 error_t mib2GetIpFragFails(const MibObject *object, const uint8_t *oid,
440  size_t oidLen, MibVariant *value, size_t *valueLen)
441 {
442  NetContext *context;
443 
444  //Point to the TCP/IP stack context
445  context = netGetDefaultContext();
446 
447  //Number of IP datagrams that have been discarded because they needed to be
448  //fragmented at this entity but could not be
449  value->counter32 = context->ipv4SystemStats.outFragFails;
450 
451  //Return status code
452  return NO_ERROR;
453 }
454 
455 
456 /**
457  * @brief Get ipFragCreates object value
458  * @param[in] object Pointer to the MIB object descriptor
459  * @param[in] oid Object identifier (object name and instance identifier)
460  * @param[in] oidLen Length of the OID, in bytes
461  * @param[out] value Object value
462  * @param[in,out] valueLen Length of the object value, in bytes
463  * @return Error code
464  **/
465 
466 error_t mib2GetIpFragCreates(const MibObject *object, const uint8_t *oid,
467  size_t oidLen, MibVariant *value, size_t *valueLen)
468 {
469  NetContext *context;
470 
471  //Point to the TCP/IP stack context
472  context = netGetDefaultContext();
473 
474  //Number of IP datagram fragments that have been generated as a result of
475  //fragmentation at this entity
476  value->counter32 = context->ipv4SystemStats.outFragCreates;
477 
478  //Return status code
479  return NO_ERROR;
480 }
481 
482 
483 /**
484  * @brief Get ipAddrEntry object value
485  * @param[in] object Pointer to the MIB object descriptor
486  * @param[in] oid Object identifier (object name and instance identifier)
487  * @param[in] oidLen Length of the OID, in bytes
488  * @param[out] value Object value
489  * @param[in,out] valueLen Length of the object value, in bytes
490  * @return Error code
491  **/
492 
493 error_t mib2GetIpAddrEntry(const MibObject *object, const uint8_t *oid,
494  size_t oidLen, MibVariant *value, size_t *valueLen)
495 {
496  error_t error;
497  size_t n;
498  uint_t i;
499  uint_t index;
501  Ipv4AddrEntry *entry;
502  NetContext *context;
503  NetInterface *interface;
504 
505  //Point to the TCP/IP stack context
506  context = netGetDefaultContext();
507 
508  //Point to the instance identifier
509  n = object->oidLen;
510 
511  //ipAdEntAddr is used as instance identifier
512  error = mibDecodeIpv4Addr(oid, oidLen, &n, &ipAddr);
513  //Invalid instance identifier?
514  if(error)
515  return error;
516 
517  //Sanity check
518  if(n != oidLen)
520 
521  //Loop through network interfaces
522  for(index = 1; index <= context->numInterfaces; index++)
523  {
524  //Point to the current interface
525  interface = &context->interfaces[index - 1];
526 
527  //Loop through the list of IPv4 addresses assigned to the interface
528  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
529  {
530  //Point to the current entry
531  entry = &interface->ipv4Context.addrList[i];
532 
533  //Compare the current address against the IP address used as
534  //instance identifier
535  if(entry->state == IPV4_ADDR_STATE_VALID &&
536  entry->addr == ipAddr)
537  {
538  break;
539  }
540  }
541 
542  //IPv4 address found?
543  if(i < IPV4_ADDR_LIST_SIZE)
544  break;
545  }
546 
547  //IP address not assigned to any interface?
548  if(index > context->numInterfaces)
550 
551  //ipAdEntAddr object?
552  if(osStrcmp(object->name, "ipAdEntAddr") == 0)
553  {
554  //Get object value
555  ipv4CopyAddr(value->ipAddr, &entry->addr);
556  }
557  //ipAdEntIfIndex object?
558  else if(osStrcmp(object->name, "ipAdEntIfIndex") == 0)
559  {
560  //Get object value
561  value->integer = index;
562  }
563  //ipAdEntNetMask object?
564  else if(osStrcmp(object->name, "ipAdEntNetMask") == 0)
565  {
566  //Get object value
567  ipv4CopyAddr(value->ipAddr, &entry->subnetMask);
568  }
569  //ipAdEntBcastAddr object?
570  else if(osStrcmp(object->name, "ipAdEntBcastAddr") == 0)
571  {
572  //Get object value
573  value->integer = 1;
574  }
575  //ipAdEntReasmMaxSize object?
576  else if(osStrcmp(object->name, "ipAdEntReasmMaxSize") == 0)
577  {
578  //Get object value
580  }
581  //Unknown object?
582  else
583  {
584  //The specified object does not exist
585  error = ERROR_OBJECT_NOT_FOUND;
586  }
587 
588  //Return status code
589  return error;
590 }
591 
592 
593 /**
594  * @brief Get next ipAddrEntry object
595  * @param[in] object Pointer to the MIB object descriptor
596  * @param[in] oid Object identifier
597  * @param[in] oidLen Length of the OID, in bytes
598  * @param[out] nextOid OID of the next object in the MIB
599  * @param[out] nextOidLen Length of the next object identifier, in bytes
600  * @return Error code
601  **/
602 
603 error_t mib2GetNextIpAddrEntry(const MibObject *object, const uint8_t *oid,
604  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
605 {
606  error_t error;
607  uint_t i;
608  size_t n;
609  uint_t index;
610  bool_t acceptable;
612  Ipv4AddrEntry *entry;
613  NetContext *context;
614  NetInterface *interface;
615 
616  //Point to the TCP/IP stack context
617  context = netGetDefaultContext();
618 
619  //Initialize IP address
621 
622  //Make sure the buffer is large enough to hold the OID prefix
623  if(*nextOidLen < object->oidLen)
624  return ERROR_BUFFER_OVERFLOW;
625 
626  //Copy OID prefix
627  osMemcpy(nextOid, object->oid, object->oidLen);
628 
629  //Loop through network interfaces
630  for(index = 1; index <= context->numInterfaces; index++)
631  {
632  //Point to the current interface
633  interface = &context->interfaces[index - 1];
634 
635  //Loop through the list of IPv4 addresses assigned to the interface
636  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
637  {
638  //Point to the current entry
639  entry = &interface->ipv4Context.addrList[i];
640 
641  //Valid IPv4 address?
642  if(entry->state == IPV4_ADDR_STATE_VALID)
643  {
644  //Append the instance identifier to the OID prefix
645  n = object->oidLen;
646 
647  //ipAdEntAddr is used as instance identifier
648  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, entry->addr);
649  //Any error to report?
650  if(error)
651  return error;
652 
653  //Check whether the resulting object identifier lexicographically
654  //follows the specified OID
655  if(oidComp(nextOid, n, oid, oidLen) > 0)
656  {
657  //Perform lexicographic comparison
659  {
660  acceptable = TRUE;
661  }
662  else if(ntohl(entry->addr) < ntohl(ipAddr))
663  {
664  acceptable = TRUE;
665  }
666  else
667  {
668  acceptable = FALSE;
669  }
670 
671  //Save the closest object identifier that follows the specified
672  //OID in lexicographic order
673  if(acceptable)
674  ipAddr = entry->addr;
675  }
676  }
677  }
678  }
679 
680  //The specified OID does not lexicographically precede the name
681  //of some object?
683  return ERROR_OBJECT_NOT_FOUND;
684 
685  //Append the instance identifier to the OID prefix
686  n = object->oidLen;
687 
688  //ipAdEntAddr is used as instance identifier
689  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, ipAddr);
690  //Any error to report?
691  if(error)
692  return error;
693 
694  //Save the length of the resulting object identifier
695  *nextOidLen = n;
696  //Next object found
697  return NO_ERROR;
698 }
699 
700 
701 /**
702  * @brief Set ipNetToMediaEntry object value
703  * @param[in] object Pointer to the MIB object descriptor
704  * @param[in] oid Object identifier (object name and instance identifier)
705  * @param[in] oidLen Length of the OID, in bytes
706  * @param[in] value Object value
707  * @param[in] valueLen Length of the object value, in bytes
708  * @param[in] commit This flag tells whether the changes shall be committed
709  * to the MIB base
710  * @return Error code
711  **/
712 
713 error_t mib2SetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid,
714  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
715 {
716  //Not implemented
717  return ERROR_WRITE_FAILED;
718 }
719 
720 
721 /**
722  * @brief Get ipNetToMediaEntry object value
723  * @param[in] object Pointer to the MIB object descriptor
724  * @param[in] oid Object identifier (object name and instance identifier)
725  * @param[in] oidLen Length of the OID, in bytes
726  * @param[out] value Object value
727  * @param[in,out] valueLen Length of the object value, in bytes
728  * @return Error code
729  **/
730 
731 error_t mib2GetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid,
732  size_t oidLen, MibVariant *value, size_t *valueLen)
733 {
734 #if (ETH_SUPPORT == ENABLED)
735  error_t error;
736  size_t n;
737  uint_t index;
739  NetContext *context;
740  NetInterface *interface;
741  ArpCacheEntry *entry;
742 
743  //Point to the TCP/IP stack context
744  context = netGetDefaultContext();
745 
746  //Point to the instance identifier
747  n = object->oidLen;
748 
749  //ipNetToMediaIfIndex is used as 1st instance identifier
750  error = mibDecodeIndex(oid, oidLen, &n, &index);
751  //Invalid instance identifier?
752  if(error)
753  return error;
754 
755  //ipNetToMediaNetAddress is used as 2nd instance identifier
756  error = mibDecodeIpv4Addr(oid, oidLen, &n, &ipAddr);
757  //Invalid instance identifier?
758  if(error)
759  return error;
760 
761  //Sanity check
762  if(n != oidLen)
764 
765  //Check index range
766  if(index < 1 || index > context->numInterfaces)
768 
769  //Point to the network interface
770  interface = &context->interfaces[index - 1];
771 
772  //Search the ARP cache for the specified IP address
773  entry = arpFindEntry(interface, ipAddr);
774 
775  //No matching entry found?
776  if(entry == NULL)
778 
779  //ipNetToMediaIfIndex object?
780  if(osStrcmp(object->name, "ipNetToMediaIfIndex") == 0)
781  {
782  //Get object value
783  value->integer = index;
784  }
785  //ipNetToMediaPhysAddress object?
786  else if(osStrcmp(object->name, "ipNetToMediaPhysAddress") == 0)
787  {
788  //Make sure the buffer is large enough to hold the entire object
789  if(*valueLen >= MIB2_PHYS_ADDRESS_SIZE)
790  {
791  //Copy object value
792  macCopyAddr(value->octetString, &entry->macAddr);
793  //Return object length
794  *valueLen = MIB2_PHYS_ADDRESS_SIZE;
795  }
796  else
797  {
798  //Report an error
799  error = ERROR_BUFFER_OVERFLOW;
800  }
801  }
802  //ipNetToMediaNetAddress object?
803  else if(osStrcmp(object->name, "ipNetToMediaNetAddress") == 0)
804  {
805  //Get object value
806  ipv4CopyAddr(value->ipAddr, &entry->ipAddr);
807  }
808  //ipNetToMediaType object?
809  else if(osStrcmp(object->name, "ipNetToMediaType") == 0)
810  {
811  //Get object value
813  }
814  //Unknown object?
815  else
816  {
817  //The specified object does not exist
818  error = ERROR_OBJECT_NOT_FOUND;
819  }
820 
821  //Return status code
822  return error;
823 #else
824  //Not implemented
825  return ERROR_OBJECT_NOT_FOUND;
826 #endif
827 }
828 
829 
830 /**
831  * @brief Get next ipNetToMediaEntry object
832  * @param[in] object Pointer to the MIB object descriptor
833  * @param[in] oid Object identifier
834  * @param[in] oidLen Length of the OID, in bytes
835  * @param[out] nextOid OID of the next object in the MIB
836  * @param[out] nextOidLen Length of the next object identifier, in bytes
837  * @return Error code
838  **/
839 
840 error_t mib2GetNextIpNetToMediaEntry(const MibObject *object, const uint8_t *oid,
841  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
842 {
843 #if (ETH_SUPPORT == ENABLED)
844  error_t error;
845  uint_t i;
846  uint_t j;
847  size_t n;
848  uint_t index;
849  bool_t acceptable;
851  NetContext *context;
852  NetInterface *interface;
853  ArpCacheEntry *entry;
854 
855  //Point to the TCP/IP stack context
856  context = netGetDefaultContext();
857 
858  //Initialize variables
859  index = 0;
861 
862  //Make sure the buffer is large enough to hold the OID prefix
863  if(*nextOidLen < object->oidLen)
864  return ERROR_BUFFER_OVERFLOW;
865 
866  //Copy OID prefix
867  osMemcpy(nextOid, object->oid, object->oidLen);
868 
869  //Loop through network interfaces
870  for(i = 1; i <= context->numInterfaces; i++)
871  {
872  //Point to the current interface
873  interface = &context->interfaces[i - 1];
874 
875  //Loop through ARP cache entries
876  for(j = 0; j < ARP_CACHE_SIZE; j++)
877  {
878  //Point to the current entry
879  entry = &interface->arpCache[j];
880 
881  //Valid entry?
882  if(entry->state != ARP_STATE_NONE)
883  {
884  //Append the instance identifier to the OID prefix
885  n = object->oidLen;
886 
887  //ipNetToMediaIfIndex is used as 1st instance identifier
888  error = mibEncodeIndex(nextOid, *nextOidLen, &n, i);
889  //Any error to report?
890  if(error)
891  return error;
892 
893  //ipNetToMediaNetAddress is used as 2nd instance identifier
894  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, entry->ipAddr);
895  //Any error to report?
896  if(error)
897  return error;
898 
899  //Check whether the resulting object identifier lexicographically
900  //follows the specified OID
901  if(oidComp(nextOid, n, oid, oidLen) > 0)
902  {
903  //Perform lexicographic comparison
904  if(index == 0)
905  {
906  acceptable = TRUE;
907  }
908  else if(i < index)
909  {
910  acceptable = TRUE;
911  }
912  else if(i > index)
913  {
914  acceptable = FALSE;
915  }
916  else if(ntohl(entry->ipAddr) < ntohl(ipAddr))
917  {
918  acceptable = TRUE;
919  }
920  else
921  {
922  acceptable = FALSE;
923  }
924 
925  //Save the closest object identifier that follows the specified
926  //OID in lexicographic order
927  if(acceptable)
928  {
929  index = i;
930  ipAddr = entry->ipAddr;
931  }
932  }
933  }
934  }
935  }
936 
937  //The specified OID does not lexicographically precede the name
938  //of some object?
939  if(index == 0)
940  return ERROR_OBJECT_NOT_FOUND;
941 
942  //Append the instance identifier to the OID prefix
943  n = object->oidLen;
944 
945  //ipNetToMediaIfIndex is used as 1st instance identifier
946  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
947  //Any error to report?
948  if(error)
949  return error;
950 
951  //ipNetToMediaNetAddress is used as 2nd instance identifier
952  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, ipAddr);
953  //Any error to report?
954  if(error)
955  return error;
956 
957  //Save the length of the resulting object identifier
958  *nextOidLen = n;
959  //Next object found
960  return NO_ERROR;
961 #else
962  //Not implemented
963  return ERROR_OBJECT_NOT_FOUND;
964 #endif
965 }
966 
967 #endif
MIB-II module.
#define NetContext
Definition: net.h:36
int bool_t
Definition: compiler_port.h:63
Ipv4Addr addr
IPv4 address.
Definition: ipv4.h:411
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:143
OID (Object Identifier)
error_t mib2GetIpReasmFails(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipReasmFails object value.
Definition: mib2_impl_ip.c:386
#define MIB2_PHYS_ADDRESS_SIZE
Definition: mib2_module.h:141
#define TRUE
Definition: os_port.h:50
@ ARP_STATE_NONE
Definition: arp.h:128
error_t mib2GetIpFragCreates(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipFragCreates object value.
Definition: mib2_impl_ip.c:466
Ipv4AddrState state
IPv4 address state.
Definition: ipv4.h:412
error_t mib2GetIpInDelivers(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipInDelivers object value.
Definition: mib2_impl_ip.c:226
#define osStrcmp(s1, s2)
Definition: os_port.h:174
error_t mib2GetIpAddrEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipAddrEntry object value.
Definition: mib2_impl_ip.c:493
error_t mib2SetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ipNetToMediaEntry object value.
Definition: mib2_impl_ip.c:713
#define IPV4_MAX_FRAG_DATAGRAM_SIZE
Definition: ipv4_frag.h:69
error_t mib2GetIpForwDatagrams(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipForwDatagrams object value.
Definition: mib2_impl_ip.c:144
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:322
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
uint8_t oid[]
Definition: lldp_tlv.h:300
#define macCopyAddr(destMacAddr, srcMacAddr)
Definition: ethernet.h:127
#define FALSE
Definition: os_port.h:46
error_t mib2GetIpOutDiscards(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipOutDiscards object value.
Definition: mib2_impl_ip.c:279
#define ARP_CACHE_SIZE
Definition: arp.h:46
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t mib2GetIpInAddrErrors(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipInAddrErrors object value.
Definition: mib2_impl_ip.c:116
error_t
Error codes.
Definition: error.h:43
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:258
error_t mib2GetIpInUnknownProtos(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipInUnknownProtos object value.
Definition: mib2_impl_ip.c:172
error_t mib2GetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipNetToMediaEntry object value.
Definition: mib2_impl_ip.c:731
MacAddr macAddr
Link layer address associated with the IPv4 address.
Definition: arp.h:192
error_t mib2GetIpOutRequests(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipOutRequests object value.
Definition: mib2_impl_ip.c:252
#define NetInterface
Definition: net.h:40
MIB-II module implementation (IP group)
General definitions for cryptographic algorithms.
NetContext * netGetDefaultContext(void)
Get default TCP/IP stack context.
Definition: net.c:527
error_t mib2GetIpFragOKs(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipFragOKs object value.
Definition: mib2_impl_ip.c:412
#define IPV4_ADDR_LIST_SIZE
Definition: ipv4.h:80
error_t mib2GetIpOutNoRoutes(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipOutNoRoutes object value.
Definition: mib2_impl_ip.c:306
error_t mib2GetIpInDiscards(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipInDiscards object value.
Definition: mib2_impl_ip.c:199
ArpState state
Reachability state.
Definition: arp.h:190
IPv4 address entry.
Definition: ipv4.h:410
error_t mib2GetIpInHdrErrors(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipInHdrErrors object value.
Definition: mib2_impl_ip.c:87
MIB-II module implementation.
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 mibEncodeIpv4Addr(uint8_t *oid, size_t maxOidLen, size_t *pos, Ipv4Addr ipAddr)
Encode instance identifier (IPv4 address)
Definition: mib_common.c:664
ArpCacheEntry * arpFindEntry(NetInterface *interface, Ipv4Addr ipAddr)
Search the ARP cache for a given IPv4 address.
Definition: arp_cache.c:156
Common definitions for MIB modules.
uint8_t n
@ ERROR_WRITE_FAILED
Definition: error.h:223
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:257
#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
error_t mib2GetIpInReceives(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipInReceives object value.
Definition: mib2_impl_ip.c:60
#define ipv4CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv4.h:166
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
error_t mib2GetIpReasmReqds(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipReasmReqds object value.
Definition: mib2_impl_ip.c:333
@ IPV4_ADDR_STATE_VALID
An address assigned to an interface whose use is unrestricted.
Definition: ipv4.h:228
error_t mibDecodeIpv4Addr(const uint8_t *oid, size_t oidLen, size_t *pos, Ipv4Addr *ipAddr)
Decode instance identifier (IPv4 address)
Definition: mib_common.c:698
MibVariant
Definition: mib_common.h:196
unsigned int uint_t
Definition: compiler_port.h:57
TCP/IP stack core.
error_t mib2GetNextIpAddrEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipAddrEntry object.
Definition: mib2_impl_ip.c:603
@ MIB2_IP_NET_TO_MEDIA_TYPE_DYNAMIC
Definition: mib2_module.h:262
error_t mib2GetIpReasmOKs(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipReasmOKs object value.
Definition: mib2_impl_ip.c:360
Ipv4Addr ipAddr
Unicast IPv4 address.
Definition: arp.h:191
#define ntohl(value)
Definition: cpu_endian.h:422
error_t mib2GetIpFragFails(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ipFragFails object value.
Definition: mib2_impl_ip.c:439
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:128
error_t mib2GetNextIpNetToMediaEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ipNetToMediaEntry object.
Definition: mib2_impl_ip.c:840