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