1.\" 2.\" Copyright (c) 2004-2005 3.\" Hartmut Brandt. 4.\" All rights reserved. 5.\" Copyright (c) 2001-2003 6.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus). 7.\" All rights reserved. 8.\" 9.\" Author: Harti Brandt <harti@FreeBSD.org> 10.\" 11.\" Redistribution and use in source and binary forms, with or without 12.\" modification, are permitted provided that the following conditions 13.\" are met: 14.\" 1. Redistributions of source code must retain the above copyright 15.\" notice, this list of conditions and the following disclaimer. 16.\" 2. Redistributions in binary form must reproduce the above copyright 17.\" notice, this list of conditions and the following disclaimer in the 18.\" documentation and/or other materials provided with the distribution. 19.\" 20.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" SUCH DAMAGE. 31.\" 32.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $ 33.\" 34.Dd September 9, 2010 35.Dt BSNMPCLIENT 3 36.Os 37.Sh NAME 38.Nm snmp_client , 39.Nm snmp_send_cb_f , 40.Nm snmp_timeout_cb_f , 41.Nm snmp_timeout_start_f , 42.Nm snmp_timeout_stop_f , 43.Nm snmp_open , 44.Nm snmp_close , 45.Nm snmp_pdu_create , 46.Nm snmp_add_binding , 47.Nm snmp_pdu_check , 48.Nm snmp_pdu_send , 49.Nm snmp_oid_append , 50.Nm snmp_parse_server , 51.Nm snmp_receive , 52.Nm snmp_table_cb_f , 53.Nm snmp_table_fetch , 54.Nm snmp_table_fetch_async , 55.Nm snmp_dialog , 56.Nm snmp_discover_engine 57.Nd "SNMP client library" 58.Sh LIBRARY 59Begemot SNMP library 60.Pq libbsnmp, -lbsnmp 61.Sh SYNOPSIS 62.In asn1.h 63.In snmp.h 64.In snmpclient.h 65.Ft typedef void 66.Fn (*snmp_send_cb_f) "struct snmp_pdu *req" "struct snmp_pdu *resp" "void *uarg" 67.Ft typedef void 68.Fn (*snmp_timeout_cb_f) "void *uarg" 69.Ft typedef void * 70.Fn (*snmp_timeout_start_f) "struct timeval *timeout" "snmp_timeout_cb_f callback" "void *uarg" 71.Ft typedef void 72.Fn (*snmp_timeout_stop_f) "void *timeout_id" 73.Vt extern struct snmp_client snmp_client ; 74.Ft void 75.Fn snmp_client_init "struct snmp_client *client" 76.Ft int 77.Fn snmp_client_set_host "struct snmp_client *client" "const char *host" 78.Ft int 79.Fn snmp_client_set_port "struct snmp_client *client" "const char *port" 80.Ft int 81.Fn snmp_open "const char *host" "const char *port" "const char *read_community" "const char *write_community" 82.Ft void 83.Fn snmp_close "void" 84.Ft void 85.Fn snmp_pdu_create "struct snmp_pdu *pdu" "u_int op" 86.Ft int 87.Fn snmp_add_binding "struct snmp_pdu *pdu" "..." 88.Ft int 89.Fn snmp_pdu_check "const struct snmp_pdu *req" "const struct snmp_pdu *resp" 90.Ft int32_t 91.Fn snmp_pdu_send "struct snmp_pdu *pdu" "snmp_send_cb_f func" "void *uarg" 92.Ft int 93.Fn snmp_oid_append "struct asn_oid *oid" "const char *fmt" "..." 94.Ft int 95.Fn snmp_parse_server "struct snmp_client *sc" "const char *str" 96.Ft int 97.Fn snmp_receive "int blocking" 98.Ft typedef void 99.Fn (*snmp_table_cb_f) "void *list" "void *arg" "int res" 100.Ft int 101.Fn snmp_table_fetch "const struct snmp_table *descr" "void *list" 102.Ft int 103.Fn snmp_table_fetch_async "const struct snmp_table *descr" "void *list" "snmp_table_cb_f callback" "void *uarg" 104.Ft int 105.Fn snmp_dialog "struct snmp_pdu *req" "struct snmp_pdu *resp" 106.Ft int 107.Fn snmp_discover_engine "void" 108.Sh DESCRIPTION 109The SNMP library contains routines to easily build SNMP client applications 110that use SNMP versions 1, 2 or 3. 111Most of the routines use a 112.Vt struct snmp_client : 113.Bd -literal -offset indent 114struct snmp_client { 115 enum snmp_version version; 116 int trans; /* which transport to use */ 117 118 /* these two are read-only for the application */ 119 char *cport; /* port number as string */ 120 char *chost; /* host name or IP address as string */ 121 122 char read_community[SNMP_COMMUNITY_MAXLEN + 1]; 123 char write_community[SNMP_COMMUNITY_MAXLEN + 1]; 124 125 /* SNMPv3 specific fields */ 126 int32_t identifier; 127 int32_t security_model; 128 struct snmp_engine engine; 129 struct snmp_user user; 130 131 /* SNMPv3 Access control - VACM*/ 132 uint32_t clen; 133 uint8_t cengine[SNMP_ENGINE_ID_SIZ]; 134 char cname[SNMP_CONTEXT_NAME_SIZ]; 135 136 struct timeval timeout; 137 u_int retries; 138 139 int dump_pdus; 140 141 size_t txbuflen; 142 size_t rxbuflen; 143 144 int fd; 145 146 int32_t next_reqid; 147 int32_t max_reqid; 148 int32_t min_reqid; 149 150 char error[SNMP_STRERROR_LEN]; 151 152 snmp_timeout_start_f timeout_start; 153 snmp_timeout_stop_f timeout_stop; 154 155 char local_path[sizeof(SNMP_LOCAL_PATH)]; 156}; 157.Ed 158.Pp 159The fields of this structure are described below. 160.Bl -tag -width "timeout_start" 161.It Va version 162This is the version of SNMP to use. 163See 164.Xr bsnmplib 3 165for applicable values. 166The default version is 167.Li SNMP_V2c . 168.It Va trans 169If this is 170.Dv SNMP_TRANS_LOC_DGRAM 171a local datagram socket is used. 172If it is 173.Dv SNMP_TRANS_LOC_STREAM 174a local stream socket is used. 175For 176.Dv SNMP_TRANS_UDP 177a UDP socket is created. 178It uses the 179.Va chost 180field as the path to the server's socket for local sockets. 181.It Va cport 182The SNMP agent's UDP port number. 183This may be a symbolic port number (from 184.Pa /etc/services ) 185or a numeric port number. 186If this field is 187.Li NULL 188(the default) the standard SNMP port is used. 189This field should not be changed directly but rather by calling 190.Fn snmp_client_set_port . 191.It Va chost 192The SNMP agent's host name, IP address or 193.Ux 194domain socket path name. 195If this is 196.Li NULL 197(the default) 198.Li localhost 199is assumed. 200This field should not be changed directly but rather through calling 201.Fn snmp_client_set_host . 202.It Va read_community 203This is the community name to be used for all requests except SET requests. 204The default is 205.Sq public . 206.It Va write_community 207The community name to be used for SET requests. 208The default is 209.Sq private . 210.It Va identifier 211The message indentifier value to be used with SNMPv3 PDUs. Incremented with 212each transmitted PDU. 213.It Va security_model 214The security model to be used with SNMPv3 PDUs. Currently only User-Based 215Security model specified by RFC 3414 (value 3) is supported. 216.It Va engine 217The authorative SNMP engine parameters to be used with SNMPv3 PDUs. 218.It Va user 219The USM SNMP user credentials to be used with SNMPv3 PDUs. 220.It Va clen 221The length of the context engine id to be used with SNMPv3 PDUs. 222.It Va cengine 223The context engine id to be used with SNMPv3 PDUs. Default is empty. 224.It Va cname 225The context name to be used with SNMPv3 PDUs. Default is 226.Sq "" . 227.It Va timeout 228The maximum time to wait for responses to requests. 229If the time elapses, the request is resent up to 230.Va retries 231times. 232The default is 3 seconds. 233.It Va retries 234Number of times a request PDU is to be resent. 235If set to 0, the request is sent only once. 236The default is 3 retransmissions. 237.It Va dump_pdus 238If set to a non-zero value all received and sent PDUs are dumped via 239.Xr snmp_pdu_dump 3 . 240The default is not to dump PDUs. 241.It Va txbuflen 242The encoding buffer size to be allocated for transmitted PDUs. 243The default is 10000 octets. 244.It Va rxbuflen 245The decoding buffer size to be allocated for received PDUs. 246This is the size of the maximum PDU that can be received. 247The default is 10000 octets. 248.It Va fd 249After calling 250.Fn snmp_open 251this is the file socket file descriptor used for sending and receiving PDUs. 252.It Va next_reqid 253The request id of the next PDU to send. 254Used internal by the library. 255.It Va max_reqid 256The maximum request id to use for outgoing PDUs. 257The default is 258.Li INT32_MAX . 259.It Va min_reqid 260The minimum request id to use for outgoing PDUs. 261Request ids are allocated linearily starting at 262.Va min_reqid 263up to 264.Va max_reqid . 265.It Va error 266If an error happens, this field is set to a printable string describing the 267error. 268.It Va timeout_start 269This field must point to a function setting up a one shot timeout. 270After the timeout has elapsed, the given callback function must be called 271with the user argument. 272The 273.Fn timeout_start 274function must return a 275.Vt void * 276identifying the timeout. 277.It Va timeout_stop 278This field must be set to a function that stops a running timeout. 279The function will be called with the return value of the corresponding 280.Fn timeout_start 281function. 282.It Va local_path 283If in local socket mode, the name of the clients socket. 284Not needed by the application. 285.El 286.Pp 287In the current implementation there is a global variable 288.Pp 289.D1 Vt extern struct snmp_client snmp_client ; 290.Pp 291that is used by all the library functions. 292The first call into the library must be a call to 293.Fn snmp_client_init 294to initialize this global variable to the default values. 295After this call and before calling 296.Fn snmp_open 297the fields of the variable may be modified by the user. 298The modification of the 299.Va chost 300and 301.Va cport 302fields should be done only via the functions 303.Fn snmp_client_set_host 304and 305.Fn snmp_client_set_port . 306.Pp 307The function 308.Fn snmp_open 309creates a UDP or 310.Ux 311domain socket and connects it to the agent's IP address and port. 312If any of the arguments of the call is not 313.Li NULL 314the corresponding field in the global 315.Va snmp_client 316is set from the argument. 317Otherwise the values that are already in that variable are used. 318The function 319.Fn snmp_close 320closes the socket, stops all timeouts and frees all dynamically allocated 321resources. 322.Pp 323The next three functions are used to create request PDUs. 324The function 325.Fn snmp_pdu_create 326initializes a PDU of type 327.Va op . 328It does not allocate space for the PDU itself. 329This is the responsibility of the caller. 330.Fn snmp_add_binding 331adds bindings to the PDU and returns the (zero based) index of the first new 332binding. 333The arguments are pairs of pointer to the OIDs and syntax constants, 334terminated by a NULL. 335The call 336.Bd -literal -offset indent 337snmp_add_binding(&pdu, 338 &oid1, SNMP_SYNTAX_INTEGER, 339 &oid2, SNMP_SYNTAX_OCTETSTRING, 340 NULL); 341.Ed 342.Pp 343adds two new bindings to the PDU and returns the index of the first one. 344It is the responsibility of the caller to set the value part of the binding 345if necessary. 346The functions returns -1 if the maximum number of bindings is exhausted. 347The function 348.Fn snmp_oid_append 349can be used to construct variable OIDs for requests. 350It takes a pointer to an 351.Vt struct asn_oid 352that is to be constructed, a format string, and a number of arguments 353the type of which depends on the format string. 354The format string is interpreted 355character by character in the following way: 356.Bl -tag -width ".It Li ( Va N Ns Li )" 357.It Li i 358This format expects an argument of type 359.Vt asn_subid_t 360and appends this as a single integer to the OID. 361.It Li a 362This format expects an argument of type 363.Vt struct in_addr 364and appends to four parts of the IP address to the OID. 365.It Li s 366This format expects an argument of type 367.Vt const char * 368and appends the length of the string (as computed by 369.Xr strlen 3 ) 370and each of the characters in the string to the OID. 371.It ( Va N Ns ) 372This format expects no argument. 373.Va N 374must be a decimal number and is stored into an internal variable 375.Va size . 376.It Li b 377This format expects an argument of type 378.Vt const char * 379and appends 380.Va size 381characters from the string to the OID. 382The string may contain 383.Li NUL 384characters. 385.It Li c 386This format expects two arguments: one of type 387.Vt size_t 388and one of type 389.Vt const u_char * . 390The first argument gives the number of bytes to append to the OID from the string 391pointed to by the second argument. 392.El 393.Pp 394The function 395.Fn snmp_pdu_check 396may be used to check a response PDU. 397A number of checks are performed 398(error code, equal number of bindings, syntaxes and values for SET PDUs). 399The function returns +1 if everything is ok, 0 if a NOSUCHNAME or similar 400error was detected, -1 if the response PDU had fatal errors 401and -2 if 402.Fa resp 403is 404.Li NULL 405(a timeout occurred). 406.Pp 407The function 408.Fn snmp_pdu_send 409encodes and sends the given PDU. 410It records the PDU together with the callback 411and user pointers in an internal list and arranges for retransmission if no 412response is received. 413When a response is received or the retransmission count 414is exceeded the callback 415.Fa func 416is called with the orignal request PDU, the response PDU and the user argument 417.Fa uarg . 418If the retransmit count is exceeded, 419.Fa func 420is called with the original request PDU, the response pointer set to 421.Li NULL 422and the user argument 423.Fa uarg . 424The caller should not free the request PDU until the callback function is 425called. 426The callback function must free the request PDU and the response PDU (if not 427.Li NULL ). 428.Pp 429The function 430.Fn snmp_receive 431tries to receive a PDU. 432If the argument is zero, the function polls to see 433whether a packet is available, if the argument is non-zero, the function blocks 434until the next packet is received. 435The packet is delivered via the usual callback 436mechanism (non-response packets are silently dropped). 437The function returns 0, if a packet was received and successfully dispatched, 438-1 if an error occurred or no packet was available (in polling mode). 439.Pp 440The next two functions are used to retrieve tables from SNMP agents. 441They use 442the following input structure, that describes the table: 443.Bd -literal -offset indent 444struct snmp_table { 445 struct asn_oid table; 446 struct asn_oid last_change; 447 u_int max_iter; 448 size_t entry_size; 449 u_int index_size; 450 uint64_t req_mask; 451 452 struct snmp_table_entry { 453 asn_subid_t subid; 454 enum snmp_syntax syntax; 455 off_t offset; 456 } entries[]; 457}; 458.Ed 459.Pp 460The fields of this structure have the following meaning: 461.Bl -tag -width "last_change" 462.It Va table 463This is the base OID of the table. 464.It Va last_change 465Some tables have a scalar variable of type TIMETICKS attached to them, 466that holds the time when the table was last changed. 467This OID should be the OID of this variable (without the \&.0 index). 468When the table is retrieved 469with multiple GET requests, and the variable changes between two request, 470the table fetch is restarted. 471.It Va max_iter 472Maximum number of tries to fetch the table. 473.It Va entry_size 474The table fetching routines return a list of structures one for each table 475row. 476This variable is the size of one structure and used to 477.Xr malloc 3 478the structure. 479.It Va index_size 480This is the number of index columns in the table. 481.It Va req_mask 482This is a bit mask with a 1 for each table column that is required. 483Bit 0 corresponds to the first element (index 0) in the array 484.Va entries , 485bit 1 to the second (index 1) and so on. 486SNMP tables may be sparse. 487For sparse columns the bit should not be set. 488If the bit for a given column is set and 489the column value cannot be retrieved for a given row, the table fetch is 490restarted assuming that the table is currently being modified by the agent. 491The bits for the index columns are ignored. 492.It Va entries 493This is a variable sized array of column descriptors. 494This array is terminated by an element with syntax 495.Li SNMP_SYNTAX_NULL . 496The first 497.Va index_size 498elements describe all the index columns of the table, the rest are normal 499columns. 500If for the column at 501.Ql entries[N] 502the expression 503.Ql req_mask & (1 << N) 504yields true, the column is considered a required column. 505The fields of this the array elements have the following meaning: 506.Bl -tag -width "syntax" 507.It Va subid 508This is the OID subid of the column. 509This is ignored for index entries. 510Index entries are decoded according to the 511.Va syntax 512field. 513.It Va syntax 514This is the syntax of the column or index. 515A syntax of 516.Li SNMP_SYNTAX_NULL 517terminates the array. 518.It Va offset 519This is the starting offset of the value of the column in the return structures. 520This field can be set with the ISO-C 521.Fn offsetof 522macro. 523.El 524.El 525.Pp 526Both table fetching functions return TAILQ (see 527.Xr queue 3 ) 528of structures--one for each table row. 529These structures must start with a 530.Fn TAILQ_ENTRY 531and a 532.Vt uint64_t 533and are allocated via 534.Xr malloc 3 . 535The 536.Fa list 537argument of the table functions must point to a 538.Fn TAILQ_HEAD . 539The 540.Vt uint64_t 541fields, usually called 542.Va found 543is used to indicate which of the columns have been found for the given 544row. 545It is encoded like the 546.Fa req_mask 547field. 548.Pp 549The function 550.Fn snmp_table_fetch 551synchronously fetches the given table. 552If everything is ok 0 is returned. 553Otherwise the function returns -1 and sets an appropriate error string. 554The function 555.Fn snmp_table_fetch_async 556fetches the tables asynchronously. 557If either the entire table is fetch, or 558an error occurs the callback function 559.Fa callback 560is called with the callers arguments 561.Fa list 562and 563.Fa uarg 564and a parameter that is either 0 if the table was fetched, or 565-1 if there was an error. 566The function itself returns -1 if it could not 567initialize fetching of the table. 568.Pp 569The following table description is used to fetch the ATM interface table: 570.Bd -literal -offset indent 571/* 572 * ATM interface table 573 */ 574struct atmif { 575 TAILQ_ENTRY(atmif) link; 576 uint64_t found; 577 int32_t index; 578 u_char *ifname; 579 size_t ifnamelen; 580 uint32_t node_id; 581 uint32_t pcr; 582 int32_t media; 583 uint32_t vpi_bits; 584 uint32_t vci_bits; 585 uint32_t max_vpcs; 586 uint32_t max_vccs; 587 u_char *esi; 588 size_t esilen; 589 int32_t carrier; 590}; 591TAILQ_HEAD(atmif_list, atmif); 592 593/* list of all ATM interfaces */ 594struct atmif_list atmif_list; 595 596static const struct snmp_table atmif_table = { 597 OIDX_begemotAtmIfTable, 598 OIDX_begemotAtmIfTableLastChange, 2, 599 sizeof(struct atmif), 600 1, 0x7ffULL, 601 { 602 { 0, SNMP_SYNTAX_INTEGER, 603 offsetof(struct atmif, index) }, 604 { 1, SNMP_SYNTAX_OCTETSTRING, 605 offsetof(struct atmif, ifname) }, 606 { 2, SNMP_SYNTAX_GAUGE, 607 offsetof(struct atmif, node_id) }, 608 { 3, SNMP_SYNTAX_GAUGE, 609 offsetof(struct atmif, pcr) }, 610 { 4, SNMP_SYNTAX_INTEGER, 611 offsetof(struct atmif, media) }, 612 { 5, SNMP_SYNTAX_GAUGE, 613 offsetof(struct atmif, vpi_bits) }, 614 { 6, SNMP_SYNTAX_GAUGE, 615 offsetof(struct atmif, vci_bits) }, 616 { 7, SNMP_SYNTAX_GAUGE, 617 offsetof(struct atmif, max_vpcs) }, 618 { 8, SNMP_SYNTAX_GAUGE, 619 offsetof(struct atmif, max_vccs) }, 620 { 9, SNMP_SYNTAX_OCTETSTRING, 621 offsetof(struct atmif, esi) }, 622 { 10, SNMP_SYNTAX_INTEGER, 623 offsetof(struct atmif, carrier) }, 624 { 0, SNMP_SYNTAX_NULL, 0 } 625 } 626}; 627 628\&... 629 if (snmp_table_fetch(&atmif_table, &atmif_list) != 0) 630 errx(1, "AtmIf table: %s", snmp_client.error); 631\&... 632.Ed 633.Pp 634The function 635.Fn snmp_dialog 636is used to execute a synchonuous dialog with the agent. 637The request PDU 638.Fa req 639is sent and the function blocks until the response PDU is received. 640Note, 641that asynchonuous receives are handled (i.e. callback functions of other send 642calls or table fetches may be called while in the function). 643The response PDU is returned in 644.Fa resp . 645If no response could be received after all timeouts and retries, the function 646returns -1. 647If a response was received 0 is returned. 648.Pp 649The function 650.Fn snmp_discover_engine 651is used to discover the authorative snmpEngineId of a remote SNMPv3 agent. 652A request PDU with empty USM user name is sent and the client's engine 653parameters are set according to the snmpEngine parameters received in the 654response PDU. 655If the client is configured to use authentication and/or privacy and the 656snmpEngineBoots and/or snmpEngineTime in the response had zero values, an 657additional request (possibly encrypted) with the appropriate user credentials 658is sent to fetch the missing values. 659Note, that the function blocks until the discovery proccess is completed. 660If no response could be received after all timeouts and retries, or the 661response contained errors the function returns -1. 662If the discovery proccess was completed 0 is returned. 663.Pp 664The function 665.Fn snmp_parse_server 666is used to parse an SNMP server specification string and fill in the 667fields of a 668.Vt struct snmp_client . 669The syntax of a server specification is 670.Pp 671.D1 [trans::][community@][server][:port] 672.Pp 673where 674.Va trans 675is the transport name (one of udp, stream or dgram), 676.Va community 677is the string to be used for both the read and the write community, 678.Va server 679is the server's host name in case of UDP and the path name in case 680of a local socket, and 681.Va port 682is the port in case of UDP transport. 683The function returns 0 in the case of success and return -1 and sets 684the error string in case of an error. 685.Sh DIAGNOSTICS 686If an error occurs in any of the function an error indication as described 687above is returned. 688Additionally the function sets a printable error string 689in the 690.Va error 691filed of 692.Va snmp_client . 693.Sh SEE ALSO 694.Xr gensnmptree 1 , 695.Xr bsnmpd 1 , 696.Xr bsnmpagent 3 , 697.Xr bsnmplib 3 698.Sh STANDARDS 699This implementation conforms to the applicable IETF RFCs and ITU-T 700recommendations. 701.Sh AUTHORS 702.An Hartmut Brandt Aq harti@FreeBSD.org 703.An Kendy Kutzner Aq kutzner@fokus.gmd.de 704