|
|
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.