*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->FreeBSD man pages -> bsnmpagent (3)              



NAME    [Toc]    [Back]

     snmp_depop_t, snmp_set_finish_t, snmp_op_t, tree, tree_size, snmp_trace,
     snmp_debug, snmp_get, snmp_getnext, snmp_getbulk, snmp_set,
     snmp_make_errresp, snmp_dep_lookup, snmp_set_atfinish, snmp_init_context,
     snmp_dep_commit, snmp_dep_rollback -- SNMP agent library

LIBRARY    [Toc]    [Back]

     Begemot SNMP library (libbsnmp, -lbsnmp)

SYNOPSIS    [Toc]    [Back]

     #include <asn1.h>
     #include <snmp.h>
     #include <snmpagent.h>

     typedef int
     (*snmp_depop_t)(struct snmp_context *ctx, struct snmp_dependency *dep,
	 enum snmp_depop op);

     typedef void
     (*snmp_set_finish_t)(struct snmp_context *ctx, int fail, void *uarg);

     typedef int
     (*snmp_op_t)(struct snmp_context *ctx, struct snmp_value *val, u_int len,
	 u_int idx, enum snmp_op op);

     extern struct snmp_node *tree;
     extern u_int tree_size;
     extern u_int snmp_trace;
     extern void (*snmp_debug)(const char *fmt, ...);

     enum snmp_ret
     snmp_get(struct snmp_pdu *pdu, struct asn_buf *resp_b,
	 struct snmp_pdu *resp, void *data);

     enum snmp_ret
     snmp_getnext(struct snmp_pdu *pdu, struct asn_buf *resp_b,
	 struct snmp_pdu *resp, void *data);

     enum snmp_ret
     snmp_getbulk(struct snmp_pdu *pdu, struct asn_buf *resp_b,
	 struct snmp_pdu *resp, void *data);

     enum snmp_ret
     snmp_set(struct snmp_pdu *pdu, struct asn_buf *resp_b,
	 struct snmp_pdu *resp, void *data);

     enum snmp_ret
     snmp_make_errresp(const struct snmp_pdu *pdu, struct asn_buf *req_b,
	 struct asn_buf *resp_b);

     struct snmp_dependency *
     snmp_dep_lookup(struct snmp_context *ctx, const struct asn_oid *base,
	 const struct asn_oid *idx, size_t alloc, snmp_depop_t func);

     snmp_set_atfinish(struct snmp_context *ctx, snmp_set_finish_t func,
	 void *uarg);

     struct snmp_context *

     snmp_dep_commit(struct snmp_context *ctx);

     snmp_dep_rollback(struct snmp_context *ctx);

DESCRIPTION    [Toc]    [Back]

     The SNMP library contains routines to easily build SNMP agent applications
 that use SNMP versions 1 or 2. Note, however, that it may be even
     easier to build an snmpd(1) loadable module, that handles the new MIB
     (see snmpmod(3) ).

     Most of the agent routines operate on a global array that the describes
     the complete MIB served by the agent. This array is held in the two variables:

	   extern struct snmp_node *tree;
	   extern u_int  tree_size;

     The elements of the array are of type struct snmp_node:

	   typedef int (*snmp_op_t)(struct snmp_context *, struct snmp_value *,
	       u_int, u_int, enum snmp_op);

	   struct snmp_node {
		   struct asn_oid oid;
		   const char	   *name;	   /* name of the leaf */
		   enum snmp_node_type type;	   /* type of this node */
		   enum snmp_syntax syntax;
		   snmp_op_t	   op;
		   u_int	   flags;
		   u_int32_t	   index;	   /* index data */
		   void 	   *data;	   /* application data */

     The fields of this structure are described below.

     oid     Base OID of the scalar or table column.

     name    Name of this variable.

     type    Type of this variable. One of:

		   enum snmp_node_type {
			   SNMP_NODE_LEAF = 1,

     syntax  The SNMP syntax of this variable.

     op      The user supplied handler for this variable. The handler is
	     called with the following arguments:

	     ctx  A pointer to the context (see below).  NULL.

	     val  The value to be set or retrieved. For GETNEXT and GETBULK
		  operations the oid in this value is the current OID. The
		  function (called in this case only for table rows) must find
		  the lexically next existing OID within the same column and
		  set the oid and value subfields accordingly. If the table
		  column is exhausted the function must return
		  SNMP_ERR_NOSUCHNAME.	For all other operations the oid in
		  val is the oid to fetch or set.

	     len  The length of the base oid without index.

	     idx  For table columns this is the index expression from the node
		  (see below).

	     op   This is the operation to execute, one of:

			enum snmp_op {
				SNMP_OP_GET	= 1,

	     The user handler must return an appropiate SNMP v2 error code. If
	     the original PDU was a version 1 PDU, the error code is mapped

     flags   Currently only the flag SNMP_NODE_CANSET is defined and set for
	     nodes, that can be written or created.

     index   This word describes the index for table columns. Each part of the
	     index takes 4 bits starting at bit 4. Bits 0 to 3 hold the number
	     of index parts.  This arrangment allows for tables with up to
	     seven indexes. Each bit group contains the syntax for the index
	     part. There are a number of macros to help in parsing this field:

		   #define SNMP_INDEXES_MAX	   7
		   #define SNMP_INDEX_SHIFT	   4
		   #define SNMP_INDEX_MASK 0xf
		   #define SNMP_INDEX_COUNT(V)	   ((V) & SNMP_INDEX_MASK)
		   #define SNMP_INDEX(V,I) \
			   (((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & \

     data    This field may contain arbitrary data and is not used by the

     The easiest way to construct the node table is gensnmptree(1).  Note,
     that one must be careful when changing the tree while executing a SET
     operation. Consult the sources for snmpd(1).

     The global variable snmp_trace together with the function pointed to by
     snmp_debug help in debugging the library and the agent.  snmp_trace is a
     bit mask with the following bits:

	   enum {

     Setting a bit to true causes the library to call snmp_debug() in strategic
 places with a debug string. The library contains a default implementation
 for the debug function that prints a message to standard error.

     Many of the functions use a so called context:

	   struct snmp_context {
		   u_int   var_index;
		   struct snmp_scratch *scratch;
		   struct snmp_dependency *dep;
		   void    *data;	   /* user data */

	   struct snmp_scratch {
		   void 	   *ptr1;
		   void 	   *ptr2;
		   u_int32_t	   int1;
		   u_int32_t	   int2;

     The fields are used as follows:

     va_index	For the node operation callback this is the index of the variable
 binding that should be returned if an error occures.  Set
		by the library. In all other functions this is undefined.

     scratch	For the node operation callback this is a pointer to a per
		variable binding scratch area that can be used to implement
		the commit and rollback. Set by the library.

     dep	In the dependency callback function (see below) this is a
		pointer to the current dependency. Set by the library.

     data	This is the data argument from the call to the library and is
		not used by the library.

     The next three functions execute different kinds of GET requests.	The
     function snmp_get() executes an SNMP GET operation, the function
     snmp_getnext() executes an SNMP GETNEXT operation and the function
     snmp_getbulk() executes an SNMP GETBULK operation.  For all three functions
 the response PDU is constructed and encoded on the fly. If everything
 is ok, the response PDU is returned in resp and resp_b.  The caller
     must call snmp_pdu_free() to free the response PDU in this case. One of
     the following values may be returned:

     SNMP_RET_OK   Operation successful, response PDU may be sent.

     SNMP_RET_IGN  Operation failed, no response PDU constructed. Request is

     SNMP_RET_ERR  Error in operation. The error code and index have been set
		   in pdu.  No response PDU has been constructed.  The caller
		   may construct an error response PDU via

     The function snmp_set() executes an SNMP SET operation. The arguments are
     the same as for the previous three functions. The operation of this functions
 is, however, much more complex.

     The SET operation occures in several stages:

	   1.	For each binding search the corresponding nodes, check that
		the variable is writeable and the syntax is ok. The writeable
		check can be done only for scalars. For columns it must be
		done in the node's operation callback function.

	   2.	For each binding call the node's operation callback with function
 SNMP_OP_SET.  The callback may create dependencies or
		finalizers (see below). For simple scalars the scratch area
		may be enough to handle commit and rollback, for interdependend
 table columns dependencies may be necessary.

	   3.	If the previous step fails at any point, the node's operation
		callback functions are called for all bindings for which
		SNMP_OP_SET was executed with SNMP_OP_ROLLBACK, in the opposite
 order. This allows all variables to undo the effect of
		the SET operation. After this all the dependencies are freed
		and the finalizers are executed with a fail flag of 1. Then
		the function returns to the caller with an appropriate error

	   4.	If the SET step was successful for all bindings, the dependency
 callbacks are executed in the order in which the dependencies
 were created with an operation of SNMP_DEPOP_COMMIT.
		If any of the dependencies fails, all the committed dependencies
 are called again in the opposite order with
		SNMP_DEPOP_ROLLBACK. Than for all bindings from the last to
		the first the node's operation callback is called with
		SNMP_OP_ROLLBACK to undo the effect of SNMP_OP_SET. At the end
		the dependencies are freed and the finalizers are called with
		a fail flag of 1 and the function returns to the caller with
		an appropriate error indication.

	   5.	If the dependency commits were successful, for each binding
		the node's operation callback is called with SNMP_OP_COMMIT.
		Any error returned from the callbacks is ignored (an error
		message is generated via snmp_error().)

	   6.	Now the dependencies are freed and the finalizers are called
		with a fail flag of 0. Then the function returns SNMP_ERR_OK.

     There are to mechanisms to help in complex SET operations: dependencies
     and finalizers. A dependency is used if several bindings depend on each
     other.  A typical example is the creation of a conceptual row, which
     requires the setting of several columns to succeed. A dependency is identified
 by two OIDs. In the table case, the first oid is typically the table's
 base OID and the second one the index. Both of these can easily be
     generated from the variables OID with asn_slice_oid().  The function
     snmp_dep_lookup() tries to find a dependency based on these two OIDs and,
     if it cannot find one creates a new one. This means for the table example,
 that the function returns the same dependency for each of the columns
 of the same table row.  This allows during the SNMP_OP_SET processing
 to collect all information about the row into the dependency. The
     arguments to snmp_dep_lookup() are: the two OIDs to identify the dependency
 (they are copied into newly created dependencies), the size of the
     structure to allocate and the dependency callback.

     When all SNMP_OP_SET operations have succeeded the dependencies are executed.
  At this stage the dependency callback has all information about
     the given table row that was available in this SET PDU and can operate

     If a SNMP_OP_SET operation fails, the dependency callbacks are never
     called. The nodes SNMP_OP_ROLLBACK operations have to ensure, that any
     dynamically allocated data is freed.

     Finalizers are a `last change' to do processing.  They are called after
     everything has been done, just before returning to the user. They get a
     flag, that tells them, whether the return to the user is a good one or
     not. The typical use is to finally remove deleted table elements.	Finalizers
 are created with snmp_set_atfinish() which takes the callback function
 and a user data pointer as argument.

     The function snmp_make_errresp() makes an error response if an operation
     has failed. It takes the original request PDU (it will look only on the
     error code and index fields), the buffer containing the original PDU and
     a buffer for the error PDU. It copies the bindings field from the original
 PDUs buffer directly to the response PDU and thus does not depend on
     the decodability of this field. It may return the same values as the
     operation functions.

     The next three functions allow some parts of the SET operation to be executed.
  This is only used in snmpd(1) to implement the configuration as a
     single transaction.  The function snmp_init_context() creates and initializes
 a context.  The function snmp_dep_commit() executes
     SNMP_DEPOP_COMMIT for all dependencies in the context stopping at the
     first error.  The function snmp_dep_rollback() executes SNMP_DEPOP_ROLLBACK
 starting at the previous of the current dependency in the context.

DIAGNOSTICS    [Toc]    [Back]

     If an error occures in any of the function an error indication as
     described above is returned. Additionally the functions may call
     snmp_error on unexected errors.

SEE ALSO    [Toc]    [Back]

     snmpd(1), gensnmptree(1), bsnmplib(3) bsnmpclient(3), snmpmod(3)

STANDARDS    [Toc]    [Back]

     This implementation conforms to the applicable IETF RFCs and ITU-T recommendations.

AUTHORS    [Toc]    [Back]

     Hartmut Brandt <brandt@fokus.gmd.de>

FreeBSD 5.2.1			August 16, 2002 		 FreeBSD 5.2.1
[ Back ]
 Similar pages
Name OS Title
peer_snmpd_config IRIX SNMP master agent configuration
snmpd.conf HP-UX configuration file for the SNMP agent
rsvpd-snmpagent IRIX Silicon Graphics RSVP & IntSrv SNMP Agent
snmpd.conf Tru64 Simple Network Management Protocol (SNMP) agent daemon
snmpd Tru64 Simple Network Management Protocol (SNMP) agent daemon
asn1 FreeBSD ASN.1 library for SNMP
bsnmpclient FreeBSD SNMP client library
bsnmplib FreeBSD SNMP decoding and encoding library
hpsnmpd IRIX SNMP HP-UX MIB subagent
bsnmpd FreeBSD simple and extendable SNMP daemon
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service