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/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $
39 .Nm snmp_client_init ,
40 .Nm snmp_client_set_host ,
41 .Nm snmp_client_set_port ,
43 .Nm snmp_timeout_cb_f ,
44 .Nm snmp_timeout_start_f ,
45 .Nm snmp_timeout_stop_f ,
49 .Nm snmp_add_binding ,
53 .Nm snmp_parse_server ,
56 .Nm snmp_table_fetch ,
57 .Nm snmp_table_fetch_async ,
59 .Nm snmp_discover_engine
60 .Nd "SNMP client library"
69 .Fn (*snmp_send_cb_f) "struct snmp_pdu *req" "struct snmp_pdu *resp" "void *uarg"
71 .Fn (*snmp_timeout_cb_f) "void *uarg"
73 .Fn (*snmp_timeout_start_f) "struct timeval *timeout" "snmp_timeout_cb_f callback" "void *uarg"
75 .Fn (*snmp_timeout_stop_f) "void *timeout_id"
76 .Vt extern struct snmp_client snmp_client ;
78 .Fn snmp_client_init "struct snmp_client *client"
80 .Fn snmp_client_set_host "struct snmp_client *client" "const char *host"
82 .Fn snmp_client_set_port "struct snmp_client *client" "const char *port"
84 .Fn snmp_open "const char *host" "const char *port" "const char *read_community" "const char *write_community"
88 .Fn snmp_pdu_create "struct snmp_pdu *pdu" "u_int op"
90 .Fn snmp_add_binding "struct snmp_pdu *pdu" "..."
92 .Fn snmp_pdu_check "const struct snmp_pdu *req" "const struct snmp_pdu *resp"
94 .Fn snmp_pdu_send "struct snmp_pdu *pdu" "snmp_send_cb_f func" "void *uarg"
96 .Fn snmp_oid_append "struct asn_oid *oid" "const char *fmt" "..."
98 .Fn snmp_parse_server "struct snmp_client *sc" "const char *str"
100 .Fn snmp_receive "int blocking"
102 .Fn (*snmp_table_cb_f) "void *list" "void *arg" "int res"
104 .Fn snmp_table_fetch "const struct snmp_table *descr" "void *list"
106 .Fn snmp_table_fetch_async "const struct snmp_table *descr" "void *list" "snmp_table_cb_f callback" "void *uarg"
108 .Fn snmp_dialog "struct snmp_pdu *req" "struct snmp_pdu *resp"
110 .Fn snmp_discover_engine "void"
112 The SNMP library contains routines to easily build SNMP client applications
113 that use SNMP versions 1, 2 or 3.
114 Most of the routines use a
115 .Vt struct snmp_client :
116 .Bd -literal -offset indent
118 enum snmp_version version;
119 int trans; /* which transport to use */
121 /* these two are read-only for the application */
122 char *cport; /* port number as string */
123 char *chost; /* host name or IP address as string */
125 char read_community[SNMP_COMMUNITY_MAXLEN + 1];
126 char write_community[SNMP_COMMUNITY_MAXLEN + 1];
128 /* SNMPv3 specific fields */
130 int32_t security_model;
131 struct snmp_engine engine;
132 struct snmp_user user;
134 /* SNMPv3 Access control - VACM*/
136 uint8_t cengine[SNMP_ENGINE_ID_SIZ];
137 char cname[SNMP_CONTEXT_NAME_SIZ];
139 struct timeval timeout;
153 char error[SNMP_STRERROR_LEN];
155 snmp_timeout_start_f timeout_start;
156 snmp_timeout_stop_f timeout_stop;
158 char local_path[sizeof(SNMP_LOCAL_PATH)];
162 The fields of this structure are described below.
163 .Bl -tag -width "timeout_start"
165 This is the version of SNMP to use.
168 for applicable values.
169 The default version is
173 .Dv SNMP_TRANS_LOC_DGRAM
174 a local datagram socket is used.
176 .Dv SNMP_TRANS_LOC_STREAM
177 a local stream socket is used.
180 a UDP socket is created.
183 field as the path to the server's socket for local sockets.
185 The SNMP agent's UDP port number.
186 This may be a symbolic port number (from
188 or a numeric port number.
191 (the default) the standard SNMP port is used.
192 This field should not be changed directly but rather by calling
193 .Fn snmp_client_set_port .
195 The SNMP agent's host name, IP address or
197 domain socket path name.
203 This field should not be changed directly but rather through calling
204 .Fn snmp_client_set_host .
205 .It Va read_community
206 This is the community name to be used for all requests except SET requests.
209 .It Va write_community
210 The community name to be used for SET requests.
214 The message identifier value to be used with SNMPv3 PDUs. Incremented with
215 each transmitted PDU.
216 .It Va security_model
217 The security model to be used with SNMPv3 PDUs. Currently only User-Based
218 Security model specified by RFC 3414 (value 3) is supported.
220 The authoritive SNMP engine parameters to be used with SNMPv3 PDUs.
222 The USM SNMP user credentials to be used with SNMPv3 PDUs.
224 The length of the context engine id to be used with SNMPv3 PDUs.
226 The context engine id to be used with SNMPv3 PDUs. Default is empty.
228 The context name to be used with SNMPv3 PDUs. Default is
231 The maximum time to wait for responses to requests.
232 If the time elapses, the request is resent up to
235 The default is 3 seconds.
237 Number of times a request PDU is to be resent.
238 If set to 0, the request is sent only once.
239 The default is 3 retransmissions.
241 If set to a non-zero value all received and sent PDUs are dumped via
242 .Xr snmp_pdu_dump 3 .
243 The default is not to dump PDUs.
245 The encoding buffer size to be allocated for transmitted PDUs.
246 The default is 10000 octets.
248 The decoding buffer size to be allocated for received PDUs.
249 This is the size of the maximum PDU that can be received.
250 The default is 10000 octets.
254 this is the file socket file descriptor used for sending and receiving PDUs.
256 The request id of the next PDU to send.
257 Used internal by the library.
259 The maximum request id to use for outgoing PDUs.
263 The minimum request id to use for outgoing PDUs.
264 Request ids are allocated linearily starting at
269 If an error happens, this field is set to a printable string describing the
272 This field must point to a function setting up a one shot timeout.
273 After the timeout has elapsed, the given callback function must be called
274 with the user argument.
277 function must return a
279 identifying the timeout.
281 This field must be set to a function that stops a running timeout.
282 The function will be called with the return value of the corresponding
286 If in local socket mode, the name of the clients socket.
287 Not needed by the application.
290 In the current implementation there is a global variable
292 .D1 Vt extern struct snmp_client snmp_client ;
294 that is used by all the library functions.
295 The first call into the library must be a call to
297 to initialize this global variable to the default values.
298 After this call and before calling
300 the fields of the variable may be modified by the user.
301 The modification of the
305 fields should be done only via the functions
306 .Fn snmp_client_set_host
308 .Fn snmp_client_set_port .
314 domain socket and connects it to the agent's IP address and port.
315 If any of the arguments of the call is not
317 the corresponding field in the global
319 is set from the argument.
320 Otherwise the values that are already in that variable are used.
323 closes the socket, stops all timeouts and frees all dynamically allocated
326 The next three functions are used to create request PDUs.
329 initializes a PDU of type
331 It does not allocate space for the PDU itself.
332 This is the responsibility of the caller.
334 adds bindings to the PDU and returns the (zero based) index of the first new
336 The arguments are pairs of pointer to the OIDs and syntax constants,
337 terminated by a NULL.
339 .Bd -literal -offset indent
340 snmp_add_binding(&pdu,
341 &oid1, SNMP_SYNTAX_INTEGER,
342 &oid2, SNMP_SYNTAX_OCTETSTRING,
346 adds two new bindings to the PDU and returns the index of the first one.
347 It is the responsibility of the caller to set the value part of the binding
349 The functions returns -1 if the maximum number of bindings is exhausted.
352 can be used to construct variable OIDs for requests.
353 It takes a pointer to an
355 that is to be constructed, a format string, and a number of arguments
356 the type of which depends on the format string.
357 The format string is interpreted
358 character by character in the following way:
359 .Bl -tag -width ".It Li ( Va N Ns Li )"
361 This format expects an argument of type
363 and appends this as a single integer to the OID.
365 This format expects an argument of type
367 and appends to four parts of the IP address to the OID.
369 This format expects an argument of type
371 and appends the length of the string (as computed by
373 and each of the characters in the string to the OID.
375 This format expects no argument.
377 must be a decimal number and is stored into an internal variable
380 This format expects an argument of type
384 characters from the string to the OID.
385 The string may contain
389 This format expects two arguments: one of type
393 The first argument gives the number of bytes to append to the OID from the string
394 pointed to by the second argument.
399 may be used to check a response PDU.
400 A number of checks are performed
401 (error code, equal number of bindings, syntaxes and values for SET PDUs).
402 The function returns +1 if everything is ok, 0 if a NOSUCHNAME or similar
403 error was detected, -1 if the response PDU had fatal errors
408 (a timeout occurred).
412 encodes and sends the given PDU.
413 It records the PDU together with the callback
414 and user pointers in an internal list and arranges for retransmission if no
415 response is received.
416 When a response is received or the retransmission count
417 is exceeded the callback
419 is called with the original request PDU, the response PDU and the user argument
421 If the retransmit count is exceeded,
423 is called with the original request PDU, the response pointer set to
425 and the user argument
427 The caller should not free the request PDU until the callback function is
429 The callback function must free the request PDU and the response PDU (if not
434 tries to receive a PDU.
435 If the argument is zero, the function polls to see
436 whether a packet is available, if the argument is non-zero, the function blocks
437 until the next packet is received.
438 The packet is delivered via the usual callback
439 mechanism (non-response packets are silently dropped).
440 The function returns 0, if a packet was received and successfully dispatched,
441 -1 if an error occurred or no packet was available (in polling mode).
443 The next two functions are used to retrieve tables from SNMP agents.
445 the following input structure, that describes the table:
446 .Bd -literal -offset indent
448 struct asn_oid table;
449 struct asn_oid last_change;
455 struct snmp_table_entry {
457 enum snmp_syntax syntax;
463 The fields of this structure have the following meaning:
464 .Bl -tag -width "last_change"
466 This is the base OID of the table.
468 Some tables have a scalar variable of type TIMETICKS attached to them,
469 that holds the time when the table was last changed.
470 This OID should be the OID of this variable (without the \&.0 index).
471 When the table is retrieved
472 with multiple GET requests, and the variable changes between two request,
473 the table fetch is restarted.
475 Maximum number of tries to fetch the table.
477 The table fetching routines return a list of structures one for each table
479 This variable is the size of one structure and used to
483 This is the number of index columns in the table.
485 This is a bit mask with a 1 for each table column that is required.
486 Bit 0 corresponds to the first element (index 0) in the array
488 bit 1 to the second (index 1) and so on.
489 SNMP tables may be sparse.
490 For sparse columns the bit should not be set.
491 If the bit for a given column is set and
492 the column value cannot be retrieved for a given row, the table fetch is
493 restarted assuming that the table is currently being modified by the agent.
494 The bits for the index columns are ignored.
496 This is a variable sized array of column descriptors.
497 This array is terminated by an element with syntax
498 .Li SNMP_SYNTAX_NULL .
501 elements describe all the index columns of the table, the rest are normal
506 .Ql req_mask & (1 << N)
507 yields true, the column is considered a required column.
508 The fields of this the array elements have the following meaning:
509 .Bl -tag -width "syntax"
511 This is the OID subid of the column.
512 This is ignored for index entries.
513 Index entries are decoded according to the
517 This is the syntax of the column or index.
520 terminates the array.
522 This is the starting offset of the value of the column in the return structures.
523 This field can be set with the ISO-C
529 Both table fetching functions return TAILQ (see
531 of structures--one for each table row.
532 These structures must start with a
536 and are allocated via
540 argument of the table functions must point to a
544 fields, usually called
546 is used to indicate which of the columns have been found for the given
548 It is encoded like the
554 synchronously fetches the given table.
555 If everything is ok 0 is returned.
556 Otherwise the function returns -1 and sets an appropriate error string.
558 .Fn snmp_table_fetch_async
559 fetches the tables asynchronously.
560 If either the entire table is fetch, or
561 an error occurs the callback function
563 is called with the callers arguments
567 and a parameter that is either 0 if the table was fetched, or
568 -1 if there was an error.
569 The function itself returns -1 if it could not
570 initialize fetching of the table.
572 The following table description is used to fetch the ATM interface table:
573 .Bd -literal -offset indent
575 * ATM interface table
578 TAILQ_ENTRY(atmif) link;
594 TAILQ_HEAD(atmif_list, atmif);
596 /* list of all ATM interfaces */
597 struct atmif_list atmif_list;
599 static const struct snmp_table atmif_table = {
600 OIDX_begemotAtmIfTable,
601 OIDX_begemotAtmIfTableLastChange, 2,
602 sizeof(struct atmif),
605 { 0, SNMP_SYNTAX_INTEGER,
606 offsetof(struct atmif, index) },
607 { 1, SNMP_SYNTAX_OCTETSTRING,
608 offsetof(struct atmif, ifname) },
609 { 2, SNMP_SYNTAX_GAUGE,
610 offsetof(struct atmif, node_id) },
611 { 3, SNMP_SYNTAX_GAUGE,
612 offsetof(struct atmif, pcr) },
613 { 4, SNMP_SYNTAX_INTEGER,
614 offsetof(struct atmif, media) },
615 { 5, SNMP_SYNTAX_GAUGE,
616 offsetof(struct atmif, vpi_bits) },
617 { 6, SNMP_SYNTAX_GAUGE,
618 offsetof(struct atmif, vci_bits) },
619 { 7, SNMP_SYNTAX_GAUGE,
620 offsetof(struct atmif, max_vpcs) },
621 { 8, SNMP_SYNTAX_GAUGE,
622 offsetof(struct atmif, max_vccs) },
623 { 9, SNMP_SYNTAX_OCTETSTRING,
624 offsetof(struct atmif, esi) },
625 { 10, SNMP_SYNTAX_INTEGER,
626 offsetof(struct atmif, carrier) },
627 { 0, SNMP_SYNTAX_NULL, 0 }
632 if (snmp_table_fetch(&atmif_table, &atmif_list) != 0)
633 errx(1, "AtmIf table: %s", snmp_client.error);
639 is used to execute a synchonuous dialog with the agent.
642 is sent and the function blocks until the response PDU is received.
644 that asynchonuous receives are handled (i.e. callback functions of other send
645 calls or table fetches may be called while in the function).
646 The response PDU is returned in
648 If no response could be received after all timeouts and retries, the function
650 If a response was received 0 is returned.
653 .Fn snmp_discover_engine
654 is used to discover the authoritative snmpEngineId of a remote SNMPv3 agent.
655 A request PDU with empty USM user name is sent and the client's engine
656 parameters are set according to the snmpEngine parameters received in the
658 If the client is configured to use authentication and/or privacy and the
659 snmpEngineBoots and/or snmpEngineTime in the response had zero values, an
660 additional request (possibly encrypted) with the appropriate user credentials
661 is sent to fetch the missing values.
662 Note, that the function blocks until the discovery process is completed.
663 If no response could be received after all timeouts and retries, or the
664 response contained errors the function returns -1.
665 If the discovery process was completed 0 is returned.
668 .Fn snmp_parse_server
669 is used to parse an SNMP server specification string and fill in the
671 .Vt struct snmp_client .
672 The syntax of a server specification is
674 .D1 [trans::][community@][server][:port]
678 is the transport name (one of udp, stream or dgram),
680 is the string to be used for both the read and the write community,
682 is the server's host name in case of UDP and the path name in case
683 of a local socket, and
685 is the port in case of UDP transport.
686 The function returns 0 in the case of success and return -1 and sets
687 the error string in case of an error.
689 If an error occurs in any of the function an error indication as described
691 Additionally the function sets a printable error string
702 This implementation conforms to the applicable IETF RFCs and ITU-T
705 .An Hartmut Brandt Aq harti@FreeBSD.org
706 .An Kendy Kutzner Aq kutzner@fokus.gmd.de