1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <arpa/inet.h>
28 #include <sys/types.h>
33 #include "path-util.h"
35 #include "socket-util.h"
39 int socket_address_parse(SocketAddress *a, const char *s) {
48 a->type = SOCK_STREAM;
51 /* IPv6 in [x:.....:z]:p notation */
53 if (!socket_ipv6_is_supported()) {
54 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
62 n = strndupa(s+1, e-s-1);
65 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
66 return errno > 0 ? -errno : -EINVAL;
77 if (u <= 0 || u > 0xFFFF)
80 a->sockaddr.in6.sin6_family = AF_INET6;
81 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
82 a->size = sizeof(struct sockaddr_in6);
84 } else if (*s == '/') {
90 if (l >= sizeof(a->sockaddr.un.sun_path))
93 a->sockaddr.un.sun_family = AF_UNIX;
94 memcpy(a->sockaddr.un.sun_path, s, l);
95 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
97 } else if (*s == '@') {
98 /* Abstract AF_UNIX socket */
102 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
105 a->sockaddr.un.sun_family = AF_UNIX;
106 memcpy(a->sockaddr.un.sun_path+1, s+1, l);
107 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
112 r = safe_atou(e+1, &u);
116 if (u <= 0 || u > 0xFFFF)
119 n = strndupa(s, e-s);
121 /* IPv4 in w.x.y.z:p notation? */
122 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
127 /* Gotcha, it's a traditional IPv4 address */
128 a->sockaddr.in.sin_family = AF_INET;
129 a->sockaddr.in.sin_port = htons((uint16_t) u);
130 a->size = sizeof(struct sockaddr_in);
134 if (strlen(n) > IF_NAMESIZE-1)
137 /* Uh, our last resort, an interface name */
138 idx = if_nametoindex(n);
142 if (!socket_ipv6_is_supported()) {
143 log_warning("Binding to interface is not available since kernel does not support IPv6.");
144 return -EAFNOSUPPORT;
147 a->sockaddr.in6.sin6_family = AF_INET6;
148 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
149 a->sockaddr.in6.sin6_scope_id = idx;
150 a->sockaddr.in6.sin6_addr = in6addr_any;
151 a->size = sizeof(struct sockaddr_in6);
156 r = safe_atou(s, &u);
160 if (u <= 0 || u > 0xFFFF)
163 if (socket_ipv6_is_supported()) {
164 a->sockaddr.in6.sin6_family = AF_INET6;
165 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
166 a->sockaddr.in6.sin6_addr = in6addr_any;
167 a->size = sizeof(struct sockaddr_in6);
169 a->sockaddr.in.sin_family = AF_INET;
170 a->sockaddr.in.sin_port = htons((uint16_t) u);
171 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
172 a->size = sizeof(struct sockaddr_in);
180 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
183 _cleanup_free_ char *sfamily = NULL;
191 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
192 return errno > 0 ? -errno : -EINVAL;
194 family = netlink_family_from_string(sfamily);
198 a->sockaddr.nl.nl_family = AF_NETLINK;
199 a->sockaddr.nl.nl_groups = group;
202 a->size = sizeof(struct sockaddr_nl);
203 a->protocol = family;
208 int socket_address_verify(const SocketAddress *a) {
211 switch (socket_address_family(a)) {
214 if (a->size != sizeof(struct sockaddr_in))
217 if (a->sockaddr.in.sin_port == 0)
220 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
226 if (a->size != sizeof(struct sockaddr_in6))
229 if (a->sockaddr.in6.sin6_port == 0)
232 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
238 if (a->size < offsetof(struct sockaddr_un, sun_path))
241 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
243 if (a->sockaddr.un.sun_path[0] != 0) {
247 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
251 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
256 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
263 if (a->size != sizeof(struct sockaddr_nl))
266 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
272 return -EAFNOSUPPORT;
276 int socket_address_print(const SocketAddress *a, char **ret) {
282 r = socket_address_verify(a);
286 if (socket_address_family(a) == AF_NETLINK) {
287 _cleanup_free_ char *sfamily = NULL;
289 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
293 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
300 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, ret);
303 bool socket_address_can_accept(const SocketAddress *a) {
307 a->type == SOCK_STREAM ||
308 a->type == SOCK_SEQPACKET;
311 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
315 /* Invalid addresses are unequal to all */
316 if (socket_address_verify(a) < 0 ||
317 socket_address_verify(b) < 0)
320 if (a->type != b->type)
323 if (socket_address_family(a) != socket_address_family(b))
326 switch (socket_address_family(a)) {
329 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
332 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
338 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
341 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
347 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
348 b->size <= offsetof(struct sockaddr_un, sun_path))
351 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
354 if (a->sockaddr.un.sun_path[0]) {
355 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
358 if (a->size != b->size)
361 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
368 if (a->protocol != b->protocol)
371 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
377 /* Cannot compare, so we assume the addresses are different */
384 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
385 struct SocketAddress b;
390 if (socket_address_parse(&b, s) < 0)
395 return socket_address_equal(a, &b);
398 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
399 struct SocketAddress b;
404 if (socket_address_parse_netlink(&b, s) < 0)
407 return socket_address_equal(a, &b);
410 const char* socket_address_get_path(const SocketAddress *a) {
413 if (socket_address_family(a) != AF_UNIX)
416 if (a->sockaddr.un.sun_path[0] == 0)
419 return a->sockaddr.un.sun_path;
422 bool socket_ipv6_is_supported(void) {
423 _cleanup_free_ char *l = NULL;
425 if (access("/sys/module/ipv6", F_OK) != 0)
428 /* If we can't check "disable" parameter, assume enabled */
429 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
432 /* If module was loaded with disable=1 no IPv6 available */
436 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
443 b.size = sizeof(b.sockaddr);
444 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
447 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
450 solen = sizeof(b.type);
451 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
454 if (b.type != a->type)
457 if (a->protocol != 0) {
458 solen = sizeof(b.protocol);
459 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
462 if (b.protocol != a->protocol)
466 return socket_address_equal(a, &b);
469 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, char **ret) {
470 union sockaddr_union *sa = (union sockaddr_union*) _sa;
474 assert(salen >= sizeof(sa->sa.sa_family));
476 switch (sa->sa.sa_family) {
481 a = ntohl(sa->in.sin_addr.s_addr);
485 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
486 ntohs(sa->in.sin_port)) < 0)
493 static const unsigned char ipv4_prefix[] = {
494 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
497 if (translate_ipv6 && memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
498 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
502 a[0], a[1], a[2], a[3],
503 ntohs(sa->in6.sin6_port)) < 0)
506 char a[INET6_ADDRSTRLEN];
510 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a)),
511 ntohs(sa->in6.sin6_port)) < 0)
519 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
520 p = strdup("<unnamed>");
524 } else if (sa->un.sun_path[0] == 0) {
527 /* FIXME: We assume we can print the
528 * socket path here and that it hasn't
529 * more than one NUL byte. That is
530 * actually an invalid assumption */
532 p = new(char, sizeof(sa->un.sun_path)+1);
537 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
538 p[sizeof(sa->un.sun_path)] = 0;
541 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
557 int getpeername_pretty(int fd, char **ret) {
558 union sockaddr_union sa;
559 socklen_t salen = sizeof(sa);
565 if (getpeername(fd, &sa.sa, &salen) < 0)
568 if (sa.sa.sa_family == AF_UNIX) {
569 struct ucred ucred = {};
571 /* UNIX connection sockets are anonymous, so let's use
572 * PID/UID as pretty credentials instead */
574 r = getpeercred(fd, &ucred);
578 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
584 /* For remote sockets we translate IPv6 addresses back to IPv4
585 * if applicable, since that's nicer. */
587 return sockaddr_pretty(&sa.sa, salen, true, ret);
590 int getsockname_pretty(int fd, char **ret) {
591 union sockaddr_union sa;
592 socklen_t salen = sizeof(sa);
597 if (getsockname(fd, &sa.sa, &salen) < 0)
600 /* For local sockets we do not translate IPv6 addresses back
601 * to IPv6 if applicable, since this is usually used for
602 * listening sockets where the difference between IPv4 and
605 return sockaddr_pretty(&sa.sa, salen, false, ret);
608 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
610 char host[NI_MAXHOST], *ret;
614 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
615 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
617 int saved_errno = errno;
619 r = sockaddr_pretty(&sa->sa, salen, true, &ret);
621 return log_error_errno(r, "sockadd_pretty() failed: %m");
623 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
634 int getnameinfo_pretty(int fd, char **ret) {
635 union sockaddr_union sa;
636 socklen_t salen = sizeof(sa);
641 if (getsockname(fd, &sa.sa, &salen) < 0)
642 return log_error_errno(errno, "getsockname(%d) failed: %m", fd);
644 return socknameinfo_pretty(&sa, salen, ret);
647 int socket_address_unlink(SocketAddress *a) {
650 if (socket_address_family(a) != AF_UNIX)
653 if (a->sockaddr.un.sun_path[0] == 0)
656 if (unlink(a->sockaddr.un.sun_path) < 0)
662 static const char* const netlink_family_table[] = {
663 [NETLINK_ROUTE] = "route",
664 [NETLINK_FIREWALL] = "firewall",
665 [NETLINK_INET_DIAG] = "inet-diag",
666 [NETLINK_NFLOG] = "nflog",
667 [NETLINK_XFRM] = "xfrm",
668 [NETLINK_SELINUX] = "selinux",
669 [NETLINK_ISCSI] = "iscsi",
670 [NETLINK_AUDIT] = "audit",
671 [NETLINK_FIB_LOOKUP] = "fib-lookup",
672 [NETLINK_CONNECTOR] = "connector",
673 [NETLINK_NETFILTER] = "netfilter",
674 [NETLINK_IP6_FW] = "ip6-fw",
675 [NETLINK_DNRTMSG] = "dnrtmsg",
676 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
677 [NETLINK_GENERIC] = "generic",
678 [NETLINK_SCSITRANSPORT] = "scsitransport",
679 [NETLINK_ECRYPTFS] = "ecryptfs"
682 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
684 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
685 [SOCKET_ADDRESS_DEFAULT] = "default",
686 [SOCKET_ADDRESS_BOTH] = "both",
687 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
690 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
692 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
696 if (a->sa.sa_family != b->sa.sa_family)
699 if (a->sa.sa_family == AF_INET)
700 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
702 if (a->sa.sa_family == AF_INET6)
703 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
708 char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
712 /* Like ether_ntoa() but uses %02x instead of %x to print
713 * ethernet addresses, which makes them look less funny. Also,
714 * doesn't use a static buffer. */
716 sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
717 addr->ether_addr_octet[0],
718 addr->ether_addr_octet[1],
719 addr->ether_addr_octet[2],
720 addr->ether_addr_octet[3],
721 addr->ether_addr_octet[4],
722 addr->ether_addr_octet[5]);