|
|
1.1 root 1: /*++ BUILD Version: 0001 // Increment this if a change has global effects
2:
3: Copyright (c) 1991 Microsoft Corporation
4:
5: Module Name:
6:
7: snmputil.c
8:
9: Abstract:
10:
11: Sample SNMP Management API usage for Windows NT.
12:
13: This file is an example of how to code management applications using
14: the SNMP Management API for Windows NT. It is similar in operation to
15: the other commonly available SNMP command line utilities.
16:
17: Extensive comments have been included to describe its structure and
18: operation. See also "Microsoft Windows/NT SNMP Programmer's Reference".
19:
20: Created:
21:
22: 28-Jun-1991
23:
24: Revision History:
25:
26: --*/
27:
28:
29: static char *vcsid = "@(#) $Logfile: N:/agent/mgmtapi/vcs/snmputil.c_v $ $Revision: 1.5 $";
30:
31:
32: // General notes:
33: // Microsoft's SNMP Management API for Windows NT is implemented as a DLL
34: // that is linked with the developer's code. These APIs (examples follow in
35: // this file) allow the developer's code to generate SNMP queries and receive
36: // SNMP traps. A simple MIB compiler and related APIs are also available to
37: // allow conversions between OBJECT IDENTIFIERS and OBJECT DESCRIPTORS.
38:
39:
40: // Necessary includes.
41:
42: #include <windows.h>
43:
44: #include <stdio.h>
45: #include <string.h>
46: #include <malloc.h>
47:
48: #include <snmp.h>
49: #include <mgmtapi.h>
50:
51:
52: // Constants used in this example.
53:
54: #define GET 1
55: #define GETNEXT 2
56: #define WALK 3
57: #define TRAP 4
58:
59: #define TIMEOUT 6000 /* milliseconds */
60: #define RETRIES 3
61:
62:
63: // Main program.
64:
65: INT _CRTAPI1 main(
66: IN int argumentCount,
67: IN char *argumentVector[])
68: {
69: INT operation;
70: LPSTR agent;
71: LPSTR community;
72: RFC1157VarBindList variableBindings;
73: LPSNMP_MGR_SESSION session;
74:
75: INT timeout = TIMEOUT;
76: INT retries = RETRIES;
77:
78: BYTE requestType;
79: AsnInteger requestId;
80: AsnInteger errorStatus;
81: AsnInteger errorIndex;
82:
83:
84: // Parse command line arguments to determine requested operation.
85:
86: // Verify number of arguments...
87: if (argumentCount < 5 && argumentCount != 2)
88: {
89: printf("Error: Incorrect number of arguments specified.\n");
90: printf(
91: "\nusage: snmputil [get|getnext|walk] agent community oid [oid ...]\n");
92: printf(
93: " snmputil trap\n");
94:
95: return 1;
96: }
97:
98: // Get/verify operation...
99: argumentVector++;
100: argumentCount--;
101: if (!strcmp(*argumentVector, "get"))
102: operation = GET;
103: else if (!strcmp(*argumentVector, "getnext"))
104: operation = GETNEXT;
105: else if (!strcmp(*argumentVector, "walk"))
106: operation = WALK;
107: else if (!strcmp(*argumentVector, "trap"))
108: operation = TRAP;
109: else
110: {
111: printf("Error: Invalid operation, '%s', specified.\n",
112: *argumentVector);
113:
114: return 1;
115: }
116:
117: if (operation != TRAP)
118: {
119: if (argumentCount < 4)
120: {
121: printf("Error: Incorrect number of arguments specified.\n");
122: printf(
123: "\nusage: snmputil [get|getnext|walk] agent community oid [oid ...]\n");
124: printf(
125: " snmputil trap\n");
126:
127: return 1;
128: }
129:
130: // Get agent address...
131: argumentVector++;
132: argumentCount--;
133: agent = (LPSTR)malloc(strlen(*argumentVector) + 1);
134: strcpy(agent, *argumentVector);
135:
136: // Get agent community...
137: argumentVector++;
138: argumentCount--;
139: community = (LPSTR)malloc(strlen(*argumentVector) + 1);
140: strcpy(community, *argumentVector);
141:
142: // Get oid's...
143: variableBindings.list = NULL;
144: variableBindings.len = 0;
145:
146: while(--argumentCount)
147: {
148: AsnObjectIdentifier reqObject;
149:
150: argumentVector++;
151:
152: // Convert the string representation to an internal representation.
153: if (!SnmpMgrStrToOid(*argumentVector, &reqObject))
154: {
155: printf("Error: Invalid oid, %s, specified.\n", *argumentVector);
156:
157: return 1;
158: }
159: else
160: {
161: // Since sucessfull, add to the variable bindings list.
162: variableBindings.len++;
163: if ((variableBindings.list = (RFC1157VarBind *)realloc(
164: variableBindings.list, sizeof(RFC1157VarBind) *
165: variableBindings.len)) == NULL)
166: {
167: printf("Error: Error allocating oid, %s.\n",
168: *argumentVector);
169:
170: return 1;
171: }
172:
173: variableBindings.list[variableBindings.len - 1].name =
174: reqObject; // NOTE! structure copy
175: variableBindings.list[variableBindings.len - 1].value.asnType =
176: ASN_NULL;
177: }
178: } // end while()
179:
180: // Make sure only one variable binding was specified if operation
181: // is WALK.
182: if (operation == WALK && variableBindings.len != 1)
183: {
184: printf("Error: Multiple oids specified for WALK.\n");
185:
186: return 1;
187: }
188:
189:
190: // Establish a SNMP session to communicate with the remote agent. The
191: // community, communications timeout, and communications retry count
192: // for the session are also required.
193:
194: if ((session = SnmpMgrOpen(agent, community, timeout, retries)) == NULL)
195: {
196: printf("error on SnmpMgrOpen %d\n", GetLastError());
197:
198: return 1;
199: }
200:
201: } // end if(TRAP)
202:
203:
204: // Determine and perform the requested operation.
205:
206: if (operation == GET || operation == GETNEXT)
207: {
208: // Get and GetNext are relatively simple operations to perform.
209: // Simply initiate the request and process the result and/or
210: // possible error conditions.
211:
212:
213: if (operation == GET)
214: requestType = ASN_RFC1157_GETREQUEST;
215: else
216: requestType = ASN_RFC1157_GETNEXTREQUEST;
217:
218:
219: // Request that the API carry out the desired operation.
220:
221: if (!SnmpMgrRequest(session, requestType, &variableBindings,
222: &errorStatus, &errorIndex))
223: {
224: // The API is indicating an error.
225:
226: printf("error on SnmpMgrRequest %d\n", GetLastError());
227: }
228: else
229: {
230: // The API succeeded, errors may be indicated from the remote
231: // agent.
232:
233: if (errorStatus > 0)
234: {
235: printf("Error: errorStatus=%d, errorIndex=%d\n",
236: errorStatus, errorIndex);
237: }
238: else
239: {
240: // Display the resulting variable bindings.
241:
242: UINT i;
243: char *string = NULL;
244:
245: for(i=0; i < variableBindings.len; i++)
246: {
247: SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
248: printf("Variable = %s\n", string);
249: if (string) free(string);
250:
251: printf("Value = ");
252: SnmpUtilPrintAsnAny(&variableBindings.list[i].value);
253:
254: printf("\n");
255: } // end for()
256: }
257: }
258:
259:
260: // Free the variable bindings that have been allocated.
261:
262: SnmpUtilVarBindListFree(&variableBindings);
263:
264:
265: }
266: else if (operation == WALK)
267: {
268: // Walk is a common term used to indicate that all MIB variables
269: // under a given OID are to be traversed and displayed. This is
270: // a more complex operation requiring tests and looping in addition
271: // to the steps for get/getnext above.
272:
273:
274: AsnObjectIdentifier root;
275: AsnObjectIdentifier tempOid;
276:
277:
278: SnmpUtilOidCpy(&root, &variableBindings.list[0].name);
279:
280: requestType = ASN_RFC1157_GETNEXTREQUEST;
281:
282:
283: while(1)
284: {
285: if (!SnmpMgrRequest(session, requestType, &variableBindings,
286: &errorStatus, &errorIndex))
287: {
288: // The API is indicating an error.
289:
290: printf("error on SnmpMgrRequest %d\n", GetLastError());
291:
292: break;
293: }
294: else
295: {
296: // The API succeeded, errors may be indicated from the remote
297: // agent.
298:
299:
300: // Test for end of subtree or end of MIB.
301:
302: if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
303: SnmpUtilOidNCmp(&variableBindings.list[0].name,
304: &root, root.idLength))
305: {
306: printf("End of MIB subtree.\n\n");
307:
308: break;
309: }
310:
311:
312: // Test for general error conditions or sucesss.
313:
314: if (errorStatus > 0)
315: {
316: printf("Error: errorStatus=%d, errorIndex=%d \n",
317: errorStatus, errorIndex);
318:
319: break;
320: }
321: else
322: {
323: // Display resulting variable binding for this iteration.
324:
325: char *string = NULL;
326:
327: SnmpMgrOidToStr(&variableBindings.list[0].name, &string);
328: printf("Variable = %s\n", string);
329: if (string) free(string);
330:
331: printf("Value = ");
332: SnmpUtilPrintAsnAny(&variableBindings.list[0].value);
333:
334: printf("\n");
335: }
336: } // end if()
337:
338:
339: // Prepare for the next iteration. Make sure returned oid is
340: // preserved and the returned value is freed.
341:
342: SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name);
343:
344: SnmpUtilVarBindFree(&variableBindings.list[0]);
345:
346: SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid);
347: variableBindings.list[0].value.asnType = ASN_NULL;
348:
349: SnmpUtilOidFree(&tempOid);
350:
351: } // end while()
352:
353:
354: // Free the variable bindings that have been allocated.
355:
356: SnmpUtilVarBindListFree(&variableBindings);
357:
358: SnmpUtilOidFree(&root);
359:
360:
361: }
362: else if (operation == TRAP)
363: {
364: // Trap handling can be done two different ways: event driven or
365: // polled. The following code illustrates the steps to use event
366: // driven trap reception in a management application.
367:
368:
369: HANDLE hNewTraps = NULL;
370:
371:
372: if (!SnmpMgrTrapListen(&hNewTraps))
373: {
374: printf("error on SnmpMgrTrapListen %d\n", GetLastError());
375: }
376: else
377: {
378: printf("snmputil: listening for traps...\n");
379: }
380:
381:
382: while(1)
383: {
384: DWORD dwResult;
385:
386: if ((dwResult = WaitForSingleObject(hNewTraps, 0xffffffff))
387: == 0xffffffff)
388: {
389: printf("error on WaitForSingleObject %d\n",
390: GetLastError());
391: }
392: else if (!ResetEvent(hNewTraps))
393: {
394: printf("error on ResetEvent %d\n", GetLastError());
395: }
396: else
397: {
398: AsnObjectIdentifier enterprise;
399: AsnNetworkAddress IPAddress;
400: AsnInteger genericTrap;
401: AsnInteger specificTrap;
402: AsnTimeticks timeStamp;
403: RFC1157VarBindList variableBindings;
404:
405: UINT i;
406: char *string = NULL;
407:
408: while(SnmpMgrGetTrap(&enterprise, &IPAddress, &genericTrap,
409: &specificTrap, &timeStamp, &variableBindings))
410: {
411: printf("snmputil: trap generic=%d specific=%d\n",
412: genericTrap, specificTrap);
413: if (IPAddress.length == 4) {
414: printf(" from -> %d.%d.%d.%d\n",
415: (int)IPAddress.stream[0], (int)IPAddress.stream[1],
416: (int)IPAddress.stream[2], (int)IPAddress.stream[3]);
417:
418: }
419: if (IPAddress.dynamic) {
420: SNMP_free(IPAddress.stream);
421: }
422:
423: for(i=0; i < variableBindings.len; i++)
424: {
425: SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
426: printf("Variable = %s\n", string);
427: if (string) free(string);
428:
429: printf("Value = ");
430: SnmpUtilPrintAsnAny(&variableBindings.list[i].value);
431: } // end for()
432: printf("\n");
433:
434:
435: SnmpUtilOidFree(&enterprise);
436:
437: SnmpUtilVarBindListFree(&variableBindings);
438: }
439: }
440: } // end while()
441:
442:
443: } // end if(operation)
444:
445:
446: if (operation != TRAP)
447: {
448: // Close SNMP session with the remote agent.
449:
450: if (!SnmpMgrClose(session))
451: {
452: printf("error on SnmpMgrClose %d\n", GetLastError());
453:
454: return 1;
455: }
456: }
457:
458:
459: // Let the command interpreter know things went ok.
460:
461: return 0;
462:
463: } // end main()
464:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.