Processing Requests from the Agent

After we have registered our sample MIB sub-tree with the agent, we must expect that SNMP requests for that sub-tree will be passed for processing by us. Since the requests will arrive in the form of DPI packets on the connection that the we have established, we go into a while loop to await DPI packets from the agent.

Since the subagent cannot know in advance which kind of packet arrives from the agent, we await a DPI packet (forever), then we 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/serialized DPI packet, returns a pointer to a DPI parse tree. The pointer points to a 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, we decide how to process the DPI packet. The following code example demonstrates the high level process of a DPI subagent.

#include <snmp_dpi.h>              /* DPI 2.0 API definitions */
static int handle;                 /* handle has global scope */

main(int argc, char *argvφ∙, char *envpφ∙)
{
  unsigned char *packet_p;
  int            rc = 0;
  unsigned long  length;
  snmp_dpi_hdr  *hdr_p;

  if (argc>1) {                     /* if use passed one parm */
     if (strcmp(argvφ1∙,"-d")==0)   /* being -d, then we      */
         DPIdebug(2);               /* turn on DPI debugging  */
  } /* endif */                     /* which shows us things  */

  do_connect_and_open();            /* connect and DPI-OPEN   */

  do_register();                    /* register our sub-tree  */

  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() */


[Back: Registering a Sub-Tree with the Agent]
[Next: Processing a GET Request]