xref: /freebsd/contrib/bsnmp/snmpd/snmpmod.3 (revision cfd6422a5217410fbd66f7a7a8a64d9d85e61229)
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
137Begemot 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
316The
317.Xr bsnmpd 1
318SNMP daemon implements a minimal MIB which consists of the system group, part
319of the SNMP MIB, a private configuration MIB, a trap destination table, a
320UDP port table, a community table, a module table, a statistics group and
321a debugging group.
322All other MIBs are support through loadable modules.
323This allows
324.Xr bsnmpd 1
325to use for task, that are not the classical SNMP task.
326.Ss MODULE LOADING AND UNLOADING
327Modules are loaded by writing to the module table.
328This table is indexed by a string, that identifies the module to the daemon.
329This identifier is used
330to select the correct configuration section from the configuration files and
331to identify resources allocated to this module.
332A row in the module table is
333created by writing a string of non-zero length to the
334.Va begemotSnmpdModulePath
335column.
336This string must be the complete path to the file containing the module.
337A module can be unloaded by writing a zero length string to the path column
338of an existing row.
339.Pp
340Modules may depend on each other an hence must be loaded in the correct order.
341The dependencies are listed in the corresponding manual pages.
342.Pp
343Upon loading a module the SNMP daemon expects the module file to a export
344a global symbol
345.Va config .
346This symbol should be a variable of type
347.Vt struct snmp_module :
348.Bd -literal -offset indent
349typedef 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
354struct 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
369This structure must be statically initialized and its fields have the
370following functions:
371.Bl -tag -width ".It Va tree_size"
372.It Va comment
373This is a string that will be visible in the module table.
374It should give some hint about the function of this module.
375.It Va init
376This function is called upon loading the module.
377The module pointer should
378be stored by the module because it is needed in other calls and the
379argument vector will contain the arguments to this module from the daemons
380command line.
381This function should return 0 if everything is ok or an UNIX error code (see
382.Xr errno 3 ) .
383Once the function returns 0, the
384.Va fini
385function is called when the module is unloaded.
386.It Va fini
387The module is unloaded.
388This gives the module a chance to free resources that
389are not automatically freed.
390Be sure to free all memory, because daemons tend to run very long.
391This function pointer may be
392.Li NULL
393if it is not needed.
394.It Va idle
395If this function pointer is not
396.Li NULL ,
397the function pointed to by it is called whenever the daemon is going
398to wait for an event.
399Try to avoid using this feature.
400.It Va dump
401Whenever the daemon receives a
402.Li SIGUSR1
403it dumps it internal state via
404.Xr syslog 3 .
405If the
406.Va dump
407field is not
408.Li NULL
409it is called by the daemon to dump the state of the module.
410.It Va config
411Whenever the daemon receives a
412.Li SIGHUP
413signal it re-reads its configuration file.
414If the
415.Va config
416field is not
417.Li NULL
418it is called after reading the configuration file to give the module a chance
419to adapt to the new configuration.
420.It Va start
421If not
422.Li NULL
423this function is called after successful loading and initializing the module
424to start its actual operation.
425.It Va proxy
426If the daemon receives a PDU and that PDU has a community string whose
427community was registered by this module and
428.Va proxy
429is not
430.Li NULL
431than this function is called to handle the PDU.
432.It Va tree
433This is a pointer to the node array for the MIB tree implemented by this module.
434.It Va tree_size
435This is the number of nodes in
436.Va tree .
437.It Va loading
438If this pointer is not
439.Li NULL
440it is called whenever another module was loaded or unloaded.
441It gets a
442pointer to that module and a flag that is 0 for unloading and 1 for loading.
443.El
444.Pp
445When everything is ok, the daemon merges the module's MIB tree into its current
446global tree, calls the modules
447.Fn init
448function.
449If this function returns an error, the modules MIB tree is removed from
450the global one and the module is unloaded.
451If initialization is successful, the modules
452.Fn start
453function is called.
454After it returns the
455.Fn loaded
456functions of all modules (including the loaded one) are called.
457.Pp
458When the module is unloaded, its MIB tree is removed from the global one,
459the communities, request id ranges, running timers and selected file
460descriptors are released, the
461.Fn fini
462function is called, the module file is unloaded and the
463.Fn loaded
464functions of all other modules are called.
465.Ss IMPLEMENTING TABLES
466There are a number of macros designed to help implementing SNMP tables.
467A problem while implementing a table is the support for the GETNEXT operator.
468The GETNEXT operation has to find out whether, given an arbitrary OID, the
469lessest table row, that has an OID higher than the given OID.
470The easiest way
471to do this is to keep the table as an ordered list of structures each one
472of which contains an OID that is the index of the table row.
473This allows easy removal, insertion and search.
474.Pp
475The helper macros assume, that the table is organized as a TAILQ (see
476.Xr queue 3
477and each structure contains a
478.Vt struct asn_oid
479that is used as index.
480For simple tables with only a integer or unsigned index, an alternate form
481of the macros is available, that presume the existence of an integer or
482unsigned field as index field.
483.Pp
484The macros have name of the form
485.Bd -literal -offset indent
486{INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]]
487.Ed
488.Pp
489The
490.Fn INSERT_*
491macros are used in the SET operation to insert a new table row into the table.
492The
493.Fn FIND_*
494macros are used in the GET operation to find a specific row in the table.
495The
496.Fn NEXT_*
497macros are used in the GETNEXT operation to find the next row in the table.
498The last two macros return a pointer to the row structure if a row is found,
499.Li NULL
500otherwise.
501The macros
502.Fn *_OBJECT_OID_*
503assume the existence of a
504.Vt struct asn_oid
505that is used as index, the macros
506.Fn *_OBJECT_INT_*
507assume the existence of an unsigned integer field that is used as index.
508.Pp
509The macros
510.Fn *_INDEX
511allow the explicit naming of the index field in the parameter
512.Fa INDEX ,
513whereas the other macros assume that this field is named
514.Va index .
515The macros
516.Fn *_LINK_*
517allow the explicit naming of the link field of the tail queues, the others
518assume that the link field is named
519.Va link .
520Explicitly naming the link field may be necessary if the same structures
521are held in two or more different tables.
522.Pp
523The arguments to the macros are as follows:
524.Bl -tag -width "INDEX"
525.It Fa PTR
526A pointer to the new structure to be inserted into the table.
527.It Fa LIST
528A pointer to the tail queue head.
529.It Fa LINK
530The name of the link field in the row structure.
531.It Fa INDEX
532The name of the index field in the row structure.
533.It Fa OID
534Must point to the
535.Va var
536field of the
537.Fa value
538argument to the node operation callback.
539This is the OID to search for.
540.It Fa SUB
541This is the index of the start of the table index in the OID pointed to
542by
543.Fa OID .
544This is usually the same as the
545.Fa sub
546argument to the node operation callback.
547.El
548.Ss DAEMON TIMESTAMPS
549The variable
550.Va this_tick
551contains the tick (there are 100 SNMP ticks in a second) when
552the current PDU processing was started.
553The variable
554.Va start_tick
555contains the tick when the daemon was started.
556The function
557.Fn get_ticks
558returns the current tick.
559The number of ticks since the daemon was started
560is
561.Bd -literal -offset indent
562get_ticks() - start_tick
563.Ed
564.Ss THE SYSTEM GROUP
565The scalar fields of the system group are held in the global variable
566.Va systemg :
567.Bd -literal -offset indent
568struct 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
579The SNMP daemon implements a community table.
580On receipt of a request message
581the community string in that message is compared to each of the community
582strings in that table, if a match is found, the global variable
583.Va community
584is set to the community identifier for that community.
585Community identifiers are unsigned integers.
586For 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
594is set to
595.Li COMM_INITIALIZE
596while the assignments in the configuration file are processed.
597To
598.Li COMM_READ
599or
600.Li COMM_WRITE
601when the community strings for the read-write or read-only community are found
602in the incoming PDU.
603.Pp
604Modules can define additional communities.
605This may be necessary to provide
606transport proxying (a PDU received on one communication link is proxied to
607another link) or to implement non-UDP access points to SNMP.
608A new community is defined with the function
609.Fn comm_define .
610It takes the following parameters:
611.Bl -tag -width ".It Fa descr"
612.It Fa priv
613This is an integer identifying the community to the module.
614Each module has its own namespace with regard to this parameter.
615The community table is indexed with the module name and this identifier.
616.It Fa descr
617This is a string providing a human readable description of the community.
618It is visible in the community table.
619.It Fa mod
620This is the module defining the community.
621.It Fa str
622This is the initial community string.
623.El
624.Pp
625The function returns a globally unique community identifier.
626If a SNMPv1 or SNMPv2 PDU is
627received who's community string matches, this identifier is set into the global
628.Va community .
629.Pp
630The function
631.Fn comm_string
632returns the current community string for the given community.
633.Pp
634All communities defined by a module are automatically released when the module
635is unloaded.
636.Ss THE USER-BASED SECURITY GROUP
637The scalar statistics of the USM group are held in the global variable
638.Va snmpd_usmstats :
639.Bd -literal -offset indent
640struct 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
650returns a pointer to the global structure containing the statistics.
651.Fn bsnmpd_reset_usm_stats
652clears the statistics of the USM group.
653.Pp
654A global list of configured USM users is maintained by the daemon.
655.Bd -literal -offset indent
656struct 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
667This structure represents an USM user. The daemon only responds to SNMPv3 PDUs
668with user credentials matching an USM user entry in its global list.
669If a SNMPv3 PDU is received, whose security model is USM, the global
670.Va usm_user
671is set to point at the user entry that matches the credentials contained in
672the PDU.
673However, the daemon does not create or remove USM users, it gives an interface
674to external loadable module(s) to manage the list.
675.Fn usm_new_user
676adds an user entry in the list, and
677.Fn usm_delete_user
678deletes an existing entry from the list.
679.Fn usm_flush_users
680is used to remove all configured USM users.
681.Fn usm_first_user
682will return the first user in the list, or
683.Li NULL
684if the list is empty.
685.Fn usm_next_user
686will return  the next user of a given entry if one exists, or
687.Li NULL .
688The list is sorted according to the USM user name and Engine ID.
689.Fn usm_find_user
690returns the USM user entry matching the given
691.Fa engine
692and
693.Fa uname
694or
695.Li NULL
696if an user with the specified name and engine id is not present in the list.
697.Ss THE MANAGEMENT TARGET GROUP
698The Management Target group holds target address information used when sending
699SNMPv3 notifications.
700.Pp
701The scalar statistics of the Management Target group are held in the global
702variable
703.Va snmpd_target_stats :
704.Bd -literal -offset indent
705struct snmpd_target_stats {
706	uint32_t			unavail_contexts;
707	uint32_t			unknown_contexts;
708};
709.Ed
710.Fn bsnmpd_get_target_stats
711returns a pointer to the global structure containing the statistics.
712.Pp
713Three global lists of configured management target addresses, parameters and
714notifications respectively are maintained by the daemon.
715.Bd -literal -offset indent
716struct 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
729This structure represents a SNMPv3 Management Target address. Each time a SNMP
730TRAP is send the daemon will send the Trap to all active Management Target
731addresses in its global list.
732.Bd -literal -offset indent
733struct 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
744This structure represents the information used to generate SNMP messages to the
745associated SNMPv3 Management Target addresses.
746.Bd -literal -offset indent
747struct 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
756This structure represents Notification Tag entries - SNMP notifications are sent
757to the Target address for each entry in the Management Target Address list that
758has a tag matching the specified tag in this structure.
759.Pp
760The daemon does not create or remove entries in the Management Target group
761lists, it gives an interface to external loadable module(s) to manage the lists.
762.Fn target_new_address
763adds a target address entry, and
764.Fn target_delete_address
765deletes an existing entry from the target address list.
766.Fn target_activate_address
767creates a socket associated with the target address entry so that SNMP
768notifications may actually be send to that target address.
769.Fn target_first_address
770will return a pointer to the first target address entry in the list, while
771.Fn target_next_address
772will return a pointer to the next target address of a given entry if one exists.
773.Fn target_new_param
774adds a target parameters' entry, and
775.Fn target_delete_param
776deletes an existing entry from the target parameters list.
777.Fn target_first_param
778will return a pointer to the first target parameters' entry in the list, while
779.Fn target_next_param
780will return a pointer to the next target parameters of a given entry if one
781exists.
782.Fn target_new_notify
783adds a notification target entry, and
784.Fn target_delete_notify
785deletes an existing entry from the notification target list.
786.Fn target_first_notify
787will return a pointer to the first notification target entry in the list, while
788.Fn target_next_notify
789will return a pointer to the next notification target of a given entry if one
790exists.
791.Fn target_flush_all
792is used to remove all configured data from the three global Management Target
793Group lists.
794.Ss WELL KNOWN OIDS
795The global variable
796.Va oid_zeroDotZero
797contains the OID 0.0.
798The global variables
799.Va oid_usmUnknownEngineIDs
800.Va oid_usmNotInTimeWindows
801contains 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
802in the SNMPv3 USM Engine Discovery.
803.Ss REQUEST ID RANGES
804For modules that implement SNMP client functions besides SNMP agent functions
805it may be necessary to identify SNMP requests by their identifier to allow
806easier routing of responses to the correct sub-system.
807Request id ranges
808provide a way to acquire globally non-overlapping sub-ranges of the entire
80931-bit id range.
810.Pp
811A request id range is allocated with
812.Fn reqid_allocate .
813The arguments are: the size of the range and the module allocating the range.
814For example, the call
815.Bd -literal -offset indent
816id = reqid_allocate(1000, module);
817.Ed
818.Pp
819allocates a range of 1000 request ids.
820The function returns the request
821id range identifier or 0 if there is not enough identifier space.
822The function
823.Fn reqid_base
824returns the lowest request id in the given range.
825.Pp
826Request id are allocated starting at the lowest one linear throughout the range.
827If the client application may have a lot of outstanding request the range
828must be large enough so that an id is not reused until it is really expired.
829.Fn reqid_next
830returns the sequentially next id in the range.
831.Pp
832The function
833.Fn reqid_istype
834checks whether the request id
835.Fa reqid
836is within the range identified by
837.Fa type .
838The function
839.Fn reqid_type
840returns the range identifier for the given
841.Fa reqid
842or 0 if the request id is in none of the ranges.
843.Ss TIMERS
844The SNMP daemon supports an arbitrary number of timers with SNMP tick granularity.
845The function
846.Fn timer_start
847arranges for the callback
848.Fa func
849to be called with the argument
850.Fa uarg
851after
852.Fa ticks
853SNMP ticks have expired.
854.Fa mod
855is the module that starts the timer.
856These timers are one-shot, they are not restarted.
857Repeatable timers are started with
858.Fn timer_start_repeat
859which takes an additional argument
860.Fa repeat_ticks .
861The argument
862.Fa ticks
863gives the number of ticks until the first execution of the callback, while
864.Fa repeat_ticks
865is the number of ticks between invocations of the callback.
866Note, that currently the number of initial ticks silently may be set identical
867to the number of ticks between callback invocations.
868The function returns a timer identifier that can be used to stop the timer via
869.Fn timer_stop .
870If a module is unloaded all timers started by the module that have not expired
871yet are stopped.
872.Ss FILE DESCRIPTOR SUPPORT
873A module may need to get input from socket file descriptors without blocking
874the daemon (for example to implement alternative SNMP transports).
875.Pp
876The function
877.Fn fd_select
878causes the callback function
879.Fa func
880to be called with the file descriptor
881.Fa fd
882and the user argument
883.Fa uarg
884whenever the file descriptor
885.Fa fd
886can be read or has a close condition.
887If the file descriptor is not in
888non-blocking mode, it is set to non-blocking mode.
889If the callback is not needed anymore,
890.Fn fd_deselect
891may be called with the value returned from
892.Fn fd_select .
893All file descriptors selected by a module are automatically deselected when
894the module is unloaded.
895.Pp
896To temporarily suspend the file descriptor registration
897.Fn fd_suspend
898can be called.
899This also causes the file descriptor to be switched back to
900blocking mode if it was blocking prior the call to
901.Fn fd_select .
902This is necessary to do synchronous input on a selected socket.
903The effect of
904.Fn fd_suspend
905can be undone with
906.Fn fd_resume .
907.Ss OBJECT RESOURCES
908The system group contains an object resource table.
909A module may create an entry in this table by calling
910.Fn or_register
911with the
912.Fa oid
913to be registered, a textual description in
914.Fa str
915and a pointer to the module
916.Fa mod .
917The registration can be removed with
918.Fn or_unregister .
919All registrations of a module are automatically removed if the module is
920unloaded.
921.Ss TRANSMIT AND RECEIVE BUFFERS
922A buffer is allocated via
923.Fn buf_alloc .
924The argument must be 1 for transmit and 0 for receive buffers.
925The function may return
926.Li NULL
927if there is no memory available.
928The current buffersize can be obtained with
929.Fn buf_size .
930.Sh PROCESSING PDUS
931For modules that need to do their own PDU processing (for example for proxying)
932the following functions are available:
933.Pp
934Function
935.Fn snmp_input_start
936decodes the PDU, searches the community, and sets the global
937.Va this_tick .
938It returns one of the following error codes:
939.Bl -tag -width ".It Er SNMPD_INPUT_VALBADLEN"
940.It Er SNMPD_INPUT_OK
941Everything ok, continue with processing.
942.It Er SNMPD_INPUT_FAILED
943The PDU could not be decoded, has a wrong version or an unknown
944community string.
945.It Er SNMPD_INPUT_VALBADLEN
946A SET PDU had a value field in a binding with a wrong length field in an
947ASN.1 header.
948.It Er SNMPD_INPUT_VALRANGE
949A SET PDU had a value field in a binding with a value that is out of range
950for the given ASN.1 type.
951.It Er SNMPD_INPUT_VALBADENC
952A SET PDU had a value field in a binding with wrong ASN.1 encoding.
953.It Er SNMPD_INPUT_TRUNC
954The buffer appears to contain a valid begin of a PDU, but is too short.
955For streaming transports this means that the caller must save what he
956already has and trying to obtain more input and reissue this input to
957the function.
958For datagram transports this means that part of the
959datagram was lost and the input should be ignored.
960.El
961.Pp
962The function
963.Fn snmp_input_finish
964does the other half of processing: if
965.Fn snmp_input_start
966did not return OK, tries to construct an error response.
967If the start was OK, it calls the correct function from
968.Xr bsnmpagent 3
969to execute the request and depending on the outcome constructs a response or
970error response PDU or ignores the request PDU.
971It returns either
972.Er SNMPD_INPUT_OK
973or
974.Er SNMPD_INPUT_FAILED .
975In the first case a response PDU was constructed and should be sent.
976.Pp
977The function
978.Fn snmp_output
979takes a PDU and encodes it.
980.Pp
981The function
982.Fn snmp_send_port
983takes a PDU, encodes it and sends it through the given port (identified by
984the transport and the index in the port table) to the given address.
985.Pp
986The function
987.Fn snmp_send_trap
988sends a trap to all trap destinations.
989The arguments are the
990.Fa oid
991identifying the trap and a NULL-terminated list of
992.Vt struct snmp_value
993pointers that are to be inserted into the trap binding list.
994.Fn snmp_pdu_auth_access
995verifies 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
998rules.
999.Fa ip
1000contains the index of the first varbinding to which access was denied, or 0 if
1001access to all varbindings in the PDU is granted.
1002.Ss SIMPLE ACTION SUPPORT
1003For simple scalar variables that need no dependencies a number of support
1004functions is available to handle the set, commit, rollback and get.
1005.Pp
1006The following functions are used for OCTET STRING scalars, either NUL terminated
1007or not:
1008.Bl -tag -width "XXXXXXXXX"
1009.It Fn string_save
1010should be called for SNMP_OP_SET.
1011.Fa value
1012and
1013.Fa ctx
1014are the resp\&.\& arguments to the node callback.
1015.Fa valp
1016is a pointer to the pointer that holds the current value and
1017.Fa req_size
1018should be -1 if any size of the string is acceptable or a number larger or
1019equal zero if the string must have a specific size.
1020The function saves
1021the old value in the scratch area (note, that any initial value must have
1022been allocated by
1023.Xr malloc 3 ) ,
1024allocates a new string, copies over the new value, NUL-terminates it and
1025sets the new current value.
1026.It Fn string_commit
1027simply frees the saved old value in the scratch area.
1028.It Fn string_rollback
1029frees the new value, and puts back the old one.
1030.It Fn string_get
1031is used for GET or GETNEXT.
1032The function
1033.It Fn string_get_max
1034can be used instead of
1035.Fn string_get
1036to ensure that the returned string has a certain maximum length.
1037If
1038.Fa len
1039is -1, the length is computed via
1040.Xr strlen 3
1041from the current string value.
1042If the current value is NULL,
1043a OCTET STRING of zero length is returned.
1044.It Fn string_free
1045must be called if either rollback or commit fails to free the saved old value.
1046.El
1047.Pp
1048The following functions are used to process scalars of type IP-address:
1049.Bl -tag -width "XXXXXXXXX"
1050.It Fn ip_save
1051Saves the current value in the scratch area and sets the new value from
1052.Fa valp .
1053.It Fn ip_commit
1054Does nothing.
1055.It Fn ip_rollback
1056Restores the old IP address from the scratch area.
1057.It Fn ip_get
1058Retrieves the IP current address.
1059.El
1060.Pp
1061The following functions handle OID-typed variables:
1062.Bl -tag -width "XXXXXXXXX"
1063.It Fn oid_save
1064Saves the current value in the scratch area by allocating a
1065.Vt struct asn_oid
1066with
1067.Xr malloc 3
1068and sets the new value from
1069.Fa oid .
1070.It Fn oid_commit
1071Frees the old value in the scratch area.
1072.It Fn oid_rollback
1073Restores the old OID from the scratch area and frees the old OID.
1074.It Fn oid_get
1075Retrieves the OID
1076.El
1077.Ss TABLE INDEX HANDLING
1078The following functions help in handling table indexes:
1079.Bl -tag -width "XXXXXXXXX"
1080.It Fn index_decode
1081Decodes the index part of the OID.
1082The parameter
1083.Fa oid
1084must be a pointer to the
1085.Va var
1086field of the
1087.Fa value
1088argument of the node callback.
1089The
1090.Fa sub
1091argument must be the index of the start of the index in the OID (this is
1092the
1093.Fa sub
1094argument to the node callback).
1095.Fa code
1096is the index expression (parameter
1097.Fa idx
1098to the node callback).
1099These parameters are followed by parameters depending on the syntax of the index
1100elements as follows:
1101.Bl -tag -width ".It Li OCTET STRING"
1102.It Li INTEGER
1103.Vt int32_t *
1104expected as argument.
1105.It Li COUNTER64
1106.Vt uint64_t *
1107expected as argument.
1108Note, that this syntax is illegal for indexes.
1109.It Li OCTET STRING
1110A
1111.Vt u_char **
1112and a
1113.Vt size_t *
1114expected as arguments.
1115A buffer is allocated to hold the decoded string.
1116.It Li OID
1117A
1118.Vt struct asn_oid *
1119is expected as argument.
1120.It Li IP ADDRESS
1121A
1122.Vt u_int8_t *
1123expected as argument that points to a buffer of at least four byte.
1124.It Li COUNTER, GAUGE, TIMETICKS
1125A
1126.Vt u_int32_t
1127expected.
1128.It Li NULL
1129No argument expected.
1130.El
1131.It Fn index_compare
1132compares the current variable with an OID.
1133.Fa oid1
1134and
1135.Fa sub
1136come from the node callback arguments
1137.Fa value->var
1138and
1139.Fa sub
1140resp.
1141.Fa oid2
1142is the OID to compare to.
1143The function returns -1, 0, +1 when the
1144variable is lesser, equal, higher to the given OID.
1145.Fa oid2
1146must contain only the index part of the table column.
1147.It Fn index_compare_off
1148is equivalent to
1149.Fn index_compare
1150except that it takes an additional parameter
1151.Fa off
1152that causes it to ignore the first
1153.Fa off
1154components of both indexes.
1155.It Fn index_append
1156appends OID
1157.Fa src
1158beginning at position
1159.Fa sub
1160to
1161.Fa dst .
1162.It Fn index_append_off
1163appends OID
1164.Fa src
1165beginning at position
1166.Fa off
1167to
1168.Fa dst
1169beginning 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
1181This implementation conforms to the applicable IETF RFCs and ITU-T
1182recommendations.
1183.Sh AUTHORS
1184.An Hartmut Brandt Aq harti@FreeBSD.org
1185