]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/bsnmp/snmpd/snmpmod.3
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / bsnmp / snmpd / snmpmod.3
1 .\"
2 .\" Copyright (c) 2004-2005
3 .\"     Hartmut Brandt.
4 .\"     All rights reserved.
5 .\" Copyright (c) 2001-2003
6 .\"     Fraunhofer Institute for Open Communication Systems (FhG Fokus).
7 .\"     All rights reserved.
8 .\"
9 .\" Author: Harti Brandt <harti@freebsd.org>
10 .\" 
11 .\" Redistribution and use in source and binary forms, with or without
12 .\" modification, are permitted provided that the following conditions
13 .\" are met:
14 .\" 1. Redistributions of source code must retain the above copyright
15 .\"    notice, this list of conditions and the following disclaimer.
16 .\" 2. Redistributions in binary form must reproduce the above copyright
17 .\"    notice, this list of conditions and the following disclaimer in the
18 .\"    documentation and/or other materials provided with the distribution.
19 .\" 
20 .\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 .\" ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
24 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 .\" SUCH DAMAGE.
31 .\"
32 .\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.14 2005/10/04 13:30:35 brandt_h Exp $
33 .\"
34 .Dd February 27, 2006
35 .Dt SNMPMOD 3
36 .Os
37 .Sh NAME
38 .Nm INSERT_OBJECT_OID_LINK_INDEX ,
39 .Nm INSERT_OBJECT_INT_LINK_INDEX ,
40 .Nm FIND_OBJECT_OID_LINK_INDEX ,
41 .Nm NEXT_OBJECT_OID_LINK_INDEX ,
42 .Nm FIND_OBJECT_INT_LINK_INDEX ,
43 .Nm NEXT_OBJECT_INT_LINK_INDEX ,
44 .Nm INSERT_OBJECT_OID_LINK ,
45 .Nm INSERT_OBJECT_INT_LINK ,
46 .Nm FIND_OBJECT_OID_LINK ,
47 .Nm NEXT_OBJECT_OID_LINK ,
48 .Nm FIND_OBJECT_INT_LINK ,
49 .Nm NEXT_OBJECT_INT_LINK ,
50 .Nm INSERT_OBJECT_OID ,
51 .Nm INSERT_OBJECT_INT ,
52 .Nm FIND_OBJECT_OID ,
53 .Nm FIND_OBJECT_INT ,
54 .Nm NEXT_OBJECT_OID ,
55 .Nm NEXT_OBJECT_INT ,
56 .Nm this_tick ,
57 .Nm start_tick ,
58 .Nm get_ticks ,
59 .Nm systemg ,
60 .Nm comm_define ,
61 .Nm community ,
62 .Nm oid_zeroDotZero ,
63 .Nm reqid_allocate ,
64 .Nm reqid_next ,
65 .Nm reqid_base ,
66 .Nm reqid_istype ,
67 .Nm reqid_type ,
68 .Nm timer_start ,
69 .Nm timer_start_repeat ,
70 .Nm timer_stop ,
71 .Nm fd_select ,
72 .Nm fd_deselect ,
73 .Nm fd_suspend ,
74 .Nm fd_resume ,
75 .Nm or_register ,
76 .Nm or_unregister ,
77 .Nm buf_alloc ,
78 .Nm buf_size ,
79 .Nm snmp_input_start ,
80 .Nm snmp_input_finish ,
81 .Nm snmp_output ,
82 .Nm snmp_send_port ,
83 .Nm snmp_send_trap ,
84 .Nm string_save ,
85 .Nm string_commit ,
86 .Nm string_rollback ,
87 .Nm string_get ,
88 .Nm string_get_max ,
89 .Nm string_free ,
90 .Nm ip_save ,
91 .Nm ip_rollback ,
92 .Nm ip_commit ,
93 .Nm ip_get ,
94 .Nm oid_save ,
95 .Nm oid_rollback ,
96 .Nm oid_commit ,
97 .Nm oid_get ,
98 .Nm index_decode ,
99 .Nm index_compare ,
100 .Nm index_compare_off ,
101 .Nm index_append ,
102 .Nm index_append_off
103 .Nd "SNMP daemon loadable module interface"
104 .Sh LIBRARY
105 Begemot SNMP library
106 .Pq libbsnmp, -lbsnmp
107 .Sh SYNOPSIS
108 .In bsnmp/snmpmod.h
109 .Fn INSERT_OBJECT_OID_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
110 .Fn INSERT_OBJECT_INT_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
111 .Fn FIND_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
112 .Fn FIND_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
113 .Fn NEXT_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
114 .Fn NEXT_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
115 .Fn INSERT_OBJECT_OID_LINK "PTR" "LIST" "LINK"
116 .Fn INSERT_OBJECT_INT_LINK "PTR" "LIST" "LINK"
117 .Fn FIND_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
118 .Fn FIND_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
119 .Fn NEXT_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
120 .Fn NEXT_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
121 .Fn INSERT_OBJECT_OID "PTR" "LIST"
122 .Fn INSERT_OBJECT_INT "PTR" "LIST"
123 .Fn FIND_OBJECT_OID "LIST" "OID" "SUB"
124 .Fn FIND_OBJECT_INT "LIST" "OID" "SUB"
125 .Fn NEXT_OBJECT_OID "LIST" "OID" "SUB"
126 .Fn NEXT_OBJECT_INT "LIST" "OID" "SUB"
127 .Vt extern uint64_t this_tick ;
128 .Vt extern uint64_t start_tick ;
129 .Ft uint64_t
130 .Fn get_ticks "void"
131 .Vt extern struct systemg systemg ;
132 .Ft u_int
133 .Fn comm_define "u_int priv" "const char *descr" "struct lmodule *mod" "const char *str"
134 .Ft const char *
135 .Fn comm_string "u_int comm"
136 .Vt extern u_int community ;
137 .Vt extern const struct asn_oid oid_zeroDotZero ;
138 .Ft u_int
139 .Fn reqid_allocate "int size" "struct lmodule *mod"
140 .Ft int32_t
141 .Fn reqid_next "u_int type"
142 .Ft int32_t
143 .Fn reqid_base "u_int type"
144 .Ft int
145 .Fn reqid_istype "int32_t reqid" "u_int type"
146 .Ft u_int
147 .Fn reqid_type "int32_t reqid"
148 .Ft void *
149 .Fn timer_start "u_int ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
150 .Ft void *
151 .Fn timer_start_repeat "u_int ticks" "u_int repeat_ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
152 .Ft void
153 .Fn timer_stop "void *timer_id"
154 .Ft void *
155 .Fn fd_select "int fd" "void (*func)(int, void *)" "void *uarg" "struct lmodule *mod"
156 .Ft void
157 .Fn fd_deselect "void *fd_id"
158 .Ft void
159 .Fn fd_suspend "void *fd_id"
160 .Ft int
161 .Fn fd_resume "void *fd_id"
162 .Ft u_int
163 .Fn or_register "const struct asn_oid *oid" "const char *descr" "struct lmodule *mod"
164 .Ft void
165 .Fn or_unregister "u_int or_id"
166 .Ft void *
167 .Fn buf_alloc "int tx"
168 .Ft size_t
169 .Fn buf_size "int tx"
170 .Ft enum snmpd_input_err
171 .Fo snmp_input_start
172 .Fa "const u_char *buf" "size_t len" "const char *source"
173 .Fa "struct snmp_pdu *pdu" "int32_t *ip" "size_t *pdulen"
174 .Fc
175 .Ft enum snmpd_input_err
176 .Fo snmp_input_finish
177 .Fa "struct snmp_pdu *pdu" "const u_char *rcvbuf"
178 .Fa "size_t rcvlen" "u_char *sndbuf" "size_t *sndlen" "const char *source"
179 .Fa "enum snmpd_input_err ierr" "int32_t ip" "void *data"
180 .Fc
181 .Ft void
182 .Fo snmp_output
183 .Fa "struct snmp_pdu *pdu" "u_char *sndbuf" "size_t *sndlen"
184 .Fa "const char *dest"
185 .Fc
186 .Ft void
187 .Fo snmp_send_port
188 .Fa "void *trans" "const struct asn_oid *port"
189 .Fa "struct snmp_pdu *pdu" "const struct sockaddr *addr" "socklen_t addrlen"
190 .Fc
191 .Ft void
192 .Fn snmp_send_trap "const struct asn_oid *oid" "..."
193 .Ft int
194 .Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
195 .Ft void
196 .Fn string_commit "struct snmp_context *ctx"
197 .Ft void
198 .Fn string_rollback "struct snmp_context *ctx" "u_char **strp"
199 .Ft int
200 .Fn string_get "struct snmp_value *val" "const u_char *str" "ssize_t len"
201 .Ft int
202 .Fn string_get_max "struct snmp_value *val" "const u_char *str" "ssize_t len" "size_t maxlen"
203 .Ft void
204 .Fn string_free "struct snmp_context *ctx"
205 .Ft int
206 .Fn ip_save "struct snmp_value *val" "struct snmp_context *ctx" "u_char *ipa"
207 .Ft void
208 .Fn ip_rollback "struct snmp_context *ctx" "u_char *ipa"
209 .Ft void
210 .Fn ip_commit "struct snmp_context *ctx"
211 .Ft int
212 .Fn ip_get "struct snmp_value *val" "u_char *ipa"
213 .Ft int
214 .Fn oid_save "struct snmp_value *val" "struct snmp_context *ctx" "struct asn_oid *oid"
215 .Ft void
216 .Fn oid_rollback "struct snmp_context *ctx" "struct asn_oid *oid"
217 .Ft void
218 .Fn oid_commit "struct snmp_context *ctx"
219 .Ft int
220 .Fn oid_get "struct snmp_value *val" "const struct asn_oid *oid"
221 .Ft int
222 .Fn index_decode "const struct asn_oid *oid" "u_int sub" "u_int code" "..."
223 .Ft int
224 .Fn index_compare "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2"
225 .Ft int
226 .Fn index_compare_off "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2" "u_int off"
227 .Ft void
228 .Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
229 .Ft void
230 .Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off"
231 .Sh DESCRIPTION
232 The
233 .Xr bsnmpd 1
234 SNMP daemon implements a minimal MIB which consists of the system group, part
235 of the SNMP MIB, a private configuration MIB, a trap destination table, a
236 UDP port table, a community table, a module table, a statistics group and
237 a debugging group.
238 All other MIBs are support through loadable modules.
239 This allows
240 .Xr bsnmpd 1
241 to use for task, that are not the classical SNMP task.
242 .Ss MODULE LOADING AND UNLOADING
243 Modules are loaded by writing to the module table.
244 This table is indexed by a string, that identifies the module to the daemon.
245 This identifier is used
246 to select the correct configuration section from the configuration files and
247 to identify resources allocated to this module.
248 A row in the module table is
249 created by writing a string of non-zero length to the
250 .Va begemotSnmpdModulePath
251 column.
252 This string must be the complete path to the file containing the module.
253 A module can be unloaded by writing a zero length string to the path column
254 of an existing row.
255 .Pp
256 Modules may depend on each other an hence must be loaded in the correct order.
257 The dependencies are listed in the corresponding manual pages.
258 .Pp
259 Upon loading a module the SNMP daemon expects the module file to a export
260 a global symbol
261 .Va config .
262 This symbol should be a variable of type
263 .Vt struct snmp_module :
264 .Bd -literal -offset indent
265 typedef enum snmpd_proxy_err (*proxy_err_f)(struct snmp_pdu *, void *,
266     const struct asn_oid *, const struct sockaddr *, socklen_t,
267     enum snmpd_input_err, int32_t);
268
269
270 struct snmp_module {
271         const char *comment;
272         int (*init)(struct lmodule *, int argc, char *argv[]);
273         int (*fini)(void);
274         void (*idle)(void);
275         void (*dump)(void);
276         void (*config)(void);
277         void (*start)(void);
278         proxy_err_f proxy;
279         const struct snmp_node *tree;
280         u_int tree_size;
281         void (*loading)(const struct lmodule *, int);
282 };
283 .Ed
284 .Pp
285 This structure must be statically initialized and its fields have the
286 following functions:
287 .Bl -tag -width ".It Va tree_size"
288 .It Va comment
289 This is a string that will be visible in the module table.
290 It should give some hint about the function of this module.
291 .It Va init
292 This function is called upon loading the module.
293 The module pointer should
294 be stored by the module because it is needed in other calls and the
295 argument vector will contain the arguments to this module from the daemons
296 command line.
297 This function should return 0 if everything is ok or an UNIX error code (see
298 .Xr errno 3 ) .
299 Once the function returns 0, the
300 .Va fini
301 function is called when the module is unloaded.
302 .It Va fini
303 The module is unloaded.
304 This gives the module a chance to free resources that
305 are not automatically freed.
306 Be sure to free all memory, because daemons tend to run very long.
307 This function pointer may be
308 .Li NULL
309 if it is not needed.
310 .It Va idle
311 If this function pointer is not
312 .Li NULL ,
313 the function pointed to by it is called whenever the daemon is going
314 to wait for an event.
315 Try to avoid using this feature.
316 .It Va dump
317 Whenever the daemon receives a
318 .Li SIGUSR1
319 it dumps it internal state via
320 .Xr syslog 3 .
321 If the
322 .Va dump
323 field is not
324 .Li NULL
325 it is called by the daemon to dump the state of the module.
326 .It Va config
327 Whenever the daemon receives a
328 .Li SIGHUP
329 signal it re-reads its configuration file.
330 If the
331 .Va config
332 field is not
333 .Li NULL
334 it is called after reading the configuration file to give the module a chance
335 to adapt to the new configuration.
336 .It Va start
337 If not
338 .Li NULL
339 this function is called after successful loading and initializing the module
340 to start its actual operation.
341 .It Va proxy
342 If the daemon receives a PDU and that PDU has a community string whose
343 community was registered by this module and
344 .Va proxy
345 is not
346 .Li NULL
347 than this function is called to handle the PDU.
348 .It Va tree
349 This is a pointer to the node array for the MIB tree implemented by this module.
350 .It Va tree_size
351 This is the number of nodes in
352 .Va tree .
353 .It Va loading
354 If this pointer is not
355 .Li NULL
356 it is called whenever another module was loaded or unloaded.
357 It gets a
358 pointer to that module and a flag that is 0 for unloading and 1 for loading.
359 .El
360 .Pp
361 When everything is ok, the daemon merges the module's MIB tree into its current
362 global tree, calls the modules
363 .Fn init
364 function.
365 If this function returns an error, the modules MIB tree is removed from
366 the global one and the module is unloaded.
367 If initialization is successful, the modules
368 .Fn start
369 function is called.
370 After it returns the
371 .Fn loaded
372 functions of all modules (including the loaded one) are called.
373 .Pp
374 When the module is unloaded, its MIB tree is removed from the global one,
375 the communities, request id ranges, running timers and selected file
376 descriptors are released, the
377 .Fn fini
378 function is called, the module file is unloaded and the
379 .Fn loaded
380 functions of all other modules are called.
381 .Ss IMPLEMENTING TABLES
382 There are a number of macros designed to help implementing SNMP tables.
383 A problem while implementing a table is the support for the GETNEXT operator.
384 The GETNEXT operation has to find out whether, given an arbitrary OID, the
385 lessest table row, that has an OID higher than the given OID.
386 The easiest way
387 to do this is to keep the table as an ordered list of structures each one
388 of which contains an OID that is the index of the table row.
389 This allows easy removal, insertion and search.
390 .Pp
391 The helper macros assume, that the table is organized as a TAILQ (see
392 .Xr queue 3
393 and each structure contains a
394 .Vt struct asn_oid
395 that is used as index.
396 For simple tables with only a integer or unsigned index, an alternate form
397 of the macros is available, that presume the existence of an integer or
398 unsigned field as index field.
399 .Pp
400 The macros have name of the form
401 .Bd -literal -offset indent
402 {INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]]
403 .Ed
404 .Pp
405 The
406 .Fn INSERT_*
407 macros are used in the SET operation to insert a new table row into the table.
408 The
409 .Fn FIND_*
410 macros are used in the GET operation to find a specific row in the table.
411 The
412 .Fn NEXT_*
413 macros are used in the GETNEXT operation to find the next row in the table.
414 The last two macros return a pointer to the row structure if a row is found,
415 .Li NULL
416 otherwise.
417 The macros
418 .Fn *_OBJECT_OID_*
419 assume the existence of a
420 .Vt struct asn_oid
421 that is used as index, the macros
422 .Fn *_OBJECT_INT_*
423 assume the existence of an unsigned integer field that is used as index.
424 .Pp
425 The macros
426 .Fn *_INDEX
427 allow the explicit naming of the index field in the parameter
428 .Fa INDEX ,
429 whereas the other macros assume that this field is named
430 .Va index .
431 The macros
432 .Fn *_LINK_*
433 allow the explicit naming of the link field of the tail queues, the others
434 assume that the link field is named
435 .Va link .
436 Explicitly naming the link field may be necessary if the same structures
437 are held in two or more different tables.
438 .Pp
439 The arguments to the macros are as follows:
440 .Bl -tag -width "INDEX"
441 .It Fa PTR
442 A pointer to the new structure to be inserted into the table.
443 .It Fa LIST
444 A pointer to the tail queue head.
445 .It Fa LINK
446 The name of the link field in the row structure.
447 .It Fa INDEX
448 The name of the index field in the row structure.
449 .It Fa OID
450 Must point to the
451 .Va var
452 field of the
453 .Fa value
454 argument to the node operation callback.
455 This is the OID to search for.
456 .It Fa SUB
457 This is the index of the start of the table index in the OID pointed to
458 by
459 .Fa OID .
460 This is usually the same as the
461 .Fa sub
462 argument to the node operation callback.
463 .El
464 .Ss DAEMON TIMESTAMPS
465 The variable
466 .Va this_tick
467 contains the tick (there are 100 SNMP ticks in a second) when
468 the current PDU processing was started.
469 The variable
470 .Va start_tick
471 contains the tick when the daemon was started.
472 The function
473 .Fn get_ticks
474 returns the current tick.
475 The number of ticks since the daemon was started
476 is
477 .Bd -literal -offset indent
478 get_ticks() - start_tick
479 .Ed
480 .Ss THE SYSTEM GROUP
481 The scalar fields of the system group are held in the global variable
482 .Va systemg :
483 .Bd -literal -offset indent
484 struct systemg {
485         u_char          *descr;
486         struct asn_oid  object_id;
487         u_char          *contact;
488         u_char          *name;
489         u_char          *location;
490         uint32_t        services;
491         uint32_t        or_last_change;
492 };
493 .Ed
494 .Ss COMMUNITIES
495 The SNMP daemon implements a community table.
496 On recipte of a request message
497 the community string in that message is compared to each of the community
498 strings in that table, if a match is found, the global variable
499 .Va community
500 is set to the community identifier for that community.
501 Community identifiers are unsigned integers.
502 For the three standard communities there are three constants defined:
503 .Bd -literal -offset indent
504 #define COMM_INITIALIZE 0
505 #define COMM_READ       1
506 #define COMM_WRITE      2
507 .Ed
508 .Pp
509 .Va community
510 is set to
511 .Li COMM_INITIALIZE
512 while the assignments in the configuration file are processed.
513 To
514 .Li COMM_READ
515 or
516 .Li COMM_WRITE
517 when the community strings for the read-write or read-only community are found
518 in the incoming PDU.
519 .Pp
520 Modules can define additional communities.
521 This may be necessary to provide
522 transport proxying (a PDU received on one communication link is proxied to
523 another link) or to implement non-UDP access points to SNMP.
524 A new community is defined with the function
525 .Fn comm_define .
526 It takes the following parameters:
527 .Bl -tag -width ".It Fa descr"
528 .It Fa priv
529 This is an integer identifying the community to the module.
530 Each module has its own namespace with regard to this parameter.
531 The community table is indexed with the module name and this identifier.
532 .It Fa descr
533 This is a string providing a human readable description of the community.
534 It is visible in the community table.
535 .It Fa mod
536 This is the module defining the community.
537 .It Fa str
538 This is the initial community string.
539 .El
540 .Pp
541 The function returns a globally unique community identifier.
542 If a PDU is
543 received who's community string matches, this identifier is set into the global
544 .Va community .
545 .Pp
546 The function
547 .Fn comm_string
548 returns the current community string for the given community.
549 .Pp
550 All communities defined by a module are automatically released when the module
551 is unloaded.
552 .Ss WELL KNOWN OIDS
553 The global variable
554 .Va oid_zeroDotZero
555 contains the OID 0.0.
556 .Ss REQUEST ID RANGES
557 For modules that implement SNMP client functions besides SNMP agent functions
558 it may be necessary to identify SNMP requests by their identifier to allow
559 easier routing of responses to the correct sub-system.
560 Request id ranges
561 provide a way to aquire globally non-overlapping sub-ranges of the entire
562 31-bit id range.
563 .Pp
564 A request id range is allocated with
565 .Fn reqid_allocate .
566 The arguments are: the size of the range and the module allocating the range.
567 For example, the call
568 .Bd -literal -offset indent
569 id = reqid_allocate(1000, module);
570 .Ed
571 .Pp
572 allocates a range of 1000 request ids.
573 The function returns the request
574 id range identifier or 0 if there is not enough identifier space.
575 The function
576 .Fn reqid_base
577 returns the lowest request id in the given range.
578 .Pp
579 Request id are allocated starting at the lowest one linear throughout the range.
580 If the client application may have a lot of outstanding request the range
581 must be large enough so that an id is not reused until it is really expired.
582 .Fn reqid_next
583 returns the sequentially next id in the range.
584 .Pp
585 The function
586 .Fn reqid_istype
587 checks whether the request id
588 .Fa reqid
589 is withing the range identified by
590 .Fa type .
591 The function
592 .Fn reqid_type
593 returns the range identifier for the given
594 .Fa reqid
595 or 0 if the request id is in none of the ranges.
596 .Ss TIMERS
597 The SNMP daemon supports an arbitrary number of timers with SNMP tick granularity.
598 The function
599 .Fn timer_start
600 arranges for the callback
601 .Fa func
602 to be called with the argument
603 .Fa uarg
604 after
605 .Fa ticks
606 SNMP ticks have expired.
607 .Fa mod
608 is the module that starts the timer.
609 These timers are one-shot, they are not restarted.
610 Repeatable timers are started with
611 .Fn timer_start_repeat
612 which takes an additional argument
613 .Fa repeat_ticks .
614 The argument
615 .Fa ticks
616 gives the number of ticks until the first execution of the callback, while
617 .Fa repeat_ticks
618 is the number of ticks between invocations of the callback.
619 Note, that currently the number of initial ticks silently may be set identical
620 to the number of ticks between callback invocations.
621 The function returns a timer identifier that can be used to stop the timer via
622 .Fn timer_stop .
623 If a module is unloaded all timers started by the module that have not expired
624 yet are stopped.
625 .Ss FILE DESCRIPTOR SUPPORT
626 A module may need to get input from socket file descriptors without blocking
627 the daemon (for example to implement alternative SNMP transports).
628 .Pp
629 The function
630 .Fn fd_select
631 causes the callback function
632 .Fa func
633 to be called with the file descriptor
634 .Fa fd
635 and the user argument
636 .Fa uarg
637 whenever the file descriptor
638 .Fa fd
639 can be read or has a close condition.
640 If the file descriptor is not in
641 non-blocking mode, it is set to non-blocking mode.
642 If the callback is not needed anymore,
643 .Fn fd_deselect
644 may be called with the value returned from
645 .Fn fd_select .
646 All file descriptors selected by a module are automatically deselected when
647 the module is unloaded.
648 .Pp
649 To temporarily suspend the file descriptor registration
650 .Fn fd_suspend
651 can be called.
652 This also causes the file descriptor to be switched back to
653 blocking mode if it was blocking prior the call to
654 .Fn fd_select .
655 This is necessary to do synchronous input on a selected socket.
656 The effect of
657 .Fn fd_suspend
658 can be undone with
659 .Fn fd_resume .
660 .Ss OBJECT RESOURCES
661 The system group contains an object resource table.
662 A module may create an entry in this table by calling
663 .Fn or_register
664 with the
665 .Fa oid
666 to be registered, a textual description in
667 .Fa str
668 and a pointer to the module
669 .Fa mod .
670 The registration can be removed with
671 .Fn or_unregister .
672 All registrations of a module are automatically removed if the module is
673 unloaded.
674 .Ss TRANSMIT AND RECEIVE BUFFERS
675 A buffer is allocated via
676 .Fn buf_alloc .
677 The argument must be 1 for transmit and 0 for receive buffers.
678 The function may return
679 .Li NULL
680 if there is no memory available.
681 The current buffersize can be obtained with
682 .Fn buf_size .
683 .Sh PROCESSING PDUS
684 For modules that need to do their own PDU processing (for example for proxying)
685 the following functions are available:
686 .Pp
687 Function
688 .Fn snmp_input_start
689 decodes the PDU, searches the community, and sets the global
690 .Va this_tick .
691 It returns one of the following error codes:
692 .Bl -tag -width ".It Er SNMPD_INPUT_VALBADLEN"
693 .It Er SNMPD_INPUT_OK
694 Everything ok, continue with processing.
695 .It Er SNMPD_INPUT_FAILED
696 The PDU could not be decoded, has a wrong version or an unknown
697 community string.
698 .It Er SNMPD_INPUT_VALBADLEN
699 A SET PDU had a value field in a binding with a wrong length field in an
700 ASN.1 header.
701 .It Er SNMPD_INPUT_VALRANGE
702 A SET PDU had a value field in a binding with a value that is out of range
703 for the given ASN.1 type.
704 .It Er SNMPD_INPUT_VALBADENC
705 A SET PDU had a value field in a binding with wrong ASN.1 encoding.
706 .It Er SNMPD_INPUT_TRUNC
707 The buffer appears to contain a valid begin of a PDU, but is too short.
708 For streaming transports this means that the caller must save what he
709 already has and trying to obtain more input and reissue this input to
710 the function.
711 For datagram transports this means that part of the
712 datagram was lost and the input should be ignored.
713 .El
714 .Pp
715 The function
716 .Fn snmp_input_finish
717 does the other half of processing: if
718 .Fn snmp_input_start
719 did not return OK, tries to construct an error response.
720 If the start was OK, it calls the correct function from
721 .Xr bsnmpagent 3
722 to execute the request and depending on the outcome constructs a response or
723 error response PDU or ignores the request PDU.
724 It returns either
725 .Er SNMPD_INPUT_OK
726 or
727 .Er SNMPD_INPUT_FAILED .
728 In the first case a response PDU was constructed and should be sent.
729 .Pp
730 The function
731 .Fn snmp_output
732 takes a PDU and encodes it.
733 .Pp
734 The function
735 .Fn snmp_send_port
736 takes a PDU, encodes it and sends it through the given port (identified by
737 the transport and the index in the port table) to the given address.
738 .Pp
739 The function
740 .Fn snmp_send_trap
741 sends a trap to all trap destinations.
742 The arguments are the
743 .Fa oid
744 identifying the trap and a NULL-terminated list of
745 .Vt struct snmp_value
746 pointers that are to be inserted into the trap binding list.
747 .Ss SIMPLE ACTION SUPPORT
748 For simple scalar variables that need no dependencies a number of support
749 functions is available to handle the set, commit, rollback and get.
750 .Pp
751 The following functions are used for OCTET STRING scalars, either NUL terminated
752 or not:
753 .Bl -tag -width "XXXXXXXXX"
754 .It Fn string_save
755 should be called for SNMP_OP_SET.
756 .Fa value
757 and
758 .Fa ctx
759 are the resp\&.\& arguments to the node callback.
760 .Fa valp
761 is a pointer to the pointer that holds the current value and
762 .Fa req_size
763 should be -1 if any size of the string is acceptable or a number larger or
764 equal zero if the string must have a specific size.
765 The function saves
766 the old value in the scratch area (note, that any initial value must have
767 been allocated by
768 .Xr malloc 3 ) ,
769 allocates a new string, copies over the new value, NUL-terminates it and
770 sets the new current value.
771 .It Fn string_commit
772 simply frees the saved old value in the scratch area.
773 .It Fn string_rollback
774 frees the new value, and puts back the old one.
775 .It Fn string_get
776 is used for GET or GETNEXT.
777 The function
778 .It Fn string_get_max
779 can be used instead of
780 .Nf stringto ensure that the returned string has a certain maximum length.
781 If
782 .Fa len
783 is -1, the length is computed via
784 .Xr strlen 3
785 from the current string value.
786 If the current value is NULL,
787 a OCTET STRING of zero length is returned.
788 .It Fn string_free
789 must be called if either rollback or commit fails to free the saved old value.
790 .El
791 .Pp
792 The following functions are used to process scalars of type IP-address:
793 .Bl -tag -width "XXXXXXXXX"
794 .It Fn ip_save
795 Saves the current value in the scratch area and sets the new value from
796 .Fa valp .
797 .It Fn ip_commit
798 Does nothing.
799 .It Fn ip_rollback
800 Restores the old IP address from the scratch area.
801 .It Fn ip_get
802 Retrieves the IP current address.
803 .El
804 .Pp
805 The following functions handle OID-typed variables:
806 .Bl -tag -width "XXXXXXXXX"
807 .It Fn oid_save
808 Saves the current value in the scratch area by allocating a
809 .Vt struct asn_oid
810 with
811 .Xr malloc 3
812 and sets the new value from
813 .Fa oid .
814 .It Fn oid_commit
815 Frees the old value in the scratch area.
816 .It Fn oid_rollback
817 Restores the old OID from the scratch area and frees the old OID.
818 .It Fn oid_get
819 Retrieves the OID
820 .El
821 .Ss TABLE INDEX HANDLING
822 The following functions help in handling table indexes:
823 .Bl -tag -width "XXXXXXXXX"
824 .It Fn index_decode
825 Decodes the index part of the OID.
826 The parameter
827 .Fa oid
828 must be a pointer to the
829 .Va var
830 field of the
831 .Fa value
832 argument of the node callback.
833 The
834 .Fa sub
835 argument must be the index of the start of the index in the OID (this is
836 the
837 .Fa sub
838 argument to the node callback).
839 .Fa code
840 is the index expression (parameter
841 .Fa idx
842 to the node callback).
843 These parameters are followed by parameters depending on the syntax of the index
844 elements as follows:
845 .Bl -tag -width ".It Li OCTET STRING"
846 .It Li INTEGER
847 .Vt int32_t *
848 expected as argument.
849 .It Li COUNTER64
850 .Vt uint64_t *
851 expected as argument.
852 Note, that this syntax is illegal for indexes.
853 .It Li OCTET STRING
854 A
855 .Vt u_char **
856 and a
857 .Vt size_t *
858 expected as arguments.
859 A buffer is allocated to hold the decoded string.
860 .It Li OID
861 A
862 .Vt struct asn_oid *
863 is expected as argument.
864 .It Li IP ADDRESS
865 A
866 .Vt u_int8_t *
867 expected as argument that points to a buffer of at least four byte.
868 .It Li COUNTER, GAUGE, TIMETICKS
869 A
870 .Vt u_int32_t
871 expected.
872 .It Li NULL
873 No argument expected.
874 .El
875 .It Fn index_compare
876 compares the current variable with an OID.
877 .Fa oid1
878 and
879 .Fa sub
880 come from the node callback arguments
881 .Fa value->var
882 and
883 .Fa sub
884 resp.
885 .Fa oid2
886 is the OID to compare to.
887 The function returns -1, 0, +1 when the
888 variable is lesser, equal, higher to the given OID.
889 .Fa oid2
890 must contain only the index part of the table column.
891 .It Fn index_compare_off
892 is equivalent to
893 .Fn index_compare
894 except that it takes an additional parameter
895 .Fa off
896 that causes it to ignore the first
897 .Fa off
898 components of both indexes.
899 .It Fn index_append
900 appends OID
901 .Fa src
902 beginning at position
903 .Fa sub
904 to
905 .Fa dst .
906 .It Fn index_append_off
907 appends OID
908 .Fa src
909 beginning at position
910 .Fa off
911 to
912 .Fa dst
913 beginning at position
914 .Fa sub
915 +
916 .Fa off .
917 .El
918 .Sh SEE ALSO
919 .Xr gensnmptree 1 ,
920 .Xr bsnmpd 1 ,
921 .Xr bsnmpagent 3 ,
922 .Xr bsnmpclient 3 ,
923 .Xr bsnmplib 3
924 .Sh STANDARDS
925 This implementation conforms to the applicable IETF RFCs and ITU-T
926 recommendations.
927 .Sh AUTHORS
928 .An Hartmut Brandt Aq harti@freebsd.org