mib2_impl.c
Go to the documentation of this file.
1 /**
2  * @file mib2_impl.c
3  * @brief MIB-II module implementation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Dependencies
32 #include "core/net.h"
33 #include "mibs/mib_common.h"
34 #include "mibs/mib2_module.h"
35 #include "mibs/mib2_impl.h"
36 #include "core/crypto.h"
37 #include "encoding/asn1.h"
38 #include "encoding/oid.h"
39 #include "debug.h"
40 
41 //Check TCP/IP stack configuration
42 #if (MIB2_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief MIB-II module initialization
47  * @return Error code
48  **/
49 
51 {
52  uint_t i;
53  Mib2SysGroup *sysGroup;
54  Mib2IfGroup *ifGroup;
55 #if (IPV4_SUPPORT == ENABLED)
56  Mib2IpGroup *ipGroup;
57 #endif
58 #if (TCP_SUPPORT == ENABLED)
59  Mib2TcpGroup *tcpGroup;
60 #endif
61 
62  //Debug message
63  TRACE_INFO("Initializing MIB-II base...\r\n");
64 
65  //Clear MIB-II base
66  memset(&mib2Base, 0, sizeof(mib2Base));
67 
68  //Point to the system group
69  sysGroup = &mib2Base.sysGroup;
70 
71 #if (MIB2_SYS_DESCR_SIZE > 0)
72  //sysDescr object
73  strcpy(sysGroup->sysDescr, "Description");
74  sysGroup->sysDescrLen = strlen(sysGroup->sysDescr);
75 #endif
76 
77 #if (MIB2_SYS_OBJECT_ID_SIZE > 0)
78  //sysObjectID object
79  sysGroup->sysObjectID[0] = 0;
80  sysGroup->sysObjectIDLen = 1;
81 #endif
82 
83 #if (MIB2_SYS_CONTACT_SIZE > 0)
84  //sysContact object
85  strcpy(sysGroup->sysContact, "Contact");
86  sysGroup->sysContactLen = strlen(sysGroup->sysContact);
87 #endif
88 
89 #if (MIB2_SYS_NAME_SIZE > 0)
90  //sysName object
91  strcpy(sysGroup->sysName, "Name");
92  sysGroup->sysNameLen = strlen(sysGroup->sysName);
93 #endif
94 
95 #if (MIB2_SYS_LOCATION_SIZE > 0)
96  //sysLocation object
97  strcpy(sysGroup->sysLocation, "Location");
98  sysGroup->sysLocationLen = strlen(sysGroup->sysLocation);
99 #endif
100 
101  //sysServices object
103 
104  //Point to the interfaces group
105  ifGroup = &mib2Base.ifGroup;
106 
107  //ifNumber object
108  ifGroup->ifNumber = NET_INTERFACE_COUNT;
109 
110  //Interfaces table entry
111  for(i = 0; i < NET_INTERFACE_COUNT; i++)
112  {
113  //ifSpecific object
114  ifGroup->ifTable[i].ifSpecific[0] = 0;
115  ifGroup->ifTable[i].ifSpecificLen = 1;
116  }
117 
118 #if (IPV4_SUPPORT == ENABLED)
119  //Point to the IP group
120  ipGroup = &mib2Base.ipGroup;
121 
122  //ipForwarding object
124  //ipDefaultTTL object
125  ipGroup->ipDefaultTTL = IPV4_DEFAULT_TTL;
126  //ipReasmTimeout object
127  ipGroup->ipReasmTimeout = IPV4_FRAG_TIME_TO_LIVE / 1000;
128 #endif
129 
130 #if (TCP_SUPPORT == ENABLED)
131  //Point to the TCP group
132  tcpGroup = &mib2Base.tcpGroup;
133 
134  //tcpRtoAlgorithm object
136  //tcpRtoMin object
137  tcpGroup->tcpRtoMin = TCP_MIN_RTO;
138  //tcpRtoMax object
139  tcpGroup->tcpRtoMax = TCP_MAX_RTO;
140  //tcpMaxConn object
141  tcpGroup->tcpMaxConn = SOCKET_MAX_COUNT;
142 #endif
143 
144  //Successful processing
145  return NO_ERROR;
146 }
147 
148 
149 #if (MIB2_SYS_GROUP_SUPPORT == ENABLED)
150 
151 /**
152  * @brief Get sysUpTime object value
153  * @param[in] object Pointer to the MIB object descriptor
154  * @param[in] oid Object identifier (object name and instance identifier)
155  * @param[in] oidLen Length of the OID, in bytes
156  * @param[out] value Object value
157  * @param[in,out] valueLen Length of the object value, in bytes
158  * @return Error code
159  **/
160 
161 error_t mib2GetSysUpTime(const MibObject *object, const uint8_t *oid,
162  size_t oidLen, MibVariant *value, size_t *valueLen)
163 {
164  //Get object value
165  value->timeTicks = osGetSystemTime() / 10;
166 
167  //Successful processing
168  return NO_ERROR;
169 }
170 
171 #endif
172 #if (MIB2_IF_GROUP_SUPPORT == ENABLED)
173 
174 /**
175  * @brief Set ifEntry object value
176  * @param[in] object Pointer to the MIB object descriptor
177  * @param[in] oid Object identifier (object name and instance identifier)
178  * @param[in] oidLen Length of the OID, in bytes
179  * @param[in] value Object value
180  * @param[in] valueLen Length of the object value, in bytes
181  * @param[in] commit This flag tells whether the changes shall be committed
182  * to the MIB base
183  * @return Error code
184  **/
185 
186 error_t mib2SetIfEntry(const MibObject *object, const uint8_t *oid,
187  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
188 {
189  //Not implemented
190  return ERROR_WRITE_FAILED;
191 }
192 
193 
194 /**
195  * @brief Get ifEntry object value
196  * @param[in] object Pointer to the MIB object descriptor
197  * @param[in] oid Object identifier (object name and instance identifier)
198  * @param[in] oidLen Length of the OID, in bytes
199  * @param[out] value Object value
200  * @param[in,out] valueLen Length of the object value, in bytes
201  * @return Error code
202  **/
203 
204 error_t mib2GetIfEntry(const MibObject *object, const uint8_t *oid,
205  size_t oidLen, MibVariant *value, size_t *valueLen)
206 {
207  error_t error;
208  size_t n;
209  uint_t index;
210  Mib2IfEntry *entry;
211  NetInterface *interface;
212  NetInterface *logicalInterface;
213  NetInterface *physicalInterface;
214 
215  //Point to the instance identifier
216  n = object->oidLen;
217 
218  //ifIndex is used as instance identifier
219  error = mibDecodeIndex(oid, oidLen, &n, &index);
220  //Invalid instance identifier?
221  if(error)
222  return error;
223 
224  //Sanity check
225  if(n != oidLen)
227 
228  //Check index range
229  if(index < 1 || index > NET_INTERFACE_COUNT)
231 
232  //Point to the underlying interface
233  interface = &netInterface[index - 1];
234  //Point to the interface table entry
235  entry = &mib2Base.ifGroup.ifTable[index - 1];
236 
237  //Point to the logical interface
238  logicalInterface = nicGetLogicalInterface(interface);
239  //Point to the physical interface
240  physicalInterface = nicGetPhysicalInterface(interface);
241 
242  //ifIndex object?
243  if(!strcmp(object->name, "ifIndex"))
244  {
245  //Get object value
246  value->integer = index;
247  }
248  //ifDescr object?
249  else if(!strcmp(object->name, "ifDescr"))
250  {
251  //Retrieve the length of the interface name
252  n = strlen(interface->name);
253 
254  //Make sure the buffer is large enough to hold the entire object
255  if(*valueLen >= n)
256  {
257  //Copy object value
258  memcpy(value->octetString, interface->name, n);
259  //Return object length
260  *valueLen = n;
261  }
262  else
263  {
264  //Report an error
265  error = ERROR_BUFFER_OVERFLOW;
266  }
267  }
268  //ifType object?
269  else if(!strcmp(object->name, "ifType"))
270  {
271 #if (ETH_VLAN_SUPPORT == ENABLED)
272  //VLAN interface?
273  if(interface->vlanId != 0)
274  {
275  //Layer 2 virtual LAN using 802.1Q
276  value->integer = MIB2_IF_TYPE_L2_VLAN;
277  }
278  else
279 #endif
280  {
281  //Sanity check
282  if(physicalInterface->nicDriver != NULL)
283  {
284  //Get interface type
285  switch(physicalInterface->nicDriver->type)
286  {
287  //Ethernet interface
288  case NIC_TYPE_ETHERNET:
290  break;
291  //PPP interface
292  case NIC_TYPE_PPP:
293  value->integer = MIB2_IF_TYPE_PPP;
294  break;
295  //IEEE 802.15.4 WPAN interface
296  case NIC_TYPE_6LOWPAN:
298  break;
299  //Unknown interface type
300  default:
301  value->integer = MIB2_IF_TYPE_OTHER;
302  break;
303  }
304  }
305  else
306  {
307  //Unknown interface type
308  value->integer = MIB2_IF_TYPE_OTHER;
309  }
310  }
311  }
312  //ifMtu object?
313  else if(!strcmp(object->name, "ifMtu"))
314  {
315  //Get interface MTU
316  if(physicalInterface->nicDriver != NULL)
317  value->integer = physicalInterface->nicDriver->mtu;
318  else
319  value->integer = 0;
320  }
321  //ifSpeed object?
322  else if(!strcmp(object->name, "ifSpeed"))
323  {
324  //Get interface's current bandwidth
325  value->gauge32 = interface->linkSpeed;
326  }
327  //ifPhysAddress object?
328  else if(!strcmp(object->name, "ifPhysAddress"))
329  {
330  //Make sure the buffer is large enough to hold the entire object
331  if(*valueLen >= MIB2_PHYS_ADDRESS_SIZE)
332  {
333  //Copy object value
334  macCopyAddr(value->octetString, &logicalInterface->macAddr);
335  //Return object length
336  *valueLen = MIB2_PHYS_ADDRESS_SIZE;
337  }
338  else
339  {
340  //Report an error
341  error = ERROR_BUFFER_OVERFLOW;
342  }
343  }
344  //ifAdminStatus object?
345  else if(!strcmp(object->name, "ifAdminStatus"))
346  {
347  //Check whether the interface is enabled for operation
348  if(physicalInterface->nicDriver != NULL)
349  value->integer = MIB2_IF_ADMIN_STATUS_UP;
350  else
351  value->integer = MIB2_IF_ADMIN_STATUS_DOWN;
352  }
353  //ifOperStatus object?
354  else if(!strcmp(object->name, "ifOperStatus"))
355  {
356  //Get the current operational state of the interface
357  if(interface->linkState)
358  value->integer = MIB2_IF_OPER_STATUS_UP;
359  else
360  value->integer = MIB2_IF_OPER_STATUS_DOWN;
361  }
362  //ifLastChange object?
363  else if(!strcmp(object->name, "ifLastChange"))
364  {
365  //Get object value
366  value->timeTicks = entry->ifLastChange;
367  }
368  //ifInOctets object?
369  else if(!strcmp(object->name, "ifInOctets"))
370  {
371  //Get object value
372  value->counter32 = entry->ifInOctets;
373  }
374  //ifInUcastPkts object?
375  else if(!strcmp(object->name, "ifInUcastPkts"))
376  {
377  //Get object value
378  value->counter32 = entry->ifInUcastPkts;
379  }
380  //ifInNUcastPkts object?
381  else if(!strcmp(object->name, "ifInNUcastPkts"))
382  {
383  //Get object value
384  value->counter32 = entry->ifInNUcastPkts;
385  }
386  //ifInDiscards object?
387  else if(!strcmp(object->name, "ifInDiscards"))
388  {
389  //Get object value
390  value->counter32 = entry->ifInDiscards;
391  }
392  //ifInErrors object?
393  else if(!strcmp(object->name, "ifInErrors"))
394  {
395  //Get object value
396  value->counter32 = entry->ifInErrors;
397  }
398  //ifInUnknownProtos object?
399  else if(!strcmp(object->name, "ifInUnknownProtos"))
400  {
401  //Get object value
402  value->counter32 = entry->ifInUnknownProtos;
403  }
404  //ifOutOctets object?
405  else if(!strcmp(object->name, "ifOutOctets"))
406  {
407  //Get object value
408  value->counter32 = entry->ifOutOctets;
409  }
410  //ifOutUcastPkts object?
411  else if(!strcmp(object->name, "ifOutUcastPkts"))
412  {
413  //Get object value
414  value->counter32 = entry->ifOutUcastPkts;
415  }
416  //ifOutNUcastPkts object?
417  else if(!strcmp(object->name, "ifOutNUcastPkts"))
418  {
419  //Get object value
420  value->counter32 = entry->ifOutNUcastPkts;
421  }
422  //ifOutDiscards object?
423  else if(!strcmp(object->name, "ifOutDiscards"))
424  {
425  //Get object value
426  value->counter32 = entry->ifOutDiscards;
427  }
428  //ifOutErrors object?
429  else if(!strcmp(object->name, "ifOutErrors"))
430  {
431  //Get object value
432  value->counter32 = entry->ifOutErrors;
433  }
434  //ifOutQLen object?
435  else if(!strcmp(object->name, "ifOutQLen"))
436  {
437  //Get object value
438  value->gauge32 = entry->ifOutQLen;
439  }
440  //ifSpecific object?
441  else if(!strcmp(object->name, "ifSpecific"))
442  {
443  //Make sure the buffer is large enough to hold the entire object
444  if(*valueLen >= entry->ifSpecificLen)
445  {
446  //Copy object value
447  memcpy(value->oid, entry->ifSpecific, entry->ifSpecificLen);
448  //Return object length
449  *valueLen = entry->ifSpecificLen;
450  }
451  else
452  {
453  //Report an error
454  error = ERROR_BUFFER_OVERFLOW;
455  }
456  }
457  //Unknown object?
458  else
459  {
460  //The specified object does not exist
461  error = ERROR_OBJECT_NOT_FOUND;
462  }
463 
464  //Return status code
465  return error;
466 }
467 
468 
469 /**
470  * @brief Get next ifEntry object
471  * @param[in] object Pointer to the MIB object descriptor
472  * @param[in] oid Object identifier
473  * @param[in] oidLen Length of the OID, in bytes
474  * @param[out] nextOid OID of the next object in the MIB
475  * @param[out] nextOidLen Length of the next object identifier, in bytes
476  * @return Error code
477  **/
478 
479 error_t mib2GetNextIfEntry(const MibObject *object, const uint8_t *oid,
480  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
481 {
482  error_t error;
483  size_t n;
484  uint_t index;
485 
486  //Make sure the buffer is large enough to hold the OID prefix
487  if(*nextOidLen < object->oidLen)
488  return ERROR_BUFFER_OVERFLOW;
489 
490  //Copy OID prefix
491  memcpy(nextOid, object->oid, object->oidLen);
492 
493  //Loop through network interfaces
494  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
495  {
496  //Append the instance identifier to the OID prefix
497  n = object->oidLen;
498 
499  //ifIndex is used as instance identifier
500  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
501  //Any error to report?
502  if(error)
503  return error;
504 
505  //Check whether the resulting object identifier lexicographically
506  //follows the specified OID
507  if(oidComp(nextOid, n, oid, oidLen) > 0)
508  {
509  //Save the length of the resulting object identifier
510  *nextOidLen = n;
511  //Next object found
512  return NO_ERROR;
513  }
514  }
515 
516  //The specified OID does not lexicographically precede the name
517  //of some object
518  return ERROR_OBJECT_NOT_FOUND;
519 }
520 
521 #endif
522 #if (MIB2_IP_GROUP_SUPPORT == ENABLED && IPV4_SUPPORT == ENABLED)
523 
524 /**
525  * @brief Get ipAddrEntry object value
526  * @param[in] object Pointer to the MIB object descriptor
527  * @param[in] oid Object identifier (object name and instance identifier)
528  * @param[in] oidLen Length of the OID, in bytes
529  * @param[out] value Object value
530  * @param[in,out] valueLen Length of the object value, in bytes
531  * @return Error code
532  **/
533 
534 error_t mib2GetIpAddrEntry(const MibObject *object, const uint8_t *oid,
535  size_t oidLen, MibVariant *value, size_t *valueLen)
536 {
537  error_t error;
538  size_t n;
539  uint_t i;
540  uint_t index;
542  Ipv4AddrEntry *entry;
543  NetInterface *interface;
544 
545  //Point to the instance identifier
546  n = object->oidLen;
547 
548  //ipAdEntAddr is used as instance identifier
549  error = mibDecodeIpv4Addr(oid, oidLen, &n, &ipAddr);
550  //Invalid instance identifier?
551  if(error)
552  return error;
553 
554  //Sanity check
555  if(n != oidLen)
557 
558  //Loop through network interfaces
559  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
560  {
561  //Point to the current interface
562  interface = &netInterface[index - 1];
563 
564  //Loop through the list of IPv4 addresses assigned to the interface
565  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
566  {
567  //Point to the current entry
568  entry = &interface->ipv4Context.addrList[i];
569 
570  //Compare the current address against the IP address used as
571  //instance identifier
572  if(entry->state == IPV4_ADDR_STATE_VALID &&
573  entry->addr == ipAddr)
574  {
575  break;
576  }
577  }
578 
579  //IPv4 address found?
580  if(i < IPV4_ADDR_LIST_SIZE)
581  break;
582  }
583 
584  //IP address not assigned to any interface?
585  if(index > NET_INTERFACE_COUNT)
587 
588  //ipAdEntAddr object?
589  if(!strcmp(object->name, "ipAdEntAddr"))
590  {
591  //Get object value
592  ipv4CopyAddr(value->ipAddr, &entry->addr);
593  }
594  //ipAdEntIfIndex object?
595  else if(!strcmp(object->name, "ipAdEntIfIndex"))
596  {
597  //Get object value
598  value->integer = index;
599  }
600  //ipAdEntNetMask object?
601  else if(!strcmp(object->name, "ipAdEntNetMask"))
602  {
603  //Get object value
604  ipv4CopyAddr(value->ipAddr, &entry->subnetMask);
605  }
606  //ipAdEntBcastAddr object?
607  else if(!strcmp(object->name, "ipAdEntBcastAddr"))
608  {
609  //Get object value
610  value->integer = 1;
611  }
612  //ipAdEntReasmMaxSize object?
613  else if(!strcmp(object->name, "ipAdEntReasmMaxSize"))
614  {
615  //Get object value
617  }
618  //Unknown object?
619  else
620  {
621  //The specified object does not exist
622  error = ERROR_OBJECT_NOT_FOUND;
623  }
624 
625  //Return status code
626  return error;
627 }
628 
629 
630 /**
631  * @brief Get next ipAddrEntry object
632  * @param[in] object Pointer to the MIB object descriptor
633  * @param[in] oid Object identifier
634  * @param[in] oidLen Length of the OID, in bytes
635  * @param[out] nextOid OID of the next object in the MIB
636  * @param[out] nextOidLen Length of the next object identifier, in bytes
637  * @return Error code
638  **/
639 
640 error_t mib2GetNextIpAddrEntry(const MibObject *object, const uint8_t *oid,
641  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
642 {
643  error_t error;
644  uint_t i;
645  size_t n;
646  uint_t index;
647  bool_t acceptable;
649  Ipv4AddrEntry *entry;
650  NetInterface *interface;
651 
652  //Initialize IP address
654 
655  //Make sure the buffer is large enough to hold the OID prefix
656  if(*nextOidLen < object->oidLen)
657  return ERROR_BUFFER_OVERFLOW;
658 
659  //Copy OID prefix
660  memcpy(nextOid, object->oid, object->oidLen);
661 
662  //Loop through network interfaces
663  for(index = 1; index <= NET_INTERFACE_COUNT; index++)
664  {
665  //Point to the current interface
666  interface = &netInterface[index - 1];
667 
668  //Loop through the list of IPv4 addresses assigned to the interface
669  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
670  {
671  //Point to the current entry
672  entry = &interface->ipv4Context.addrList[i];
673 
674  //Valid IPv4 address?
675  if(entry->state == IPV4_ADDR_STATE_VALID)
676  {
677  //Append the instance identifier to the OID prefix
678  n = object->oidLen;
679 
680  //ipAdEntAddr is used as instance identifier
681  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, entry->addr);
682  //Any error to report?
683  if(error)
684  return error;
685 
686  //Check whether the resulting object identifier lexicographically
687  //follows the specified OID
688  if(oidComp(nextOid, n, oid, oidLen) > 0)
689  {
690  //Perform lexicographic comparison
692  acceptable = TRUE;
693  else if(ntohl(entry->addr) < ntohl(ipAddr))
694  acceptable = TRUE;
695  else
696  acceptable = FALSE;
697 
698  //Save the closest object identifier that follows the specified
699  //OID in lexicographic order
700  if(acceptable)
701  ipAddr = entry->addr;
702  }
703  }
704  }
705  }
706 
707  //The specified OID does not lexicographically precede the name
708  //of some object?
710  return ERROR_OBJECT_NOT_FOUND;
711 
712  //Append the instance identifier to the OID prefix
713  n = object->oidLen;
714 
715  //ipAdEntAddr is used as instance identifier
716  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, ipAddr);
717  //Any error to report?
718  if(error)
719  return error;
720 
721  //Save the length of the resulting object identifier
722  *nextOidLen = n;
723  //Next object found
724  return NO_ERROR;
725 }
726 
727 
728 /**
729  * @brief Set ipNetToMediaEntry object value
730  * @param[in] object Pointer to the MIB object descriptor
731  * @param[in] oid Object identifier (object name and instance identifier)
732  * @param[in] oidLen Length of the OID, in bytes
733  * @param[in] value Object value
734  * @param[in] valueLen Length of the object value, in bytes
735  * @param[in] commit This flag tells whether the changes shall be committed
736  * to the MIB base
737  * @return Error code
738  **/
739 
740 error_t mib2SetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid,
741  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
742 {
743  //Not implemented
744  return ERROR_WRITE_FAILED;
745 }
746 
747 
748 /**
749  * @brief Get ipNetToMediaEntry object value
750  * @param[in] object Pointer to the MIB object descriptor
751  * @param[in] oid Object identifier (object name and instance identifier)
752  * @param[in] oidLen Length of the OID, in bytes
753  * @param[out] value Object value
754  * @param[in,out] valueLen Length of the object value, in bytes
755  * @return Error code
756  **/
757 
758 error_t mib2GetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid,
759  size_t oidLen, MibVariant *value, size_t *valueLen)
760 {
761  error_t error;
762  size_t n;
763  uint_t index;
765  NetInterface *interface;
766  ArpCacheEntry *entry;
767 
768  //Point to the instance identifier
769  n = object->oidLen;
770 
771  //ipNetToMediaIfIndex is used as 1st instance identifier
772  error = mibDecodeIndex(oid, oidLen, &n, &index);
773  //Invalid instance identifier?
774  if(error)
775  return error;
776 
777  //ipNetToMediaNetAddress is used as 2nd instance identifier
778  error = mibDecodeIpv4Addr(oid, oidLen, &n, &ipAddr);
779  //Invalid instance identifier?
780  if(error)
781  return error;
782 
783  //Sanity check
784  if(n != oidLen)
786 
787  //Check index range
788  if(index < 1 || index > NET_INTERFACE_COUNT)
790 
791  //Point to the network interface
792  interface = &netInterface[index - 1];
793 
794  //Search the ARP cache for the specified IP address
795  entry = arpFindEntry(interface, ipAddr);
796 
797  //No matching entry found?
798  if(entry == NULL)
800 
801  //ipNetToMediaIfIndex object?
802  if(!strcmp(object->name, "ipNetToMediaIfIndex"))
803  {
804  //Get object value
805  value->integer = index;
806  }
807  //ipNetToMediaPhysAddress object?
808  else if(!strcmp(object->name, "ipNetToMediaPhysAddress"))
809  {
810  //Make sure the buffer is large enough to hold the entire object
811  if(*valueLen >= MIB2_PHYS_ADDRESS_SIZE)
812  {
813  //Copy object value
814  macCopyAddr(value->octetString, &entry->macAddr);
815  //Return object length
816  *valueLen = MIB2_PHYS_ADDRESS_SIZE;
817  }
818  else
819  {
820  //Report an error
821  error = ERROR_BUFFER_OVERFLOW;
822  }
823  }
824  //ipNetToMediaNetAddress object?
825  else if(!strcmp(object->name, "ipNetToMediaNetAddress"))
826  {
827  //Get object value
828  ipv4CopyAddr(value->ipAddr, &entry->ipAddr);
829  }
830  //ipNetToMediaType object?
831  else if(!strcmp(object->name, "ipNetToMediaType"))
832  {
833  //Get object value
835  }
836  //Unknown object?
837  else
838  {
839  //The specified object does not exist
840  error = ERROR_OBJECT_NOT_FOUND;
841  }
842 
843  //Return status code
844  return error;
845 }
846 
847 
848 /**
849  * @brief Get next ipNetToMediaEntry object
850  * @param[in] object Pointer to the MIB object descriptor
851  * @param[in] oid Object identifier
852  * @param[in] oidLen Length of the OID, in bytes
853  * @param[out] nextOid OID of the next object in the MIB
854  * @param[out] nextOidLen Length of the next object identifier, in bytes
855  * @return Error code
856  **/
857 
858 error_t mib2GetNextIpNetToMediaEntry(const MibObject *object, const uint8_t *oid,
859  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
860 {
861  error_t error;
862  uint_t i;
863  uint_t j;
864  size_t n;
865  uint_t index;
866  bool_t acceptable;
868  NetInterface *interface;
869  ArpCacheEntry *entry;
870 
871  //Initialize variables
872  index = 0;
874 
875  //Make sure the buffer is large enough to hold the OID prefix
876  if(*nextOidLen < object->oidLen)
877  return ERROR_BUFFER_OVERFLOW;
878 
879  //Copy OID prefix
880  memcpy(nextOid, object->oid, object->oidLen);
881 
882  //Loop through network interfaces
883  for(i = 1; i <= NET_INTERFACE_COUNT; i++)
884  {
885  //Point to the current interface
886  interface = &netInterface[i - 1];
887 
888  //Loop through ARP cache entries
889  for(j = 0; j < ARP_CACHE_SIZE; j++)
890  {
891  //Point to the current entry
892  entry = &interface->arpCache[j];
893 
894  //Valid entry?
895  if(entry->state != ARP_STATE_NONE)
896  {
897  //Append the instance identifier to the OID prefix
898  n = object->oidLen;
899 
900  //ipNetToMediaIfIndex is used as 1st instance identifier
901  error = mibEncodeIndex(nextOid, *nextOidLen, &n, i);
902  //Any error to report?
903  if(error)
904  return error;
905 
906  //ipNetToMediaNetAddress is used as 2nd instance identifier
907  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, entry->ipAddr);
908  //Any error to report?
909  if(error)
910  return error;
911 
912  //Check whether the resulting object identifier lexicographically
913  //follows the specified OID
914  if(oidComp(nextOid, n, oid, oidLen) > 0)
915  {
916  //Perform lexicographic comparison
917  if(index == 0)
918  acceptable = TRUE;
919  else if(i < index)
920  acceptable = TRUE;
921  else if(i > index)
922  acceptable = FALSE;
923  else if(ntohl(entry->ipAddr) < ntohl(ipAddr))
924  acceptable = TRUE;
925  else
926  acceptable = FALSE;
927 
928  //Save the closest object identifier that follows the specified
929  //OID in lexicographic order
930  if(acceptable)
931  {
932  index = i;
933  ipAddr = entry->ipAddr;
934  }
935  }
936  }
937  }
938  }
939 
940  //The specified OID does not lexicographically precede the name
941  //of some object?
942  if(index == 0)
943  return ERROR_OBJECT_NOT_FOUND;
944 
945  //Append the instance identifier to the OID prefix
946  n = object->oidLen;
947 
948  //ipNetToMediaIfIndex is used as 1st instance identifier
949  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
950  //Any error to report?
951  if(error)
952  return error;
953 
954  //ipNetToMediaNetAddress is used as 2nd instance identifier
955  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, ipAddr);
956  //Any error to report?
957  if(error)
958  return error;
959 
960  //Save the length of the resulting object identifier
961  *nextOidLen = n;
962  //Next object found
963  return NO_ERROR;
964 }
965 
966 #endif
967 #if (MIB2_TCP_GROUP_SUPPORT == ENABLED && TCP_SUPPORT == ENABLED && IPV4_SUPPORT == ENABLED)
968 
969 /**
970  * @brief Get tcpCurrEstab object value
971  * @param[in] object Pointer to the MIB object descriptor
972  * @param[in] oid Object identifier (object name and instance identifier)
973  * @param[in] oidLen Length of the OID, in bytes
974  * @param[out] value Object value
975  * @param[in,out] valueLen Length of the object value, in bytes
976  * @return Error code
977  **/
978 
979 error_t mib2GetTcpCurrEstab(const MibObject *object, const uint8_t *oid,
980  size_t oidLen, MibVariant *value, size_t *valueLen)
981 {
982  uint_t i;
983  Socket *socket;
984 
985  //Initialize object value
986  value->gauge32 = 0;
987 
988  //Loop through socket descriptors
989  for(i = 0; i < SOCKET_MAX_COUNT; i++)
990  {
991  //Point to current socket
992  socket = &socketTable[i];
993 
994  //TCP socket?
995  if(socket->type == SOCKET_TYPE_STREAM)
996  {
997  //Filter out IPv6 connections
998  if(socket->localIpAddr.length != sizeof(Ipv6Addr) &&
999  socket->remoteIpAddr.length != sizeof(Ipv6Addr))
1000  {
1001  //Check current state
1002  if(socket->state == TCP_STATE_ESTABLISHED ||
1003  socket->state == TCP_STATE_CLOSE_WAIT)
1004  {
1005  //Number of TCP connections for which the current state
1006  //is either ESTABLISHED or CLOSE-WAIT
1007  value->gauge32++;
1008  }
1009  }
1010  }
1011  }
1012 
1013  //Return status code
1014  return NO_ERROR;
1015 }
1016 
1017 
1018 /**
1019  * @brief Set tcpConnEntry object value
1020  * @param[in] object Pointer to the MIB object descriptor
1021  * @param[in] oid Object identifier (object name and instance identifier)
1022  * @param[in] oidLen Length of the OID, in bytes
1023  * @param[out] value Object value
1024  * @param[in] valueLen Length of the object value, in bytes
1025  * @param[in] commit This flag tells whether the changes shall be committed
1026  * to the MIB base
1027  * @return Error code
1028  **/
1029 
1030 error_t mib2SetTcpConnEntry(const MibObject *object, const uint8_t *oid,
1031  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
1032 {
1033  //Not implemented
1034  return ERROR_WRITE_FAILED;
1035 }
1036 
1037 
1038 /**
1039  * @brief Get tcpConnEntry object value
1040  * @param[in] object Pointer to the MIB object descriptor
1041  * @param[in] oid Object identifier (object name and instance identifier)
1042  * @param[in] oidLen Length of the OID, in bytes
1043  * @param[out] value Object value
1044  * @param[in,out] valueLen Length of the object value, in bytes
1045  * @return Error code
1046  **/
1047 
1048 error_t mib2GetTcpConnEntry(const MibObject *object, const uint8_t *oid,
1049  size_t oidLen, MibVariant *value, size_t *valueLen)
1050 {
1051  error_t error;
1052  uint_t i;
1053  size_t n;
1054  Ipv4Addr localIpAddr;
1055  uint16_t localPort;
1056  Ipv4Addr remoteIpAddr;
1057  uint16_t remotePort;
1058  Socket *socket;
1059 
1060  //Point to the instance identifier
1061  n = object->oidLen;
1062 
1063  //tcpConnLocalAddress is used as 1st instance identifier
1064  error = mibDecodeIpv4Addr(oid, oidLen, &n, &localIpAddr);
1065  //Invalid instance identifier?
1066  if(error)
1067  return error;
1068 
1069  //tcpConnLocalPort is used as 2nd instance identifier
1070  error = mibDecodePort(oid, oidLen, &n, &localPort);
1071  //Invalid instance identifier?
1072  if(error)
1073  return error;
1074 
1075  //tcpConnRemAddress is used as 3rd instance identifier
1076  error = mibDecodeIpv4Addr(oid, oidLen, &n, &remoteIpAddr);
1077  //Invalid instance identifier?
1078  if(error)
1079  return error;
1080 
1081  //tcpConnRemPort is used as 4th instance identifier
1082  error = mibDecodePort(oid, oidLen, &n, &remotePort);
1083  //Invalid instance identifier?
1084  if(error)
1085  return error;
1086 
1087  //Sanity check
1088  if(n != oidLen)
1089  return ERROR_INSTANCE_NOT_FOUND;
1090 
1091  //Loop through socket descriptors
1092  for(i = 0; i < SOCKET_MAX_COUNT; i++)
1093  {
1094  //Point to current socket
1095  socket = &socketTable[i];
1096 
1097  //TCP socket?
1098  if(socket->type == SOCKET_TYPE_STREAM)
1099  {
1100  //Check local IP address
1101  if(socket->localIpAddr.length == sizeof(Ipv6Addr))
1102  continue;
1103  if(socket->localIpAddr.ipv4Addr != localIpAddr)
1104  continue;
1105  //Check local port number
1106  if(socket->localPort != localPort)
1107  continue;
1108  //Check remote IP address
1109  if(socket->remoteIpAddr.length == sizeof(Ipv6Addr))
1110  continue;
1111  if(socket->remoteIpAddr.ipv4Addr != remoteIpAddr)
1112  continue;
1113  //Check remote port number
1114  if(socket->remotePort != remotePort)
1115  continue;
1116 
1117  //A matching socket has been found
1118  break;
1119  }
1120  }
1121 
1122  //No matching connection found in socket table?
1123  if(i >= SOCKET_MAX_COUNT)
1124  return ERROR_INSTANCE_NOT_FOUND;
1125 
1126  //tcpConnState object?
1127  if(!strcmp(object->name, "tcpConnState"))
1128  {
1129  //Get object value
1130  switch(socket->state)
1131  {
1132  case TCP_STATE_CLOSED:
1133  value->integer = MIB2_TCP_CONN_STATE_CLOSED;
1134  break;
1135  case TCP_STATE_LISTEN:
1136  value->integer = MIB2_TCP_CONN_STATE_LISTEN;
1137  break;
1138  case TCP_STATE_SYN_SENT:
1140  break;
1143  break;
1144  case TCP_STATE_ESTABLISHED:
1146  break;
1147  case TCP_STATE_FIN_WAIT_1:
1149  break;
1150  case TCP_STATE_FIN_WAIT_2:
1152  break;
1153  case TCP_STATE_CLOSE_WAIT:
1155  break;
1156  case TCP_STATE_LAST_ACK:
1158  break;
1159  case TCP_STATE_CLOSING:
1161  break;
1162  case TCP_STATE_TIME_WAIT:
1164  break;
1165  default:
1166  value->integer = 0;
1167  break;
1168  }
1169  }
1170  //tcpConnLocalAddress object?
1171  else if(!strcmp(object->name, "tcpConnLocalAddress"))
1172  {
1173  //Get object value
1174  ipv4CopyAddr(value->ipAddr, &socket->localIpAddr.ipv4Addr);
1175  }
1176  //tcpConnLocalPort object?
1177  else if(!strcmp(object->name, "tcpConnLocalPort"))
1178  {
1179  //Get object value
1180  value->integer = socket->localPort;
1181  }
1182  //tcpConnRemAddress object?
1183  else if(!strcmp(object->name, "tcpConnRemAddress"))
1184  {
1185  //Get object value
1186  ipv4CopyAddr(value->ipAddr, &socket->remoteIpAddr.ipv4Addr);
1187  }
1188  //tcpConnRemPort object?
1189  else if(!strcmp(object->name, "tcpConnRemPort"))
1190  {
1191  //Get object value
1192  value->integer = socket->remotePort;
1193  }
1194  //Unknown object?
1195  else
1196  {
1197  //The specified object does not exist
1198  error = ERROR_OBJECT_NOT_FOUND;
1199  }
1200 
1201  //Return status code
1202  return error;
1203 }
1204 
1205 
1206 /**
1207  * @brief Get next tcpConnEntry object
1208  * @param[in] object Pointer to the MIB object descriptor
1209  * @param[in] oid Object identifier
1210  * @param[in] oidLen Length of the OID, in bytes
1211  * @param[out] nextOid OID of the next object in the MIB
1212  * @param[out] nextOidLen Length of the next object identifier, in bytes
1213  * @return Error code
1214  **/
1215 
1216 error_t mib2GetNextTcpConnEntry(const MibObject *object, const uint8_t *oid,
1217  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
1218 {
1219  error_t error;
1220  uint_t i;
1221  size_t n;
1222  bool_t acceptable;
1223  Ipv4Addr localIpAddr;
1224  uint16_t localPort;
1225  Ipv4Addr remoteIpAddr;
1226  uint16_t remotePort;
1227  Socket *socket;
1228 
1229  //Initialize variables
1230  localIpAddr = IPV4_UNSPECIFIED_ADDR;
1231  localPort = 0;
1232  remoteIpAddr = IPV4_UNSPECIFIED_ADDR;
1233  remotePort = 0;
1234 
1235  //Make sure the buffer is large enough to hold the OID prefix
1236  if(*nextOidLen < object->oidLen)
1237  return ERROR_BUFFER_OVERFLOW;
1238 
1239  //Copy OID prefix
1240  memcpy(nextOid, object->oid, object->oidLen);
1241 
1242  //Loop through socket descriptors
1243  for(i = 0; i < SOCKET_MAX_COUNT; i++)
1244  {
1245  //Point to current socket
1246  socket = &socketTable[i];
1247 
1248  //TCP socket?
1249  if(socket->type == SOCKET_TYPE_STREAM)
1250  {
1251  //Filter out IPv6 connections
1252  if(socket->localIpAddr.length != sizeof(Ipv6Addr) &&
1253  socket->remoteIpAddr.length != sizeof(Ipv6Addr))
1254  {
1255  //Append the instance identifier to the OID prefix
1256  n = object->oidLen;
1257 
1258  //tcpConnLocalAddress is used as 1st instance identifier
1259  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, socket->localIpAddr.ipv4Addr);
1260  //Any error to report?
1261  if(error)
1262  return error;
1263 
1264  //tcpConnLocalPort is used as 2nd instance identifier
1265  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort);
1266  //Any error to report?
1267  if(error)
1268  return error;
1269 
1270  //tcpConnRemAddress is used as 3rd instance identifier
1271  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, socket->remoteIpAddr.ipv4Addr);
1272  //Any error to report?
1273  if(error)
1274  return error;
1275 
1276  //tcpConnRemPort is used as 4th instance identifier
1277  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->remotePort);
1278  //Any error to report?
1279  if(error)
1280  return error;
1281 
1282  //Check whether the resulting object identifier lexicographically
1283  //follows the specified OID
1284  if(oidComp(nextOid, n, oid, oidLen) > 0)
1285  {
1286  //Perform lexicographic comparison
1287  if(localPort == 0 && remotePort == 0)
1288  acceptable = TRUE;
1289  else if(ntohl(socket->localIpAddr.ipv4Addr) < ntohl(localIpAddr))
1290  acceptable = TRUE;
1291  else if(ntohl(socket->localIpAddr.ipv4Addr) > ntohl(localIpAddr))
1292  acceptable = FALSE;
1293  else if(socket->localPort < localPort)
1294  acceptable = TRUE;
1295  else if(socket->localPort > localPort)
1296  acceptable = FALSE;
1297  else if(ntohl(socket->remoteIpAddr.ipv4Addr) < ntohl(remoteIpAddr))
1298  acceptable = TRUE;
1299  else if(ntohl(socket->remoteIpAddr.ipv4Addr) > ntohl(remoteIpAddr))
1300  acceptable = FALSE;
1301  else if(socket->remotePort < remotePort)
1302  acceptable = TRUE;
1303  else
1304  acceptable = FALSE;
1305 
1306  //Save the closest object identifier that follows the specified
1307  //OID in lexicographic order
1308  if(acceptable)
1309  {
1310  localIpAddr = socket->localIpAddr.ipv4Addr;
1311  localPort = socket->localPort;
1312  remoteIpAddr = socket->remoteIpAddr.ipv4Addr;
1313  remotePort = socket->remotePort;
1314  }
1315  }
1316  }
1317  }
1318  }
1319 
1320  //The specified OID does not lexicographically precede the name
1321  //of some object?
1322  if(localPort == 0 && remotePort == 0)
1323  return ERROR_OBJECT_NOT_FOUND;
1324 
1325  //Append the instance identifier to the OID prefix
1326  n = object->oidLen;
1327 
1328  //tcpConnLocalAddress is used as 1st instance identifier
1329  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, localIpAddr);
1330  //Any error to report?
1331  if(error)
1332  return error;
1333 
1334  //tcpConnLocalPort is used as 2nd instance identifier
1335  error = mibEncodePort(nextOid, *nextOidLen, &n, localPort);
1336  //Any error to report?
1337  if(error)
1338  return error;
1339 
1340  //tcpConnRemAddress is used as 3rd instance identifier
1341  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, remoteIpAddr);
1342  //Any error to report?
1343  if(error)
1344  return error;
1345 
1346  //tcpConnRemPort is used as 4th instance identifier
1347  error = mibEncodePort(nextOid, *nextOidLen, &n, remotePort);
1348  //Any error to report?
1349  if(error)
1350  return error;
1351 
1352  //Save the length of the resulting object identifier
1353  *nextOidLen = n;
1354  //Next object found
1355  return NO_ERROR;
1356 }
1357 
1358 #endif
1359 #if (MIB2_UDP_GROUP_SUPPORT == ENABLED && UDP_SUPPORT == ENABLED && IPV4_SUPPORT == ENABLED)
1360 
1361 /**
1362  * @brief Get udpEntry object value
1363  * @param[in] object Pointer to the MIB object descriptor
1364  * @param[in] oid Object identifier (object name and instance identifier)
1365  * @param[in] oidLen Length of the OID, in bytes
1366  * @param[out] value Object value
1367  * @param[in,out] valueLen Length of the object value, in bytes
1368  * @return Error code
1369  **/
1370 
1371 error_t mib2GetUdpEntry(const MibObject *object, const uint8_t *oid,
1372  size_t oidLen, MibVariant *value, size_t *valueLen)
1373 {
1374  error_t error;
1375  uint_t i;
1376  size_t n;
1377  Ipv4Addr localIpAddr;
1378  uint16_t localPort;
1379 
1380  //Point to the instance identifier
1381  n = object->oidLen;
1382 
1383  //udpLocalAddress is used as 1st instance identifier
1384  error = mibDecodeIpv4Addr(oid, oidLen, &n, &localIpAddr);
1385  //Invalid instance identifier?
1386  if(error)
1387  return error;
1388 
1389  //udpLocalPort is used as 2nd instance identifier
1390  error = mibDecodePort(oid, oidLen, &n, &localPort);
1391  //Invalid instance identifier?
1392  if(error)
1393  return error;
1394 
1395  //Sanity check
1396  if(n != oidLen)
1397  return ERROR_INSTANCE_NOT_FOUND;
1398 
1399  //Loop through socket descriptors
1400  for(i = 0; i < SOCKET_MAX_COUNT; i++)
1401  {
1402  //Point to current socket
1403  Socket *socket = &socketTable[i];
1404 
1405  //UDP socket?
1406  if(socket->type == SOCKET_TYPE_DGRAM)
1407  {
1408  //Check local IP address
1409  if(socket->localIpAddr.length == sizeof(Ipv6Addr))
1410  continue;
1411  if(socket->localIpAddr.ipv4Addr != localIpAddr)
1412  continue;
1413  //Check local port number
1414  if(socket->localPort != localPort)
1415  continue;
1416 
1417  //A matching socket has been found
1418  break;
1419  }
1420  }
1421 
1422  //No matching connection found in socket table?
1423  if(i >= SOCKET_MAX_COUNT)
1424  {
1425  //Loop through the UDP callback table
1426  for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++)
1427  {
1428  //Point to the current entry
1429  UdpRxCallbackDesc *entry = &udpCallbackTable[i];
1430 
1431  //Check whether the entry is currently in used
1432  if(entry->callback != NULL)
1433  {
1434  //Check local port number
1435  if(entry->port == localPort)
1436  break;
1437  }
1438  }
1439 
1440  //No matching connection found in UDP callback table?
1441  if(i >= UDP_CALLBACK_TABLE_SIZE)
1442  return ERROR_INSTANCE_NOT_FOUND;
1443  }
1444 
1445  //udpLocalAddress object?
1446  if(!strcmp(object->name, "udpLocalAddress"))
1447  {
1448  //Get object value
1449  ipv4CopyAddr(value->ipAddr, &localIpAddr);
1450  }
1451  //udpLocalPort object?
1452  else if(!strcmp(object->name, "udpLocalPort"))
1453  {
1454  //Get object value
1455  value->integer = localPort;
1456  }
1457  //Unknown object?
1458  else
1459  {
1460  //The specified object does not exist
1461  error = ERROR_OBJECT_NOT_FOUND;
1462  }
1463 
1464  //Return status code
1465  return error;
1466 }
1467 
1468 
1469 /**
1470  * @brief Get next udpEntry object
1471  * @param[in] object Pointer to the MIB object descriptor
1472  * @param[in] oid Object identifier
1473  * @param[in] oidLen Length of the OID, in bytes
1474  * @param[out] nextOid OID of the next object in the MIB
1475  * @param[out] nextOidLen Length of the next object identifier, in bytes
1476  * @return Error code
1477  **/
1478 
1479 error_t mib2GetNextUdpEntry(const MibObject *object, const uint8_t *oid,
1480  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
1481 {
1482  error_t error;
1483  uint_t i;
1484  size_t n;
1485  bool_t acceptable;
1486  Ipv4Addr localIpAddr;
1487  uint16_t localPort;
1488 
1489  //Initialize variables
1490  localIpAddr = IPV4_UNSPECIFIED_ADDR;
1491  localPort = 0;
1492 
1493  //Make sure the buffer is large enough to hold the OID prefix
1494  if(*nextOidLen < object->oidLen)
1495  return ERROR_BUFFER_OVERFLOW;
1496 
1497  //Copy OID prefix
1498  memcpy(nextOid, object->oid, object->oidLen);
1499 
1500  //Loop through socket descriptors
1501  for(i = 0; i < SOCKET_MAX_COUNT; i++)
1502  {
1503  //Point to current socket
1504  Socket *socket = &socketTable[i];
1505 
1506  //UDP socket?
1507  if(socket->type == SOCKET_TYPE_DGRAM)
1508  {
1509  //Filter out IPv6 connections
1510  if(socket->localIpAddr.length != sizeof(Ipv6Addr) &&
1511  socket->remoteIpAddr.length != sizeof(Ipv6Addr))
1512  {
1513  //Append the instance identifier to the OID prefix
1514  n = object->oidLen;
1515 
1516  //udpLocalAddress is used as 1st instance identifier
1517  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, socket->localIpAddr.ipv4Addr);
1518  //Any error to report?
1519  if(error)
1520  return error;
1521 
1522  //udpLocalPort is used as 2nd instance identifier
1523  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort);
1524  //Any error to report?
1525  if(error)
1526  return error;
1527 
1528  //Check whether the resulting object identifier lexicographically
1529  //follows the specified OID
1530  if(oidComp(nextOid, n, oid, oidLen) > 0)
1531  {
1532  //Perform lexicographic comparison
1533  if(localPort == 0)
1534  acceptable = TRUE;
1535  else if(ntohl(socket->localIpAddr.ipv4Addr) < ntohl(localIpAddr))
1536  acceptable = TRUE;
1537  else if(ntohl(socket->localIpAddr.ipv4Addr) > ntohl(localIpAddr))
1538  acceptable = FALSE;
1539  else if(socket->localPort < localPort)
1540  acceptable = TRUE;
1541  else
1542  acceptable = FALSE;
1543 
1544  //Save the closest object identifier that follows the specified
1545  //OID in lexicographic order
1546  if(acceptable)
1547  {
1548  localIpAddr = socket->localIpAddr.ipv4Addr;
1549  localPort = socket->localPort;
1550  }
1551  }
1552  }
1553  }
1554  }
1555 
1556  //Loop through the UDP callback table
1557  for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++)
1558  {
1559  //Point to the current entry
1560  UdpRxCallbackDesc *entry = &udpCallbackTable[i];
1561 
1562  //Check whether the entry is currently in used
1563  if(entry->callback != NULL)
1564  {
1565  //Append the instance identifier to the OID prefix
1566  n = object->oidLen;
1567 
1568  //udpLocalAddress is used as 1st instance identifier
1569  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, IPV4_UNSPECIFIED_ADDR);
1570  //Any error to report?
1571  if(error)
1572  return error;
1573 
1574  //udpLocalPort is used as 2nd instance identifier
1575  error = mibEncodePort(nextOid, *nextOidLen, &n, entry->port);
1576  //Any error to report?
1577  if(error)
1578  return error;
1579 
1580  //Check whether the resulting object identifier lexicographically
1581  //follows the specified OID
1582  if(oidComp(nextOid, n, oid, oidLen) > 0)
1583  {
1584  //Perform lexicographic comparison
1585  if(localPort == 0)
1586  acceptable = TRUE;
1587  else if(ntohl(IPV4_UNSPECIFIED_ADDR) < ntohl(localIpAddr))
1588  acceptable = TRUE;
1589  else if(ntohl(IPV4_UNSPECIFIED_ADDR) > ntohl(localIpAddr))
1590  acceptable = FALSE;
1591  else if(entry->port < localPort)
1592  acceptable = TRUE;
1593  else
1594  acceptable = FALSE;
1595 
1596  //Save the closest object identifier that follows the specified
1597  //OID in lexicographic order
1598  if(acceptable)
1599  {
1600  localIpAddr = IPV4_UNSPECIFIED_ADDR;
1601  localPort = entry->port;
1602  }
1603  }
1604  }
1605  }
1606 
1607  //The specified OID does not lexicographically precede the name
1608  //of some object?
1609  if(localPort == 0)
1610  return ERROR_OBJECT_NOT_FOUND;
1611 
1612  //Append the instance identifier to the OID prefix
1613  n = object->oidLen;
1614 
1615  //udpLocalAddress is used as 1st instance identifier
1616  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, localIpAddr);
1617  //Any error to report?
1618  if(error)
1619  return error;
1620 
1621  //udpLocalPort is used as 2nd instance identifier
1622  error = mibEncodePort(nextOid, *nextOidLen, &n, localPort);
1623  //Any error to report?
1624  if(error)
1625  return error;
1626 
1627  //Save the length of the resulting object identifier
1628  *nextOidLen = n;
1629  //Next object found
1630  return NO_ERROR;
1631 }
1632 
1633 #endif
1634 #endif
Interfaces table entry.
Definition: mib2_module.h:319
MIB-II module.
char_t sysName[MIB2_SYS_NAME_SIZE]
Definition: mib2_module.h:304
int bool_t
Definition: compiler_port.h:49
Ipv4Addr addr
IPv4 address.
Definition: ipv4.h:312
Interfaces group.
Definition: mib2_module.h:343
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.c:740
uint32_t ifInDiscards
Definition: mib2_module.h:325
#define TCP_MAX_RTO
Definition: tcp.h:131
uint32_t ifOutDiscards
Definition: mib2_module.h:331
OID (Object Identifier)
int32_t sysServices
Definition: mib2_module.h:311
#define MIB2_PHYS_ADDRESS_SIZE
Definition: mib2_module.h:141
#define TRUE
Definition: os_port.h:50
error_t mibEncodePort(uint8_t *oid, size_t maxOidLen, size_t *pos, uint16_t port)
Encode instance identifier (port number)
Definition: mib_common.c:478
uint32_t ifInUcastPkts
Definition: mib2_module.h:323
Entry describing a user callback.
Definition: udp.h:104
uint8_t ifSpecific[MIB2_IF_SPECIFIC_SIZE]
Definition: mib2_module.h:334
#define NET_INTERFACE_COUNT
Definition: net.h:109
__start_packed struct @205 MibVariant
Variant data type.
uint32_t ifOutUcastPkts
Definition: mib2_module.h:329
Ipv4AddrState state
IPv4 address state.
Definition: ipv4.h:313
error_t mibDecodePort(const uint8_t *oid, size_t oidLen, size_t *pos, uint16_t *port)
Decode instance identifier (port number)
Definition: mib_common.c:495
int32_t tcpRtoMin
Definition: mib2_module.h:421
#define IPV4_MAX_FRAG_DATAGRAM_SIZE
Definition: ipv4_frag.h:62
error_t mib2GetTcpCurrEstab(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get tcpCurrEstab object value.
Definition: mib2_impl.c:979
size_t sysObjectIDLen
Definition: mib2_module.h:296
Mib2IfEntry ifTable[NET_INTERFACE_COUNT]
Definition: mib2_module.h:346
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
ArpCacheEntry * arpFindEntry(NetInterface *interface, Ipv4Addr ipAddr)
Search the ARP cache for a given IPv4 address.
Definition: arp.c:152
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:101
int32_t ipReasmTimeout
Definition: mib2_module.h:368
#define macCopyAddr(destMacAddr, srcMacAddr)
Definition: ethernet.h:104
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.c:858
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.c:758
error_t mib2GetIfEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get ifEntry object value.
Definition: mib2_impl.c:204
Mib2TcpGroup tcpGroup
Definition: mib2_module.h:499
uint32_t ifInNUcastPkts
Definition: mib2_module.h:324
#define FALSE
Definition: os_port.h:46
NetInterface netInterface[NET_INTERFACE_COUNT]
Definition: net.c:79
#define ARP_CACHE_SIZE
Definition: arp.h:46
int32_t ifNumber
Definition: mib2_module.h:345
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:84
UdpRxCallbackDesc udpCallbackTable[UDP_CALLBACK_TABLE_SIZE]
Definition: udp.c:56
error_t
Error codes.
Definition: error.h:42
uint32_t ifOutNUcastPkts
Definition: mib2_module.h:330
TCP group.
Definition: mib2_module.h:418
MacAddr macAddr
Definition: arp.h:187
Mib2IfGroup ifGroup
Definition: mib2_module.h:493
int_t socket(int_t family, int_t type, int_t protocol)
Create a socket that is bound to a specific transport service provider.
Definition: bsd_socket.c:108
uint32_t ifOutErrors
Definition: mib2_module.h:332
error_t mib2GetUdpEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get udpEntry object value.
Definition: mib2_impl.c:1371
error_t mib2GetSysUpTime(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get sysUpTime object value.
Definition: mib2_impl.c:161
#define NetInterface
Definition: net.h:36
General definitions for cryptographic algorithms.
uint8_t oid[1]
Definition: mib_common.h:186
size_t sysContactLen
Definition: mib2_module.h:301
int32_t tcpRtoMax
Definition: mib2_module.h:422
uint32_t ifLastChange
Definition: mib2_module.h:321
__start_packed struct @179 Ipv6Addr
IPv6 network address.
UdpRxCallback callback
Definition: udp.h:108
#define TRACE_INFO(...)
Definition: debug.h:94
#define IPV4_ADDR_LIST_SIZE
Definition: ipv4.h:63
#define IPV4_FRAG_TIME_TO_LIVE
Definition: ipv4_frag.h:69
#define UDP_CALLBACK_TABLE_SIZE
Definition: udp.h:48
ArpState state
Definition: arp.h:185
IPv4 address entry.
Definition: ipv4.h:310
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
uint32_t ifInUnknownProtos
Definition: mib2_module.h:327
size_t sysLocationLen
Definition: mib2_module.h:309
#define IPV4_DEFAULT_TTL
Definition: ipv4.h:56
PPP interface.
Definition: nic.h:80
int32_t ipDefaultTTL
Definition: mib2_module.h:357
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:315
Mib2IpGroup ipGroup
Definition: mib2_module.h:495
error_t mib2GetNextUdpEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next udpEntry object.
Definition: mib2_impl.c:1479
error_t mibEncodeIpv4Addr(uint8_t *oid, size_t maxOidLen, size_t *pos, Ipv4Addr ipAddr)
Encode instance identifier (IPv4 address)
Definition: mib_common.c:613
uint16_t port
Definition: udp.h:107
Common definitions for MIB modules.
uint8_t n
uint32_t ifOutOctets
Definition: mib2_module.h:328
error_t mib2SetIfEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set ifEntry object value.
Definition: mib2_impl.c:186
error_t mib2GetNextTcpConnEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next tcpConnEntry object.
Definition: mib2_impl.c:1216
#define Socket
Definition: socket.h:36
char_t sysDescr[MIB2_SYS_DESCR_SIZE]
Definition: mib2_module.h:291
int32_t tcpMaxConn
Definition: mib2_module.h:423
#define MibObject
Definition: mib_common.h:46
ARP cache entry.
Definition: arp.h:183
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.c:534
#define ipv4CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv4.h:142
uint32_t ifInOctets
Definition: mib2_module.h:322
#define TCP_MIN_RTO
Definition: tcp.h:124
IP group.
Definition: mib2_module.h:354
uint32_t ifOutQLen
Definition: mib2_module.h:333
error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos, uint_t index)
Encode instance identifier (index)
Definition: mib_common.c:47
An address assigned to an interface whose use is unrestricted.
Definition: ipv4.h:191
char_t sysLocation[MIB2_SYS_LOCATION_SIZE]
Definition: mib2_module.h:308
Mib2Base mib2Base
MIB-II base.
Definition: mib2_module.c:58
size_t sysNameLen
Definition: mib2_module.h:305
error_t mibDecodeIpv4Addr(const uint8_t *oid, size_t oidLen, size_t *pos, Ipv4Addr *ipAddr)
Decode instance identifier (IPv4 address)
Definition: mib_common.c:647
error_t mib2GetTcpConnEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get tcpConnEntry object value.
Definition: mib2_impl.c:1048
error_t mib2Init(void)
MIB-II module initialization.
Definition: mib2_impl.c:50
uint8_t value[]
Definition: dtls_misc.h:150
int32_t ipForwarding
Definition: mib2_module.h:356
6LoWPAN interface
Definition: nic.h:81
uint8_t sysObjectID[MIB2_SYS_OBJECT_ID_SIZE]
Definition: mib2_module.h:295
unsigned int uint_t
Definition: compiler_port.h:45
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.c:640
TCP/IP stack core.
NetInterface * nicGetLogicalInterface(NetInterface *interface)
Retrieve logical interface.
Definition: nic.c:52
char_t sysContact[MIB2_SYS_CONTACT_SIZE]
Definition: mib2_module.h:300
error_t mib2GetNextIfEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next ifEntry object.
Definition: mib2_impl.c:479
Mib2SysGroup sysGroup
Definition: mib2_module.h:492
#define SOCKET_MAX_COUNT
Definition: socket.h:45
int32_t tcpRtoAlgorithm
Definition: mib2_module.h:420
uint8_t ipAddr[4]
Definition: mib_common.h:187
Ipv4Addr ipAddr
Definition: arp.h:186
size_t ifSpecificLen
Definition: mib2_module.h:335
#define ntohl(value)
Definition: cpu_endian.h:399
Success.
Definition: error.h:44
size_t sysDescrLen
Definition: mib2_module.h:292
error_t mib2SetTcpConnEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set tcpConnEntry object value.
Definition: mib2_impl.c:1030
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
System group.
Definition: mib2_module.h:288
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:104
Ethernet interface.
Definition: nic.h:79
uint32_t ifInErrors
Definition: mib2_module.h:326
systime_t osGetSystemTime(void)
Retrieve system time.