Juan Lang : inetmib1: Support the MIB2 UDP table.

Alexandre Julliard julliard at winehq.org
Mon Jun 30 08:26:45 CDT 2008


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Sat Jun 28 09:21:14 2008 -0700

inetmib1: Support the MIB2 UDP table.

---

 dlls/inetmib1/main.c       |   93 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/inetmib1/tests/main.c |   63 +++++++++++++++++++++++++++++
 2 files changed, 156 insertions(+), 0 deletions(-)

diff --git a/dlls/inetmib1/main.c b/dlls/inetmib1/main.c
index 2dba6cf..56e52a2 100644
--- a/dlls/inetmib1/main.c
+++ b/dlls/inetmib1/main.c
@@ -1037,6 +1037,98 @@ static BOOL mib2UdpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
     return TRUE;
 }
 
+static UINT mib2UdpEntry[] = { 1,3,6,1,2,1,7,5,1 };
+static PMIB_UDPTABLE udpTable;
+
+static void mib2UdpEntryInit(void)
+{
+    DWORD size = 0, ret = GetUdpTable(NULL, &size, TRUE);
+
+    if (ret == ERROR_INSUFFICIENT_BUFFER)
+    {
+        udpTable = HeapAlloc(GetProcessHeap(), 0, size);
+        if (udpTable)
+            GetUdpTable(udpTable, &size, TRUE);
+    }
+}
+
+static struct structToAsnValue mib2UdpEntryMap[] = {
+    { FIELD_OFFSET(MIB_UDPROW, dwLocalAddr), copyIpAddr },
+    { FIELD_OFFSET(MIB_UDPROW, dwLocalPort), copyInt },
+};
+
+static void oidToUdpRow(AsnObjectIdentifier *oid, void *dst)
+{
+    MIB_UDPROW *row = dst;
+
+    assert(oid && oid->idLength >= 5);
+    row->dwLocalAddr = oidToIpAddr(oid);
+    row->dwLocalPort = oid->ids[4];
+}
+
+static int compareUdpRow(const void *a, const void *b)
+{
+    const MIB_UDPROW *key = a, *value = b;
+    int ret;
+
+    ret = key->dwLocalAddr - value->dwLocalAddr;
+    if (ret == 0)
+        ret = key->dwLocalPort - value->dwLocalPort;
+    return ret;
+}
+
+static BOOL mib2UdpEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
+    AsnInteger32 *pErrorStatus)
+{
+    AsnObjectIdentifier myOid = DEFINE_OID(mib2UdpEntry);
+
+    TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
+        pErrorStatus);
+
+    switch (bPduType)
+    {
+    case SNMP_PDU_GET:
+    case SNMP_PDU_GETNEXT:
+        if (!udpTable)
+            *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
+        else
+        {
+            UINT tableIndex = 0, item = 0;
+
+            *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name, &myOid,
+                5, bPduType, (struct GenericTable *)udpTable,
+                sizeof(MIB_UDPROW), oidToUdpRow, compareUdpRow, &item,
+                &tableIndex);
+            if (!*pErrorStatus)
+            {
+                assert(tableIndex);
+                assert(item);
+                *pErrorStatus = mapStructEntryToValue(mib2UdpEntryMap,
+                    DEFINE_SIZEOF(mib2UdpEntryMap),
+                    &udpTable->table[tableIndex - 1], item, bPduType, pVarBind);
+                if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
+                {
+                    AsnObjectIdentifier oid;
+
+                    setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
+                        udpTable->table[tableIndex - 1].dwLocalAddr);
+                    oid.idLength = 1;
+                    oid.ids = &udpTable->table[tableIndex - 1].dwLocalPort;
+                    SnmpUtilOidAppend(&pVarBind->name, &oid);
+                }
+            }
+        }
+        break;
+    case SNMP_PDU_SET:
+        *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
+        break;
+    default:
+        FIXME("0x%02x: unsupported PDU type\n", bPduType);
+        *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
+    }
+    return TRUE;
+}
+
 /* This list MUST BE lexicographically sorted */
 static struct mibImplementation supportedIDs[] = {
     { DEFINE_OID(mib2IfNumber), mib2IfNumberInit, mib2IfNumberQuery },
@@ -1048,6 +1140,7 @@ static struct mibImplementation supportedIDs[] = {
     { DEFINE_OID(mib2Icmp), mib2IcmpInit, mib2IcmpQuery },
     { DEFINE_OID(mib2Tcp), mib2TcpInit, mib2TcpQuery },
     { DEFINE_OID(mib2Udp), mib2UdpInit, mib2UdpQuery },
+    { DEFINE_OID(mib2UdpEntry), mib2UdpEntryInit, mib2UdpEntryQuery },
 };
 static UINT minSupportedIDLength;
 
diff --git a/dlls/inetmib1/tests/main.c b/dlls/inetmib1/tests/main.c
index 012d6d2..e2e63f2 100644
--- a/dlls/inetmib1/tests/main.c
+++ b/dlls/inetmib1/tests/main.c
@@ -65,6 +65,7 @@ static void testQuery(void)
     UINT mib2IfOperStatus[] = { 1,3,6,1,2,1,2,2,1,8 };
     UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1,1 };
     UINT mib2IpRouteTable[] = { 1,3,6,1,2,1,4,21,1,1 };
+    UINT mib2UdpTable[] = { 1,3,6,1,2,1,7,5,1,1 };
     SnmpVarBind vars[3], vars2[3];
     UINT entry;
 
@@ -356,6 +357,68 @@ static void testQuery(void)
         }
     } while (moreData);
     SnmpUtilVarBindFree(&vars2[0]);
+
+    /* Check the type and OIDs of the UDP table */
+    vars[0].name.idLength = DEFINE_SIZEOF(mib2UdpTable);
+    vars[0].name.ids = mib2UdpTable;
+    SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
+    vars2[0].value.asnType = 0;
+    list.len = 1;
+    list.list = vars2;
+    moreData = TRUE;
+    do {
+        ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
+        ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
+        /* FIXME:  error and index aren't checked here because the UDP table is
+         * the last OID currently supported by Wine, so the last GetNext fails.
+         * todo_wine is also not effective because it will succeed for all but
+         * the last GetNext.  Remove the if (0) if any later OID is supported
+         * by Wine.
+         */
+        if (0) {
+        ok(error == SNMP_ERRORSTATUS_NOERROR,
+            "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
+        ok(index == 0, "expected index 0, got %d\n", index);
+        }
+        if (!ret)
+            moreData = FALSE;
+        else if (error)
+            moreData = FALSE;
+        else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
+            vars[0].name.idLength))
+            moreData = FALSE;
+        if (moreData)
+        {
+            /* Make sure the size of the OID is right. */
+            ok(vars2[0].name.idLength == vars[0].name.idLength + 5,
+                "expected length %d, got %d\n", vars[0].name.idLength + 5,
+                vars2[0].name.idLength);
+            /* Make sure the type is right */
+            ok(vars2[0].value.asnType == ASN_IPADDRESS,
+                "expected type ASN_IPADDRESS, got %02x\n",
+                vars2[0].value.asnType);
+            if (vars2[0].value.asnType == ASN_IPADDRESS)
+            {
+                UINT i;
+
+                /* Again with the ugly:  the base OID for the UDP table,
+                 * 1.3.6.1.2.1.7.5.1, is appended with the local IP address and
+                 * port number of the entry.  So e.g. an entry for
+                 * 192.168.1.1:4000 is identified in MIB2 as
+                 * 1.3.6.1.2.1.7.5.1.192.168.1.1.4000
+                 */
+                for (i = 0; i < vars2[0].value.asnValue.address.length; i++)
+                {
+                    ok(vars2[0].value.asnValue.address.stream[i] ==
+                        vars2[0].name.ids[vars2[0].name.idLength - 5 + i],
+                        "expected ident byte %d to be %d, got %d\n", i,
+                        vars2[0].value.asnValue.address.stream[i],
+                        vars2[0].name.ids[vars2[0].name.idLength - 5 + i]);
+                }
+            }
+        }
+    } while (moreData);
+    SnmpUtilVarBindFree(&vars2[0]);
 }
 
 START_TEST(main)




More information about the wine-cvs mailing list