xref: /freebsd/contrib/bsnmp/lib/bsnmpclient.3 (revision 02e9120893770924227138ba49df1edb3896112a)
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