After registering your sample MIB subtree with the agent,
expect that SNMP requests for that subtree are passed back to you
for processing. Because the requests arrive in the form of DPI packets on
the connection that you have established, go into a While loop to
await DPI packets
from the agent.
Because the subagent cannot know in advance
which kind of packet arrives from the agent, await a DPI packet (forever),
then parse the packet, check the packet type, and process the request
based on the DPI packet type. A call to pDPIpacket, which expects as parameter a
pointer to the encoded or serialized DPI packet, returns a pointer to a DPI parse tree.
The pointer points to an snmp_dpi_hdr structure which looks as follows:
struct snmp_dpi_hdr {
unsigned char proto_major;
unsigned char proto_version;
unsigned char proto_release;
unsigned short packet_id;
unsigned char packet_type;
union {
snmp_dpi_reg_packet *reg_p;
snmp_dpi_ureg_packet *ureg_p;
snmp_dpi_get_packet *get_p;
snmp_dpi_next_packet *next_p;
snmp_dpi_next_packet *bulk_p;
snmp_dpi_set_packet *set_p;
snmp_dpi_resp_packet *resp_p;
snmp_dpi_trap_packet *trap_p;
snmp_dpi_open_packet *open_p;
snmp_dpi_close_packet *close_p;
unsigned char *any_p;
} data_u;
};
typedef struct snmp_dpi_hdr snmp_dpi_hdr;
#define snmp_dpi_hdr_NULL_p ((snmp_dpi_hdr *)0)
With the DPI parse tree, you decide how to process the DPI packet. The following code example
demonstrates the high-level process of a DPI subagent.
main(int argc, char
*argv[], char *envp][{}[][])
{
unsigned char *packet_p;
int i = 0;
int rc = 0;
#ifndef DPI_VERY_MINIMAL_SUBAGENT /* with VERY minimal agent
*/
int debug = 0;
#endif /* ndef DPI_VERY_MINIMAL_SUBAGENT */
unsigned long length;
snmp_dpi_hdr *hdr_p;
char *hostname_p = NULL; /* @L1C*/
char *community_p = SNMP_COMMUNITY;
char *cmd_p = "";
char hostname[MAX_HOSTNAME_LEN+1]; /*
@L1A*/
if (argc >= 1) cmd_p = argv[0];
for (i=1; i < argc; i++) {
if (strcmp(argv[i],"-h") == 0) {
if (i+1 >= argc) {
printf("Need hostname\n\n");
usage(cmd_p);
} /* endif */
hostname_p = argv[++i];
#ifndef DPI_VERY_MINIMAL_SUBAGENT /* with VERY minimal agent
*/
} else if (strcmp(argv[i],"-c") == 0) {
if (i+1 >= argc) {
printf("Need community name\n\n");
usage(cmd_p);
} /* endif */
community_p = argv[++i];
#ifdef INCLUDE_UNIX_DOMAIN_FOR_DPI
} else if (strcmp(argv[i],"-unix") == 0) {
unix_sock = 1;
#endif /* def INCLUDE_UNIX_DOMAIN_FOR_DPI */
} else if (strcmp(argv[i],"-ireg") == 0) {
instance_level = 1;
} else if (strcmp(argv[i],"-d") == 0) {
if (i+1 >= argc) {
debug = 1;
continue;
}
if ((strlen(argv[i+1]) == 1) && isdigit(*argv[i+1]))
{
i++;
debug = atoi(argv[i]);
} else {
debug = 1;
} /* endif */
#endif /* ndef DPI_VERY_MINIMAL_SUBAGENT */
} else {
usage(cmd_p);
} /* endif */
} /* endfor */
#ifndef DPI_VERY_MINIMAL_SUBAGENT
if (debug) {
printf("\n%s - %s\n",__FILE__, VERSION);
DPIdebug(debug); /* turn on DPI dubugging
*/
timeout += 6; /* longer timeout please
*/
} /* endif */
#endif /* ndef DPI_VERY_MINIMAL_SUBAGENT */
if (hostname_p == NULL) { /* -h not specified. Try
to
obtain local host name
@L1A*/
if (gethostname(hostname, MAX_HOSTNAME_LEN) != 0) {
printf("\ngethostname failed. "
"Restart with -h parameter.\n\n"); /* @L1A*/
exit(1); /* @L1A*/
}
else { /* gethostname worked @L1A*/
hostname_p = hostname; /* @L1A*/
} /* @L1A*/
} /* -h not specified @L1A*/
/* first init value2_p, our dpiSimpleString (DisplayString)
*/
/* since we treat it as display string keep terminating NULL
*/
value2_p = (char *) malloc(strlen("Initial String")+1);
if (value2_p) {
memcpy(value2_p,"Initial String",strlen("Initial String")+1);
value2_len = strlen("Initial String")+1;
} /* endif */
do_connect_and_open(hostname_p,
community_p); /* connect and DPI-OPEN
*/
do_register(); /* register our subtree
*/
do_trap(); /* issue a trap as sample
*/
while (rc == 0) { /* do forever
*/
rc = DPIawait_packet_from_agent( /* wait for a DPI packet
*/
handle, /* on this connection
*/
-1, /* wait forever
*/
&packet_p, /* receives ptr to packet
*/
&length); /* receives packet length
*/
if (rc != DPI_RC_OK) exit(1); /* If it failed, exit
*/
hdr_p = pDPIpacket(packet_p); /* parse DPI packet
*/
if (hdr_p == snmp_dpi_hdr_NULL_p)/* If we fail to parse it
*/
exit(1); /* then exit
*/
switch(hdr_p->packet_type) { /* handle by DPI type
*/
case SNMP_DPI_GET:
rc = do_get(hdr_p,
hdr_p->data_u.get_p);
break;
case SNMP_DPI_GETNEXT:
rc = do_next(hdr_p,
hdr_p->data_u.next_p);
break;
case SNMP_DPI_SET:
case SNMP_DPI_COMMIT:
case SNMP_DPI_UNDO:
rc = do_set(hdr_p,
hdr_p->data_u.set_p);
break;
case SNMP_DPI_CLOSE:
rc = do_close(hdr_p,
hdr_p->data_u.close_p);
break;
case SNMP_DPI_UNREGISTER:
rc = do_unreg(hdr_p,
hdr_p->data_u.ureg_p);
break;
default:
printf("Unexpected DPI packet type %d\n",
hdr_p->packet_type);
rc = -1;
} /* endswitch */
if (rc) exit(1);
} /* endwhile */
return(0);
} /* end of main() */