Author: dchapyshev Date: Fri Jun 27 12:08:01 2008 New Revision: 34130
URL: http://svn.reactos.org/svn/reactos?rev=34130&view=rev Log: - Add inetmib1.dll from Wine - Small update snmpapi.def
Added: trunk/reactos/dll/win32/inetmib1/ trunk/reactos/dll/win32/inetmib1/inetmib1.rbuild (with props) trunk/reactos/dll/win32/inetmib1/inetmib1.spec (with props) trunk/reactos/dll/win32/inetmib1/main.c (with props) Modified: trunk/reactos/dll/win32/snmpapi/snmpapi.def trunk/reactos/dll/win32/win32.rbuild
Added: trunk/reactos/dll/win32/inetmib1/inetmib1.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/inetmib1/inetmib1... ============================================================================== --- trunk/reactos/dll/win32/inetmib1/inetmib1.rbuild (added) +++ trunk/reactos/dll/win32/inetmib1/inetmib1.rbuild [iso-8859-1] Fri Jun 27 12:08:01 2008 @@ -1,0 +1,17 @@ +<module name="inetmib1" type="win32dll" baseaddress="${BASEADDRESS_INETMIB1}" installbase="system32" installname="inetmib1.dll" allowwarnings="true" entrypoint="0"> + <importlibrary definition="inetmib1.spec.def" /> + <include base="inetmib1">.</include> + <include base="ReactOS">include/reactos/wine</include> + <define name="__WINESRC__" /> + <define name="__USE_W32API" /> + <define name="_WIN32_IE">0x600</define> + <define name="_WIN32_WINNT">0x501</define> + <define name="WINVER">0x501</define> + <library>wine</library> + <library>snmpapi</library> + <library>kernel32</library> + <library>iphlpapi</library> + <library>ntdll</library> + <file>main.c</file> + <file>inetmib1.spec</file> +</module>
Propchange: trunk/reactos/dll/win32/inetmib1/inetmib1.rbuild ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/dll/win32/inetmib1/inetmib1.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/inetmib1/inetmib1... ============================================================================== --- trunk/reactos/dll/win32/inetmib1/inetmib1.spec (added) +++ trunk/reactos/dll/win32/inetmib1/inetmib1.spec [iso-8859-1] Fri Jun 27 12:08:01 2008 @@ -1,0 +1,4 @@ +@ stdcall SnmpExtensionInit(long ptr ptr) +@ stub SnmpExtensionInitEx +@ stdcall SnmpExtensionQuery(long ptr ptr ptr) +@ stub SnmpExtensionTrap
Propchange: trunk/reactos/dll/win32/inetmib1/inetmib1.spec ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/dll/win32/inetmib1/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/inetmib1/main.c?r... ============================================================================== --- trunk/reactos/dll/win32/inetmib1/main.c (added) +++ trunk/reactos/dll/win32/inetmib1/main.c [iso-8859-1] Fri Jun 27 12:08:01 2008 @@ -1,0 +1,1171 @@ +/* + * Copyright 2008 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> +#include <limits.h> +#include "windef.h" +#include "winbase.h" +#include "snmp.h" +#include "iphlpapi.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(inetmib1); + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + + switch (fdwReason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + case DLL_PROCESS_DETACH: + break; + default: + break; + } + + return TRUE; +} + +/** + * Utility functions + */ +static void copyInt(AsnAny *value, void *src) +{ + value->asnType = ASN_INTEGER; + value->asnValue.number = *(DWORD *)src; +} + +static void setStringValue(AsnAny *value, BYTE type, DWORD len, BYTE *str) +{ + AsnAny strValue; + + strValue.asnType = type; + strValue.asnValue.string.stream = str; + strValue.asnValue.string.length = len; + strValue.asnValue.string.dynamic = TRUE; + SnmpUtilAsnAnyCpy(value, &strValue); +} + +static void copyLengthPrecededString(AsnAny *value, void *src) +{ + DWORD len = *(DWORD *)src; + + setStringValue(value, ASN_OCTETSTRING, len, (BYTE *)src + sizeof(DWORD)); +} + +typedef void (*copyValueFunc)(AsnAny *value, void *src); + +struct structToAsnValue +{ + size_t offset; + copyValueFunc copy; +}; + +static AsnInteger32 mapStructEntryToValue(struct structToAsnValue *map, + UINT mapLen, void *record, UINT id, BYTE bPduType, SnmpVarBind *pVarBind) +{ + /* OIDs are 1-based */ + if (!id) + return SNMP_ERRORSTATUS_NOSUCHNAME; + --id; + if (id >= mapLen) + return SNMP_ERRORSTATUS_NOSUCHNAME; + if (!map[id].copy) + return SNMP_ERRORSTATUS_NOSUCHNAME; + map[id].copy(&pVarBind->value, (BYTE *)record + map[id].offset); + 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 }; + +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 }; +static PMIB_IFTABLE ifTable; + +static void mib2IfNumberInit(void) +{ + DWORD size = 0, ret = GetIfTable(NULL, &size, FALSE); + + if (ret == ERROR_INSUFFICIENT_BUFFER) + { + ifTable = HeapAlloc(GetProcessHeap(), 0, size); + if (ifTable) + GetIfTable(ifTable, &size, FALSE); + } +} + +static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier numberOid = DEFINE_OID(mib2IfNumber); + + TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), + pErrorStatus); + + switch (bPduType) + { + case SNMP_PDU_GET: + case SNMP_PDU_GETNEXT: + if ((bPduType == SNMP_PDU_GET && + !SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength)) + || SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength) + < 0) + { + DWORD numIfs = ifTable ? ifTable->dwNumEntries : 0; + + copyInt(&pVarBind->value, &numIfs); + if (bPduType == SNMP_PDU_GETNEXT) + SnmpUtilOidCpy(&pVarBind->name, &numberOid); + *pErrorStatus = SNMP_ERRORSTATUS_NOERROR; + } + else + { + *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; + /* Caller deals with OID if bPduType == SNMP_PDU_GETNEXT, so don't + * need to set it here. + */ + } + 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 void copyOperStatus(AsnAny *value, void *src) +{ + value->asnType = ASN_INTEGER; + /* The IPHlpApi definition of operational status differs from the MIB2 one, + * so map it to the MIB2 value. + */ + switch (*(DWORD *)src) + { + case MIB_IF_OPER_STATUS_OPERATIONAL: + value->asnValue.number = MIB_IF_ADMIN_STATUS_UP; + break; + case MIB_IF_OPER_STATUS_CONNECTING: + case MIB_IF_OPER_STATUS_CONNECTED: + value->asnValue.number = MIB_IF_ADMIN_STATUS_TESTING; + break; + default: + value->asnValue.number = MIB_IF_ADMIN_STATUS_DOWN; + }; +} + +/* Given an OID and a base OID that it must begin with, finds the item and + * integer instance from the OID. E.g., given an OID foo.1.2 and a base OID + * foo, returns item 1 and instance 2. + * 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 getItemAndIntegerInstanceFromOid(AsnObjectIdentifier *oid, + AsnObjectIdentifier *base, BYTE bPduType, UINT *item, UINT *instance) +{ + AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR; + + switch (bPduType) + { + case SNMP_PDU_GETNEXT: + if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0) + { + *item = 1; + *instance = 1; + } + else if (!SnmpUtilOidNCmp(oid, base, base->idLength)) + { + if (oid->idLength == base->idLength || + oid->idLength == base->idLength + 1) + { + /* Either the table or an item within the table is specified, + * but the instance is not. Get the first instance. + */ + *instance = 1; + if (oid->idLength == base->idLength + 1) + *item = oid->ids[base->idLength]; + else + *item = 1; + } + else + { + *item = oid->ids[base->idLength]; + *instance = oid->ids[base->idLength + 1] + 1; + } + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + break; + default: + if (!SnmpUtilOidNCmp(oid, base, base->idLength)) + { + if (oid->idLength == base->idLength || + oid->idLength == base->idLength + 1) + { + /* Either the table or an item within the table is specified, + * but the instance is not. + */ + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + else + { + *item = oid->ids[base->idLength]; + *instance = oid->ids[base->idLength + 1]; + } + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + return ret; +} + +/* Given an OID and a base OID that it must begin with, finds the item from the + * OID. E.g., given an OID foo.1 and a base OID foo, returns item 1. + * If bPduType is not SNMP_PDU_GETNEXT and the item is missing, returns + * SNMP_ERRORSTATUS_NOSUCHNAME. + * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item, or item + * 1 if the item is missing. + */ +static AsnInteger32 getItemFromOid(AsnObjectIdentifier *oid, + AsnObjectIdentifier *base, BYTE bPduType, UINT *item) +{ + AsnInteger32 ret = SNMP_ERRORSTATUS_NOERROR; + + switch (bPduType) + { + case SNMP_PDU_GETNEXT: + if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0) + *item = 1; + else if (!SnmpUtilOidNCmp(oid, base, base->idLength)) + { + if (oid->idLength == base->idLength) + { + /* The item is missing, assume the first item */ + *item = 1; + } + else + *item = oid->ids[base->idLength] + 1; + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + break; + default: + if (!SnmpUtilOidNCmp(oid, base, base->idLength)) + { + if (oid->idLength == base->idLength) + { + /* The item is missing */ + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + else + { + *item = oid->ids[base->idLength]; + if (!*item) + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + return ret; +} + +struct GenericTable +{ + DWORD numEntries; + BYTE entries[1]; +}; + +static DWORD oidToIpAddr(AsnObjectIdentifier *oid) +{ + assert(oid && oid->idLength >= 4); + /* Map the IDs to an IP address in little-endian order */ + return (BYTE)oid->ids[3] << 24 | (BYTE)oid->ids[2] << 16 | + (BYTE)oid->ids[1] << 8 | (BYTE)oid->ids[0]; +} + +typedef void (*oidToKeyFunc)(AsnObjectIdentifier *oid, void *dst); +typedef int (*compareFunc)(const void *key, const void *value); + +static UINT findValueInTable(AsnObjectIdentifier *oid, + struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey, + compareFunc compare) +{ + UINT index = 0; + void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize); + + if (key) + { + void *value; + + makeKey(oid, key); + value = bsearch(key, table->entries, table->numEntries, tableEntrySize, + compare); + if (value) + index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize + + 1; + HeapFree(GetProcessHeap(), 0, key); + } + 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, oidToKeyFunc makeKey, compareFunc compare, + 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 = findValueInTable(&ipOid, table, tableEntrySize, + makeKey, compare) + 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 = findValueInTable(&ipOid, table, tableEntrySize, + makeKey, compare); + if (!*instance) + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + } + return ret; +} + +static void setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, + UINT item) +{ + UINT id; + AsnObjectIdentifier oid; + + SnmpUtilOidCpy(dst, base); + oid.idLength = 1; + oid.ids = &id; + id = item; + SnmpUtilOidAppend(dst, &oid); +} + +static void setOidWithItemAndIpAddr(AsnObjectIdentifier *dst, + AsnObjectIdentifier *base, UINT item, DWORD addr) +{ + UINT id; + BYTE *ptr; + AsnObjectIdentifier oid; + + setOidWithItem(dst, base, item); + oid.idLength = 1; + oid.ids = &id; + for (ptr = (BYTE *)&addr; ptr < (BYTE *)&addr + sizeof(DWORD); ptr++) + { + id = *ptr; + SnmpUtilOidAppend(dst, &oid); + } +} + +static void setOidWithItemAndInteger(AsnObjectIdentifier *dst, + AsnObjectIdentifier *base, UINT item, UINT instance) +{ + AsnObjectIdentifier oid; + + setOidWithItem(dst, base, item); + oid.idLength = 1; + oid.ids = &instance; + SnmpUtilOidAppend(dst, &oid); +} + +static struct structToAsnValue mib2IfEntryMap[] = { + { FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyLengthPrecededString }, + { FIELD_OFFSET(MIB_IFROW, dwType), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwMtu), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwSpeed), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen), copyLengthPrecededString }, + { FIELD_OFFSET(MIB_IFROW, dwAdminStatus), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwOperStatus), copyOperStatus }, + { FIELD_OFFSET(MIB_IFROW, dwLastChange), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwInOctets), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwInUcastPkts), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwInNUcastPkts), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwInDiscards), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwInErrors), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwInUnknownProtos), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwOutOctets), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwOutUcastPkts), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwOutNUcastPkts), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwOutDiscards), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwOutErrors), copyInt }, + { FIELD_OFFSET(MIB_IFROW, dwOutQLen), copyInt }, +}; + +static UINT mib2IfEntry[] = { 1,3,6,1,2,1,2,2,1 }; + +static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier entryOid = DEFINE_OID(mib2IfEntry); + + TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), + pErrorStatus); + + switch (bPduType) + { + case SNMP_PDU_GET: + case SNMP_PDU_GETNEXT: + if (!ifTable) + { + /* There is no interface present, so let the caller deal + * with finding the successor. + */ + *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; + } + else + { + UINT tableIndex = 0, item = 0; + + *pErrorStatus = getItemAndIntegerInstanceFromOid(&pVarBind->name, + &entryOid, bPduType, &item, &tableIndex); + if (!*pErrorStatus) + { + assert(tableIndex); + assert(item); + if (tableIndex > ifTable->dwNumEntries) + *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; + else + { + *pErrorStatus = mapStructEntryToValue(mib2IfEntryMap, + DEFINE_SIZEOF(mib2IfEntryMap), + &ifTable->table[tableIndex - 1], item, bPduType, + pVarBind); + if (bPduType == SNMP_PDU_GETNEXT) + setOidWithItemAndInteger(&pVarBind->name, &entryOid, + item, tableIndex); + } + } + } + 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 mib2Ip[] = { 1,3,6,1,2,1,4 }; +static MIB_IPSTATS ipStats; + +static void mib2IpStatsInit(void) +{ + GetIpStatistics(&ipStats); +} + +static struct structToAsnValue mib2IpMap[] = { + { FIELD_OFFSET(MIB_IPSTATS, dwForwarding), copyInt }, /* 1 */ + { FIELD_OFFSET(MIB_IPSTATS, dwDefaultTTL), copyInt }, /* 2 */ + { FIELD_OFFSET(MIB_IPSTATS, dwInReceives), copyInt }, /* 3 */ + { FIELD_OFFSET(MIB_IPSTATS, dwInHdrErrors), copyInt }, /* 4 */ + { FIELD_OFFSET(MIB_IPSTATS, dwInAddrErrors), copyInt }, /* 5 */ + { FIELD_OFFSET(MIB_IPSTATS, dwForwDatagrams), copyInt }, /* 6 */ + { FIELD_OFFSET(MIB_IPSTATS, dwInUnknownProtos), copyInt }, /* 7 */ + { FIELD_OFFSET(MIB_IPSTATS, dwInDiscards), copyInt }, /* 8 */ + { FIELD_OFFSET(MIB_IPSTATS, dwInDelivers), copyInt }, /* 9 */ + { FIELD_OFFSET(MIB_IPSTATS, dwOutRequests), copyInt }, /* 10 */ + { FIELD_OFFSET(MIB_IPSTATS, dwOutDiscards), copyInt }, /* 11 */ + { FIELD_OFFSET(MIB_IPSTATS, dwOutNoRoutes), copyInt }, /* 12 */ + { FIELD_OFFSET(MIB_IPSTATS, dwReasmTimeout), copyInt }, /* 13 */ + { FIELD_OFFSET(MIB_IPSTATS, dwReasmReqds), copyInt }, /* 14 */ + { FIELD_OFFSET(MIB_IPSTATS, dwReasmOks), copyInt }, /* 15 */ + { FIELD_OFFSET(MIB_IPSTATS, dwReasmFails), copyInt }, /* 16 */ + { FIELD_OFFSET(MIB_IPSTATS, dwFragOks), copyInt }, /* 17 */ + { FIELD_OFFSET(MIB_IPSTATS, dwFragFails), copyInt }, /* 18 */ + { FIELD_OFFSET(MIB_IPSTATS, dwFragCreates), copyInt }, /* 19 */ + { 0, NULL }, /* 20: not used, IP addr table */ + { 0, NULL }, /* 21: not used, route table */ + { 0, NULL }, /* 22: not used, net to media (ARP) table */ + { FIELD_OFFSET(MIB_IPSTATS, dwRoutingDiscards), copyInt }, /* 23 */ +}; + +static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier myOid = DEFINE_OID(mib2Ip); + UINT item = 0; + + TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), + pErrorStatus); + + switch (bPduType) + { + case SNMP_PDU_GET: + case SNMP_PDU_GETNEXT: + *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType, + &item); + if (!*pErrorStatus) + { + *pErrorStatus = mapStructEntryToValue(mib2IpMap, + DEFINE_SIZEOF(mib2IpMap), &ipStats, item, bPduType, pVarBind); + if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) + setOidWithItem(&pVarBind->name, &myOid, item); + } + 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 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, TRUE); + + if (ret == ERROR_INSUFFICIENT_BUFFER) + { + ipAddrTable = HeapAlloc(GetProcessHeap(), 0, size); + if (ipAddrTable) + GetIpAddrTable(ipAddrTable, &size, TRUE); + } +} + +static void oidToIpAddrRow(AsnObjectIdentifier *oid, void *dst) +{ + MIB_IPADDRROW *row = dst; + + row->dwAddr = oidToIpAddr(oid); +} + +static int compareIpAddrRow(const void *a, const void *b) +{ + const MIB_IPADDRROW *key = a, *value = b; + + return key->dwAddr - value->dwAddr; +} + +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 = getItemAndIpAddressInstanceFromOid(&pVarBind->name, + &myOid, bPduType, (struct GenericTable *)ipAddrTable, + sizeof(MIB_IPADDRROW), oidToIpAddrRow, compareIpAddrRow, &item, + &tableIndex); + 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) + setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item, + ipAddrTable->table[tableIndex - 1].dwAddr); + } + 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 mib2IpRoute[] = { 1,3,6,1,2,1,4,21,1 }; +static PMIB_IPFORWARDTABLE ipRouteTable; + +static struct structToAsnValue mib2IpRouteMap[] = { + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardDest), copyIpAddr }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardIfIndex), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric1), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric2), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric3), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric4), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardNextHop), copyIpAddr }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardType), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardProto), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardAge), copyInt }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMask), copyIpAddr }, + { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric5), copyInt }, +}; + +static void mib2IpRouteInit(void) +{ + DWORD size = 0, ret = GetIpForwardTable(NULL, &size, TRUE); + + if (ret == ERROR_INSUFFICIENT_BUFFER) + { + ipRouteTable = HeapAlloc(GetProcessHeap(), 0, size); + if (ipRouteTable) + GetIpForwardTable(ipRouteTable, &size, TRUE); + } +} + +static void oidToIpForwardRow(AsnObjectIdentifier *oid, void *dst) +{ + MIB_IPFORWARDROW *row = dst; + + row->dwForwardDest = oidToIpAddr(oid); +} + +static int compareIpForwardRow(const void *a, const void *b) +{ + const MIB_IPFORWARDROW *key = a, *value = b; + + return key->dwForwardDest - value->dwForwardDest; +} + +static BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier myOid = DEFINE_OID(mib2IpRoute); + 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 = getItemAndIpAddressInstanceFromOid(&pVarBind->name, + &myOid, bPduType, (struct GenericTable *)ipRouteTable, + sizeof(MIB_IPFORWARDROW), oidToIpForwardRow, compareIpForwardRow, + &item, &tableIndex); + if (!*pErrorStatus) + { + assert(tableIndex); + assert(item); + *pErrorStatus = mapStructEntryToValue(mib2IpRouteMap, + DEFINE_SIZEOF(mib2IpRouteMap), + &ipRouteTable->table[tableIndex - 1], item, bPduType, pVarBind); + if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) + setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item, + ipRouteTable->table[tableIndex - 1].dwForwardDest); + } + 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 mib2IpNet[] = { 1,3,6,1,2,1,4,22,1 }; +static PMIB_IPNETTABLE ipNetTable; + +static struct structToAsnValue mib2IpNetMap[] = { + { FIELD_OFFSET(MIB_IPNETROW, dwIndex), copyInt }, + { FIELD_OFFSET(MIB_IPNETROW, dwPhysAddrLen), copyLengthPrecededString }, + { FIELD_OFFSET(MIB_IPNETROW, dwAddr), copyIpAddr }, + { FIELD_OFFSET(MIB_IPNETROW, dwType), copyInt }, +}; + +static void mib2IpNetInit(void) +{ + DWORD size = 0, ret = GetIpNetTable(NULL, &size, FALSE); + + if (ret == ERROR_INSUFFICIENT_BUFFER) + { + ipNetTable = HeapAlloc(GetProcessHeap(), 0, size); + if (ipNetTable) + GetIpNetTable(ipNetTable, &size, FALSE); + } +} + +static BOOL mib2IpNetQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier myOid = DEFINE_OID(mib2IpNet); + + TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), + pErrorStatus); + + switch (bPduType) + { + case SNMP_PDU_GET: + case SNMP_PDU_GETNEXT: + if (!ipNetTable) + *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; + else + { + UINT tableIndex = 0, item = 0; + + *pErrorStatus = getItemAndIntegerInstanceFromOid(&pVarBind->name, + &myOid, bPduType, &item, &tableIndex); + if (!*pErrorStatus) + { + assert(tableIndex); + assert(item); + if (tableIndex > ipNetTable->dwNumEntries) + *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; + else + { + *pErrorStatus = mapStructEntryToValue(mib2IpNetMap, + DEFINE_SIZEOF(mib2IpNetMap), + &ipNetTable[tableIndex - 1], item, bPduType, pVarBind); + if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) + setOidWithItemAndInteger(&pVarBind->name, &myOid, item, + tableIndex); + } + } + } + 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; + +static void mib2IcmpInit(void) +{ + GetIcmpStatistics(&icmpStats); +} + +static struct structToAsnValue mib2IcmpMap[] = { + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwMsgs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwErrors), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwDestUnreachs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimeExcds), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwParmProbs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwSrcQuenchs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwRedirects), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwEchos), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwEchoReps), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimestamps), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimestampReps), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwAddrMasks), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwAddrMaskReps), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwMsgs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwErrors), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwDestUnreachs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimeExcds), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwParmProbs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwSrcQuenchs), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwRedirects), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwEchos), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwEchoReps), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimestamps), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimestampReps), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwAddrMasks), copyInt }, + { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwAddrMaskReps), copyInt }, +}; + +static BOOL mib2IcmpQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier myOid = DEFINE_OID(mib2Icmp); + UINT item = 0; + + TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), + pErrorStatus); + + switch (bPduType) + { + case SNMP_PDU_GET: + case SNMP_PDU_GETNEXT: + *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType, + &item); + if (!*pErrorStatus) + { + *pErrorStatus = mapStructEntryToValue(mib2IcmpMap, + DEFINE_SIZEOF(mib2IcmpMap), &icmpStats, item, bPduType, + pVarBind); + if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) + setOidWithItem(&pVarBind->name, &myOid, item); + } + 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 mib2Tcp[] = { 1,3,6,1,2,1,6 }; +static MIB_TCPSTATS tcpStats; + +static void mib2TcpInit(void) +{ + GetTcpStatistics(&tcpStats); +} + +static struct structToAsnValue mib2TcpMap[] = { + { FIELD_OFFSET(MIB_TCPSTATS, dwRtoAlgorithm), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwRtoMin), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwRtoMax), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwMaxConn), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwActiveOpens), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwPassiveOpens), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwAttemptFails), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwEstabResets), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwCurrEstab), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwInSegs), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwOutSegs), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwRetransSegs), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwInErrs), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwOutRsts), copyInt }, + { FIELD_OFFSET(MIB_TCPSTATS, dwNumConns), copyInt }, +}; + +static BOOL mib2TcpQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier myOid = DEFINE_OID(mib2Tcp); + UINT item = 0; + + TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), + pErrorStatus); + + switch (bPduType) + { + case SNMP_PDU_GET: + case SNMP_PDU_GETNEXT: + *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType, + &item); + if (!*pErrorStatus) + { + *pErrorStatus = mapStructEntryToValue(mib2TcpMap, + DEFINE_SIZEOF(mib2TcpMap), &tcpStats, item, bPduType, pVarBind); + if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) + setOidWithItem(&pVarBind->name, &myOid, item); + } + 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 mib2Udp[] = { 1,3,6,1,2,1,7 }; +static MIB_UDPSTATS udpStats; + +static void mib2UdpInit(void) +{ + GetUdpStatistics(&udpStats); +} + +static struct structToAsnValue mib2UdpMap[] = { + { FIELD_OFFSET(MIB_UDPSTATS, dwInDatagrams), copyInt }, + { FIELD_OFFSET(MIB_UDPSTATS, dwNoPorts), copyInt }, + { FIELD_OFFSET(MIB_UDPSTATS, dwInErrors), copyInt }, + { FIELD_OFFSET(MIB_UDPSTATS, dwOutDatagrams), copyInt }, +}; + +static BOOL mib2UdpQuery(BYTE bPduType, SnmpVarBind *pVarBind, + AsnInteger32 *pErrorStatus) +{ + AsnObjectIdentifier myOid = DEFINE_OID(mib2Udp); + UINT item; + + TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), + pErrorStatus); + + switch (bPduType) + { + case SNMP_PDU_GET: + case SNMP_PDU_GETNEXT: + *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType, + &item); + if (!*pErrorStatus) + { + *pErrorStatus = mapStructEntryToValue(mib2UdpMap, + DEFINE_SIZEOF(mib2UdpMap), &udpStats, item, bPduType, pVarBind); + if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) + setOidWithItem(&pVarBind->name, &myOid, item); + } + 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 }, + { DEFINE_OID(mib2IfEntry), NULL, mib2IfEntryQuery }, + { DEFINE_OID(mib2Ip), mib2IpStatsInit, mib2IpStatsQuery }, + { DEFINE_OID(mib2IpAddr), mib2IpAddrInit, mib2IpAddrQuery }, + { DEFINE_OID(mib2IpRoute), mib2IpRouteInit, mib2IpRouteQuery }, + { DEFINE_OID(mib2IpNet), mib2IpNetInit, mib2IpNetQuery }, + { DEFINE_OID(mib2Icmp), mib2IcmpInit, mib2IcmpQuery }, + { DEFINE_OID(mib2Tcp), mib2TcpInit, mib2TcpQuery }, + { DEFINE_OID(mib2Udp), mib2UdpInit, mib2UdpQuery }, +}; +static UINT minSupportedIDLength; + +BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference, + HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion) +{ + AsnObjectIdentifier myOid = DEFINE_OID(mib2System); + UINT i; + + 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) +{ + AsnObjectIdentifier mib2oid = DEFINE_OID(mib2); + AsnInteger32 error = SNMP_ERRORSTATUS_NOERROR, errorIndex = 0; + UINT i; + + TRACE("(0x%02x, %p, %p, %p)\n", bPduType, pVarBindList, + pErrorStatus, pErrorIndex); + + for (i = 0; !error && i < pVarBindList->len; i++) + { + /* Ignore any OIDs not in MIB2 */ + if (!SnmpUtilOidNCmp(&pVarBindList->list[i].name, &mib2oid, + mib2oid.idLength)) + { + 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; + *pErrorIndex = errorIndex; + return TRUE; +}
Propchange: trunk/reactos/dll/win32/inetmib1/main.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/win32/snmpapi/snmpapi.def URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/snmpapi/snmpapi.d... ============================================================================== --- trunk/reactos/dll/win32/snmpapi/snmpapi.def [iso-8859-1] (original) +++ trunk/reactos/dll/win32/snmpapi/snmpapi.def [iso-8859-1] Fri Jun 27 12:08:01 2008 @@ -14,7 +14,7 @@ SnmpTfxOpen SnmpTfxQuery SnmpUtilAnsiToUnicode -SnmpUtilAsnAnyCpy +SnmpUtilAsnAnyCpy@8 SnmpUtilAsnAnyFree SnmpUtilDbgPrint SnmpUtilIdsToA @@ -25,12 +25,12 @@ SnmpUtilOctetsCpy SnmpUtilOctetsFree SnmpUtilOctetsNCmp -SnmpUtilOidAppend +SnmpUtilOidAppend@8 SnmpUtilOidCmp -SnmpUtilOidCpy -SnmpUtilOidFree -SnmpUtilOidNCmp -SnmpUtilOidToA +SnmpUtilOidCpy@8 +SnmpUtilOidFree@4 +SnmpUtilOidNCmp@12 +SnmpUtilOidToA@4 SnmpUtilPrintAsnAny SnmpUtilPrintOid SnmpUtilUTF8ToUnicode
Modified: trunk/reactos/dll/win32/win32.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/win32.rbuild?rev=... ============================================================================== --- trunk/reactos/dll/win32/win32.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/win32/win32.rbuild [iso-8859-1] Fri Jun 27 12:08:01 2008 @@ -115,6 +115,9 @@ <directory name="inetcomm"> <xi:include href="inetcomm/inetcomm.rbuild" /> </directory> +<directory name="inetmib1"> + <xi:include href="inetmib1/inetmib1.rbuild" /> +</directory> <directory name="iphlpapi"> <xi:include href="iphlpapi/iphlpapi.rbuild" /> </directory>