mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 14:10:32 +00:00
inetmib1: Support the MIB2 IP address table.
This commit is contained in:
parent
7d85506a9d
commit
ea20d6b793
@ -98,6 +98,11 @@ static AsnInteger32 mapStructEntryToValue(struct structToAsnValue *map,
|
||||
return SNMP_ERRORSTATUS_NOERROR;
|
||||
}
|
||||
|
||||
static void copyIpAddr(AsnAny *value, void *src)
|
||||
{
|
||||
setStringValue(value, ASN_IPADDRESS, sizeof(DWORD), src);
|
||||
}
|
||||
|
||||
static UINT mib2[] = { 1,3,6,1,2,1 };
|
||||
static UINT mib2System[] = { 1,3,6,1,2,1,1 };
|
||||
|
||||
@ -408,6 +413,166 @@ static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1 };
|
||||
static PMIB_IPADDRTABLE ipAddrTable;
|
||||
|
||||
static struct structToAsnValue mib2IpAddrMap[] = {
|
||||
{ FIELD_OFFSET(MIB_IPADDRROW, dwAddr), copyIpAddr },
|
||||
{ FIELD_OFFSET(MIB_IPADDRROW, dwIndex), copyInt },
|
||||
{ FIELD_OFFSET(MIB_IPADDRROW, dwMask), copyIpAddr },
|
||||
{ FIELD_OFFSET(MIB_IPADDRROW, dwBCastAddr), copyInt },
|
||||
{ FIELD_OFFSET(MIB_IPADDRROW, dwReasmSize), copyInt },
|
||||
};
|
||||
|
||||
static void mib2IpAddrInit(void)
|
||||
{
|
||||
DWORD size = 0, ret = GetIpAddrTable(NULL, &size, FALSE);
|
||||
|
||||
if (ret == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
ipAddrTable = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
if (ipAddrTable)
|
||||
GetIpAddrTable(ipAddrTable, &size, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
||||
AsnInteger32 *pErrorStatus)
|
||||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2IpAddr);
|
||||
UINT tableIndex = 0, item = 0;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
||||
switch (bPduType)
|
||||
{
|
||||
case SNMP_PDU_GET:
|
||||
case SNMP_PDU_GETNEXT:
|
||||
*pErrorStatus = 0;
|
||||
if (!ipAddrTable)
|
||||
{
|
||||
/* There is no address present, so let the caller deal with
|
||||
* finding the successor.
|
||||
*/
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
else if (!SnmpUtilOidNCmp(&pVarBind->name, &myOid, myOid.idLength) &&
|
||||
pVarBind->name.idLength < myOid.idLength + 5)
|
||||
{
|
||||
/* 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 address */
|
||||
tableIndex = 1;
|
||||
if (pVarBind->name.idLength == myOid.idLength + 1)
|
||||
item = pVarBind->name.ids[myOid.idLength];
|
||||
else
|
||||
item = 1;
|
||||
}
|
||||
}
|
||||
else if (!SnmpUtilOidNCmp(&pVarBind->name, &myOid, myOid.idLength) &&
|
||||
pVarBind->name.idLength == myOid.idLength + 5)
|
||||
{
|
||||
item = pVarBind->name.ids[myOid.idLength];
|
||||
if (!item)
|
||||
{
|
||||
if (bPduType == SNMP_PDU_GET)
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
else
|
||||
{
|
||||
tableIndex = 1;
|
||||
item = 1;
|
||||
}
|
||||
}
|
||||
else if (item - 1 >= DEFINE_SIZEOF(mib2IpAddrMap))
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
else
|
||||
{
|
||||
DWORD addr;
|
||||
UINT i;
|
||||
|
||||
/* Map the IDs to an IP address in little-endian order */
|
||||
addr =
|
||||
(BYTE)pVarBind->name.ids[myOid.idLength + 4] << 24 |
|
||||
(BYTE)pVarBind->name.ids[myOid.idLength + 3] << 16 |
|
||||
(BYTE)pVarBind->name.ids[myOid.idLength + 2] << 8 |
|
||||
(BYTE)pVarBind->name.ids[myOid.idLength + 1];
|
||||
/* Find the item whose address matches */
|
||||
for (i = 0; !tableIndex && i < ipAddrTable->dwNumEntries; i++)
|
||||
if (addr == ipAddrTable->table[i].dwAddr)
|
||||
tableIndex = i + 1;
|
||||
if (bPduType == SNMP_PDU_GETNEXT)
|
||||
{
|
||||
if (!tableIndex)
|
||||
{
|
||||
/* No address matched, so let caller find successor */
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We want the successor to the matching address */
|
||||
tableIndex++;
|
||||
}
|
||||
}
|
||||
if (tableIndex > ipAddrTable->dwNumEntries)
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Some item after the address table was requested, so let the
|
||||
* caller deal with finding a successor.
|
||||
*/
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
if (!*pErrorStatus)
|
||||
{
|
||||
assert(tableIndex);
|
||||
assert(item);
|
||||
*pErrorStatus = mapStructEntryToValue(mib2IpAddrMap,
|
||||
DEFINE_SIZEOF(mib2IpAddrMap),
|
||||
&ipAddrTable->table[tableIndex - 1], item, bPduType, pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
{
|
||||
UINT id;
|
||||
BYTE *ptr;
|
||||
AsnObjectIdentifier oid;
|
||||
|
||||
SnmpUtilOidCpy(&pVarBind->name, &myOid);
|
||||
oid.idLength = 1;
|
||||
oid.ids = &id;
|
||||
id = item;
|
||||
SnmpUtilOidAppend(&pVarBind->name, &oid);
|
||||
for (ptr = (BYTE *)&ipAddrTable->table[tableIndex - 1].dwAddr;
|
||||
ptr < (BYTE *)&ipAddrTable->table[tableIndex - 1].dwAddr +
|
||||
sizeof(DWORD); ptr++)
|
||||
{
|
||||
id = *ptr;
|
||||
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;
|
||||
}
|
||||
|
||||
static UINT mib2Icmp[] = { 1,3,6,1,2,1,5 };
|
||||
static MIB_ICMP icmpStats;
|
||||
|
||||
@ -508,6 +673,7 @@ static struct mibImplementation supportedIDs[] = {
|
||||
{ DEFINE_OID(mib2IfNumber), mib2IfNumberInit, mib2IfNumberQuery },
|
||||
{ DEFINE_OID(mib2IfEntry), NULL, mib2IfEntryQuery },
|
||||
{ DEFINE_OID(mib2Ip), mib2IpStatsInit, mib2IpStatsQuery },
|
||||
{ DEFINE_OID(mib2IpAddr), mib2IpAddrInit, mib2IpAddrQuery },
|
||||
{ DEFINE_OID(mib2Icmp), mib2IcmpInit, mib2IcmpQuery },
|
||||
};
|
||||
static UINT minSupportedIDLength;
|
||||
|
@ -63,6 +63,7 @@ static void testQuery(void)
|
||||
UINT mib2IfDescr[] = { 1,3,6,1,2,1,2,2,1,2 };
|
||||
UINT mib2IfAdminStatus[] = { 1,3,6,1,2,1,2,2,1,7 };
|
||||
UINT mib2IfOperStatus[] = { 1,3,6,1,2,1,2,2,1,8 };
|
||||
UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1,1 };
|
||||
SnmpVarBind vars[3], vars2[3];
|
||||
UINT entry;
|
||||
|
||||
@ -242,6 +243,62 @@ static void testQuery(void)
|
||||
ok(!SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, vars[0].name.idLength),
|
||||
"expected 1.3.6.1.2.1.2, got %s\n", SnmpUtilOidToA(&vars2[0].name));
|
||||
SnmpUtilVarBindFree(&vars2[0]);
|
||||
|
||||
/* Check the type and OIDs of the IP address table */
|
||||
vars[0].name.idLength = sizeof(mib2IpAddr) / sizeof(mib2IpAddr[0]);
|
||||
vars[0].name.ids = mib2IpAddr;
|
||||
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());
|
||||
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.
|
||||
* FIXME: don't know if IPv6 addrs are shared with this table.
|
||||
* Don't think so, but I'm not certain.
|
||||
*/
|
||||
ok(vars2[0].name.idLength == vars[0].name.idLength + 4,
|
||||
"expected length %d, got %d\n", vars[0].name.idLength + 4,
|
||||
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;
|
||||
|
||||
/* This looks uglier than it is: the base OID for the IP
|
||||
* address, 1.3.6.1.2.1.4.20.1.1, is appended with the IP
|
||||
* address of the entry. So e.g. the loopback address is
|
||||
* identified in MIB2 as 1.3.6.1.2.1.4.20.1.1.127.0.0.1
|
||||
*/
|
||||
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 - 4 + 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 - 4 + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (moreData);
|
||||
SnmpUtilVarBindFree(&vars2[0]);
|
||||
}
|
||||
|
||||
START_TEST(main)
|
||||
|
Loading…
Reference in New Issue
Block a user