Juan Lang : inetmib1: Use a helper function to get the item and instance of the MIB2 IP address table .

Alexandre Julliard julliard at winehq.org
Wed Jun 25 16:44:40 CDT 2008


Module: wine
Branch: master
Commit: 297190fde2ef3d15d5c46ea1b393389668e95bec
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=297190fde2ef3d15d5c46ea1b393389668e95bec

Author: Juan Lang <juan.lang at 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);




More information about the wine-cvs mailing list