Using SNMP Manager APIs--Example

The examples in this topic provide two small routines that may aid in the use of several SNMP manager APIs. In addition, a sample snmpGet loop is provided to show the use of the two sample programs and its relation to an snmpGet call.

These examples are for the SNMP manager APIs snmpGet, snmpSet, and snmpGetnext.

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.


AddVarbind Routine

This routine is used to create an initial protocol data unit (PDU), and subsequent calls will add varbinds to that PDU.

The value of this routine is that you will be able to create PDUs and add varbinds to those PDUs. The burden of storage allocation for each varbind and its values is removed from you, as is pointer maintenance on the varbinds. Remember that you need to deallocate any dynamic storage when you are done with it. The FreePdu routine (see page FreePdu Routine) is an easy way to do this. The AddVarbind sample code follows:

#include <qtomeapi.h>

int AddVarbind(snmppdu **pdu, char * oid, value v, unsigned
char pdu_type, unsigned char asn_type)
{

   varBind * t;                           /* Varbind pointer.       */
   int str_len,i;

   switch ( pdu_type ) {                  /* Check to make sure that*/
      case GET_PDU_TYPE:                  /* the PDU type is a known*/
      case SET_PDU_TYPE:                  /* value.  If not, the    */
      case GETNEXT_PDU_TYPE: break;       /* you may want to set a  */
      defaults: return(-2005);            /* return code value of   */
                                          /* your liking (for       */
   }                                      /* example, -2005).       */


   if (pdu[0] == NULL ||
       pdu[0] == 0 ||
       pdu[0] == '\0')
       {                  /* Check if PDU is null (meaning new PDU).*/
          pdu[0] = ( snmppdu *) malloc(sizeof(snmppdu));
                          /* Allocate storage for the PDU.          */
          memset( (snmppdu *) pdu[0],0,sizeof(pdu[0]));
                          /* Initialize the PDU to zeros.           */
          pdu[0]->pdu_type = pdu_type;
                          /* Initialize the PDU type.               */
          pdu[0]->varbind = ( varBind * ) malloc(sizeof(varBind));
                          /* Allocate storage for the varbind.      */
          str_len = strlen(oid);
                          /* Set the length of the OID.             */

         if (str_len > API_MAX_OID_SIZE ) return(-2000);
                          /* If OID length is not valid return.     */
         pdu[0]->varbind->oid =

           (char *) malloc(API_MAX_OID_SIZE+1);
         strcpy(pdu[0]->varbind->oid,oid);          /* Copy the
OID.*/
         pdu[0]->varbind->oid[str_len] = '\0';
                                               /*Null terminate OID.*/
         pdu[0]->varbind->next = NULL;      /* Nullify next
pointer.*/
                                     /* This signifies last varbind.*/
         t = pdu[0]->varbind;   /* Set temporary pointer to
varbind.*/
         t->val.str_val =
           (char *) malloc(API_MAX_VALUE_SIZE+1); /*Allocate storage */
                                         /* for the value of the OID.*/
/*********************************************************************/
/* Note:  This sample code shows a malloc of the maximum value size  */
/* plus 1 for null termination.  It would be in your best interest   */
/* to allocate only the amount of the actual value, plus 1.  This    */
/* reduces the amount of space allocated on each PDU.                */
/*********************************************************************/
   }
   else
   {
      if ( pdu[0]->pdu_type != pdu_type ) \keyword{return(-2001);
                           /* If this is not the initial call to      */
                           /* add a varbind, then check to make       */
                           /* sure the PDU type of this call          */
                           /* matches the original.                   */
      t = pdu[0]->varbind;
                           /* Store temporary pointer to this varbind.*/
      i = 0;               /* Initialize loop variable.               */

      while ( t->next != NULL ) /* Loop until you locate last varbind.*/
      {
         t = t->next;

         i++;

      }

      if ( i > 100 /* MAX_NUM... */ ) \keyword{return(-2002);
                           /* Return if you exceed maximum varbinds.  */
      t->next = ( varBind * ) malloc(sizeof(varBind));
                           /* Allocate storage for this varbind.      */
      t = t->next;         /* Set new temporary varbind pointer.      */
      str_len = strlen(oid);   /* Set length of OID.                  */

      if (str_len > API_MAX_OID_SIZE ) return(-2000);
                             /* If OID length exceed maximum, return. */
      t->oid = (char *) malloc(API_MAX_OID_SIZE+1);
                               /* Allocate storage for the OID.       */
      strcpy(t->oid,oid);
                               /* Copy OID to storage.                */
      t->oid[str_len] = '\0';
                               /* Null terminate the OID.             */
      t->val.str_val = (char *) malloc(API_MAX_VALUE_SIZE+1);
                               /* Allocate storage to hold value.     */
      t->val_len = API_MAX_VALUE_SIZE+1;
/**********************************************************************/
/* Note:  This sample code shows a malloc of the maximum value size   */
/* plus 1 for null termination.  It would be in your best interest    */
/* to allocate only the amount of the actual value, plus 1.  This     */
/* reduces the amount of space allocated on each PDU.                 */
/**********************************************************************/
      t->next = NULL;
                               /* Nullify next varbind pointer        */
   }                           /* signifying the last varbind.        */

   if ( pdu_type == SET_PDU_TYPE )           /* For sets only         */
    {
      t->asn_type = asn_type;                /* Save ASN type         */

      switch (asn_type) {
         case API_ASN_OCTET_STRING:          /* All string types      */
         case API_ASN_OBJECT_IDENTIFIER:
         case API_ASN_IpAddress:
         case API_ASN_Opaque:
            str_len = strlen(v.str_val);        /* Store length       */
            strcpy(t->val.str_val,v.str_val);   /* Copy string        */
            t->val.str_val[str_len] = '\0';
                                                /* Null terminate     */
            t->val_len = str_len;               /* Save length        */
            break;
         case API_ASN_INTEGER:
         case API_ASN_Counter:
         case API_ASN_Gauge:
         case API_ASN_TimeTicks:
            *t->val.int_val = *v.int_val;       /* Save integer value */
            t->val_len = sizeof(int);           /* Save length of     */
            break;                              /* an integer.        */
         default: return(-2003);
      }
   }
   return(API_RC_OK);
}


FreePdu Routine

This routine is used to free all the dynamically allocated storage from AddVarbind.

The value of this routine is that you can free all the dynamically allocated (user domain) storage with one call. The FreePdu sample code follows:

#include <qtomeapi.h>

void FreePdu(snmppdu * pdu)   /* Pass in pointer to PDU.              */
{
   varBind * vb, *t;          /* Define pointers to varbinds.         */

   vb = pdu->varbind;         /* Set first varbind pointer.           */
   while (vb != NULL){        /* Loop as long as varbinds exist.      */
      t = vb;                 /* Save current varbind pointer.        */
      vb = vb->next;          /* Pointer to next varbind.             */
      free(t->oid);           /* Free storage allocated for OID.      */
      free(t->val.str_val);   /* Free storage allocated for value.    */
      free(t);       /* Free storage allocated for temporary varbind. */
   }
   free(pdu);                 /* Free storage allocated for PDU.      */
}



snmpGet Call Example

When you use the following example to call the snmpGet, snmpSet, or snmpGetnext API, it is important to note the following:

The snmpGet sample code follows:

#include <qtomeapi.h>

void main() {

typedef union
 {
   int  * int_val;
   char * str_val;
 } value;                                   /* Value typedef.         */

   snmppdu *pdu;                            /* PDU pointer.           */
   value   v;                               /* Value container.       */
   int     rc;                              /* Return code.           */
   char    community_name[120];           /* Community container.   */

   pdu = NULL;                              /* Nullify PDU pointer.   */
   rc = AddVarbind(&pdu,                    /* Add varbind with       */
                      "1.3.6.1.2.1.1.1.0",  /* OID, value, type of    */
                      v,                    /* PDU this is for, ASN   */
                      GET_PDU_TYPE,         /* type.  PDU pointer     */
                      0);                   /* is set to non-null.    */
   if ( rc < 0 ) {                          /* Check error code user  */
      printf("Error: %d\n",rc);             /* defined here.  Sample  */
      exit(1);                              /* is print return code.  */
   }

   rc = AddVarbind(&pdu,                    /* Add second varbind.    */
                      "1.3.6.1.2.1.1.1.1",  /* PDU pointer is now     */
                      v,                    /* non-null after 1st     */
                      GET_PDU_TYPE,         /* invocation of Add-     */
                      0);                   /* Varbind.               */
   if ( rc < 0 ) {
      printf("Error: %d\n",rc);           /* Again, check return code.*/
      exit(1);
   }
      strcpy(community_name,"public");      /* Set community name.    */

 rc = snmpGet(pdu,                          /* Invoke operation.      */
                "system_name_of_snmp_agent_system",  /* Hostname.     */
                10,                         /* Time-out value.        */
                community_name,         /* Pointer to community name. */
                6);                         /* Correct length of      */
 }                                          /* community name.        */




[ Back to top | UNIX-Type APIs | APIs by category ]