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