inetmib1: Implement SnmpExtensionQuery.
This commit is contained in:
parent
f28cd51d0d
commit
dedff1329f
|
@ -19,7 +19,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "snmp.h"
|
#include "snmp.h"
|
||||||
|
@ -51,10 +51,14 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
static UINT mib2[] = { 1,3,6,1,2,1 };
|
static UINT mib2[] = { 1,3,6,1,2,1 };
|
||||||
static UINT mib2System[] = { 1,3,6,1,2,1,1 };
|
static UINT mib2System[] = { 1,3,6,1,2,1,1 };
|
||||||
|
|
||||||
|
typedef BOOL (*varqueryfunc)(BYTE bPduType, SnmpVarBind *pVarBind,
|
||||||
|
AsnInteger32 *pErrorStatus);
|
||||||
|
|
||||||
struct mibImplementation
|
struct mibImplementation
|
||||||
{
|
{
|
||||||
AsnObjectIdentifier name;
|
AsnObjectIdentifier name;
|
||||||
void (*init)(void);
|
void (*init)(void);
|
||||||
|
varqueryfunc query;
|
||||||
};
|
};
|
||||||
|
|
||||||
static UINT mib2IfNumber[] = { 1,3,6,1,2,1,2,1 };
|
static UINT mib2IfNumber[] = { 1,3,6,1,2,1,2,1 };
|
||||||
|
@ -72,9 +76,11 @@ static void mib2IfNumberInit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This list MUST BE lexicographically sorted */
|
||||||
static struct mibImplementation supportedIDs[] = {
|
static struct mibImplementation supportedIDs[] = {
|
||||||
{ DEFINE_OID(mib2IfNumber), mib2IfNumberInit },
|
{ DEFINE_OID(mib2IfNumber), mib2IfNumberInit },
|
||||||
};
|
};
|
||||||
|
static UINT minSupportedIDLength;
|
||||||
|
|
||||||
BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference,
|
BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference,
|
||||||
HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion)
|
HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion)
|
||||||
|
@ -85,14 +91,47 @@ BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference,
|
||||||
TRACE("(%d, %p, %p)\n", dwUptimeReference, phSubagentTrapEvent,
|
TRACE("(%d, %p, %p)\n", dwUptimeReference, phSubagentTrapEvent,
|
||||||
pFirstSupportedRegion);
|
pFirstSupportedRegion);
|
||||||
|
|
||||||
|
minSupportedIDLength = UINT_MAX;
|
||||||
for (i = 0; i < sizeof(supportedIDs) / sizeof(supportedIDs[0]); i++)
|
for (i = 0; i < sizeof(supportedIDs) / sizeof(supportedIDs[0]); i++)
|
||||||
|
{
|
||||||
if (supportedIDs[i].init)
|
if (supportedIDs[i].init)
|
||||||
supportedIDs[i].init();
|
supportedIDs[i].init();
|
||||||
|
if (supportedIDs[i].name.idLength < minSupportedIDLength)
|
||||||
|
minSupportedIDLength = supportedIDs[i].name.idLength;
|
||||||
|
}
|
||||||
*phSubagentTrapEvent = NULL;
|
*phSubagentTrapEvent = NULL;
|
||||||
SnmpUtilOidCpy(pFirstSupportedRegion, &myOid);
|
SnmpUtilOidCpy(pFirstSupportedRegion, &myOid);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mibImplementation *findSupportedQuery(UINT *ids, UINT idLength,
|
||||||
|
UINT *matchingIndex)
|
||||||
|
{
|
||||||
|
int indexHigh = DEFINE_SIZEOF(supportedIDs) - 1, indexLow = 0, i;
|
||||||
|
struct mibImplementation *impl = NULL;
|
||||||
|
AsnObjectIdentifier oid1 = { idLength, ids};
|
||||||
|
|
||||||
|
if (!idLength)
|
||||||
|
return NULL;
|
||||||
|
for (i = (indexLow + indexHigh) / 2; !impl && indexLow <= indexHigh;
|
||||||
|
i = (indexLow + indexHigh) / 2)
|
||||||
|
{
|
||||||
|
INT cmp;
|
||||||
|
|
||||||
|
cmp = SnmpUtilOidNCmp(&oid1, &supportedIDs[i].name, idLength);
|
||||||
|
if (!cmp)
|
||||||
|
{
|
||||||
|
impl = &supportedIDs[i];
|
||||||
|
*matchingIndex = i;
|
||||||
|
}
|
||||||
|
else if (cmp > 0)
|
||||||
|
indexLow = i + 1;
|
||||||
|
else
|
||||||
|
indexHigh = i - 1;
|
||||||
|
}
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
||||||
AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex)
|
AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex)
|
||||||
{
|
{
|
||||||
|
@ -109,8 +148,52 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
||||||
if (!SnmpUtilOidNCmp(&pVarBindList->list[i].name, &mib2oid,
|
if (!SnmpUtilOidNCmp(&pVarBindList->list[i].name, &mib2oid,
|
||||||
mib2oid.idLength))
|
mib2oid.idLength))
|
||||||
{
|
{
|
||||||
FIXME("%s: stub\n", SnmpUtilOidToA(&pVarBindList->list[i].name));
|
struct mibImplementation *impl = NULL;
|
||||||
error = SNMP_ERRORSTATUS_NOSUCHNAME;
|
UINT len, matchingIndex = 0;
|
||||||
|
|
||||||
|
TRACE("%s\n", SnmpUtilOidToA(&pVarBindList->list[i].name));
|
||||||
|
/* Search for an implementation matching as many octets as possible
|
||||||
|
*/
|
||||||
|
for (len = pVarBindList->list[i].name.idLength;
|
||||||
|
len >= minSupportedIDLength && !impl; len--)
|
||||||
|
impl = findSupportedQuery(pVarBindList->list[i].name.ids, len,
|
||||||
|
&matchingIndex);
|
||||||
|
if (impl && impl->query)
|
||||||
|
impl->query(bPduType, &pVarBindList->list[i], &error);
|
||||||
|
else
|
||||||
|
error = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
if (error == SNMP_ERRORSTATUS_NOSUCHNAME &&
|
||||||
|
bPduType == SNMP_PDU_GETNEXT)
|
||||||
|
{
|
||||||
|
/* GetNext is special: it finds the successor to the given OID,
|
||||||
|
* so we have to continue until an implementation handles the
|
||||||
|
* query or we exhaust the table of supported OIDs.
|
||||||
|
*/
|
||||||
|
for (; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
|
||||||
|
matchingIndex < DEFINE_SIZEOF(supportedIDs);
|
||||||
|
matchingIndex++)
|
||||||
|
{
|
||||||
|
error = SNMP_ERRORSTATUS_NOERROR;
|
||||||
|
impl = &supportedIDs[matchingIndex];
|
||||||
|
if (impl->query)
|
||||||
|
impl->query(bPduType, &pVarBindList->list[i], &error);
|
||||||
|
else
|
||||||
|
error = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||||
|
}
|
||||||
|
/* If the query still isn't resolved, set the OID to the
|
||||||
|
* successor to the last entry in the table.
|
||||||
|
*/
|
||||||
|
if (error == SNMP_ERRORSTATUS_NOSUCHNAME)
|
||||||
|
{
|
||||||
|
SnmpUtilOidFree(&pVarBindList->list[i].name);
|
||||||
|
SnmpUtilOidCpy(&pVarBindList->list[i].name,
|
||||||
|
&supportedIDs[matchingIndex - 1].name);
|
||||||
|
pVarBindList->list[i].name.ids[
|
||||||
|
pVarBindList->list[i].name.idLength - 1] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (error)
|
||||||
|
errorIndex = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*pErrorStatus = error;
|
*pErrorStatus = error;
|
||||||
|
|
|
@ -117,7 +117,6 @@ static void testQuery(void)
|
||||||
ok(error == SNMP_ERRORSTATUS_NOSUCHNAME,
|
ok(error == SNMP_ERRORSTATUS_NOSUCHNAME,
|
||||||
"expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error);
|
"expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error);
|
||||||
/* The index is 1-based rather than 0-based */
|
/* The index is 1-based rather than 0-based */
|
||||||
todo_wine
|
|
||||||
ok(index == 1, "expected index 1, got %d\n", index);
|
ok(index == 1, "expected index 1, got %d\n", index);
|
||||||
|
|
||||||
/* Even though SnmpExtensionInit says this DLL supports the MIB2 system
|
/* Even though SnmpExtensionInit says this DLL supports the MIB2 system
|
||||||
|
@ -133,13 +132,13 @@ static void testQuery(void)
|
||||||
moreData = TRUE;
|
moreData = TRUE;
|
||||||
ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
|
ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
|
||||||
ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
|
ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
|
||||||
todo_wine
|
todo_wine {
|
||||||
ok(error == SNMP_ERRORSTATUS_NOERROR,
|
ok(error == SNMP_ERRORSTATUS_NOERROR,
|
||||||
"expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
|
"expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
|
||||||
ok(index == 0, "expected index 0, got %d\n", index);
|
ok(index == 0, "expected index 0, got %d\n", index);
|
||||||
|
}
|
||||||
vars[0].name.idLength = sizeof(mib2If) / sizeof(mib2If[0]);
|
vars[0].name.idLength = sizeof(mib2If) / sizeof(mib2If[0]);
|
||||||
vars[0].name.ids = mib2If;
|
vars[0].name.ids = mib2If;
|
||||||
todo_wine
|
|
||||||
ok(!SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, vars[0].name.idLength),
|
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));
|
"expected 1.3.6.1.2.1.2, got %s\n", SnmpUtilOidToA(&vars2[0].name));
|
||||||
SnmpUtilVarBindFree(&vars2[0]);
|
SnmpUtilVarBindFree(&vars2[0]);
|
||||||
|
|
Loading…
Reference in New Issue