static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus) { AsnObjectIdentifier myOid = DEFINE_OID(mib2Ip); UINT item = 0; BOOL ret = TRUE; 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, pVarBind); if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) ret = setOidWithItem(&pVarBind->name, &myOid, item); } break; case SNMP_PDU_SET: *pErrorStatus = SNMP_ERRORSTATUS_READONLY; ret = FALSE; break; default: FIXME("0x%02x: unsupported PDU type\n", bPduType); *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; } return ret; }
static BOOL mib2UdpEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus) { AsnObjectIdentifier myOid = DEFINE_OID(mib2UdpEntry); BOOL ret = TRUE; TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), pErrorStatus); switch (bPduType) { case SNMP_PDU_GET: case SNMP_PDU_GETNEXT: if (!udpTable) *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; else { UINT tableIndex = 0, item = 0; *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name, &myOid, 5, bPduType, (struct GenericTable *)udpTable, sizeof(MIB_UDPROW), oidToUdpRow, compareUdpRow, &item, &tableIndex); if (!*pErrorStatus) { assert(tableIndex); assert(item); *pErrorStatus = mapStructEntryToValue(mib2UdpEntryMap, DEFINE_SIZEOF(mib2UdpEntryMap), &udpTable->table[tableIndex - 1], item, pVarBind); if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) { AsnObjectIdentifier oid; ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item, udpTable->table[tableIndex - 1].dwLocalAddr); if (ret) { oid.idLength = 1; oid.ids = &udpTable->table[tableIndex - 1].dwLocalPort; ret = SnmpUtilOidAppend(&pVarBind->name, &oid); } } } } break; case SNMP_PDU_SET: *pErrorStatus = SNMP_ERRORSTATUS_READONLY; ret = FALSE; break; default: FIXME("0x%02x: unsupported PDU type\n", bPduType); *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; } return ret; }
static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus) { AsnObjectIdentifier entryOid = DEFINE_OID(mib2IfEntry); BOOL ret = TRUE; 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, pVarBind); if (bPduType == SNMP_PDU_GETNEXT) ret = setOidWithItemAndInteger(&pVarBind->name, &entryOid, item, tableIndex); } } } break; case SNMP_PDU_SET: *pErrorStatus = SNMP_ERRORSTATUS_READONLY; ret = FALSE; break; default: FIXME("0x%02x: unsupported PDU type\n", bPduType); *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; } return ret; }
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 BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus) { AsnObjectIdentifier numberOid = DEFINE_OID(mib2IfNumber); BOOL ret = TRUE; 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) { SnmpUtilOidFree(&pVarBind->name); 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; ret = FALSE; break; default: FIXME("0x%02x: unsupported PDU type\n", bPduType); *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; } return ret; }
/***************************************************************************** * SnmpExtensionInit [INETMIB1.@] */ 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 BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus) { AsnObjectIdentifier myOid = DEFINE_OID(mib2IpRoute); UINT tableIndex = 0, item = 0; BOOL ret = TRUE; TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name), pErrorStatus); switch (bPduType) { case SNMP_PDU_GET: case SNMP_PDU_GETNEXT: *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name, &myOid, 4, 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, pVarBind); if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT) ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item, ipRouteTable->table[tableIndex - 1].dwForwardDest); } break; case SNMP_PDU_SET: *pErrorStatus = SNMP_ERRORSTATUS_READONLY; ret = FALSE; break; default: FIXME("0x%02x: unsupported PDU type\n", bPduType); *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; } return ret; }
/***************************************************************************** * SnmpExtensionQuery [INETMIB1.@] */ 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; BOOL ret = TRUE; 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) ret = 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 (matchingIndex++; error == SNMP_ERRORSTATUS_NOSUCHNAME && matchingIndex < DEFINE_SIZEOF(supportedIDs); matchingIndex++) { error = SNMP_ERRORSTATUS_NOERROR; impl = &supportedIDs[matchingIndex]; if (impl->query) ret = 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); ret = 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 ret; }
} break; case SNMP_PDU_SET: *pErrorStatus = SNMP_ERRORSTATUS_READONLY; ret = FALSE; break; default: FIXME("0x%02x: unsupported PDU type\n", bPduType); *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME; } return ret; } /* This list MUST BE lexicographically sorted */ static struct mibImplementation supportedIDs[] = { { DEFINE_OID(mib2IfNumber), mib2IfNumberInit, mib2IfNumberQuery, mib2IfNumberCleanup }, { DEFINE_OID(mib2IfEntry), NULL, mib2IfEntryQuery, NULL }, { DEFINE_OID(mib2Ip), mib2IpStatsInit, mib2IpStatsQuery, NULL }, { DEFINE_OID(mib2IpAddr), mib2IpAddrInit, mib2IpAddrQuery, mib2IpAddrCleanup }, { DEFINE_OID(mib2IpRoute), mib2IpRouteInit, mib2IpRouteQuery, mib2IpRouteCleanup }, { DEFINE_OID(mib2IpNet), mib2IpNetInit, mib2IpNetQuery, mib2IpNetCleanup }, { DEFINE_OID(mib2Icmp), mib2IcmpInit, mib2IcmpQuery, NULL }, { DEFINE_OID(mib2Tcp), mib2TcpInit, mib2TcpQuery, NULL }, { DEFINE_OID(mib2Udp), mib2UdpInit, mib2UdpQuery, NULL }, { DEFINE_OID(mib2UdpEntry), mib2UdpEntryInit, mib2UdpEntryQuery, mib2UdpEntryCleanup }, }; static UINT minSupportedIDLength;