snmptest.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:17k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * snmptest.c - send snmp requests to a network entity.
  3.  *
  4.  * Usage: snmptest -v 1 [-q] hostname community [objectID]
  5.  *
  6.  */
  7. /***********************************************************************
  8. Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
  9.                       All Rights Reserved
  10. Permission to use, copy, modify, and distribute this software and its
  11. documentation for any purpose and without fee is hereby granted,
  12. provided that the above copyright notice appear in all copies and that
  13. both that copyright notice and this permission notice appear in
  14. supporting documentation, and that the name of CMU not be
  15. used in advertising or publicity pertaining to distribution of the
  16. software without specific, written prior permission.
  17. CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  18. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  19. CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  20. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  22. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23. SOFTWARE.
  24. ******************************************************************/
  25. #include <net-snmp/net-snmp-config.h>
  26. #if HAVE_STDLIB_H
  27. #include <stdlib.h>
  28. #endif
  29. #if HAVE_UNISTD_H
  30. #include <unistd.h>
  31. #endif
  32. #if HAVE_STRING_H
  33. #include <string.h>
  34. #else
  35. #include <strings.h>
  36. #endif
  37. #include <sys/types.h>
  38. #if HAVE_NETINET_IN_H
  39. #include <netinet/in.h>
  40. #endif
  41. #include <stdio.h>
  42. #include <ctype.h>
  43. #if TIME_WITH_SYS_TIME
  44. # ifdef WIN32
  45. #  include <sys/timeb.h>
  46. # else
  47. #  include <sys/time.h>
  48. # endif
  49. # include <time.h>
  50. #else
  51. # if HAVE_SYS_TIME_H
  52. #  include <sys/time.h>
  53. # else
  54. #  include <time.h>
  55. # endif
  56. #endif
  57. #if HAVE_SYS_SELECT_H
  58. #include <sys/select.h>
  59. #endif
  60. #if HAVE_WINSOCK_H
  61. #include <winsock.h>
  62. #endif
  63. #if HAVE_NETDB_H
  64. #include <netdb.h>
  65. #endif
  66. #if HAVE_ARPA_INET_H
  67. #include <arpa/inet.h>
  68. #endif
  69. #include <net-snmp/net-snmp-includes.h>
  70. int             command = SNMP_MSG_GET;
  71. int             input_variable(netsnmp_variable_list *);
  72. void
  73. usage(void)
  74. {
  75.     fprintf(stderr, "USAGE: snmptest ");
  76.     snmp_parse_args_usage(stderr);
  77.     fprintf(stderr, "nn");
  78.     snmp_parse_args_descriptions(stderr);
  79. }
  80. int
  81. main(int argc, char *argv[])
  82. {
  83.     netsnmp_session session, *ss;
  84.     netsnmp_pdu    *pdu = NULL, *response, *copy = NULL;
  85.     netsnmp_variable_list *vars, *vp;
  86.     netsnmp_transport *transport = NULL;
  87.     int             ret;
  88.     int             status, count;
  89.     char            input[128];
  90.     int             varcount, nonRepeaters = -1, maxRepetitions;
  91.     /*
  92.      * get the common command line arguments 
  93.      */
  94.     switch (snmp_parse_args(argc, argv, &session, NULL, NULL)) {
  95.     case -2:
  96.         exit(0);
  97.     case -1:
  98.         usage();
  99.         exit(1);
  100.     default:
  101.         break;
  102.     }
  103.     SOCK_STARTUP;
  104.     /*
  105.      * open an SNMP session 
  106.      */
  107.     ss = snmp_open(&session);
  108.     if (ss == NULL) {
  109.         /*
  110.          * diagnose snmp_open errors with the input netsnmp_session pointer 
  111.          */
  112.         snmp_sess_perror("snmptest", &session);
  113.         SOCK_CLEANUP;
  114.         exit(1);
  115.     }
  116.     varcount = 0;
  117.     while (1) {
  118.         vars = NULL;
  119.         for (ret = 1; ret != 0;) {
  120.             vp = (netsnmp_variable_list *)
  121.                 malloc(sizeof(netsnmp_variable_list));
  122.             memset(vp, 0, sizeof(netsnmp_variable_list));
  123.             while ((ret = input_variable(vp)) == -1);
  124.             if (ret == 1) {
  125.                 varcount++;
  126.                 /*
  127.                  * add it to the list 
  128.                  */
  129.                 if (vars == NULL) {
  130.                     /*
  131.                      * if first variable 
  132.                      */
  133.                     pdu = snmp_pdu_create(command);
  134.                     pdu->variables = vp;
  135.                 } else {
  136.                     vars->next_variable = vp;
  137.                 }
  138.                 vars = vp;
  139.             } else {
  140.                 /*
  141.                  * free the last (unused) variable 
  142.                  */
  143.                 if (vp->name)
  144.                     free((char *) vp->name);
  145.                 if (vp->val.string)
  146.                     free((char *) vp->val.string);
  147.                 free((char *) vp);
  148.                 if (command == SNMP_MSG_GETBULK) {
  149.                     if (nonRepeaters == -1) {
  150.                         nonRepeaters = varcount;
  151.                         ret = -1;       /* so we collect more variables */
  152.                         printf("Now input the repeating variablesn");
  153.                     } else {
  154.                         printf("What repeat count? ");
  155.                         fflush(stdout);
  156.                         fgets(input, sizeof(input), stdin);
  157.                         maxRepetitions = atoi(input);
  158.                         pdu->non_repeaters = nonRepeaters;
  159.                         pdu->max_repetitions = maxRepetitions;
  160.                     }
  161.                 }
  162.             }
  163.             if (varcount == 0 && ret == 0) {
  164.                 if (!copy) {
  165.                     printf("No PDU to send.n");
  166.                     ret = -1;
  167.                 } else {
  168.                     pdu = snmp_clone_pdu(copy);
  169.                     printf("Resending last PDU.n");
  170.                 }
  171.             }
  172.         }
  173.         copy = snmp_clone_pdu(pdu);
  174.         if (command == SNMP_MSG_TRAP2) {
  175.             /*
  176.              * No response needed 
  177.              */
  178.             if (!snmp_send(ss, pdu)) {
  179.                 snmp_free_pdu(pdu);
  180.                 snmp_sess_perror("snmptest", ss);
  181.             }
  182.         } else {
  183.             status = snmp_synch_response(ss, pdu, &response);
  184.             if (status == STAT_SUCCESS) {
  185.                 if (command == SNMP_MSG_INFORM &&
  186.                     response->errstat == SNMP_ERR_NOERROR) {
  187.                     printf("Inform Acknowledgedn");
  188.                 } else {
  189.                     switch (response->command) {
  190.                     case SNMP_MSG_GET:
  191.                         printf("Received Get Request ");
  192.                         break;
  193.                     case SNMP_MSG_GETNEXT:
  194.                         printf("Received Getnext Request ");
  195.                         break;
  196.                     case SNMP_MSG_RESPONSE:
  197.                         printf("Received Get Response ");
  198.                         break;
  199.                     case SNMP_MSG_SET:
  200.                         printf("Received Set Request ");
  201.                         break;
  202.                     case SNMP_MSG_TRAP:
  203.                         printf("Received Trap Request ");
  204.                         break;
  205.                     case SNMP_MSG_GETBULK:
  206.                         printf("Received Bulk Request ");
  207.                         break;
  208.                     case SNMP_MSG_INFORM:
  209.                         printf("Received Inform Request ");
  210.                         break;
  211.                     case SNMP_MSG_TRAP2:
  212.                         printf("Received SNMPv2 Trap Request ");
  213.                         break;
  214.                     }
  215.                     transport = snmp_sess_transport(snmp_sess_pointer(ss));
  216.                     if (transport != NULL && transport->f_fmtaddr != NULL) {
  217.                         char *addr_string = transport->f_fmtaddr(transport,
  218.                                                                  response->
  219.                                                                  transport_data,
  220.                                                                  response->
  221.                                                                  transport_data_length);
  222.                         if (addr_string != NULL) {
  223.                             printf("from %sn", addr_string);
  224.                             free(addr_string);
  225.                         }
  226.                     } else {
  227.                         printf("from <UNKNOWN>n");
  228.                     }
  229.                     printf
  230.                         ("requestid 0x%lX errstat 0x%lX errindex 0x%lXn",
  231.                          response->reqid, response->errstat,
  232.                          response->errindex);
  233.                     if (response->errstat == SNMP_ERR_NOERROR) {
  234.                         for (vars = response->variables; vars;
  235.                              vars = vars->next_variable)
  236.                             print_variable(vars->name, vars->name_length,
  237.                                            vars);
  238.                     } else {
  239.                         printf("Error in packet.nReason: %sn",
  240.                                snmp_errstring(response->errstat));
  241.                         if (response->errindex != 0) {
  242.                             for (count = 1, vars = response->variables;
  243.                                  vars && count != response->errindex;
  244.                                  vars = vars->next_variable, count++);
  245.                             if (vars) {
  246.                                 printf("Failed object: ");
  247.                                 print_objid(vars->name, vars->name_length);
  248.                             }
  249.                             printf("n");
  250.                         }
  251.                     }
  252.                 }
  253.             } else if (status == STAT_TIMEOUT) {
  254.                 printf("Timeout: No Response from %sn", session.peername);
  255.             } else {            /* status == STAT_ERROR */
  256.                 snmp_sess_perror("snmptest", ss);
  257.             }
  258.             if (response)
  259.                 snmp_free_pdu(response);
  260.         }
  261.         varcount = 0;
  262.         nonRepeaters = -1;
  263.     }
  264.     SOCK_CLEANUP;
  265.     return 0;
  266. }
  267. int
  268. input_variable(netsnmp_variable_list * vp)
  269. {
  270.     char            buf[256];
  271.     size_t          val_len;
  272.     u_char          value[256], ch;
  273.     oid             name[MAX_OID_LEN];
  274.     printf("Variable: ");
  275.     fflush(stdout);
  276.     if (!fgets(buf, sizeof(buf), stdin)) {
  277.         printf("Quitting,  Goobyen");
  278.         SOCK_CLEANUP;
  279.         exit(0);
  280.     }
  281.     val_len = strlen(buf);
  282.     if (val_len == 0 || *buf == 'n') {
  283.         vp->name_length = 0;
  284.         return 0;
  285.     }
  286.     if (buf[val_len - 1] == 'n')
  287.         buf[--val_len] = 0;
  288.     if (*buf == '$') {
  289.         switch (toupper(buf[1])) {
  290.         case 'G':
  291.             command = SNMP_MSG_GET;
  292.             printf("Request type is Get Requestn");
  293.             break;
  294.         case 'N':
  295.             command = SNMP_MSG_GETNEXT;
  296.             printf("Request type is Getnext Requestn");
  297.             break;
  298.         case 'S':
  299.             command = SNMP_MSG_SET;
  300.             printf("Request type is Set Requestn");
  301.             break;
  302.         case 'B':
  303.             command = SNMP_MSG_GETBULK;
  304.             printf("Request type is Bulk Requestn");
  305.             printf
  306.                 ("Enter a blank line to terminate the list of non-repeatersn");
  307.             printf("and to begin the repeating variablesn");
  308.             break;
  309.         case 'I':
  310.             command = SNMP_MSG_INFORM;
  311.             printf("Request type is Inform Requestn");
  312.             printf("(Are you sending to the right port?)n");
  313.             break;
  314.         case 'T':
  315.             command = SNMP_MSG_TRAP2;
  316.             printf("Request type is SNMPv2 Trap Requestn");
  317.             printf("(Are you sending to the right port?)n");
  318.             break;
  319.         case 'D':
  320.             if (snmp_get_dump_packet()) {
  321.                 snmp_set_dump_packet(0);
  322.                 printf("Turned packet dump offn");
  323.             } else {
  324.                 snmp_set_dump_packet(1);
  325.                 printf("Turned packet dump onn");
  326.             }
  327.             break;
  328.         case 'Q':
  329.             switch ((toupper(buf[2]))) {
  330.             case 'n':
  331.             case 0:
  332.                 printf("Quitting,  Goodbyen");
  333.                 SOCK_CLEANUP;
  334.                 exit(0);
  335.                 break;
  336.             case 'P':
  337.                 if (snmp_get_quick_print()) {
  338.                     snmp_set_quick_print(0);
  339.                     printf("Turned quick printing offn");
  340.                 } else {
  341.                     snmp_set_quick_print(1);
  342.                     printf("Turned quick printing onn");
  343.                 }
  344.                 break;
  345.             }
  346.             break;
  347.         default:
  348.             printf("Bad commandn");
  349.         }
  350.         return -1;
  351.     }
  352.     vp->name_length = MAX_OID_LEN;
  353.     if (!snmp_parse_oid(buf, name, &vp->name_length)) {
  354.         snmp_perror(buf);
  355.         return -1;
  356.     }
  357.     vp->name = (oid *) malloc(vp->name_length * sizeof(oid));
  358.     memmove(vp->name, name, vp->name_length * sizeof(oid));
  359.     if (command == SNMP_MSG_SET || command == SNMP_MSG_INFORM
  360.         || command == SNMP_MSG_TRAP2) {
  361.         printf("Type [i|u|s|x|d|n|o|t|a]: ");
  362.         fflush(stdout);
  363.         fgets(buf, sizeof(buf), stdin);
  364.         ch = *buf;
  365.         switch (ch) {
  366.         case 'i':
  367.             vp->type = ASN_INTEGER;
  368.             break;
  369.         case 'u':
  370.             vp->type = ASN_UNSIGNED;
  371.             break;
  372.         case 's':
  373.             vp->type = ASN_OCTET_STR;
  374.             break;
  375.         case 'x':
  376.             vp->type = ASN_OCTET_STR;
  377.             break;
  378.         case 'd':
  379.             vp->type = ASN_OCTET_STR;
  380.             break;
  381.         case 'n':
  382.             vp->type = ASN_NULL;
  383.             break;
  384.         case 'o':
  385.             vp->type = ASN_OBJECT_ID;
  386.             break;
  387.         case 't':
  388.             vp->type = ASN_TIMETICKS;
  389.             break;
  390.         case 'a':
  391.             vp->type = ASN_IPADDRESS;
  392.             break;
  393.         default:
  394.             printf
  395.                 ("bad type "%c", use "i", "u", "s", "x", "d", "n", "o", "t", or "a".n",
  396.                  *buf);
  397.             return -1;
  398.         }
  399.       getValue:
  400.         printf("Value: ");
  401.         fflush(stdout);
  402.         fgets(buf, sizeof(buf), stdin);
  403.         switch (vp->type) {
  404.         case ASN_INTEGER:
  405.             vp->val.integer = (long *) malloc(sizeof(long));
  406.             *(vp->val.integer) = atoi(buf);
  407.             vp->val_len = sizeof(long);
  408.             break;
  409.         case ASN_UNSIGNED:
  410.             vp->val.integer = (long *) malloc(sizeof(long));
  411.             *(vp->val.integer) = strtoul(buf, NULL, 0);
  412.             vp->val_len = sizeof(long);
  413.             break;
  414.         case ASN_OCTET_STR:
  415.             if (ch == 'd') {
  416.                 size_t          buf_len = 256;
  417.                 val_len = 0;
  418.                 if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
  419.                     printf("malloc failuren");
  420.                     goto getValue;
  421.                 }
  422.                 if (!snmp_decimal_to_binary(&(vp->val.string), &buf_len,
  423.                                             &val_len, 1, buf)) {
  424.                     printf("Bad value or no sub-identifier > 255n");
  425.                     free(vp->val.string);
  426.                     goto getValue;
  427.                 }
  428.                 vp->val_len = val_len;
  429.             } else if (ch == 's') {
  430.                 /*
  431.                  * -1 to omit trailing newline  
  432.                  */
  433.                 vp->val.string = (u_char *) malloc(strlen(buf) - 1);
  434.                 if (vp->val.string == NULL) {
  435.                     printf("malloc failuren");
  436.                     goto getValue;
  437.                 }
  438.                 memcpy(vp->val.string, buf, strlen(buf) - 1);
  439.                 vp->val_len = strlen(buf) - 1;
  440.             } else if (ch == 'x') {
  441.                 size_t          buf_len = 256;
  442.                 val_len = 0;
  443.                 if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
  444.                     printf("malloc failuren");
  445.                     goto getValue;
  446.                 }
  447.                 if (!snmp_hex_to_binary(&(vp->val.string), &buf_len,
  448.                                         &val_len, 1, buf)) {
  449.                     printf("Bad value (need pairs of hex digits)n");
  450.                     free(vp->val.string);
  451.                     goto getValue;
  452.                 }
  453.                 vp->val_len = val_len;
  454.             }
  455.             break;
  456.         case ASN_NULL:
  457.             vp->val_len = 0;
  458.             vp->val.string = NULL;
  459.             break;
  460.         case ASN_OBJECT_ID:
  461.             if ('n' == buf[strlen(buf) - 1])
  462.                 buf[strlen(buf) - 1] = '';
  463.             vp->val_len = MAX_OID_LEN;;
  464.             read_objid(buf, (oid *) value, &vp->val_len);
  465.             vp->val_len *= sizeof(oid);
  466.             vp->val.objid = (oid *) malloc(vp->val_len);
  467.             memmove(vp->val.objid, value, vp->val_len);
  468.             break;
  469.         case ASN_TIMETICKS:
  470.             vp->val.integer = (long *) malloc(sizeof(long));
  471.             *(vp->val.integer) = atoi(buf);
  472.             vp->val_len = sizeof(long);
  473.             break;
  474.         case ASN_IPADDRESS:
  475.             vp->val.integer = (long *) malloc(sizeof(long));
  476.             *(vp->val.integer) = inet_addr(buf);
  477.             vp->val_len = sizeof(long);
  478.             break;
  479.         default:
  480.             printf("Internal errorn");
  481.             break;
  482.         }
  483.     } else {                    /* some form of get message */
  484.         vp->type = ASN_NULL;
  485.         vp->val_len = 0;
  486.     }
  487.     return 1;
  488. }