Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mib2_impl.c
00001 /** 00002 * @file mib2_impl.c 00003 * @brief MIB-II module implementation 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Dependencies 00030 #include "core/net.h" 00031 #include "mibs/mib_common.h" 00032 #include "mibs/mib2_module.h" 00033 #include "mibs/mib2_impl.h" 00034 #include "crypto.h" 00035 #include "asn1.h" 00036 #include "oid.h" 00037 #include "debug.h" 00038 00039 //Check TCP/IP stack configuration 00040 #if (MIB2_SUPPORT == ENABLED) 00041 00042 00043 /** 00044 * @brief MIB-II module initialization 00045 * @return Error code 00046 **/ 00047 00048 error_t mib2Init(void) 00049 { 00050 uint_t i; 00051 Mib2SysGroup *sysGroup; 00052 Mib2IfGroup *ifGroup; 00053 #if (IPV4_SUPPORT == ENABLED) 00054 Mib2IpGroup *ipGroup; 00055 #endif 00056 #if (TCP_SUPPORT == ENABLED) 00057 Mib2TcpGroup *tcpGroup; 00058 #endif 00059 00060 //Debug message 00061 TRACE_INFO("Initializing standard MIB-II base...\r\n"); 00062 00063 //Clear MIB-II base 00064 memset(&mib2Base, 0, sizeof(mib2Base)); 00065 00066 //Point to the system group 00067 sysGroup = &mib2Base.sysGroup; 00068 00069 #if (MIB2_SYS_DESCR_SIZE > 0) 00070 //sysDescr object 00071 strcpy(sysGroup->sysDescr, "Description"); 00072 sysGroup->sysDescrLen = strlen(sysGroup->sysDescr); 00073 #endif 00074 00075 #if (MIB2_SYS_OBJECT_ID_SIZE > 0) 00076 //sysObjectID object 00077 sysGroup->sysObjectID[0] = 0; 00078 sysGroup->sysObjectIDLen = 1; 00079 #endif 00080 00081 #if (MIB2_SYS_CONTACT_SIZE > 0) 00082 //sysContact object 00083 strcpy(sysGroup->sysContact, "Contact"); 00084 sysGroup->sysContactLen = strlen(sysGroup->sysContact); 00085 #endif 00086 00087 #if (MIB2_SYS_NAME_SIZE > 0) 00088 //sysName object 00089 strcpy(sysGroup->sysName, "Name"); 00090 sysGroup->sysNameLen = strlen(sysGroup->sysName); 00091 #endif 00092 00093 #if (MIB2_SYS_LOCATION_SIZE > 0) 00094 //sysLocation object 00095 strcpy(sysGroup->sysLocation, "Location"); 00096 sysGroup->sysLocationLen = strlen(sysGroup->sysLocation); 00097 #endif 00098 00099 //sysServices object 00100 sysGroup->sysServices = MIB2_SYS_SERVICE_INTERNET; 00101 00102 //Point to the interfaces group 00103 ifGroup = &mib2Base.ifGroup; 00104 00105 //Interfaces table entry 00106 for(i = 0; i < NET_INTERFACE_COUNT; i++) 00107 { 00108 //ifSpecific object 00109 ifGroup->ifTable[i].ifSpecific[0] = 0; 00110 ifGroup->ifTable[i].ifSpecificLen = 1; 00111 } 00112 00113 #if (IPV4_SUPPORT == ENABLED) 00114 //Point to the IP group 00115 ipGroup = &mib2Base.ipGroup; 00116 00117 //ipForwarding object 00118 ipGroup->ipForwarding = MIB2_IP_FORWARDING_DISABLED; 00119 //ipDefaultTTL object 00120 ipGroup->ipDefaultTTL = IPV4_DEFAULT_TTL; 00121 //ipReasmTimeout object 00122 ipGroup->ipReasmTimeout = IPV4_FRAG_TIME_TO_LIVE / 1000; 00123 #endif 00124 00125 #if (TCP_SUPPORT == ENABLED) 00126 //Point to the TCP group 00127 tcpGroup = &mib2Base.tcpGroup; 00128 00129 //tcpRtoAlgorithm object 00130 tcpGroup->tcpRtoAlgorithm = MIB2_TCP_RTO_ALGORITHM_VANJ; 00131 //tcpRtoMin object 00132 tcpGroup->tcpRtoMin = TCP_MIN_RTO; 00133 //tcpRtoMax object 00134 tcpGroup->tcpRtoMax = TCP_MAX_RTO; 00135 //tcpMaxConn object 00136 tcpGroup->tcpMaxConn = SOCKET_MAX_COUNT; 00137 #endif 00138 00139 //Successful processing 00140 return NO_ERROR; 00141 } 00142 00143 00144 /** 00145 * @brief Lock MIB-II base 00146 **/ 00147 00148 void mib2Lock(void) 00149 { 00150 //Get exclusive access 00151 osAcquireMutex(&netMutex); 00152 } 00153 00154 00155 /** 00156 * @brief Unlock MIB-II base 00157 **/ 00158 00159 void mib2Unlock(void) 00160 { 00161 //Release exclusive access 00162 osReleaseMutex(&netMutex); 00163 } 00164 00165 00166 /** 00167 * @brief Get sysUpTime object value 00168 * @param[in] object Pointer to the MIB object descriptor 00169 * @param[in] oid Object identifier (object name and instance identifier) 00170 * @param[in] oidLen Length of the OID, in bytes 00171 * @param[out] value Object value 00172 * @param[in,out] valueLen Length of the object value, in bytes 00173 * @return Error code 00174 **/ 00175 00176 error_t mib2GetSysUpTime(const MibObject *object, const uint8_t *oid, 00177 size_t oidLen, MibVariant *value, size_t *valueLen) 00178 { 00179 //Get object value 00180 value->timeTicks = osGetSystemTime() / 10; 00181 //Successful processing 00182 return NO_ERROR; 00183 } 00184 00185 00186 /** 00187 * @brief Get ifEntry object value 00188 * @param[in] object Pointer to the MIB object descriptor 00189 * @param[in] oid Object identifier (object name and instance identifier) 00190 * @param[in] oidLen Length of the OID, in bytes 00191 * @param[out] value Object value 00192 * @param[in,out] valueLen Length of the object value, in bytes 00193 * @return Error code 00194 **/ 00195 00196 error_t mib2GetIfEntry(const MibObject *object, const uint8_t *oid, 00197 size_t oidLen, MibVariant *value, size_t *valueLen) 00198 { 00199 error_t error; 00200 size_t n; 00201 uint_t index; 00202 Mib2IfEntry *entry; 00203 00204 //Point to the instance identifier 00205 n = object->oidLen; 00206 00207 //The ifIndex is used as instance identifier 00208 error = mibDecodeIndex(oid, oidLen, &n, &index); 00209 //Invalid instance identifier? 00210 if(error) 00211 return error; 00212 00213 //Sanity check 00214 if(n != oidLen) 00215 return ERROR_INSTANCE_NOT_FOUND; 00216 00217 //Check index range 00218 if(index < 1 || index > NET_INTERFACE_COUNT) 00219 return ERROR_INSTANCE_NOT_FOUND; 00220 00221 //Point to the interface table entry 00222 entry = &mib2Base.ifGroup.ifTable[index - 1]; 00223 00224 //ifIndex object? 00225 if(!strcmp(object->name, "ifIndex")) 00226 { 00227 //Get object value 00228 value->integer = entry->ifIndex; 00229 } 00230 //ifDescr object? 00231 else if(!strcmp(object->name, "ifDescr")) 00232 { 00233 //Make sure the buffer is large enough to hold the entire object 00234 if(*valueLen >= entry->ifDescrLen) 00235 { 00236 //Copy object value 00237 memcpy(value->octetString, entry->ifDescr, entry->ifDescrLen); 00238 //Return object length 00239 *valueLen = entry->ifDescrLen; 00240 } 00241 else 00242 { 00243 //Report an error 00244 error = ERROR_BUFFER_OVERFLOW; 00245 } 00246 } 00247 //ifType object? 00248 else if(!strcmp(object->name, "ifType")) 00249 { 00250 //Get object value 00251 value->integer = entry->ifType; 00252 } 00253 //ifMtu object? 00254 else if(!strcmp(object->name, "ifMtu")) 00255 { 00256 //Get object value 00257 value->integer = entry->ifMtu; 00258 } 00259 //ifSpeed object? 00260 else if(!strcmp(object->name, "ifSpeed")) 00261 { 00262 //Get object value 00263 value->gauge32 = entry->ifSpeed; 00264 } 00265 //ifPhysAddress object? 00266 else if(!strcmp(object->name, "ifPhysAddress")) 00267 { 00268 //Make sure the buffer is large enough to hold the entire object 00269 if(*valueLen >= entry->ifPhysAddressLen) 00270 { 00271 //Copy object value 00272 memcpy(value->octetString, entry->ifPhysAddress, entry->ifPhysAddressLen); 00273 //Return object length 00274 *valueLen = entry->ifPhysAddressLen; 00275 } 00276 else 00277 { 00278 //Report an error 00279 error = ERROR_BUFFER_OVERFLOW; 00280 } 00281 } 00282 //ifAdminStatus object? 00283 else if(!strcmp(object->name, "ifAdminStatus")) 00284 { 00285 //Get object value 00286 value->integer = entry->ifAdminStatus; 00287 } 00288 //ifOperStatus object? 00289 else if(!strcmp(object->name, "ifOperStatus")) 00290 { 00291 //Get object value 00292 value->integer = entry->ifOperStatus; 00293 } 00294 //ifLastChange object? 00295 else if(!strcmp(object->name, "ifLastChange")) 00296 { 00297 //Get object value 00298 value->timeTicks = entry->ifLastChange; 00299 } 00300 //ifInOctets object? 00301 else if(!strcmp(object->name, "ifInOctets")) 00302 { 00303 //Get object value 00304 value->counter32 = entry->ifInOctets; 00305 } 00306 //ifInUcastPkts object? 00307 else if(!strcmp(object->name, "ifInUcastPkts")) 00308 { 00309 //Get object value 00310 value->counter32 = entry->ifInUcastPkts; 00311 } 00312 //ifInNUcastPkts object? 00313 else if(!strcmp(object->name, "ifInNUcastPkts")) 00314 { 00315 //Get object value 00316 value->counter32 = entry->ifInNUcastPkts; 00317 } 00318 //ifInDiscards object? 00319 else if(!strcmp(object->name, "ifInDiscards")) 00320 { 00321 //Get object value 00322 value->counter32 = entry->ifInDiscards; 00323 } 00324 //ifInErrors object? 00325 else if(!strcmp(object->name, "ifInErrors")) 00326 { 00327 //Get object value 00328 value->counter32 = entry->ifInErrors; 00329 } 00330 //ifInUnknownProtos object? 00331 else if(!strcmp(object->name, "ifInUnknownProtos")) 00332 { 00333 //Get object value 00334 value->counter32 = entry->ifInUnknownProtos; 00335 } 00336 //ifOutOctets object? 00337 else if(!strcmp(object->name, "ifOutOctets")) 00338 { 00339 //Get object value 00340 value->counter32 = entry->ifOutOctets; 00341 } 00342 //ifOutUcastPkts object? 00343 else if(!strcmp(object->name, "ifOutUcastPkts")) 00344 { 00345 //Get object value 00346 value->counter32 = entry->ifOutUcastPkts; 00347 } 00348 //ifOutNUcastPkts object? 00349 else if(!strcmp(object->name, "ifOutNUcastPkts")) 00350 { 00351 //Get object value 00352 value->counter32 = entry->ifOutNUcastPkts; 00353 } 00354 //ifOutDiscards object? 00355 else if(!strcmp(object->name, "ifOutDiscards")) 00356 { 00357 //Get object value 00358 value->counter32 = entry->ifOutDiscards; 00359 } 00360 //ifOutErrors object? 00361 else if(!strcmp(object->name, "ifOutErrors")) 00362 { 00363 //Get object value 00364 value->counter32 = entry->ifOutErrors; 00365 } 00366 //ifOutQLen object? 00367 else if(!strcmp(object->name, "ifOutQLen")) 00368 { 00369 //Get object value 00370 value->gauge32 = entry->ifOutQLen; 00371 } 00372 //ifSpecific object? 00373 else if(!strcmp(object->name, "ifSpecific")) 00374 { 00375 //Make sure the buffer is large enough to hold the entire object 00376 if(*valueLen >= entry->ifSpecificLen) 00377 { 00378 //Copy object value 00379 memcpy(value->oid, entry->ifSpecific, entry->ifSpecificLen); 00380 //Return object length 00381 *valueLen = entry->ifSpecificLen; 00382 } 00383 else 00384 { 00385 //Report an error 00386 error = ERROR_BUFFER_OVERFLOW; 00387 } 00388 } 00389 //Unknown object? 00390 else 00391 { 00392 //The specified object does not exist 00393 error = ERROR_OBJECT_NOT_FOUND; 00394 } 00395 00396 //Return status code 00397 return error; 00398 } 00399 00400 00401 /** 00402 * @brief Get next ifEntry object 00403 * @param[in] object Pointer to the MIB object descriptor 00404 * @param[in] oid Object identifier 00405 * @param[in] oidLen Length of the OID, in bytes 00406 * @param[out] nextOid OID of the next object in the MIB 00407 * @param[out] nextOidLen Length of the next object identifier, in bytes 00408 * @return Error code 00409 **/ 00410 00411 error_t mib2GetNextIfEntry(const MibObject *object, const uint8_t *oid, 00412 size_t oidLen, uint8_t *nextOid, size_t *nextOidLen) 00413 { 00414 error_t error; 00415 size_t n; 00416 uint_t index; 00417 00418 //Make sure the buffer is large enough to hold the OID prefix 00419 if(*nextOidLen < object->oidLen) 00420 return ERROR_BUFFER_OVERFLOW; 00421 00422 //Copy OID prefix 00423 memcpy(nextOid, object->oid, object->oidLen); 00424 00425 //Loop through network interfaces 00426 for(index = 1; index <= NET_INTERFACE_COUNT; index++) 00427 { 00428 //Append the instance identifier to the OID prefix 00429 n = object->oidLen; 00430 00431 //The ifIndex is used as instance identifier 00432 error = mibEncodeIndex(nextOid, *nextOidLen, &n, index); 00433 //Any error to report? 00434 if(error) 00435 return error; 00436 00437 //Check whether the resulting object identifier lexicographically 00438 //follows the specified OID 00439 if(oidComp(nextOid, n, oid, oidLen) > 0) 00440 { 00441 //Save the length of the resulting object identifier 00442 *nextOidLen = n; 00443 //Next object found 00444 return NO_ERROR; 00445 } 00446 } 00447 00448 //The specified OID does not lexicographically precede the name 00449 //of some object 00450 return ERROR_OBJECT_NOT_FOUND; 00451 } 00452 00453 00454 #if (IPV4_SUPPORT == ENABLED) 00455 00456 /** 00457 * @brief Get ipAddrEntry object value 00458 * @param[in] object Pointer to the MIB object descriptor 00459 * @param[in] oid Object identifier (object name and instance identifier) 00460 * @param[in] oidLen Length of the OID, in bytes 00461 * @param[out] value Object value 00462 * @param[in,out] valueLen Length of the object value, in bytes 00463 * @return Error code 00464 **/ 00465 00466 error_t mib2GetIpAddrEntry(const MibObject *object, const uint8_t *oid, 00467 size_t oidLen, MibVariant *value, size_t *valueLen) 00468 { 00469 error_t error; 00470 uint_t i; 00471 size_t n; 00472 Ipv4Addr ipAddr; 00473 NetInterface *interface; 00474 00475 //Point to the instance identifier 00476 n = object->oidLen; 00477 00478 //The ipAdEntAddr is used as instance identifier 00479 error = mibDecodeIpv4Addr(oid, oidLen, &n, &ipAddr); 00480 //Invalid instance identifier? 00481 if(error) 00482 return error; 00483 00484 //Sanity check 00485 if(n != oidLen) 00486 return ERROR_INSTANCE_NOT_FOUND; 00487 00488 //Loop through network interfaces 00489 for(i = 0; i < NET_INTERFACE_COUNT; i++) 00490 { 00491 //Point to the current interface 00492 interface = &netInterface[i]; 00493 00494 //Check address state 00495 if(interface->ipv4Context.addrState == IPV4_ADDR_STATE_VALID) 00496 { 00497 //Compare the current address against the IP address used as 00498 //instance identifier 00499 if(interface->ipv4Context.addr == ipAddr) 00500 break; 00501 } 00502 } 00503 00504 //IP address not assigned to any interface? 00505 if(i >= NET_INTERFACE_COUNT) 00506 return ERROR_INSTANCE_NOT_FOUND; 00507 00508 //ipAdEntAddr object? 00509 if(!strcmp(object->name, "ipAdEntAddr")) 00510 { 00511 //Get object value 00512 ipv4CopyAddr(value->ipAddr, &interface->ipv4Context.addr); 00513 } 00514 //ipAdEntIfIndex object? 00515 else if(!strcmp(object->name, "ipAdEntIfIndex")) 00516 { 00517 //Get object value 00518 value->integer = interface->id + 1; 00519 } 00520 //ipAdEntNetMask object? 00521 else if(!strcmp(object->name, "ipAdEntNetMask")) 00522 { 00523 //Get object value 00524 ipv4CopyAddr(value->ipAddr, &interface->ipv4Context.subnetMask); 00525 } 00526 //ipAdEntBcastAddr object? 00527 else if(!strcmp(object->name, "ipAdEntBcastAddr")) 00528 { 00529 //Get object value 00530 value->integer = 1; 00531 } 00532 //ipAdEntReasmMaxSize object? 00533 else if(!strcmp(object->name, "ipAdEntReasmMaxSize")) 00534 { 00535 //Get object value 00536 value->integer = IPV4_MAX_FRAG_DATAGRAM_SIZE; 00537 } 00538 //Unknown object? 00539 else 00540 { 00541 //The specified object does not exist 00542 error = ERROR_OBJECT_NOT_FOUND; 00543 } 00544 00545 //Return status code 00546 return error; 00547 } 00548 00549 00550 /** 00551 * @brief Get next ipAddrEntry object 00552 * @param[in] object Pointer to the MIB object descriptor 00553 * @param[in] oid Object identifier 00554 * @param[in] oidLen Length of the OID, in bytes 00555 * @param[out] nextOid OID of the next object in the MIB 00556 * @param[out] nextOidLen Length of the next object identifier, in bytes 00557 * @return Error code 00558 **/ 00559 00560 error_t mib2GetNextIpAddrEntry(const MibObject *object, const uint8_t *oid, 00561 size_t oidLen, uint8_t *nextOid, size_t *nextOidLen) 00562 { 00563 error_t error; 00564 uint_t i; 00565 size_t n; 00566 Ipv4Addr ipAddr; 00567 NetInterface *interface; 00568 00569 //Initialize IP address 00570 ipAddr = IPV4_UNSPECIFIED_ADDR; 00571 00572 //Make sure the buffer is large enough to hold the OID prefix 00573 if(*nextOidLen < object->oidLen) 00574 return ERROR_BUFFER_OVERFLOW; 00575 00576 //Copy OID prefix 00577 memcpy(nextOid, object->oid, object->oidLen); 00578 00579 //Loop through network interfaces 00580 for(i = 0; i < NET_INTERFACE_COUNT; i++) 00581 { 00582 //Point to the current interface 00583 interface = &netInterface[i]; 00584 00585 //Check address state 00586 if(interface->ipv4Context.addrState == IPV4_ADDR_STATE_VALID) 00587 { 00588 //Append the instance identifier to the OID prefix 00589 n = object->oidLen; 00590 00591 //The ipAdEntAddr is used as instance identifier 00592 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, interface->ipv4Context.addr); 00593 //Any error to report? 00594 if(error) 00595 return error; 00596 00597 //Check whether the resulting object identifier lexicographically 00598 //follows the specified OID 00599 if(oidComp(nextOid, n, oid, oidLen) > 0) 00600 { 00601 //Save the closest object identifier that follows the specified 00602 //OID in lexicographic order 00603 if(ipAddr == IPV4_UNSPECIFIED_ADDR) 00604 { 00605 ipAddr = interface->ipv4Context.addr; 00606 } 00607 else if(ntohl(interface->ipv4Context.addr) < ntohl(ipAddr)) 00608 { 00609 ipAddr = interface->ipv4Context.addr; 00610 } 00611 } 00612 } 00613 } 00614 00615 //The specified OID does not lexicographically precede the name 00616 //of some object? 00617 if(ipAddr == IPV4_UNSPECIFIED_ADDR) 00618 return ERROR_OBJECT_NOT_FOUND; 00619 00620 //Append the instance identifier to the OID prefix 00621 n = object->oidLen; 00622 00623 //The ipAdEntAddr is used as instance identifier 00624 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, interface->ipv4Context.addr); 00625 //Any error to report? 00626 if(error) 00627 return error; 00628 00629 //Save the length of the resulting object identifier 00630 *nextOidLen = n; 00631 //Next object found 00632 return NO_ERROR; 00633 } 00634 00635 00636 /** 00637 * @brief Set ipNetToMediaEntry object value 00638 * @param[in] object Pointer to the MIB object descriptor 00639 * @param[in] oid Object identifier (object name and instance identifier) 00640 * @param[in] oidLen Length of the OID, in bytes 00641 * @param[in] value Object value 00642 * @param[in] valueLen Length of the object value, in bytes 00643 * @return Error code 00644 **/ 00645 00646 error_t mib2SetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid, 00647 size_t oidLen, const MibVariant *value, size_t valueLen) 00648 { 00649 //Not implemented 00650 return ERROR_WRITE_FAILED; 00651 } 00652 00653 00654 /** 00655 * @brief Get ipNetToMediaEntry object value 00656 * @param[in] object Pointer to the MIB object descriptor 00657 * @param[in] oid Object identifier (object name and instance identifier) 00658 * @param[in] oidLen Length of the OID, in bytes 00659 * @param[out] value Object value 00660 * @param[in,out] valueLen Length of the object value, in bytes 00661 * @return Error code 00662 **/ 00663 00664 error_t mib2GetIpNetToMediaEntry(const MibObject *object, const uint8_t *oid, 00665 size_t oidLen, MibVariant *value, size_t *valueLen) 00666 { 00667 error_t error; 00668 size_t n; 00669 uint_t index; 00670 Ipv4Addr ipAddr; 00671 NetInterface *interface; 00672 ArpCacheEntry *entry; 00673 00674 //Point to the instance identifier 00675 n = object->oidLen; 00676 00677 //The ipNetToMediaIfIndex is used as 1st instance identifier 00678 error = mibDecodeIndex(oid, oidLen, &n, &index); 00679 //Invalid instance identifier? 00680 if(error) 00681 return error; 00682 00683 //The ipNetToMediaNetAddress is used as 2nd instance identifier 00684 error = mibDecodeIpv4Addr(oid, oidLen, &n, &ipAddr); 00685 //Invalid instance identifier? 00686 if(error) 00687 return error; 00688 00689 //Sanity check 00690 if(n != oidLen) 00691 return ERROR_INSTANCE_NOT_FOUND; 00692 00693 //Check index range 00694 if(index < 1 || index > NET_INTERFACE_COUNT) 00695 return ERROR_INSTANCE_NOT_FOUND; 00696 00697 //Point to the network interface 00698 interface = &netInterface[index - 1]; 00699 00700 //Search the ARP cache for the specified IP address 00701 entry = arpFindEntry(interface, ipAddr); 00702 00703 //No matching entry found? 00704 if(entry == NULL) 00705 return ERROR_INSTANCE_NOT_FOUND; 00706 00707 //ipNetToMediaIfIndex object? 00708 if(!strcmp(object->name, "ipNetToMediaIfIndex")) 00709 { 00710 //Get object value 00711 value->integer = index; 00712 } 00713 //ipNetToMediaPhysAddress object? 00714 else if(!strcmp(object->name, "ipNetToMediaPhysAddress")) 00715 { 00716 //Make sure the buffer is large enough to hold the entire object 00717 if(*valueLen >= MIB2_PHYS_ADDRESS_SIZE) 00718 { 00719 //Copy object value 00720 macCopyAddr(value->octetString, &entry->macAddr); 00721 //Return object length 00722 *valueLen = MIB2_PHYS_ADDRESS_SIZE; 00723 } 00724 else 00725 { 00726 //Report an error 00727 error = ERROR_BUFFER_OVERFLOW; 00728 } 00729 } 00730 //ipNetToMediaNetAddress object? 00731 else if(!strcmp(object->name, "ipNetToMediaNetAddress")) 00732 { 00733 //Get object value 00734 ipv4CopyAddr(value->ipAddr, &entry->ipAddr); 00735 } 00736 //ipNetToMediaType object? 00737 else if(!strcmp(object->name, "ipNetToMediaType")) 00738 { 00739 //Get object value 00740 value->integer = MIB2_IP_NET_TO_MEDIA_TYPE_DYNAMIC; 00741 } 00742 //Unknown object? 00743 else 00744 { 00745 //The specified object does not exist 00746 error = ERROR_OBJECT_NOT_FOUND; 00747 } 00748 00749 //Return status code 00750 return error; 00751 } 00752 00753 00754 /** 00755 * @brief Get next ipNetToMediaEntry object 00756 * @param[in] object Pointer to the MIB object descriptor 00757 * @param[in] oid Object identifier 00758 * @param[in] oidLen Length of the OID, in bytes 00759 * @param[out] nextOid OID of the next object in the MIB 00760 * @param[out] nextOidLen Length of the next object identifier, in bytes 00761 * @return Error code 00762 **/ 00763 00764 error_t mib2GetNextIpNetToMediaEntry(const MibObject *object, const uint8_t *oid, 00765 size_t oidLen, uint8_t *nextOid, size_t *nextOidLen) 00766 { 00767 error_t error; 00768 uint_t i; 00769 uint_t j; 00770 size_t n; 00771 uint32_t index; 00772 bool_t acceptable; 00773 Ipv4Addr ipAddr; 00774 NetInterface *interface; 00775 ArpCacheEntry *entry; 00776 00777 //Initialize variables 00778 index = 0; 00779 ipAddr = IPV4_UNSPECIFIED_ADDR; 00780 00781 //Make sure the buffer is large enough to hold the OID prefix 00782 if(*nextOidLen < object->oidLen) 00783 return ERROR_BUFFER_OVERFLOW; 00784 00785 //Copy OID prefix 00786 memcpy(nextOid, object->oid, object->oidLen); 00787 00788 //Loop through network interfaces 00789 for(i = 1; i <= NET_INTERFACE_COUNT; i++) 00790 { 00791 //Point to the current interface 00792 interface = &netInterface[i - 1]; 00793 00794 //Loop through ARP cache entries 00795 for(j = 0; j < ARP_CACHE_SIZE; j++) 00796 { 00797 //Point to the current entry 00798 entry = &interface->arpCache[j]; 00799 00800 //Valid entry? 00801 if(entry->state != ARP_STATE_NONE) 00802 { 00803 //Append the instance identifier to the OID prefix 00804 n = object->oidLen; 00805 00806 //The ipNetToMediaIfIndex is used as 1st instance identifier 00807 error = mibEncodeIndex(nextOid, *nextOidLen, &n, i); 00808 //Any error to report? 00809 if(error) 00810 return error; 00811 00812 //The ipNetToMediaNetAddress is used as 2nd instance identifier 00813 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, entry->ipAddr); 00814 //Any error to report? 00815 if(error) 00816 return error; 00817 00818 //Check whether the resulting object identifier lexicographically 00819 //follows the specified OID 00820 if(oidComp(nextOid, n, oid, oidLen) > 0) 00821 { 00822 //Perform lexicographic comparison 00823 if(index == 0) 00824 acceptable = TRUE; 00825 else if(i < index) 00826 acceptable = TRUE; 00827 else if(i > index) 00828 acceptable = FALSE; 00829 else if(ntohl(entry->ipAddr) < ntohl(ipAddr)) 00830 acceptable = TRUE; 00831 else 00832 acceptable = FALSE; 00833 00834 //Save the closest object identifier that follows the specified 00835 //OID in lexicographic order 00836 if(acceptable) 00837 { 00838 index = i; 00839 ipAddr = entry->ipAddr; 00840 } 00841 } 00842 } 00843 } 00844 } 00845 00846 //The specified OID does not lexicographically precede the name 00847 //of some object? 00848 if(index == 0) 00849 return ERROR_OBJECT_NOT_FOUND; 00850 00851 //Append the instance identifier to the OID prefix 00852 n = object->oidLen; 00853 00854 //The ipNetToMediaIfIndex is used as 1st instance identifier 00855 error = mibEncodeIndex(nextOid, *nextOidLen, &n, index); 00856 //Any error to report? 00857 if(error) 00858 return error; 00859 00860 //The ipNetToMediaNetAddress is used as 2nd instance identifier 00861 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, ipAddr); 00862 //Any error to report? 00863 if(error) 00864 return error; 00865 00866 //Save the length of the resulting object identifier 00867 *nextOidLen = n; 00868 //Next object found 00869 return NO_ERROR; 00870 } 00871 00872 00873 /** 00874 * @brief Set tcpConnEntry object value 00875 * @param[in] object Pointer to the MIB object descriptor 00876 * @param[in] oid Object identifier (object name and instance identifier) 00877 * @param[in] oidLen Length of the OID, in bytes 00878 * @param[out] value Object value 00879 * @param[in] valueLen Length of the object value, in bytes 00880 * @return Error code 00881 **/ 00882 00883 error_t mib2SetTcpConnEntry(const MibObject *object, const uint8_t *oid, 00884 size_t oidLen, const MibVariant *value, size_t valueLen) 00885 { 00886 //Not implemented 00887 return ERROR_WRITE_FAILED; 00888 } 00889 00890 00891 /** 00892 * @brief Get tcpConnEntry object value 00893 * @param[in] object Pointer to the MIB object descriptor 00894 * @param[in] oid Object identifier (object name and instance identifier) 00895 * @param[in] oidLen Length of the OID, in bytes 00896 * @param[out] value Object value 00897 * @param[in,out] valueLen Length of the object value, in bytes 00898 * @return Error code 00899 **/ 00900 00901 error_t mib2GetTcpConnEntry(const MibObject *object, const uint8_t *oid, 00902 size_t oidLen, MibVariant *value, size_t *valueLen) 00903 { 00904 error_t error; 00905 uint_t i; 00906 size_t n; 00907 Ipv4Addr localIpAddr; 00908 uint16_t localPort; 00909 Ipv4Addr remoteIpAddr; 00910 uint16_t remotePort; 00911 Socket *socket; 00912 00913 //Point to the instance identifier 00914 n = object->oidLen; 00915 00916 //The tcpConnLocalAddress is used as 1st instance identifier 00917 error = mibDecodeIpv4Addr(oid, oidLen, &n, &localIpAddr); 00918 //Invalid instance identifier? 00919 if(error) 00920 return error; 00921 00922 //The tcpConnLocalPort is used as 2nd instance identifier 00923 error = mibDecodePort(oid, oidLen, &n, &localPort); 00924 //Invalid instance identifier? 00925 if(error) 00926 return error; 00927 00928 //The tcpConnRemAddress is used as 3rd instance identifier 00929 error = mibDecodeIpv4Addr(oid, oidLen, &n, &remoteIpAddr); 00930 //Invalid instance identifier? 00931 if(error) 00932 return error; 00933 00934 //The tcpConnRemPort is used as 4th instance identifier 00935 error = mibDecodePort(oid, oidLen, &n, &remotePort); 00936 //Invalid instance identifier? 00937 if(error) 00938 return error; 00939 00940 //Sanity check 00941 if(n != oidLen) 00942 return ERROR_INSTANCE_NOT_FOUND; 00943 00944 //Loop through socket descriptors 00945 for(i = 0; i < SOCKET_MAX_COUNT; i++) 00946 { 00947 //Point to current socket 00948 socket = &socketTable[i]; 00949 00950 //TCP socket? 00951 if(socketTable[i].type == SOCKET_TYPE_STREAM) 00952 { 00953 //Check local IP address 00954 if(socket->localIpAddr.length == sizeof(Ipv6Addr)) 00955 continue; 00956 if(socket->localIpAddr.ipv4Addr != localIpAddr) 00957 continue; 00958 //Check local port number 00959 if(socket->localPort != localPort) 00960 continue; 00961 //Check remote IP address 00962 if(socket->remoteIpAddr.length == sizeof(Ipv6Addr)) 00963 continue; 00964 if(socket->remoteIpAddr.ipv4Addr != remoteIpAddr) 00965 continue; 00966 //Check remote port number 00967 if(socket->remotePort != remotePort) 00968 continue; 00969 00970 //A matching socket has been found 00971 break; 00972 } 00973 } 00974 00975 //No matching connection found in socket table? 00976 if(i >= SOCKET_MAX_COUNT) 00977 return ERROR_INSTANCE_NOT_FOUND; 00978 00979 //tcpConnState object? 00980 if(!strcmp(object->name, "tcpConnState")) 00981 { 00982 //Get object value 00983 switch(socket->state) 00984 { 00985 case TCP_STATE_CLOSED: 00986 value->integer = MIB2_TCP_CONN_STATE_CLOSED; 00987 break; 00988 case TCP_STATE_LISTEN: 00989 value->integer = MIB2_TCP_CONN_STATE_LISTEN; 00990 break; 00991 case TCP_STATE_SYN_SENT: 00992 value->integer = MIB2_TCP_CONN_STATE_SYN_SENT; 00993 break; 00994 case TCP_STATE_SYN_RECEIVED: 00995 value->integer = MIB2_TCP_CONN_STATE_SYN_RECEIVED; 00996 break; 00997 case TCP_STATE_ESTABLISHED: 00998 value->integer = MIB2_TCP_CONN_STATE_ESTABLISHED; 00999 break; 01000 case TCP_STATE_FIN_WAIT_1: 01001 value->integer = MIB2_TCP_CONN_STATE_FIN_WAIT_1; 01002 break; 01003 case TCP_STATE_FIN_WAIT_2: 01004 value->integer = MIB2_TCP_CONN_STATE_FIN_WAIT_2; 01005 break; 01006 case TCP_STATE_CLOSE_WAIT: 01007 value->integer = MIB2_TCP_CONN_STATE_CLOSE_WAIT; 01008 break; 01009 case TCP_STATE_LAST_ACK: 01010 value->integer = MIB2_TCP_CONN_STATE_LAST_ACK; 01011 break; 01012 case TCP_STATE_CLOSING: 01013 value->integer = MIB2_TCP_CONN_STATE_CLOSING; 01014 break; 01015 case TCP_STATE_TIME_WAIT: 01016 value->integer = MIB2_TCP_CONN_STATE_TIME_WAIT; 01017 break; 01018 default: 01019 value->integer = 0; 01020 break; 01021 } 01022 } 01023 //tcpConnLocalAddress object? 01024 else if(!strcmp(object->name, "tcpConnLocalAddress")) 01025 { 01026 //Get object value 01027 ipv4CopyAddr(value->ipAddr, &socket->localIpAddr.ipv4Addr); 01028 } 01029 //tcpConnLocalPort object? 01030 else if(!strcmp(object->name, "tcpConnLocalPort")) 01031 { 01032 //Get object value 01033 value->integer = socket->localPort; 01034 } 01035 //tcpConnRemAddress object? 01036 else if(!strcmp(object->name, "tcpConnRemAddress")) 01037 { 01038 //Get object value 01039 ipv4CopyAddr(value->ipAddr, &socket->remoteIpAddr.ipv4Addr); 01040 } 01041 //tcpConnRemPort object? 01042 else if(!strcmp(object->name, "tcpConnRemPort")) 01043 { 01044 //Get object value 01045 value->integer = socket->remotePort; 01046 } 01047 //Unknown object? 01048 else 01049 { 01050 //The specified object does not exist 01051 error = ERROR_OBJECT_NOT_FOUND; 01052 } 01053 01054 //Return status code 01055 return error; 01056 } 01057 01058 01059 /** 01060 * @brief Get next tcpConnEntry object 01061 * @param[in] object Pointer to the MIB object descriptor 01062 * @param[in] oid Object identifier 01063 * @param[in] oidLen Length of the OID, in bytes 01064 * @param[out] nextOid OID of the next object in the MIB 01065 * @param[out] nextOidLen Length of the next object identifier, in bytes 01066 * @return Error code 01067 **/ 01068 01069 error_t mib2GetNextTcpConnEntry(const MibObject *object, const uint8_t *oid, 01070 size_t oidLen, uint8_t *nextOid, size_t *nextOidLen) 01071 { 01072 error_t error; 01073 uint_t i; 01074 size_t n; 01075 bool_t acceptable; 01076 Ipv4Addr localIpAddr; 01077 uint16_t localPort; 01078 Ipv4Addr remoteIpAddr; 01079 uint16_t remotePort; 01080 Socket *socket; 01081 01082 //Initialize variables 01083 localIpAddr = IPV4_UNSPECIFIED_ADDR; 01084 localPort = 0; 01085 remoteIpAddr = IPV4_UNSPECIFIED_ADDR; 01086 remotePort = 0; 01087 01088 //Make sure the buffer is large enough to hold the OID prefix 01089 if(*nextOidLen < object->oidLen) 01090 return ERROR_BUFFER_OVERFLOW; 01091 01092 //Copy OID prefix 01093 memcpy(nextOid, object->oid, object->oidLen); 01094 01095 //Loop through socket descriptors 01096 for(i = 0; i < SOCKET_MAX_COUNT; i++) 01097 { 01098 //Point to current socket 01099 socket = &socketTable[i]; 01100 01101 //TCP socket? 01102 if(socketTable[i].type == SOCKET_TYPE_STREAM) 01103 { 01104 //Filter out IPv6 connections 01105 if(socket->localIpAddr.length != sizeof(Ipv6Addr) && 01106 socket->remoteIpAddr.length != sizeof(Ipv6Addr)) 01107 { 01108 //Append the instance identifier to the OID prefix 01109 n = object->oidLen; 01110 01111 //The tcpConnLocalAddress is used as 1st instance identifier 01112 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, socket->localIpAddr.ipv4Addr); 01113 //Any error to report? 01114 if(error) 01115 return error; 01116 01117 //The tcpConnLocalPort is used as 2nd instance identifier 01118 error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort); 01119 //Any error to report? 01120 if(error) 01121 return error; 01122 01123 //The tcpConnRemAddress is used as 3rd instance identifier 01124 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, socket->remoteIpAddr.ipv4Addr); 01125 //Any error to report? 01126 if(error) 01127 return error; 01128 01129 //The tcpConnRemPort is used as 4th instance identifier 01130 error = mibEncodePort(nextOid, *nextOidLen, &n, socket->remotePort); 01131 //Any error to report? 01132 if(error) 01133 return error; 01134 01135 //Check whether the resulting object identifier lexicographically 01136 //follows the specified OID 01137 if(oidComp(nextOid, n, oid, oidLen) > 0) 01138 { 01139 //Perform lexicographic comparison 01140 if(localPort == 0 && remotePort == 0) 01141 acceptable = TRUE; 01142 else if(ntohl(socket->localIpAddr.ipv4Addr) < ntohl(localIpAddr)) 01143 acceptable = TRUE; 01144 else if(ntohl(socket->localIpAddr.ipv4Addr) > ntohl(localIpAddr)) 01145 acceptable = FALSE; 01146 else if(socket->localPort < localPort) 01147 acceptable = TRUE; 01148 else if(socket->localPort > localPort) 01149 acceptable = FALSE; 01150 else if(ntohl(socket->remoteIpAddr.ipv4Addr) < ntohl(remoteIpAddr)) 01151 acceptable = TRUE; 01152 else if(ntohl(socket->remoteIpAddr.ipv4Addr) > ntohl(remoteIpAddr)) 01153 acceptable = FALSE; 01154 else if(socket->remotePort < remotePort) 01155 acceptable = TRUE; 01156 else 01157 acceptable = FALSE; 01158 01159 //Save the closest object identifier that follows the specified 01160 //OID in lexicographic order 01161 if(acceptable) 01162 { 01163 localIpAddr = socket->localIpAddr.ipv4Addr; 01164 localPort = socket->localPort; 01165 remoteIpAddr = socket->remoteIpAddr.ipv4Addr; 01166 remotePort = socket->remotePort; 01167 } 01168 } 01169 } 01170 } 01171 } 01172 01173 //The specified OID does not lexicographically precede the name 01174 //of some object? 01175 if(localPort == 0 && remotePort == 0) 01176 return ERROR_OBJECT_NOT_FOUND; 01177 01178 //Append the instance identifier to the OID prefix 01179 n = object->oidLen; 01180 01181 //The tcpConnLocalAddress is used as 1st instance identifier 01182 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, localIpAddr); 01183 //Any error to report? 01184 if(error) 01185 return error; 01186 01187 //The tcpConnLocalPort is used as 2nd instance identifier 01188 error = mibEncodePort(nextOid, *nextOidLen, &n, localPort); 01189 //Any error to report? 01190 if(error) 01191 return error; 01192 01193 //The tcpConnRemAddress is used as 3rd instance identifier 01194 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, remoteIpAddr); 01195 //Any error to report? 01196 if(error) 01197 return error; 01198 01199 //The tcpConnRemPort is used as 4th instance identifier 01200 error = mibEncodePort(nextOid, *nextOidLen, &n, remotePort); 01201 //Any error to report? 01202 if(error) 01203 return error; 01204 01205 //Save the length of the resulting object identifier 01206 *nextOidLen = n; 01207 //Next object found 01208 return NO_ERROR; 01209 } 01210 01211 01212 /** 01213 * @brief Get udpEntry object value 01214 * @param[in] object Pointer to the MIB object descriptor 01215 * @param[in] oid Object identifier (object name and instance identifier) 01216 * @param[in] oidLen Length of the OID, in bytes 01217 * @param[out] value Object value 01218 * @param[in,out] valueLen Length of the object value, in bytes 01219 * @return Error code 01220 **/ 01221 01222 error_t mib2GetUdpEntry(const MibObject *object, const uint8_t *oid, 01223 size_t oidLen, MibVariant *value, size_t *valueLen) 01224 { 01225 error_t error; 01226 uint_t i; 01227 size_t n; 01228 Ipv4Addr localIpAddr; 01229 uint16_t localPort; 01230 01231 //Point to the instance identifier 01232 n = object->oidLen; 01233 01234 //The udpLocalAddress is used as 1st instance identifier 01235 error = mibDecodeIpv4Addr(oid, oidLen, &n, &localIpAddr); 01236 //Invalid instance identifier? 01237 if(error) 01238 return error; 01239 01240 //The udpLocalPort is used as 2nd instance identifier 01241 error = mibDecodePort(oid, oidLen, &n, &localPort); 01242 //Invalid instance identifier? 01243 if(error) 01244 return error; 01245 01246 //Sanity check 01247 if(n != oidLen) 01248 return ERROR_INSTANCE_NOT_FOUND; 01249 01250 //Loop through socket descriptors 01251 for(i = 0; i < SOCKET_MAX_COUNT; i++) 01252 { 01253 //Point to current socket 01254 Socket *socket = &socketTable[i]; 01255 01256 //UDP socket? 01257 if(socketTable[i].type == SOCKET_TYPE_DGRAM) 01258 { 01259 //Check local IP address 01260 if(socket->localIpAddr.length == sizeof(Ipv6Addr)) 01261 continue; 01262 if(socket->localIpAddr.ipv4Addr != localIpAddr) 01263 continue; 01264 //Check local port number 01265 if(socket->localPort != localPort) 01266 continue; 01267 01268 //A matching socket has been found 01269 break; 01270 } 01271 } 01272 01273 //No matching connection found in socket table? 01274 if(i >= SOCKET_MAX_COUNT) 01275 { 01276 //Loop through the UDP callback table 01277 for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++) 01278 { 01279 //Point to the current entry 01280 UdpRxCallbackDesc *entry = &udpCallbackTable[i]; 01281 01282 //Check whether the entry is currently in used 01283 if(entry->callback != NULL) 01284 { 01285 //Check local port number 01286 if(entry->port == localPort) 01287 break; 01288 } 01289 } 01290 01291 //No matching connection found in UDP callback table? 01292 if(i >= UDP_CALLBACK_TABLE_SIZE) 01293 return ERROR_INSTANCE_NOT_FOUND; 01294 } 01295 01296 //udpLocalAddress object? 01297 if(!strcmp(object->name, "udpLocalAddress")) 01298 { 01299 //Get object value 01300 ipv4CopyAddr(value->ipAddr, &localIpAddr); 01301 } 01302 //udpLocalPort object? 01303 else if(!strcmp(object->name, "udpLocalPort")) 01304 { 01305 //Get object value 01306 value->integer = localPort; 01307 } 01308 //Unknown object? 01309 else 01310 { 01311 //The specified object does not exist 01312 error = ERROR_OBJECT_NOT_FOUND; 01313 } 01314 01315 //Return status code 01316 return error; 01317 } 01318 01319 01320 /** 01321 * @brief Get next udpEntry object 01322 * @param[in] object Pointer to the MIB object descriptor 01323 * @param[in] oid Object identifier 01324 * @param[in] oidLen Length of the OID, in bytes 01325 * @param[out] nextOid OID of the next object in the MIB 01326 * @param[out] nextOidLen Length of the next object identifier, in bytes 01327 * @return Error code 01328 **/ 01329 01330 error_t mib2GetNextUdpEntry(const MibObject *object, const uint8_t *oid, 01331 size_t oidLen, uint8_t *nextOid, size_t *nextOidLen) 01332 { 01333 error_t error; 01334 uint_t i; 01335 size_t n; 01336 bool_t acceptable; 01337 Ipv4Addr localIpAddr; 01338 uint16_t localPort; 01339 01340 //Initialize variables 01341 localIpAddr = IPV4_UNSPECIFIED_ADDR; 01342 localPort = 0; 01343 01344 //Make sure the buffer is large enough to hold the OID prefix 01345 if(*nextOidLen < object->oidLen) 01346 return ERROR_BUFFER_OVERFLOW; 01347 01348 //Copy OID prefix 01349 memcpy(nextOid, object->oid, object->oidLen); 01350 01351 //Loop through socket descriptors 01352 for(i = 0; i < SOCKET_MAX_COUNT; i++) 01353 { 01354 //Point to current socket 01355 Socket *socket = &socketTable[i]; 01356 01357 //TCP socket? 01358 if(socketTable[i].type == SOCKET_TYPE_DGRAM) 01359 { 01360 //Filter out IPv6 connections 01361 if(socket->localIpAddr.length != sizeof(Ipv6Addr) && 01362 socket->remoteIpAddr.length != sizeof(Ipv6Addr)) 01363 { 01364 //Append the instance identifier to the OID prefix 01365 n = object->oidLen; 01366 01367 //The udpLocalAddress is used as 1st instance identifier 01368 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, socket->localIpAddr.ipv4Addr); 01369 //Any error to report? 01370 if(error) 01371 return error; 01372 01373 //The udpLocalPort is used as 2nd instance identifier 01374 error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort); 01375 //Any error to report? 01376 if(error) 01377 return error; 01378 01379 //Check whether the resulting object identifier lexicographically 01380 //follows the specified OID 01381 if(oidComp(nextOid, n, oid, oidLen) > 0) 01382 { 01383 //Perform lexicographic comparison 01384 if(localPort == 0) 01385 acceptable = TRUE; 01386 else if(ntohl(socket->localIpAddr.ipv4Addr) < ntohl(localIpAddr)) 01387 acceptable = TRUE; 01388 else if(ntohl(socket->localIpAddr.ipv4Addr) > ntohl(localIpAddr)) 01389 acceptable = FALSE; 01390 else if(socket->localPort < localPort) 01391 acceptable = TRUE; 01392 else 01393 acceptable = FALSE; 01394 01395 //Save the closest object identifier that follows the specified 01396 //OID in lexicographic order 01397 if(acceptable) 01398 { 01399 localIpAddr = socket->localIpAddr.ipv4Addr; 01400 localPort = socket->localPort; 01401 } 01402 } 01403 } 01404 } 01405 } 01406 01407 //Loop through the UDP callback table 01408 for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++) 01409 { 01410 //Point to the current entry 01411 UdpRxCallbackDesc *entry = &udpCallbackTable[i]; 01412 01413 //Check whether the entry is currently in used 01414 if(entry->callback != NULL) 01415 { 01416 //Append the instance identifier to the OID prefix 01417 n = object->oidLen; 01418 01419 //The udpLocalAddress is used as 1st instance identifier 01420 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, IPV4_UNSPECIFIED_ADDR); 01421 //Any error to report? 01422 if(error) 01423 return error; 01424 01425 //The udpLocalPort is used as 2nd instance identifier 01426 error = mibEncodePort(nextOid, *nextOidLen, &n, entry->port); 01427 //Any error to report? 01428 if(error) 01429 return error; 01430 01431 //Check whether the resulting object identifier lexicographically 01432 //follows the specified OID 01433 if(oidComp(nextOid, n, oid, oidLen) > 0) 01434 { 01435 //Perform lexicographic comparison 01436 if(localPort == 0) 01437 acceptable = TRUE; 01438 else if(ntohl(IPV4_UNSPECIFIED_ADDR) < ntohl(localIpAddr)) 01439 acceptable = TRUE; 01440 else if(ntohl(IPV4_UNSPECIFIED_ADDR) > ntohl(localIpAddr)) 01441 acceptable = FALSE; 01442 else if(entry->port < localPort) 01443 acceptable = TRUE; 01444 else 01445 acceptable = FALSE; 01446 01447 //Save the closest object identifier that follows the specified 01448 //OID in lexicographic order 01449 if(acceptable) 01450 { 01451 localIpAddr = IPV4_UNSPECIFIED_ADDR; 01452 localPort = entry->port; 01453 } 01454 } 01455 } 01456 } 01457 01458 //The specified OID does not lexicographically precede the name 01459 //of some object? 01460 if(localPort == 0) 01461 return ERROR_OBJECT_NOT_FOUND; 01462 01463 //Append the instance identifier to the OID prefix 01464 n = object->oidLen; 01465 01466 //The udpLocalAddress is used as 1st instance identifier 01467 error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, localIpAddr); 01468 //Any error to report? 01469 if(error) 01470 return error; 01471 01472 //The udpLocalPort is used as 2nd instance identifier 01473 error = mibEncodePort(nextOid, *nextOidLen, &n, localPort); 01474 //Any error to report? 01475 if(error) 01476 return error; 01477 01478 //Save the length of the resulting object identifier 01479 *nextOidLen = n; 01480 //Next object found 01481 return NO_ERROR; 01482 } 01483 01484 #endif 01485 #endif 01486
Generated on Tue Jul 12 2022 17:10:14 by
1.7.2