| /* | |
| * 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 <stdio.h> | |
| #include <stdarg.h> | |
| #include <windef.h> | |
| #include <winbase.h> | |
| #include <snmp.h> | |
| #include "wine/test.h" | |
| static BOOL (WINAPI *pSnmpExtensionInit)(DWORD, HANDLE*, AsnObjectIdentifier*); | |
| static BOOL (WINAPI *pSnmpExtensionQuery)(BYTE, SnmpVarBindList*, AsnInteger32*, AsnInteger32*); | |
| static HMODULE init_test_functions(void) | |
| { | |
| HMODULE mod = LoadLibraryA("inetmib1"); | |
| ok(mod != NULL, "failed to load inetmib1.dll\n"); | |
| if (!mod) return NULL; | |
| pSnmpExtensionInit = (void *)GetProcAddress(mod, "SnmpExtensionInit"); | |
| pSnmpExtensionQuery = (void *)GetProcAddress(mod, "SnmpExtensionQuery"); | |
| return mod; | |
| } | |
| static void uninit_test_functions(HMODULE mod) | |
| { | |
| FreeLibrary(mod); | |
| } | |
| static void testInit(void) | |
| { | |
| BOOL ret; | |
| HANDLE event; | |
| AsnObjectIdentifier oid; | |
| if (!pSnmpExtensionInit) | |
| { | |
| win_skip("no SnmpExtensionInit\n"); | |
| return; | |
| } | |
| if (0) /* crashes on native */ | |
| { | |
| ret = pSnmpExtensionInit(0, NULL, NULL); | |
| ret = pSnmpExtensionInit(0, NULL, &oid); | |
| ret = pSnmpExtensionInit(0, &event, NULL); | |
| } | |
| ret = pSnmpExtensionInit(0, &event, &oid); | |
| ok(ret, "SnmpExtensionInit failed: %d\n", GetLastError()); | |
| ok(!strcmp("1.3.6.1.2.1.1", SnmpUtilOidToA(&oid)), | |
| "Expected 1.3.6.1.2.1.1, got %s\n", SnmpUtilOidToA(&oid)); | |
| if (0) | |
| { | |
| /* Fails when called on win8, documentation suggests that | |
| extension itself is responsible for freeing this oid */ | |
| SnmpUtilOidFree(&oid); | |
| } | |
| } | |
| static void testQuery(void) | |
| { | |
| BOOL ret, moreData, noChange; | |
| SnmpVarBindList list; | |
| AsnInteger32 error, index; | |
| UINT bogus[] = { 1,2,3,4 }; | |
| UINT mib2System[] = { 1,3,6,1,2,1,1 }; | |
| UINT mib2If[] = { 1,3,6,1,2,1,2 }; | |
| UINT mib2IfTable[] = { 1,3,6,1,2,1,2,2 }; | |
| UINT mib2IfDescr[] = { 1,3,6,1,2,1,2,2,1,2 }; | |
| UINT mib2IfAdminStatus[] = { 1,3,6,1,2,1,2,2,1,7 }; | |
| UINT mib2IfOperStatus[] = { 1,3,6,1,2,1,2,2,1,8 }; | |
| UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1,1 }; | |
| UINT mib2IpRouteTable[] = { 1,3,6,1,2,1,4,21,1,1 }; | |
| UINT mib2UdpTable[] = { 1,3,6,1,2,1,7,5,1,1 }; | |
| SnmpVarBind vars[3], vars2[3], vars3[3]; | |
| UINT entry; | |
| if (!pSnmpExtensionQuery) | |
| { | |
| win_skip("couldn't find SnmpExtensionQuery\n"); | |
| return; | |
| } | |
| if (0) /* crashes on native */ | |
| { | |
| ret = pSnmpExtensionQuery(0, NULL, NULL, NULL); | |
| ret = pSnmpExtensionQuery(0, NULL, &error, NULL); | |
| ret = pSnmpExtensionQuery(0, NULL, NULL, &index); | |
| ret = pSnmpExtensionQuery(0, &list, NULL, NULL); | |
| ret = pSnmpExtensionQuery(0, &list, &error, NULL); | |
| } | |
| /* An empty list succeeds */ | |
| list.len = 0; | |
| error = 0xdeadbeef; | |
| index = 0xdeadbeef; | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GET, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOERROR, | |
| "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); | |
| ok(index == 0, "expected index 0, got %d\n", index); | |
| /* Oddly enough, this "succeeds," even though the OID is clearly | |
| * unsupported. | |
| */ | |
| vars[0].name.idLength = sizeof(bogus) / sizeof(bogus[0]); | |
| vars[0].name.ids = bogus; | |
| vars[0].value.asnType = 0; | |
| list.len = 1; | |
| list.list = vars; | |
| SetLastError(0xdeadbeef); | |
| error = 0xdeadbeef; | |
| index = 0xdeadbeef; | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GET, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOERROR || | |
| broken(error == ERROR_FILE_NOT_FOUND) /* NT4 */, | |
| "expected SNMP_ERRORSTATUS_NOERROR or ERROR_FILE_NOT_FOUND, got %d\n", | |
| error); | |
| if (error == SNMP_ERRORSTATUS_NOERROR) | |
| ok(index == 0, "expected index 0, got %d\n", index); | |
| else if (error == ERROR_FILE_NOT_FOUND) | |
| ok(index == 1, "expected index 1, got %d\n", index); | |
| /* The OID isn't changed either: */ | |
| ok(!strcmp("1.2.3.4", SnmpUtilOidToA(&vars[0].name)), | |
| "expected 1.2.3.4, got %s\n", SnmpUtilOidToA(&vars[0].name)); | |
| /* The table is not an accessible variable, so it fails */ | |
| vars[0].name.idLength = sizeof(mib2IfTable) / sizeof(mib2IfTable[0]); | |
| vars[0].name.ids = mib2IfTable; | |
| SetLastError(0xdeadbeef); | |
| error = 0xdeadbeef; | |
| index = 0xdeadbeef; | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GET, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOSUCHNAME, | |
| "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error); | |
| /* The index is 1-based rather than 0-based */ | |
| ok(index == 1, "expected index 1, got %d\n", index); | |
| /* A Get fails on something that specifies a table (but not a particular | |
| * entry in it)... | |
| */ | |
| vars[0].name.idLength = sizeof(mib2IfDescr) / sizeof(mib2IfDescr[0]); | |
| vars[0].name.ids = mib2IfDescr; | |
| vars[1].name.idLength = | |
| sizeof(mib2IfAdminStatus) / sizeof(mib2IfAdminStatus[0]); | |
| vars[1].name.ids = mib2IfAdminStatus; | |
| vars[2].name.idLength = | |
| sizeof(mib2IfOperStatus) / sizeof(mib2IfOperStatus[0]); | |
| vars[2].name.ids = mib2IfOperStatus; | |
| list.len = 3; | |
| SetLastError(0xdeadbeef); | |
| error = 0xdeadbeef; | |
| index = 0xdeadbeef; | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GET, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOSUCHNAME, | |
| "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error); | |
| ok(index == 1, "expected index 1, got %d\n", index); | |
| /* but a GetNext succeeds with the same values, because GetNext gets the | |
| * entry after the specified OID, not the entry specified by it. The | |
| * successor to the table is the first entry in the table. | |
| * The OIDs need to be allocated, because GetNext modifies them to indicate | |
| * the end of data. | |
| */ | |
| SnmpUtilOidCpy(&vars2[0].name, &vars[0].name); | |
| SnmpUtilOidCpy(&vars2[1].name, &vars[1].name); | |
| SnmpUtilOidCpy(&vars2[2].name, &vars[2].name); | |
| list.list = vars2; | |
| moreData = TRUE; | |
| noChange = FALSE; | |
| entry = 0; | |
| do { | |
| SetLastError(0xdeadbeef); | |
| error = 0xdeadbeef; | |
| index = 0xdeadbeef; | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GETNEXT, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOERROR, | |
| "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); | |
| ok(index == 0, "expected index 0, got %d\n", index); | |
| if (!ret) | |
| moreData = FALSE; | |
| else if (error) | |
| moreData = FALSE; | |
| else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, | |
| vars[0].name.idLength)) | |
| moreData = FALSE; | |
| else if (SnmpUtilOidNCmp(&vars2[1].name, &vars[1].name, | |
| vars[1].name.idLength)) | |
| moreData = FALSE; | |
| else if (SnmpUtilOidNCmp(&vars2[2].name, &vars[2].name, | |
| vars[2].name.idLength)) | |
| moreData = FALSE; | |
| else if (!SnmpUtilOidCmp(&vars[0].name, &vars2[0].name) || | |
| !SnmpUtilOidCmp(&vars[1].name, &vars2[1].name) || | |
| !SnmpUtilOidCmp(&vars[2].name, &vars2[2].name)) | |
| { | |
| /* If the OID isn't modified, the function isn't implemented on this | |
| * platform, skip the remaining tests. | |
| */ | |
| noChange = TRUE; | |
| } | |
| if (moreData) | |
| { | |
| UINT lastID; | |
| /* Check the OIDs. For these types of values (display strings and | |
| * integers) they should increase by 1 for each element of the table | |
| * according to RFC 1158. Windows sometimes has a weird value in the | |
| * table, so allow any value as long as it's greater than the previous | |
| * value on Windows. | |
| */ | |
| ok(vars2[0].name.idLength == vars[0].name.idLength + 1, | |
| "expected length %d, got %d\n", vars[0].name.idLength + 1, | |
| vars2[0].name.idLength); | |
| lastID = vars2[0].name.ids[vars2[0].name.idLength - 1]; | |
| ok(lastID == entry + 1 || broken(lastID > entry), | |
| "expected %d, got %d\n", entry + 1, lastID); | |
| ok(vars2[1].name.idLength == vars[1].name.idLength + 1, | |
| "expected length %d, got %d\n", vars[1].name.idLength + 1, | |
| vars2[1].name.idLength); | |
| lastID = vars2[1].name.ids[vars2[1].name.idLength - 1]; | |
| ok(lastID == entry + 1 || broken(lastID > entry), | |
| "expected %d, got %d\n", entry + 1, lastID); | |
| ok(vars2[2].name.idLength == vars[2].name.idLength + 1, | |
| "expected length %d, got %d\n", vars[2].name.idLength + 1, | |
| vars2[2].name.idLength); | |
| lastID = vars2[2].name.ids[vars2[2].name.idLength - 1]; | |
| ok(lastID == entry + 1 || broken(lastID > entry), | |
| "expected %d, got %d\n", entry + 1, lastID); | |
| entry = lastID; | |
| /* Check the types while we're at it */ | |
| ok(vars2[0].value.asnType == ASN_OCTETSTRING, | |
| "expected ASN_OCTETSTRING, got %02x\n", vars2[0].value.asnType); | |
| ok(vars2[1].value.asnType == ASN_INTEGER, | |
| "expected ASN_INTEGER, got %02x\n", vars2[1].value.asnType); | |
| ok(vars2[2].value.asnType == ASN_INTEGER, | |
| "expected ASN_INTEGER, got %02x\n", vars2[2].value.asnType); | |
| } | |
| else if (noChange) | |
| skip("no change in OID, no MIB2 IF table implementation\n"); | |
| } while (moreData && !noChange); | |
| SnmpUtilVarBindFree(&vars2[0]); | |
| SnmpUtilVarBindFree(&vars2[1]); | |
| SnmpUtilVarBindFree(&vars2[2]); | |
| /* Even though SnmpExtensionInit says this DLL supports the MIB2 system | |
| * variables, on recent systems (at least Win2k) the first variable it | |
| * returns a value for is the first interface. | |
| */ | |
| vars[0].name.idLength = sizeof(mib2System) / sizeof(mib2System[0]); | |
| vars[0].name.ids = mib2System; | |
| SnmpUtilOidCpy(&vars2[0].name, &vars[0].name); | |
| vars2[0].value.asnType = 0; | |
| list.len = 1; | |
| list.list = vars2; | |
| noChange = FALSE; | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GETNEXT, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOERROR, | |
| "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); | |
| ok(index == 0, "expected index 0, got %d\n", index); | |
| vars3[0].name.idLength = sizeof(mib2If) / sizeof(mib2If[0]); | |
| vars3[0].name.ids = mib2If; | |
| ok(!SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, vars[0].name.idLength) || | |
| !SnmpUtilOidNCmp(&vars2[0].name, &vars3[0].name, vars3[0].name.idLength), | |
| "expected 1.3.6.1.2.1.1 or 1.3.6.1.2.1.2, got %s\n", | |
| SnmpUtilOidToA(&vars2[0].name)); | |
| SnmpUtilVarBindFree(&vars2[0]); | |
| /* Check the type and OIDs of the IP address table */ | |
| vars[0].name.idLength = sizeof(mib2IpAddr) / sizeof(mib2IpAddr[0]); | |
| vars[0].name.ids = mib2IpAddr; | |
| SnmpUtilOidCpy(&vars2[0].name, &vars[0].name); | |
| vars2[0].value.asnType = 0; | |
| list.len = 1; | |
| list.list = vars2; | |
| moreData = TRUE; | |
| do { | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GETNEXT, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOERROR, | |
| "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); | |
| ok(index == 0, "expected index 0, got %d\n", index); | |
| if (!ret) | |
| moreData = FALSE; | |
| else if (error) | |
| moreData = FALSE; | |
| else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, | |
| vars[0].name.idLength)) | |
| moreData = FALSE; | |
| else if (!SnmpUtilOidCmp(&vars2[0].name, &vars[0].name)) | |
| { | |
| /* If the OID isn't modified, the function isn't implemented on this | |
| * platform, skip the remaining tests. | |
| */ | |
| noChange = TRUE; | |
| } | |
| if (moreData) | |
| { | |
| /* Make sure the size of the OID is right. | |
| * FIXME: don't know if IPv6 addrs are shared with this table. | |
| * Don't think so, but I'm not certain. | |
| */ | |
| ok(vars2[0].name.idLength == vars[0].name.idLength + 4, | |
| "expected length %d, got %d\n", vars[0].name.idLength + 4, | |
| vars2[0].name.idLength); | |
| /* Make sure the type is right */ | |
| ok(vars2[0].value.asnType == ASN_IPADDRESS, | |
| "expected type ASN_IPADDRESS, got %02x\n", | |
| vars2[0].value.asnType); | |
| if (vars2[0].value.asnType == ASN_IPADDRESS) | |
| { | |
| UINT i; | |
| /* This looks uglier than it is: the base OID for the IP | |
| * address, 1.3.6.1.2.1.4.20.1.1, is appended with the IP | |
| * address of the entry. So e.g. the loopback address is | |
| * identified in MIB2 as 1.3.6.1.2.1.4.20.1.1.127.0.0.1 | |
| */ | |
| for (i = 0; i < vars2[0].value.asnValue.address.length; i++) | |
| { | |
| ok(vars2[0].value.asnValue.address.stream[i] == | |
| vars2[0].name.ids[vars2[0].name.idLength - 4 + i], | |
| "expected ident byte %d to be %d, got %d\n", i, | |
| vars2[0].value.asnValue.address.stream[i], | |
| vars2[0].name.ids[vars2[0].name.idLength - 4 + i]); | |
| } | |
| } | |
| } | |
| else if (noChange) | |
| skip("no change in OID, no MIB2 IP address table implementation\n"); | |
| } while (moreData && !noChange); | |
| SnmpUtilVarBindFree(&vars2[0]); | |
| /* Check the type and OIDs of the IP route table */ | |
| vars[0].name.idLength = DEFINE_SIZEOF(mib2IpRouteTable); | |
| vars[0].name.ids = mib2IpRouteTable; | |
| SnmpUtilOidCpy(&vars2[0].name, &vars[0].name); | |
| vars2[0].value.asnType = 0; | |
| list.len = 1; | |
| list.list = vars2; | |
| moreData = TRUE; | |
| noChange = FALSE; | |
| do { | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GETNEXT, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| ok(error == SNMP_ERRORSTATUS_NOERROR, | |
| "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); | |
| ok(index == 0, "expected index 0, got %d\n", index); | |
| if (!ret) | |
| moreData = FALSE; | |
| else if (error) | |
| moreData = FALSE; | |
| else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, | |
| vars[0].name.idLength)) | |
| moreData = FALSE; | |
| else if (!SnmpUtilOidCmp(&vars2[0].name, &vars[0].name)) | |
| { | |
| /* If the OID isn't modified, the function isn't implemented on this | |
| * platform, skip the remaining tests. | |
| */ | |
| noChange = TRUE; | |
| } | |
| if (moreData) | |
| { | |
| /* Make sure the size of the OID is right. | |
| * FIXME: don't know if IPv6 addrs are shared with this table. | |
| * Don't think so, but I'm not certain. | |
| */ | |
| ok(vars2[0].name.idLength == vars[0].name.idLength + 4, | |
| "expected length %d, got %d\n", vars[0].name.idLength + 4, | |
| vars2[0].name.idLength); | |
| /* Make sure the type is right */ | |
| ok(vars2[0].value.asnType == ASN_IPADDRESS, | |
| "expected type ASN_IPADDRESS, got %02x\n", | |
| vars2[0].value.asnType); | |
| if (vars2[0].value.asnType == ASN_IPADDRESS) | |
| { | |
| UINT i; | |
| /* The base OID for the route table, 1.3.6.1.2.1.4.21.1.1, is | |
| * appended with the dest IP address of the entry. So e.g. a | |
| * route entry for 224.0.0.0 is identified in MIB2 as | |
| * 1.3.6.1.2.1.4.21.1.1.224.0.0.0 | |
| */ | |
| for (i = 0; i < vars2[0].value.asnValue.address.length; i++) | |
| { | |
| ok(vars2[0].value.asnValue.address.stream[i] == | |
| vars2[0].name.ids[vars2[0].name.idLength - 4 + i], | |
| "expected ident byte %d to be %d, got %d\n", i, | |
| vars2[0].value.asnValue.address.stream[i], | |
| vars2[0].name.ids[vars2[0].name.idLength - 4 + i]); | |
| } | |
| } | |
| } | |
| else if (noChange) | |
| skip("no change in OID, no MIB2 IP route table implementation\n"); | |
| } while (moreData && !noChange); | |
| SnmpUtilVarBindFree(&vars2[0]); | |
| /* Check the type and OIDs of the UDP table */ | |
| vars[0].name.idLength = DEFINE_SIZEOF(mib2UdpTable); | |
| vars[0].name.ids = mib2UdpTable; | |
| SnmpUtilOidCpy(&vars2[0].name, &vars[0].name); | |
| vars2[0].value.asnType = 0; | |
| list.len = 1; | |
| list.list = vars2; | |
| moreData = TRUE; | |
| noChange = FALSE; | |
| do { | |
| ret = pSnmpExtensionQuery(SNMP_PDU_GETNEXT, &list, &error, &index); | |
| ok(ret, "SnmpExtensionQuery failed: %d, %d\n", error, index); | |
| /* FIXME: error and index aren't checked here because the UDP table is | |
| * the last OID currently supported by Wine, so the last GetNext fails. | |
| * todo_wine is also not effective because it will succeed for all but | |
| * the last GetNext. Remove the if (0) if any later OID is supported | |
| * by Wine. | |
| */ | |
| if (0) { | |
| ok(error == SNMP_ERRORSTATUS_NOERROR, | |
| "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error); | |
| ok(index == 0, "expected index 0, got %d\n", index); | |
| } | |
| if (!ret) | |
| moreData = FALSE; | |
| else if (error) | |
| moreData = FALSE; | |
| else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, | |
| vars[0].name.idLength)) | |
| moreData = FALSE; | |
| else if (!SnmpUtilOidCmp(&vars2[0].name, &vars[0].name)) | |
| { | |
| /* If the OID isn't modified, the function isn't implemented on this | |
| * platform, skip the remaining tests. | |
| */ | |
| noChange = TRUE; | |
| } | |
| if (moreData) | |
| { | |
| /* Make sure the size of the OID is right. */ | |
| ok(vars2[0].name.idLength == vars[0].name.idLength + 5, | |
| "expected length %d, got %d\n", vars[0].name.idLength + 5, | |
| vars2[0].name.idLength); | |
| /* Make sure the type is right */ | |
| ok(vars2[0].value.asnType == ASN_IPADDRESS, | |
| "expected type ASN_IPADDRESS, got %02x\n", | |
| vars2[0].value.asnType); | |
| if (vars2[0].value.asnType == ASN_IPADDRESS) | |
| { | |
| UINT i; | |
| /* Again with the ugly: the base OID for the UDP table, | |
| * 1.3.6.1.2.1.7.5.1, is appended with the local IP address and | |
| * port number of the entry. So e.g. an entry for | |
| * 192.168.1.1:4000 is identified in MIB2 as | |
| * 1.3.6.1.2.1.7.5.1.192.168.1.1.4000 | |
| */ | |
| for (i = 0; i < vars2[0].value.asnValue.address.length; i++) | |
| { | |
| ok(vars2[0].value.asnValue.address.stream[i] == | |
| vars2[0].name.ids[vars2[0].name.idLength - 5 + i], | |
| "expected ident byte %d to be %d, got %d\n", i, | |
| vars2[0].value.asnValue.address.stream[i], | |
| vars2[0].name.ids[vars2[0].name.idLength - 5 + i]); | |
| } | |
| } | |
| } | |
| else if (noChange) | |
| skip("no change in OID, no MIB2 UDP table implementation\n"); | |
| } while (moreData && !noChange); | |
| SnmpUtilVarBindFree(&vars2[0]); | |
| } | |
| START_TEST(main) | |
| { | |
| HMODULE mod; | |
| if (!(mod = init_test_functions())) | |
| return; | |
| testInit(); | |
| testQuery(); | |
| uninit_test_functions(mod); | |
| } |