inetmib1: Use a helper function to get the item and instance of the MIB2 IP address table.
This commit is contained in:
parent
969bc943ac
commit
297190fde2
|
@ -311,6 +311,126 @@ static AsnInteger32 getItemFromOid(AsnObjectIdentifier *oid,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GenericTable
|
||||||
|
{
|
||||||
|
DWORD numEntries;
|
||||||
|
BYTE entries[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Finds the index in table whose IP address (at offset addressOffset within the
|
||||||
|
* entry) matches that given the OID, which is assumed to have at least 4 IDs.
|
||||||
|
*/
|
||||||
|
static UINT findOIDIPAddressInTable(AsnObjectIdentifier *oid,
|
||||||
|
struct GenericTable *table, size_t tableEntrySize, size_t addressOffset)
|
||||||
|
{
|
||||||
|
DWORD addr;
|
||||||
|
UINT i, index = 0;
|
||||||
|
|
||||||
|
/* Map the IDs to an IP address in little-endian order */
|
||||||
|
addr = (BYTE)oid->ids[3] << 24 | (BYTE)oid->ids[2] << 16 |
|
||||||
|
(BYTE)oid->ids[1] << 8 | (BYTE)oid->ids[0];
|
||||||
|
/* Find the item whose address matches */
|
||||||
|
for (i = 0; !index && i < table->numEntries; i++)
|
||||||
|
{
|
||||||
|
DWORD tableAddr =
|
||||||
|
*(DWORD *)(table->entries + i * tableEntrySize + addressOffset);
|
||||||
|
|
||||||
|
if (addr == tableAddr)
|
||||||
|
index = i + 1;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given an OID and a base OID that it must begin with, finds the item and
|
||||||
|
* element of the table whose IP address matches the instance from the OID.
|
||||||
|
* E.g., given an OID foo.1.2.3.4.5 and a base OID foo, returns item 1 and the
|
||||||
|
* index of the entry in the table whose IP address is 2.3.4.5.
|
||||||
|
* If bPduType is not SNMP_PDU_GETNEXT and either the item or instance is
|
||||||
|
* missing, returns SNMP_ERRORSTATUS_NOSUCHNAME.
|
||||||
|
* If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item and
|
||||||
|
* instance, or item 1, instance 1 if either is missing.
|
||||||
|
*/
|
||||||
|
static AsnInteger32 getItemAndIpAddressInstanceFromOid(AsnObjectIdentifier *oid,
|
||||||
|
AsnObjectIdentifier *base, BYTE bPduType, struct GenericTable *table,
|
||||||
|
size_t tableEntrySize, size_t addressOffset, UINT *item, UINT *instance)
|
||||||
|
{
|
||||||
|
AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR;
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
return SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
|
||||||
|
switch (bPduType)
|
||||||
|
{
|
||||||
|
case SNMP_PDU_GETNEXT:
|
||||||
|
if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
|
||||||
|
{
|
||||||
|
/* Return the first item and instance from the table */
|
||||||
|
*item = 1;
|
||||||
|
*instance = 1;
|
||||||
|
}
|
||||||
|
else if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
|
||||||
|
oid->idLength < base->idLength + 5)
|
||||||
|
{
|
||||||
|
/* Either the table or an item is specified, but the instance is
|
||||||
|
* not.
|
||||||
|
*/
|
||||||
|
*instance = 1;
|
||||||
|
if (oid->idLength >= base->idLength + 1)
|
||||||
|
{
|
||||||
|
*item = oid->ids[base->idLength];
|
||||||
|
if (!*item)
|
||||||
|
*item = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*item = 1;
|
||||||
|
}
|
||||||
|
else if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
|
||||||
|
oid->idLength == base->idLength + 5)
|
||||||
|
{
|
||||||
|
*item = oid->ids[base->idLength];
|
||||||
|
if (!*item)
|
||||||
|
{
|
||||||
|
*instance = 1;
|
||||||
|
*item = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AsnObjectIdentifier ipOid = { 4, oid->ids + base->idLength + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
*instance = findOIDIPAddressInTable(&ipOid, table,
|
||||||
|
tableEntrySize, addressOffset) + 1;
|
||||||
|
if (*instance > table->numEntries)
|
||||||
|
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
|
||||||
|
oid->idLength == base->idLength + 5)
|
||||||
|
{
|
||||||
|
*item = oid->ids[base->idLength];
|
||||||
|
if (!*item)
|
||||||
|
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AsnObjectIdentifier ipOid = { 4, oid->ids + base->idLength + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
*instance = findOIDIPAddressInTable(&ipOid, table,
|
||||||
|
tableEntrySize, addressOffset);
|
||||||
|
if (!*instance)
|
||||||
|
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static struct structToAsnValue mib2IfEntryMap[] = {
|
static struct structToAsnValue mib2IfEntryMap[] = {
|
||||||
{ FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt },
|
{ FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt },
|
||||||
{ FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyLengthPrecededString },
|
{ FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyLengthPrecededString },
|
||||||
|
@ -516,92 +636,10 @@ static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
||||||
{
|
{
|
||||||
case SNMP_PDU_GET:
|
case SNMP_PDU_GET:
|
||||||
case SNMP_PDU_GETNEXT:
|
case SNMP_PDU_GETNEXT:
|
||||||
*pErrorStatus = 0;
|
*pErrorStatus = getItemAndIpAddressInstanceFromOid(&pVarBind->name,
|
||||||
if (!ipAddrTable)
|
&myOid, bPduType, (struct GenericTable *)ipAddrTable,
|
||||||
{
|
sizeof(MIB_IPADDRROW), FIELD_OFFSET(MIB_IPADDRROW, dwAddr), &item,
|
||||||
/* There is no address present, so let the caller deal with
|
&tableIndex);
|
||||||
* 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)
|
if (!*pErrorStatus)
|
||||||
{
|
{
|
||||||
assert(tableIndex);
|
assert(tableIndex);
|
||||||
|
|
Loading…
Reference in New Issue