Commit 8f66c13e authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

inetmib1: Support the MIB2 UDP table.

parent cf3d35cf
......@@ -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;
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment