2 .\" Copyright (c) 2004-2005
4 .\" All rights reserved.
5 .\" Copyright (c) 2001-2003
6 .\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
7 .\" All rights reserved.
9 .\" Author: Harti Brandt <harti@FreeBSD.org>
11 .\" Redistribution and use in source and binary forms, with or without
12 .\" modification, are permitted provided that the following conditions
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.
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
32 .\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.14 2005/10/04 13:30:35 brandt_h Exp $
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 ,
63 .Nm oid_usmUnknownEngineIDs ,
64 .Nm oid_usmNotInTimeWindows ,
71 .Nm timer_start_repeat ,
81 .Nm snmp_input_start ,
82 .Nm snmp_input_finish ,
86 .Nm snmp_pdu_auth_access
103 .Nm index_compare_off ,
105 .Nm index_append_off,
107 .Nm bsnmpd_get_usm_stats,
108 .Nm bsnmpd_reset_usm_stats,
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
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
135 .Nd "SNMP daemon loadable module interface"
138 .Pq libbsnmp, -lbsnmp
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 ;
163 .Vt extern struct systemg systemg ;
165 .Fn comm_define "u_int priv" "const char *descr" "struct lmodule *mod" "const char *str"
167 .Fn comm_string "u_int comm"
168 .Vt extern u_int community ;
169 .Vt extern const struct asn_oid oid_zeroDotZero ;
171 .Fn reqid_allocate "int size" "struct lmodule *mod"
173 .Fn reqid_next "u_int type"
175 .Fn reqid_base "u_int type"
177 .Fn reqid_istype "int32_t reqid" "u_int type"
179 .Fn reqid_type "int32_t reqid"
181 .Fn timer_start "u_int ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
183 .Fn timer_start_repeat "u_int ticks" "u_int repeat_ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
185 .Fn timer_stop "void *timer_id"
187 .Fn fd_select "int fd" "void (*func)(int, void *)" "void *uarg" "struct lmodule *mod"
189 .Fn fd_deselect "void *fd_id"
191 .Fn fd_suspend "void *fd_id"
193 .Fn fd_resume "void *fd_id"
195 .Fn or_register "const struct asn_oid *oid" "const char *descr" "struct lmodule *mod"
197 .Fn or_unregister "u_int or_id"
199 .Fn buf_alloc "int tx"
201 .Fn buf_size "int tx"
202 .Ft enum snmpd_input_err
204 .Fa "const u_char *buf" "size_t len" "const char *source"
205 .Fa "struct snmp_pdu *pdu" "int32_t *ip" "size_t *pdulen"
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"
215 .Fa "struct snmp_pdu *pdu" "u_char *sndbuf" "size_t *sndlen"
216 .Fa "const char *dest"
220 .Fa "void *trans" "const struct asn_oid *port"
221 .Fa "struct snmp_pdu *pdu" "const struct sockaddr *addr" "socklen_t addrlen"
224 .Fn snmp_send_trap "const struct asn_oid *oid" "..."
226 .Fn snmp_pdu_auth_access "struct snmp_pdu *pdu" "int32_t *ip"
228 .Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
230 .Fn string_commit "struct snmp_context *ctx"
232 .Fn string_rollback "struct snmp_context *ctx" "u_char **strp"
234 .Fn string_get "struct snmp_value *val" "const u_char *str" "ssize_t len"
236 .Fn string_get_max "struct snmp_value *val" "const u_char *str" "ssize_t len" "size_t maxlen"
238 .Fn string_free "struct snmp_context *ctx"
240 .Fn ip_save "struct snmp_value *val" "struct snmp_context *ctx" "u_char *ipa"
242 .Fn ip_rollback "struct snmp_context *ctx" "u_char *ipa"
244 .Fn ip_commit "struct snmp_context *ctx"
246 .Fn ip_get "struct snmp_value *val" "u_char *ipa"
248 .Fn oid_save "struct snmp_value *val" "struct snmp_context *ctx" "struct asn_oid *oid"
250 .Fn oid_rollback "struct snmp_context *ctx" "struct asn_oid *oid"
252 .Fn oid_commit "struct snmp_context *ctx"
254 .Fn oid_get "struct snmp_value *val" "const struct asn_oid *oid"
256 .Fn index_decode "const struct asn_oid *oid" "u_int sub" "u_int code" "..."
258 .Fn index_compare "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2"
260 .Fn index_compare_off "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2" "u_int off"
262 .Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
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"
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"
279 .Fn usm_delete_user "struct usm_user *"
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 *"
292 .Fn target_activate_address "struct target_address *"
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 *"
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 *"
310 .Fn target_delete_notify "struct target_notify *"
312 .Fn target_flush_all "void"
313 .Vt extern const struct asn_oid oid_usmUnknownEngineIDs;
314 .Vt extern const struct asn_oid oid_usmNotInTimeWindows;
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
322 All other MIBs are support through loadable modules.
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
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
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.
343 Upon loading a module the SNMP daemon expects the module file to a export
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);
356 int (*init)(struct lmodule *, int argc, char *argv[]);
360 void (*config)(void);
363 const struct snmp_node *tree;
365 void (*loading)(const struct lmodule *, int);
369 This structure must be statically initialized and its fields have the
371 .Bl -tag -width ".It Va tree_size"
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.
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
381 This function should return 0 if everything is ok or an UNIX error code (see
383 Once the function returns 0, the
385 function is called when the module is unloaded.
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
395 If this function pointer is not
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.
401 Whenever the daemon receives a
403 it dumps it internal state via
409 it is called by the daemon to dump the state of the module.
411 Whenever the daemon receives a
413 signal it re-reads its configuration file.
418 it is called after reading the configuration file to give the module a chance
419 to adapt to the new configuration.
423 this function is called after successful loading and initializing the module
424 to start its actual operation.
426 If the daemon receives a PDU and that PDU has a community string whose
427 community was registered by this module and
431 than this function is called to handle the PDU.
433 This is a pointer to the node array for the MIB tree implemented by this module.
435 This is the number of nodes in
438 If this pointer is not
440 it is called whenever another module was loaded or unloaded.
442 pointer to that module and a flag that is 0 for unloading and 1 for loading.
445 When everything is ok, the daemon merges the module's MIB tree into its current
446 global tree, calls the modules
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
456 functions of all modules (including the loaded one) are called.
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
462 function is called, the module file is unloaded and the
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.
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.
475 The helper macros assume, that the table is organized as a TAILQ (see
477 and each structure contains a
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.
484 The macros have name of the form
485 .Bd -literal -offset indent
486 {INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]]
491 macros are used in the SET operation to insert a new table row into the table.
494 macros are used in the GET operation to find a specific row in the table.
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,
503 assume the existence of a
505 that is used as index, the macros
507 assume the existence of an unsigned integer field that is used as index.
511 allow the explicit naming of the index field in the parameter
513 whereas the other macros assume that this field is named
517 allow the explicit naming of the link field of the tail queues, the others
518 assume that the link field is named
520 Explicitly naming the link field may be necessary if the same structures
521 are held in two or more different tables.
523 The arguments to the macros are as follows:
524 .Bl -tag -width "INDEX"
526 A pointer to the new structure to be inserted into the table.
528 A pointer to the tail queue head.
530 The name of the link field in the row structure.
532 The name of the index field in the row structure.
538 argument to the node operation callback.
539 This is the OID to search for.
541 This is the index of the start of the table index in the OID pointed to
544 This is usually the same as the
546 argument to the node operation callback.
548 .Ss DAEMON TIMESTAMPS
551 contains the tick (there are 100 SNMP ticks in a second) when
552 the current PDU processing was started.
555 contains the tick when the daemon was started.
558 returns the current tick.
559 The number of ticks since the daemon was started
561 .Bd -literal -offset indent
562 get_ticks() - start_tick
565 The scalar fields of the system group are held in the global variable
567 .Bd -literal -offset indent
570 struct asn_oid object_id;
575 uint32_t or_last_change;
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
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
596 while the assignments in the configuration file are processed.
601 when the community strings for the read-write or read-only community are found
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
610 It takes the following parameters:
611 .Bl -tag -width ".It Fa descr"
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.
617 This is a string providing a human readable description of the community.
618 It is visible in the community table.
620 This is the module defining the community.
622 This is the initial community string.
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
632 returns the current community string for the given community.
634 All communities defined by a module are automatically released when the module
636 .Ss THE USER-BASED SECURITY GROUP
637 The scalar statistics of the USM group are held in the global variable
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;
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.
654 A global list of configured USM users is maintained by the daemon.
655 .Bd -literal -offset indent
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;
664 SLIST_ENTRY(usm_user) up;
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
671 is set to point at the user entry that matches the credentials contained in
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.
676 adds an user entry in the list, and
678 deletes an existing entry from the list.
680 is used to remove all configured USM users.
682 will return the first user in the list, or
684 if the list is empty.
686 will return the next user of a given entry if one exists, or
688 The list is sorted according to the USM user name and Engine ID.
690 returns the USM user entry matching the given
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.
701 The scalar statistics of the Management Target group are held in the global
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;
710 .Fn bsnmpd_get_target_stats
711 returns a pointer to the global structure containing the statistics.
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];
721 char taglist[SNMP_TAG_SIZ];
722 char paramname[SNMP_ADM_STR32_SIZ];
726 SLIST_ENTRY(target_address) ta;
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];
737 char secname[SNMP_ADM_STR32_SIZ];
738 enum snmp_usm_level sec_level;
741 SLIST_ENTRY(target_param) tp;
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];
753 SLIST_ENTRY(target_notify) tn;
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.
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.
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
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
792 is used to remove all configured data from the three global Management Target
797 contains the OID 0.0.
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.
808 provide a way to acquire globally non-overlapping sub-ranges of the entire
811 A request id range is allocated with
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);
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.
824 returns the lowest request id in the given range.
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.
830 returns the sequentially next id in the range.
834 checks whether the request id
836 is within the range identified by
840 returns the range identifier for the given
842 or 0 if the request id is in none of the ranges.
844 The SNMP daemon supports an arbitrary number of timers with SNMP tick granularity.
847 arranges for the callback
849 to be called with the argument
853 SNMP ticks have expired.
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
863 gives the number of ticks until the first execution of the callback, while
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
870 If a module is unloaded all timers started by the module that have not expired
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).
878 causes the callback function
880 to be called with the file descriptor
882 and the user argument
884 whenever the file descriptor
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,
891 may be called with the value returned from
893 All file descriptors selected by a module are automatically deselected when
894 the module is unloaded.
896 To temporarily suspend the file descriptor registration
899 This also causes the file descriptor to be switched back to
900 blocking mode if it was blocking prior the call to
902 This is necessary to do synchronous input on a selected socket.
908 The system group contains an object resource table.
909 A module may create an entry in this table by calling
913 to be registered, a textual description in
915 and a pointer to the module
917 The registration can be removed with
919 All registrations of a module are automatically removed if the module is
921 .Ss TRANSMIT AND RECEIVE BUFFERS
922 A buffer is allocated via
924 The argument must be 1 for transmit and 0 for receive buffers.
925 The function may return
927 if there is no memory available.
928 The current buffersize can be obtained with
931 For modules that need to do their own PDU processing (for example for proxying)
932 the following functions are available:
936 decodes the PDU, searches the community, and sets the global
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
945 .It Er SNMPD_INPUT_VALBADLEN
946 A SET PDU had a value field in a binding with a wrong length field in an
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
958 For datagram transports this means that part of the
959 datagram was lost and the input should be ignored.
963 .Fn snmp_input_finish
964 does the other half of processing: if
966 did not return OK, tries to construct an error response.
967 If the start was OK, it calls the correct function from
969 to execute the request and depending on the outcome constructs a response or
970 error response PDU or ignores the request PDU.
974 .Er SNMPD_INPUT_FAILED .
975 In the first case a response PDU was constructed and should be sent.
979 takes a PDU and encodes it.
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.
988 sends a trap to all trap destinations.
989 The arguments are the
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
997 should be granted or denied, according to the configured View-Based Access
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.
1006 The following functions are used for OCTET STRING scalars, either NUL terminated
1008 .Bl -tag -width "XXXXXXXXX"
1010 should be called for SNMP_OP_SET.
1014 are the resp\&.\& arguments to the node callback.
1016 is a pointer to the pointer that holds the current value and
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.
1021 the old value in the scratch area (note, that any initial value must have
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.
1031 is used for GET or GETNEXT.
1033 .It Fn string_get_max
1034 can be used instead of
1036 to ensure that the returned string has a certain maximum length.
1039 is -1, the length is computed via
1041 from the current string value.
1042 If the current value is NULL,
1043 a OCTET STRING of zero length is returned.
1045 must be called if either rollback or commit fails to free the saved old value.
1048 The following functions are used to process scalars of type IP-address:
1049 .Bl -tag -width "XXXXXXXXX"
1051 Saves the current value in the scratch area and sets the new value from
1056 Restores the old IP address from the scratch area.
1058 Retrieves the IP current address.
1061 The following functions handle OID-typed variables:
1062 .Bl -tag -width "XXXXXXXXX"
1064 Saves the current value in the scratch area by allocating a
1068 and sets the new value from
1071 Frees the old value in the scratch area.
1073 Restores the old OID from the scratch area and frees the old OID.
1077 .Ss TABLE INDEX HANDLING
1078 The following functions help in handling table indexes:
1079 .Bl -tag -width "XXXXXXXXX"
1081 Decodes the index part of the OID.
1084 must be a pointer to the
1088 argument of the node callback.
1091 argument must be the index of the start of the index in the OID (this is
1094 argument to the node callback).
1096 is the index expression (parameter
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"
1104 expected as argument.
1107 expected as argument.
1108 Note, that this syntax is illegal for indexes.
1114 expected as arguments.
1115 A buffer is allocated to hold the decoded string.
1118 .Vt struct asn_oid *
1119 is expected as argument.
1123 expected as argument that points to a buffer of at least four byte.
1124 .It Li COUNTER, GAUGE, TIMETICKS
1129 No argument expected.
1131 .It Fn index_compare
1132 compares the current variable with an OID.
1136 come from the node callback arguments
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.
1146 must contain only the index part of the table column.
1147 .It Fn index_compare_off
1150 except that it takes an additional parameter
1152 that causes it to ignore the first
1154 components of both indexes.
1158 beginning at position
1162 .It Fn index_append_off
1165 beginning at position
1169 beginning at position
1181 This implementation conforms to the applicable IETF RFCs and ITU-T
1184 .An Hartmut Brandt Aq harti@FreeBSD.org