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 $
40 .Nm snmp_timeout_cb_f ,
41 .Nm snmp_timeout_start_f ,
42 .Nm snmp_timeout_stop_f ,
46 .Nm snmp_add_binding ,
50 .Nm snmp_parse_server ,
53 .Nm snmp_table_fetch ,
54 .Nm snmp_table_fetch_async ,
56 .Nd "SNMP client library"
65 .Fn (*snmp_send_cb_f) "struct snmp_pdu *req" "struct snmp_pdu *resp" "void *uarg"
67 .Fn (*snmp_timeout_cb_f) "void *uarg"
69 .Fn (*snmp_timeout_start_f) "struct timeval *timeout" "snmp_timeout_cb_f callback" "void *uarg"
71 .Fn (*snmp_timeout_stop_f) "void *timeout_id"
72 .Vt extern struct snmp_client snmp_client ;
74 .Fn snmp_client_init "struct snmp_client *client"
76 .Fn snmp_client_set_host "struct snmp_client *client" "const char *host"
78 .Fn snmp_client_set_port "struct snmp_client *client" "const char *port"
80 .Fn snmp_open "const char *host" "const char *port" "const char *read_community" "const char *write_community"
84 .Fn snmp_pdu_create "struct snmp_pdu *pdu" "u_int op"
86 .Fn snmp_add_binding "struct snmp_pdu *pdu" "..."
88 .Fn snmp_pdu_check "const struct snmp_pdu *req" "const struct snmp_pdu *resp"
90 .Fn snmp_pdu_send "struct snmp_pdu *pdu" "snmp_send_cb_f func" "void *uarg"
92 .Fn snmp_oid_append "struct asn_oid *oid" "const char *fmt" "..."
94 .Fn snmp_parse_server "struct snmp_client *sc" "const char *str"
96 .Fn snmp_receive "int blocking"
98 .Fn (*snmp_table_cb_f) "void *list" "void *arg" "int res"
100 .Fn snmp_table_fetch "const struct snmp_table *descr" "void *list"
102 .Fn snmp_table_fetch_async "const struct snmp_table *descr" "void *list" "snmp_table_cb_f callback" "void *uarg"
104 .Fn snmp_dialog "struct snmp_pdu *req" "struct snmp_pdu *resp"
106 The SNMP library contains routines to easily build SNMP client applications
107 that use SNMP versions 1 or 2.
108 Most of the routines use a
109 .Vt struct snmp_client :
110 .Bd -literal -offset indent
112 enum snmp_version version;
113 int trans; /* transport type to use */
115 /* these two are read-only for the application */
116 char *cport; /* port number as string */
117 char *chost; /* host name or IP address as string */
119 char read_community[SNMP_COMMUNITY_MAXLEN + 1];
120 char write_community[SNMP_COMMUNITY_MAXLEN + 1];
122 struct timeval timeout;
136 char error[SNMP_STRERROR_LEN];
138 snmp_timeout_start_f timeout_start;
139 snmp_timeout_stop_f timeout_stop;
142 char local_path[sizeof(SNMP_LOCAL_PATH)];
146 The fields of this structure are described below.
147 .Bl -tag -width "timeout_start"
149 This is the version of SNMP to use.
152 for applicable values.
153 The default version is
157 .Dv SNMP_TRANS_LOC_DGRAM
158 a local datagram socket is used.
160 .Dv SNMP_TRANS_LOC_STREAM
161 a local stream socket is used.
164 a UDP socket is created.
167 field as the path to the server's socket for local sockets.
169 The SNMP agent's UDP port number.
170 This may be a symbolic port number (from
172 or a numeric port number.
175 (the default) the standard SNMP port is used.
176 This field should not be changed directly but rather by calling
177 .Fn snmp_client_set_port .
179 The SNMP agent's host name, IP address or
181 domain socket path name.
187 This field should not be changed directly but rather through calling
188 .Fn snmp_client_set_host .
189 .It Va read_community
190 This is the community name to be used for all requests except SET requests.
193 .It Va write_community
194 The community name to be used for SET requests.
198 The maximum time to wait for responses to requests.
199 If the time elapses, the request is resent up to
202 The default is 3 seconds.
204 Number of times a request PDU is to be resent.
205 If set to 0, the request is sent only once.
206 The default is 3 retransmissions.
208 If set to a non-zero value all received and sent PDUs are dumped via
209 .Xr snmp_pdu_dump 3 .
210 The default is not to dump PDUs.
212 The encoding buffer size to be allocated for transmitted PDUs.
213 The default is 10000 octets.
215 The decoding buffer size to be allocated for received PDUs.
216 This is the size of the maximum PDU that can be received.
217 The default is 10000 octets.
221 this is the file socket file descriptor used for sending and receiving PDUs.
223 The request id of the next PDU to send.
224 Used internal by the library.
226 The maximum request id to use for outgoing PDUs.
230 The minimum request id to use for outgoing PDUs.
231 Request ids are allocated linearily starting at
236 If an error happens, this field is set to a printable string describing the
239 This field must point to a function setting up a one shot timeout.
240 After the timeout has elapsed, the given callback function must be called
241 with the user argument.
244 function must return a
246 identifying the timeout.
248 This field must be set to a function that stops a running timeout.
249 The function will be called with the return value of the corresponding
253 If in local socket mode, the name of the clients socket.
254 Not needed by the application.
257 In the current implementation there is a global variable
259 .D1 Vt extern struct snmp_client snmp_client ;
261 that is used by all the library functions.
262 The first call into the library must be a call to
264 to initialize this global variable to the default values.
265 After this call and before calling
267 the fields of the variable may be modified by the user.
268 The modification of the
272 fields should be done only via the functions
273 .Fn snmp_client_set_host
275 .Fn snmp_client_set_port .
281 domain socket and connects it to the agent's IP address and port.
282 If any of the arguments of the call is not
284 the corresponding field in the global
286 is set from the argument.
287 Otherwise the values that are already in that variable are used.
290 closes the socket, stops all timeouts and frees all dynamically allocated
293 The next three functions are used to create request PDUs.
296 initializes a PDU of type
298 It does not allocate space for the PDU itself.
299 This is the responsibility of the caller.
301 adds bindings to the PDU and returns the (zero based) index of the first new
303 The arguments are pairs of pointer to the OIDs and syntax constants,
304 terminated by a NULL.
306 .Bd -literal -offset indent
307 snmp_add_binding(&pdu,
308 &oid1, SNMP_SYNTAX_INTEGER,
309 &oid2, SNMP_SYNTAX_OCTETSTRING,
313 adds two new bindings to the PDU and returns the index of the first one.
314 It is the responsibility of the caller to set the value part of the binding
316 The functions returns -1 if the maximum number of bindings is exhausted.
319 can be used to construct variable OIDs for requests.
320 It takes a pointer to an
322 that is to be constructed, a format string, and a number of arguments
323 the type of which depends on the format string.
324 The format string is interpreted
325 character by character in the following way:
326 .Bl -tag -width ".It Li ( Va N Ns Li )"
328 This format expects an argument of type
330 and appends this as a single integer to the OID.
332 This format expects an argument of type
334 and appends to four parts of the IP address to the OID.
336 This format expects an argument of type
338 and appends the length of the string (as computed by
340 and each of the characters in the string to the OID.
341 .It Li ( Va N Ns Li )
342 This format expects no argument.
344 must be a decimal number and is stored into an internal variable
347 This format expects an argument of type
351 characters from the string to the OID.
352 The string may contain
356 This format expects two arguments: one of type
360 The first argument gives the number of bytes to append to the OID from the string
361 pointed to by the second argument.
366 may be used to check a response PDU.
367 A number of checks are performed
368 (error code, equal number of bindings, syntaxes and values for SET PDUs).
369 The function returns +1 if everything is ok, 0 if a NOSUCHNAME or similar
370 error was detected, -1 if the response PDU had fatal errors
375 (a timeout occurred).
379 encodes and sends the given PDU.
380 It records the PDU together with the callback
381 and user pointers in an internal list and arranges for retransmission if no
382 response is received.
383 When a response is received or the retransmission count
384 is exceeded the callback
386 is called with the orignal request PDU, the response PDU and the user argument
388 If the retransmit count is exceeded,
390 is called with the original request PDU, the response pointer set to
392 and the user argument
394 The caller should not free the request PDU until the callback function is
396 The callback function must free the request PDU and the response PDU (if not
401 tries to receive a PDU.
402 If the argument is zero, the function polls to see
403 whether a packet is available, if the argument is non-zero, the function blocks
404 until the next packet is received.
405 The packet is delivered via the usual callback
406 mechanism (non-response packets are silently dropped).
407 The function returns 0, if a packet was received and successfully dispatched,
408 -1 if an error occurred or no packet was available (in polling mode).
410 The next two functions are used to retrieve tables from SNMP agents.
412 the following input structure, that describes the table:
413 .Bd -literal -offset indent
415 struct asn_oid table;
416 struct asn_oid last_change;
422 struct snmp_table_entry {
424 enum snmp_syntax syntax;
430 The fields of this structure have the following meaning:
431 .Bl -tag -width "last_change"
433 This is the base OID of the table.
435 Some tables have a scalar variable of type TIMETICKS attached to them,
436 that holds the time when the table was last changed.
437 This OID should be the OID of this variable (without the \&.0 index).
438 When the table is retrieved
439 with multiple GET requests, and the variable changes between two request,
440 the table fetch is restarted.
442 Maximum number of tries to fetch the table.
444 The table fetching routines return a list of structures one for each table
446 This variable is the size of one structure and used to
450 This is the number of index columns in the table.
452 This is a bit mask with a 1 for each table column that is required.
453 Bit 0 corresponds to the first element (index 0) in the array
455 bit 1 to the second (index 1) and so on.
456 SNMP tables may be sparse.
457 For sparse columns the bit should not be set.
458 If the bit for a given column is set and
459 the column value cannot be retrieved for a given row, the table fetch is
460 restarted assuming that the table is currently being modified by the agent.
461 The bits for the index columns are ignored.
463 This is a variable sized array of column descriptors.
464 This array is terminated by an element with syntax
465 .Li SNMP_SYNTAX_NULL .
468 elements describe all the index columns of the table, the rest are normal
473 .Ql req_mask & (1 << N)
474 yields true, the column is considered a required column.
475 The fields of this the array elements have the following meaning:
476 .Bl -tag -width "syntax"
478 This is the OID subid of the column.
479 This is ignored for index entries.
480 Index entries are decoded according to the
484 This is the syntax of the column or index.
487 terminates the array.
489 This is the starting offset of the value of the column in the return structures.
490 This field can be set with the ISO-C
496 Both table fetching functions return TAILQ (see
498 of structures--one for each table row.
499 These structures must start with a
503 and are allocated via
507 argument of the table functions must point to a
511 fields, usually called
513 is used to indicate which of the columns have been found for the given
515 It is encoded like the
521 synchronously fetches the given table.
522 If everything is ok 0 is returned.
523 Otherwise the function returns -1 and sets an appropriate error string.
525 .Fn snmp_table_fetch_async
526 fetches the tables asynchronously.
527 If either the entire table is fetch, or
528 an error occurs the callback function
530 is called with the callers arguments
534 and a parameter that is either 0 if the table was fetched, or
535 -1 if there was an error.
536 The function itself returns -1 if it could not
537 initialize fetching of the table.
539 The following table description is used to fetch the ATM interface table:
540 .Bd -literal -offset indent
542 * ATM interface table
545 TAILQ_ENTRY(atmif) link;
561 TAILQ_HEAD(atmif_list, atmif);
563 /* list of all ATM interfaces */
564 struct atmif_list atmif_list;
566 static const struct snmp_table atmif_table = {
567 OIDX_begemotAtmIfTable,
568 OIDX_begemotAtmIfTableLastChange, 2,
569 sizeof(struct atmif),
572 { 0, SNMP_SYNTAX_INTEGER,
573 offsetof(struct atmif, index) },
574 { 1, SNMP_SYNTAX_OCTETSTRING,
575 offsetof(struct atmif, ifname) },
576 { 2, SNMP_SYNTAX_GAUGE,
577 offsetof(struct atmif, node_id) },
578 { 3, SNMP_SYNTAX_GAUGE,
579 offsetof(struct atmif, pcr) },
580 { 4, SNMP_SYNTAX_INTEGER,
581 offsetof(struct atmif, media) },
582 { 5, SNMP_SYNTAX_GAUGE,
583 offsetof(struct atmif, vpi_bits) },
584 { 6, SNMP_SYNTAX_GAUGE,
585 offsetof(struct atmif, vci_bits) },
586 { 7, SNMP_SYNTAX_GAUGE,
587 offsetof(struct atmif, max_vpcs) },
588 { 8, SNMP_SYNTAX_GAUGE,
589 offsetof(struct atmif, max_vccs) },
590 { 9, SNMP_SYNTAX_OCTETSTRING,
591 offsetof(struct atmif, esi) },
592 { 10, SNMP_SYNTAX_INTEGER,
593 offsetof(struct atmif, carrier) },
594 { 0, SNMP_SYNTAX_NULL, 0 }
599 if (snmp_table_fetch(&atmif_table, &atmif_list) != 0)
600 errx(1, "AtmIf table: %s", snmp_client.error);
606 is used to execute a synchonuous dialog with the agent.
609 is sent and the function blocks until the response PDU is received.
611 that asynchonuous receives are handled (i.e. callback functions of other send
612 calls or table fetches may be called while in the function).
613 The response PDU is returned in
615 If no response could be received after all timeouts and retries, the function
617 If a response was received 0 is returned.
620 .Fn snmp_parse_server
621 is used to parse an SNMP server specification string and fill in the
623 .Vt struct snmp_client .
624 The syntax of a server specification is
626 .D1 [trans::][community@][server][:port]
630 is the transport name (one of udp, stream or dgram),
632 is the string to be used for both the read and the write community,
634 is the server's host name in case of UDP and the path name in case
635 of a local socket, and
637 is the port in case of UDP transport.
638 The function returns 0 in the case of success and return -1 and sets
639 the error string in case of an error.
641 If an error occurs in any of the function an error indication as described
643 Additionally the function sets a printable error string
654 This implementation conforms to the applicable IETF RFCs and ITU-T
657 .An Hartmut Brandt Aq harti@freebsd.org
658 .An Kendy Kutzner Aq kutzner@fokus.gmd.de