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