xref: /freebsd/contrib/bsnmp/lib/bsnmpagent.3 (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
1.\"
2.\" Copyright (c) 2001-2003
3.\"	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4.\"	All rights reserved.
5.\"
6.\" Author: Harti Brandt <harti@freebsd.org>
7.\"
8.\" Redistribution of this software and documentation and use in source and
9.\" binary forms, with or without modification, are permitted provided that
10.\" the following conditions are met:
11.\"
12.\" 1. Redistributions of source code or documentation must retain the above
13.\"    copyright notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\" 3. Neither the name of the Institute nor the names of its contributors
18.\"    may be used to endorse or promote products derived from this software
19.\"    without specific prior written permission.
20.\"
21.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
22.\" AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24.\" FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
25.\" FRAUNHOFER FOKUS OR ITS CONTRIBUTORS  BE LIABLE FOR ANY DIRECT, INDIRECT,
26.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
28.\" OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32.\"
33.\" $Begemot: bsnmp/lib/bsnmpagent.3,v 1.5 2004/04/13 17:01:31 novo Exp $
34.\"
35.Dd August 16, 2002
36.Dt bsnmpagent 3
37.Os
38.Sh NAME
39.Nm bsnmpagent
40.Nm snmp_depop_t ,
41.Nm snmp_op_t ,
42.Nm tree ,
43.Nm tree_size ,
44.Nm snmp_trace ,
45.Nm snmp_debug ,
46.Nm snmp_get ,
47.Nm snmp_getnext ,
48.Nm snmp_getbulk ,
49.Nm snmp_set ,
50.Nm snmp_make_errresp ,
51.Nm snmp_dep_lookup ,
52.Nm snmp_init_context ,
53.Nm snmp_dep_commit ,
54.Nm snmp_dep_rollback ,
55.Nm snmp_dep_finish
56.Nd "SNMP agent library"
57.Sh LIBRARY
58Begemot SNMP library
59.Pq libbsnmp, -lbsnmp
60.Sh SYNOPSIS
61.In asn1.h
62.In snmp.h
63.In snmpagent.h
64.Ft typedef int
65.Fn (*snmp_depop_t) "struct snmp_context *ctx" "struct snmp_dependency *dep" "enum snmp_depop op"
66.Ft typedef int
67.Fn (*snmp_op_t) "struct snmp_context *ctx" "struct snmp_value *val" "u_int len" "u_int idx" "enum snmp_op op"
68.Vt extern struct snmp_node *tree ;
69.Vt extern u_int tree_size ;
70.Vt extern u_int snmp_trace ;
71.Vt extern void (*snmp_debug)(const char *fmt, ...) ;
72.Ft enum snmp_ret
73.Fn snmp_get "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
74.Ft enum snmp_ret
75.Fn snmp_getnext "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
76.Ft enum snmp_ret
77.Fn snmp_getbulk "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
78.Ft enum snmp_ret
79.Fn snmp_set "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
80.Ft enum snmp_ret
81.Fn snmp_make_errresp "const struct snmp_pdu *pdu" "struct asn_buf *req_b" "struct asn_buf *resp_b"
82.Ft struct snmp_dependency *
83.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"
84.Ft struct snmp_context *
85.Fn snmp_init_context "void"
86.Ft int
87.Fn snmp_dep_commit "struct snmp_context *ctx"
88.Ft int
89.Fn snmp_dep_rollback "struct snmp_context *ctx"
90.Ft void
91.Fn snmp_dep_finish "struct snmp_context *ctx"
92.Sh DESCRIPTION
93The SNMP library contains routines to easily build SNMP agent applications
94that use SNMP versions 1 or 2. Note, however, that it may be even easier to
95build an
96.Xr snmpd 1
97loadable module, that handles the new MIB (see
98.Xr snmpmod 3 ).
99.Pp
100Most of the agent routines operate on a global array that the describes the
101complete MIB served by the agent. This array is held in the two variables:
102.Bd -literal -offset indent
103extern struct snmp_node *tree;
104extern u_int  tree_size;
105.Ed
106.Pp
107The elements of the array are of type
108.Vt struct snmp_node :
109.Bd -literal -offset indent
110typedef int (*snmp_op_t)(struct snmp_context *, struct snmp_value *,
111    u_int, u_int, enum snmp_op);
112
113struct snmp_node {
114	struct asn_oid oid;
115	const char	*name;		/* name of the leaf */
116	enum snmp_node_type type;	/* type of this node */
117	enum snmp_syntax syntax;
118	snmp_op_t	op;
119	u_int		flags;
120	u_int32_t	index;		/* index data */
121	void		*data;		/* application data */
122	void		*tree_data;	/* application data */
123};
124.Ed
125.Pp
126The fields of this structure are described below.
127.Bl -tag -width "syntax"
128.It Va oid
129Base OID of the scalar or table column.
130.It Va name
131Name of this variable.
132.It Va type
133Type of this variable. One of:
134.Bd -literal -offset indent
135enum snmp_node_type {
136	SNMP_NODE_LEAF = 1,
137	SNMP_NODE_COLUMN
138};
139.Ed
140.It Va syntax
141The SNMP syntax of this variable.
142.It Va op
143The user supplied handler for this variable. The handler is called with
144the following arguments:
145.Bl -tag -width "ctx"
146.It Fa ctx
147A pointer to the context (see below).
148.Li NULL .
149.It Fa val
150The value to be set or retrieved. For GETNEXT and GETBULK operations the oid in
151this value is the current OID. The function (called in this case only for
152table rows) must find the lexically next existing OID within the same column and
153set the oid and value subfields accordingly. If the table column is exhausted the
154function must return
155.Li SNMP_ERR_NOSUCHNAME .
156For all other operations the oid in
157.Fa val
158is the oid to fetch or set.
159.It Fa len
160The length of the base oid without index.
161.It Fa idx
162For table columns this is the index expression from the node (see below).
163.It Fa op
164This is the operation to execute, one of:
165.Bd -literal -offset indent
166enum snmp_op {
167	SNMP_OP_GET 	= 1,
168	SNMP_OP_GETNEXT,
169	SNMP_OP_SET,
170	SNMP_OP_COMMIT,
171	SNMP_OP_ROLLBACK,
172};
173.Ed
174.El
175.Pp
176The user handler must return an appropiate SNMP v2 error code. If the original
177PDU was a version 1 PDU, the error code is mapped automatically.
178.It Va flags
179Currently only the flag
180.Li SNMP_NODE_CANSET is defined and set for nodes, that can be written or
181created.
182.It Va index
183This word describes the index for table columns. Each part of the index
184takes 4 bits starting at bit 4. Bits 0 to 3 hold the number of index parts.
185This arrangment allows for tables with up to seven indexes. Each bit group
186contains the syntax for the index part. There are a number of macros to
187help in parsing this field:
188.Bd -literal -offset indent
189#define SNMP_INDEXES_MAX	7
190#define SNMP_INDEX_SHIFT	4
191#define SNMP_INDEX_MASK	0xf
192#define SNMP_INDEX_COUNT(V)	((V) & SNMP_INDEX_MASK)
193#define SNMP_INDEX(V,I) \e
194	(((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & \e
195	SNMP_INDEX_MASK)
196.Ed
197.It Va data
198This field may contain arbitrary data and is not used by the library.
199.El
200.Pp
201The easiest way to construct the node table is
202.Xr gensnmptree 1 .
203Note, that one must be careful when changing the tree while executing a SET
204operation. Consult the sources for
205.Xr snmpd 1 .
206.Pp
207The global variable
208.Va snmp_trace
209together with the function pointed to by
210.Va snmp_debug
211help in debugging the library and the agent.
212.Va snmp_trace is a bit mask with the following bits:
213.Bd -literal -offset indent
214enum {
215	SNMP_TRACE_GET,
216	SNMP_TRACE_GETNEXT,
217	SNMP_TRACE_SET,
218	SNMP_TRACE_DEPEND,
219	SNMP_TRACE_FIND,
220};
221.Ed
222.Pp
223Setting a bit to true causes the library to call
224.Fn snmp_debug
225in strategic places with a debug string. The library contains a default
226implementation for the debug function that prints a message to standard error.
227.Pp
228Many of the functions use a so called context:
229.Bd -literal -offset indent
230struct snmp_context {
231	u_int	var_index;
232	struct snmp_scratch *scratch;
233	struct snmp_dependency *dep;
234	void	*data;		/* user data */
235	enum snmp_ret code;	/* return code */
236};
237
238struct snmp_scratch {
239	void		*ptr1;
240	void		*ptr2;
241	u_int32_t	int1;
242	u_int32_t	int2;
243};
244.Ed
245.Pp
246The fields are used as follows:
247.Bl -tag -width ".It Va var_index"
248.It Va va_index
249For the node operation callback this is the
250index of the variable binding that should be returned if an error occures.
251Set by the library. In all other functions this is undefined.
252.It Va scratch
253For the node operation callback this is a pointer to a per variable binding
254scratch area that can be used to implement the commit and rollback. Set
255by the library.
256.It Va dep
257In the dependency callback function (see below) this is a pointer to the
258current dependency. Set by the library.
259.It Va data
260This is the
261.Fa data
262argument from the call to the library and is not used by the library.
263.El
264.Pp
265The next three functions execute different kinds of GET requests.
266The function
267.Fn snmp_get
268executes an SNMP GET operation, the function
269.Fn snmp_getnext
270executes an SNMP GETNEXT operation and the function
271.Fn snmp_getbulk
272executes an SNMP GETBULK operation.
273For all three functions the response PDU is constructed and encoded
274on the fly. If everything is ok, the response PDU is returned in
275.Fa resp
276and
277.Fa resp_b .
278The caller must call
279.Fn snmp_pdu_free
280to free the response PDU in this case. One of the following values may be
281returned:
282.Bl -tag -width ".It Li SNMP_RET_ERR"
283.It Li SNMP_RET_OK
284Operation successful, response PDU may be sent.
285.It Li SNMP_RET_IGN
286Operation failed, no response PDU constructed. Request is ignored.
287.It Li SNMP_RET_ERR
288Error in operation. The error code and index have been set in
289.Fa pdu .
290No response PDU has been constructed.
291The caller may construct an error response PDU via
292.Fn snmp_make_errresp .
293.El
294.Pp
295The function
296.Fn snmp_set
297executes an SNMP SET operation. The arguments are the same as for the previous
298three functions. The operation of this functions is, however, much more complex.
299.Pp
300The SET operation occures in several stages:
301.Bl -enum -offset indent
302.It
303For each binding search the corresponding nodes, check that the
304variable is writeable and the syntax is ok. The writeable check can be done
305only for scalars. For columns it must be done in the node's operation callback
306function.
307.It
308For each binding call the node's operation callback with function SNMP_OP_SET.
309The callback may create dependencies or finalizers (see below). For simple
310scalars the scratch area may be enough to handle commit and rollback, for
311interdependend table columns dependencies may be necessary.
312.It
313If the previous step fails at any point, the node's operation callback
314functions are called for all bindings for which SNMP_OP_SET was executed
315with SNMP_OP_ROLLBACK, in the opposite order. This allows all variables to
316undo the effect of the SET operation. After this all the dependencies
317are freed
318and the finalizers are executed with a fail flag of 1. Then the function
319returns to the caller with an appropriate error indication.
320.It
321If the SET step was successful for all bindings, the dependency callbacks
322are executed in the order in which the dependencies were created with an
323operation of SNMP_DEPOP_COMMIT. If any of the dependencies fails, all the
324committed dependencies are called again in the opposite order
325with SNMP_DEPOP_ROLLBACK. Than for all bindings from the last to the first
326the node's operation callback is called with SNMP_OP_ROLLBACK to undo
327the effect of SNMP_OP_SET. At the end the dependencies are freed
328and the finalizers are called with a fail flag
329of 1 and the function returns to the caller with an appropriate error indication.
330.It
331If the dependency commits were successful, for each binding the node's
332operation callback is called with SNMP_OP_COMMIT. Any error returned from
333the callbacks is ignored (an error message is generated via
334.Fn snmp_error ).
335.It
336Now the dependencies are freed and the finalizers are called
337with a fail flag of 0. For each dependency just before freeing it
338its callback is called with
339.Li SNMP_DEPOP_FINISH.
340Then the function returns
341.Li SNMP_ERR_OK .
342.El
343.Pp
344There are to mechanisms to help in complex SET operations: dependencies and
345finalizers. A dependency is used if several bindings depend on each other.
346A typical example is the creation of a conceptual row, which requires
347the setting of several columns to succeed. A dependency is identified by
348two OIDs. In the table case, the first oid is typically the table's base OID
349and the second one the index. Both of these can easily be generated from the
350variables OID with
351.Fn asn_slice_oid .
352The function
353.Fn snmp_dep_lookup
354tries to find a dependency based on these two OIDs and, if it cannot find one
355creates a new one. This means for the table example, that the function
356returns the same dependency for each of the columns of the same table row.
357This allows during the SNMP_OP_SET processing to collect all information
358about the row into the dependency. The arguments to
359.Fn snmp_dep_lookup
360are: the two OIDs to identify the dependency (they are copied into newly
361created dependencies), the size of the structure to allocate and
362the dependency callback.
363.Pp
364When all SNMP_OP_SET operations have succeeded the dependencies are executed.
365At this stage the dependency callback has all information about the given
366table row that was available in this SET PDU and can operate accordingly.
367.Pp
368It is guaranteed that each dependency callback is executed at minimum once
369- with an operation of
370.Li SNMP_OP_ROLLBACK .
371This ensures that all dynamically allocated resources in a callback can be
372freed correctly.
373.Pp
374The function
375.Fn snmp_make_errresp
376makes an error response if an operation has failed. It takes the original
377request PDU (it will look only on the error code and index fields), the
378buffer containing the original PDU and a buffer for the error PDU. It copies
379the bindings field from the original PDUs buffer directly to the response
380PDU and thus does not depend on the decodability of this field. It may return
381the same values as the operation functions.
382.Pp
383The next four functions allow some parts of the SET operation to be executed.
384This is only used in
385.Xr snmpd 1
386to implement the configuration as a single transaction.
387The function
388.Fn snmp_init_context
389creates and initializes a context.
390The function
391.Fn snmp_dep_commit
392executes SNMP_DEPOP_COMMIT for all dependencies in the context stopping at
393the first error.
394The function
395.Fn snmp_dep_rollback
396executes SNMP_DEPOP_ROLLBACK starting at the previous of the current
397dependency in the context.
398The function
399.Fn snmp_dep_finish
400executes SNMP_DEPOP_FINISH for all dependencies.
401.Sh DIAGNOSTICS
402If an error occures in any of the function an error indication as described
403above is returned. Additionally the functions may call snmp_error on unexected
404errors.
405.Sh SEE ALSO
406.Xr snmpd 1 ,
407.Xr gensnmptree 1 ,
408.Xr bsnmplib 3
409.Xr bsnmpclient 3 ,
410.Xr snmpmod 3
411.Sh STANDARDS
412This implementation conforms to the applicable IETF RFCs and ITU-T
413recommendations.
414.Sh AUTHORS
415.An Hartmut Brandt Aq harti@freebsd.org
416