home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 29 Fixes_o / 29-Fixes_o.zip / tcpcsd2.zip / BASECSD2.EXE / SAMPLES / SNMPSAMP / DPISAMPL.C next >
C/C++ Source or Header  |  1992-12-09  |  47KB  |  1,248 lines

  1. /*********************************************************************/
  2. /*                                                                   */
  3. /* SNMP-DPI - SNMP Distributed Programming Interface                 */
  4. /*                                                                   */
  5. /*   May 1991 - Version 1.0  - SNMP-DPI Version 1.0 (RFC1228)        */
  6. /*                             Created by IBM Research.              */
  7. /*   Feb 1992 - Version 1.1  - Allow enterpriseID to be passed with  */
  8. /*                             a (enterprise specific) trap          */
  9. /*                           - allow multiple variables to be passed */
  10. /*                           - Use 4 octets (INTEGER from RFC1157)   */
  11. /*                             for generic and specific type.        */
  12. /*   Jun 1992                - Make it run on OS/2 as well           */
  13. /*                             Note: dpisample = dpisampl on OS/2    */
  14. /*                                                                   */
  15. /* Copyright None                                                    */
  16. /*                                                                   */
  17. /* dpisample.c  - a sample SNMP-DPI subagent                         */
  18. /*              - can be used to test agent DPI implementations.     */
  19. /*                                                                   */
  20. /*  For testing with XGMON and/or SQESERV (SNMP Query Engine)        */
  21. /*  it is best to keep the following define for OID in sync          */
  22. /*  with the dpiSample objectID in the MIB description file          */
  23. /*  (mib_desc for XGMON, MIB_DESC DATA for SQESERV on VM and         */
  24. /*   MIB@DESC.DATA for SQESERV on MVS, MIB2TBL on OS/2).             */
  25. /*                                                                   */
  26. /*  See dpisample README file for more info.                         */
  27. /*                                                                   */
  28. /*********************************************************************/
  29.  
  30. #define OID                      "1.3.6.1.4.1.2.2.1.4."
  31. #define ENTERPRISE_OID           "1.3.6.1.4.1.2.2.1.4"  /* dpiSample */
  32. #define ifIndex                  "1.3.6.1.2.1.2.2.1.1.0"
  33. #define egpNeighAddr             "1.3.6.1.2.8.5.1.2.0"
  34. #define PUBLIC_COMMUNITY_NAME    "public"
  35.  
  36. #if defined(VM) || defined(MVS)
  37.  
  38. #define SNMPAGENTUSERID          "SNMPD"
  39. #define SNMPIUCVNAME             "SNMP_DPI"
  40. #pragma csect(CODE,  "$DPISAMP")
  41. #pragma csect(STATIC,"#DPISAMP")
  42. #include <manifest.h>            /* VM specific things */
  43. #include "snmpnms.h"             /* short external names for VM/MVS */
  44. #include "snmp_vm.h"             /* more of those short names */
  45. #include <saiucv.h>
  46. #include <bsdtime.h>
  47. #include <bsdtypes.h>
  48. #include <socket.h>
  49. #include <in.h>
  50. #include <netdb.h>
  51. #include <inet.h>
  52. extern char   ebcdicto[], asciitoe[];
  53. #pragma linkage(cmxlate,OS)
  54. #define DO_ETOA(a) cmxlate((a),ebcdictoascii,strlen((a)))
  55. #define DO_ATOE(a) cmxlate((a),asciitoebcdic,strlen((a)))
  56. #define DO_ERROR(a) tcperror((a))
  57. #define LOOPBACK "loopback"
  58. #define IUCV TRUE
  59. #define max(a,b) (((a) > (b)) ? (a) : (b))
  60. #define min(a,b) (((a) < (b)) ? (a) : (b))
  61.  
  62. #else  /* we are not on VM or MVS */
  63.  
  64. #ifdef OS2
  65. #include <stdlib.h>
  66. #include <types.h>
  67. #include <doscalls.h>
  68. #ifndef sleep
  69. #define sleep(a) DOSSLEEP(1000 * (a))
  70. #endif
  71. #define close soclose
  72. /*char * malloc(); */
  73. /*unsigned long strtoul(); */
  74. #endif
  75.  
  76. #include <sys/time.h>
  77. #include <sys/types.h>
  78. #include <sys/socket.h>
  79. #include <netinet/in.h>
  80. #include <netdb.h>
  81. // #include <arpa/inet.h>
  82. #define DO_ETOA(a) ;          /* no need for this */
  83. #define DO_ATOE(a) ;          /* no need for this */
  84. #define DO_ERROR(a) perror((a))
  85. #define LOOPBACK "localhost"
  86. #define IUCV FALSE
  87. #ifdef AIX221
  88. #define isdigit(c) (((c) >= '0') && ((c) <= '9'))
  89. #else
  90. // #include <sys/select.h>
  91. #endif /* AIX221 */
  92.  
  93. #endif /* defined(VM) || defined(MVS) */
  94.  
  95. #include <stdio.h>
  96. #ifdef OS2
  97. #include <dpi/snmp_dpi.h>
  98. #else
  99. #include "snmp_dpi.h"
  100. #endif
  101.  
  102. #define WAIT_FOR_AGENT 3   /* time to wait before closing agent fd */
  103.  
  104. #ifndef TRUE
  105. #define TRUE 1
  106. #define FALSE 0
  107. #endif
  108.  
  109. #ifdef _NO_PROTO                             /* for classic K&R C */
  110. static void check_arguments();
  111. static void send_packet();
  112. static void print_val();
  113. static void usage();
  114. static void init_connection();
  115. static void init_variables();
  116. static void await_and_read_packet();
  117. static void handle_packet();
  118. static void do_get();
  119. static void do_set();
  120. static void issue_traps();
  121. static void issue_one_trap();
  122. static void issue_one_trape();
  123. static void issue_std_traps();
  124. static void issue_ent_traps();
  125. static void issue_ent_trapse();
  126. static void do_register();
  127. static void dump_bfr();
  128. static struct dpi_set_packet *addtoset();
  129. extern unsigned long lookup_host();
  130.  
  131. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  132.  
  133. static void check_arguments(const int argc, char *argv[]);
  134. static void send_packet(const char * packet);
  135. static void print_val(const int index);
  136. static void usage(const char *progname, const int exit_rc);
  137. static void init_connection(void);
  138. static void init_variables(void);
  139. static void await_and_read_packet(void);
  140. static void handle_packet(void);
  141. static void do_get(void);
  142. static void do_set(void);
  143. static void issue_traps(void);
  144. static void issue_one_trap(void);
  145. static void issue_one_trape(void);
  146. static void issue_std_traps(void);
  147. static void issue_ent_traps(void);
  148. static void issue_ent_trapse(void);
  149. static void do_register(void);
  150. static void dump_bfr(const char *buf, const int len);
  151. static struct dpi_set_packet *addtoset(struct dpi_set_packet *data,
  152.                                        int stype);
  153. extern unsigned long lookup_host(const char *hostname);
  154.  
  155. #endif /* _NO_PROTO */
  156.  
  157. #define OSTRING              "hex01-04:"
  158. #define DSTRING              "Initial Display String"
  159. #define COMMAND              "None"
  160. #define BUFSIZE               4096
  161. #define TIMEOUT               3
  162. #define PACKET_LEN(packet)   (((unsigned char)*(packet)) * 256 + \
  163.                               ((unsigned char)*((packet) + 1)) + 2)
  164.  
  165. /* We have the following instances for OID.x variables */
  166.                                       /* 0 - table */
  167. static          long number      = 0; /* 1 - a number */
  168. static unsigned char *ostring    = 0; /* 2 - octet string */
  169. static          int  ostring_len = 0; /*     and its length */
  170. static unsigned char *objectID   = 0; /* 3 - objectID */
  171. static          int  objectID_len= 0; /*     and its length */
  172.                                       /* 4 - some empty variable */
  173. static unsigned long ipaddr      = 0; /* 5 - ipaddress */
  174. static unsigned long counter     = 1; /* 6 - a counter */
  175. static unsigned long gauge       = 1; /* 7 - a gauge */
  176. static unsigned long ticks       = 1; /* 8 - time ticks */
  177. static unsigned char *dstring    = 0; /* 9 - display string */
  178. static unsigned char *command    = 0; /* 10 - command */
  179.  
  180. static char *DPI_var[] = {
  181.    "dpiSample",
  182.    "dpiSampleNumber",
  183.    "dpiSampleOctetString",
  184.    "dpiSampleObjectID",
  185.    "dpiSampleEmpty",
  186.    "dpiSampleInetAddress",
  187.    "dpiSampleCounter",
  188.    "dpiSampleGauge",
  189.    "dpiSampleTimeTicks",
  190.    "dpiSampleDisplayString",
  191.    "dpiSampleCommand"
  192. };
  193.  
  194. static short int valid_types[] = { /* SNMP_TYPEs accepted on SET */
  195.         -1,                        /* 0 do not check type */
  196.         SNMP_TYPE_NUMBER,          /* 1 number */
  197.         SNMP_TYPE_STRING,          /* 2 octet string */
  198.         SNMP_TYPE_OBJECT,          /* 3 object identifier */
  199.         -1, /* SNMP_TYPE_EMPTY */  /* 4 do not check type */
  200.         SNMP_TYPE_INTERNET,        /* 5 internet address */
  201.         SNMP_TYPE_COUNTER,         /* 6 counter */
  202.         SNMP_TYPE_GAUGE,           /* 7 gauge */
  203.         SNMP_TYPE_TICKS,           /* 8 time ticks */
  204.         SNMP_TYPE_STRING,          /* 9 display string */
  205.         SNMP_TYPE_STRING           /* 10 command (display string) */
  206. #define OID_COUNT_FOR_TRAPS   9
  207. #define OID_COUNT             10
  208. };
  209.  
  210. static char         *packet = NULL;   /* ptr to send packet. */
  211. static char          inbuf[BUFSIZE];  /* buffer for receive packets */
  212. static int           dpi_fd;          /* fd for socket to DPI agent */
  213. static short int     dpi_port;        /* DPI_port at agent */
  214. static unsigned long dpi_ipaddress;   /* IP address of DPI agent */
  215. static char         *dpi_hostname;    /* hostname of DPI agent */
  216. static char         *dpi_userid;      /* userid of DPI agent VM/MVS */
  217. static char         *var_gid;         /* groupID received */
  218. static char         *var_oid;         /* objectID received */
  219. static int           var_index;       /* OID variable index */
  220. static unsigned char var_type;        /* SET value type */
  221. static char         *var_value;       /* SET value */
  222. static short int     var_value_len;   /* SET value length */
  223. static int           debug_lvl = 0;   /* current debug level */
  224. static int           use_iucv = IUCV; /* optional use of AF_IUCV */
  225. static int           do_quit  = FALSE;/* Quit in await loop */
  226. static int           trap_gtype = 0;  /* trap generic type */
  227. static int           trap_stype = 0;  /* trap specific type */
  228. static char         *trap_data = NULL;/* trap data */
  229. static int           do_trap  = 0;    /* switch for traps  */
  230. #define ONE_TRAP        1
  231. #define ONE_TRAPE       2
  232. #define STD_TRAPS       3
  233. #define ENT_TRAPS       4
  234. #define ENT_TRAPSE      5
  235. #define ALL_TRAPS       6
  236. #define MAX_TRAPE_DATA 10             /* data for extended trap */
  237. static long   trape_gtype = 6;        /* trap generic type */
  238. static long   trape_stype = 11;       /* trap specific type */
  239. static char  *trape_eprise = NULL;    /* enterprise id */
  240. static char  *trape_data[MAX_TRAPE_DATA]; /* pointers to data values */
  241. static int    trape_datacnt;          /* actual number of values */
  242.  
  243. #ifdef _NO_PROTO                      /* for classic K&R C */
  244. main(argc, argv)                      /* main line */
  245. int   argc;
  246. char *argv[];
  247. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  248. main(const int argc, char *argv[])    /* main line */
  249. #endif /* _NO_PROTO */
  250. {
  251.    check_arguments(argc, argv);       /* check callers arguments */
  252.    dpi_ipaddress = lookup_host(dpi_hostname); /* get ip address */
  253.    init_connection();                 /* connect to specified agent */
  254.    init_variables();                  /* initialize our variables */
  255.    if (do_trap) {                     /* we just need to do traps */
  256.       issue_traps();                  /* issue the trap(s) */
  257.       sleep(WAIT_FOR_AGENT);          /* sleep a bit, so agent can */
  258.       close(dpi_fd);                  /* read data before we close */
  259.       exit(0);                        /* and that's it */
  260.    }                                  /* end if (do_trap) */
  261.    do_register();                     /* register our objectIDs */
  262.    printf("%s ready and awaiting queries from agent\n",argv[0]);
  263.    while (do_quit == FALSE) {         /* forever until quit or error */
  264.       await_and_read_packet();        /* wait for next packet */
  265.       handle_packet();                /* handle it */
  266.       if (do_trap) issue_traps();     /* request to issue traps */
  267.    }                                  /* while loop */
  268.    sleep(WAIT_FOR_AGENT);             /* allow agent to read response */
  269.    printf("Quitting, %s set to: quit\n",DPI_var[10]);
  270.    exit(2);                           /* sampleDisplayString == quit */
  271. }
  272.  
  273. #ifdef _NO_PROTO                      /* for classic K&R C */
  274. static void issue_traps()
  275. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  276. static void issue_traps(void)
  277. #endif /* _NO_PROTO */
  278. {
  279.    switch (do_trap) {              /* let's see which one(s) */
  280.    case ONE_TRAP:                  /* only need to issue one trap */
  281.      issue_one_trap();             /* go issue the one trap */
  282.      break;
  283.    case ONE_TRAPE:                 /* only need to issue one trape */
  284.      issue_one_trape();            /* go issue the one trape */
  285.      break;
  286.    case STD_TRAPS:                 /* only need to issue std traps */
  287.      issue_std_traps();            /* standard traps gtypes 0-5 */
  288.      break;
  289.    case ENT_TRAPS:                 /* only need to issue ent traps */
  290.      issue_ent_traps();            /* enterprise specific traps */
  291.      break;
  292.    case ENT_TRAPSE:                /* only need to issue ent trapse */
  293.      issue_ent_trapse();           /* enterprise specific trapse */
  294.      break;
  295.    case ALL_TRAPS:                 /* only need to issue std traps */
  296.      issue_std_traps();            /* standard traps gtypes 0-5 */
  297.      issue_ent_traps();            /* enterprise specific traps */
  298.      issue_ent_trapse();           /* enterprise specific trapse */
  299.      break;
  300.    default:
  301.      break;
  302.    }                               /* end switch (do_trap) */
  303.    do_trap = 0;                    /* reset do_trap switch */
  304. }
  305.  
  306. #ifdef _NO_PROTO                             /* for classic K&R C */
  307. static void await_and_read_packet()    /* await packet from DPI agent */
  308. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  309. static void await_and_read_packet(void)/* await packet from DPI agent */
  310. #endif /* _NO_PROTO */
  311. {
  312.    int len, rc, bytes_to_read, bytes_read = 0;
  313. #ifdef OS2
  314.    int socks[5];
  315. #else
  316.    fd_set read_mask;
  317. #endif
  318.    struct timeval timeout;
  319.  
  320. #ifdef OS2
  321.    socks[0] = dpi_fd;
  322.    rc = select(socks, 1, 0, 0, -1L);
  323. #else
  324.    FD_ZERO(&read_mask);
  325.    FD_SET(dpi_fd, &read_mask);                    /* wait for data */
  326.    rc = select(dpi_fd+1, &read_mask, NULL, NULL, NULL);
  327. #endif
  328.    if (rc != 1) {                                 /* exit on error */
  329.       DO_ERROR("await_and_read_packet:  select");
  330.       close(dpi_fd);
  331.       exit(1);
  332.    }
  333. #ifdef OS2
  334.    len = recv(dpi_fd, inbuf, 2, 0);           /* read 2 bytes first */
  335. #else
  336.    len = read(dpi_fd, inbuf, 2);              /* read 2 bytes first */
  337. #endif
  338.    if (len <= 0) {                            /* exit on error or EOF */
  339.       if (len < 0) DO_ERROR("await_and_read_packet:  read");
  340.       else printf("Quitting, EOF received from DPI-agent\n");
  341.       close(dpi_fd);
  342.       exit(1);
  343.    }
  344.    bytes_to_read = (inbuf[0] << 8) + inbuf[1]; /* bytes to follow */
  345.    if (BUFSIZE < (bytes_to_read + 2)) {        /* exit if too much */
  346.       printf("Quitting, packet larger than %d byte buffer\n",BUFSIZE);
  347.       close(dpi_fd);
  348.       exit(1);
  349.    }
  350.    while (bytes_to_read > 0) {                /* while bytes to read */
  351. #ifdef OS2
  352.       socks[0] = dpi_fd;
  353.       len = select(socks, 1, 0, 0, 3000L);
  354. #else
  355.       timeout.tv_sec  = 3;                    /* wait max 3 seconds */
  356.       timeout.tv_usec = 0;
  357.       FD_SET(dpi_fd, &read_mask);             /* check for data */
  358.       len = select(dpi_fd+1, &read_mask, NULL, NULL, &timeout);
  359. #endif
  360.       if (len == 1) {                         /* select returned OK */
  361. #ifdef OS2
  362.          len = recv(dpi_fd, &inbuf[2] + bytes_read, bytes_to_read, 0);
  363. #else
  364.          len = read(dpi_fd, &inbuf[2] + bytes_read, bytes_to_read);
  365. #endif
  366.       } /* end if (len == 1) */
  367.       if (len <= 0) {                         /* exit on error or EOF */
  368.          if (len < 0) DO_ERROR("await_and_read_packet:  read");
  369.          printf("Can't read remainder of packet\n");
  370.          close(dpi_fd);
  371.          exit(1);
  372.       } else {                                /* count bytes_read */
  373.          bytes_read    += len;
  374.          bytes_to_read -= len;
  375.       }
  376.    }  /* while (bytes_to_read > 0) */
  377. }
  378.  
  379. #ifdef _NO_PROTO                             /* for classic K&R C */
  380. static void handle_packet()     /* handle DPI packet from agent */
  381. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  382. static void handle_packet(void) /* handle DPI packet from agent */
  383. #endif /* _NO_PROTO */
  384. {
  385.    struct   snmp_dpi_hdr   *hdr;
  386.  
  387.    if (debug_lvl > 2) {
  388.       printf("Received following SNMP-DPI packet:\n");
  389.       dump_bfr(inbuf, PACKET_LEN(inbuf));
  390.    }
  391.    hdr = pDPIpacket(inbuf);                /* parse received packet */
  392.    if (hdr == 0) {                         /* ignore if can't parse */
  393.       printf("Ignore received packet, could not parse it!\n");
  394.       return;
  395.    }
  396.    packet   = NULL;
  397.    var_type = 0;
  398.    var_oid  = "";
  399.    var_gid  = "";
  400.    switch (hdr->packet_type) {
  401.      /* extract pointers and/or data from specific packet types, */
  402.      /* such that we can use them independent of packet type. */
  403.      case SNMP_DPI_GET:
  404.        if (debug_lvl > 0) printf("SNMP_DPI_GET for ");
  405.        var_oid       = hdr->packet_body.dpi_get->object_id;
  406.        break;
  407.      case SNMP_DPI_GET_NEXT:
  408.        if (debug_lvl > 0) printf("SNMP_DPI_GET_NEXT for ");
  409.        var_oid       = hdr->packet_body.dpi_next->object_id;
  410.        var_gid       = hdr->packet_body.dpi_next->group_id;
  411.        break;
  412.      case SNMP_DPI_SET:
  413.        if (debug_lvl > 0) printf("SNMP_DPI_SET for ");
  414.        var_value_len = hdr->packet_body.dpi_set->value_len;
  415.        var_value     = hdr->packet_body.dpi_set->value;
  416.        var_oid       = hdr->packet_body.dpi_set->object_id;
  417.        var_type      = hdr->packet_body.dpi_set->type;
  418.        break;
  419.      default:   /* Return a GEN_ERROR */
  420.        if (debug_lvl > 0) printf("Unexpected packet_type %d, genErr\n",
  421.                                   hdr->packet_type);
  422.        packet = mkDPIresponse(SNMP_GEN_ERR, NULL);
  423.        fDPIparse(hdr); /* return storage allocated by pDPIpacket() */
  424.        send_packet(packet);
  425.        return;
  426.        break;
  427.    } /* end switch(hdr->packet_type) */
  428.    if (debug_lvl > 0) printf("objectID: %s \n",var_oid);
  429.  
  430.    if (strlen(var_oid) <= strlen(OID)) { /* not in our tree */
  431.       if (hdr->packet_type == SNMP_DPI_GET_NEXT) var_index = 0; /* OK */
  432.       else { /* cannot handle */
  433.          if (debug_lvl>0) printf("...Ignored %s, noSuchName\n",var_oid);
  434.          packet = mkDPIresponse(SNMP_NO_SUCH_NAME, NULL);
  435.          fDPIparse(hdr); /* return storage allocated by pDPIpacket() */
  436.          send_packet(packet);
  437.          return;
  438.       }
  439.    } else {  /* Extract our variable index (from OID.index.instance) */
  440.       /* We handle any instance the same (we only have one instance) */
  441.       var_index = atoi(&var_oid[strlen(OID)]);
  442.    }
  443.    if (debug_lvl > 1) {
  444.       printf("...The groupID=%s\n",var_gid);
  445.       printf("...Handle as if objectID=%s%d\n",OID,var_index);
  446.    }
  447.    switch (hdr->packet_type) {
  448.      case SNMP_DPI_GET:
  449.        do_get();               /* do a get to return response */
  450.        break;
  451.      case SNMP_DPI_GET_NEXT:
  452.      { char toid[256];         /* space for temporary objectID */
  453.        var_index++;            /* do a get for the next variable */
  454.        sprintf(toid,"%s%d",OID,var_index); /* construct objectID */
  455.        var_oid = toid;         /* point to it */
  456.        do_get();               /* do a get to return response */
  457.      } break;
  458.      case SNMP_DPI_SET:
  459.        if (debug_lvl > 1) printf("...value_type=%d\n",var_type);
  460.        do_set();               /* set new value first */
  461.        if (packet) break;      /* some error response was generated */
  462.        do_get();               /* do a get to return response */
  463.        break;
  464.    }
  465.    fDPIparse(hdr);     /* return storage allocated by pDPIpacket() */
  466. }
  467.  
  468. #ifdef _NO_PROTO                             /* for classic K&R C */
  469. static void do_get()       /* handle SNMP_GET request */
  470. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  471. static void do_get(void)   /* handle SNMP_GET request */
  472. #endif /* _NO_PROTO */
  473. {
  474.    struct dpi_set_packet *data = NULL;
  475.  
  476.    switch (var_index) {
  477.     case 0: /* table, cannot be queried by itself */
  478.      printf("...Should not issue GET for table %s.0\n", OID);
  479.      break;
  480.     case 1:  /* a number */
  481.      data = mkDPIset(var_oid,SNMP_TYPE_NUMBER,sizeof(number),&number);
  482.      break;
  483.     case 2:  /* an octet_string (can have binary data) */
  484.      data = mkDPIset(var_oid,SNMP_TYPE_STRING,ostring_len,ostring);
  485.      break;
  486.     case 3: /* object id */
  487.      data = mkDPIset(var_oid,SNMP_TYPE_OBJECT,objectID_len,objectID);
  488.      break;
  489.     case 4: /* some empty variable */
  490.      data = mkDPIset(var_oid,SNMP_TYPE_EMPTY,0,NULL);
  491.      break;
  492.     case 5: /* internet address */
  493.      data = mkDPIset(var_oid,SNMP_TYPE_INTERNET,sizeof(ipaddr),&ipaddr);
  494.      break;
  495.     case 6: /* counter (unsigned) */
  496.      data =mkDPIset(var_oid,SNMP_TYPE_COUNTER,sizeof(counter),&counter);
  497.      break;
  498.     case 7: /* gauge (unsigned) */
  499.      data = mkDPIset(var_oid,SNMP_TYPE_GAUGE,sizeof(gauge),&gauge);
  500.      break;
  501.     case 8: /* time ticks (unsigned) */
  502.      data = mkDPIset(var_oid,SNMP_TYPE_TICKS,sizeof(ticks),&ticks);
  503.      break;
  504.     case 9:  /* a display_string (printable ascii only) */
  505.      DO_ETOA(dstring);
  506.      data = mkDPIset(var_oid,SNMP_TYPE_STRING,strlen(dstring),dstring);
  507.      DO_ATOE(dstring);
  508.      break;
  509.     case 10:  /* a command request (command is a display string) */
  510.      DO_ETOA(command);
  511.      data = mkDPIset(var_oid,SNMP_TYPE_STRING,strlen(command),command);
  512.      DO_ATOE(command);
  513.      break;
  514.     default: /* Return a NoSuchName */
  515.      if (debug_lvl > 1)
  516.         printf("...GET[NEXT] for %s, not found\n", var_oid);
  517.      break;
  518.    } /* end switch (var_index) */
  519.  
  520.    if (data) {
  521.       if (debug_lvl > 0) {
  522.          printf("...Sending response oid: %s type: %d\n",
  523.                 var_oid, data->type);
  524.          printf("......Current value: ");
  525.          print_val(var_index); /* prints \n at end */
  526.       }
  527.       packet = mkDPIresponse(SNMP_NO_ERROR,data);
  528.    } else { /* Could have been an error in mkDPIset though */
  529.       if (debug_lvl > 0) printf("...Sending response noSuchName\n");
  530.       packet = mkDPIresponse(SNMP_NO_SUCH_NAME,NULL);
  531.    } /* end if (data) */
  532.    if (packet) send_packet(packet);
  533. }
  534.  
  535. #ifdef _NO_PROTO                             /* for classic K&R C */
  536. static void do_set()      /* handle SNMP_SET request */
  537. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  538. static void do_set(void)  /* handle SNMP_SET request */
  539. #endif /* _NO_PROTO */
  540. {
  541.    unsigned long *ulp;
  542.             long *lp;
  543.  
  544.   if (valid_types[var_index] != var_type &&
  545.       valid_types[var_index] != -1) {
  546.       printf("...Ignored set request with type %d, expect type %d,",
  547.              var_type, valid_types[var_index]);
  548.       printf(" Returning badValue\n");
  549.       packet = mkDPIresponse(SNMP_BAD_VALUE, NULL);
  550.       if (packet) send_packet(packet);
  551.       return;
  552.    }
  553.    switch (var_index) {
  554.     case 0: /* table, cannot set table. */
  555.      if (debug_lvl > 0) printf("...Ignored set TABLE, noSuchName\n");
  556.      packet = mkDPIresponse(SNMP_NO_SUCH_NAME,NULL);
  557.      break;
  558.     case 1:  /* a number */
  559.      lp      = (long *)var_value;
  560.      number  = *lp;
  561.      break;
  562.     case 2:  /* an octet_string (can have binary data) */
  563.      free(ostring);
  564.      ostring = (char *)malloc(var_value_len + 1);
  565.      bcopy(var_value, ostring, var_value_len);
  566.      ostring_len = var_value_len;
  567.      ostring[var_value_len] = '\0'; /* so we can use it as a string */
  568.      break;
  569.     case 3: /* object id */
  570.      free(objectID);
  571.      objectID   = (char *)malloc(var_value_len + 1);
  572.      bcopy(var_value, objectID, var_value_len);
  573.      objectID_len = var_value_len;
  574.      if (objectID[objectID_len -1]) {
  575.         objectID[objectID_len++] = '\0'; /* a valid one needs a null */
  576.         if (debug_lvl > 0)
  577.            printf("...added a terminating null to objectID\n");
  578.      }
  579.      break;
  580.     case 4: /* an empty variable, cannot set */
  581.      if (debug_lvl > 0) printf("...Ignored set EMPTY, readOnly\n");
  582.      packet = mkDPIresponse(SNMP_READ_ONLY,NULL);
  583.      break;
  584.     case 5: /* Internet address */
  585.      ulp     = (unsigned long *)var_value;
  586.      ipaddr  = *ulp;
  587.      break;
  588.     case 6: /* counter (unsigned) */
  589.      ulp     = (unsigned long *)var_value;
  590.      counter = *ulp;
  591.      break;
  592.     case 7: /* gauge (unsigned) */
  593.      ulp     = (unsigned long *)var_value;
  594.      gauge   = *ulp;
  595.      break;
  596.     case 8: /* time ticks (unsigned) */
  597.      ulp     = (unsigned long *)var_value;
  598.      ticks   = *ulp;
  599.      break;
  600.     case 9:  /* a display_string (printable ascii only) */
  601.      free(dstring);
  602.      dstring = (char *)malloc(var_value_len + 1);
  603.      bcopy(var_value, dstring, var_value_len);
  604.      dstring[var_value_len] = '\0'; /* so we can use it as a string */
  605.      DO_ATOE(dstring);
  606.      break;
  607.     case 10:  /* a request to execute a command */
  608.      free(command);
  609.      command = (char *)malloc(var_value_len + 1);
  610.      bcopy(var_value, command, var_value_len);
  611.      command[var_value_len] = '\0'; /* so we can use it as a string */
  612.      DO_ATOE(command);
  613.      if (strcmp("all_traps",command) == 0) do_trap = ALL_TRAPS;
  614.      else if (strcmp("std_traps",command) == 0) do_trap = STD_TRAPS;
  615.      else if (strcmp("ent_traps",command) == 0) do_trap = ENT_TRAPS;
  616.      else if (strcmp("ent_trapse",command) == 0) do_trap = ENT_TRAPSE;
  617.      else if (strcmp("all_traps",command) == 0) do_trap = ALL_TRAPS;
  618.      else if (strcmp("quit",command) == 0) do_quit = TRUE;
  619.      else break;
  620.      if (debug_lvl > 0)
  621.         printf("...Action requested: %s set to: %s\n",
  622.                 DPI_var[10], command);
  623.      break;
  624.     default: /* NoSuchName */
  625.      if (debug_lvl > 0)
  626.         printf("...Ignored set for %s, noSuchName\n", var_oid);
  627.      packet = mkDPIresponse(SNMP_NO_SUCH_NAME,NULL);
  628.      break;
  629.   } /* end switch (var_index) */
  630.   if (packet) send_packet(packet);
  631. }
  632.  
  633. #ifdef _NO_PROTO                      /* for classic K&R C */
  634. static void issue_std_traps()
  635. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  636. static void issue_std_traps(void)
  637. #endif /* _NO_PROTO */
  638. {
  639.    trap_stype = 0;
  640.    trap_data  = dpi_hostname;
  641.    for (trap_gtype=0; trap_gtype<6; trap_gtype++) {
  642.        issue_one_trap();
  643.        if (trap_gtype == 0) sleep(10); /* some managers purge cache */
  644.    }
  645. }
  646.  
  647. #ifdef _NO_PROTO                      /* for classic K&R C */
  648. static void issue_ent_traps()
  649. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  650. static void issue_ent_traps(void)
  651. #endif /* _NO_PROTO */
  652. {
  653.    char temp_string[256];
  654.  
  655.    trap_gtype = 6;
  656.    for (trap_stype = 1; trap_stype < 10; trap_stype++) {
  657.      trap_data = temp_string;
  658.      switch (trap_stype) {
  659.      case 1 :
  660.        sprintf(temp_string,"%ld",number);
  661.        break;
  662.      case 2 :
  663.        sprintf(temp_string,"%s",ostring);
  664.        break;
  665.      case 3 :
  666.        trap_data = objectID;
  667.        break;
  668.      case 4 :
  669.        trap_data = "";
  670.        break;
  671.      case 5 :
  672.        trap_data = dpi_hostname;
  673.        break;
  674.      case 6 :
  675.        sleep(1); /* give manager a break */
  676.        sprintf(temp_string,"%lu",counter);
  677.        break;
  678.      case 7 :
  679.        sprintf(temp_string,"%lu",gauge);
  680.        break;
  681.      case 8 :
  682.        sprintf(temp_string,"%lu",ticks);
  683.        break;
  684.      case 9 :
  685.        trap_data = dstring;
  686.        break;
  687.      } /* end switch (trap_stype) */
  688.      issue_one_trap();
  689.    }
  690. }
  691.  
  692. /*  issue a set of extended traps, pass enterprise ID and multiple
  693.  *  variable (assume octect string) as passed by caller
  694.  */
  695. #ifdef _NO_PROTO                      /* for classic K&R C */
  696. static void issue_ent_trapse()
  697. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  698. static void issue_ent_trapse(void)
  699. #endif /* _NO_PROTO */
  700. {
  701.   int i, n;
  702.   struct dpi_set_packet *data = NULL;
  703.   unsigned char *packet = NULL;
  704.   unsigned long ipaddr, ulnum;
  705.   char oid[256];
  706.   char *cp;
  707.  
  708.   trape_gtype = 6;
  709.   trape_eprise = ENTERPRISE_OID;
  710.   for (n=11; n < (11+OID_COUNT_FOR_TRAPS); n++) {
  711.       data = 0;
  712.       trape_stype = n;
  713.       for (i=1; i<=(n-10); i++)
  714.           data = addtoset(data, i);
  715.       if (data == 0) {
  716.          printf("Could not make dpi_set_packet\n");
  717.          return;
  718.       }
  719.       packet = mkDPItrape(trape_gtype,trape_stype,data,trape_eprise);
  720.       if ((debug_lvl > 0) && (packet)) {
  721.          printf("sending trape packet: %lu %lu enterprise=%s\n",
  722.                  trape_gtype, trape_stype, trape_eprise);
  723.       }
  724.       if (packet) send_packet(packet);
  725.       else printf("Could not make trape packet\n");
  726.   }
  727. }
  728.  
  729. /*  issue one extended trap, pass enterprise ID and multiple
  730.  *  variable (assume octect string) as passed by caller
  731.  */
  732. #ifdef _NO_PROTO                      /* for classic K&R C */
  733. static void issue_one_trape()
  734. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  735. static void issue_one_trape(void)
  736. #endif /* _NO_PROTO */
  737. {
  738.   struct dpi_set_packet *data = NULL;
  739.   unsigned char *packet = NULL;
  740.   char oid[256];
  741.   char *cp;
  742.   int i;
  743.  
  744.   for (i=0; i<trape_datacnt; i++) {
  745.       sprintf(oid,"%s2.%d",OID,i);
  746.       /* assume an octet_string (could have hex data) */
  747.       data = mkDPIlist(data, oid, SNMP_TYPE_STRING,
  748.                        strlen(trape_data[i]), trape_data[i]);
  749.       if (data == 0) {
  750.          printf("Could not make dpiset_packet\n");
  751.       } else if (debug_lvl > 0) {
  752.          printf("Preparing: [oid=%s] value: ", oid);
  753.          printf("'");
  754.          for (cp = trape_data[i]; *cp; cp++)  /* loop through data */
  755.              printf("%2.2x",*cp);             /* hex print one byte */
  756.          printf("'H\n");
  757.       }
  758.   }
  759.   packet = mkDPItrape(trape_gtype,trape_stype,data,trape_eprise);
  760.   if ((debug_lvl > 0) && (packet)) {
  761.      printf("sending trape packet: %lu %lu enterprise=%s\n",
  762.              trape_gtype, trape_stype, trape_eprise);
  763.   }
  764.   if (packet) send_packet(packet);
  765.   else printf("Could not make trape packet\n");
  766. }
  767.  
  768. #ifdef _NO_PROTO                      /* for classic K&R C */
  769. static void issue_one_trap()
  770. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  771. static void issue_one_trap(void)
  772. #endif /* _NO_PROTO */
  773. {
  774.   long int num;  /* must be 4 bytes */
  775.   struct dpi_set_packet *data = NULL;
  776.   unsigned char *packet = NULL;
  777.   unsigned long ipaddr, ulnum;
  778.   char oid[256];
  779.   char *cp;
  780.  
  781.   switch (trap_gtype) {
  782.   /*  all traps are handled more or less the same sofar.  */
  783.   /*  could put specific handling here if needed/wanted.  */
  784.   case 0:  /* simulate cold start */
  785.   case 1:  /* simulate warm start */
  786.   case 4:  /* simulate authentication failure */
  787.     strcpy(oid,"none");
  788.     break;
  789.   case 2:  /* simulate link down  */
  790.   case 3:  /* simulate link up    */
  791.     strcpy(oid,ifIndex);
  792.     num = 1;
  793.     data = mkDPIset(oid, SNMP_TYPE_NUMBER, sizeof(num), &num);
  794.     break;
  795.   case 5:  /* simulate EGP neighbor loss */
  796.     strcpy(oid,egpNeighAddr);
  797.     ipaddr = lookup_host(trap_data);
  798.     data = mkDPIset(oid, SNMP_TYPE_INTERNET, sizeof(ipaddr), &ipaddr);
  799.     break;
  800.   case 6:  /* simulate enterprise specific trap */
  801.     sprintf(oid,"%s%d.0",OID, trap_stype);
  802.     switch (trap_stype) {
  803.     case 1:  /* a number */
  804.       num  = strtol(trap_data,(char **)0,10);
  805.       data = mkDPIset(oid, SNMP_TYPE_NUMBER, sizeof(num), &num);
  806.       break;
  807.     case 2:  /* an octet_string (could have hex data) */
  808.       data = mkDPIset(oid,SNMP_TYPE_STRING,strlen(trap_data),trap_data);
  809.       break;
  810.     case 3: /* object id */
  811.       data = mkDPIset(oid,SNMP_TYPE_OBJECT,strlen(trap_data) + 1,
  812.                       trap_data);
  813.       break;
  814.     case 4: /* an empty variable value */
  815.       data = mkDPIset(oid, SNMP_TYPE_EMPTY, 0, 0);
  816.       break;
  817.     case 5: /* internet address */
  818.       ipaddr = lookup_host(trap_data);
  819.       data = mkDPIset(oid, SNMP_TYPE_INTERNET, sizeof(ipaddr), &ipaddr);
  820.       break;
  821.     case 6: /* counter (unsigned) */
  822.       ulnum  = strtoul(trap_data,(char **)0,10);
  823.       data = mkDPIset(oid, SNMP_TYPE_COUNTER, sizeof(ulnum), &ulnum);
  824.       break;
  825.     case 7: /* gauge (unsigned) */
  826.       ulnum  = strtoul(trap_data,(char **)0,10);
  827.       data = mkDPIset(oid, SNMP_TYPE_GAUGE, sizeof(ulnum), &ulnum);
  828.       break;
  829.     case 8: /* time ticks (unsigned) */
  830.       ulnum  = strtoul(trap_data,(char **)0,10);
  831.       data = mkDPIset(oid, SNMP_TYPE_TICKS, sizeof(num), &ulnum);
  832.       break;
  833.     case 9:  /* a display_string (ascii only) */
  834.       DO_ETOA(trap_data);
  835.       data = mkDPIset(oid,SNMP_TYPE_STRING,strlen(trap_data),trap_data);
  836.       DO_ATOE(trap_data);
  837.       break;
  838.     default: /* handle as string */
  839.       printf("Unknown specific trap type: %s, assume octet_string\n",
  840.               trap_stype);
  841.       data = mkDPIset(oid,SNMP_TYPE_STRING,strlen(trap_data),trap_data);
  842.       break;
  843.     } /* end switch (trap_stype) */
  844.     break;
  845.   default: /* unknown trap */
  846.     printf("Unknown general trap type: %s\n", trap_gtype);
  847.     return;
  848.     break;
  849.   } /* end switch (trap_gtype) */
  850.  
  851.   packet = mkDPItrap(trap_gtype,trap_stype,data);
  852.   if ((debug_lvl > 0) && (packet)) {
  853.      printf("sending trap packet: %u %u [oid=%s] value: ",
  854.             trap_gtype, trap_stype, oid);
  855.      if (trap_stype == 2) {
  856.         printf("'");
  857.         for (cp = trap_data; *cp; cp++)      /* loop through data */
  858.             printf("%2.2x",*cp);             /* hex print one byte */
  859.         printf("'H\n");
  860.      } else printf("%s\n", trap_data);
  861.   }
  862.   if (packet) send_packet(packet);
  863.   else printf("Could not make trap packet\n");
  864. }
  865.  
  866. #ifdef _NO_PROTO                             /* for classic K&R C */
  867. static void send_packet(packet)              /* DPI packet to agent */
  868. char *packet;
  869. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  870. static void send_packet(const char *packet)  /* DPI packet to agent */
  871. #endif /* _NO_PROTO */
  872. {
  873.    int rc;
  874.  
  875.    if (debug_lvl > 2) {
  876.       printf("...Sending DPI packet:\n");
  877.       dump_bfr(packet, PACKET_LEN(packet));
  878.    }
  879. #ifdef OS2
  880.    rc = send(dpi_fd,packet,PACKET_LEN(packet),0);
  881. #else
  882.    rc = write(dpi_fd,packet,PACKET_LEN(packet));
  883. #endif
  884.    if (rc != PACKET_LEN(packet)) DO_ERROR("send_packet:  write");
  885.    /* no need to free packet (static buffer in mkDPI.... routine) */
  886. }
  887.  
  888. #ifdef _NO_PROTO                             /* for classic K&R C */
  889. static void do_register()  /* register our objectIDs with agent */
  890. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  891. static void do_register(void)  /* register our objectIDs with agent */
  892. #endif /* _NO_PROTO */
  893. {
  894.    int  i, rc;
  895.    char toid[256];
  896.  
  897.    if (debug_lvl > 0) printf("Registering variables:\n");
  898.    for (i=1; i<=OID_COUNT; i++) {
  899.        sprintf(toid,"%s%d.",OID,i);
  900.        packet = mkDPIregister(toid);
  901. #ifdef OS2
  902.        rc     = send(dpi_fd, packet, PACKET_LEN(packet),0);
  903. #else
  904.        rc     = write(dpi_fd, packet, PACKET_LEN(packet));
  905. #endif
  906.        if (rc <= 0) {
  907.           DO_ERROR("do_register:  write");
  908.           printf("Quitting, unsuccessful register for %s\n",toid);
  909.           close(dpi_fd);
  910.           exit(1);
  911.        }
  912.        if (debug_lvl > 0) {
  913.           printf("...Registered: %-25s oid: %s\n",DPI_var[i],toid);
  914.           printf("......Initial value: ");
  915.           print_val(i); /* prints \n at end */
  916.        }
  917.    }
  918. }
  919.  
  920. /*  add specified variable to list of variable in the dpi_set_packet
  921.  */
  922. #ifdef _NO_PROTO                      /* for classic K&R C */
  923. struct dpi_set_packet *addtoset(data, stype)
  924. struct dpi_set_packet *data;
  925. int stype;
  926. #else  /* _NO_PROTO */                /* for ANSI-C compiler */
  927. struct dpi_set_packet *addtoset(struct dpi_set_packet *data, int stype)
  928. #endif /* _NO_PROTO */
  929. {
  930.     char var_oid[256];
  931.  
  932.     sprintf(var_oid,"%s%d.0",OID, stype);
  933.     switch (stype) {
  934.     case 1:  /* a number */
  935.       data = mkDPIlist(data, var_oid, SNMP_TYPE_NUMBER,
  936.                        sizeof(number), &number);
  937.       break;
  938.     case 2:  /* an octet_string (can have binary data) */
  939.      data = mkDPIlist(data, var_oid, SNMP_TYPE_STRING,
  940.                       ostring_len, ostring);
  941.      break;
  942.     case 3: /* object id */
  943.      data = mkDPIlist(data, var_oid, SNMP_TYPE_OBJECT,
  944.                       objectID_len, objectID);
  945.      break;
  946.     case 4: /* some empty variable */
  947.      data = mkDPIlist(data, var_oid, SNMP_TYPE_EMPTY, 0, NULL);
  948.      break;
  949.     case 5: /* internet address */
  950.      data = mkDPIlist(data, var_oid, SNMP_TYPE_INTERNET,
  951.                       sizeof(ipaddr), &ipaddr);
  952.      break;
  953.     case 6: /* counter (unsigned) */
  954.      data =mkDPIlist(data, var_oid, SNMP_TYPE_COUNTER,
  955.                      sizeof(counter), &counter);
  956.      break;
  957.     case 7: /* gauge (unsigned) */
  958.      data = mkDPIlist(data, var_oid, SNMP_TYPE_GAUGE,
  959.                       sizeof(gauge), &gauge);
  960.      break;
  961.     case 8: /* time ticks (unsigned) */
  962.      data = mkDPIlist(data, var_oid, SNMP_TYPE_TICKS,
  963.                       sizeof(ticks), &ticks);
  964.      break;
  965.     case 9:  /* a display_string (printable ascii only) */
  966.      DO_ETOA(dstring);
  967.      data = mkDPIlist(data, var_oid, SNMP_TYPE_STRING,
  968.                       strlen(dstring), dstring);
  969.      DO_ATOE(dstring);
  970.      break;
  971.     } /* end switch (stype) */
  972.     return(data);
  973. }
  974.  
  975. #ifdef _NO_PROTO                             /* for classic K&R C */
  976. static void print_val(index)
  977. int index;
  978. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  979. static void print_val(const int index)
  980. #endif /* _NO_PROTO */
  981. {
  982.    char *cp;
  983.    struct in_addr display_ipaddr;
  984.  
  985.    switch (index) {
  986.    case 1 :
  987.      printf("%ld\n",number);
  988.      break;
  989.    case 2 :
  990.      printf("'");
  991.      for (cp = ostring; cp < ostring + ostring_len; cp++)
  992.          printf("%2.2x",*cp);
  993.      printf("'H\n");
  994.      break;
  995.    case 3 :
  996.      printf("%*s\n", objectID_len, objectID);
  997.      break;
  998.    case 4 :
  999.      printf("no value (EMPTY)\n");
  1000.      break;
  1001.   case 5 :
  1002.      display_ipaddr.s_addr = (u_long) ipaddr;
  1003.      printf("%s\n",inet_ntoa(display_ipaddr));
  1004. /*   This worked on VM, MVS and AIX, but not on OS/2
  1005.  *   printf("%d.%d.%d.%d\n", (ipaddr >> 24), ((ipaddr << 8) >> 24),
  1006.  *          ((ipaddr << 16) >> 24), ((ipaddr << 24) >> 24));
  1007.  */
  1008.      break;
  1009.    case 6 :
  1010.      printf("%lu\n",counter);
  1011.      break;
  1012.    case 7 :
  1013.      printf("%lu\n",gauge);
  1014.      break;
  1015.    case 8 :
  1016.      printf("%lu\n",ticks);
  1017.      break;
  1018.    case 9 :
  1019.      printf("%s\n",dstring);
  1020.      break;
  1021.    case 10 :
  1022.      printf("%s\n",command);
  1023.      break;
  1024.    } /* end switch(index) */
  1025. }
  1026.  
  1027. #ifdef _NO_PROTO                             /* for classic K&R C */
  1028. static void check_arguments(argc, argv)      /* check arguments */
  1029. int   argc;
  1030. char *argv[];
  1031. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  1032. static void check_arguments(const int argc, char *argv[])
  1033. #endif /* _NO_PROTO */
  1034. {
  1035.    char *hname, *cname;
  1036.    int i, j;
  1037.  
  1038.    dpi_userid = hname = cname = NULL;
  1039.    for (i=1; argc > i; i++) {
  1040.       if (strcmp(argv[i],"-d") == 0) {
  1041.          i++;
  1042.          if (argc > i) {
  1043.             debug_lvl = atoi(argv[i]);
  1044.             if (debug_lvl >= 5) {
  1045.                DPIdebug(1);
  1046.             }
  1047.          }
  1048.       } else if (strcmp(argv[i],"-trap") == 0) {
  1049.          if (argc > i+3) {
  1050.             trap_gtype = atoi(argv[i+1]);
  1051.             trap_stype = atoi(argv[i+2]);
  1052.             trap_data  = argv[i+3];
  1053.             i = i + 3;
  1054.             do_trap = ONE_TRAP;
  1055.          } else usage(argv[0], 1);
  1056.       } else if (strcmp(argv[i],"-trape") == 0) {
  1057.          if (argc > i+4) {
  1058.             trape_gtype  = strtoul(argv[i+1],(char**)0,10);
  1059.             trape_stype  = strtoul(argv[i+2],(char**)0,10);
  1060.             trape_eprise = argv[i+3];
  1061.             for (i = i + 4, j = 0;
  1062.                  (argc > i) && (j < MAX_TRAPE_DATA);
  1063.                  i++, j++) {
  1064.                 trape_data[j]  = argv[i];
  1065.             }
  1066.             trape_datacnt = j;
  1067.             do_trap = ONE_TRAPE;
  1068.             break;  /* -trape must be last option */
  1069.          } else usage(argv[0], 1);
  1070.       } else if (strcmp(argv[i],"-all_traps") == 0) {
  1071.          do_trap = ALL_TRAPS;
  1072.       } else if (strcmp(argv[i],"-std_traps") == 0) {
  1073.          do_trap = STD_TRAPS;
  1074.       } else if (strcmp(argv[i],"-ent_traps") == 0) {
  1075.          do_trap = ENT_TRAPS;
  1076.       } else if (strcmp(argv[i],"-ent_trapse") == 0) {
  1077.          do_trap = ENT_TRAPSE;
  1078. #if defined(VM) || defined(MVS)
  1079.       } else if (strcmp(argv[i],"-inet") == 0) {
  1080.          use_iucv = 0;
  1081.       } else if (strcmp(argv[i],"-iucv") == 0) {
  1082.          use_iucv = TRUE;
  1083.       } else if (strcmp(argv[i],"-u") == 0) {
  1084.          use_iucv = TRUE;  /* -u implies -iucv */
  1085.          i++;
  1086.          if (argc > i) {
  1087.             dpi_userid = argv[i];
  1088.          }
  1089. #endif
  1090.       } else if (strcmp(argv[i],"?") == 0) {
  1091.          usage(argv[0], 0);
  1092.       } else {
  1093.         if (hname == NULL) hname = argv[i];
  1094.         else if (cname == NULL) cname = argv[i];
  1095.         else usage(argv[0], 1);
  1096.       }
  1097.    }
  1098.    if (hname == NULL) hname = LOOPBACK;              /* use default */
  1099.    if (cname == NULL) cname = PUBLIC_COMMUNITY_NAME; /* use default */
  1100. #if defined(VM) || defined(MVS)
  1101.    if (dpi_userid == NULL) dpi_userid = SNMPAGENTUSERID;
  1102.    if (debug_lvl > 2)
  1103.       printf("hname=%s, cname=%s, userid=%s\n",hname,cname,dpi_userid);
  1104. #else
  1105.    if (debug_lvl > 2)
  1106.       printf("hname=%s, cname=%s\n",hname,cname);
  1107. #endif
  1108.    if (use_iucv != TRUE) {
  1109.       DO_ETOA(cname);                                /* for VM or MVS */
  1110.       dpi_port = query_DPI_port(hname,cname);
  1111.       DO_ATOE(cname);                                /* for VM or MVS */
  1112.       if (dpi_port == -1) {
  1113.          printf("No response from agent at %s(%s)\n",hname,cname);
  1114.          exit(1);
  1115.       }
  1116.    } else dpi_port == -1;
  1117.    dpi_hostname = hname;
  1118. }
  1119.  
  1120. #ifdef _NO_PROTO                             /* for classic K&R C */
  1121. static void usage(pname, exit_rc)
  1122. char *pname;
  1123. int   exit_rc;
  1124. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  1125. static void usage(const char *pname, const int exit_rc)
  1126. #endif /* _NO_PROTO */
  1127. {
  1128.    printf("Usage: %s [-d debug_lvl] [-trap g_type s_type data]", pname);
  1129.    printf(" [-all_traps]\n");
  1130.    printf("%*s[-trape g_type s_type enterprise data1 data2 .. datan]\n",
  1131.           strlen(pname)+8,"");
  1132.    printf("%*s[-std_traps] [-ent_traps] [-ent_trapse]\n",
  1133.           strlen(pname)+8,"");
  1134. #if defined(VM) || defined(MVS)
  1135.    printf("%*s[-iucv] [-u agent_userid]\n",strlen(pname)+8, "");
  1136.    printf("%*s", strlen(pname)+8, "");
  1137.    printf("[-inet] [agent_hostname [community_name]]\n");
  1138.    printf("default: -d 0 -iucv -u %s\n", SNMPAGENTUSERID);
  1139.    printf("         -inet %s %s\n", LOOPBACK, PUBLIC_COMMUNITY_NAME);
  1140. #else
  1141.    printf("%*s[agent_hostname [community_name]]\n",strlen(pname)+8,"");
  1142.    printf("default: -d 0 %s %s\n", LOOPBACK, PUBLIC_COMMUNITY_NAME);
  1143. #endif
  1144.    exit(exit_rc);
  1145. }
  1146.  
  1147. #ifdef _NO_PROTO                     /* for classic K&R C */
  1148. static void init_variables()         /* initialize our variables */
  1149. #else  /* _NO_PROTO */               /* for ANSI-C compiler */
  1150. static void init_variables(void)     /* initialize our variables */
  1151. #endif /* _NO_PROTO */
  1152. {
  1153.    char ch, *cp;
  1154.  
  1155.    ostring  = (char *)malloc(strlen(OSTRING) + 4 + 1 );
  1156.    bcopy(OSTRING,ostring,strlen(OSTRING));
  1157.    ostring_len = strlen(OSTRING);
  1158.    for (ch=1;ch<5;ch++)               /* add hex data 0x01020304 */
  1159.         ostring[ostring_len++] = ch;
  1160.    ostring[ostring_len] = '\0';       /* so we can use it as a string */
  1161.    objectID     = (char *)malloc(strlen(OID));
  1162.    objectID_len = strlen(OID);
  1163.    bcopy(OID,objectID,strlen(OID));
  1164.    if (objectID[objectID_len - 1] == '.')  /* if trailing dot, */
  1165.        objectID[objectID_len - 1] = '\0';  /* remove it */
  1166.    else objectID_len++;                    /* length includes null */
  1167.    dstring  = (char *)malloc(strlen(DSTRING)+1);
  1168.    bcopy(DSTRING,dstring,strlen(DSTRING)+1);
  1169.    command  = (char *)malloc(strlen(COMMAND)+1);
  1170.    bcopy(COMMAND,command,strlen(COMMAND)+1);
  1171.    ipaddr = dpi_ipaddress;
  1172.  
  1173. }
  1174.  
  1175. #ifdef _NO_PROTO                     /* for classic K&R C */
  1176. static void init_connection()        /* connect to the DPI agent */
  1177. #else  /* _NO_PROTO */               /* for ANSI-C compiler */
  1178. static void init_connection(void)    /* connect to the DPI agent */
  1179. #endif /* _NO_PROTO */
  1180. {
  1181.     int                   rc;
  1182.     int               sasize;        /* size of socket structure */
  1183.     struct sockaddr_in   sin;        /* socket address AF_INET */
  1184.     struct sockaddr      *sa;        /* socket address general */
  1185. #if defined(VM) || defined (MVS)
  1186.     struct sockaddr_iucv siu;        /* socket address AF_IUCV */
  1187.  
  1188.     if (use_iucv == TRUE) {
  1189.        printf("Connecting to %s DPI_port %d userid %s (TCP, AF_IUCV)\n",
  1190.               dpi_hostname,dpi_port,dpi_userid);
  1191.        bzero(&siu,sizeof(siu));
  1192.        siu.siucv_family = AF_IUCV;
  1193.        siu.siucv_addr = dpi_ipaddress;
  1194.        siu.siucv_port = dpi_port;
  1195.        memset(siu.siucv_nodeid, ' ', sizeof(siu.siucv_nodeid));
  1196.        memset(siu.siucv_userid, ' ', sizeof(siu.siucv_userid));
  1197.        memset(siu.siucv_name, ' ', sizeof(siu.siucv_name));
  1198.        bcopy(dpi_userid, siu.siucv_userid, min(8,strlen(dpi_userid)));
  1199.        bcopy(SNMPIUCVNAME, siu.siucv_name, min(8,strlen(SNMPIUCVNAME)));
  1200.        dpi_fd = socket(AF_IUCV, SOCK_STREAM, 0);
  1201.        sa     = (struct sockaddr *) &siu;
  1202.        sasize = sizeof(struct sockaddr_iucv);
  1203.     } else {
  1204. #endif
  1205.        printf("Connecting to %s DPI_port %d (TCP, AF_INET)\n",
  1206.               dpi_hostname,dpi_port);
  1207.        bzero(&sin,sizeof(sin));
  1208.        sin.sin_family      = AF_INET;
  1209.        sin.sin_port        = htons(dpi_port);
  1210.        sin.sin_addr.s_addr = dpi_ipaddress;
  1211.        dpi_fd = socket(AF_INET, SOCK_STREAM, 0);
  1212.        sa     = (struct sockaddr *) &sin;
  1213.        sasize = sizeof(struct sockaddr_in);
  1214. #if defined(VM) || defined (MVS)
  1215.     }
  1216. #endif
  1217.     if (dpi_fd < 0) {                            /* exit on error */
  1218.        DO_ERROR("init_connection:  socket");
  1219.        exit(1);
  1220.     }
  1221.     rc = connect(dpi_fd, sa, sasize);            /* connect to agent */
  1222.     if (rc != 0) {                               /* exit on error */
  1223.        DO_ERROR("init_connection:  connect");
  1224.        close(dpi_fd);
  1225.        exit(1);
  1226.     }
  1227. }
  1228.  
  1229. #ifdef _NO_PROTO                             /* for classic K&R C */
  1230. static void dump_bfr(buf, len)               /* hex dump buffer */
  1231. char *buf;
  1232. int   len;
  1233. #else  /* _NO_PROTO */                       /* for ANSI-C compiler */
  1234. static void dump_bfr(const char *buf, const int len)
  1235. #endif /* _NO_PROTO */
  1236. {
  1237.    register int i;
  1238.  
  1239.    if (len == 0) printf("     empty buffer\n"); /* buffer is empty */
  1240.    for (i=0;i<len;i++) {                     /* loop through buffer */
  1241.        if ((i&15) == 0) printf("     ");     /* indent new line */
  1242.        printf("%2.2x",(unsigned char)buf[i]);/* hex print one byte */
  1243.        if ((i&15) == 15) printf("\n");       /* nl every 16 bytes */
  1244.        else if ((i&3) == 3) printf(" ");     /* space every 4 bytes */
  1245.    }
  1246.    if (i&15) printf("\n");                   /* always end with nl */
  1247. }
  1248.