e95204c39d
document details of salen in getnameinfo(3) manual page. getnameinfo(3) returned EAI_FAIL when salen was not equal to the length corresponding to the value specified by sa->sa_family. However, POSIX or RFC 3493 does not require it and RFC 4038 Sec.6.2.3 shows an example passing sizeof(struct sockaddr_storage) to salen. This change makes the requirement less strict by accepting salen up to sizeof(struct sockaddr_storage). It also includes two more changes: one is to fix return values because both SUSv4 and RFC 3493 require EAI_FAMILY when the address length is invalid, another is to fix sa_len dependency in PF_LOCAL. Pointed out by: Christophe Beauval Reviewed by: ae Differential Revision: https://reviews.freebsd.org/D14585
313 lines
7.6 KiB
Groff
313 lines
7.6 KiB
Groff
.\" $KAME: getnameinfo.3,v 1.37 2005/01/05 03:23:05 itojun Exp $
|
|
.\" $OpenBSD: getnameinfo.3,v 1.36 2004/12/21 09:48:20 jmc Exp $
|
|
.\"
|
|
.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
|
|
.\" Copyright (C) 2000, 2001 Internet Software Consortium.
|
|
.\"
|
|
.\" Permission to use, copy, modify, and distribute this software for any
|
|
.\" purpose with or without fee is hereby granted, provided that the above
|
|
.\" copyright notice and this permission notice appear in all copies.
|
|
.\"
|
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
|
.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
.\" PERFORMANCE OF THIS SOFTWARE.
|
|
.\"
|
|
.\" $FreeBSD$
|
|
.\"
|
|
.Dd March 15, 2018
|
|
.Dt GETNAMEINFO 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm getnameinfo
|
|
.Nd socket address structure to hostname and service name
|
|
.Sh SYNOPSIS
|
|
.In sys/types.h
|
|
.In sys/socket.h
|
|
.In netdb.h
|
|
.Ft int
|
|
.Fo getnameinfo
|
|
.Fa "const struct sockaddr *sa" "socklen_t salen" "char *host"
|
|
.Fa "size_t hostlen" "char *serv" "size_t servlen" "int flags"
|
|
.Fc
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Fn getnameinfo
|
|
function is used to convert a
|
|
.Li sockaddr
|
|
structure to a pair of host name and service strings.
|
|
It is a replacement for and provides more flexibility than the
|
|
.Xr gethostbyaddr 3
|
|
and
|
|
.Xr getservbyport 3
|
|
functions and is the converse of the
|
|
.Xr getaddrinfo 3
|
|
function.
|
|
.Pp
|
|
If a link-layer address or UNIX-domain address is passed to
|
|
.Fn getnameinfo ,
|
|
its ASCII representation will be stored in
|
|
.Fa host .
|
|
The string pointed to by
|
|
.Fa serv
|
|
will be set to the empty string if non-NULL;
|
|
.Fa flags
|
|
will always be ignored.
|
|
For a link-layer address,
|
|
this can be used as a replacement of the legacy
|
|
.Xr link_ntoa 3
|
|
function.
|
|
.Pp
|
|
The
|
|
.Li sockaddr
|
|
structure
|
|
.Fa sa
|
|
should point to either a
|
|
.Li sockaddr_in ,
|
|
.Li sockaddr_in6 ,
|
|
.Li sockaddr_dl ,
|
|
or
|
|
.Li sockaddr_un
|
|
structure
|
|
.Po for IPv4 ,
|
|
IPv6,
|
|
link-layer,
|
|
or UNIX-domain respectively
|
|
.Pc
|
|
that is
|
|
.Fa salen
|
|
bytes long.
|
|
If
|
|
.Fa salen
|
|
is shorter than the length corresponding to the specified
|
|
address family or longer than
|
|
.Fn sizeof "struct sockaddr_storage" ,
|
|
it returns
|
|
.Er EAI_FAMILY .
|
|
Note that
|
|
.Va sa->sa_len
|
|
should be consistent with
|
|
.Fa salen
|
|
though the value of
|
|
.Va sa->sa_len
|
|
is not directly used in this function.
|
|
.Pp
|
|
The host and service names associated with
|
|
.Fa sa
|
|
are stored in
|
|
.Fa host
|
|
and
|
|
.Fa serv
|
|
which have length parameters
|
|
.Fa hostlen
|
|
and
|
|
.Fa servlen .
|
|
The maximum value for
|
|
.Fa hostlen
|
|
is
|
|
.Dv NI_MAXHOST
|
|
and
|
|
the maximum value for
|
|
.Fa servlen
|
|
is
|
|
.Dv NI_MAXSERV ,
|
|
as defined by
|
|
.Aq Pa netdb.h .
|
|
If a length parameter is zero, no string will be stored.
|
|
Otherwise, enough space must be provided to store the
|
|
host name or service string plus a byte for the NUL terminator.
|
|
.Pp
|
|
The
|
|
.Fa flags
|
|
argument is formed by
|
|
.Tn OR Ns 'ing
|
|
the following values:
|
|
.Bl -tag -width "NI_NUMERICSCOPEXX"
|
|
.It Dv NI_NOFQDN
|
|
A fully qualified domain name is not required for local hosts.
|
|
The local part of the fully qualified domain name is returned instead.
|
|
.It Dv NI_NUMERICHOST
|
|
Return the address in numeric form, as if calling
|
|
.Xr inet_ntop 3 ,
|
|
instead of a host name.
|
|
.It Dv NI_NAMEREQD
|
|
A name is required.
|
|
If the host name cannot be found in DNS and this flag is set,
|
|
a non-zero error code is returned.
|
|
If the host name is not found and the flag is not set, the
|
|
address is returned in numeric form.
|
|
.It NI_NUMERICSERV
|
|
The service name is returned as a digit string representing the port number.
|
|
.It NI_NUMERICSCOPE
|
|
The scope identifier is returned as a digit string.
|
|
.It NI_DGRAM
|
|
Specifies that the service being looked up is a datagram
|
|
service, and causes
|
|
.Xr getservbyport 3
|
|
to be called with a second argument of
|
|
.Dq udp
|
|
instead of its default of
|
|
.Dq tcp .
|
|
This is required for the few ports (512\-514) that have different services
|
|
for
|
|
.Tn UDP
|
|
and
|
|
.Tn TCP .
|
|
.El
|
|
.Pp
|
|
This implementation allows numeric IPv6 address notation with scope identifier,
|
|
as documented in chapter 11 of RFC 4007.
|
|
IPv6 link-local address will appear as a string like
|
|
.Dq Li fe80::1%ne0 .
|
|
Refer to
|
|
.Xr getaddrinfo 3
|
|
for more information.
|
|
.Sh RETURN VALUES
|
|
.Fn getnameinfo
|
|
returns zero on success or one of the error codes listed in
|
|
.Xr gai_strerror 3
|
|
if an error occurs.
|
|
.Sh EXAMPLES
|
|
The following code tries to get a numeric host name, and service name,
|
|
for a given socket address.
|
|
Observe that there is no hardcoded reference to a particular address family.
|
|
.Bd -literal -offset indent
|
|
struct sockaddr *sa; /* input */
|
|
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
|
|
|
|
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
|
|
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
|
|
errx(1, "could not get numeric hostname");
|
|
/* NOTREACHED */
|
|
}
|
|
printf("host=%s, serv=%s\en", hbuf, sbuf);
|
|
.Ed
|
|
.Pp
|
|
The following version checks if the socket address has a reverse address mapping:
|
|
.Bd -literal -offset indent
|
|
struct sockaddr *sa; /* input */
|
|
char hbuf[NI_MAXHOST];
|
|
|
|
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
|
|
NI_NAMEREQD)) {
|
|
errx(1, "could not resolve hostname");
|
|
/* NOTREACHED */
|
|
}
|
|
printf("host=%s\en", hbuf);
|
|
.Ed
|
|
.Sh SEE ALSO
|
|
.Xr gai_strerror 3 ,
|
|
.Xr getaddrinfo 3 ,
|
|
.Xr gethostbyaddr 3 ,
|
|
.Xr getservbyport 3 ,
|
|
.Xr inet_ntop 3 ,
|
|
.Xr link_ntoa 3 ,
|
|
.Xr resolver 3 ,
|
|
.Xr inet 4 ,
|
|
.Xr inet6 4 ,
|
|
.Xr unix 4 ,
|
|
.Xr hosts 5 ,
|
|
.Xr resolv.conf 5 ,
|
|
.Xr services 5 ,
|
|
.Xr hostname 7 ,
|
|
.Xr named 8
|
|
.Rs
|
|
.%A R. Gilligan
|
|
.%A S. Thomson
|
|
.%A J. Bound
|
|
.%A J. McCann
|
|
.%A W. Stevens
|
|
.%T Basic Socket Interface Extensions for IPv6
|
|
.%R RFC 3493
|
|
.%D February 2003
|
|
.Re
|
|
.Rs
|
|
.%A S. Deering
|
|
.%A B. Haberman
|
|
.%A T. Jinmei
|
|
.%A E. Nordmark
|
|
.%A B. Zill
|
|
.%T "IPv6 Scoped Address Architecture"
|
|
.%R RFC 4007
|
|
.%D March 2005
|
|
.Re
|
|
.Rs
|
|
.%A Craig Metz
|
|
.%T Protocol Independence Using the Sockets API
|
|
.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference"
|
|
.%D June 2000
|
|
.Re
|
|
.Sh STANDARDS
|
|
The
|
|
.Fn getnameinfo
|
|
function is defined by the
|
|
.St -p1003.1-2004
|
|
specification and documented in
|
|
.Tn "RFC 3493" ,
|
|
.Dq Basic Socket Interface Extensions for IPv6 .
|
|
.Sh CAVEATS
|
|
.Fn getnameinfo
|
|
can return both numeric and FQDN forms of the address specified in
|
|
.Fa sa .
|
|
There is no return value that indicates whether the string returned in
|
|
.Fa host
|
|
is a result of binary to numeric-text translation (like
|
|
.Xr inet_ntop 3 ) ,
|
|
or is the result of a DNS reverse lookup.
|
|
Because of this, malicious parties could set up a PTR record as follows:
|
|
.Bd -literal -offset indent
|
|
1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1
|
|
.Ed
|
|
.Pp
|
|
and trick the caller of
|
|
.Fn getnameinfo
|
|
into believing that
|
|
.Fa sa
|
|
is
|
|
.Li 10.1.1.1
|
|
when it is actually
|
|
.Li 127.0.0.1 .
|
|
.Pp
|
|
To prevent such attacks, the use of
|
|
.Dv NI_NAMEREQD
|
|
is recommended when the result of
|
|
.Fn getnameinfo
|
|
is used
|
|
for access control purposes:
|
|
.Bd -literal -offset indent
|
|
struct sockaddr *sa;
|
|
socklen_t salen;
|
|
char addr[NI_MAXHOST];
|
|
struct addrinfo hints, *res;
|
|
int error;
|
|
|
|
error = getnameinfo(sa, salen, addr, sizeof(addr),
|
|
NULL, 0, NI_NAMEREQD);
|
|
if (error == 0) {
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
|
hints.ai_flags = AI_NUMERICHOST;
|
|
if (getaddrinfo(addr, "0", &hints, &res) == 0) {
|
|
/* malicious PTR record */
|
|
freeaddrinfo(res);
|
|
printf("bogus PTR record\en");
|
|
return -1;
|
|
}
|
|
/* addr is FQDN as a result of PTR lookup */
|
|
} else {
|
|
/* addr is numeric string */
|
|
error = getnameinfo(sa, salen, addr, sizeof(addr),
|
|
NULL, 0, NI_NUMERICHOST);
|
|
}
|
|
.Ed
|
|
.\".Pp
|
|
.\".Ox
|
|
.\"intentionally uses a different
|
|
.\".Dv NI_MAXHOST
|
|
.\"value from what
|
|
.\".Tn "RFC 2553"
|
|
.\"suggests, to avoid buffer length handling mistakes.
|