]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/bsnmp/snmpd/snmpmod.3
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 December 19, 2010
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 oid_usmUnknownEngineIDs ,
64 .Nm oid_usmNotInTimeWindows ,
65 .Nm reqid_allocate ,
66 .Nm reqid_next ,
67 .Nm reqid_base ,
68 .Nm reqid_istype ,
69 .Nm reqid_type ,
70 .Nm timer_start ,
71 .Nm timer_start_repeat ,
72 .Nm timer_stop ,
73 .Nm fd_select ,
74 .Nm fd_deselect ,
75 .Nm fd_suspend ,
76 .Nm fd_resume ,
77 .Nm or_register ,
78 .Nm or_unregister ,
79 .Nm buf_alloc ,
80 .Nm buf_size ,
81 .Nm snmp_input_start ,
82 .Nm snmp_input_finish ,
83 .Nm snmp_output ,
84 .Nm snmp_send_port ,
85 .Nm snmp_send_trap ,
86 .Nm snmp_pdu_auth_access
87 .Nm string_save ,
88 .Nm string_commit ,
89 .Nm string_rollback ,
90 .Nm string_get ,
91 .Nm string_get_max ,
92 .Nm string_free ,
93 .Nm ip_save ,
94 .Nm ip_rollback ,
95 .Nm ip_commit ,
96 .Nm ip_get ,
97 .Nm oid_save ,
98 .Nm oid_rollback ,
99 .Nm oid_commit ,
100 .Nm oid_get ,
101 .Nm index_decode ,
102 .Nm index_compare ,
103 .Nm index_compare_off ,
104 .Nm index_append ,
105 .Nm index_append_off,
106 .Nm snmpd_usmstats,
107 .Nm bsnmpd_get_usm_stats,
108 .Nm bsnmpd_reset_usm_stats,
109 .Nm usm_first_user,
110 .Nm usm_next_user,
111 .Nm usm_find_user,
112 .Nm usm_new_user,
113 .Nm usm_delete_user,
114 .Nm usm_flush_users,
115 .Nm usm_user
116 .Nm snmpd_target_stat
117 .Nm bsnmpd_get_target_stats
118 .Nm target_first_address
119 .Nm target_next_address
120 .Nm target_new_address
121 .Nm target_activate_address
122 .Nm target_delete_address
123 .Nm target_first_param
124 .Nm target_next_param
125 .Nm target_new_param
126 .Nm target_delete_param
127 .Nm target_first_notify
128 .Nm target_next_notify
129 .Nm target_new_notify
130 .Nm target_delete_notify
131 .Nm target_flush_all
132 .Nm target_address
133 .Nm target_param
134 .Nm target_notify
135 .Nd "SNMP daemon loadable module interface"
136 .Sh LIBRARY
137 Begemot SNMP library
138 .Pq libbsnmp, -lbsnmp
139 .Sh SYNOPSIS
140 .In bsnmp/snmpmod.h
141 .Fn INSERT_OBJECT_OID_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
142 .Fn INSERT_OBJECT_INT_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
143 .Fn FIND_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
144 .Fn FIND_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
145 .Fn NEXT_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
146 .Fn NEXT_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
147 .Fn INSERT_OBJECT_OID_LINK "PTR" "LIST" "LINK"
148 .Fn INSERT_OBJECT_INT_LINK "PTR" "LIST" "LINK"
149 .Fn FIND_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
150 .Fn FIND_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
151 .Fn NEXT_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
152 .Fn NEXT_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
153 .Fn INSERT_OBJECT_OID "PTR" "LIST"
154 .Fn INSERT_OBJECT_INT "PTR" "LIST"
155 .Fn FIND_OBJECT_OID "LIST" "OID" "SUB"
156 .Fn FIND_OBJECT_INT "LIST" "OID" "SUB"
157 .Fn NEXT_OBJECT_OID "LIST" "OID" "SUB"
158 .Fn NEXT_OBJECT_INT "LIST" "OID" "SUB"
159 .Vt extern uint64_t this_tick ;
160 .Vt extern uint64_t start_tick ;
161 .Ft uint64_t
162 .Fn get_ticks "void"
163 .Vt extern struct systemg systemg ;
164 .Ft u_int
165 .Fn comm_define "u_int priv" "const char *descr" "struct lmodule *mod" "const char *str"
166 .Ft const char *
167 .Fn comm_string "u_int comm"
168 .Vt extern u_int community ;
169 .Vt extern const struct asn_oid oid_zeroDotZero ;
170 .Ft u_int
171 .Fn reqid_allocate "int size" "struct lmodule *mod"
172 .Ft int32_t
173 .Fn reqid_next "u_int type"
174 .Ft int32_t
175 .Fn reqid_base "u_int type"
176 .Ft int
177 .Fn reqid_istype "int32_t reqid" "u_int type"
178 .Ft u_int
179 .Fn reqid_type "int32_t reqid"
180 .Ft void *
181 .Fn timer_start "u_int ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
182 .Ft void *
183 .Fn timer_start_repeat "u_int ticks" "u_int repeat_ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
184 .Ft void
185 .Fn timer_stop "void *timer_id"
186 .Ft void *
187 .Fn fd_select "int fd" "void (*func)(int, void *)" "void *uarg" "struct lmodule *mod"
188 .Ft void
189 .Fn fd_deselect "void *fd_id"
190 .Ft void
191 .Fn fd_suspend "void *fd_id"
192 .Ft int
193 .Fn fd_resume "void *fd_id"
194 .Ft u_int
195 .Fn or_register "const struct asn_oid *oid" "const char *descr" "struct lmodule *mod"
196 .Ft void
197 .Fn or_unregister "u_int or_id"
198 .Ft void *
199 .Fn buf_alloc "int tx"
200 .Ft size_t
201 .Fn buf_size "int tx"
202 .Ft enum snmpd_input_err
203 .Fo snmp_input_start
204 .Fa "const u_char *buf" "size_t len" "const char *source"
205 .Fa "struct snmp_pdu *pdu" "int32_t *ip" "size_t *pdulen"
206 .Fc
207 .Ft enum snmpd_input_err
208 .Fo snmp_input_finish
209 .Fa "struct snmp_pdu *pdu" "const u_char *rcvbuf"
210 .Fa "size_t rcvlen" "u_char *sndbuf" "size_t *sndlen" "const char *source"
211 .Fa "enum snmpd_input_err ierr" "int32_t ip" "void *data"
212 .Fc
213 .Ft void
214 .Fo snmp_output
215 .Fa "struct snmp_pdu *pdu" "u_char *sndbuf" "size_t *sndlen"
216 .Fa "const char *dest"
217 .Fc
218 .Ft void
219 .Fo snmp_send_port
220 .Fa "void *trans" "const struct asn_oid *port"
221 .Fa "struct snmp_pdu *pdu" "const struct sockaddr *addr" "socklen_t addrlen"
222 .Fc
223 .Ft void
224 .Fn snmp_send_trap "const struct asn_oid *oid" "..."
225 .Ft enum snmp_code
226 .Fn snmp_pdu_auth_access "struct snmp_pdu *pdu" "int32_t *ip"
227 .Ft int
228 .Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
229 .Ft void
230 .Fn string_commit "struct snmp_context *ctx"
231 .Ft void
232 .Fn string_rollback "struct snmp_context *ctx" "u_char **strp"
233 .Ft int
234 .Fn string_get "struct snmp_value *val" "const u_char *str" "ssize_t len"
235 .Ft int
236 .Fn string_get_max "struct snmp_value *val" "const u_char *str" "ssize_t len" "size_t maxlen"
237 .Ft void
238 .Fn string_free "struct snmp_context *ctx"
239 .Ft int
240 .Fn ip_save "struct snmp_value *val" "struct snmp_context *ctx" "u_char *ipa"
241 .Ft void
242 .Fn ip_rollback "struct snmp_context *ctx" "u_char *ipa"
243 .Ft void
244 .Fn ip_commit "struct snmp_context *ctx"
245 .Ft int
246 .Fn ip_get "struct snmp_value *val" "u_char *ipa"
247 .Ft int
248 .Fn oid_save "struct snmp_value *val" "struct snmp_context *ctx" "struct asn_oid *oid"
249 .Ft void
250 .Fn oid_rollback "struct snmp_context *ctx" "struct asn_oid *oid"
251 .Ft void
252 .Fn oid_commit "struct snmp_context *ctx"
253 .Ft int
254 .Fn oid_get "struct snmp_value *val" "const struct asn_oid *oid"
255 .Ft int
256 .Fn index_decode "const struct asn_oid *oid" "u_int sub" "u_int code" "..."
257 .Ft int
258 .Fn index_compare "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2"
259 .Ft int
260 .Fn index_compare_off "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2" "u_int off"
261 .Ft void
262 .Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
263 .Ft void
264 .Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off"
265 .Vt extern struct snmpd_usmstat snmpd_usmstats ;
266 .Ft struct snmpd_usmstat *
267 .Fn bsnmpd_get_usm_stats "void"
268 .Ft void
269 .Fn bsnmpd_reset_usm_stats "void"
270 .Ft struct usm_user *
271 .Fn usm_first_user "void"
272 .Ft struct usm_user *
273 .Fn usm_next_user "struct usm_user *uuser"
274 .Ft struct usm_user *
275 .Fn usm_find_user "uint8_t *engine" "uint32_t elen" "char *uname"
276 .Ft struct usm_user *
277 .Fn usm_new_user "uint8_t *engine" "uint32_t elen" "char *uname"
278 .Ft void
279 .Fn usm_delete_user "struct usm_user *"
280 .Ft void
281 .Fn usm_flush_users "void"
282 .Vt extern struct usm_user *usm_user;
283 .Ft struct snmpd_target_stats *
284 .Fn bsnmpd_get_target_stats "void"
285 .Ft struct target_address *
286 .Fn target_first_address "void"
287 .Ft struct target_address *
288 .Fn target_next_address "struct target_address *"
289 .Ft struct target_address *
290 .Fn target_new_address "char *"
291 .Ft int
292 .Fn target_activate_address "struct target_address *"
293 .Ft int
294 .Fn target_delete_address "struct target_address *"
295 .Ft struct target_param *
296 .Fn target_first_param "void"
297 .Ft struct target_param *
298 .Fn target_next_param "struct target_param *"
299 .Ft struct target_param *
300 .Fn target_new_param "char *"
301 .Ft int
302 .Fn target_delete_param "struct target_param *"
303 .Ft struct target_notify *
304 .Fn target_first_notify "void"
305 .Ft struct target_notify *
306 .Fn target_next_notify "struct target_notify *"
307 .Ft struct target_notify *
308 .Fn target_new_notify "char *"
309 .Ft int
310 .Fn target_delete_notify "struct target_notify *"
311 .Ft void
312 .Fn target_flush_all "void"
313 .Vt extern const struct asn_oid oid_usmUnknownEngineIDs;
314 .Vt extern const struct asn_oid oid_usmNotInTimeWindows;
315 .Sh DESCRIPTION
316 The
317 .Xr bsnmpd 1
318 SNMP daemon implements a minimal MIB which consists of the system group, part
319 of the SNMP MIB, a private configuration MIB, a trap destination table, a
320 UDP port table, a community table, a module table, a statistics group and
321 a debugging group.
322 All other MIBs are support through loadable modules.
323 This allows
324 .Xr bsnmpd 1
325 to use for task, that are not the classical SNMP task.
326 .Ss MODULE LOADING AND UNLOADING
327 Modules are loaded by writing to the module table.
328 This table is indexed by a string, that identifies the module to the daemon.
329 This identifier is used
330 to select the correct configuration section from the configuration files and
331 to identify resources allocated to this module.
332 A row in the module table is
333 created by writing a string of non-zero length to the
334 .Va begemotSnmpdModulePath
335 column.
336 This string must be the complete path to the file containing the module.
337 A module can be unloaded by writing a zero length string to the path column
338 of an existing row.
339 .Pp
340 Modules may depend on each other an hence must be loaded in the correct order.
341 The dependencies are listed in the corresponding manual pages.
342 .Pp
343 Upon loading a module the SNMP daemon expects the module file to a export
344 a global symbol
345 .Va config .
346 This symbol should be a variable of type
347 .Vt struct snmp_module :
348 .Bd -literal -offset indent
349 typedef enum snmpd_proxy_err (*proxy_err_f)(struct snmp_pdu *, void *,
350     const struct asn_oid *, const struct sockaddr *, socklen_t,
351     enum snmpd_input_err, int32_t);
352
353
354 struct snmp_module {
355         const char *comment;
356         int (*init)(struct lmodule *, int argc, char *argv[]);
357         int (*fini)(void);
358         void (*idle)(void);
359         void (*dump)(void);
360         void (*config)(void);
361         void (*start)(void);
362         proxy_err_f proxy;
363         const struct snmp_node *tree;
364         u_int tree_size;
365         void (*loading)(const struct lmodule *, int);
366 };
367 .Ed
368 .Pp
369 This structure must be statically initialized and its fields have the
370 following functions:
371 .Bl -tag -width ".It Va tree_size"
372 .It Va comment
373 This is a string that will be visible in the module table.
374 It should give some hint about the function of this module.
375 .It Va init
376 This function is called upon loading the module.
377 The module pointer should
378 be stored by the module because it is needed in other calls and the
379 argument vector will contain the arguments to this module from the daemons
380 command line.
381 This function should return 0 if everything is ok or an UNIX error code (see
382 .Xr errno 3 ) .
383 Once the function returns 0, the
384 .Va fini
385 function is called when the module is unloaded.
386 .It Va fini
387 The module is unloaded.
388 This gives the module a chance to free resources that
389 are not automatically freed.
390 Be sure to free all memory, because daemons tend to run very long.
391 This function pointer may be
392 .Li NULL
393 if it is not needed.
394 .It Va idle
395 If this function pointer is not
396 .Li NULL ,
397 the function pointed to by it is called whenever the daemon is going
398 to wait for an event.
399 Try to avoid using this feature.
400 .It Va dump
401 Whenever the daemon receives a
402 .Li SIGUSR1
403 it dumps it internal state via
404 .Xr syslog 3 .
405 If the
406 .Va dump
407 field is not
408 .Li NULL
409 it is called by the daemon to dump the state of the module.
410 .It Va config
411 Whenever the daemon receives a
412 .Li SIGHUP
413 signal it re-reads its configuration file.
414 If the
415 .Va config
416 field is not
417 .Li NULL
418 it is called after reading the configuration file to give the module a chance
419 to adapt to the new configuration.
420 .It Va start
421 If not
422 .Li NULL
423 this function is called after successful loading and initializing the module
424 to start its actual operation.
425 .It Va proxy
426 If the daemon receives a PDU and that PDU has a community string whose
427 community was registered by this module and
428 .Va proxy
429 is not
430 .Li NULL
431 than this function is called to handle the PDU.
432 .It Va tree
433 This is a pointer to the node array for the MIB tree implemented by this module.
434 .It Va tree_size
435 This is the number of nodes in
436 .Va tree .
437 .It Va loading
438 If this pointer is not
439 .Li NULL
440 it is called whenever another module was loaded or unloaded.
441 It gets a
442 pointer to that module and a flag that is 0 for unloading and 1 for loading.
443 .El
444 .Pp
445 When everything is ok, the daemon merges the module's MIB tree into its current
446 global tree, calls the modules
447 .Fn init
448 function.
449 If this function returns an error, the modules MIB tree is removed from
450 the global one and the module is unloaded.
451 If initialization is successful, the modules
452 .Fn start
453 function is called.
454 After it returns the
455 .Fn loaded
456 functions of all modules (including the loaded one) are called.
457 .Pp
458 When the module is unloaded, its MIB tree is removed from the global one,
459 the communities, request id ranges, running timers and selected file
460 descriptors are released, the
461 .Fn fini
462 function is called, the module file is unloaded and the
463 .Fn loaded
464 functions of all other modules are called.
465 .Ss IMPLEMENTING TABLES
466 There are a number of macros designed to help implementing SNMP tables.
467 A problem while implementing a table is the support for the GETNEXT operator.
468 The GETNEXT operation has to find out whether, given an arbitrary OID, the
469 lessest table row, that has an OID higher than the given OID.
470 The easiest way
471 to do this is to keep the table as an ordered list of structures each one
472 of which contains an OID that is the index of the table row.
473 This allows easy removal, insertion and search.
474 .Pp
475 The helper macros assume, that the table is organized as a TAILQ (see
476 .Xr queue 3
477 and each structure contains a
478 .Vt struct asn_oid
479 that is used as index.
480 For simple tables with only a integer or unsigned index, an alternate form
481 of the macros is available, that presume the existence of an integer or
482 unsigned field as index field.
483 .Pp
484 The macros have name of the form
485 .Bd -literal -offset indent
486 {INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]]
487 .Ed
488 .Pp
489 The
490 .Fn INSERT_*
491 macros are used in the SET operation to insert a new table row into the table.
492 The
493 .Fn FIND_*
494 macros are used in the GET operation to find a specific row in the table.
495 The
496 .Fn NEXT_*
497 macros are used in the GETNEXT operation to find the next row in the table.
498 The last two macros return a pointer to the row structure if a row is found,
499 .Li NULL
500 otherwise.
501 The macros
502 .Fn *_OBJECT_OID_*
503 assume the existence of a
504 .Vt struct asn_oid
505 that is used as index, the macros
506 .Fn *_OBJECT_INT_*
507 assume the existence of an unsigned integer field that is used as index.
508 .Pp
509 The macros
510 .Fn *_INDEX
511 allow the explicit naming of the index field in the parameter
512 .Fa INDEX ,
513 whereas the other macros assume that this field is named
514 .Va index .
515 The macros
516 .Fn *_LINK_*
517 allow the explicit naming of the link field of the tail queues, the others
518 assume that the link field is named
519 .Va link .
520 Explicitly naming the link field may be necessary if the same structures
521 are held in two or more different tables.
522 .Pp
523 The arguments to the macros are as follows:
524 .Bl -tag -width "INDEX"
525 .It Fa PTR
526 A pointer to the new structure to be inserted into the table.
527 .It Fa LIST
528 A pointer to the tail queue head.
529 .It Fa LINK
530 The name of the link field in the row structure.
531 .It Fa INDEX
532 The name of the index field in the row structure.
533 .It Fa OID
534 Must point to the
535 .Va var
536 field of the
537 .Fa value
538 argument to the node operation callback.
539 This is the OID to search for.
540 .It Fa SUB
541 This is the index of the start of the table index in the OID pointed to
542 by
543 .Fa OID .
544 This is usually the same as the
545 .Fa sub
546 argument to the node operation callback.
547 .El
548 .Ss DAEMON TIMESTAMPS
549 The variable
550 .Va this_tick
551 contains the tick (there are 100 SNMP ticks in a second) when
552 the current PDU processing was started.
553 The variable
554 .Va start_tick
555 contains the tick when the daemon was started.
556 The function
557 .Fn get_ticks
558 returns the current tick.
559 The number of ticks since the daemon was started
560 is
561 .Bd -literal -offset indent
562 get_ticks() - start_tick
563 .Ed
564 .Ss THE SYSTEM GROUP
565 The scalar fields of the system group are held in the global variable
566 .Va systemg :
567 .Bd -literal -offset indent
568 struct systemg {
569         u_char          *descr;
570         struct asn_oid  object_id;
571         u_char          *contact;
572         u_char          *name;
573         u_char          *location;
574         uint32_t        services;
575         uint32_t        or_last_change;
576 };
577 .Ed
578 .Ss COMMUNITIES
579 The SNMP daemon implements a community table.
580 On recipte of a request message
581 the community string in that message is compared to each of the community
582 strings in that table, if a match is found, the global variable
583 .Va community
584 is set to the community identifier for that community.
585 Community identifiers are unsigned integers.
586 For the three standard communities there are three constants defined:
587 .Bd -literal -offset indent
588 #define COMM_INITIALIZE 0
589 #define COMM_READ       1
590 #define COMM_WRITE      2
591 .Ed
592 .Pp
593 .Va community
594 is set to
595 .Li COMM_INITIALIZE
596 while the assignments in the configuration file are processed.
597 To
598 .Li COMM_READ
599 or
600 .Li COMM_WRITE
601 when the community strings for the read-write or read-only community are found
602 in the incoming PDU.
603 .Pp
604 Modules can define additional communities.
605 This may be necessary to provide
606 transport proxying (a PDU received on one communication link is proxied to
607 another link) or to implement non-UDP access points to SNMP.
608 A new community is defined with the function
609 .Fn comm_define .
610 It takes the following parameters:
611 .Bl -tag -width ".It Fa descr"
612 .It Fa priv
613 This is an integer identifying the community to the module.
614 Each module has its own namespace with regard to this parameter.
615 The community table is indexed with the module name and this identifier.
616 .It Fa descr
617 This is a string providing a human readable description of the community.
618 It is visible in the community table.
619 .It Fa mod
620 This is the module defining the community.
621 .It Fa str
622 This is the initial community string.
623 .El
624 .Pp
625 The function returns a globally unique community identifier.
626 If a SNMPv1 or SNMPv2 PDU is
627 received who's community string matches, this identifier is set into the global
628 .Va community .
629 .Pp
630 The function
631 .Fn comm_string
632 returns the current community string for the given community.
633 .Pp
634 All communities defined by a module are automatically released when the module
635 is unloaded.
636 .Ss THE USER-BASED SECURITY GROUP
637 The scalar statistics of the USM group are held in the global variable
638 .Va snmpd_usmstats :
639 .Bd -literal -offset indent
640 struct snmpd_usmstat {
641         uint32_t        unsupported_seclevels;
642         uint32_t        not_in_time_windows;
643         uint32_t        unknown_users;
644         uint32_t        unknown_engine_ids;
645         uint32_t        wrong_digests;
646         uint32_t        decrypt_errors;
647 };
648 .Ed
649 .Fn bsnmpd_get_usm_stats
650 returns a pointer to the global structure containing the statistics.
651 .Fn bsnmpd_reset_usm_stats
652 clears the statistics of the USM group.
653 .Pp
654 A global list of configured USM users is maintained by the daemon.
655 .Bd -literal -offset indent
656 struct usm_user {
657         struct snmp_user                suser;
658         uint8_t                         user_engine_id[SNMP_ENGINE_ID_SIZ];
659         uint32_t                        user_engine_len;
660         char                            user_public[SNMP_ADM_STR32_SIZ];
661         uint32_t                        user_public_len;
662         int32_t                         status;
663         int32_t                         type;
664         SLIST_ENTRY(usm_user)           up;
665 };
666 .Ed
667 This structure represents an USM user. The daemon only responds to SNMPv3 PDUs
668 with user credentials matching an USM user entry in its global list.
669 If a SNMPv3 PDU is received, whose security model is USM, the global
670 .Va usm_user
671 is set to point at the user entry that matches the credentials contained in
672 the PDU.
673 However, the daemon does not create or remove USM users, it gives an interface
674 to external loadable module(s) to manage the list.
675 .Fn usm_new_user
676 adds an user entry in the list, and
677 .Fn usm_delete_user
678 deletes an existing entry from the list.
679 .Fn usm_flush_users
680 is used to remove all configured USM users.
681 .Fn usm_first_user
682 will return the first user in the list, or
683 .Li NULL
684 if the list is empty.
685 .Fn usm_next_user
686 will return  the next user of a given entry if one exists, or
687 .Li NULL .
688 The list is sorted according to the USM user name and Engine ID.
689 .Fn usm_find_user
690 returns the USM user entry matching the given
691 .Fa engine
692 and
693 .Fa uname
694 or
695 .Li NULL
696 if an user with the specified name and engine id is not present in the list.
697 .Ss THE MANAGEMENT TARGET GROUP
698 The Management Target group holds target address information used when sending
699 SNMPv3 notifications.
700 .Pp
701 The scalar statistics of the Management Target group are held in the global
702 variable
703 .Va snmpd_target_stats :
704 .Bd -literal -offset indent
705 struct snmpd_target_stats {
706         uint32_t                        unavail_contexts;
707         uint32_t                        unknown_contexts;
708 };
709 .Ed
710 .Fn bsnmpd_get_target_stats
711 returns a pointer to the global structure containing the statistics.
712 .Pp
713 Three global lists of configured management target addresses, parameters and
714 notifications respectively are maintained by the daemon.
715 .Bd -literal -offset indent
716 struct target_address {
717         char                            name[SNMP_ADM_STR32_SIZ];
718         uint8_t                         address[SNMP_UDP_ADDR_SIZ];
719         int32_t                         timeout;
720         int32_t                         retry;
721         char                            taglist[SNMP_TAG_SIZ];
722         char                            paramname[SNMP_ADM_STR32_SIZ];
723         int32_t                         type;
724         int32_t                         socket;
725         int32_t                         status;
726         SLIST_ENTRY(target_address)     ta;
727 };
728 .Ed
729 This structure represents a SNMPv3 Management Target address. Each time a SNMP
730 TRAP is send the daemon will send the Trap to all active Management Target
731 addresses in its global list.
732 .Bd -literal -offset indent
733 struct target_param {
734         char                            name[SNMP_ADM_STR32_SIZ];
735         int32_t                         mpmodel;
736         int32_t                         sec_model;
737         char                            secname[SNMP_ADM_STR32_SIZ];
738         enum snmp_usm_level             sec_level;
739         int32_t                         type;
740         int32_t                         status;
741         SLIST_ENTRY(target_param)       tp;
742 };
743 .Ed
744 This structure represents the information used to generate SNMP messages to the
745 associated SNMPv3 Management Target addresses.
746 .Bd -literal -offset indent
747 struct target_notify {
748         char                            name[SNMP_ADM_STR32_SIZ];
749         char                            taglist[SNMP_TAG_SIZ];
750         int32_t                         notify_type;
751         int32_t                         type;
752         int32_t                         status;
753         SLIST_ENTRY(target_notify)      tn;
754 };
755 .Ed
756 This structure represents Notification Tag entries - SNMP notifications are sent
757 to the Target address for each entry in the Management Target Address list that
758 has a tag matching the specified tag in this structure.
759 .Pp
760 The daemon does not create or remove entries in the Management Target group
761 lists, it gives an interface to external loadable module(s) to manage the lists.
762 .Fn target_new_address
763 adds a target address entry, and
764 .Fn target_delete_address
765 deletes an existing entry from the target address list.
766 .Fn target_activate_address
767 creates a socket associated with the target address entry so that SNMP
768 notifications may actually be send to that target address.
769 .Fn target_first_address
770 will return a pointer to the first target address entry in the list, while
771 .Fn target_next_address
772 will return a pointer to the next target address of a given entry if one exists.
773 .Fn target_new_param
774 adds a target parameters' entry, and
775 .Fn target_delete_param
776 deletes an existing entry from the target parameters list.
777 .Fn target_first_param
778 will return a pointer to the first target parameters' entry in the list, while
779 .Fn target_next_param
780 will return a pointer to the next target parameters of a given entry if one
781 exists.
782 .Fn target_new_notify
783 adds a notification target entry, and
784 .Fn target_delete_notify
785 deletes an existing entry from the notification target list.
786 .Fn target_first_notify
787 will return a pointer to the first notification target entry in the list, while
788 .Fn target_next_notify
789 will return a pointer to the next notification target of a given entry if one
790 exists.
791 .Fn target_flush_all
792 is used to remove all configured data from the three global Management Target
793 Group lists.
794 .Ss WELL KNOWN OIDS
795 The global variable
796 .Va oid_zeroDotZero
797 contains the OID 0.0.
798 The global variables
799 .Va oid_usmUnknownEngineIDs
800 .Va oid_usmNotInTimeWindows
801 contains the OIDs 1.3.6.1.6.3.15.1.1.4.0 and  1.3.6.1.6.3.15.1.1.2.0 used
802 in the SNMPv3 USM Engine Discovery.
803 .Ss REQUEST ID RANGES
804 For modules that implement SNMP client functions besides SNMP agent functions
805 it may be necessary to identify SNMP requests by their identifier to allow
806 easier routing of responses to the correct sub-system.
807 Request id ranges
808 provide a way to acquire globally non-overlapping sub-ranges of the entire
809 31-bit id range.
810 .Pp
811 A request id range is allocated with
812 .Fn reqid_allocate .
813 The arguments are: the size of the range and the module allocating the range.
814 For example, the call
815 .Bd -literal -offset indent
816 id = reqid_allocate(1000, module);
817 .Ed
818 .Pp
819 allocates a range of 1000 request ids.
820 The function returns the request
821 id range identifier or 0 if there is not enough identifier space.
822 The function
823 .Fn reqid_base
824 returns the lowest request id in the given range.
825 .Pp
826 Request id are allocated starting at the lowest one linear throughout the range.
827 If the client application may have a lot of outstanding request the range
828 must be large enough so that an id is not reused until it is really expired.
829 .Fn reqid_next
830 returns the sequentially next id in the range.
831 .Pp
832 The function
833 .Fn reqid_istype
834 checks whether the request id
835 .Fa reqid
836 is within the range identified by
837 .Fa type .
838 The function
839 .Fn reqid_type
840 returns the range identifier for the given
841 .Fa reqid
842 or 0 if the request id is in none of the ranges.
843 .Ss TIMERS
844 The SNMP daemon supports an arbitrary number of timers with SNMP tick granularity.
845 The function
846 .Fn timer_start
847 arranges for the callback
848 .Fa func
849 to be called with the argument
850 .Fa uarg
851 after
852 .Fa ticks
853 SNMP ticks have expired.
854 .Fa mod
855 is the module that starts the timer.
856 These timers are one-shot, they are not restarted.
857 Repeatable timers are started with
858 .Fn timer_start_repeat
859 which takes an additional argument
860 .Fa repeat_ticks .
861 The argument
862 .Fa ticks
863 gives the number of ticks until the first execution of the callback, while
864 .Fa repeat_ticks
865 is the number of ticks between invocations of the callback.
866 Note, that currently the number of initial ticks silently may be set identical
867 to the number of ticks between callback invocations.
868 The function returns a timer identifier that can be used to stop the timer via
869 .Fn timer_stop .
870 If a module is unloaded all timers started by the module that have not expired
871 yet are stopped.
872 .Ss FILE DESCRIPTOR SUPPORT
873 A module may need to get input from socket file descriptors without blocking
874 the daemon (for example to implement alternative SNMP transports).
875 .Pp
876 The function
877 .Fn fd_select
878 causes the callback function
879 .Fa func
880 to be called with the file descriptor
881 .Fa fd
882 and the user argument
883 .Fa uarg
884 whenever the file descriptor
885 .Fa fd
886 can be read or has a close condition.
887 If the file descriptor is not in
888 non-blocking mode, it is set to non-blocking mode.
889 If the callback is not needed anymore,
890 .Fn fd_deselect
891 may be called with the value returned from
892 .Fn fd_select .
893 All file descriptors selected by a module are automatically deselected when
894 the module is unloaded.
895 .Pp
896 To temporarily suspend the file descriptor registration
897 .Fn fd_suspend
898 can be called.
899 This also causes the file descriptor to be switched back to
900 blocking mode if it was blocking prior the call to
901 .Fn fd_select .
902 This is necessary to do synchronous input on a selected socket.
903 The effect of
904 .Fn fd_suspend
905 can be undone with
906 .Fn fd_resume .
907 .Ss OBJECT RESOURCES
908 The system group contains an object resource table.
909 A module may create an entry in this table by calling
910 .Fn or_register
911 with the
912 .Fa oid
913 to be registered, a textual description in
914 .Fa str
915 and a pointer to the module
916 .Fa mod .
917 The registration can be removed with
918 .Fn or_unregister .
919 All registrations of a module are automatically removed if the module is
920 unloaded.
921 .Ss TRANSMIT AND RECEIVE BUFFERS
922 A buffer is allocated via
923 .Fn buf_alloc .
924 The argument must be 1 for transmit and 0 for receive buffers.
925 The function may return
926 .Li NULL
927 if there is no memory available.
928 The current buffersize can be obtained with
929 .Fn buf_size .
930 .Sh PROCESSING PDUS
931 For modules that need to do their own PDU processing (for example for proxying)
932 the following functions are available:
933 .Pp
934 Function
935 .Fn snmp_input_start
936 decodes the PDU, searches the community, and sets the global
937 .Va this_tick .
938 It returns one of the following error codes:
939 .Bl -tag -width ".It Er SNMPD_INPUT_VALBADLEN"
940 .It Er SNMPD_INPUT_OK
941 Everything ok, continue with processing.
942 .It Er SNMPD_INPUT_FAILED
943 The PDU could not be decoded, has a wrong version or an unknown
944 community string.
945 .It Er SNMPD_INPUT_VALBADLEN
946 A SET PDU had a value field in a binding with a wrong length field in an
947 ASN.1 header.
948 .It Er SNMPD_INPUT_VALRANGE
949 A SET PDU had a value field in a binding with a value that is out of range
950 for the given ASN.1 type.
951 .It Er SNMPD_INPUT_VALBADENC
952 A SET PDU had a value field in a binding with wrong ASN.1 encoding.
953 .It Er SNMPD_INPUT_TRUNC
954 The buffer appears to contain a valid begin of a PDU, but is too short.
955 For streaming transports this means that the caller must save what he
956 already has and trying to obtain more input and reissue this input to
957 the function.
958 For datagram transports this means that part of the
959 datagram was lost and the input should be ignored.
960 .El
961 .Pp
962 The function
963 .Fn snmp_input_finish
964 does the other half of processing: if
965 .Fn snmp_input_start
966 did not return OK, tries to construct an error response.
967 If the start was OK, it calls the correct function from
968 .Xr bsnmpagent 3
969 to execute the request and depending on the outcome constructs a response or
970 error response PDU or ignores the request PDU.
971 It returns either
972 .Er SNMPD_INPUT_OK
973 or
974 .Er SNMPD_INPUT_FAILED .
975 In the first case a response PDU was constructed and should be sent.
976 .Pp
977 The function
978 .Fn snmp_output
979 takes a PDU and encodes it.
980 .Pp
981 The function
982 .Fn snmp_send_port
983 takes a PDU, encodes it and sends it through the given port (identified by
984 the transport and the index in the port table) to the given address.
985 .Pp
986 The function
987 .Fn snmp_send_trap
988 sends a trap to all trap destinations.
989 The arguments are the
990 .Fa oid
991 identifying the trap and a NULL-terminated list of
992 .Vt struct snmp_value
993 pointers that are to be inserted into the trap binding list.
994 .Fn snmp_pdu_auth_access
995 verifies whether access to the object IDs contained in the
996 .Fa pdu
997  should be granted or denied, according to the configured View-Based Access
998 rules.
999 .Fa ip
1000 contains the index of the first varbinding to which access was denied, or 0 if
1001 access to all varbindings in the PDU is granted.
1002 .Ss SIMPLE ACTION SUPPORT
1003 For simple scalar variables that need no dependencies a number of support
1004 functions is available to handle the set, commit, rollback and get.
1005 .Pp
1006 The following functions are used for OCTET STRING scalars, either NUL terminated
1007 or not:
1008 .Bl -tag -width "XXXXXXXXX"
1009 .It Fn string_save
1010 should be called for SNMP_OP_SET.
1011 .Fa value
1012 and
1013 .Fa ctx
1014 are the resp\&.\& arguments to the node callback.
1015 .Fa valp
1016 is a pointer to the pointer that holds the current value and
1017 .Fa req_size
1018 should be -1 if any size of the string is acceptable or a number larger or
1019 equal zero if the string must have a specific size.
1020 The function saves
1021 the old value in the scratch area (note, that any initial value must have
1022 been allocated by
1023 .Xr malloc 3 ) ,
1024 allocates a new string, copies over the new value, NUL-terminates it and
1025 sets the new current value.
1026 .It Fn string_commit
1027 simply frees the saved old value in the scratch area.
1028 .It Fn string_rollback
1029 frees the new value, and puts back the old one.
1030 .It Fn string_get
1031 is used for GET or GETNEXT.
1032 The function
1033 .It Fn string_get_max
1034 can be used instead of
1035 .Fn string_get
1036 to ensure that the returned string has a certain maximum length.
1037 If
1038 .Fa len
1039 is -1, the length is computed via
1040 .Xr strlen 3
1041 from the current string value.
1042 If the current value is NULL,
1043 a OCTET STRING of zero length is returned.
1044 .It Fn string_free
1045 must be called if either rollback or commit fails to free the saved old value.
1046 .El
1047 .Pp
1048 The following functions are used to process scalars of type IP-address:
1049 .Bl -tag -width "XXXXXXXXX"
1050 .It Fn ip_save
1051 Saves the current value in the scratch area and sets the new value from
1052 .Fa valp .
1053 .It Fn ip_commit
1054 Does nothing.
1055 .It Fn ip_rollback
1056 Restores the old IP address from the scratch area.
1057 .It Fn ip_get
1058 Retrieves the IP current address.
1059 .El
1060 .Pp
1061 The following functions handle OID-typed variables:
1062 .Bl -tag -width "XXXXXXXXX"
1063 .It Fn oid_save
1064 Saves the current value in the scratch area by allocating a
1065 .Vt struct asn_oid
1066 with
1067 .Xr malloc 3
1068 and sets the new value from
1069 .Fa oid .
1070 .It Fn oid_commit
1071 Frees the old value in the scratch area.
1072 .It Fn oid_rollback
1073 Restores the old OID from the scratch area and frees the old OID.
1074 .It Fn oid_get
1075 Retrieves the OID
1076 .El
1077 .Ss TABLE INDEX HANDLING
1078 The following functions help in handling table indexes:
1079 .Bl -tag -width "XXXXXXXXX"
1080 .It Fn index_decode
1081 Decodes the index part of the OID.
1082 The parameter
1083 .Fa oid
1084 must be a pointer to the
1085 .Va var
1086 field of the
1087 .Fa value
1088 argument of the node callback.
1089 The
1090 .Fa sub
1091 argument must be the index of the start of the index in the OID (this is
1092 the
1093 .Fa sub
1094 argument to the node callback).
1095 .Fa code
1096 is the index expression (parameter
1097 .Fa idx
1098 to the node callback).
1099 These parameters are followed by parameters depending on the syntax of the index
1100 elements as follows:
1101 .Bl -tag -width ".It Li OCTET STRING"
1102 .It Li INTEGER
1103 .Vt int32_t *
1104 expected as argument.
1105 .It Li COUNTER64
1106 .Vt uint64_t *
1107 expected as argument.
1108 Note, that this syntax is illegal for indexes.
1109 .It Li OCTET STRING
1110 A
1111 .Vt u_char **
1112 and a
1113 .Vt size_t *
1114 expected as arguments.
1115 A buffer is allocated to hold the decoded string.
1116 .It Li OID
1117 A
1118 .Vt struct asn_oid *
1119 is expected as argument.
1120 .It Li IP ADDRESS
1121 A
1122 .Vt u_int8_t *
1123 expected as argument that points to a buffer of at least four byte.
1124 .It Li COUNTER, GAUGE, TIMETICKS
1125 A
1126 .Vt u_int32_t
1127 expected.
1128 .It Li NULL
1129 No argument expected.
1130 .El
1131 .It Fn index_compare
1132 compares the current variable with an OID.
1133 .Fa oid1
1134 and
1135 .Fa sub
1136 come from the node callback arguments
1137 .Fa value->var
1138 and
1139 .Fa sub
1140 resp.
1141 .Fa oid2
1142 is the OID to compare to.
1143 The function returns -1, 0, +1 when the
1144 variable is lesser, equal, higher to the given OID.
1145 .Fa oid2
1146 must contain only the index part of the table column.
1147 .It Fn index_compare_off
1148 is equivalent to
1149 .Fn index_compare
1150 except that it takes an additional parameter
1151 .Fa off
1152 that causes it to ignore the first
1153 .Fa off
1154 components of both indexes.
1155 .It Fn index_append
1156 appends OID
1157 .Fa src
1158 beginning at position
1159 .Fa sub
1160 to
1161 .Fa dst .
1162 .It Fn index_append_off
1163 appends OID
1164 .Fa src
1165 beginning at position
1166 .Fa off
1167 to
1168 .Fa dst
1169 beginning at position
1170 .Fa sub
1171 +
1172 .Fa off .
1173 .El
1174 .Sh SEE ALSO
1175 .Xr gensnmptree 1 ,
1176 .Xr bsnmpd 1 ,
1177 .Xr bsnmpagent 3 ,
1178 .Xr bsnmpclient 3 ,
1179 .Xr bsnmplib 3
1180 .Sh STANDARDS
1181 This implementation conforms to the applicable IETF RFCs and ITU-T
1182 recommendations.
1183 .Sh AUTHORS
1184 .An Hartmut Brandt Aq harti@FreeBSD.org