push 7f8c39dca3a5819e8ef115eebf7abed537de3a22
[wine/hacks.git] / dlls / inetmib1 / tests / main.c
blob012d6d2c45873844a35b2ed3f45c35462afadb88
1 /*
2 * Copyright 2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <windef.h>
21 #include <winbase.h>
22 #include <snmp.h>
24 #include "wine/test.h"
26 static HMODULE inetmib1;
28 static void testInit(void)
30 BOOL (WINAPI *pInit)(DWORD, HANDLE *, AsnObjectIdentifier *);
31 BOOL ret;
32 HANDLE event;
33 AsnObjectIdentifier oid;
35 pInit = (void *)GetProcAddress(inetmib1, "SnmpExtensionInit");
36 if (!pInit)
38 skip("no SnmpExtensionInit\n");
39 return;
41 /* Crash
42 ret = pInit(0, NULL, NULL);
43 ret = pInit(0, NULL, &oid);
44 ret = pInit(0, &event, NULL);
46 ret = pInit(0, &event, &oid);
47 ok(ret, "SnmpExtensionInit failed: %d\n", GetLastError());
48 ok(!strcmp("1.3.6.1.2.1.1", SnmpUtilOidToA(&oid)),
49 "Expected 1.3.6.1.2.1.1, got %s\n", SnmpUtilOidToA(&oid));
52 static void testQuery(void)
54 BOOL (WINAPI *pQuery)(BYTE, SnmpVarBindList *, AsnInteger32 *,
55 AsnInteger32 *);
56 BOOL ret, moreData;
57 SnmpVarBindList list;
58 AsnInteger32 error, index;
59 UINT bogus[] = { 1,2,3,4 };
60 UINT mib2System[] = { 1,3,6,1,2,1,1 };
61 UINT mib2If[] = { 1,3,6,1,2,1,2 };
62 UINT mib2IfTable[] = { 1,3,6,1,2,1,2,2 };
63 UINT mib2IfDescr[] = { 1,3,6,1,2,1,2,2,1,2 };
64 UINT mib2IfAdminStatus[] = { 1,3,6,1,2,1,2,2,1,7 };
65 UINT mib2IfOperStatus[] = { 1,3,6,1,2,1,2,2,1,8 };
66 UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1,1 };
67 UINT mib2IpRouteTable[] = { 1,3,6,1,2,1,4,21,1,1 };
68 SnmpVarBind vars[3], vars2[3];
69 UINT entry;
71 pQuery = (void *)GetProcAddress(inetmib1, "SnmpExtensionQuery");
72 if (!pQuery)
74 skip("couldn't find SnmpExtensionQuery\n");
75 return;
77 /* Crash
78 ret = pQuery(0, NULL, NULL, NULL);
79 ret = pQuery(0, NULL, &error, NULL);
80 ret = pQuery(0, NULL, NULL, &index);
81 ret = pQuery(0, &list, NULL, NULL);
82 ret = pQuery(0, &list, &error, NULL);
85 /* An empty list succeeds */
86 list.len = 0;
87 error = 0xdeadbeef;
88 index = 0xdeadbeef;
89 ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
90 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
91 ok(error == SNMP_ERRORSTATUS_NOERROR,
92 "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
93 ok(index == 0, "expected index 0, got %d\n", index);
95 /* Oddly enough, this "succeeds," even though the OID is clearly
96 * unsupported.
98 vars[0].name.idLength = sizeof(bogus) / sizeof(bogus[0]);
99 vars[0].name.ids = bogus;
100 vars[0].value.asnType = 0;
101 list.len = 1;
102 list.list = vars;
103 SetLastError(0xdeadbeef);
104 error = 0xdeadbeef;
105 index = 0xdeadbeef;
106 ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
107 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
108 ok(error == SNMP_ERRORSTATUS_NOERROR,
109 "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
110 ok(index == 0, "expected index 0, got %d\n", index);
111 /* The OID isn't changed either: */
112 ok(!strcmp("1.2.3.4", SnmpUtilOidToA(&vars[0].name)),
113 "expected 1.2.3.4, got %s\n", SnmpUtilOidToA(&vars[0].name));
115 /* The table is not an accessible variable, so it fails */
116 vars[0].name.idLength = sizeof(mib2IfTable) / sizeof(mib2IfTable[0]);
117 vars[0].name.ids = mib2IfTable;
118 SetLastError(0xdeadbeef);
119 error = 0xdeadbeef;
120 index = 0xdeadbeef;
121 ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
122 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
123 ok(error == SNMP_ERRORSTATUS_NOSUCHNAME,
124 "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error);
125 /* The index is 1-based rather than 0-based */
126 ok(index == 1, "expected index 1, got %d\n", index);
128 /* A Get fails on something that specifies a table (but not a particular
129 * entry in it)...
131 vars[0].name.idLength = sizeof(mib2IfDescr) / sizeof(mib2IfDescr[0]);
132 vars[0].name.ids = mib2IfDescr;
133 vars[1].name.idLength =
134 sizeof(mib2IfAdminStatus) / sizeof(mib2IfAdminStatus[0]);
135 vars[1].name.ids = mib2IfAdminStatus;
136 vars[2].name.idLength =
137 sizeof(mib2IfOperStatus) / sizeof(mib2IfOperStatus[0]);
138 vars[2].name.ids = mib2IfOperStatus;
139 list.len = 3;
140 SetLastError(0xdeadbeef);
141 error = 0xdeadbeef;
142 index = 0xdeadbeef;
143 ret = pQuery(SNMP_PDU_GET, &list, &error, &index);
144 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
145 ok(error == SNMP_ERRORSTATUS_NOSUCHNAME,
146 "expected SNMP_ERRORSTATUS_NOSUCHNAME, got %d\n", error);
147 ok(index == 1, "expected index 1, got %d\n", index);
148 /* but a GetNext succeeds with the same values, because GetNext gets the
149 * entry after the specified OID, not the entry specified by it. The
150 * successor to the table is the first entry in the table.
151 * The OIDs need to be allocated, because GetNext modifies them to indicate
152 * the end of data.
154 SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
155 SnmpUtilOidCpy(&vars2[1].name, &vars[1].name);
156 SnmpUtilOidCpy(&vars2[2].name, &vars[2].name);
157 list.list = vars2;
158 moreData = TRUE;
159 entry = 1;
160 do {
161 SetLastError(0xdeadbeef);
162 error = 0xdeadbeef;
163 index = 0xdeadbeef;
164 ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
165 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
166 ok(error == SNMP_ERRORSTATUS_NOERROR,
167 "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
168 ok(index == 0, "expected index 0, got %d\n", index);
169 if (!ret)
170 moreData = FALSE;
171 else if (error)
172 moreData = FALSE;
173 else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
174 vars[0].name.idLength))
175 moreData = FALSE;
176 else if (SnmpUtilOidNCmp(&vars2[1].name, &vars[1].name,
177 vars[1].name.idLength))
178 moreData = FALSE;
179 else if (SnmpUtilOidNCmp(&vars2[2].name, &vars[2].name,
180 vars[2].name.idLength))
181 moreData = FALSE;
182 if (moreData)
184 /* Check the OIDs. For these types of values (display strings and
185 * integers) they increase by 1 for each element of the table.
187 ok(vars2[0].name.idLength == vars[0].name.idLength + 1,
188 "expected length %d, got %d\n", vars[0].name.idLength + 1,
189 vars2[0].name.idLength);
190 ok(vars2[0].name.ids[vars2[0].name.idLength - 1] == entry,
191 "expected %d, got %d\n", entry,
192 vars2[0].name.ids[vars2[0].name.idLength - 1]);
193 ok(vars2[1].name.idLength == vars[1].name.idLength + 1,
194 "expected length %d, got %d\n", vars[1].name.idLength + 1,
195 vars2[1].name.idLength);
196 ok(vars2[1].name.ids[vars2[1].name.idLength - 1] == entry,
197 "expected %d, got %d\n", entry,
198 vars2[1].name.ids[vars2[1].name.idLength - 1]);
199 ok(vars2[2].name.idLength == vars[2].name.idLength + 1,
200 "expected length %d, got %d\n", vars[2].name.idLength + 1,
201 vars2[2].name.idLength);
202 ok(vars2[2].name.ids[vars2[2].name.idLength - 1] == entry,
203 "expected %d, got %d\n", entry,
204 vars2[2].name.ids[vars2[2].name.idLength - 1]);
205 ++entry;
206 /* Check the types while we're at it */
207 ok(vars2[0].value.asnType == ASN_OCTETSTRING,
208 "expected ASN_OCTETSTRING, got %02x\n", vars2[0].value.asnType);
209 ok(vars2[1].value.asnType == ASN_INTEGER,
210 "expected ASN_INTEGER, got %02x\n", vars2[1].value.asnType);
211 ok(vars2[2].value.asnType == ASN_INTEGER,
212 "expected ASN_INTEGER, got %02x\n", vars2[2].value.asnType);
213 /* Check that the operational status of an interface correctly
214 * follows the MIB2 definition of it, rather than the values
215 * defined for IPHlpApi's dwOperStatus field.
217 ok(vars2[2].value.asnValue.unsigned32 <= 2,
218 "expected a value of 0, 1, or 2, got %u\n",
219 vars2[2].value.asnValue.unsigned32);
221 } while (moreData);
222 SnmpUtilVarBindFree(&vars2[0]);
223 SnmpUtilVarBindFree(&vars2[1]);
224 SnmpUtilVarBindFree(&vars2[2]);
226 /* Even though SnmpExtensionInit says this DLL supports the MIB2 system
227 * variables, the first variable it returns a value for is the first
228 * interface.
230 vars[0].name.idLength = sizeof(mib2System) / sizeof(mib2System[0]);
231 vars[0].name.ids = mib2System;
232 SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
233 vars2[0].value.asnType = 0;
234 list.len = 1;
235 list.list = vars2;
236 moreData = TRUE;
237 ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
238 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
239 ok(error == SNMP_ERRORSTATUS_NOERROR,
240 "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
241 ok(index == 0, "expected index 0, got %d\n", index);
242 vars[0].name.idLength = sizeof(mib2If) / sizeof(mib2If[0]);
243 vars[0].name.ids = mib2If;
244 ok(!SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name, vars[0].name.idLength),
245 "expected 1.3.6.1.2.1.2, got %s\n", SnmpUtilOidToA(&vars2[0].name));
246 SnmpUtilVarBindFree(&vars2[0]);
248 /* Check the type and OIDs of the IP address table */
249 vars[0].name.idLength = sizeof(mib2IpAddr) / sizeof(mib2IpAddr[0]);
250 vars[0].name.ids = mib2IpAddr;
251 SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
252 vars2[0].value.asnType = 0;
253 list.len = 1;
254 list.list = vars2;
255 moreData = TRUE;
256 do {
257 ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
258 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
259 ok(error == SNMP_ERRORSTATUS_NOERROR,
260 "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
261 ok(index == 0, "expected index 0, got %d\n", index);
262 if (!ret)
263 moreData = FALSE;
264 else if (error)
265 moreData = FALSE;
266 else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
267 vars[0].name.idLength))
268 moreData = FALSE;
269 if (moreData)
271 /* Make sure the size of the OID is right.
272 * FIXME: don't know if IPv6 addrs are shared with this table.
273 * Don't think so, but I'm not certain.
275 ok(vars2[0].name.idLength == vars[0].name.idLength + 4,
276 "expected length %d, got %d\n", vars[0].name.idLength + 4,
277 vars2[0].name.idLength);
278 /* Make sure the type is right */
279 ok(vars2[0].value.asnType == ASN_IPADDRESS,
280 "expected type ASN_IPADDRESS, got %02x\n",
281 vars2[0].value.asnType);
282 if (vars2[0].value.asnType == ASN_IPADDRESS)
284 UINT i;
286 /* This looks uglier than it is: the base OID for the IP
287 * address, 1.3.6.1.2.1.4.20.1.1, is appended with the IP
288 * address of the entry. So e.g. the loopback address is
289 * identified in MIB2 as 1.3.6.1.2.1.4.20.1.1.127.0.0.1
291 for (i = 0; i < vars2[0].value.asnValue.address.length; i++)
293 ok(vars2[0].value.asnValue.address.stream[i] ==
294 vars2[0].name.ids[vars2[0].name.idLength - 4 + i],
295 "expected ident byte %d to be %d, got %d\n", i,
296 vars2[0].value.asnValue.address.stream[i],
297 vars2[0].name.ids[vars2[0].name.idLength - 4 + i]);
301 } while (moreData);
302 SnmpUtilVarBindFree(&vars2[0]);
304 /* Check the type and OIDs of the IP route table */
305 vars[0].name.idLength = DEFINE_SIZEOF(mib2IpRouteTable);
306 vars[0].name.ids = mib2IpRouteTable;
307 SnmpUtilOidCpy(&vars2[0].name, &vars[0].name);
308 vars2[0].value.asnType = 0;
309 list.len = 1;
310 list.list = vars2;
311 moreData = TRUE;
312 do {
313 ret = pQuery(SNMP_PDU_GETNEXT, &list, &error, &index);
314 ok(ret, "SnmpExtensionQuery failed: %d\n", GetLastError());
315 ok(error == SNMP_ERRORSTATUS_NOERROR,
316 "expected SNMP_ERRORSTATUS_NOERROR, got %d\n", error);
317 ok(index == 0, "expected index 0, got %d\n", index);
318 if (!ret)
319 moreData = FALSE;
320 else if (error)
321 moreData = FALSE;
322 else if (SnmpUtilOidNCmp(&vars2[0].name, &vars[0].name,
323 vars[0].name.idLength))
324 moreData = FALSE;
325 if (moreData)
327 /* Make sure the size of the OID is right.
328 * FIXME: don't know if IPv6 addrs are shared with this table.
329 * Don't think so, but I'm not certain.
331 ok(vars2[0].name.idLength = vars[0].name.idLength + 4,
332 "expected length %d, got %d\n", vars[0].name.idLength + 4,
333 vars2[0].name.idLength);
334 /* Make sure the type is right */
335 ok(vars2[0].value.asnType == ASN_IPADDRESS,
336 "expected type ASN_IPADDRESS, got %02x\n",
337 vars2[0].value.asnType);
338 if (vars2[0].value.asnType == ASN_IPADDRESS)
340 UINT i;
342 /* The base OID for the route table, 1.3.6.1.2.1.4.21.1.1, is
343 * appended with the dest IP address of the entry. So e.g. a
344 * route entry for 224.0.0.0 is identified in MIB2 as
345 * 1.3.6.1.2.1.4.21.1.1.224.0.0.0
347 for (i = 0; i < vars2[0].value.asnValue.address.length; i++)
349 ok(vars2[0].value.asnValue.address.stream[i] ==
350 vars2[0].name.ids[vars2[0].name.idLength - 4 + i],
351 "expected ident byte %d to be %d, got %d\n", i,
352 vars2[0].value.asnValue.address.stream[i],
353 vars2[0].name.ids[vars2[0].name.idLength - 4 + i]);
357 } while (moreData);
358 SnmpUtilVarBindFree(&vars2[0]);
361 START_TEST(main)
363 inetmib1 = LoadLibraryA("inetmib1");
364 testInit();
365 testQuery();