inetmib1: Support the MIB2 UDP table.
This commit is contained in:
parent
cf3d35cf15
commit
8f66c13e35
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue