]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - contrib/bsnmp/snmpd/snmpmod.3
MFC r300667:
[FreeBSD/stable/8.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 acquire 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 within 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 .Fn string_get
781 to ensure that the returned string has a certain maximum length.
782 If
783 .Fa len
784 is -1, the length is computed via
785 .Xr strlen 3
786 from the current string value.
787 If the current value is NULL,
788 a OCTET STRING of zero length is returned.
789 .It Fn string_free
790 must be called if either rollback or commit fails to free the saved old value.
791 .El
792 .Pp
793 The following functions are used to process scalars of type IP-address:
794 .Bl -tag -width "XXXXXXXXX"
795 .It Fn ip_save
796 Saves the current value in the scratch area and sets the new value from
797 .Fa valp .
798 .It Fn ip_commit
799 Does nothing.
800 .It Fn ip_rollback
801 Restores the old IP address from the scratch area.
802 .It Fn ip_get
803 Retrieves the IP current address.
804 .El
805 .Pp
806 The following functions handle OID-typed variables:
807 .Bl -tag -width "XXXXXXXXX"
808 .It Fn oid_save
809 Saves the current value in the scratch area by allocating a
810 .Vt struct asn_oid
811 with
812 .Xr malloc 3
813 and sets the new value from
814 .Fa oid .
815 .It Fn oid_commit
816 Frees the old value in the scratch area.
817 .It Fn oid_rollback
818 Restores the old OID from the scratch area and frees the old OID.
819 .It Fn oid_get
820 Retrieves the OID
821 .El
822 .Ss TABLE INDEX HANDLING
823 The following functions help in handling table indexes:
824 .Bl -tag -width "XXXXXXXXX"
825 .It Fn index_decode
826 Decodes the index part of the OID.
827 The parameter
828 .Fa oid
829 must be a pointer to the
830 .Va var
831 field of the
832 .Fa value
833 argument of the node callback.
834 The
835 .Fa sub
836 argument must be the index of the start of the index in the OID (this is
837 the
838 .Fa sub
839 argument to the node callback).
840 .Fa code
841 is the index expression (parameter
842 .Fa idx
843 to the node callback).
844 These parameters are followed by parameters depending on the syntax of the index
845 elements as follows:
846 .Bl -tag -width ".It Li OCTET STRING"
847 .It Li INTEGER
848 .Vt int32_t *
849 expected as argument.
850 .It Li COUNTER64
851 .Vt uint64_t *
852 expected as argument.
853 Note, that this syntax is illegal for indexes.
854 .It Li OCTET STRING
855 A
856 .Vt u_char **
857 and a
858 .Vt size_t *
859 expected as arguments.
860 A buffer is allocated to hold the decoded string.
861 .It Li OID
862 A
863 .Vt struct asn_oid *
864 is expected as argument.
865 .It Li IP ADDRESS
866 A
867 .Vt u_int8_t *
868 expected as argument that points to a buffer of at least four byte.
869 .It Li COUNTER, GAUGE, TIMETICKS
870 A
871 .Vt u_int32_t
872 expected.
873 .It Li NULL
874 No argument expected.
875 .El
876 .It Fn index_compare
877 compares the current variable with an OID.
878 .Fa oid1
879 and
880 .Fa sub
881 come from the node callback arguments
882 .Fa value->var
883 and
884 .Fa sub
885 resp.
886 .Fa oid2
887 is the OID to compare to.
888 The function returns -1, 0, +1 when the
889 variable is lesser, equal, higher to the given OID.
890 .Fa oid2
891 must contain only the index part of the table column.
892 .It Fn index_compare_off
893 is equivalent to
894 .Fn index_compare
895 except that it takes an additional parameter
896 .Fa off
897 that causes it to ignore the first
898 .Fa off
899 components of both indexes.
900 .It Fn index_append
901 appends OID
902 .Fa src
903 beginning at position
904 .Fa sub
905 to
906 .Fa dst .
907 .It Fn index_append_off
908 appends OID
909 .Fa src
910 beginning at position
911 .Fa off
912 to
913 .Fa dst
914 beginning at position
915 .Fa sub
916 +
917 .Fa off .
918 .El
919 .Sh SEE ALSO
920 .Xr gensnmptree 1 ,
921 .Xr bsnmpd 1 ,
922 .Xr bsnmpagent 3 ,
923 .Xr bsnmpclient 3 ,
924 .Xr bsnmplib 3
925 .Sh STANDARDS
926 This implementation conforms to the applicable IETF RFCs and ITU-T
927 recommendations.
928 .Sh AUTHORS
929 .An Hartmut Brandt Aq harti@FreeBSD.org