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/>.
22 #include <arpa/inet.h>
26 #include <netinet/ip.h>
30 #include <sys/types.h>
33 #include "alloc-util.h"
36 #include "formats-util.h"
39 #include "parse-util.h"
40 #include "path-util.h"
41 #include "socket-util.h"
42 #include "string-table.h"
43 #include "string-util.h"
44 #include "user-util.h"
47 #if 0 /// UNNEEDED by elogind
48 int socket_address_parse(SocketAddress *a, const char *s) {
57 a->type = SOCK_STREAM;
60 /* IPv6 in [x:.....:z]:p notation */
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 a->sockaddr.in6.sin6_family = AF_INET6;
147 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
148 a->sockaddr.in6.sin6_scope_id = idx;
149 a->sockaddr.in6.sin6_addr = in6addr_any;
150 a->size = sizeof(struct sockaddr_in6);
155 r = safe_atou(s, &u);
159 if (u <= 0 || u > 0xFFFF)
162 if (socket_ipv6_is_supported()) {
163 a->sockaddr.in6.sin6_family = AF_INET6;
164 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
165 a->sockaddr.in6.sin6_addr = in6addr_any;
166 a->size = sizeof(struct sockaddr_in6);
168 a->sockaddr.in.sin_family = AF_INET;
169 a->sockaddr.in.sin_port = htons((uint16_t) u);
170 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
171 a->size = sizeof(struct sockaddr_in);
179 int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
183 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
185 r = socket_address_parse(&b, s);
189 if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
190 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
191 return -EAFNOSUPPORT;
198 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
201 _cleanup_free_ char *sfamily = NULL;
209 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
210 return errno > 0 ? -errno : -EINVAL;
212 family = netlink_family_from_string(sfamily);
216 a->sockaddr.nl.nl_family = AF_NETLINK;
217 a->sockaddr.nl.nl_groups = group;
220 a->size = sizeof(struct sockaddr_nl);
221 a->protocol = family;
226 int socket_address_verify(const SocketAddress *a) {
229 switch (socket_address_family(a)) {
232 if (a->size != sizeof(struct sockaddr_in))
235 if (a->sockaddr.in.sin_port == 0)
238 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
244 if (a->size != sizeof(struct sockaddr_in6))
247 if (a->sockaddr.in6.sin6_port == 0)
250 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
256 if (a->size < offsetof(struct sockaddr_un, sun_path))
259 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
261 if (a->sockaddr.un.sun_path[0] != 0) {
265 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
269 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
274 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
281 if (a->size != sizeof(struct sockaddr_nl))
284 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
290 return -EAFNOSUPPORT;
294 int socket_address_print(const SocketAddress *a, char **ret) {
300 r = socket_address_verify(a);
304 if (socket_address_family(a) == AF_NETLINK) {
305 _cleanup_free_ char *sfamily = NULL;
307 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
311 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
318 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
321 bool socket_address_can_accept(const SocketAddress *a) {
325 a->type == SOCK_STREAM ||
326 a->type == SOCK_SEQPACKET;
329 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
333 /* Invalid addresses are unequal to all */
334 if (socket_address_verify(a) < 0 ||
335 socket_address_verify(b) < 0)
338 if (a->type != b->type)
341 if (socket_address_family(a) != socket_address_family(b))
344 switch (socket_address_family(a)) {
347 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
350 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
356 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
359 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
365 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
366 b->size <= offsetof(struct sockaddr_un, sun_path))
369 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
372 if (a->sockaddr.un.sun_path[0]) {
373 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
376 if (a->size != b->size)
379 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
386 if (a->protocol != b->protocol)
389 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
395 /* Cannot compare, so we assume the addresses are different */
402 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
403 struct SocketAddress b;
408 if (socket_address_parse(&b, s) < 0)
413 return socket_address_equal(a, &b);
416 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
417 struct SocketAddress b;
422 if (socket_address_parse_netlink(&b, s) < 0)
425 return socket_address_equal(a, &b);
428 const char* socket_address_get_path(const SocketAddress *a) {
431 if (socket_address_family(a) != AF_UNIX)
434 if (a->sockaddr.un.sun_path[0] == 0)
437 return a->sockaddr.un.sun_path;
441 bool socket_ipv6_is_supported(void) {
442 _cleanup_free_ char *l = NULL;
444 if (access("/sys/module/ipv6", F_OK) != 0)
447 /* If we can't check "disable" parameter, assume enabled */
448 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
451 /* If module was loaded with disable=1 no IPv6 available */
455 #if 0 /// UNNEEDED by elogind
456 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
463 b.size = sizeof(b.sockaddr);
464 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
467 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
470 solen = sizeof(b.type);
471 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
474 if (b.type != a->type)
477 if (a->protocol != 0) {
478 solen = sizeof(b.protocol);
479 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
482 if (b.protocol != a->protocol)
486 return socket_address_equal(a, &b);
489 int sockaddr_port(const struct sockaddr *_sa) {
490 union sockaddr_union *sa = (union sockaddr_union*) _sa;
494 if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
495 return -EAFNOSUPPORT;
497 return ntohs(sa->sa.sa_family == AF_INET6 ?
502 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
503 union sockaddr_union *sa = (union sockaddr_union*) _sa;
508 assert(salen >= sizeof(sa->sa.sa_family));
510 switch (sa->sa.sa_family) {
515 a = ntohl(sa->in.sin_addr.s_addr);
520 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
521 ntohs(sa->in.sin_port));
525 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
532 static const unsigned char ipv4_prefix[] = {
533 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
536 if (translate_ipv6 &&
537 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
538 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
542 a[0], a[1], a[2], a[3],
543 ntohs(sa->in6.sin6_port));
547 a[0], a[1], a[2], a[3]);
551 char a[INET6_ADDRSTRLEN];
553 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
559 ntohs(sa->in6.sin6_port));
573 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
574 p = strdup("<unnamed>");
578 } else if (sa->un.sun_path[0] == 0) {
581 /* FIXME: We assume we can print the
582 * socket path here and that it hasn't
583 * more than one NUL byte. That is
584 * actually an invalid assumption */
586 p = new(char, sizeof(sa->un.sun_path)+1);
591 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
592 p[sizeof(sa->un.sun_path)] = 0;
595 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
611 int getpeername_pretty(int fd, char **ret) {
612 union sockaddr_union sa;
613 socklen_t salen = sizeof(sa);
619 if (getpeername(fd, &sa.sa, &salen) < 0)
622 if (sa.sa.sa_family == AF_UNIX) {
623 struct ucred ucred = {};
625 /* UNIX connection sockets are anonymous, so let's use
626 * PID/UID as pretty credentials instead */
628 r = getpeercred(fd, &ucred);
632 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
638 /* For remote sockets we translate IPv6 addresses back to IPv4
639 * if applicable, since that's nicer. */
641 return sockaddr_pretty(&sa.sa, salen, true, true, ret);
644 int getsockname_pretty(int fd, char **ret) {
645 union sockaddr_union sa;
646 socklen_t salen = sizeof(sa);
651 if (getsockname(fd, &sa.sa, &salen) < 0)
654 /* For local sockets we do not translate IPv6 addresses back
655 * to IPv6 if applicable, since this is usually used for
656 * listening sockets where the difference between IPv4 and
659 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
662 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
664 char host[NI_MAXHOST], *ret;
668 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
669 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
671 int saved_errno = errno;
673 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
677 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
688 int getnameinfo_pretty(int fd, char **ret) {
689 union sockaddr_union sa;
690 socklen_t salen = sizeof(sa);
695 if (getsockname(fd, &sa.sa, &salen) < 0)
698 return socknameinfo_pretty(&sa, salen, ret);
701 int socket_address_unlink(SocketAddress *a) {
704 if (socket_address_family(a) != AF_UNIX)
707 if (a->sockaddr.un.sun_path[0] == 0)
710 if (unlink(a->sockaddr.un.sun_path) < 0)
716 static const char* const netlink_family_table[] = {
717 [NETLINK_ROUTE] = "route",
718 [NETLINK_FIREWALL] = "firewall",
719 [NETLINK_INET_DIAG] = "inet-diag",
720 [NETLINK_NFLOG] = "nflog",
721 [NETLINK_XFRM] = "xfrm",
722 [NETLINK_SELINUX] = "selinux",
723 [NETLINK_ISCSI] = "iscsi",
724 [NETLINK_AUDIT] = "audit",
725 [NETLINK_FIB_LOOKUP] = "fib-lookup",
726 [NETLINK_CONNECTOR] = "connector",
727 [NETLINK_NETFILTER] = "netfilter",
728 [NETLINK_IP6_FW] = "ip6-fw",
729 [NETLINK_DNRTMSG] = "dnrtmsg",
730 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
731 [NETLINK_GENERIC] = "generic",
732 [NETLINK_SCSITRANSPORT] = "scsitransport",
733 [NETLINK_ECRYPTFS] = "ecryptfs"
736 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
738 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
739 [SOCKET_ADDRESS_DEFAULT] = "default",
740 [SOCKET_ADDRESS_BOTH] = "both",
741 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
744 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
746 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
750 if (a->sa.sa_family != b->sa.sa_family)
753 if (a->sa.sa_family == AF_INET)
754 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
756 if (a->sa.sa_family == AF_INET6)
757 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
763 int fd_inc_sndbuf(int fd, size_t n) {
765 socklen_t l = sizeof(value);
767 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
768 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
771 /* If we have the privileges we will ignore the kernel limit. */
774 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
775 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
781 int fd_inc_rcvbuf(int fd, size_t n) {
783 socklen_t l = sizeof(value);
785 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
786 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
789 /* If we have the privileges we will ignore the kernel limit. */
792 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
793 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
798 #if 0 /// UNNEEDED by elogind
799 static const char* const ip_tos_table[] = {
800 [IPTOS_LOWDELAY] = "low-delay",
801 [IPTOS_THROUGHPUT] = "throughput",
802 [IPTOS_RELIABILITY] = "reliability",
803 [IPTOS_LOWCOST] = "low-cost",
806 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
809 int getpeercred(int fd, struct ucred *ucred) {
810 socklen_t n = sizeof(struct ucred);
817 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
821 if (n != sizeof(struct ucred))
824 /* Check if the data is actually useful and not suppressed due
825 * to namespacing issues */
828 if (u.uid == UID_INVALID)
830 if (u.gid == GID_INVALID)
837 int getpeersec(int fd, char **ret) {
849 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
860 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
876 int send_one_fd(int transport_fd, int fd, int flags) {
878 struct cmsghdr cmsghdr;
879 uint8_t buf[CMSG_SPACE(sizeof(int))];
882 .msg_control = &control,
883 .msg_controllen = sizeof(control),
885 struct cmsghdr *cmsg;
887 assert(transport_fd >= 0);
890 cmsg = CMSG_FIRSTHDR(&mh);
891 cmsg->cmsg_level = SOL_SOCKET;
892 cmsg->cmsg_type = SCM_RIGHTS;
893 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
894 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
896 mh.msg_controllen = CMSG_SPACE(sizeof(int));
897 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
903 #if 0 /// UNNEEDED by elogind
904 int receive_one_fd(int transport_fd, int flags) {
906 struct cmsghdr cmsghdr;
907 uint8_t buf[CMSG_SPACE(sizeof(int))];
910 .msg_control = &control,
911 .msg_controllen = sizeof(control),
913 struct cmsghdr *cmsg, *found = NULL;
915 assert(transport_fd >= 0);
918 * Receive a single FD via @transport_fd. We don't care for
919 * the transport-type. We retrieve a single FD at most, so for
920 * packet-based transports, the caller must ensure to send
921 * only a single FD per packet. This is best used in
922 * combination with send_one_fd().
925 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
928 CMSG_FOREACH(cmsg, &mh) {
929 if (cmsg->cmsg_level == SOL_SOCKET &&
930 cmsg->cmsg_type == SCM_RIGHTS &&
931 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
943 return *(int*) CMSG_DATA(found);