Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150006714
D3634.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D3634.diff
View Options
Index: head/lib/libc/net/getaddrinfo.3
===================================================================
--- head/lib/libc/net/getaddrinfo.3
+++ head/lib/libc/net/getaddrinfo.3
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 14, 2013
+.Dd September 20, 2015
.Dt GETADDRINFO 3
.Os
.Sh NAME
@@ -40,7 +40,6 @@
The
.Fn getaddrinfo
function is used to get a list of
-.Tn IP
addresses and port numbers for host
.Fa hostname
and service
@@ -59,7 +58,9 @@
An acceptable value for
.Fa hostname
is either a valid host name or a numeric host address string consisting
-of a dotted decimal IPv4 address or an IPv6 address.
+of a dotted decimal IPv4 address,
+an IPv6 address,
+or a UNIX-domain address.
The
.Fa servname
is either a decimal port number or a service name listed in
@@ -105,6 +106,7 @@
Denotes the type of socket that is wanted:
.Dv SOCK_STREAM ,
.Dv SOCK_DGRAM ,
+.Dv SOCK_SEQPACKET ,
or
.Dv SOCK_RAW .
When
@@ -112,9 +114,11 @@
is zero the caller will accept any socket type.
.It Fa ai_protocol
Indicates which transport protocol is desired,
-.Dv IPPROTO_UDP
+.Dv IPPROTO_UDP ,
+.Dv IPPROTO_TCP ,
+.Dv IPPROTO_SCTP ,
or
-.Dv IPPROTO_TCP .
+.Dv IPPROTO_UDPLITE .
If
.Fa ai_protocol
is zero the caller will accept any protocol.
@@ -131,6 +135,9 @@
.Dv AI_NUMERICSERV
and
.Dv AI_PASSIVE .
+For a UNIX-domain address,
+.Fa ai_flags
+is ignored.
.Bl -tag -width "AI_CANONNAMEXX"
.It Dv AI_ADDRCONFIG
If the
@@ -419,6 +426,9 @@
.Xr getnameinfo 3 ,
.Xr getservbyname 3 ,
.Xr resolver 3 ,
+.Xr inet 4 ,
+.Xr inet6 4 ,
+.Xr unix 4 ,
.Xr hosts 5 ,
.Xr resolv.conf 5 ,
.Xr services 5 ,
Index: head/lib/libc/net/getaddrinfo.c
===================================================================
--- head/lib/libc/net/getaddrinfo.c
+++ head/lib/libc/net/getaddrinfo.c
@@ -137,13 +137,20 @@
offsetof(struct sockaddr_in6, sin6_addr),
in6_addrany, in6_loopback, 1},
#define N_INET 1
+#define N_LOCAL 2
#else
#define N_INET 0
+#define N_LOCAL 1
#endif
{PF_INET, sizeof(struct in_addr),
sizeof(struct sockaddr_in),
offsetof(struct sockaddr_in, sin_addr),
in_addrany, in_loopback, 0},
+#define sizeofmember(type, member) (sizeof(((type *)0)->member))
+ {PF_LOCAL, sizeofmember(struct sockaddr_un, sun_path),
+ sizeof(struct sockaddr_un),
+ offsetof(struct sockaddr_un, sun_path),
+ NULL, NULL, 0},
{0, 0, 0, 0, NULL, NULL, 0},
};
@@ -152,29 +159,47 @@
int e_socktype;
int e_protocol;
int e_wild;
-#define WILD_AF(ex) ((ex)->e_wild & 0x01)
-#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
-#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
+#define AF_ANY 0x01
+#define SOCKTYPE_ANY 0x02
+#define PROTOCOL_ANY 0x04
+#define WILD_AF(ex) ((ex)->e_wild & AF_ANY)
+#define WILD_SOCKTYPE(ex) ((ex)->e_wild & SOCKTYPE_ANY)
+#define WILD_PROTOCOL(ex) ((ex)->e_wild & PROTOCOL_ANY)
};
static const struct explore explore[] = {
-#if 0
- { PF_LOCAL, ANY, ANY, 0x01 },
-#endif
-#ifdef INET6
- { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0x07 },
- { PF_INET6, SOCK_STREAM, IPPROTO_TCP, 0x07 },
- { PF_INET6, SOCK_STREAM, IPPROTO_SCTP, 0x03 },
- { PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 },
- { PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 },
- { PF_INET6, SOCK_RAW, ANY, 0x05 },
-#endif
- { PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0x07 },
- { PF_INET, SOCK_STREAM, IPPROTO_TCP, 0x07 },
- { PF_INET, SOCK_STREAM, IPPROTO_SCTP, 0x03 },
- { PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 },
- { PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 },
- { PF_INET, SOCK_RAW, ANY, 0x05 },
+ { PF_LOCAL, SOCK_DGRAM, ANY,
+ AF_ANY | PROTOCOL_ANY },
+ { PF_LOCAL, SOCK_STREAM, ANY,
+ AF_ANY | PROTOCOL_ANY },
+ { PF_LOCAL, SOCK_SEQPACKET, ANY,
+ AF_ANY | PROTOCOL_ANY },
+#ifdef INET6
+ { PF_INET6, SOCK_DGRAM, IPPROTO_UDP,
+ AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY },
+ { PF_INET6, SOCK_STREAM, IPPROTO_TCP,
+ AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY },
+ { PF_INET6, SOCK_STREAM, IPPROTO_SCTP,
+ AF_ANY | SOCKTYPE_ANY },
+ { PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP,
+ AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY },
+ { PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE,
+ AF_ANY | SOCKTYPE_ANY },
+ { PF_INET6, SOCK_RAW, ANY,
+ AF_ANY | PROTOCOL_ANY },
+#endif
+ { PF_INET, SOCK_DGRAM, IPPROTO_UDP,
+ AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY },
+ { PF_INET, SOCK_STREAM, IPPROTO_TCP,
+ AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY },
+ { PF_INET, SOCK_STREAM, IPPROTO_SCTP,
+ AF_ANY | SOCKTYPE_ANY },
+ { PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP,
+ AF_ANY | SOCKTYPE_ANY | PROTOCOL_ANY },
+ { PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE,
+ AF_ANY | SOCKTYPE_ANY },
+ { PF_INET, SOCK_RAW, ANY,
+ AF_ANY | PROTOCOL_ANY },
{ -1, 0, 0, 0 },
};
@@ -408,6 +433,7 @@
ERR(EAI_BADFLAGS);
switch (hints->ai_family) {
case PF_UNSPEC:
+ case PF_LOCAL:
case PF_INET:
#ifdef INET6
case PF_INET6:
@@ -1130,6 +1156,9 @@
*res = NULL;
ai = NULL;
+ if (pai->ai_family == PF_LOCAL)
+ return (0);
+
/*
* filter out AFs that are not supported by the kernel
* XXX errno?
@@ -1172,8 +1201,11 @@
const struct afd *afd;
struct addrinfo *ai;
int error;
- char pton[PTON_MAX];
+ char pton[PTON_MAX], path[PATH_MAX], *p;
+#ifdef CTASSERT
+ CTASSERT(sizeofmember(struct sockaddr_un, sun_path) <= PATH_MAX);
+#endif
*res = NULL;
ai = NULL;
@@ -1182,6 +1214,15 @@
return 0;
switch (afd->a_af) {
+ case AF_LOCAL:
+ if (hostname[0] != '/')
+ ERR(EAI_NONAME);
+ if (strlen(hostname) > afd->a_addrlen)
+ ERR(EAI_MEMORY);
+ /* NUL-termination does not need to be guaranteed. */
+ strncpy(path, hostname, afd->a_addrlen);
+ p = &path[0];
+ break;
case AF_INET:
/*
* RFC3493 requires getaddrinfo() to accept AF_INET formats
@@ -1192,15 +1233,17 @@
*/
if (inet_aton(hostname, (struct in_addr *)pton) != 1)
return 0;
+ p = pton;
break;
default:
if (inet_pton(afd->a_af, hostname, pton) != 1)
return 0;
+ p = pton;
break;
}
if (pai->ai_family == afd->a_af) {
- GET_AI(ai, afd, pton);
+ GET_AI(ai, afd, p);
GET_PORT(ai, servname);
if ((pai->ai_flags & AI_CANONNAME)) {
/*
@@ -1320,6 +1363,12 @@
memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
ai->ai_addr->sa_len = afd->a_socklen;
ai->ai_addrlen = afd->a_socklen;
+ if (ai->ai_family == PF_LOCAL) {
+ size_t n = strnlen(addr, afd->a_addrlen);
+
+ ai->ai_addrlen -= afd->a_addrlen - n;
+ ai->ai_addr->sa_len -= afd->a_addrlen - n;
+ }
ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
p = (char *)(void *)(ai->ai_addr);
memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
@@ -1378,6 +1427,9 @@
if (servname == NULL)
return 0;
switch (ai->ai_family) {
+ case AF_LOCAL:
+ /* AF_LOCAL ignores servname silently. */
+ return (0);
case AF_INET:
#ifdef AF_INET6
case AF_INET6:
Index: head/lib/libc/net/getnameinfo.3
===================================================================
--- head/lib/libc/net/getnameinfo.3
+++ head/lib/libc/net/getnameinfo.3
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 14, 2013
+.Dd September 20, 2015
.Dt GETNAMEINFO 3
.Os
.Sh NAME
@@ -47,7 +47,7 @@
.Xr getaddrinfo 3
function.
.Pp
-If a link-layer address is passed to
+If a link-layer address or UNIX-domain address is passed to
.Fn getnameinfo ,
its ASCII representation will be stored in
.Fa host .
@@ -56,7 +56,8 @@
will be set to the empty string if non-NULL;
.Fa flags
will always be ignored.
-This is intended as a replacement for the legacy
+For a link-layer address,
+this can be used as a replacement of the legacy
.Xr link_ntoa 3
function.
.Pp
@@ -66,10 +67,17 @@
.Fa sa
should point to either a
.Li sockaddr_in ,
-.Li sockaddr_in6
+.Li sockaddr_in6 ,
+.Li sockaddr_dl ,
or
-.Li sockaddr_dl
-structure (for IPv4, IPv6 or link-layer respectively) that is
+.Li sockaddr_un
+structure
+.Po for IPv4 ,
+IPv6,
+link-layer,
+or UNIX-domain respectively
+.Pc
+that is
.Fa salen
bytes long.
.Pp
@@ -182,6 +190,9 @@
.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 ,
Index: head/lib/libc/net/getnameinfo.c
===================================================================
--- head/lib/libc/net/getnameinfo.c
+++ head/lib/libc/net/getnameinfo.c
@@ -49,6 +49,7 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
@@ -62,67 +63,102 @@
#include <stddef.h>
#include <errno.h>
-static int getnameinfo_inet(const struct sockaddr *, socklen_t, char *,
+static const struct afd *find_afd(int);
+static int getnameinfo_inet(const struct afd *,
+ const struct sockaddr *, socklen_t, char *,
size_t, char *, size_t, int);
#ifdef INET6
static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
size_t, int);
static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
#endif
-static int getnameinfo_link(const struct sockaddr *, socklen_t, char *,
+static int getnameinfo_link(const struct afd *,
+ const struct sockaddr *, socklen_t, char *,
+ size_t, char *, size_t, int);
+static int hexname(const u_int8_t *, size_t, char *, size_t);
+static int getnameinfo_un(const struct afd *,
+ const struct sockaddr *, socklen_t, char *,
size_t, char *, size_t, int);
-static int hexname(const u_int8_t *, size_t, char *, size_t);
-
-int
-getnameinfo(const struct sockaddr *sa, socklen_t salen,
- char *host, size_t hostlen, char *serv, size_t servlen,
- int flags)
-{
- if (sa == NULL)
- return (EAI_FAIL);
-
- switch (sa->sa_family) {
- case AF_INET:
-#ifdef INET6
- case AF_INET6:
-#endif
- return getnameinfo_inet(sa, salen, host, hostlen, serv,
- servlen, flags);
- case AF_LINK:
- return getnameinfo_link(sa, salen, host, hostlen, serv,
- servlen, flags);
- default:
- return EAI_FAMILY;
- }
-}
static const struct afd {
int a_af;
size_t a_addrlen;
socklen_t a_socklen;
int a_off;
+ int (*a_func)(const struct afd *,
+ const struct sockaddr *, socklen_t, char *,
+ size_t, char *, size_t, int);
} afdl [] = {
#ifdef INET6
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
- offsetof(struct sockaddr_in6, sin6_addr)},
+ offsetof(struct sockaddr_in6, sin6_addr),
+ getnameinfo_inet},
#endif
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
- offsetof(struct sockaddr_in, sin_addr)},
+ offsetof(struct sockaddr_in, sin_addr),
+ getnameinfo_inet},
+#define sizeofmember(type, member) (sizeof(((type *)0)->member))
+ {PF_LOCAL, sizeofmember(struct sockaddr_un, sun_path),
+ sizeof(struct sockaddr_un),
+ offsetof(struct sockaddr_un, sun_path),
+ getnameinfo_un},
+ {PF_LINK, sizeofmember(struct sockaddr_dl, sdl_data),
+ sizeof(struct sockaddr_dl),
+ offsetof(struct sockaddr_dl, sdl_data),
+ getnameinfo_link},
{0, 0, 0},
};
-struct sockinet {
- u_char si_len;
- u_char si_family;
- u_short si_port;
-};
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen, char *serv, size_t servlen,
+ int flags)
+{
+ const struct afd *afd;
+
+ if (sa == NULL)
+ return (EAI_FAIL);
+
+ afd = find_afd(sa->sa_family);
+ if (afd == NULL)
+ return (EAI_FAMILY);
+ if (sa->sa_family == PF_LOCAL) {
+ /*
+ * PF_LOCAL uses variable sa->sa_len depending on the
+ * content length of sun_path. Require 1 byte in
+ * sun_path at least.
+ */
+ if (salen > afd->a_socklen ||
+ salen <= afd->a_socklen -
+ sizeofmember(struct sockaddr_un, sun_path))
+ return (EAI_FAIL);
+ } else if (salen != afd->a_socklen)
+ return (EAI_FAIL);
+
+ return ((*afd->a_func)(afd, sa, salen, host, hostlen,
+ serv, servlen, flags));
+}
+
+static const struct afd *
+find_afd(int af)
+{
+ const struct afd *afd;
+
+ if (af == PF_UNSPEC)
+ return (NULL);
+ for (afd = &afdl[0]; afd->a_af > 0; afd++) {
+ if (afd->a_af == af)
+ return (afd);
+ }
+ return (NULL);
+}
static int
-getnameinfo_inet(const struct sockaddr *sa, socklen_t salen,
+getnameinfo_inet(const struct afd *afd,
+ const struct sockaddr *sa, socklen_t salen,
char *host, size_t hostlen, char *serv, size_t servlen,
int flags)
{
- const struct afd *afd;
struct servent *sp;
struct hostent *hp;
u_short port;
@@ -132,18 +168,8 @@
char numserv[512];
char numaddr[512];
- for (afd = &afdl[0]; afd->a_af > 0; afd++) {
- if (afd->a_af == sa->sa_family)
- break;
- }
- if (afd->a_af == 0)
- return (EAI_FAMILY);
-
- if (salen != afd->a_socklen)
- return EAI_FAIL;
-
/* network byte order */
- port = ((const struct sockinet *)sa)->si_port;
+ port = ((const struct sockaddr_in *)sa)->sin_port;
addr = (const char *)sa + afd->a_off;
if (serv == NULL || servlen == 0) {
@@ -377,7 +403,8 @@
*/
/* ARGSUSED */
static int
-getnameinfo_link(const struct sockaddr *sa, socklen_t salen,
+getnameinfo_link(const struct afd *afd,
+ const struct sockaddr *sa, socklen_t salen,
char *host, size_t hostlen, char *serv, size_t servlen, int flags)
{
const struct sockaddr_dl *sdl =
@@ -465,3 +492,30 @@
}
return 0;
}
+
+/*
+ * getnameinfo_un():
+ * Format a UNIX IPC domain address (pathname).
+ */
+/* ARGSUSED */
+static int
+getnameinfo_un(const struct afd *afd,
+ const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen, char *serv, size_t servlen, int flags)
+{
+ size_t pathlen;
+
+ if (serv != NULL && servlen > 0)
+ *serv = '\0';
+ if (host != NULL && hostlen > 0) {
+ pathlen = sa->sa_len - afd->a_off;
+
+ if (pathlen + 1 > hostlen) {
+ *host = '\0';
+ return (EAI_MEMORY);
+ }
+ strlcpy(host, (const char *)sa + afd->a_off, pathlen + 1);
+ }
+
+ return (0);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 29, 5:35 PM (18 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30542980
Default Alt Text
D3634.diff (13 KB)
Attached To
Mode
D3634: Add PF_LOCAL support to getaddrinfo(3) and getnameinfo(3)
Attached
Detach File
Event Timeline
Log In to Comment