ReactOS 0.4.16-dev-136-g52192f1
main.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Juan Lang
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include <assert.h>
20#include <stdarg.h>
21#include <stdlib.h>
22#include <limits.h>
23
24#define NONAMELESSUNION
25
26#include "windef.h"
27#include "winbase.h"
28#include "snmp.h"
29#include "iphlpapi.h"
30#include "wine/debug.h"
31
33
37static DWORD copyInt(AsnAny *value, void *src)
38{
39 value->asnType = ASN_INTEGER;
40 value->asnValue.number = *(DWORD *)src;
42}
43
45{
46 AsnAny strValue;
47
48 strValue.asnType = type;
49 strValue.asnValue.string.stream = str;
50 strValue.asnValue.string.length = len;
51 strValue.asnValue.string.dynamic = FALSE;
52 SnmpUtilAsnAnyCpy(value, &strValue);
53}
54
55typedef DWORD (*copyValueFunc)(AsnAny *value, void *src);
56
58{
59 size_t offset;
61};
62
64 UINT mapLen, void *record, UINT id, SnmpVarBind *pVarBind)
65{
66 /* OIDs are 1-based */
67 if (!id)
69 --id;
70 if (id >= mapLen)
72 if (!map[id].copy)
74 return map[id].copy(&pVarBind->value, (BYTE *)record + map[id].offset);
75}
76
78{
81}
82
83static UINT mib2[] = { 1,3,6,1,2,1 };
84static UINT mib2System[] = { 1,3,6,1,2,1,1 };
85
86typedef BOOL (*varqueryfunc)(BYTE bPduType, SnmpVarBind *pVarBind,
87 AsnInteger32 *pErrorStatus);
88
90{
95};
96
97static UINT mib2IfNumber[] = { 1,3,6,1,2,1,2,1 };
99
100static void mib2IfNumberInit(void)
101{
103
105 {
107 if (table)
108 {
110 else HeapFree(GetProcessHeap(), 0, table );
111 }
112 }
113}
114
115static void mib2IfNumberCleanup(void)
116{
118}
119
120static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind,
121 AsnInteger32 *pErrorStatus)
122{
124 BOOL ret = TRUE;
125
126 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
127 pErrorStatus);
128
129 switch (bPduType)
130 {
131 case SNMP_PDU_GET:
132 case SNMP_PDU_GETNEXT:
133 if ((bPduType == SNMP_PDU_GET &&
134 !SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength))
135 || SnmpUtilOidNCmp(&pVarBind->name, &numberOid, numberOid.idLength)
136 < 0)
137 {
138 DWORD numIfs = ifTable ? ifTable->dwNumEntries : 0;
139
140 copyInt(&pVarBind->value, &numIfs);
141 if (bPduType == SNMP_PDU_GETNEXT)
142 {
143 SnmpUtilOidFree(&pVarBind->name);
144 SnmpUtilOidCpy(&pVarBind->name, &numberOid);
145 }
146 *pErrorStatus = SNMP_ERRORSTATUS_NOERROR;
147 }
148 else
149 {
150 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
151 /* Caller deals with OID if bPduType == SNMP_PDU_GETNEXT, so don't
152 * need to set it here.
153 */
154 }
155 break;
156 case SNMP_PDU_SET:
157 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
158 ret = FALSE;
159 break;
160 default:
161 FIXME("0x%02x: unsupported PDU type\n", bPduType);
162 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
163 }
164 return ret;
165}
166
168{
169 value->asnType = ASN_INTEGER;
170 /* The IPHlpApi definition of operational status differs from the MIB2 one,
171 * so map it to the MIB2 value.
172 */
173 switch (*(DWORD *)src)
174 {
176 value->asnValue.number = MIB_IF_ADMIN_STATUS_UP;
177 break;
180 value->asnValue.number = MIB_IF_ADMIN_STATUS_TESTING;
181 break;
182 default:
183 value->asnValue.number = MIB_IF_ADMIN_STATUS_DOWN;
184 };
186}
187
188/* Given an OID and a base OID that it must begin with, finds the item and
189 * integer instance from the OID. E.g., given an OID foo.1.2 and a base OID
190 * foo, returns item 1 and instance 2.
191 * If bPduType is not SNMP_PDU_GETNEXT and either the item or instance is
192 * missing, returns SNMP_ERRORSTATUS_NOSUCHNAME.
193 * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item and
194 * instance, or item 1, instance 1 if either is missing.
195 */
198{
200
201 switch (bPduType)
202 {
203 case SNMP_PDU_GETNEXT:
204 if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
205 {
206 *item = 1;
207 *instance = 1;
208 }
209 else if (!SnmpUtilOidNCmp(oid, base, base->idLength))
210 {
211 if (oid->idLength == base->idLength ||
212 oid->idLength == base->idLength + 1)
213 {
214 /* Either the table or an item within the table is specified,
215 * but the instance is not. Get the first instance.
216 */
217 *instance = 1;
218 if (oid->idLength == base->idLength + 1)
219 *item = oid->ids[base->idLength];
220 else
221 *item = 1;
222 }
223 else
224 {
225 *item = oid->ids[base->idLength];
226 *instance = oid->ids[base->idLength + 1] + 1;
227 }
228 }
229 else
231 break;
232 default:
233 if (!SnmpUtilOidNCmp(oid, base, base->idLength))
234 {
235 if (oid->idLength == base->idLength ||
236 oid->idLength == base->idLength + 1)
237 {
238 /* Either the table or an item within the table is specified,
239 * but the instance is not.
240 */
242 }
243 else
244 {
245 *item = oid->ids[base->idLength];
246 *instance = oid->ids[base->idLength + 1];
247 }
248 }
249 else
251 }
252 return ret;
253}
254
255/* Given an OID and a base OID that it must begin with, finds the item from the
256 * OID. E.g., given an OID foo.1 and a base OID foo, returns item 1.
257 * If bPduType is not SNMP_PDU_GETNEXT and the item is missing, returns
258 * SNMP_ERRORSTATUS_NOSUCHNAME.
259 * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item, or item
260 * 1 if the item is missing.
261 */
264{
266
267 switch (bPduType)
268 {
269 case SNMP_PDU_GETNEXT:
270 if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
271 *item = 1;
272 else if (!SnmpUtilOidNCmp(oid, base, base->idLength))
273 {
274 if (oid->idLength == base->idLength)
275 {
276 /* The item is missing, assume the first item */
277 *item = 1;
278 }
279 else
280 *item = oid->ids[base->idLength] + 1;
281 }
282 else
284 break;
285 default:
286 if (!SnmpUtilOidNCmp(oid, base, base->idLength))
287 {
288 if (oid->idLength == base->idLength)
289 {
290 /* The item is missing */
292 }
293 else
294 {
295 *item = oid->ids[base->idLength];
296 if (!*item)
298 }
299 }
300 else
302 }
303 return ret;
304}
305
307{
310};
311
313{
314 assert(oid && oid->idLength >= 4);
315 /* Map the IDs to an IP address in little-endian order */
316 return (BYTE)oid->ids[3] << 24 | (BYTE)oid->ids[2] << 16 |
317 (BYTE)oid->ids[1] << 8 | (BYTE)oid->ids[0];
318}
319
320typedef void (*oidToKeyFunc)(AsnObjectIdentifier *oid, void *dst);
321typedef int (__cdecl *compareFunc)(const void *key, const void *value);
322
323/* Finds the first value in the table that matches key. Returns its 1-based
324 * index if found, or 0 if not found.
325 */
326static UINT findValueInTable(const void *key,
327 struct GenericTable *table, size_t tableEntrySize, compareFunc compare)
328{
329 UINT index = 0;
330 void *value;
331
332 value = bsearch(key, table->entries, table->numEntries, tableEntrySize,
333 compare);
334 if (value)
335 index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize + 1;
336 return index;
337}
338
339/* Finds the first value in the table that matches oid, using makeKey to
340 * convert the oid to a key for comparison. Returns the value's 1-based
341 * index if found, or 0 if not found.
342 */
344 struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
346{
347 UINT index = 0;
348 void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize);
349
350 if (key)
351 {
352 makeKey(oid, key);
353 index = findValueInTable(key, table, tableEntrySize, compare);
355 }
356 return index;
357}
358
359/* Finds the first successor to the value in the table that does matches oid,
360 * using makeKey to convert the oid to a key for comparison. A successor is
361 * a value that does not match oid, so if multiple entries match an oid, only
362 * the first will ever be returned using this method.
363 * Returns the successor's 1-based index if found, or 0 if not found.
364 */
366 struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
368{
369 UINT index = 0;
370 void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize);
371
372 if (key)
373 {
374 makeKey(oid, key);
375 index = findValueInTable(key, table, tableEntrySize, compare);
376 if (index == 0)
377 {
378 /* Not found in table. If it's less than the first entry, return
379 * the first index. Otherwise just return 0 and let the caller
380 * handle finding the successor.
381 */
382 if (compare(key, table->entries) < 0)
383 index = 1;
384 }
385 else
386 {
387 /* Skip any entries that match the same key. This enumeration will
388 * be incomplete, but it's what Windows appears to do if there are
389 * multiple entries with the same index in a table, and it avoids
390 * an infinite loop.
391 */
392 for (++index; index <= table->numEntries && compare(key,
393 &table->entries[tableEntrySize * (index - 1)]) == 0; ++index)
394 ;
395 }
397 }
398 return index;
399}
400
401/* Given an OID and a base OID that it must begin with, finds the item and
402 * element of the table whose value matches the instance from the OID.
403 * The OID is converted to a key with the function makeKey, and compared
404 * against entries in the table with the function compare.
405 * If bPduType is not SNMP_PDU_GETNEXT and either the item or instance is
406 * missing, returns SNMP_ERRORSTATUS_NOSUCHNAME.
407 * If bPduType is SNMP_PDU_GETNEXT, returns the successor to the item and
408 * instance, or item 1, instance 1 if either is missing.
409 */
411 AsnObjectIdentifier *base, UINT instanceLen, BYTE bPduType,
412 struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
414{
416
417 if (!table)
419
420 switch (bPduType)
421 {
422 case SNMP_PDU_GETNEXT:
423 if (SnmpUtilOidNCmp(oid, base, base->idLength) < 0)
424 {
425 /* Return the first item and instance from the table */
426 *item = 1;
427 *instance = 1;
428 }
429 else if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
430 oid->idLength < base->idLength + instanceLen + 1)
431 {
432 /* Either the table or an item is specified, but the instance is
433 * not.
434 */
435 *instance = 1;
436 if (oid->idLength >= base->idLength + 1)
437 {
438 *item = oid->ids[base->idLength];
439 if (!*item)
440 *item = 1;
441 }
442 else
443 *item = 1;
444 }
445 else if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
446 oid->idLength == base->idLength + instanceLen + 1)
447 {
448 *item = oid->ids[base->idLength];
449 if (!*item)
450 {
451 *instance = 1;
452 *item = 1;
453 }
454 else
455 {
456 AsnObjectIdentifier instanceOid = { instanceLen,
457 oid->ids + base->idLength + 1 };
458
459 *instance = findNextOidInTable(&instanceOid, table,
460 tableEntrySize, makeKey, compare);
461 if (!*instance || *instance > table->numEntries)
463 }
464 }
465 else
467 break;
468 default:
469 if (!SnmpUtilOidNCmp(oid, base, base->idLength) &&
470 oid->idLength == base->idLength + instanceLen + 1)
471 {
472 *item = oid->ids[base->idLength];
473 if (!*item)
475 else
476 {
477 AsnObjectIdentifier instanceOid = { instanceLen,
478 oid->ids + base->idLength + 1 };
479
480 *instance = findOidInTable(&instanceOid, table, tableEntrySize,
481 makeKey, compare);
482 if (!*instance)
484 }
485 }
486 else
488 }
489 return ret;
490}
491
493 UINT item)
494{
495 UINT id;
497 INT ret;
498
501 if (ret)
502 {
503 oid.idLength = 1;
504 oid.ids = &id;
505 id = item;
506 ret = SnmpUtilOidAppend(dst, &oid);
507 }
508 return ret;
509}
510
513{
514 UINT id;
515 BYTE *ptr;
517 INT ret;
518
520 if (ret)
521 {
522 oid.idLength = 1;
523 oid.ids = &id;
524 for (ptr = (BYTE *)&addr; ret && ptr < (BYTE *)&addr + sizeof(DWORD);
525 ptr++)
526 {
527 id = *ptr;
528 ret = SnmpUtilOidAppend(dst, &oid);
529 }
530 }
531 return ret;
532}
533
536{
538 INT ret;
539
541 if (ret)
542 {
543 oid.idLength = 1;
544 oid.ids = &instance;
545 ret = SnmpUtilOidAppend(dst, &oid);
546 }
547 return ret;
548}
549
551{
553 FIELD_OFFSET(MIB_IFROW, dwDescrLen));
554 DWORD ret;
555
556 if (row->dwDescrLen)
557 {
558 setStringValue(value, ASN_OCTETSTRING, row->dwDescrLen, row->bDescr);
560 }
561 else
563 return ret;
564}
565
567{
569 FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen));
570 DWORD ret;
571
572 if (row->dwPhysAddrLen)
573 {
574 setStringValue(value, ASN_OCTETSTRING, row->dwPhysAddrLen,
575 row->bPhysAddr);
577 }
578 else
580 return ret;
581}
582
584 { FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt },
585 { FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyIfRowDescr },
586 { FIELD_OFFSET(MIB_IFROW, dwType), copyInt },
587 { FIELD_OFFSET(MIB_IFROW, dwMtu), copyInt },
588 { FIELD_OFFSET(MIB_IFROW, dwSpeed), copyInt },
589 { FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen), copyIfRowPhysAddr },
590 { FIELD_OFFSET(MIB_IFROW, dwAdminStatus), copyInt },
591 { FIELD_OFFSET(MIB_IFROW, dwOperStatus), copyOperStatus },
592 { FIELD_OFFSET(MIB_IFROW, dwLastChange), copyInt },
593 { FIELD_OFFSET(MIB_IFROW, dwInOctets), copyInt },
594 { FIELD_OFFSET(MIB_IFROW, dwInUcastPkts), copyInt },
595 { FIELD_OFFSET(MIB_IFROW, dwInNUcastPkts), copyInt },
596 { FIELD_OFFSET(MIB_IFROW, dwInDiscards), copyInt },
597 { FIELD_OFFSET(MIB_IFROW, dwInErrors), copyInt },
598 { FIELD_OFFSET(MIB_IFROW, dwInUnknownProtos), copyInt },
599 { FIELD_OFFSET(MIB_IFROW, dwOutOctets), copyInt },
600 { FIELD_OFFSET(MIB_IFROW, dwOutUcastPkts), copyInt },
601 { FIELD_OFFSET(MIB_IFROW, dwOutNUcastPkts), copyInt },
602 { FIELD_OFFSET(MIB_IFROW, dwOutDiscards), copyInt },
603 { FIELD_OFFSET(MIB_IFROW, dwOutErrors), copyInt },
604 { FIELD_OFFSET(MIB_IFROW, dwOutQLen), copyInt },
605};
606
607static UINT mib2IfEntry[] = { 1,3,6,1,2,1,2,2,1 };
608
609static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
610 AsnInteger32 *pErrorStatus)
611{
613 BOOL ret = TRUE;
614
615 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
616 pErrorStatus);
617
618 switch (bPduType)
619 {
620 case SNMP_PDU_GET:
621 case SNMP_PDU_GETNEXT:
622 if (!ifTable)
623 {
624 /* There is no interface present, so let the caller deal
625 * with finding the successor.
626 */
627 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
628 }
629 else
630 {
631 UINT tableIndex = 0, item = 0;
632
633 *pErrorStatus = getItemAndIntegerInstanceFromOid(&pVarBind->name,
634 &entryOid, bPduType, &item, &tableIndex);
635 if (!*pErrorStatus)
636 {
637 assert(tableIndex);
638 assert(item);
639 if (tableIndex > ifTable->dwNumEntries)
640 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
641 else
642 {
645 &ifTable->table[tableIndex - 1], item,
646 pVarBind);
647 if (bPduType == SNMP_PDU_GETNEXT)
648 ret = setOidWithItemAndInteger(&pVarBind->name,
649 &entryOid, item, tableIndex);
650 }
651 }
652 }
653 break;
654 case SNMP_PDU_SET:
655 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
656 ret = FALSE;
657 break;
658 default:
659 FIXME("0x%02x: unsupported PDU type\n", bPduType);
660 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
661 }
662 return ret;
663}
664
665static UINT mib2Ip[] = { 1,3,6,1,2,1,4 };
667
668static void mib2IpStatsInit(void)
669{
671}
672
673static struct structToAsnValue mib2IpMap[] = {
674 { FIELD_OFFSET(MIB_IPSTATS, u.dwForwarding), copyInt }, /* 1 */
675 { FIELD_OFFSET(MIB_IPSTATS, dwDefaultTTL), copyInt }, /* 2 */
676 { FIELD_OFFSET(MIB_IPSTATS, dwInReceives), copyInt }, /* 3 */
677 { FIELD_OFFSET(MIB_IPSTATS, dwInHdrErrors), copyInt }, /* 4 */
678 { FIELD_OFFSET(MIB_IPSTATS, dwInAddrErrors), copyInt }, /* 5 */
679 { FIELD_OFFSET(MIB_IPSTATS, dwForwDatagrams), copyInt }, /* 6 */
680 { FIELD_OFFSET(MIB_IPSTATS, dwInUnknownProtos), copyInt }, /* 7 */
681 { FIELD_OFFSET(MIB_IPSTATS, dwInDiscards), copyInt }, /* 8 */
682 { FIELD_OFFSET(MIB_IPSTATS, dwInDelivers), copyInt }, /* 9 */
683 { FIELD_OFFSET(MIB_IPSTATS, dwOutRequests), copyInt }, /* 10 */
684 { FIELD_OFFSET(MIB_IPSTATS, dwOutDiscards), copyInt }, /* 11 */
685 { FIELD_OFFSET(MIB_IPSTATS, dwOutNoRoutes), copyInt }, /* 12 */
686 { FIELD_OFFSET(MIB_IPSTATS, dwReasmTimeout), copyInt }, /* 13 */
687 { FIELD_OFFSET(MIB_IPSTATS, dwReasmReqds), copyInt }, /* 14 */
688 { FIELD_OFFSET(MIB_IPSTATS, dwReasmOks), copyInt }, /* 15 */
689 { FIELD_OFFSET(MIB_IPSTATS, dwReasmFails), copyInt }, /* 16 */
690 { FIELD_OFFSET(MIB_IPSTATS, dwFragOks), copyInt }, /* 17 */
691 { FIELD_OFFSET(MIB_IPSTATS, dwFragFails), copyInt }, /* 18 */
692 { FIELD_OFFSET(MIB_IPSTATS, dwFragCreates), copyInt }, /* 19 */
693 { 0, NULL }, /* 20: not used, IP addr table */
694 { 0, NULL }, /* 21: not used, route table */
695 { 0, NULL }, /* 22: not used, net to media (ARP) table */
696 { FIELD_OFFSET(MIB_IPSTATS, dwRoutingDiscards), copyInt }, /* 23 */
697};
698
699static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind,
700 AsnInteger32 *pErrorStatus)
701{
703 UINT item = 0;
704 BOOL ret = TRUE;
705
706 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
707 pErrorStatus);
708
709 switch (bPduType)
710 {
711 case SNMP_PDU_GET:
712 case SNMP_PDU_GETNEXT:
713 *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
714 &item);
715 if (!*pErrorStatus)
716 {
717 *pErrorStatus = mapStructEntryToValue(mib2IpMap,
718 DEFINE_SIZEOF(mib2IpMap), &ipStats, item, pVarBind);
719 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
720 ret = setOidWithItem(&pVarBind->name, &myOid, item);
721 }
722 break;
723 case SNMP_PDU_SET:
724 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
725 ret = FALSE;
726 break;
727 default:
728 FIXME("0x%02x: unsupported PDU type\n", bPduType);
729 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
730 }
731 return ret;
732}
733
734static UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1 };
736
739 { FIELD_OFFSET(MIB_IPADDRROW, dwIndex), copyInt },
741 { FIELD_OFFSET(MIB_IPADDRROW, dwBCastAddr), copyInt },
742 { FIELD_OFFSET(MIB_IPADDRROW, dwReasmSize), copyInt },
743};
744
745static void mib2IpAddrInit(void)
746{
748
750 {
752 if (table)
753 {
755 else HeapFree(GetProcessHeap(), 0, table );
756 }
757 }
758}
759
760static void mib2IpAddrCleanup(void)
761{
763}
764
765static void oidToIpAddrRow(AsnObjectIdentifier *oid, void *dst)
766{
768
769 row->dwAddr = oidToIpAddr(oid);
770}
771
772static int __cdecl compareIpAddrRow(const void *a, const void *b)
773{
774 const MIB_IPADDRROW *key = a, *value = b;
775
776 return key->dwAddr - value->dwAddr;
777}
778
779static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind,
780 AsnInteger32 *pErrorStatus)
781{
783 UINT tableIndex = 0, item = 0;
784 BOOL ret = TRUE;
785
786 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
787 pErrorStatus);
788
789 switch (bPduType)
790 {
791 case SNMP_PDU_GET:
792 case SNMP_PDU_GETNEXT:
793 *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name,
794 &myOid, 4, bPduType, (struct GenericTable *)ipAddrTable,
796 &tableIndex);
797 if (!*pErrorStatus)
798 {
799 assert(tableIndex);
800 assert(item);
801 *pErrorStatus = mapStructEntryToValue(mib2IpAddrMap,
803 &ipAddrTable->table[tableIndex - 1], item, pVarBind);
804 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
805 ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
806 ipAddrTable->table[tableIndex - 1].dwAddr);
807 }
808 break;
809 case SNMP_PDU_SET:
810 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
811 ret = FALSE;
812 break;
813 default:
814 FIXME("0x%02x: unsupported PDU type\n", bPduType);
815 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
816 }
817 return ret;
818}
819
820static UINT mib2IpRoute[] = { 1,3,6,1,2,1,4,21,1 };
822
824 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardDest), copyIpAddr },
825 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardIfIndex), copyInt },
826 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric1), copyInt },
827 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric2), copyInt },
828 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric3), copyInt },
829 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric4), copyInt },
830 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardNextHop), copyIpAddr },
833 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardAge), copyInt },
834 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMask), copyIpAddr },
835 { FIELD_OFFSET(MIB_IPFORWARDROW, dwForwardMetric5), copyInt },
836};
837
838static void mib2IpRouteInit(void)
839{
841
843 {
845 if (table)
846 {
848 else HeapFree(GetProcessHeap(), 0, table );
849 }
850 }
851}
852
853static void mib2IpRouteCleanup(void)
854{
856}
857
859{
861
862 row->dwForwardDest = oidToIpAddr(oid);
863}
864
865static int __cdecl compareIpForwardRow(const void *a, const void *b)
866{
867 const MIB_IPFORWARDROW *key = a, *value = b;
868
869 return key->dwForwardDest - value->dwForwardDest;
870}
871
872static BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind,
873 AsnInteger32 *pErrorStatus)
874{
876 UINT tableIndex = 0, item = 0;
877 BOOL ret = TRUE;
878
879 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
880 pErrorStatus);
881
882 switch (bPduType)
883 {
884 case SNMP_PDU_GET:
885 case SNMP_PDU_GETNEXT:
886 *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name,
887 &myOid, 4, bPduType, (struct GenericTable *)ipRouteTable,
889 &item, &tableIndex);
890 if (!*pErrorStatus)
891 {
892 assert(tableIndex);
893 assert(item);
896 &ipRouteTable->table[tableIndex - 1], item, pVarBind);
897 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
898 ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
899 ipRouteTable->table[tableIndex - 1].dwForwardDest);
900 }
901 break;
902 case SNMP_PDU_SET:
903 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
904 ret = FALSE;
905 break;
906 default:
907 FIXME("0x%02x: unsupported PDU type\n", bPduType);
908 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
909 }
910 return ret;
911}
912
913static UINT mib2IpNet[] = { 1,3,6,1,2,1,4,22,1 };
915
917{
919 dwPhysAddrLen));
920
921 setStringValue(value, ASN_OCTETSTRING, row->dwPhysAddrLen, row->bPhysAddr);
923}
924
926 { FIELD_OFFSET(MIB_IPNETROW, dwIndex), copyInt },
927 { FIELD_OFFSET(MIB_IPNETROW, dwPhysAddrLen), copyIpNetPhysAddr },
929 { FIELD_OFFSET(MIB_IPNETROW, u.dwType), copyInt },
930};
931
932static void mib2IpNetInit(void)
933{
935
937 {
939 if (table)
940 {
942 else HeapFree(GetProcessHeap(), 0, table );
943 }
944 }
945}
946
947static void mib2IpNetCleanup(void)
948{
950}
951
952static BOOL mib2IpNetQuery(BYTE bPduType, SnmpVarBind *pVarBind,
953 AsnInteger32 *pErrorStatus)
954{
956 BOOL ret = TRUE;
957
958 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
959 pErrorStatus);
960
961 switch (bPduType)
962 {
963 case SNMP_PDU_GET:
964 case SNMP_PDU_GETNEXT:
965 if (!ipNetTable)
966 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
967 else
968 {
969 UINT tableIndex = 0, item = 0;
970
971 *pErrorStatus = getItemAndIntegerInstanceFromOid(&pVarBind->name,
972 &myOid, bPduType, &item, &tableIndex);
973 if (!*pErrorStatus)
974 {
975 assert(tableIndex);
976 assert(item);
977 if (tableIndex > ipNetTable->dwNumEntries)
978 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
979 else
980 {
981 *pErrorStatus = mapStructEntryToValue(mib2IpNetMap,
983 &ipNetTable[tableIndex - 1], item, pVarBind);
984 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
985 ret = setOidWithItemAndInteger(&pVarBind->name, &myOid,
986 item, tableIndex);
987 }
988 }
989 }
990 break;
991 case SNMP_PDU_SET:
992 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
993 ret = FALSE;
994 break;
995 default:
996 FIXME("0x%02x: unsupported PDU type\n", bPduType);
997 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
998 }
999 return ret;
1000}
1001
1002static UINT mib2Icmp[] = { 1,3,6,1,2,1,5 };
1004
1005static void mib2IcmpInit(void)
1006{
1008}
1009
1011 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwMsgs), copyInt },
1012 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwErrors), copyInt },
1013 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwDestUnreachs), copyInt },
1014 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimeExcds), copyInt },
1015 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwParmProbs), copyInt },
1016 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwSrcQuenchs), copyInt },
1017 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwRedirects), copyInt },
1018 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwEchos), copyInt },
1019 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwEchoReps), copyInt },
1020 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimestamps), copyInt },
1021 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwTimestampReps), copyInt },
1022 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwAddrMasks), copyInt },
1023 { FIELD_OFFSET(MIBICMPINFO, icmpInStats.dwAddrMaskReps), copyInt },
1024 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwMsgs), copyInt },
1025 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwErrors), copyInt },
1026 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwDestUnreachs), copyInt },
1027 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimeExcds), copyInt },
1028 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwParmProbs), copyInt },
1029 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwSrcQuenchs), copyInt },
1030 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwRedirects), copyInt },
1031 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwEchos), copyInt },
1032 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwEchoReps), copyInt },
1033 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimestamps), copyInt },
1034 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwTimestampReps), copyInt },
1035 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwAddrMasks), copyInt },
1036 { FIELD_OFFSET(MIBICMPINFO, icmpOutStats.dwAddrMaskReps), copyInt },
1037};
1038
1039static BOOL mib2IcmpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
1040 AsnInteger32 *pErrorStatus)
1041{
1043 UINT item = 0;
1044 BOOL ret = TRUE;
1045
1046 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
1047 pErrorStatus);
1048
1049 switch (bPduType)
1050 {
1051 case SNMP_PDU_GET:
1052 case SNMP_PDU_GETNEXT:
1053 *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
1054 &item);
1055 if (!*pErrorStatus)
1056 {
1057 *pErrorStatus = mapStructEntryToValue(mib2IcmpMap,
1059 pVarBind);
1060 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
1061 ret = setOidWithItem(&pVarBind->name, &myOid, item);
1062 }
1063 break;
1064 case SNMP_PDU_SET:
1065 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
1066 ret = FALSE;
1067 break;
1068 default:
1069 FIXME("0x%02x: unsupported PDU type\n", bPduType);
1070 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
1071 }
1072 return ret;
1073}
1074
1075static UINT mib2Tcp[] = { 1,3,6,1,2,1,6 };
1077
1078static void mib2TcpInit(void)
1079{
1081}
1082
1083static struct structToAsnValue mib2TcpMap[] = {
1084 { FIELD_OFFSET(MIB_TCPSTATS, u.dwRtoAlgorithm), copyInt },
1085 { FIELD_OFFSET(MIB_TCPSTATS, dwRtoMin), copyInt },
1086 { FIELD_OFFSET(MIB_TCPSTATS, dwRtoMax), copyInt },
1087 { FIELD_OFFSET(MIB_TCPSTATS, dwMaxConn), copyInt },
1088 { FIELD_OFFSET(MIB_TCPSTATS, dwActiveOpens), copyInt },
1089 { FIELD_OFFSET(MIB_TCPSTATS, dwPassiveOpens), copyInt },
1090 { FIELD_OFFSET(MIB_TCPSTATS, dwAttemptFails), copyInt },
1091 { FIELD_OFFSET(MIB_TCPSTATS, dwEstabResets), copyInt },
1092 { FIELD_OFFSET(MIB_TCPSTATS, dwCurrEstab), copyInt },
1093 { FIELD_OFFSET(MIB_TCPSTATS, dwInSegs), copyInt },
1094 { FIELD_OFFSET(MIB_TCPSTATS, dwOutSegs), copyInt },
1095 { FIELD_OFFSET(MIB_TCPSTATS, dwRetransSegs), copyInt },
1096 { FIELD_OFFSET(MIB_TCPSTATS, dwInErrs), copyInt },
1097 { FIELD_OFFSET(MIB_TCPSTATS, dwOutRsts), copyInt },
1098 { FIELD_OFFSET(MIB_TCPSTATS, dwNumConns), copyInt },
1099};
1100
1101static BOOL mib2TcpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
1102 AsnInteger32 *pErrorStatus)
1103{
1105 UINT item = 0;
1106 BOOL ret = TRUE;
1107
1108 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
1109 pErrorStatus);
1110
1111 switch (bPduType)
1112 {
1113 case SNMP_PDU_GET:
1114 case SNMP_PDU_GETNEXT:
1115 *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
1116 &item);
1117 if (!*pErrorStatus)
1118 {
1119 *pErrorStatus = mapStructEntryToValue(mib2TcpMap,
1120 DEFINE_SIZEOF(mib2TcpMap), &tcpStats, item, pVarBind);
1121 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
1122 ret = setOidWithItem(&pVarBind->name, &myOid, item);
1123 }
1124 break;
1125 case SNMP_PDU_SET:
1126 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
1127 ret = FALSE;
1128 break;
1129 default:
1130 FIXME("0x%02x: unsupported PDU type\n", bPduType);
1131 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
1132 }
1133 return ret;
1134}
1135
1136static UINT mib2Udp[] = { 1,3,6,1,2,1,7 };
1138
1139static void mib2UdpInit(void)
1140{
1142}
1143
1144static struct structToAsnValue mib2UdpMap[] = {
1145 { FIELD_OFFSET(MIB_UDPSTATS, dwInDatagrams), copyInt },
1146 { FIELD_OFFSET(MIB_UDPSTATS, dwNoPorts), copyInt },
1147 { FIELD_OFFSET(MIB_UDPSTATS, dwInErrors), copyInt },
1148 { FIELD_OFFSET(MIB_UDPSTATS, dwOutDatagrams), copyInt },
1149};
1150
1151static BOOL mib2UdpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
1152 AsnInteger32 *pErrorStatus)
1153{
1155 UINT item;
1156 BOOL ret = TRUE;
1157
1158 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
1159 pErrorStatus);
1160
1161 switch (bPduType)
1162 {
1163 case SNMP_PDU_GET:
1164 case SNMP_PDU_GETNEXT:
1165 *pErrorStatus = getItemFromOid(&pVarBind->name, &myOid, bPduType,
1166 &item);
1167 if (!*pErrorStatus)
1168 {
1169 *pErrorStatus = mapStructEntryToValue(mib2UdpMap,
1170 DEFINE_SIZEOF(mib2UdpMap), &udpStats, item, pVarBind);
1171 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
1172 ret = setOidWithItem(&pVarBind->name, &myOid, item);
1173 }
1174 break;
1175 case SNMP_PDU_SET:
1176 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
1177 ret = FALSE;
1178 break;
1179 default:
1180 FIXME("0x%02x: unsupported PDU type\n", bPduType);
1181 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
1182 }
1183 return ret;
1184}
1185
1186static UINT mib2UdpEntry[] = { 1,3,6,1,2,1,7,5,1 };
1188
1189static void mib2UdpEntryInit(void)
1190{
1191 DWORD size = 0, ret = GetUdpTable(NULL, &size, TRUE);
1192
1194 {
1196 if (table)
1197 {
1199 else HeapFree(GetProcessHeap(), 0, table);
1200 }
1201 }
1202}
1203
1204static void mib2UdpEntryCleanup(void)
1205{
1207}
1208
1210 { FIELD_OFFSET(MIB_UDPROW, dwLocalAddr), copyIpAddr },
1211 { FIELD_OFFSET(MIB_UDPROW, dwLocalPort), copyInt },
1212};
1213
1214static void oidToUdpRow(AsnObjectIdentifier *oid, void *dst)
1215{
1216 MIB_UDPROW *row = dst;
1217
1218 assert(oid && oid->idLength >= 5);
1219 row->dwLocalAddr = oidToIpAddr(oid);
1220 row->dwLocalPort = oid->ids[4];
1221}
1222
1223static int __cdecl compareUdpRow(const void *a, const void *b)
1224{
1225 const MIB_UDPROW *key = a, *value = b;
1226 int ret;
1227
1228 ret = key->dwLocalAddr - value->dwLocalAddr;
1229 if (ret == 0)
1230 ret = key->dwLocalPort - value->dwLocalPort;
1231 return ret;
1232}
1233
1234static BOOL mib2UdpEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
1235 AsnInteger32 *pErrorStatus)
1236{
1238 BOOL ret = TRUE;
1239
1240 TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
1241 pErrorStatus);
1242
1243 switch (bPduType)
1244 {
1245 case SNMP_PDU_GET:
1246 case SNMP_PDU_GETNEXT:
1247 if (!udpTable)
1248 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
1249 else
1250 {
1251 UINT tableIndex = 0, item = 0;
1252
1253 *pErrorStatus = getItemAndInstanceFromTable(&pVarBind->name, &myOid,
1254 5, bPduType, (struct GenericTable *)udpTable,
1256 &tableIndex);
1257 if (!*pErrorStatus)
1258 {
1259 assert(tableIndex);
1260 assert(item);
1261 *pErrorStatus = mapStructEntryToValue(mib2UdpEntryMap,
1263 &udpTable->table[tableIndex - 1], item, pVarBind);
1264 if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
1265 {
1267
1268 ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
1269 udpTable->table[tableIndex - 1].dwLocalAddr);
1270 if (ret)
1271 {
1272 oid.idLength = 1;
1273 oid.ids = &udpTable->table[tableIndex - 1].dwLocalPort;
1274 ret = SnmpUtilOidAppend(&pVarBind->name, &oid);
1275 }
1276 }
1277 }
1278 }
1279 break;
1280 case SNMP_PDU_SET:
1281 *pErrorStatus = SNMP_ERRORSTATUS_READONLY;
1282 ret = FALSE;
1283 break;
1284 default:
1285 FIXME("0x%02x: unsupported PDU type\n", bPduType);
1286 *pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
1287 }
1288 return ret;
1289}
1290
1291/* This list MUST BE lexicographically sorted */
1307};
1309
1310/*****************************************************************************
1311 * SnmpExtensionInit [INETMIB1.@]
1312 */
1314 HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion)
1315{
1317 UINT i;
1318
1319 TRACE("(%d, %p, %p)\n", dwUptimeReference, phSubagentTrapEvent,
1320 pFirstSupportedRegion);
1321
1323 for (i = 0; i < ARRAY_SIZE(supportedIDs); i++)
1324 {
1325 if (supportedIDs[i].init)
1326 supportedIDs[i].init();
1327 if (supportedIDs[i].name.idLength < minSupportedIDLength)
1328 minSupportedIDLength = supportedIDs[i].name.idLength;
1329 }
1330 *phSubagentTrapEvent = NULL;
1331 SnmpUtilOidCpy(pFirstSupportedRegion, &myOid);
1332 return TRUE;
1333}
1334
1335static void cleanup(void)
1336{
1337 UINT i;
1338
1339 for (i = 0; i < ARRAY_SIZE(supportedIDs); i++)
1340 if (supportedIDs[i].cleanup)
1341 supportedIDs[i].cleanup();
1342}
1343
1345 UINT *matchingIndex)
1346{
1347 int indexHigh = DEFINE_SIZEOF(supportedIDs) - 1, indexLow = 0;
1348 AsnObjectIdentifier oid1 = { idLength, ids};
1349
1350 if (!idLength)
1351 return NULL;
1352
1353 while (indexLow <= indexHigh)
1354 {
1355 INT cmp, i = (indexLow + indexHigh) / 2;
1356 if (!(cmp = SnmpUtilOidNCmp(&oid1, &supportedIDs[i].name, idLength)))
1357 {
1358 *matchingIndex = i;
1359 return &supportedIDs[i];
1360 }
1361 if (cmp > 0)
1362 indexLow = i + 1;
1363 else
1364 indexHigh = i - 1;
1365 }
1366 return NULL;
1367}
1368
1369/*****************************************************************************
1370 * SnmpExtensionQuery [INETMIB1.@]
1371 */
1373 AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex)
1374{
1377 UINT i;
1378 BOOL ret = TRUE;
1379
1380 TRACE("(0x%02x, %p, %p, %p)\n", bPduType, pVarBindList,
1381 pErrorStatus, pErrorIndex);
1382
1383 for (i = 0; !error && i < pVarBindList->len; i++)
1384 {
1385 /* Ignore any OIDs not in MIB2 */
1386 if (!SnmpUtilOidNCmp(&pVarBindList->list[i].name, &mib2oid,
1387 mib2oid.idLength))
1388 {
1389 struct mibImplementation *impl = NULL;
1390 UINT len, matchingIndex = 0;
1391
1392 TRACE("%s\n", SnmpUtilOidToA(&pVarBindList->list[i].name));
1393 /* Search for an implementation matching as many octets as possible
1394 */
1395 for (len = pVarBindList->list[i].name.idLength;
1396 len >= minSupportedIDLength && !impl; len--)
1397 impl = findSupportedQuery(pVarBindList->list[i].name.ids, len,
1398 &matchingIndex);
1399 if (impl && impl->query)
1400 ret = impl->query(bPduType, &pVarBindList->list[i], &error);
1401 else
1404 bPduType == SNMP_PDU_GETNEXT)
1405 {
1406 /* GetNext is special: it finds the successor to the given OID,
1407 * so we have to continue until an implementation handles the
1408 * query or we exhaust the table of supported OIDs.
1409 */
1410 for (matchingIndex++; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
1411 matchingIndex < DEFINE_SIZEOF(supportedIDs);
1412 matchingIndex++)
1413 {
1415 impl = &supportedIDs[matchingIndex];
1416 if (impl->query)
1417 ret = impl->query(bPduType, &pVarBindList->list[i],
1418 &error);
1419 else
1421 }
1422 /* If the query still isn't resolved, set the OID to the
1423 * successor to the last entry in the table.
1424 */
1426 {
1427 SnmpUtilOidFree(&pVarBindList->list[i].name);
1428 ret = SnmpUtilOidCpy(&pVarBindList->list[i].name,
1429 &supportedIDs[matchingIndex - 1].name);
1430 pVarBindList->list[i].name.ids[
1431 pVarBindList->list[i].name.idLength - 1] += 1;
1432 }
1433 }
1434 if (error)
1435 errorIndex = i + 1;
1436 }
1437 }
1438 *pErrorStatus = error;
1439 *pErrorIndex = errorIndex;
1440 return ret;
1441}
1442
1443/*****************************************************************************
1444 * DllMain [INETMIB1.@]
1445 */
1447{
1448 TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
1449
1450 switch (fdwReason)
1451 {
1452 case DLL_PROCESS_ATTACH:
1453 DisableThreadLibraryCalls(hinstDLL);
1454 break;
1455 case DLL_PROCESS_DETACH:
1456 if (lpvReserved) break;
1457 cleanup();
1458 break;
1459 }
1460
1461 return TRUE;
1462}
#define compare
#define __cdecl
Definition: accygwin.h:79
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: precomp.h:53
Definition: _map.h:48
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
Definition: main.c:26
static HINSTANCE instance
Definition: main.c:40
int id
Definition: main.c:4925
#define GetProcessHeap()
Definition: compat.h:736
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
void(* oidToKeyFunc)(AsnObjectIdentifier *oid, void *dst)
Definition: main.c:320
static UINT findOidInTable(AsnObjectIdentifier *oid, struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey, compareFunc compare)
Definition: main.c:343
static void oidToIpAddrRow(AsnObjectIdentifier *oid, void *dst)
Definition: main.c:765
static AsnInteger32 getItemAndInstanceFromTable(AsnObjectIdentifier *oid, AsnObjectIdentifier *base, UINT instanceLen, BYTE bPduType, struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey, compareFunc compare, UINT *item, UINT *instance)
Definition: main.c:410
static void mib2IpRouteCleanup(void)
Definition: main.c:853
static AsnInteger32 getItemFromOid(AsnObjectIdentifier *oid, AsnObjectIdentifier *base, BYTE bPduType, UINT *item)
Definition: main.c:262
static AsnInteger32 getItemAndIntegerInstanceFromOid(AsnObjectIdentifier *oid, AsnObjectIdentifier *base, BYTE bPduType, UINT *item, UINT *instance)
Definition: main.c:196
static UINT minSupportedIDLength
Definition: main.c:1308
static void mib2UdpEntryCleanup(void)
Definition: main.c:1204
static void mib2IpStatsInit(void)
Definition: main.c:668
static struct structToAsnValue mib2IpNetMap[]
Definition: main.c:925
static BOOL mib2IcmpQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:1039
static UINT mib2Tcp[]
Definition: main.c:1075
static UINT mib2IfEntry[]
Definition: main.c:607
static void mib2IpRouteInit(void)
Definition: main.c:838
static DWORD copyOperStatus(AsnAny *value, void *src)
Definition: main.c:167
static BOOL mib2TcpQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:1101
static DWORD copyInt(AsnAny *value, void *src)
Definition: main.c:37
static INT setOidWithItemAndIpAddr(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, UINT item, DWORD addr)
Definition: main.c:511
static void mib2IfNumberCleanup(void)
Definition: main.c:115
static void mib2IpNetInit(void)
Definition: main.c:932
static int __cdecl compareUdpRow(const void *a, const void *b)
Definition: main.c:1223
static UINT mib2[]
Definition: main.c:83
static void mib2UdpEntryInit(void)
Definition: main.c:1189
static void mib2IfNumberInit(void)
Definition: main.c:100
static struct structToAsnValue mib2TcpMap[]
Definition: main.c:1083
static void mib2UdpInit(void)
Definition: main.c:1139
static struct structToAsnValue mib2IfEntryMap[]
Definition: main.c:583
static UINT mib2IpNet[]
Definition: main.c:913
BOOL WINAPI SnmpExtensionInit(DWORD dwUptimeReference, HANDLE *phSubagentTrapEvent, AsnObjectIdentifier *pFirstSupportedRegion)
Definition: main.c:1313
static PMIB_IPNETTABLE ipNetTable
Definition: main.c:914
static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:609
static void oidToIpForwardRow(AsnObjectIdentifier *oid, void *dst)
Definition: main.c:858
static struct mibImplementation supportedIDs[]
Definition: main.c:1292
int(__cdecl * compareFunc)(const void *key, const void *value)
Definition: main.c:321
static MIB_UDPSTATS udpStats
Definition: main.c:1137
static void cleanup(void)
Definition: main.c:1335
static PMIB_IFTABLE ifTable
Definition: main.c:98
static UINT findNextOidInTable(AsnObjectIdentifier *oid, struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey, compareFunc compare)
Definition: main.c:365
static int __cdecl compareIpForwardRow(const void *a, const void *b)
Definition: main.c:865
static UINT mib2Udp[]
Definition: main.c:1136
static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:120
static BOOL mib2IpNetQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:952
static struct structToAsnValue mib2IpMap[]
Definition: main.c:673
static MIB_IPSTATS ipStats
Definition: main.c:666
static PMIB_IPFORWARDTABLE ipRouteTable
Definition: main.c:821
static INT setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, UINT item)
Definition: main.c:492
static INT setOidWithItemAndInteger(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, UINT item, UINT instance)
Definition: main.c:534
static void setStringValue(AsnAny *value, BYTE type, DWORD len, BYTE *str)
Definition: main.c:44
static struct structToAsnValue mib2IpRouteMap[]
Definition: main.c:823
static UINT mib2IpRoute[]
Definition: main.c:820
static void mib2TcpInit(void)
Definition: main.c:1078
static struct mibImplementation * findSupportedQuery(UINT *ids, UINT idLength, UINT *matchingIndex)
Definition: main.c:1344
static DWORD copyIfRowDescr(AsnAny *value, void *src)
Definition: main.c:550
static struct structToAsnValue mib2UdpMap[]
Definition: main.c:1144
static struct structToAsnValue mib2IpAddrMap[]
Definition: main.c:737
DWORD(* copyValueFunc)(AsnAny *value, void *src)
Definition: main.c:55
static void mib2IpNetCleanup(void)
Definition: main.c:947
static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:779
static UINT findValueInTable(const void *key, struct GenericTable *table, size_t tableEntrySize, compareFunc compare)
Definition: main.c:326
static UINT mib2System[]
Definition: main.c:84
static DWORD copyIfRowPhysAddr(AsnAny *value, void *src)
Definition: main.c:566
static UINT mib2Ip[]
Definition: main.c:665
static BOOL mib2UdpEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:1234
static MIB_ICMP icmpStats
Definition: main.c:1003
static void oidToUdpRow(AsnObjectIdentifier *oid, void *dst)
Definition: main.c:1214
static UINT mib2UdpEntry[]
Definition: main.c:1186
static BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:872
static PMIB_UDPTABLE udpTable
Definition: main.c:1187
static DWORD copyIpAddr(AsnAny *value, void *src)
Definition: main.c:77
static int __cdecl compareIpAddrRow(const void *a, const void *b)
Definition: main.c:772
BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList, AsnInteger32 *pErrorStatus, AsnInteger32 *pErrorIndex)
Definition: main.c:1372
static UINT mib2IfNumber[]
Definition: main.c:97
static PMIB_IPADDRTABLE ipAddrTable
Definition: main.c:735
static struct structToAsnValue mib2UdpEntryMap[]
Definition: main.c:1209
static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:699
static AsnInteger32 mapStructEntryToValue(struct structToAsnValue *map, UINT mapLen, void *record, UINT id, SnmpVarBind *pVarBind)
Definition: main.c:63
static void mib2IpAddrCleanup(void)
Definition: main.c:760
static struct structToAsnValue mib2IcmpMap[]
Definition: main.c:1010
static MIB_TCPSTATS tcpStats
Definition: main.c:1076
static DWORD oidToIpAddr(AsnObjectIdentifier *oid)
Definition: main.c:312
static DWORD copyIpNetPhysAddr(AsnAny *value, void *src)
Definition: main.c:916
BOOL(* varqueryfunc)(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:86
static UINT mib2IpAddr[]
Definition: main.c:734
static void mib2IpAddrInit(void)
Definition: main.c:745
static BOOL mib2UdpQuery(BYTE bPduType, SnmpVarBind *pVarBind, AsnInteger32 *pErrorStatus)
Definition: main.c:1151
static void mib2IcmpInit(void)
Definition: main.c:1005
static UINT mib2Icmp[]
Definition: main.c:1002
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
INT WINAPI SnmpUtilOidAppend(AsnObjectIdentifier *dst, AsnObjectIdentifier *src)
Definition: main.c:289
INT WINAPI SnmpUtilOidNCmp(AsnObjectIdentifier *oid1, AsnObjectIdentifier *oid2, UINT count)
Definition: main.c:358
INT WINAPI SnmpUtilAsnAnyCpy(AsnAny *dst, AsnAny *src)
Definition: main.c:197
VOID WINAPI SnmpUtilOidFree(AsnObjectIdentifier *oid)
Definition: main.c:344
INT WINAPI SnmpUtilOidCpy(AsnObjectIdentifier *dst, AsnObjectIdentifier *src)
Definition: main.c:319
LPSTR WINAPI SnmpUtilOidToA(AsnObjectIdentifier *oid)
Definition: main.c:534
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint * ids
Definition: glext.h:5907
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLenum dst
Definition: glext.h:6340
GLenum const GLvoid * addr
Definition: glext.h:9621
GLdouble GLdouble u2
Definition: glext.h:8308
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLdouble u1
Definition: glext.h:8308
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
struct _MIB_IFROW * PMIB_IFROW
#define UINT_MAX
Definition: limits.h:41
DWORD WINAPI GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSize, BOOL bOrder)
DWORD WINAPI GetIpStatistics(PMIB_IPSTATS pStats)
DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOrder)
DWORD WINAPI GetIcmpStatistics(PMIB_ICMP pStats)
DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats)
DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder)
DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS pStats)
DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
#define MIB_IF_ADMIN_STATUS_TESTING
Definition: ipifcons.h:234
#define MIB_IF_ADMIN_STATUS_UP
Definition: ipifcons.h:232
#define MIB_IF_OPER_STATUS_CONNECTED
Definition: ipifcons.h:250
#define MIB_IF_OPER_STATUS_CONNECTING
Definition: ipifcons.h:249
#define MIB_IF_ADMIN_STATUS_DOWN
Definition: ipifcons.h:233
#define MIB_IF_OPER_STATUS_OPERATIONAL
Definition: ipifcons.h:251
struct _MIB_IPNETROW * PMIB_IPNETROW
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
static IN DWORD IN LPVOID lpvReserved
#define error(str)
Definition: mkdosfs.c:1605
static PVOID ptr
Definition: dispmode.c:27
static char oid1[]
Definition: encode.c:7583
#define cmp(status, error)
Definition: error.c:114
static ATOM item
Definition: dde.c:856
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
const WCHAR * str
#define ASN_OCTETSTRING
Definition: snmp.h:105
#define SNMP_ERRORSTATUS_READONLY
Definition: snmp.h:137
#define DEFINE_OID(x)
Definition: snmp.h:180
#define SNMP_PDU_GET
Definition: snmp.h:94
#define SNMP_ERRORSTATUS_NOSUCHNAME
Definition: snmp.h:135
#define SNMP_PDU_SET
Definition: snmp.h:97
#define SNMP_PDU_GETNEXT
Definition: snmp.h:95
LONG AsnInteger32
Definition: snmp.h:40
#define SNMP_ERRORSTATUS_NOERROR
Definition: snmp.h:133
#define ASN_INTEGER
Definition: snmp.h:103
#define DEFINE_SIZEOF(x)
Definition: snmp.h:179
#define ASN_IPADDRESS
Definition: snmp.h:113
#define TRACE(s)
Definition: solgame.cpp:4
Definition: snmp.h:54
BYTE asnType
Definition: snmp.h:55
union AsnAny::@3228 asnValue
AsnOctetString string
Definition: snmp.h:60
UINT * ids
Definition: snmp.h:37
BOOL dynamic
Definition: snmp.h:32
UINT length
Definition: snmp.h:31
BYTE * stream
Definition: snmp.h:30
DWORD numEntries
Definition: main.c:308
BYTE entries[1]
Definition: main.c:309
SnmpVarBind * list
Definition: snmp.h:81
UINT len
Definition: snmp.h:82
AsnObjectName name
Definition: snmp.h:76
AsnObjectSyntax value
Definition: snmp.h:77
MIB_IFROW table[1]
Definition: ifmib.h:66
DWORD dwNumEntries
Definition: ifmib.h:65
DWORD dwAddr
Definition: ipmib.h:36
MIB_IPADDRROW table[1]
Definition: ipmib.h:48
DWORD dwForwardProto
Definition: ipmib.h:83
DWORD dwForwardDest
Definition: ipmib.h:71
DWORD dwForwardType
Definition: ipmib.h:78
MIB_IPFORWARDROW table[1]
Definition: ipmib.h:98
DWORD dwNumEntries
Definition: ipmib.h:127
DWORD dwLocalAddr
Definition: udpmib.h:28
DWORD dwLocalPort
Definition: udpmib.h:29
MIB_UDPROW table[1]
Definition: udpmib.h:35
Definition: bug.cpp:8
Definition: copy.c:22
void(* cleanup)(void)
Definition: main.c:94
void(* init)(void)
Definition: main.c:92
AsnObjectIdentifier name
Definition: main.c:91
varqueryfunc query
Definition: main.c:93
Definition: name.c:39
copyValueFunc copy
Definition: main.c:60
size_t offset
Definition: main.c:59
#define bsearch
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
Definition: pdh_main.c:94
int ret
#define WINAPI
Definition: msvc.h:6
static int init
Definition: wintirpc.c:33
unsigned char BYTE
Definition: xxhash.c:193