Juan Lang : inetmib1: Implement SnmpExtensionQuery.
Alexandre Julliard
julliard at winehq.org
Wed Jun 25 04:47:32 CDT 2008
Module: wine
Branch: master
Commit: dedff1329fe051f4f40f52da5dcc239b6ec65564
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dedff1329fe051f4f40f52da5dcc239b6ec65564
Author: Juan Lang <juan.lang at gmail.com>
Date: Tue May 20 20:52:39 2008 -0700
inetmib1: Implement SnmpExtensionQuery.
---
dlls/inetmib1/main.c | 89 ++++++++++++++++++++++++++++++++++++++++++-
dlls/inetmib1/tests/main.c | 5 +-
2 files changed, 88 insertions(+), 6 deletions(-)
diff --git a/dlls/inetmib1/main.c b/dlls/inetmib1/main.c
index 2ee0ba9..5e87b8c 100644
--- a/dlls/inetmib1/main.c
+++ b/dlls/inetmib1/main.c
@@ -19,7 +19,7 @@
#include "config.h"
#include <stdarg.h>
-
+#include <limits.h>
#include "windef.h"
#include "winbase.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 mib2System[] = { 1,3,6,1,2,1,1 };
+typedef BOOL (*varqueryfunc)(BYTE bPduType, SnmpVarBind *pVarBind,
+ AsnInteger32 *pErrorStatus);
+
struct mibImplementation
{
AsnObjectIdentifier name;
void (*init)(void);
+ varqueryfunc query;
};
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[] = {
{ DEFINE_OID(mib2IfNumber), mib2IfNumberInit },
};
+static UINT minSupportedIDLength;
BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference,
HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion)
@@ -85,14 +91,47 @@ BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference,
TRACE("(%d, %p, %p)\n", dwUptimeReference, phSubagentTrapEvent,
pFirstSupportedRegion);
+ minSupportedIDLength = UINT_MAX;
for (i = 0; i < sizeof(supportedIDs) / sizeof(supportedIDs[0]); i++)
+ {
if (supportedIDs[i].init)
supportedIDs[i].init();
+ if (supportedIDs[i].name.idLength < minSupportedIDLength)
+ minSupportedIDLength = supportedIDs[i].name.idLength;
+ }
*phSubagentTrapEvent = NULL;
SnmpUtilOidCpy(pFirstSupportedRegion, &myOid);
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,
AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex)
{
@@ -109,8 +148,52 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
if (!SnmpUtilOidNCmp(&pVarBindList->list[i].name, &mib2oid,
mib2oid.idLength))
{
- FIXME("%s: stub\n", SnmpUtilOidToA(&pVarBindList->list[i].name));
- error = SNMP_ERRORSTATUS_NOSUCHNAME;
+ struct mibImplementation *impl = NULL;
+ 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;
diff --git a/dlls/inetmib1/tests/main.c b/dlls/inetmib1/tests/main.c
index 8667995..6e4627e 100644
--- a/dlls/inetmib1/tests/main.c
+++ b/dlls/inetmib1/tests/main.c
@@ -117,7 +117,6 @@ static void testQuery(void)
ok(error == SNMP_ERRORSTATUS_NOSUCHNAME,
"expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error);
/* The index is 1-based rather than 0-based */
- todo_wine
ok(index == 1, "expected index 1, got %d\n", index);
/* Even though SnmpExtensionInit says this DLL supports the MIB2 system
@@ -133,13 +132,13 @@ static void testQuery(void)
moreData = TRUE;
ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
- todo_wine
+ todo_wine {
ok(error == SNMP_ERRORSTATUS_NOERROR,
"expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
ok(index == 0, "expected index 0, got %d\n", index);
+ }
vars[0].name.idLength = sizeof(mib2If) / sizeof(mib2If[0]);
vars[0].name.ids = mib2If;
- todo_wine
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]);
More information about the wine-cvs
mailing list