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

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


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Wed Jun 25 09:27:53 2008 -0700

inetmib1: Use a helper function to get the item and instance of the MIB2 interface table.

---

 dlls/inetmib1/main.c |  120 ++++++++++++++++++++++++++++++++------------------
 1 files changed, 77 insertions(+), 43 deletions(-)

diff --git a/dlls/inetmib1/main.c b/dlls/inetmib1/main.c
index 7263ca5..2500fa1 100644
--- a/dlls/inetmib1/main.c
+++ b/dlls/inetmib1/main.c
@@ -193,6 +193,73 @@ static void copyOperStatus(AsnAny *value, void *src)
     };
 }
 
+/* Given an OID and a base OID that it must begin with, finds the item and
+ * integer instance from the OID.  E.g., given an OID foo.1.2 and a base OID
+ * foo, returns item 1 and instance 2.
+ * 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 getItemAndIntegerInstanceFromOid(AsnObjectIdentifier *oid,
+    AsnObjectIdentifier *base, BYTE bPduType, UINT *item, UINT *instance)
+{
+    AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR;
+
+    switch (bPduType)
+    {
+    case SNMP_PDU_GETNEXT:
+        if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
+        {
+            *item = 1;
+            *instance = 1;
+        }
+        else if (!SnmpUtilOidNCmp(oid, base, base->idLength))
+        {
+            if (oid->idLength == base->idLength ||
+                oid->idLength == base->idLength + 1)
+            {
+                /* Either the table or an item within the table is specified,
+                 * but the instance is not.  Get the first instance.
+                 */
+                *instance = 1;
+                if (oid->idLength == base->idLength + 1)
+                    *item = oid->ids[base->idLength];
+                else
+                    *item = 1;
+            }
+            else
+            {
+                *item = oid->ids[base->idLength];
+                *instance = oid->ids[base->idLength + 1] + 1;
+            }
+        }
+        else
+            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
+        break;
+    default:
+        if (!SnmpUtilOidNCmp(oid, base, base->idLength))
+        {
+            if (oid->idLength == base->idLength ||
+                oid->idLength == base->idLength + 1)
+            {
+                /* Either the table or an item within the table is specified,
+                 * but the instance is not.
+                 */
+                ret = SNMP_ERRORSTATUS_NOSUCHNAME;
+            }
+            else
+            {
+                *item = oid->ids[base->idLength];
+                *instance = oid->ids[base->idLength + 1];
+            }
+        }
+        else
+            ret = SNMP_ERRORSTATUS_NOSUCHNAME;
+    }
+    return ret;
+}
+
 static struct structToAsnValue mib2IfEntryMap[] = {
     { FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt },
     { FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyLengthPrecededString },
@@ -238,44 +305,12 @@ static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
              */
             *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
         }
-        else if (!SnmpUtilOidNCmp(&pVarBind->name, &entryOid, entryOid.idLength))
+        else
         {
             UINT tableIndex = 0, item = 0;
 
-            *pErrorStatus = 0;
-            if (pVarBind->name.idLength == entryOid.idLength ||
-                pVarBind->name.idLength == entryOid.idLength + 1)
-            {
-                /* 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 interface */
-                    tableIndex = 1;
-                    if (pVarBind->name.idLength == entryOid.idLength + 1)
-                        item = pVarBind->name.ids[entryOid.idLength];
-                    else
-                        item = 1;
-                }
-            }
-            else
-            {
-                tableIndex = pVarBind->name.ids[entryOid.idLength + 1];
-                item = pVarBind->name.ids[entryOid.idLength];
-                if (bPduType == SNMP_PDU_GETNEXT)
-                {
-                    tableIndex++;
-                    item = 1;
-                }
-            }
+            *pErrorStatus = getItemAndIntegerInstanceFromOid(&pVarBind->name,
+                &entryOid, bPduType, &item, &tableIndex);
             if (!*pErrorStatus)
             {
                 assert(tableIndex);
@@ -296,20 +331,19 @@ static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
                         oid.idLength = 1;
                         oid.ids = &item;
                         SnmpUtilOidAppend(&pVarBind->name, &oid);
+                        /* According to RFC1158, the value of the interface
+                         * index must vary between 1 and ifNumber (the number
+                         * of interfaces), so use the 1-based table index
+                         * directly, rather than assuming that IPHlpApi's
+                         * dwIndex will have the correct range.
+                         */
                         oid.idLength = 1;
-                        oid.ids = &ifTable->table[tableIndex - 1].dwIndex;
+                        oid.ids = &tableIndex;
                         SnmpUtilOidAppend(&pVarBind->name, &oid);
                     }
                 }
             }
         }
-        else
-        {
-            *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
-            /* Caller deals with OID if bPduType == SNMP_PDU_GETNEXT, so don't
-             * need to set it here.
-             */
-        }
         break;
     case SNMP_PDU_SET:
         *pErrorStatus = SNMP_ERRORSTATUS_READONLY;




More information about the wine-cvs mailing list