xref: /freebsd/lib/libc/net/getnameinfo.3 (revision 1da7f3f6f72b2245e458fc7195733268ae4a1136)
1.\"	$KAME: getnameinfo.3,v 1.37 2005/01/05 03:23:05 itojun Exp $
2.\"	$OpenBSD: getnameinfo.3,v 1.36 2004/12/21 09:48:20 jmc Exp $
3.\"
4.\" Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
5.\" Copyright (C) 2000, 2001  Internet Software Consortium.
6.\"
7.\" Permission to use, copy, modify, and distribute this software for any
8.\" purpose with or without fee is hereby granted, provided that the above
9.\" copyright notice and this permission notice appear in all copies.
10.\"
11.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13.\" AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17.\" PERFORMANCE OF THIS SOFTWARE.
18.\"
19.Dd June 27, 2022
20.Dt GETNAMEINFO 3
21.Os
22.Sh NAME
23.Nm getnameinfo
24.Nd socket address structure to hostname and service name
25.Sh SYNOPSIS
26.In sys/types.h
27.In sys/socket.h
28.In netdb.h
29.Ft int
30.Fo getnameinfo
31.Fa "const struct sockaddr *sa" "socklen_t salen" "char *host"
32.Fa "size_t hostlen" "char *serv" "size_t servlen" "int flags"
33.Fc
34.Sh DESCRIPTION
35The
36.Fn getnameinfo
37function is used to convert a
38.Li sockaddr
39structure to a pair of host name and service strings.
40It is a replacement for and provides more flexibility than the
41.Xr gethostbyaddr 3
42and
43.Xr getservbyport 3
44functions and is the converse of the
45.Xr getaddrinfo 3
46function.
47.Pp
48If a link-layer address or UNIX-domain address is passed to
49.Fn getnameinfo ,
50its ASCII representation will be stored in
51.Fa host .
52The string pointed to by
53.Fa serv
54will be set to the empty string if non-NULL;
55.Fa flags
56will always be ignored.
57For a link-layer address,
58this can be used as a replacement of the legacy
59.Xr link_ntoa 3
60function.
61.Pp
62The
63.Li sockaddr
64structure
65.Fa sa
66should point to either a
67.Li sockaddr_in ,
68.Li sockaddr_in6 ,
69.Li sockaddr_dl ,
70or
71.Li sockaddr_un
72structure
73.Po for IPv4 ,
74IPv6,
75link-layer,
76or UNIX-domain respectively
77.Pc
78that is
79.Fa salen
80bytes long.
81If
82.Fa salen
83is shorter than the length corresponding to the specified
84address family or longer than
85.Fn sizeof "struct sockaddr_storage" ,
86it returns
87.Er EAI_FAMILY .
88Note that
89.Va sa->sa_len
90should be consistent with
91.Fa salen
92though the value of
93.Va sa->sa_len
94is not directly used in this function.
95.Pp
96The host and service names associated with
97.Fa sa
98are stored in
99.Fa host
100and
101.Fa serv
102which have length parameters
103.Fa hostlen
104and
105.Fa servlen .
106The maximum value for
107.Fa hostlen
108is
109.Dv NI_MAXHOST
110and
111the maximum value for
112.Fa servlen
113is
114.Dv NI_MAXSERV ,
115as defined by
116.Aq Pa netdb.h .
117If a length parameter is zero, no string will be stored.
118Otherwise, enough space must be provided to store the
119host name or service string plus a byte for the NUL terminator.
120.Pp
121The
122.Fa flags
123argument is formed by
124.Tn OR Ns 'ing
125the following values:
126.Bl -tag -width "NI_NUMERICSCOPEXX"
127.It Dv NI_NOFQDN
128A fully qualified domain name is not required for local hosts.
129The local part of the fully qualified domain name is returned instead.
130.It Dv NI_NUMERICHOST
131Return the address in numeric form, as if calling
132.Xr inet_ntop 3 ,
133instead of a host name.
134.It Dv NI_NAMEREQD
135A name is required.
136If the host name cannot be found in DNS and this flag is set,
137a non-zero error code is returned.
138If the host name is not found and the flag is not set, the
139address is returned in numeric form.
140.It NI_NUMERICSERV
141The service name is returned as a digit string representing the port number.
142.It NI_NUMERICSCOPE
143The scope identifier is returned as a digit string.
144.It NI_DGRAM
145Specifies that the service being looked up is a datagram
146service, and causes
147.Xr getservbyport 3
148to be called with a second argument of
149.Dq udp
150instead of its default of
151.Dq tcp .
152This is required for the few ports (512\-514) that have different services
153for
154.Tn UDP
155and
156.Tn TCP .
157.El
158.Pp
159This implementation allows numeric IPv6 address notation with scope identifier,
160as documented in chapter 11 of RFC 4007.
161IPv6 link-local address will appear as a string like
162.Dq Li fe80::1%ne0 .
163Refer to
164.Xr getaddrinfo 3
165for more information.
166.Sh RETURN VALUES
167.Fn getnameinfo
168returns zero on success or one of the error codes listed in
169.Xr gai_strerror 3
170if an error occurs.
171.Sh EXAMPLES
172The following code tries to get a numeric host name, and service name,
173for a given socket address.
174Observe that there is no hardcoded reference to a particular address family.
175.Bd -literal -offset indent
176struct sockaddr *sa;	/* input */
177char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
178
179if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
180    sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
181	errx(1, "could not get numeric hostname");
182	/* NOTREACHED */
183}
184printf("host=%s, serv=%s\en", hbuf, sbuf);
185.Ed
186.Pp
187The following version checks if the socket address has a reverse address mapping:
188.Bd -literal -offset indent
189struct sockaddr *sa;	/* input */
190char hbuf[NI_MAXHOST];
191
192if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
193    NI_NAMEREQD)) {
194	errx(1, "could not resolve hostname");
195	/* NOTREACHED */
196}
197printf("host=%s\en", hbuf);
198.Ed
199.Sh SEE ALSO
200.Xr gai_strerror 3 ,
201.Xr getaddrinfo 3 ,
202.Xr gethostbyaddr 3 ,
203.Xr getservbyport 3 ,
204.Xr inet_ntop 3 ,
205.Xr link_ntoa 3 ,
206.Xr resolver 3 ,
207.Xr inet 4 ,
208.Xr inet6 4 ,
209.Xr unix 4 ,
210.Xr hosts 5 ,
211.Xr resolv.conf 5 ,
212.Xr services 5 ,
213.Xr hostname 7
214.Rs
215.%A R. Gilligan
216.%A S. Thomson
217.%A J. Bound
218.%A J. McCann
219.%A W. Stevens
220.%T Basic Socket Interface Extensions for IPv6
221.%R RFC 3493
222.%D February 2003
223.Re
224.Rs
225.%A S. Deering
226.%A B. Haberman
227.%A T. Jinmei
228.%A E. Nordmark
229.%A B. Zill
230.%T "IPv6 Scoped Address Architecture"
231.%R RFC 4007
232.%D March 2005
233.Re
234.Rs
235.%A Craig Metz
236.%T Protocol Independence Using the Sockets API
237.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
238.%D June 2000
239.Re
240.Sh STANDARDS
241The
242.Fn getnameinfo
243function is defined by the
244.St -p1003.1-2004
245specification and documented in
246.Tn "RFC 3493" ,
247.Dq Basic Socket Interface Extensions for IPv6 .
248.Sh CAVEATS
249.Fn getnameinfo
250can return both numeric and FQDN forms of the address specified in
251.Fa sa .
252There is no return value that indicates whether the string returned in
253.Fa host
254is a result of binary to numeric-text translation (like
255.Xr inet_ntop 3 ) ,
256or is the result of a DNS reverse lookup.
257Because of this, malicious parties could set up a PTR record as follows:
258.Bd -literal -offset indent
2591.0.0.127.in-addr.arpa. IN PTR  10.1.1.1
260.Ed
261.Pp
262and trick the caller of
263.Fn getnameinfo
264into believing that
265.Fa sa
266is
267.Li 10.1.1.1
268when it is actually
269.Li 127.0.0.1 .
270.Pp
271To prevent such attacks, the use of
272.Dv NI_NAMEREQD
273is recommended when the result of
274.Fn getnameinfo
275is used
276for access control purposes:
277.Bd -literal -offset indent
278struct sockaddr *sa;
279socklen_t salen;
280char addr[NI_MAXHOST];
281struct addrinfo hints, *res;
282int error;
283
284error = getnameinfo(sa, salen, addr, sizeof(addr),
285    NULL, 0, NI_NAMEREQD);
286if (error == 0) {
287	memset(&hints, 0, sizeof(hints));
288	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
289	hints.ai_flags = AI_NUMERICHOST;
290	if (getaddrinfo(addr, "0", &hints, &res) == 0) {
291		/* malicious PTR record */
292		freeaddrinfo(res);
293		printf("bogus PTR record\en");
294		return -1;
295	}
296	/* addr is FQDN as a result of PTR lookup */
297} else {
298	/* addr is numeric string */
299	error = getnameinfo(sa, salen, addr, sizeof(addr),
300	    NULL, 0, NI_NUMERICHOST);
301}
302.Ed
303.\".Pp
304.\".Ox
305.\"intentionally uses a different
306.\".Dv NI_MAXHOST
307.\"value from what
308.\".Tn "RFC 2553"
309.\"suggests, to avoid buffer length handling mistakes.
310