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/>.
27 #include <arpa/inet.h>
30 #include <sys/types.h>
33 #include <sys/ioctl.h>
38 #include "path-util.h"
39 #include "socket-util.h"
43 int socket_address_parse(SocketAddress *a, const char *s) {
52 a->type = SOCK_STREAM;
55 /* IPv6 in [x:.....:z]:p notation */
57 if (!socket_ipv6_is_supported()) {
58 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
66 n = strndupa(s+1, e-s-1);
69 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
70 return errno > 0 ? -errno : -EINVAL;
81 if (u <= 0 || u > 0xFFFF)
84 a->sockaddr.in6.sin6_family = AF_INET6;
85 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
86 a->size = sizeof(struct sockaddr_in6);
88 } else if (*s == '/') {
94 if (l >= sizeof(a->sockaddr.un.sun_path))
97 a->sockaddr.un.sun_family = AF_UNIX;
98 memcpy(a->sockaddr.un.sun_path, s, l);
99 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
101 } else if (*s == '@') {
102 /* Abstract AF_UNIX socket */
106 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
109 a->sockaddr.un.sun_family = AF_UNIX;
110 memcpy(a->sockaddr.un.sun_path+1, s+1, l);
111 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
116 r = safe_atou(e+1, &u);
120 if (u <= 0 || u > 0xFFFF)
123 n = strndupa(s, e-s);
125 /* IPv4 in w.x.y.z:p notation? */
126 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
131 /* Gotcha, it's a traditional IPv4 address */
132 a->sockaddr.in.sin_family = AF_INET;
133 a->sockaddr.in.sin_port = htons((uint16_t) u);
134 a->size = sizeof(struct sockaddr_in);
138 if (strlen(n) > IF_NAMESIZE-1)
141 /* Uh, our last resort, an interface name */
142 idx = if_nametoindex(n);
146 if (!socket_ipv6_is_supported()) {
147 log_warning("Binding to interface is not available since kernel does not support IPv6.");
148 return -EAFNOSUPPORT;
151 a->sockaddr.in6.sin6_family = AF_INET6;
152 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
153 a->sockaddr.in6.sin6_scope_id = idx;
154 a->sockaddr.in6.sin6_addr = in6addr_any;
155 a->size = sizeof(struct sockaddr_in6);
160 r = safe_atou(s, &u);
164 if (u <= 0 || u > 0xFFFF)
167 if (socket_ipv6_is_supported()) {
168 a->sockaddr.in6.sin6_family = AF_INET6;
169 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
170 a->sockaddr.in6.sin6_addr = in6addr_any;
171 a->size = sizeof(struct sockaddr_in6);
173 a->sockaddr.in.sin_family = AF_INET;
174 a->sockaddr.in.sin_port = htons((uint16_t) u);
175 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
176 a->size = sizeof(struct sockaddr_in);
184 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
187 _cleanup_free_ char *sfamily = NULL;
195 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
196 return errno > 0 ? -errno : -EINVAL;
198 family = netlink_family_from_string(sfamily);
202 a->sockaddr.nl.nl_family = AF_NETLINK;
203 a->sockaddr.nl.nl_groups = group;
206 a->size = sizeof(struct sockaddr_nl);
207 a->protocol = family;
212 int socket_address_verify(const SocketAddress *a) {
215 switch (socket_address_family(a)) {
218 if (a->size != sizeof(struct sockaddr_in))
221 if (a->sockaddr.in.sin_port == 0)
224 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
230 if (a->size != sizeof(struct sockaddr_in6))
233 if (a->sockaddr.in6.sin6_port == 0)
236 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
242 if (a->size < offsetof(struct sockaddr_un, sun_path))
245 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
247 if (a->sockaddr.un.sun_path[0] != 0) {
251 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
255 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
260 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
267 if (a->size != sizeof(struct sockaddr_nl))
270 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
276 return -EAFNOSUPPORT;
280 int socket_address_print(const SocketAddress *a, char **ret) {
286 r = socket_address_verify(a);
290 if (socket_address_family(a) == AF_NETLINK) {
291 _cleanup_free_ char *sfamily = NULL;
293 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
297 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
304 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, ret);
307 bool socket_address_can_accept(const SocketAddress *a) {
311 a->type == SOCK_STREAM ||
312 a->type == SOCK_SEQPACKET;
315 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
319 /* Invalid addresses are unequal to all */
320 if (socket_address_verify(a) < 0 ||
321 socket_address_verify(b) < 0)
324 if (a->type != b->type)
327 if (a->size != b->size)
330 if (socket_address_family(a) != socket_address_family(b))
333 switch (socket_address_family(a)) {
336 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
339 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
345 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
348 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
355 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
358 if (a->sockaddr.un.sun_path[0]) {
359 if (!strneq(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)))
362 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
370 if (a->protocol != b->protocol)
373 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
379 /* Cannot compare, so we assume the addresses are different */
386 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
387 struct SocketAddress b;
392 if (socket_address_parse(&b, s) < 0)
397 return socket_address_equal(a, &b);
400 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
401 struct SocketAddress b;
406 if (socket_address_parse_netlink(&b, s) < 0)
409 return socket_address_equal(a, &b);
412 const char* socket_address_get_path(const SocketAddress *a) {
415 if (socket_address_family(a) != AF_UNIX)
418 if (a->sockaddr.un.sun_path[0] == 0)
421 return a->sockaddr.un.sun_path;
424 bool socket_ipv6_is_supported(void) {
425 _cleanup_free_ char *l = NULL;
427 if (access("/sys/module/ipv6", F_OK) != 0)
430 /* If we can't check "disable" parameter, assume enabled */
431 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
434 /* If module was loaded with disable=1 no IPv6 available */
438 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
439 union sockaddr_union sa;
440 socklen_t salen = sizeof(sa), solen;
446 if (getsockname(fd, &sa.sa, &salen) < 0)
449 if (sa.sa.sa_family != a->sockaddr.sa.sa_family)
452 solen = sizeof(type);
453 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &solen) < 0)
459 if (a->protocol != 0) {
460 solen = sizeof(protocol);
461 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &solen) < 0)
464 if (protocol != a->protocol)
468 switch (sa.sa.sa_family) {
471 return sa.in.sin_port == a->sockaddr.in.sin_port &&
472 sa.in.sin_addr.s_addr == a->sockaddr.in.sin_addr.s_addr;
475 return sa.in6.sin6_port == a->sockaddr.in6.sin6_port &&
476 memcmp(&sa.in6.sin6_addr, &a->sockaddr.in6.sin6_addr, sizeof(struct in6_addr)) == 0;
479 return salen == a->size &&
480 memcmp(sa.un.sun_path, a->sockaddr.un.sun_path, salen - offsetof(struct sockaddr_un, sun_path)) == 0;
487 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, char **ret) {
488 union sockaddr_union *sa = (union sockaddr_union*) _sa;
492 assert(salen >= sizeof(sa->sa.sa_family));
494 switch (sa->sa.sa_family) {
499 a = ntohl(sa->in.sin_addr.s_addr);
503 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
504 ntohs(sa->in.sin_port)) < 0)
511 static const unsigned char ipv4_prefix[] = {
512 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
515 if (translate_ipv6 && memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
516 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
520 a[0], a[1], a[2], a[3],
521 ntohs(sa->in6.sin6_port)) < 0)
524 char a[INET6_ADDRSTRLEN];
528 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a)),
529 ntohs(sa->in6.sin6_port)) < 0)
537 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
538 p = strdup("<unnamed>");
542 } else if (sa->un.sun_path[0] == 0) {
545 /* FIXME: We assume we can print the
546 * socket path here and that it hasn't
547 * more than one NUL byte. That is
548 * actually an invalid assumption */
550 p = new(char, sizeof(sa->un.sun_path)+1);
555 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
556 p[sizeof(sa->un.sun_path)] = 0;
559 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
575 int getpeername_pretty(int fd, char **ret) {
576 union sockaddr_union sa;
584 if (getpeername(fd, &sa.sa, &salen) < 0)
587 if (sa.sa.sa_family == AF_UNIX) {
588 struct ucred ucred = {};
590 /* UNIX connection sockets are anonymous, so let's use
591 * PID/UID as pretty credentials instead */
593 r = getpeercred(fd, &ucred);
597 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
603 /* For remote sockets we translate IPv6 addresses back to IPv4
604 * if applicable, since that's nicer. */
606 return sockaddr_pretty(&sa.sa, salen, true, ret);
609 int getsockname_pretty(int fd, char **ret) {
610 union sockaddr_union sa;
617 if (getsockname(fd, &sa.sa, &salen) < 0)
620 /* For local sockets we do not translate IPv6 addresses back
621 * to IPv6 if applicable, since this is usually used for
622 * listening sockets where the difference between IPv4 and
625 return sockaddr_pretty(&sa.sa, salen, false, ret);
628 int socket_address_unlink(SocketAddress *a) {
631 if (socket_address_family(a) != AF_UNIX)
634 if (a->sockaddr.un.sun_path[0] == 0)
637 if (unlink(a->sockaddr.un.sun_path) < 0)
643 int in_addr_null(unsigned family, union in_addr_union *u) {
646 if (family == AF_INET)
647 return u->in.s_addr == 0;
649 if (family == AF_INET6)
651 u->in6.s6_addr32[0] == 0 &&
652 u->in6.s6_addr32[1] == 0 &&
653 u->in6.s6_addr32[2] == 0 &&
654 u->in6.s6_addr32[3] == 0;
656 return -EAFNOSUPPORT;
660 int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b) {
664 if (family == AF_INET)
665 return a->in.s_addr == b->in.s_addr;
667 if (family == AF_INET6)
669 a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
670 a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
671 a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
672 a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
674 return -EAFNOSUPPORT;
677 int in_addr_prefix_intersect(
679 const union in_addr_union *a,
681 const union in_addr_union *b,
682 unsigned bprefixlen) {
689 /* Checks whether there are any addresses that are in both
692 m = MIN(aprefixlen, bprefixlen);
694 if (family == AF_INET) {
697 x = be32toh(a->in.s_addr ^ b->in.s_addr);
698 nm = 0xFFFFFFFFUL << (32 - m);
700 return (x & nm) == 0;
703 if (family == AF_INET6) {
709 for (i = 0; i < 16; i++) {
712 x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i];
715 nm = 0xFF << (8 - m);
731 return -EAFNOSUPPORT;
734 int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen) {
737 /* Increases the network part of an address by one. Returns
738 * positive it that succeeds, or 0 if this overflows. */
743 if (family == AF_INET) {
749 c = be32toh(u->in.s_addr);
750 n = c + (1UL << (32 - prefixlen));
753 n &= 0xFFFFFFFFUL << (32 - prefixlen);
755 u->in.s_addr = htobe32(n);
759 if (family == AF_INET6) {
760 struct in6_addr add = {}, result;
761 uint8_t overflow = 0;
767 /* First calculate what we have to add */
768 add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8);
770 for (i = 16; i > 0; i--) {
773 result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow;
774 overflow = (result.s6_addr[j] < u->in6.s6_addr[j]);
784 return -EAFNOSUPPORT;
787 int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret) {
794 if (family == AF_INET)
796 else if (family == AF_INET6)
797 l = INET6_ADDRSTRLEN;
799 return -EAFNOSUPPORT;
806 if (!inet_ntop(family, u, x, l)) {
808 return errno ? -errno : -EINVAL;
815 int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret) {
820 if (!IN_SET(family, AF_INET, AF_INET6))
821 return -EAFNOSUPPORT;
824 if (inet_pton(family, s, ret) <= 0)
825 return errno ? -errno : -EINVAL;
830 static const char* const netlink_family_table[] = {
831 [NETLINK_ROUTE] = "route",
832 [NETLINK_FIREWALL] = "firewall",
833 [NETLINK_INET_DIAG] = "inet-diag",
834 [NETLINK_NFLOG] = "nflog",
835 [NETLINK_XFRM] = "xfrm",
836 [NETLINK_SELINUX] = "selinux",
837 [NETLINK_ISCSI] = "iscsi",
838 [NETLINK_AUDIT] = "audit",
839 [NETLINK_FIB_LOOKUP] = "fib-lookup",
840 [NETLINK_CONNECTOR] = "connector",
841 [NETLINK_NETFILTER] = "netfilter",
842 [NETLINK_IP6_FW] = "ip6-fw",
843 [NETLINK_DNRTMSG] = "dnrtmsg",
844 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
845 [NETLINK_GENERIC] = "generic",
846 [NETLINK_SCSITRANSPORT] = "scsitransport",
847 [NETLINK_ECRYPTFS] = "ecryptfs"
850 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
852 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
853 [SOCKET_ADDRESS_DEFAULT] = "default",
854 [SOCKET_ADDRESS_BOTH] = "both",
855 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
858 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);