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.C1
< prev
next >
Wrap
Text File
|
1992-11-27
|
47KB
|
1,247 lines
/*********************************************************************/
/* */
/* SNMP-DPI - SNMP Distributed Programming Interface */
/* */
/* May 1991 - Version 1.0 - SNMP-DPI Version 1.0 (RFC1228) */
/* Created by IBM Research. */
/* Feb 1992 - Version 1.1 - Allow enterpriseID to be passed with */
/* a (enterprise specific) trap */
/* - allow multiple variables to be passed */
/* - Use 4 octets (INTEGER from RFC1157) */
/* for generic and specific type. */
/* Jun 1992 - Make it run on OS/2 as well */
/* */
/* Copyright None */
/* */
/* dpisample.c - a sample SNMP-DPI subagent */
/* - can be used to test agent DPI implementations. */
/* */
/* For testing with XGMON and/or SQESERV (SNMP Query Engine) */
/* it is best to keep the following define for OID in sync */
/* with the spiSample objectID in the MIB description file */
/* (mib_desc for XGMON, MIB_DESC DATA for SQESERV on VM and */
/* MIB@DESC.DATA for SQESERV on MVS). */
/* */
/* See dpisample README file for more info. */
/* */
/*********************************************************************/
#define OID "1.3.6.1.4.1.2.2.1.4."
#define ENTERPRISE_OID "1.3.6.1.4.1.2.2.1.4" /* dpiSample */
#define ifIndex "1.3.6.1.2.1.2.2.1.1.0"
#define egpNeighAddr "1.3.6.1.2.8.5.1.2.0"
#define PUBLIC_COMMUNITY_NAME "public"
#if defined(VM) || defined(MVS)
#define SNMPAGENTUSERID "SNMPD"
#define SNMPIUCVNAME "SNMP_DPI"
#pragma csect(CODE, "$DPISAMP")
#pragma csect(STATIC,"#DPISAMP")
#include <manifest.h> /* VM specific things */
#include "snmpnms.h" /* short external names for VM/MVS */
#include "snmp_vm.h" /* more of those short names */
#include <saiucv.h>
#include <bsdtime.h>
#include <bsdtypes.h>
#include <socket.h>
#include <in.h>
#include <netdb.h>
#include <inet.h>
extern char ebcdicto[], asciitoe[];
#pragma linkage(cmxlate,OS)
#define DO_ETOA(a) cmxlate((a),ebcdictoascii,strlen((a)))
#define DO_ATOE(a) cmxlate((a),asciitoebcdic,strlen((a)))
#define DO_ERROR(a) tcperror((a))
#define LOOPBACK "loopback"
#define IUCV TRUE
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#else /* we are not on VM or MVS */
#ifdef OS2
#include <stdlib.h>
#include <types.h>
#include <doscalls.h>
#ifndef sleep
#define sleep(a) DOSSLEEP(1000 * (a))
#endif
#define close soclose
/*char * malloc(); */
/*unsigned long strtoul(); */
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
// #include <arpa/inet.h>
#define DO_ETOA(a) ; /* no need for this */
#define DO_ATOE(a) ; /* no need for this */
#define DO_ERROR(a) perror((a))
#define LOOPBACK "localhost"
#define IUCV FALSE
#ifdef AIX221
#define isdigit(c) (((c) >= '0') && ((c) <= '9'))
#else
// #include <sys/select.h>
#endif /* AIX221 */
#endif /* defined(VM) || defined(MVS) */
#include <stdio.h>
#ifdef OS2
#include <dpi/snmp_dpi.h>
#else
#include "snmp_dpi.h"
#endif
#define WAIT_FOR_AGENT 3 /* time to wait before closing agent fd */
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifdef _NO_PROTO /* for classic K&R C */
static void check_arguments();
static void send_packet();
static void print_val();
static void usage();
static void init_connection();
static void init_variables();
static void await_and_read_packet();
static void handle_packet();
static void do_get();
static void do_set();
static void issue_traps();
static void issue_one_trap();
static void issue_one_trape();
static void issue_std_traps();
static void issue_ent_traps();
static void issue_ent_trapse();
static void do_register();
static void dump_bfr();
static struct dpi_set_packet *addtoset();
extern unsigned long lookup_host();
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void check_arguments(const int argc, char *argv[]);
static void send_packet(const char * packet);
static void print_val(const int index);
static void usage(const char *progname, const int exit_rc);
static void init_connection(void);
static void init_variables(void);
static void await_and_read_packet(void);
static void handle_packet(void);
static void do_get(void);
static void do_set(void);
static void issue_traps(void);
static void issue_one_trap(void);
static void issue_one_trape(void);
static void issue_std_traps(void);
static void issue_ent_traps(void);
static void issue_ent_trapse(void);
static void do_register(void);
static void dump_bfr(const char *buf, const int len);
static struct dpi_set_packet *addtoset(struct dpi_set_packet *data,
int stype);
extern unsigned long lookup_host(const char *hostname);
#endif /* _NO_PROTO */
#define OSTRING "hex01-04:"
#define DSTRING "Initial Display String"
#define COMMAND "None"
#define BUFSIZE 4096
#define TIMEOUT 3
#define PACKET_LEN(packet) (((unsigned char)*(packet)) * 256 + \
((unsigned char)*((packet) + 1)) + 2)
/* We have the following instances for OID.x variables */
/* 0 - table */
static long number = 0; /* 1 - a number */
static unsigned char *ostring = 0; /* 2 - octet string */
static int ostring_len = 0; /* and its length */
static unsigned char *objectID = 0; /* 3 - objectID */
static int objectID_len= 0; /* and its length */
/* 4 - some empty variable */
static unsigned long ipaddr = 0; /* 5 - ipaddress */
static unsigned long counter = 1; /* 6 - a counter */
static unsigned long gauge = 1; /* 7 - a gauge */
static unsigned long ticks = 1; /* 8 - time ticks */
static unsigned char *dstring = 0; /* 9 - display string */
static unsigned char *command = 0; /* 10 - command */
static char *DPI_var[] = {
"dpiSample",
"dpiSampleNumber",
"dpiSampleOctetString",
"dpiSampleObjectID",
"dpiSampleEmpty",
"dpiSampleInetAddress",
"dpiSampleCounter",
"dpiSampleGauge",
"dpiSampleTimeTicks",
"dpiSampleDisplayString",
"dpiSampleCommand"
};
static short int valid_types[] = { /* SNMP_TYPEs accepted on SET */
-1, /* 0 do not check type */
SNMP_TYPE_NUMBER, /* 1 number */
SNMP_TYPE_STRING, /* 2 octet string */
SNMP_TYPE_OBJECT, /* 3 object identifier */
-1, /* SNMP_TYPE_EMPTY */ /* 4 do not check type */
SNMP_TYPE_INTERNET, /* 5 internet address */
SNMP_TYPE_COUNTER, /* 6 counter */
SNMP_TYPE_GAUGE, /* 7 gauge */
SNMP_TYPE_TICKS, /* 8 time ticks */
SNMP_TYPE_STRING, /* 9 display string */
SNMP_TYPE_STRING /* 10 command (display string) */
#define OID_COUNT_FOR_TRAPS 9
#define OID_COUNT 10
};
static char *packet = NULL; /* ptr to send packet. */
static char inbuf[BUFSIZE]; /* buffer for receive packets */
static int dpi_fd; /* fd for socket to DPI agent */
static short int dpi_port; /* DPI_port at agent */
static unsigned long dpi_ipaddress; /* IP address of DPI agent */
static char *dpi_hostname; /* hostname of DPI agent */
static char *dpi_userid; /* userid of DPI agent VM/MVS */
static char *var_gid; /* groupID received */
static char *var_oid; /* objectID received */
static int var_index; /* OID variable index */
static unsigned char var_type; /* SET value type */
static char *var_value; /* SET value */
static short int var_value_len; /* SET value length */
static int debug_lvl = 0; /* current debug level */
static int use_iucv = IUCV; /* optional use of AF_IUCV */
static int do_quit = FALSE;/* Quit in await loop */
static int trap_gtype = 0; /* trap generic type */
static int trap_stype = 0; /* trap specific type */
static char *trap_data = NULL;/* trap data */
static int do_trap = 0; /* switch for traps */
#define ONE_TRAP 1
#define ONE_TRAPE 2
#define STD_TRAPS 3
#define ENT_TRAPS 4
#define ENT_TRAPSE 5
#define ALL_TRAPS 6
#define MAX_TRAPE_DATA 10 /* data for extended trap */
static long trape_gtype = 6; /* trap generic type */
static long trape_stype = 11; /* trap specific type */
static char *trape_eprise = NULL; /* enterprise id */
static char *trape_data[MAX_TRAPE_DATA]; /* pointers to data values */
static int trape_datacnt; /* actual number of values */
#ifdef _NO_PROTO /* for classic K&R C */
main(argc, argv) /* main line */
int argc;
char *argv[];
#else /* _NO_PROTO */ /* for ANSI-C compiler */
main(const int argc, char *argv[]) /* main line */
#endif /* _NO_PROTO */
{
check_arguments(argc, argv); /* check callers arguments */
dpi_ipaddress = lookup_host(dpi_hostname); /* get ip address */
init_connection(); /* connect to specified agent */
init_variables(); /* initialize our variables */
if (do_trap) { /* we just need to do traps */
issue_traps(); /* issue the trap(s) */
sleep(WAIT_FOR_AGENT); /* sleep a bit, so agent can */
close(dpi_fd); /* read data before we close */
exit(0); /* and that's it */
} /* end if (do_trap) */
do_register(); /* register our objectIDs */
printf("%s ready and awaiting queries from agent\n",argv[0]);
while (do_quit == FALSE) { /* forever until quit or error */
await_and_read_packet(); /* wait for next packet */
handle_packet(); /* handle it */
if (do_trap) issue_traps(); /* request to issue traps */
} /* while loop */
sleep(WAIT_FOR_AGENT); /* allow agent to read response */
printf("Quitting, %s set to: quit\n",DPI_var[10]);
exit(2); /* sampleDisplayString == quit */
}
#ifdef _NO_PROTO /* for classic K&R C */
static void issue_traps()
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void issue_traps(void)
#endif /* _NO_PROTO */
{
switch (do_trap) { /* let's see which one(s) */
case ONE_TRAP: /* only need to issue one trap */
issue_one_trap(); /* go issue the one trap */
break;
case ONE_TRAPE: /* only need to issue one trape */
issue_one_trape(); /* go issue the one trape */
break;
case STD_TRAPS: /* only need to issue std traps */
issue_std_traps(); /* standard traps gtypes 0-5 */
break;
case ENT_TRAPS: /* only need to issue ent traps */
issue_ent_traps(); /* enterprise specific traps */
break;
case ENT_TRAPSE: /* only need to issue ent trapse */
issue_ent_trapse(); /* enterprise specific trapse */
break;
case ALL_TRAPS: /* only need to issue std traps */
issue_std_traps(); /* standard traps gtypes 0-5 */
issue_ent_traps(); /* enterprise specific traps */
issue_ent_trapse(); /* enterprise specific trapse */
break;
default:
break;
} /* end switch (do_trap) */
do_trap = 0; /* reset do_trap switch */
}
#ifdef _NO_PROTO /* for classic K&R C */
static void await_and_read_packet() /* await packet from DPI agent */
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void await_and_read_packet(void)/* await packet from DPI agent */
#endif /* _NO_PROTO */
{
int len, rc, bytes_to_read, bytes_read = 0;
#ifdef OS2
int socks[5];
#else
fd_set read_mask;
#endif
struct timeval timeout;
#ifdef OS2
socks[0] = dpi_fd;
rc = select(socks, 1, 0, 0, -1L);
#else
FD_ZERO(&read_mask);
FD_SET(dpi_fd, &read_mask); /* wait for data */
rc = select(dpi_fd+1, &read_mask, NULL, NULL, NULL);
#endif
if (rc != 1) { /* exit on error */
DO_ERROR("await_and_read_packet: select");
close(dpi_fd);
exit(1);
}
#ifdef OS2
len = recv(dpi_fd, inbuf, 2, 0); /* read 2 bytes first */
#else
len = read(dpi_fd, inbuf, 2); /* read 2 bytes first */
#endif
if (len <= 0) { /* exit on error or EOF */
if (len < 0) DO_ERROR("await_and_read_packet: read");
else printf("Quitting, EOF received from DPI-agent\n");
close(dpi_fd);
exit(1);
}
bytes_to_read = (inbuf[0] << 8) + inbuf[1]; /* bytes to follow */
if (BUFSIZE < (bytes_to_read + 2)) { /* exit if too much */
printf("Quitting, packet larger than %d byte buffer\n",BUFSIZE);
close(dpi_fd);
exit(1);
}
while (bytes_to_read > 0) { /* while bytes to read */
#ifdef OS2
socks[0] = dpi_fd;
len = select(socks, 1, 0, 0, 3000L);
#else
timeout.tv_sec = 3; /* wait max 3 seconds */
timeout.tv_usec = 0;
FD_SET(dpi_fd, &read_mask); /* check for data */
len = select(dpi_fd+1, &read_mask, NULL, NULL, &timeout);
#endif
if (len == 1) { /* select returned OK */
#ifdef OS2
len = recv(dpi_fd, &inbuf[2] + bytes_read, bytes_to_read, 0);
#else
len = read(dpi_fd, &inbuf[2] + bytes_read, bytes_to_read);
#endif
} /* end if (len == 1) */
if (len <= 0) { /* exit on error or EOF */
if (len < 0) DO_ERROR("await_and_read_packet: read");
printf("Can't read remainder of packet\n");
close(dpi_fd);
exit(1);
} else { /* count bytes_read */
bytes_read += len;
bytes_to_read -= len;
}
} /* while (bytes_to_read > 0) */
}
#ifdef _NO_PROTO /* for classic K&R C */
static void handle_packet() /* handle DPI packet from agent */
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void handle_packet(void) /* handle DPI packet from agent */
#endif /* _NO_PROTO */
{
struct snmp_dpi_hdr *hdr;
if (debug_lvl > 2) {
printf("Received following SNMP-DPI packet:\n");
dump_bfr(inbuf, PACKET_LEN(inbuf));
}
hdr = pDPIpacket(inbuf); /* parse received packet */
if (hdr == 0) { /* ignore if can't parse */
printf("Ignore received packet, could not parse it!\n");
return;
}
packet = NULL;
var_type = 0;
var_oid = "";
var_gid = "";
switch (hdr->packet_type) {
/* extract pointers and/or data from specific packet types, */
/* such that we can use them independent of packet type. */
case SNMP_DPI_GET:
if (debug_lvl > 0) printf("SNMP_DPI_GET for ");
var_oid = hdr->packet_body.dpi_get->object_id;
break;
case SNMP_DPI_GET_NEXT:
if (debug_lvl > 0) printf("SNMP_DPI_GET_NEXT for ");
var_oid = hdr->packet_body.dpi_next->object_id;
var_gid = hdr->packet_body.dpi_next->group_id;
break;
case SNMP_DPI_SET:
if (debug_lvl > 0) printf("SNMP_DPI_SET for ");
var_value_len = hdr->packet_body.dpi_set->value_len;
var_value = hdr->packet_body.dpi_set->value;
var_oid = hdr->packet_body.dpi_set->object_id;
var_type = hdr->packet_body.dpi_set->type;
break;
default: /* Return a GEN_ERROR */
if (debug_lvl > 0) printf("Unexpected packet_type %d, genErr\n",
hdr->packet_type);
packet = mkDPIresponse(SNMP_GEN_ERR, NULL);
fDPIparse(hdr); /* return storage allocated by pDPIpacket() */
send_packet(packet);
return;
break;
} /* end switch(hdr->packet_type) */
if (debug_lvl > 0) printf("objectID: %s \n",var_oid);
if (strlen(var_oid) <= strlen(OID)) { /* not in our tree */
if (hdr->packet_type == SNMP_DPI_GET_NEXT) var_index = 0; /* OK */
else { /* cannot handle */
if (debug_lvl>0) printf("...Ignored %s, noSuchName\n",var_oid);
packet = mkDPIresponse(SNMP_NO_SUCH_NAME, NULL);
fDPIparse(hdr); /* return storage allocated by pDPIpacket() */
send_packet(packet);
return;
}
} else { /* Extract our variable index (from OID.index.instance) */
/* We handle any instance the same (we only have one instance) */
var_index = atoi(&var_oid[strlen(OID)]);
}
if (debug_lvl > 1) {
printf("...The groupID=%s\n",var_gid);
printf("...Handle as if objectID=%s%d\n",OID,var_index);
}
switch (hdr->packet_type) {
case SNMP_DPI_GET:
do_get(); /* do a get to return response */
break;
case SNMP_DPI_GET_NEXT:
{ char toid[256]; /* space for temporary objectID */
var_index++; /* do a get for the next variable */
sprintf(toid,"%s%d",OID,var_index); /* construct objectID */
var_oid = toid; /* point to it */
do_get(); /* do a get to return response */
} break;
case SNMP_DPI_SET:
if (debug_lvl > 1) printf("...value_type=%d\n",var_type);
do_set(); /* set new value first */
if (packet) break; /* some error response was generated */
do_get(); /* do a get to return response */
break;
}
fDPIparse(hdr); /* return storage allocated by pDPIpacket() */
}
#ifdef _NO_PROTO /* for classic K&R C */
static void do_get() /* handle SNMP_GET request */
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void do_get(void) /* handle SNMP_GET request */
#endif /* _NO_PROTO */
{
struct dpi_set_packet *data = NULL;
switch (var_index) {
case 0: /* table, cannot be queried by itself */
printf("...Should not issue GET for table %s.0\n", OID);
break;
case 1: /* a number */
data = mkDPIset(var_oid,SNMP_TYPE_NUMBER,sizeof(number),&number);
break;
case 2: /* an octet_string (can have binary data) */
data = mkDPIset(var_oid,SNMP_TYPE_STRING,ostring_len,ostring);
break;
case 3: /* object id */
data = mkDPIset(var_oid,SNMP_TYPE_OBJECT,objectID_len,objectID);
break;
case 4: /* some empty variable */
data = mkDPIset(var_oid,SNMP_TYPE_EMPTY,0,NULL);
break;
case 5: /* internet address */
data = mkDPIset(var_oid,SNMP_TYPE_INTERNET,sizeof(ipaddr),&ipaddr);
break;
case 6: /* counter (unsigned) */
data =mkDPIset(var_oid,SNMP_TYPE_COUNTER,sizeof(counter),&counter);
break;
case 7: /* gauge (unsigned) */
data = mkDPIset(var_oid,SNMP_TYPE_GAUGE,sizeof(gauge),&gauge);
break;
case 8: /* time ticks (unsigned) */
data = mkDPIset(var_oid,SNMP_TYPE_TICKS,sizeof(ticks),&ticks);
break;
case 9: /* a display_string (printable ascii only) */
DO_ETOA(dstring);
data = mkDPIset(var_oid,SNMP_TYPE_STRING,strlen(dstring),dstring);
DO_ATOE(dstring);
break;
case 10: /* a command request (command is a display string) */
DO_ETOA(command);
data = mkDPIset(var_oid,SNMP_TYPE_STRING,strlen(command),command);
DO_ATOE(command);
break;
default: /* Return a NoSuchName */
if (debug_lvl > 1)
printf("...GET[NEXT] for %s, not found\n", var_oid);
break;
} /* end switch (var_index) */
if (data) {
if (debug_lvl > 0) {
printf("...Sending response oid: %s type: %d\n",
var_oid, data->type);
printf("......Current value: ");
print_val(var_index); /* prints \n at end */
}
packet = mkDPIresponse(SNMP_NO_ERROR,data);
} else { /* Could have been an error in mkDPIset though */
if (debug_lvl > 0) printf("...Sending response noSuchName\n");
packet = mkDPIresponse(SNMP_NO_SUCH_NAME,NULL);
} /* end if (data) */
if (packet) send_packet(packet);
}
#ifdef _NO_PROTO /* for classic K&R C */
static void do_set() /* handle SNMP_SET request */
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void do_set(void) /* handle SNMP_SET request */
#endif /* _NO_PROTO */
{
unsigned long *ulp;
long *lp;
if (valid_types[var_index] != var_type &&
valid_types[var_index] != -1) {
printf("...Ignored set request with type %d, expect type %d,",
var_type, valid_types[var_index]);
printf(" Returning badValue\n");
packet = mkDPIresponse(SNMP_BAD_VALUE, NULL);
if (packet) send_packet(packet);
return;
}
switch (var_index) {
case 0: /* table, cannot set table. */
if (debug_lvl > 0) printf("...Ignored set TABLE, noSuchName\n");
packet = mkDPIresponse(SNMP_NO_SUCH_NAME,NULL);
break;
case 1: /* a number */
lp = (long *)var_value;
number = *lp;
break;
case 2: /* an octet_string (can have binary data) */
free(ostring);
ostring = (char *)malloc(var_value_len + 1);
bcopy(var_value, ostring, var_value_len);
ostring_len = var_value_len;
ostring[var_value_len] = '\0'; /* so we can use it as a string */
break;
case 3: /* object id */
free(objectID);
objectID = (char *)malloc(var_value_len + 1);
bcopy(var_value, objectID, var_value_len);
objectID_len = var_value_len;
if (objectID[objectID_len -1]) {
objectID[objectID_len++] = '\0'; /* a valid one needs a null */
if (debug_lvl > 0)
printf("...added a terminating null to objectID\n");
}
break;
case 4: /* an empty variable, cannot set */
if (debug_lvl > 0) printf("...Ignored set EMPTY, readOnly\n");
packet = mkDPIresponse(SNMP_READ_ONLY,NULL);
break;
case 5: /* Internet address */
ulp = (unsigned long *)var_value;
ipaddr = *ulp;
break;
case 6: /* counter (unsigned) */
ulp = (unsigned long *)var_value;
counter = *ulp;
break;
case 7: /* gauge (unsigned) */
ulp = (unsigned long *)var_value;
gauge = *ulp;
break;
case 8: /* time ticks (unsigned) */
ulp = (unsigned long *)var_value;
ticks = *ulp;
break;
case 9: /* a display_string (printable ascii only) */
free(dstring);
dstring = (char *)malloc(var_value_len + 1);
bcopy(var_value, dstring, var_value_len);
dstring[var_value_len] = '\0'; /* so we can use it as a string */
DO_ATOE(dstring);
break;
case 10: /* a request to execute a command */
free(command);
command = (char *)malloc(var_value_len + 1);
bcopy(var_value, command, var_value_len);
command[var_value_len] = '\0'; /* so we can use it as a string */
DO_ATOE(command);
if (strcmp("all_traps",command) == 0) do_trap = ALL_TRAPS;
else if (strcmp("std_traps",command) == 0) do_trap = STD_TRAPS;
else if (strcmp("ent_traps",command) == 0) do_trap = ENT_TRAPS;
else if (strcmp("ent_trapse",command) == 0) do_trap = ENT_TRAPSE;
else if (strcmp("all_traps",command) == 0) do_trap = ALL_TRAPS;
else if (strcmp("quit",command) == 0) do_quit = TRUE;
else break;
if (debug_lvl > 0)
printf("...Action requested: %s set to: %s\n",
DPI_var[10], command);
break;
default: /* NoSuchName */
if (debug_lvl > 0)
printf("...Ignored set for %s, noSuchName\n", var_oid);
packet = mkDPIresponse(SNMP_NO_SUCH_NAME,NULL);
break;
} /* end switch (var_index) */
if (packet) send_packet(packet);
}
#ifdef _NO_PROTO /* for classic K&R C */
static void issue_std_traps()
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void issue_std_traps(void)
#endif /* _NO_PROTO */
{
trap_stype = 0;
trap_data = dpi_hostname;
for (trap_gtype=0; trap_gtype<6; trap_gtype++) {
issue_one_trap();
if (trap_gtype == 0) sleep(10); /* some managers purge cache */
}
}
#ifdef _NO_PROTO /* for classic K&R C */
static void issue_ent_traps()
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void issue_ent_traps(void)
#endif /* _NO_PROTO */
{
char temp_string[256];
trap_gtype = 6;
for (trap_stype = 1; trap_stype < 10; trap_stype++) {
trap_data = temp_string;
switch (trap_stype) {
case 1 :
sprintf(temp_string,"%ld",number);
break;
case 2 :
sprintf(temp_string,"%s",ostring);
break;
case 3 :
trap_data = objectID;
break;
case 4 :
trap_data = "";
break;
case 5 :
trap_data = dpi_hostname;
break;
case 6 :
sleep(1); /* give manager a break */
sprintf(temp_string,"%lu",counter);
break;
case 7 :
sprintf(temp_string,"%lu",gauge);
break;
case 8 :
sprintf(temp_string,"%lu",ticks);
break;
case 9 :
trap_data = dstring;
break;
} /* end switch (trap_stype) */
issue_one_trap();
}
}
/* issue a set of extended traps, pass enterprise ID and multiple
* variable (assume octect string) as passed by caller
*/
#ifdef _NO_PROTO /* for classic K&R C */
static void issue_ent_trapse()
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void issue_ent_trapse(void)
#endif /* _NO_PROTO */
{
int i, n;
struct dpi_set_packet *data = NULL;
unsigned char *packet = NULL;
unsigned long ipaddr, ulnum;
char oid[256];
char *cp;
trape_gtype = 6;
trape_eprise = ENTERPRISE_OID;
for (n=11; n < (11+OID_COUNT_FOR_TRAPS); n++) {
data = 0;
trape_stype = n;
for (i=1; i<=(n-10); i++)
data = addtoset(data, i);
if (data == 0) {
printf("Could not make dpi_set_packet\n");
return;
}
packet = mkDPItrape(trape_gtype,trape_stype,data,trape_eprise);
if ((debug_lvl > 0) && (packet)) {
printf("sending trape packet: %lu %lu enterprise=%s\n",
trape_gtype, trape_stype, trape_eprise);
}
if (packet) send_packet(packet);
else printf("Could not make trape packet\n");
}
}
/* issue one extended trap, pass enterprise ID and multiple
* variable (assume octect string) as passed by caller
*/
#ifdef _NO_PROTO /* for classic K&R C */
static void issue_one_trape()
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void issue_one_trape(void)
#endif /* _NO_PROTO */
{
struct dpi_set_packet *data = NULL;
unsigned char *packet = NULL;
char oid[256];
char *cp;
int i;
for (i=0; i<trape_datacnt; i++) {
sprintf(oid,"%s2.%d",OID,i);
/* assume an octet_string (could have hex data) */
data = mkDPIlist(data, oid, SNMP_TYPE_STRING,
strlen(trape_data[i]), trape_data[i]);
if (data == 0) {
printf("Could not make dpiset_packet\n");
} else if (debug_lvl > 0) {
printf("Preparing: [oid=%s] value: ", oid);
printf("'");
for (cp = trape_data[i]; *cp; cp++) /* loop through data */
printf("%2.2x",*cp); /* hex print one byte */
printf("'H\n");
}
}
packet = mkDPItrape(trape_gtype,trape_stype,data,trape_eprise);
if ((debug_lvl > 0) && (packet)) {
printf("sending trape packet: %lu %lu enterprise=%s\n",
trape_gtype, trape_stype, trape_eprise);
}
if (packet) send_packet(packet);
else printf("Could not make trape packet\n");
}
#ifdef _NO_PROTO /* for classic K&R C */
static void issue_one_trap()
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void issue_one_trap(void)
#endif /* _NO_PROTO */
{
long int num; /* must be 4 bytes */
struct dpi_set_packet *data = NULL;
unsigned char *packet = NULL;
unsigned long ipaddr, ulnum;
char oid[256];
char *cp;
switch (trap_gtype) {
/* all traps are handled more or less the same sofar. */
/* could put specific handling here if needed/wanted. */
case 0: /* simulate cold start */
case 1: /* simulate warm start */
case 4: /* simulate authentication failure */
strcpy(oid,"none");
break;
case 2: /* simulate link down */
case 3: /* simulate link up */
strcpy(oid,ifIndex);
num = 1;
data = mkDPIset(oid, SNMP_TYPE_NUMBER, sizeof(num), &num);
break;
case 5: /* simulate EGP neighbor loss */
strcpy(oid,egpNeighAddr);
ipaddr = lookup_host(trap_data);
data = mkDPIset(oid, SNMP_TYPE_INTERNET, sizeof(ipaddr), &ipaddr);
break;
case 6: /* simulate enterprise specific trap */
sprintf(oid,"%s%d.0",OID, trap_stype);
switch (trap_stype) {
case 1: /* a number */
num = strtol(trap_data,(char **)0,10);
data = mkDPIset(oid, SNMP_TYPE_NUMBER, sizeof(num), &num);
break;
case 2: /* an octet_string (could have hex data) */
data = mkDPIset(oid,SNMP_TYPE_STRING,strlen(trap_data),trap_data);
break;
case 3: /* object id */
data = mkDPIset(oid,SNMP_TYPE_OBJECT,strlen(trap_data) + 1,
trap_data);
break;
case 4: /* an empty variable value */
data = mkDPIset(oid, SNMP_TYPE_EMPTY, 0, 0);
break;
case 5: /* internet address */
ipaddr = lookup_host(trap_data);
data = mkDPIset(oid, SNMP_TYPE_INTERNET, sizeof(ipaddr), &ipaddr);
break;
case 6: /* counter (unsigned) */
ulnum = strtoul(trap_data,(char **)0,10);
data = mkDPIset(oid, SNMP_TYPE_COUNTER, sizeof(ulnum), &ulnum);
break;
case 7: /* gauge (unsigned) */
ulnum = strtoul(trap_data,(char **)0,10);
data = mkDPIset(oid, SNMP_TYPE_GAUGE, sizeof(ulnum), &ulnum);
break;
case 8: /* time ticks (unsigned) */
ulnum = strtoul(trap_data,(char **)0,10);
data = mkDPIset(oid, SNMP_TYPE_TICKS, sizeof(num), &ulnum);
break;
case 9: /* a display_string (ascii only) */
DO_ETOA(trap_data);
data = mkDPIset(oid,SNMP_TYPE_STRING,strlen(trap_data),trap_data);
DO_ATOE(trap_data);
break;
default: /* handle as string */
printf("Unknown specific trap type: %s, assume octet_string\n",
trap_stype);
data = mkDPIset(oid,SNMP_TYPE_STRING,strlen(trap_data),trap_data);
break;
} /* end switch (trap_stype) */
break;
default: /* unknown trap */
printf("Unknown general trap type: %s\n", trap_gtype);
return;
break;
} /* end switch (trap_gtype) */
packet = mkDPItrap(trap_gtype,trap_stype,data);
if ((debug_lvl > 0) && (packet)) {
printf("sending trap packet: %u %u [oid=%s] value: ",
trap_gtype, trap_stype, oid);
if (trap_stype == 2) {
printf("'");
for (cp = trap_data; *cp; cp++) /* loop through data */
printf("%2.2x",*cp); /* hex print one byte */
printf("'H\n");
} else printf("%s\n", trap_data);
}
if (packet) send_packet(packet);
else printf("Could not make trap packet\n");
}
#ifdef _NO_PROTO /* for classic K&R C */
static void send_packet(packet) /* DPI packet to agent */
char *packet;
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void send_packet(const char *packet) /* DPI packet to agent */
#endif /* _NO_PROTO */
{
int rc;
if (debug_lvl > 2) {
printf("...Sending DPI packet:\n");
dump_bfr(packet, PACKET_LEN(packet));
}
#ifdef OS2
rc = send(dpi_fd,packet,PACKET_LEN(packet),0);
#else
rc = write(dpi_fd,packet,PACKET_LEN(packet));
#endif
if (rc != PACKET_LEN(packet)) DO_ERROR("send_packet: write");
/* no need to free packet (static buffer in mkDPI.... routine) */
}
#ifdef _NO_PROTO /* for classic K&R C */
static void do_register() /* register our objectIDs with agent */
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void do_register(void) /* register our objectIDs with agent */
#endif /* _NO_PROTO */
{
int i, rc;
char toid[256];
if (debug_lvl > 0) printf("Registering variables:\n");
for (i=1; i<=OID_COUNT; i++) {
sprintf(toid,"%s%d.",OID,i);
packet = mkDPIregister(toid);
#ifdef OS2
rc = send(dpi_fd, packet, PACKET_LEN(packet),0);
#else
rc = write(dpi_fd, packet, PACKET_LEN(packet));
#endif
if (rc <= 0) {
DO_ERROR("do_register: write");
printf("Quitting, unsuccessful register for %s\n",toid);
close(dpi_fd);
exit(1);
}
if (debug_lvl > 0) {
printf("...Registered: %-25s oid: %s\n",DPI_var[i],toid);
printf("......Initial value: ");
print_val(i); /* prints \n at end */
}
}
}
/* add specified variable to list of variable in the dpi_set_packet
*/
#ifdef _NO_PROTO /* for classic K&R C */
struct dpi_set_packet *addtoset(data, stype)
struct dpi_set_packet *data;
int stype;
#else /* _NO_PROTO */ /* for ANSI-C compiler */
struct dpi_set_packet *addtoset(struct dpi_set_packet *data, int stype)
#endif /* _NO_PROTO */
{
char var_oid[256];
sprintf(var_oid,"%s%d.0",OID, stype);
switch (stype) {
case 1: /* a number */
data = mkDPIlist(data, var_oid, SNMP_TYPE_NUMBER,
sizeof(number), &number);
break;
case 2: /* an octet_string (can have binary data) */
data = mkDPIlist(data, var_oid, SNMP_TYPE_STRING,
ostring_len, ostring);
break;
case 3: /* object id */
data = mkDPIlist(data, var_oid, SNMP_TYPE_OBJECT,
objectID_len, objectID);
break;
case 4: /* some empty variable */
data = mkDPIlist(data, var_oid, SNMP_TYPE_EMPTY, 0, NULL);
break;
case 5: /* internet address */
data = mkDPIlist(data, var_oid, SNMP_TYPE_INTERNET,
sizeof(ipaddr), &ipaddr);
break;
case 6: /* counter (unsigned) */
data =mkDPIlist(data, var_oid, SNMP_TYPE_COUNTER,
sizeof(counter), &counter);
break;
case 7: /* gauge (unsigned) */
data = mkDPIlist(data, var_oid, SNMP_TYPE_GAUGE,
sizeof(gauge), &gauge);
break;
case 8: /* time ticks (unsigned) */
data = mkDPIlist(data, var_oid, SNMP_TYPE_TICKS,
sizeof(ticks), &ticks);
break;
case 9: /* a display_string (printable ascii only) */
DO_ETOA(dstring);
data = mkDPIlist(data, var_oid, SNMP_TYPE_STRING,
strlen(dstring), dstring);
DO_ATOE(dstring);
break;
} /* end switch (stype) */
return(data);
}
#ifdef _NO_PROTO /* for classic K&R C */
static void print_val(index)
int index;
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void print_val(const int index)
#endif /* _NO_PROTO */
{
char *cp;
struct in_addr display_ipaddr;
switch (index) {
case 1 :
printf("%ld\n",number);
break;
case 2 :
printf("'");
for (cp = ostring; cp < ostring + ostring_len; cp++)
printf("%2.2x",*cp);
printf("'H\n");
break;
case 3 :
printf("%*s\n", objectID_len, objectID);
break;
case 4 :
printf("no value (EMPTY)\n");
break;
case 5 :
display_ipaddr.s_addr = (u_long) ipaddr;
printf("%s\n",inet_ntoa(display_ipaddr));
/* This worked on VM, MVS and AIX, but not on OS/2
* printf("%d.%d.%d.%d\n", (ipaddr >> 24), ((ipaddr << 8) >> 24),
* ((ipaddr << 16) >> 24), ((ipaddr << 24) >> 24));
*/
break;
case 6 :
printf("%lu\n",counter);
break;
case 7 :
printf("%lu\n",gauge);
break;
case 8 :
printf("%lu\n",ticks);
break;
case 9 :
printf("%s\n",dstring);
break;
case 10 :
printf("%s\n",command);
break;
} /* end switch(index) */
}
#ifdef _NO_PROTO /* for classic K&R C */
static void check_arguments(argc, argv) /* check arguments */
int argc;
char *argv[];
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void check_arguments(const int argc, char *argv[])
#endif /* _NO_PROTO */
{
char *hname, *cname;
int i, j;
dpi_userid = hname = cname = NULL;
for (i=1; argc > i; i++) {
if (strcmp(argv[i],"-d") == 0) {
i++;
if (argc > i) {
debug_lvl = atoi(argv[i]);
if (debug_lvl >= 5) {
DPIdebug(1);
}
}
} else if (strcmp(argv[i],"-trap") == 0) {
if (argc > i+3) {
trap_gtype = atoi(argv[i+1]);
trap_stype = atoi(argv[i+2]);
trap_data = argv[i+3];
i = i + 3;
do_trap = ONE_TRAP;
} else usage(argv[0], 1);
} else if (strcmp(argv[i],"-trape") == 0) {
if (argc > i+4) {
trape_gtype = strtoul(argv[i+1],(char**)0,10);
trape_stype = strtoul(argv[i+2],(char**)0,10);
trape_eprise = argv[i+3];
for (i = i + 4, j = 0;
(argc > i) && (j < MAX_TRAPE_DATA);
i++, j++) {
trape_data[j] = argv[i];
}
trape_datacnt = j;
do_trap = ONE_TRAPE;
break; /* -trape must be last option */
} else usage(argv[0], 1);
} else if (strcmp(argv[i],"-all_traps") == 0) {
do_trap = ALL_TRAPS;
} else if (strcmp(argv[i],"-std_traps") == 0) {
do_trap = STD_TRAPS;
} else if (strcmp(argv[i],"-ent_traps") == 0) {
do_trap = ENT_TRAPS;
} else if (strcmp(argv[i],"-ent_trapse") == 0) {
do_trap = ENT_TRAPSE;
#if defined(VM) || defined(MVS)
} else if (strcmp(argv[i],"-inet") == 0) {
use_iucv = 0;
} else if (strcmp(argv[i],"-iucv") == 0) {
use_iucv = TRUE;
} else if (strcmp(argv[i],"-u") == 0) {
use_iucv = TRUE; /* -u implies -iucv */
i++;
if (argc > i) {
dpi_userid = argv[i];
}
#endif
} else if (strcmp(argv[i],"?") == 0) {
usage(argv[0], 0);
} else {
if (hname == NULL) hname = argv[i];
else if (cname == NULL) cname = argv[i];
else usage(argv[0], 1);
}
}
if (hname == NULL) hname = LOOPBACK; /* use default */
if (cname == NULL) cname = PUBLIC_COMMUNITY_NAME; /* use default */
#if defined(VM) || defined(MVS)
if (dpi_userid == NULL) dpi_userid = SNMPAGENTUSERID;
if (debug_lvl > 2)
printf("hname=%s, cname=%s, userid=%s\n",hname,cname,dpi_userid);
#else
if (debug_lvl > 2)
printf("hname=%s, cname=%s\n",hname,cname);
#endif
if (use_iucv != TRUE) {
DO_ETOA(cname); /* for VM or MVS */
dpi_port = query_DPI_port(hname,cname);
DO_ATOE(cname); /* for VM or MVS */
if (dpi_port == -1) {
printf("No response from agent at %s(%s)\n",hname,cname);
exit(1);
}
} else dpi_port == -1;
dpi_hostname = hname;
}
#ifdef _NO_PROTO /* for classic K&R C */
static void usage(pname, exit_rc)
char *pname;
int exit_rc;
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void usage(const char *pname, const int exit_rc)
#endif /* _NO_PROTO */
{
printf("Usage: %s [-d debug_lvl] [-trap g_type s_type data]", pname);
printf(" [-all_traps]\n");
printf("%*s[-trape g_type s_type enterprise data1 data2 .. datan]\n",
strlen(pname)+8,"");
printf("%*s[-std_traps] [-ent_traps] [-ent_trapse]\n",
strlen(pname)+8,"");
#if defined(VM) || defined(MVS)
printf("%*s[-iucv] [-u agent_userid]\n",strlen(pname)+8, "");
printf("%*s", strlen(pname)+8, "");
printf("[-inet] [agent_hostname [community_name]]\n");
printf("default: -d 0 -iucv -u %s\n", SNMPAGENTUSERID);
printf(" -inet %s %s\n", LOOPBACK, PUBLIC_COMMUNITY_NAME);
#else
printf("%*s[agent_hostname [community_name]]\n",strlen(pname)+8,"");
printf("default: -d 0 %s %s\n", LOOPBACK, PUBLIC_COMMUNITY_NAME);
#endif
exit(exit_rc);
}
#ifdef _NO_PROTO /* for classic K&R C */
static void init_variables() /* initialize our variables */
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void init_variables(void) /* initialize our variables */
#endif /* _NO_PROTO */
{
char ch, *cp;
ostring = (char *)malloc(strlen(OSTRING) + 4 + 1 );
bcopy(OSTRING,ostring,strlen(OSTRING));
ostring_len = strlen(OSTRING);
for (ch=1;ch<5;ch++) /* add hex data 0x01020304 */
ostring[ostring_len++] = ch;
ostring[ostring_len] = '\0'; /* so we can use it as a string */
objectID = (char *)malloc(strlen(OID));
objectID_len = strlen(OID);
bcopy(OID,objectID,strlen(OID));
if (objectID[objectID_len - 1] == '.') /* if trailing dot, */
objectID[objectID_len - 1] = '\0'; /* remove it */
else objectID_len++; /* length includes null */
dstring = (char *)malloc(strlen(DSTRING)+1);
bcopy(DSTRING,dstring,strlen(DSTRING)+1);
command = (char *)malloc(strlen(COMMAND)+1);
bcopy(COMMAND,command,strlen(COMMAND)+1);
ipaddr = dpi_ipaddress;
}
#ifdef _NO_PROTO /* for classic K&R C */
static void init_connection() /* connect to the DPI agent */
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void init_connection(void) /* connect to the DPI agent */
#endif /* _NO_PROTO */
{
int rc;
int sasize; /* size of socket structure */
struct sockaddr_in sin; /* socket address AF_INET */
struct sockaddr *sa; /* socket address general */
#if defined(VM) || defined (MVS)
struct sockaddr_iucv siu; /* socket address AF_IUCV */
if (use_iucv == TRUE) {
printf("Connecting to %s DPI_port %d userid %s (TCP, AF_IUCV)\n",
dpi_hostname,dpi_port,dpi_userid);
bzero(&siu,sizeof(siu));
siu.siucv_family = AF_IUCV;
siu.siucv_addr = dpi_ipaddress;
siu.siucv_port = dpi_port;
memset(siu.siucv_nodeid, ' ', sizeof(siu.siucv_nodeid));
memset(siu.siucv_userid, ' ', sizeof(siu.siucv_userid));
memset(siu.siucv_name, ' ', sizeof(siu.siucv_name));
bcopy(dpi_userid, siu.siucv_userid, min(8,strlen(dpi_userid)));
bcopy(SNMPIUCVNAME, siu.siucv_name, min(8,strlen(SNMPIUCVNAME)));
dpi_fd = socket(AF_IUCV, SOCK_STREAM, 0);
sa = (struct sockaddr *) &siu;
sasize = sizeof(struct sockaddr_iucv);
} else {
#endif
printf("Connecting to %s DPI_port %d (TCP, AF_INET)\n",
dpi_hostname,dpi_port);
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(dpi_port);
sin.sin_addr.s_addr = dpi_ipaddress;
dpi_fd = socket(AF_INET, SOCK_STREAM, 0);
sa = (struct sockaddr *) &sin;
sasize = sizeof(struct sockaddr_in);
#if defined(VM) || defined (MVS)
}
#endif
if (dpi_fd < 0) { /* exit on error */
DO_ERROR("init_connection: socket");
exit(1);
}
rc = connect(dpi_fd, sa, sasize); /* connect to agent */
if (rc != 0) { /* exit on error */
DO_ERROR("init_connection: connect");
close(dpi_fd);
exit(1);
}
}
#ifdef _NO_PROTO /* for classic K&R C */
static void dump_bfr(buf, len) /* hex dump buffer */
char *buf;
int len;
#else /* _NO_PROTO */ /* for ANSI-C compiler */
static void dump_bfr(const char *buf, const int len)
#endif /* _NO_PROTO */
{
register int i;
if (len == 0) printf(" empty buffer\n"); /* buffer is empty */
for (i=0;i<len;i++) { /* loop through buffer */
if ((i&15) == 0) printf(" "); /* indent new line */
printf("%2.2x",(unsigned char)buf[i]);/* hex print one byte */
if ((i&15) == 15) printf("\n"); /* nl every 16 bytes */
else if ((i&3) == 3) printf(" "); /* space every 4 bytes */
}
if (i&15) printf("\n"); /* always end with nl */
}