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