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