Module: wine Branch: master Commit: 297190fde2ef3d15d5c46ea1b393389668e95bec URL: http://source.winehq.org/git/wine.git/?a=commit;h=297190fde2ef3d15d5c46ea1b3...
Author: Juan Lang juan.lang@gmail.com Date: Wed Jun 25 09:30:59 2008 -0700
inetmib1: Use a helper function to get the item and instance of the MIB2 IP address table.
---
dlls/inetmib1/main.c | 210 +++++++++++++++++++++++++++++-------------------- 1 files changed, 124 insertions(+), 86 deletions(-)
diff --git a/dlls/inetmib1/main.c b/dlls/inetmib1/main.c index f97a5ee..b6dea35 100644 --- a/dlls/inetmib1/main.c +++ b/dlls/inetmib1/main.c @@ -311,6 +311,126 @@ static AsnInteger32 getItemFromOid(AsnObjectIdentifier *oid, return ret; }
+struct GenericTable +{ + DWORD numEntries; + BYTE entries[1]; +}; + +/* Finds the index in table whose IP address (at offset addressOffset within the + * entry) matches that given the OID, which is assumed to have at least 4 IDs. + */ +static UINT findOIDIPAddressInTable(AsnObjectIdentifier *oid, + struct GenericTable *table, size_t tableEntrySize, size_t addressOffset) +{ + DWORD addr; + UINT i, index = 0; + + /* Map the IDs to an IP address in little-endian order */ + addr = (BYTE)oid->ids[3] << 24 | (BYTE)oid->ids[2] << 16 | + (BYTE)oid->ids[1] << 8 | (BYTE)oid->ids[0]; + /* Find the item whose address matches */ + for (i = 0; !index && i < table->numEntries; i++) + { + DWORD tableAddr = + *(DWORD *)(table->entries + i * tableEntrySize + addressOffset); + + if (addr == tableAddr) + index = i + 1; + } + return index; +} + +/* Given an OID and a base OID that it must begin with, finds the item and + * element of the table whose IP address matches the instance from the OID. + * E.g., given an OID foo.1.2.3.4.5 and a base OID foo, returns item 1 and the + * index of the entry in the table whose IP address is 2.3.4.5. + * If bPduType is not SNMP_PDU_GETNEXT and either the item or instance is + * missing, returns SNMP_ERRORSTATUS_NOSUCHNAME. + * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item and + * instance, or item 1, instance 1 if either is missing. + */ +static AsnInteger32 getItemAndIpAddressInstanceFromOid(AsnObjectIdentifier *oid, + AsnObjectIdentifier *base, BYTE bPduType, struct GenericTable *table, + size_t tableEntrySize, size_t addressOffset, UINT *item, UINT *instance) +{ + AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR; + + if (!table) + return SNMP_ERRORSTATUS_NOSUCHNAME; + + switch (bPduType) + { + case SNMP_PDU_GETNEXT: + if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0) + { + /* Return the first item and instance from the table */ + *item = 1; + *instance = 1; + } + else if (!SnmpUtilOidNCmp(oid, base, base->idLength) && + oid->idLength < base->idLength + 5) + { + /* Either the table or an item is specified, but the instance is + * not. + */ + *instance = 1; + if (oid->idLength >= base->idLength + 1) + { + *item = oid->ids[base->idLength]; + if (!*item) + *item = 1; + } + else + *item = 1; + } + else if (!SnmpUtilOidNCmp(oid, base, base->idLength) && + oid->idLength == base->idLength + 5) + { + *item = oid->ids[base->idLength]; + if (!*item) + { + *instance = 1; + *item = 1; + } + else + { + AsnObjectIdentifier ipOid = { 4, oid->ids + base->idLength + 1 + }; + + *instance = findOIDIPAddressInTable(&ipOid, table, + tableEntrySize, addressOffset) + 1; + if (*instance > table->numEntries) + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + break; + default: + if (!SnmpUtilOidNCmp(oid, base, base->idLength) && + oid->idLength == base->idLength + 5) + { + *item = oid->ids[base->idLength]; + if (!*item) + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + else + { + AsnObjectIdentifier ipOid = { 4, oid->ids + base->idLength + 1 + }; + + *instance = findOIDIPAddressInTable(&ipOid, table, + tableEntrySize, addressOffset); + if (!*instance) + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + return ret; +} + static struct structToAsnValue mib2IfEntryMap[] = { { FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt }, { FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyLengthPrecededString }, @@ -516,92 +636,10 @@ static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind, { case SNMP_PDU_GET: case SNMP_PDU_GETNEXT: - *pErrorStatus = 0; - if (!ipAddrTable) - { - /* There is no address present, so let the caller deal with - * finding the successor. - */ - *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; - } - else if (!SnmpUtilOidNCmp(&pVarBind->name, &myOid, myOid.idLength) && - pVarBind->name.idLength < myOid.idLength + 5) - { - /* Either the table or an element within the table is specified, - * but the instance is not. - */ - if (bPduType == SNMP_PDU_GET) - { - /* Can't get an interface entry without specifying the - * instance. - */ - *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; - } - else - { - /* Get the first address */ - tableIndex = 1; - if (pVarBind->name.idLength == myOid.idLength + 1) - item = pVarBind->name.ids[myOid.idLength]; - else - item = 1; - } - } - else if (!SnmpUtilOidNCmp(&pVarBind->name, &myOid, myOid.idLength) && - pVarBind->name.idLength == myOid.idLength + 5) - { - item = pVarBind->name.ids[myOid.idLength]; - if (!item) - { - if (bPduType == SNMP_PDU_GET) - *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; - else - { - tableIndex = 1; - item = 1; - } - } - else if (item - 1 >= DEFINE_SIZEOF(mib2IpAddrMap)) - *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; - else - { - DWORD addr; - UINT i; - - /* Map the IDs to an IP address in little-endian order */ - addr = - (BYTE)pVarBind->name.ids[myOid.idLength + 4] << 24 | - (BYTE)pVarBind->name.ids[myOid.idLength + 3] << 16 | - (BYTE)pVarBind->name.ids[myOid.idLength + 2] << 8 | - (BYTE)pVarBind->name.ids[myOid.idLength + 1]; - /* Find the item whose address matches */ - for (i = 0; !tableIndex && i < ipAddrTable->dwNumEntries; i++) - if (addr == ipAddrTable->table[i].dwAddr) - tableIndex = i + 1; - if (bPduType == SNMP_PDU_GETNEXT) - { - if (!tableIndex) - { - /* No address matched, so let caller find successor */ - *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; - } - else - { - /* We want the successor to the matching address */ - tableIndex++; - } - } - if (tableIndex > ipAddrTable->dwNumEntries) - *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; - } - } - else - { - /* Some item after the address table was requested, so let the - * caller deal with finding a successor. - */ - *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; - } + *pErrorStatus = getItemAndIpAddressInstanceFromOid(&pVarBind->name, + &myOid, bPduType, (struct GenericTable *)ipAddrTable, + sizeof(MIB_IPADDRROW), FIELD_OFFSET(MIB_IPADDRROW, dwAddr), &item, + &tableIndex); if (!*pErrorStatus) { assert(tableIndex);