diff options
Diffstat (limited to 'contrib/bsnmp/snmpd/snmpmod.3')
-rw-r--r-- | contrib/bsnmp/snmpd/snmpmod.3 | 861 |
1 files changed, 861 insertions, 0 deletions
diff --git a/contrib/bsnmp/snmpd/snmpmod.3 b/contrib/bsnmp/snmpd/snmpmod.3 new file mode 100644 index 0000000..143d12d --- /dev/null +++ b/contrib/bsnmp/snmpd/snmpmod.3 @@ -0,0 +1,861 @@ +.\" +.\" Copyright (c) 2001-2003 +.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus). +.\" All rights reserved. +.\" +.\" Author: Harti Brandt <harti@freebsd.org> +.\" +.\" Redistribution of this software and documentation and use in source and +.\" binary forms, with or without modification, are permitted provided that +.\" the following conditions are met: +.\" +.\" 1. Redistributions of source code or documentation must retain the above +.\" copyright notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS +.\" AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +.\" FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +.\" FRAUNHOFER FOKUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +.\" OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.3 2003/01/28 13:44:35 hbb Exp $ +.\" +.Dd August 16, 2002 +.Dt snmpmod 3 +.Os +.Sh NAME +.Nm INSERT_OBJECT_OID_LINK_INDEX , +.Nm INSERT_OBJECT_INT_LINK_INDEX , +.Nm FIND_OBJECT_OID_LINK_INDEX , +.Nm NEXT_OBJECT_OID_LINK_INDEX , +.Nm FIND_OBJECT_INT_LINK_INDEX , +.Nm NEXT_OBJECT_INT_LINK_INDEX , +.Nm INSERT_OBJECT_OID_LINK , +.Nm INSERT_OBJECT_INT_LINK , +.Nm FIND_OBJECT_OID_LINK , +.Nm NEXT_OBJECT_OID_LINK , +.Nm FIND_OBJECT_INT_LINK , +.Nm NEXT_OBJECT_INT_LINK , +.Nm INSERT_OBJECT_OID , +.Nm INSERT_OBJECT_INT , +.Nm FIND_OBJECT_OID , +.Nm FIND_OBJECT_INT , +.Nm NEXT_OBJECT_OID , +.Nm NEXT_OBJECT_INT , +.Nm this_tick , +.Nm start_tick , +.Nm get_ticks , +.Nm systemg , +.Nm comm_define , +.Nm community , +.Nm oid_zeroDotZero , +.Nm reqid_allocate , +.Nm reqid_next , +.Nm reqid_base , +.Nm reqid_istype , +.Nm reqid_type , +.Nm timer_start , +.Nm timer_stop , +.Nm fd_select , +.Nm fd_deselect , +.Nm fd_suspend , +.Nm fd_resume , +.Nm or_register , +.Nm or_unregister , +.Nm buf_alloc , +.Nm buf_size , +.Nm snmp_input_start , +.Nm snmp_input_finish , +.Nm snmp_output , +.Nm snmp_send_port , +.Nm snmp_send_trap , +.Nm string_save , +.Nm string_commit , +.Nm string_rollback , +.Nm string_get , +.Nm string_free , +.Nm ip_save , +.Nm ip_rollback , +.Nm ip_commit , +.Nm ip_get , +.Nm oid_save , +.Nm oid_rollback , +.Nm oid_commit , +.Nm oid_get , +.Nm index_decode , +.Nm index_compare , +.Nm index_compare_off , +.Nm index_append , +.Nm index_append_off +.Nd "SNMP daemon loadable module interface" +.Sh LIBRARY +Begemot SNMP library +.Pq libbsnmp, -lbsnmp +.Sh SYNOPSIS +.In bsnmp/snmpmod.h +.Fn INSERT_OBJECT_OID_LINK_INDEX "PTR" "LIST" "LINK" "INDEX" +.Fn INSERT_OBJECT_INT_LINK_INDEX "PTR" "LIST" "LINK" "INDEX" +.Fn FIND_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX" +.Fn FIND_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX" +.Fn NEXT_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX" +.Fn NEXT_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX" +.Fn INSERT_OBJECT_OID_LINK "PTR" "LIST" "LINK" +.Fn INSERT_OBJECT_INT_LINK "PTR" "LIST" "LINK" +.Fn FIND_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK" +.Fn FIND_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK" +.Fn NEXT_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK" +.Fn NEXT_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK" +.Fn INSERT_OBJECT_OID "PTR" "LIST" +.Fn INSERT_OBJECT_INT "PTR" "LIST" +.Fn FIND_OBJECT_OID "LIST" "OID" "SUB" +.Fn FIND_OBJECT_INT "LIST" "OID" "SUB" +.Fn NEXT_OBJECT_OID "LIST" "OID" "SUB" +.Fn NEXT_OBJECT_INT "LIST" "OID" "SUB" +.Vt extern u_int32_t this_tick ; +.Vt extern u_int32_t start_tick ; +.Ft u_int32_t +.Fn get_ticks "void" +.Vt extern struct systemg systemg ; +.Ft u_int +.Fn comm_define "u_int priv" "const char *descr" "struct lmodule *mod" "const char *str" +.Ft const char * +.Fn comm_string "u_int comm" +.Vt extern u_int community ; +.Vt extern const struct asn_oid oid_zeroDotZero ; +.Ft u_int +.Fn reqid_allocate "int size" "struct lmodule *mod" +.Ft int32_t +.Fn reqid_next "u_int type" +.Ft int32_t +.Fn reqid_base "u_int type" +.Ft int +.Fn reqid_istype "int32_t reqid" "u_int type" +.Ft u_int +.Fn reqid_type "int32_t reqid" +.Ft void * +.Fn timer_start "u_int ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod" +.Ft void +.Fn timer_stop "void *timer_id" +.Ft void * +.Fn fd_select "int fd" "void (*func)(int, void *)" "void *uarg" "struct lmodule *mod" +.Ft void +.Fn fd_deselect "void *fd_id" +.Ft void +.Fn fd_suspend "void *fd_id" +.Ft int +.Fn fd_resume "void *fd_id" +.Ft u_int +.Fn or_register "const struct asn_oid *oid" "const char *descr" "struct lmodule *mod" +.Ft void +.Fn or_unregister "u_int or_id" +.Ft void * +.Fn buf_alloc "int tx" +.Ft size_t +.Fn buf_size "int tx" +.Ft enum snmpd_input_err +.Fn snmp_input_start "const u_char *buf" "size_t len" "const char *source" \ + "struct snmp_pdu *pdu" "int32_t *ip" +.Ft enum snmpd_input_err +.Fn snmp_input_finish "struct snmp_pdu *pdu" "const u_char *rcvbuf" \ + "size_t rcvlen" "u_char *sndbuf" "size_t *sndlen" "const char *source" \ + "enum snmpd_input_err ierr" "int32_t ip" "void *data" +.Ft void +.Fn snmp_output "struct snmp_pdu *pdu" "u_char *sndbuf" "size_t *sndlen" \ + "const char *dest" +.Ft void +.Fn snmp_send_port "const struct asn_oid *port" "struct snmp_pdu *pdu" \ + "const struct sockaddr *addr" "socklen_t addrlen" +.Ft void +.Fn snmp_send_trap "const struct asn_oid *oid" "..." +.Ft int +.Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp" +.Ft void +.Fn string_commit "struct snmp_context *ctx" +.Ft void +.Fn string_rollback "struct snmp_context *ctx" "u_char **strp" +.Ft int +.Fn string_get "struct snmp_value *val" "const u_char *str" "ssize_t len" +.Ft void +.Fn string_free "struct snmp_context *ctx" +.Ft int +.Fn ip_save "struct snmp_value *val" "struct snmp_context *ctx" "u_char *ipa" +.Ft void +.Fn ip_rollback "struct snmp_context *ctx" "u_char *ipa" +.Ft void +.Fn ip_commit "struct snmp_context *ctx" +.Ft int +.Fn ip_get "struct snmp_value *val" "u_char *ipa" +.Ft int +.Fn oid_save "struct snmp_value *val" "struct snmp_context *ctx" "struct asn_oid *oid" +.Ft void +.Fn oid_rollback "struct snmp_context *ctx" "struct asn_oid *oid" +.Ft void +.Fn oid_commit "struct snmp_context *ctx" +.Ft int +.Fn oid_get "struct snmp_value *val" "const struct asn_oid *oid" +.Ft int +.Fn index_decode "const struct asn_oid *oid" "u_int sub" "u_int code" "..." +.Ft int +.Fn index_compare "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2" +.Ft int +.Fn index_compare_off "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2" "u_int off" +.Ft void +.Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" +.Ft void +.Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off" +.Sh DESCRIPTION +The +.Xr snmpd 1 +SNMP daemon implements a minimal MIB which consists of the system group, part +of the SNMP MIB, a private configuration MIB, a trap destination table, a +UDP port table, a community table, a module table, a statistics group and +a debugging group. All other MIBs are support through loadable modules. +This allows +.Xr snmpd 1 +to use for task, that are not the classical SNMP task. +.Ss MODULE LOADING AND UNLOADING +Modules are loaded by writing to the module table. This table is indexed by +a string, that identfies the module to the daemon. This identifier is used +to select the correct configuration section from the configuration files and +to identify resources allocated to this module. A row in the module table is +created by writing a string of non-zero length to the +.Va begemotSnmpdModulePath +column. This string must be the complete path to the file containing the module. +A module can be unloaded by writing a zero length string to the path column +of an existing row. +.Pp +Modules may depend on each other an hence must be loaded in the correct order. +The dependencies are listed in the corresponding manual pages. +.Pp +Upon loading a module the SNMP daemon expects the module file to a export +a global symbol +.Va config . +This symbol should be a variable of type +.Vt struct snmp_module : +.Bd -literal -offset indent +typedef enum snmpd_proxy_err (*proxy_err_f)(struct snmp_pdu *, + const struct asn_oid *, const struct sockaddr *, socklen_t, + enum snmpd_input_err, int32_t); + + +struct snmp_module { + const char *comment; + int (*init)(struct lmodule *, int argc, char *argv[]); + int (*fini)(void); + void (*idle)(void); + void (*dump)(void); + void (*config)(void); + void (*start)(void); + proxy_err_f proxy; + const struct snmp_node *tree; + u_int tree_size; + void (*loading)(const struct lmodule *, int); +}; +.Ed +.Pp +This structure must be statically initialized and its fields have the +following functions: +.Bl -tag -width ".It Va tree_size" +.It Va comment +This is a string that will be visible in the module table. It should give +some hint about the function of this module. +.It Va init +This function is called upon loading the module. The module pointer should +be stored by the module because it is needed in other calls and the +argument vector will contain the arguments to this module from the daemons +command line. This function should return 0 if everything is ok or an +UNIX error code (see +.Xr errno 3 ). +Once the function returns 0, the +.Va fini +function is called when the module is unloaded. +.It Va fini +The module is unloaded. This gives the module a chance to free resources that +are not automatically freed. Be sure to free all memory, because daemons tend +to run very long. This function pointer may be +.Li NULL +if it is not needed. +.It Va idle +If this function pointer is not +.Li NULL , +the function pointed to by it is called whenever the daemon is going +to wait for an event. Try to avoid using this feature. +.It Va dump +Whenever the daemon receives a +.Li SIGUSR1 +it dumps it internal state via +.Xr syslog 3 . +If the +.Va dump +field is not +.Li NULL +it is called by the daemon to dump the state of the module. +.It Va config +Whenever the daemon receives a +.Li SIGHUP +signal it re-reads its configuration file. +If the +.Va config +field is not +.Li NULL +it is called after reading the configuration file to give the module a chance +to adapt to the new configuration. +.It Va start +If not +.Li NULL +this function is called after successful loading and initializing the module +to start its actual operation. +.It Va proxy +If the daemon receives a PDU and that PDU has a community string who's +community was registered by this module and +.Va proxy +is not +.Li NULL +than this function is called to handle the PDU. +.It Va tree +This is a pointer to the node array for the MIB tree implemented by this module. +.It Va tree_size +This is the number of nodes in +.Va tree . +.It Va loading +If this pointer is not +.Li NULL +it is called whenever another module was loaded or unloaded. It gets a +pointer to that module and a flag that is 0 for unloading and 1 for loading. +.El +.Pp +When everything is ok, the daemon merges the module's MIB tree into its current +global tree, calls the modules +.Fn init +function. If this function returns an error, the modules MIB tree is removed from +the global one and the module is unloaded. If initialisation is successful, +the modules +.Fn start +function is called. +After it returns the +.Fn loaded +functions of all modules (including the loaded one) are called. +.Pp +When the module is unloaded, its MIB tree is removed from the global one, +the communities, request id ranges, running timers and selected file +descriptors are released, the +.Fn fini +function is called, the module file is unloaded and the +.Fn loaded +functions of all other modules are called. +.Ss IMPLEMENTING TABLES +There are a number of macros designed to help implementing SNMP tables. +A problem while implementing a table is the support for the GETNEXT operator. +The GETNEXT operation has to find out whether, given an arbitrary OID, the +lessest table row, that has an OID higher than the given OID. The easiest way +to do this is to keep the table as an ordered list of structures each one +of which contains an OID that is the index of the table row. This allows easy +removal, insertion and search. +.Pp +The helper macros assume, that the table is organized as a TAILQ (see +.Xr queue 3 +and each structure contains a +.Vt struct asn_oid +that is used as index. +For simple tables with only a integer or unsigned index, an alternate form +of the macros is available, that presume the existence of an integer or +unsigned field as index field. +.Pp +The macros have name of the form +.Bd -literal -offset indent +{INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]] +.Ed +.Pp +The +.Fn INSERT_* +macros are used in the SET operation to insert a new table row into the table. +The +.Fn FIND_* +macros are used in the GET operation to find a specific row in the table. +The +.Fn NEXT_* +macros are used in the GETNEXT operation to find the next row in the table. +The last two macros return a pointer to the row structure if a row is found, +.Li NULL +otherwise. +The macros +.Fn *_OBJECT_OID_* +assume the existence of a +.Vt struct asn_oid +that is used as index, the macros +.Fn *_OBJECT_INT_* +assume the existance of an unsigned integer field that is used as index. +.Pp +The macros +.Fn *_INDEX +allow the explicit naming of the index field in the parameter +.Fa INDEX , +whereas the other macros assume that this field is named +.Va index . +The macros +.Fn *_LINK_* +allow the explicit naming of the link field of the tail queues, the others +assume that the link field is named +.Va link . +Explicitely naming the link field may be necessary if the same structures +are held in two or more different tables. +.Pp +The arguments to the macros are as follows: +.Bl -tag -width "INDEX" +.It Fa PTR +A pointer to the new structure to be inserted into the table. +.It Fa LIST +A pointer to the tail queue head. +.It Fa LINK +The name of the link field in the row structure. +.It Fa INDEX +The name of the index field in the row structure. +.It Fa OID +Must point to the +.Va var +field of the +.Fa value +argument to the node operation callback. This is the OID to search for. +.It Fa SUB +This is the index of the start of the table index in the OID pointed to +by +.Fa OID . +This is usually the same as the +.Fa sub +argument to the node operation callback. +.El +.Ss DAEMON TIMESTAMPS +The variable +.Va this_tick +contains the tick (there are 100 SNMP ticks in a second) when +the current PDU processing was started. +The variable +.Va start_tick +contains the tick when the daemon was started. +The function +.Fn get_ticks +returns the current tick. The number of ticks since the daemon was started +is +.Bd -literal -offset indent +get_ticks() - start_tick +.Ed +.Ss THE SYSTEM GROUP +The scalar fields of the system group are held in the global variable +.Va systemg : +.Bd -literal -offset indent +struct systemg { + u_char *descr; + struct asn_oid object_id; + u_char *contact; + u_char *name; + u_char *location; + u_int32_t services; + u_int32_t or_last_change; +}; +.Ed +.Ss COMMUNITIES +The SNMP daemon implements a community table. On recipte of a request message +the community string in that message is compared to each of the community +strings in that table, if a match is found, the global variable +.Va community +is set to the community identifier for that community. Community identifiers +are unsigned integers. For the three standard communities there are three +constants defined: +.Bd -literal -offset indent +#define COMM_INITIALIZE 0 +#define COMM_READ 1 +#define COMM_WRITE 2 +.Ed +.Pp +.Va community +is set to +.Li COMM_INITIALIZE +while the assignments in the configuration file are processed. To +.Li COMM_READ +or +.Li COMM_WRITE +when the community strings for the read-write or read-only community are found +in the incoming PDU. +.Pp +Modules can define additional communities. This may be necessary to provide +transport proxying (a PDU received on one communication link is proxied to +another link) or to implement non-UDP access points to SNMP. A new +community is defined with the function +.Fn comm_define . +It takes the following parameters: +.Bl -tag -width ".It Fa descr" +.It Fa priv +This is an integer identifying the community to the module. Each module has +its own namespace with regard to this parameter. The community table is +indexed with the module name and this identifier. +.It Fa descr +This is a string providing a human readable description of the community. +It is visible in the community table. +.It Fa mod +This is the module defining the community. +.It Fa str +This is the initial community string. +.El +.Pp +The function returns a globally unique community identifier. If a PDU is +received who's community string matches, this identifier is set into the global +.Va community . +.Pp +The function +.Fn comm_string +returns the current community string for the given community. +.Pp +All communities defined by a module are automatically released when the module +is unloaded. +.Ss WELL KNOWN OIDS +The global variable +.Va oid_zeroDotZero +contains the OID 0.0. +.Ss REQUEST ID RANGES +For modules that implement SNMP client functions besides SNMP agent functions +it may be necessary to identify SNMP requests by their identifier to allow +easier routing of responses to the correct sub-system. Request id ranges +provide a way to aquire globally non-overlapping sub-ranges of the entire +31-bit id range. +.Pp +A request id range is allocated with +.Fn reqid_allocate . +The arguments are: the size of the range and the module allocating the range. +For example, the call +.Bd -literal -offset indent +id = reqid_allocate(1000, module); +.Ed +.Pp +allocates a range of 1000 request ids. The function returns the request +id range identifier or 0 if there is not enough identifier space. +The function +.Fn reqid_base +returns the lowest request id in the given range. +.Pp +Request id are allocated starting at the lowest one linear throughout the range. +If the client application may have a lot of outstanding request the range +must be large enough so that an id is not reused until it is really expired. +.Fn reqid_next +returns the sequentially next id in the range. +.Pp +The function +.Fn reqid_istype +checks whether the request id +.Fa reqid +is withing the range identified by +.Fa type . +The function +.Fn reqid_type +returns the range identifier for the given +.Fa reqid +or 0 if the request id is in none of the ranges. +.Ss TIMERS +The SNMP daemon supports an arbitrary number of timers with SNMP tick granularity. +The function +.Fn timer_start +arranges for the callback +.Fa func +to be called with the argument +.Fa uarg +after +.Fa ticks +SNMP ticks have expired. +.Fa mod +is the module that starts the timer. Timers are one-shot, they are not +restarted. The function returns a timer identifier that can be used to +stop the timer via +.Fn timer_stop . +If a module is unloaded all timers started by the module that have not expired +yet are stopped. +.Ss FILE DESCRIPTOR SUPPORT +A module may need to get input from socket file descriptors without blocking +the daemon (for example to implement alternative SNMP transports). +.Pp +The function +.Fn fd_select +causes the callback function +.Fa func +to be called with the file descriptor +.Fa fd +and the user argument +.Fa uarg +whenever the file descriptor +.Fa fd +can be red or has a close condition. If the file descriptor is not in +non-blocking mode, it is set to non-blocking mode. If the callback is not +needed anymore, +.Fn fd_deselect +may be called with the value returned from +.Fn fd_select . +All file descriptors selected by a module are automatically deselected when +the module is unloaded. +.Pp +To temporarily suspend the file descriptor registration +.Fn fd_suspend +can be called. This also causes the file descriptor to be switched back to +blocking mode if it was blocking prior the call to +.Fn fd_select . +This is necessary to do synchronuous input on a selected socket. +The effect of +.Fn fd_suspend +can be undone with +.Fn fd_resume . +.Ss OBJECT RESOURCES +The system group contains an object resource table. A module may create +an entry in this table by calling +.Fn or_register +with the +.Fa oid +to be registered, a textual description in +.Fa str +and a pointer to the module +.Fa mod . +The registration can be removed with +.Fn or_unregister . +All registrations of a module are automatically removed if the module is +unloaded. +.Ss TRANSMIT AND RECEIVE BUFFERS +A buffer is allocated via +.Fn buf_alloc . +The argument must be 1 for transmit and 0 for receive buffers. The function +may return +.Li NULL +if there is no memory available. The current buffersize can be obtained with +.Fn buf_size . +.Sh PROCESSING PDUS +For modules that need to do their own PDU processing (for example for proxying) +the following functions are available: +.Pp +Function +.Fn snmp_input_start +decodes the PDU, searches the community, and sets the global +.Va this_tick . +It returns one of the following error codes: +.Bl -tag -width ".It Er SNMPD_INPUT_VALBADLEN" +.It Er SNMPD_INPUT_OK +Everything ok, continue with processing. +.It Er SNMPD_INPUT_FAILED +The PDU could not be decoded, has a wrong version or an unknown +community string. +.It Er SNMPD_INPUT_VALBADLEN +A SET PDU had a value field in a binding with a wrong length field in an +ASN.1 header. +.It Er SNMPD_INPUT_VALRANGE +A SET PDU had a value field in a binding with a value that is out of range +for the given ASN.1 type. +.It Er SNMPD_INPUT_VALBADENC +A SET PDU had a value field in a binding with wrong ASN.1 encoding. +.El +.Pp +The function +.Fn snmp_input_finish +does the other half of processing: if +.Fn snmp_input_start +did not return OK, tries to construct an error response. If the start was OK, +it calls the correct function from +.Xr bsnmpagent +to execute the request and depending on the outcome constructs a response or +error response PDU or ignores the request PDU. It returns either +.Er SNMPD_INPUT_OK +or +.Er SNMPD_INPUT_FAILED . +In the first case a response PDU was constructed and should be sent. +.Pp +The function +.Fn snmp_output +takes a PDU and encodes it. +.Pp +The function +.Fn snmp_send_port +takes a PDU, encodes it and sends it through the given port (identified by +the index in the port table) to the given address. +.Pp +The function +.Fn snmp_send_trap +sends a trap to all trap destinations. The arguments are the +.Fa oid +identifying the trap and a NULL-terminated list of +.Vt struct snmp_value +pointers that are to be inserted into the trap binding list. +.Ss SIMPLE ACTION SUPPORT +For simple scalar variables that need no dependencies a number of support +functions is available to handle the set, commit, rollback and get. +.Pp +The following functions are used for OCTET STRING scalars, either NUL terminated +or not: +.Bl -tag -width "XXXXXXXXX" +.It Fn string_save +should be called for SNMP_OP_SET. +.Fa value +and +.Fa ctx +are the resp\&. arguments to the node callback. +.Fa valp +is a pointer to the pointer that holds the current value and +.Fa req_size +should be -1 if any size of the string is acceptable or a number larger or +equal zero if the string must have a specific size. The function saves +the old value in the scratch area (note, that any initial value must have +been allocated by +.Xr malloc 3 ), +allocates a new string, copies over the new value, NUL-terminates it and +sets the new current value. +.It Fn string_commit +simply frees the saved old value in the scratch area. +.It Fn string_rollback +frees the new value, and puts back the old one. +.It Fn string_get +is used for GET or GETNEXT. If +.Fa len +is -1, the length is computed via +.Xr strlen 3 +from the current string value. If the current value is NULL, +a OCTET STRING of zero length is returned. +.It Fn string_free +must be called if either rollback or commit fails to free the saved old value. +.El +.Pp +The following functions are used to process scalars of type IP-address: +.Bl -tag -width "XXXXXXXXX" +.It Fn ip_save +Saves the current value in the scratch area and sets the new value from +.Fa valp . +.It Fn ip_commit +Does nothing. +.It Fn ip_rollback +Restores the old IP address from the scratch area. +.It Fn ip_get +Retrieves the IP current address. +.El +.Pp +The following functions handle OID-typed variables: +.Bl -tag -width "XXXXXXXXX" +.It Fn oid_save +Saves the current value in the scratch area by allocating a +.Vt struct asn_oid +with +.Xr malloc 3 +and sets the new value from +.Fa oid . +.It Fn oid_commit +Frees the old value in the scratch area. +.It Fn oid_rollback +Restores the old OID from the scratch area and frees the old OID. +.It Fn oid_get +Retrieves the OID +.El +.Ss TABLE INDEX HANDLING +The following functions help in handling table indexes: +.Bl -tag -width "XXXXXXXXX" +.It Fn index_decode +Decodes the index part of the OID. The parameter +.Fa oid +must be a pointer to the +.Va var +field of the +.Fa value +argument of the node callback. The +.Fa sub +argument must be the index of the start of the index in the OID (this is +the +.Fa sub +argument to the node callback). +.Fa code +is the index expression (parameter +.Fa idx +to the node callback). +These parameters are followed by parameters depending on the syntax of the index +elements as follows: +.Bl -tag -width ".It Li OCTET STRING" +.It Li INTEGER +.Vt int32_t * +expected as argument. +.It Li COUNTER64 +.Vt u_int64_t * +expected as argument. Note, that this syntax is illegal for indexes. +.It Li OCTET STRING +A +.Vt u_char ** +and a +.Vt size_t * +expected as arguments. A buffer is allocated to hold the decoded string. +.It Li OID +A +.Vt struct asn_oid * +is expected as argument. +.It Li IP ADDRESS +A +.Vt u_int8_t * +expected as argument that points to a buffer of at least four byte. +.It Li COUNTER, GAUGE, TIMETICKS +A +.Vt u_int32_t +expected. +.It Li NULL +No argument expected. +.El +.It Fn index_compare +compares the current variable with an OID. +.Fa oid1 +and +.Fa sub +come from the node callback arguments +.Fa value->var +and +.Fa sub +resp. +.Fa oid2 +is the OID to compare to. The function returns -1, 0, +1 when the +variable is lesser, equal, higher to the given OID. +.Fa oid2 +must contain only the index part of the table column. +.It Fn index_compare_off +is equivalent to +.Fn index_compare +except that it takes an additional parameter +.Fa off +that causes it to ignore the first +.Fa off +components of both indexes. +.It Fn index_append +appends OID +.Fa src +beginning at position +.Fa sub +to +.Fa dst . +.It Fn index_append_off +appends OID +.Fa src +beginning at position +.Fa off +to +.Fa dst +beginning at position +.Fa sub ++ +.Fa off . +.El +.Sh SEE ALSO +.Xr snmpd 1 , +.Xr gensnmptree 1 , +.Xr bsnmplib 3 +.Xr bsnmpclient 3 , +.Xr bsnmpagent 3 +.Sh STANDARDS +This implementation conforms to the applicable IETF RFCs and ITU-T +recommendations. +.Sh AUTHORS +.An Hartmut Brandt Aq brandt@fokus.gmd.de |