diff options
Diffstat (limited to 'contrib/bsnmp/lib/bsnmpagent.3')
| -rw-r--r-- | contrib/bsnmp/lib/bsnmpagent.3 | 417 |
1 files changed, 417 insertions, 0 deletions
diff --git a/contrib/bsnmp/lib/bsnmpagent.3 b/contrib/bsnmp/lib/bsnmpagent.3 new file mode 100644 index 000000000000..a9a8104013cb --- /dev/null +++ b/contrib/bsnmp/lib/bsnmpagent.3 @@ -0,0 +1,417 @@ +.\" +.\" Copyright (c) 2001-2003 +.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus). +.\" All rights reserved. +.\" +.\" Author: Harti Brandt <harti@freebsd.org> +.\" +.\" Redistribution of this software and documentation and use in source and +.\" binary forms, with or without modification, are permitted provided that +.\" the following conditions are met: +.\" +.\" 1. Redistributions of source code or documentation must retain the above +.\" copyright notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS +.\" AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +.\" FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +.\" FRAUNHOFER FOKUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +.\" OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Begemot: bsnmp/lib/bsnmpagent.3,v 1.1 2002/08/16 12:22:58 hbb Exp $ +.\" +.Dd August 16, 2002 +.Dt bsnmpagent 3 +.Os +.Sh NAME +.Nm snmp_depop_t , +.Nm snmp_set_finish_t , +.Nm snmp_op_t , +.Nm tree , +.Nm tree_size , +.Nm snmp_trace , +.Nm snmp_debug , +.Nm snmp_get , +.Nm snmp_getnext , +.Nm snmp_getbulk , +.Nm snmp_set , +.Nm snmp_make_errresp , +.Nm snmp_dep_lookup , +.Nm snmp_set_atfinish , +.Nm snmp_init_context , +.Nm snmp_dep_commit , +.Nm snmp_dep_rollback +.Nd "SNMP agent library" +.Sh LIBRARY +Begemot SNMP library +.Pq libbsnmp, -lbsnmp +.Sh SYNOPSIS +.In asn1.h +.In snmp.h +.In snmpagent.h +.Ft typedef int +.Fn (*snmp_depop_t) "struct snmp_context *ctx" "struct snmp_dependency *dep" "enum snmp_depop op" +.Ft typedef void +.Fn (*snmp_set_finish_t) "struct snmp_context *ctx" "int fail" "void *uarg" +.Ft typedef int +.Fn (*snmp_op_t) "struct snmp_context *ctx" "struct snmp_value *val" "u_int len" "u_int idx" "enum snmp_op op" +.Vt extern struct snmp_node *tree ; +.Vt extern u_int tree_size ; +.Vt extern u_int snmp_trace ; +.Vt extern void (*snmp_debug)(const char *fmt, ...) ; +.Ft enum snmp_ret +.Fn snmp_get "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data" +.Ft enum snmp_ret +.Fn snmp_getnext "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data" +.Ft enum snmp_ret +.Fn snmp_getbulk "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data" +.Ft enum snmp_ret +.Fn snmp_set "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data" +.Ft enum snmp_ret +.Fn snmp_make_errresp "const struct snmp_pdu *pdu" "struct asn_buf *req_b" "struct asn_buf *resp_b" +.Ft struct snmp_dependency * +.Fn snmp_dep_lookup "struct snmp_context *ctx" "const struct asn_oid *base" "const struct asn_oid *idx" "size_t alloc" "snmp_depop_t func" +.Ft int +.Fn snmp_set_atfinish "struct snmp_context *ctx" "snmp_set_finish_t func" "void *uarg" +.Ft struct snmp_context * +.Fn snmp_init_context "void" +.Ft int +.Fn snmp_dep_commit "struct snmp_context *ctx" +.Ft int +.Fn snmp_dep_rollback "struct snmp_context *ctx" +.Sh DESCRIPTION +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 +.Xr snmpd 1 +loadable module, that handles the new MIB (see +.Xr snmpmod 3 ). +.Pp +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: +.Bd -literal -offset indent +extern struct snmp_node *tree; +extern u_int tree_size; +.Ed +.Pp +The elements of the array are of type +.Vt struct snmp_node : +.Bd -literal -offset indent +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 */ +}; +.Ed +.Pp +The fields of this structure are described below. +.Bl -tag -width "syntax" +.It Va oid +Base OID of the scalar or table column. +.It Va name +Name of this variable. +.It Va type +Type of this variable. One of: +.Bd -literal -offset indent +enum snmp_node_type { + SNMP_NODE_LEAF = 1, + SNMP_NODE_COLUMN +}; +.Ed +.It Va syntax +The SNMP syntax of this variable. +.It Va op +The user supplied handler for this variable. The handler is called with +the following arguments: +.Bl -tag -width "ctx" +.It Fa ctx +A pointer to the context (see below). +.Li NULL . +.It Fa 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 +.Li SNMP_ERR_NOSUCHNAME . +For all other operations the oid in +.Fa val +is the oid to fetch or set. +.It Fa len +The length of the base oid without index. +.It Fa idx +For table columns this is the index expression from the node (see below). +.It Fa op +This is the operation to execute, one of: +.Bd -literal -offset indent +enum snmp_op { + SNMP_OP_GET = 1, + SNMP_OP_GETNEXT, + SNMP_OP_SET, + SNMP_OP_COMMIT, + SNMP_OP_ROLLBACK, +}; +.Ed +.El +.Pp +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 automatically. +.It Va flags +Currently only the flag +.Li SNMP_NODE_CANSET is defined and set for nodes, that can be written or +created. +.It Va 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: +.Bd -literal -offset indent +#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) \e + (((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & \e + SNMP_INDEX_MASK) +.Ed +.It Va data +This field may contain arbitrary data and is not used by the library. +.El +.Pp +The easiest way to construct the node table is +.Xr gensnmptree 1 . +Note, that one must be careful when changing the tree while executing a SET +operation. Consult the sources for +.Xr snmpd 1 . +.Pp +The global variable +.Va snmp_trace +together with the function pointed to by +.Va snmp_debug +help in debugging the library and the agent. +.Va snmp_trace is a bit mask with the following bits: +.Bd -literal -offset indent +enum { + SNMP_TRACE_GET, + SNMP_TRACE_GETNEXT, + SNMP_TRACE_SET, + SNMP_TRACE_DEPEND, + SNMP_TRACE_FIND, +}; +.Ed +.Pp +Setting a bit to true causes the library to call +.Fn 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. +.Pp +Many of the functions use a so called context: +.Bd -literal -offset indent +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; +}; +.Ed +.Pp +The fields are used as follows: +.Bl -tag -width ".It Va var_index" +.It Va 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. +.It Va 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. +.It Va dep +In the dependency callback function (see below) this is a pointer to the +current dependency. Set by the library. +.It Va data +This is the +.Fa data +argument from the call to the library and is not used by the library. +.El +.Pp +The next three functions execute different kinds of GET requests. +The function +.Fn snmp_get +executes an SNMP GET operation, the function +.Fn snmp_getnext +executes an SNMP GETNEXT operation and the function +.Fn 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 +.Fa resp +and +.Fa resp_b . +The caller must call +.Fn snmp_pdu_free +to free the response PDU in this case. One of the following values may be +returned: +.Bl -tag -width ".It Li SNMP_RET_ERR" +.It Li SNMP_RET_OK +Operation successful, response PDU may be sent. +.It Li SNMP_RET_IGN +Operation failed, no response PDU constructed. Request is ignored. +.It Li SNMP_RET_ERR +Error in operation. The error code and index have been set in +.Fa pdu . +No response PDU has been constructed. +The caller may construct an error response PDU via +.Fn snmp_make_errresp . +.El +.Pp +The function +.Fn 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. +.Pp +The SET operation occures in several stages: +.Bl -enum -offset indent +.It +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. +.It +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. +.It +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 indication. +.It +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. +.It +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 +.Fn snmp_error ). +.It +Now the dependencies are freed and the finalizers are called +with a fail flag of 0. Then the function returns +.Li SNMP_ERR_OK . +.El +.Pp +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 +.Fn asn_slice_oid . +The function +.Fn 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 +.Fn 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. +.Pp +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 accordingly. +.Pp +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. +.Pp +Finalizers are a +.Sq 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 +.Fn snmp_set_atfinish +which takes the callback function and a user data pointer as argument. +.Pp +The function +.Fn 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. +.Pp +The next three functions allow some parts of the SET operation to be executed. +This is only used in +.Xr snmpd 1 +to implement the configuration as a single transaction. +The function +.Fn snmp_init_context +creates and initializes a context. +The function +.Fn snmp_dep_commit +executes SNMP_DEPOP_COMMIT for all dependencies in the context stopping at +the first error. +The function +.Fn snmp_dep_rollback +executes SNMP_DEPOP_ROLLBACK starting at the previous of the current +dependency in the context. +.Sh DIAGNOSTICS +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. +.Sh SEE ALSO +.Xr snmpd 1 , +.Xr gensnmptree 1 , +.Xr bsnmplib 3 +.Xr bsnmpclient 3 , +.Xr snmpmod 3 +.Sh STANDARDS +This implementation conforms to the applicable IETF RFCs and ITU-T +recommendations. +.Sh AUTHORS +.An Hartmut Brandt Aq brandt@fokus.gmd.de |
