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