322 lines
14 KiB
HTML
322 lines
14 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
|
||
|
<title>Using SNMP Manager APIs--Example</title>
|
||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
||
|
<!-- US Government Users Restricted Rights -->
|
||
|
<!-- Use, duplication or disclosure restricted by -->
|
||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
||
|
<!-- Begin Header Records ========================================== -->
|
||
|
<!-- Direct1 SCRIPT J converted by B2H R4.1 (346) (CMS) by V2KEA304 -->
|
||
|
<!-- at RCHVMW2 on 17 Feb 1999 at 11:05:09 -->
|
||
|
<!--End Header Records -->
|
||
|
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
|
||
|
</head>
|
||
|
<body>
|
||
|
<a name="Top_Of_Page"></a>
|
||
|
<!-- Java sync-link -->
|
||
|
<script type="text/javascript" language="Javascript" src="../rzahg/synch.js">
|
||
|
</script>
|
||
|
|
||
|
<h2>Using SNMP Manager APIs--Example</h2>
|
||
|
|
||
|
<p>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.</p>
|
||
|
|
||
|
<p>These examples are for the SNMP manager APIs snmpGet, snmpSet, and
|
||
|
snmpGetnext.</p>
|
||
|
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
|
||
|
for information pertaining to code examples.</p>
|
||
|
<br>
|
||
|
|
||
|
|
||
|
<h3><a name="HDRVARBIND">AddVarbind Routine</a></h3>
|
||
|
|
||
|
<p>This routine is used to create an initial protocol data unit (PDU), and
|
||
|
subsequent calls will add varbinds to that PDU.</p>
|
||
|
|
||
|
<p>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 <a href="#HDRFREEPDU">FreePdu Routine</a>) is
|
||
|
an easy way to do this. The AddVarbind sample code follows:</p>
|
||
|
|
||
|
<pre>
|
||
|
#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);
|
||
|
}
|
||
|
|
||
|
</pre>
|
||
|
|
||
|
<br>
|
||
|
<h3><a name="HDRFREEPDU">FreePdu Routine</a></h3>
|
||
|
|
||
|
<p>This routine is used to free all the dynamically allocated storage from
|
||
|
AddVarbind.</p>
|
||
|
|
||
|
<p>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:</p>
|
||
|
|
||
|
<pre>
|
||
|
#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. */
|
||
|
}
|
||
|
|
||
|
</pre>
|
||
|
|
||
|
<br>
|
||
|
<br>
|
||
|
<h3><a name="HDRSNMPGEX">snmpGet Call Example</a></h3>
|
||
|
|
||
|
<p>When you use the following example to call the snmpGet, snmpSet, or
|
||
|
snmpGetnext API, it is important to note the following:</p>
|
||
|
|
||
|
<ul>
|
||
|
<li>The area where the data is returned is the responsibility of the user, not
|
||
|
the API. To allocate storage, the user may use the AddVarbind routine (see <a
|
||
|
href="#HDRVARBIND">AddVarbind Routine</a>). To deallocate storage, the user may
|
||
|
use the FreePdu routine (see <a href="#HDRFREEPDU">FreePdu Routine</a>).<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li>You must use the correct PDU type on AddVarbind. It must match the
|
||
|
operation on which you call. For example, if you build a PDU wherein AddVarbind
|
||
|
passes a PDU type of Set and then you call the snmpGet operation using the PDU
|
||
|
that you just created with Set, you will receive an error on the snmpGet
|
||
|
call.<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li>All character strings that are passed to the APIs must be null-terminated
|
||
|
unless you explicitly provide the length, if a length field is available.<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li>If you are building a PDU to go to a remote agent, you must remember to do
|
||
|
correct translation of strings. The iSeries server is an EBCDIC system, whereas
|
||
|
an SNMP agent on an RISC System/6000 (RS/6000) computer is an ASCII system.
|
||
|
Therefore, you must provide string values as you would see them on that system.
|
||
|
For example, if you are sending a PDU to an RS/6000 system and the community
|
||
|
name is <samp>public</samp>, you would enter the community name string in
|
||
|
hexadecimal, X'7075626C6963'.<br>
|
||
|
<br>
|
||
|
</li>
|
||
|
|
||
|
<li>These APIs are blocked, which means that on a call to the API a PDU is sent
|
||
|
across a communications protocol to an SNMP agent on a local or remote system.
|
||
|
The call returns when a response has been received from the agent or when the
|
||
|
command times out. On the return, all returned data is placed in the
|
||
|
appropriate locations. You need do no further action to retrieve such
|
||
|
data.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>The snmpGet sample code follows:</p>
|
||
|
|
||
|
<pre>
|
||
|
#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. */
|
||
|
|
||
|
</pre>
|
||
|
|
||
|
<br>
|
||
|
<br>
|
||
|
<hr>
|
||
|
<center>
|
||
|
<table cellpadding="2" cellspacing="2">
|
||
|
<tr align="center">
|
||
|
<td valign="middle" align="center"><a href="#Top_Of_Page">Top</a> |
|
||
|
<a href="unix.htm">UNIX-Type APIs</a> |
|
||
|
<a href="aplist.htm">APIs by category</a> </td>
|
||
|
</tr>
|
||
|
</table></center>
|
||
|
</body>
|
||
|
</html>
|
||
|
|