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>
27 #include <netinet/ip.h>
35 #include "alloc-util.h"
38 #include "formats-util.h"
42 #include "parse-util.h"
43 #include "path-util.h"
44 #include "socket-util.h"
45 #include "string-table.h"
46 #include "string-util.h"
47 #include "user-util.h"
50 #if 0 /// UNNEEDED by elogind
51 int socket_address_parse(SocketAddress *a, const char *s) {
60 a->type = SOCK_STREAM;
63 /* IPv6 in [x:.....:z]:p notation */
69 n = strndupa(s+1, e-s-1);
72 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
73 return errno > 0 ? -errno : -EINVAL;
84 if (u <= 0 || u > 0xFFFF)
87 a->sockaddr.in6.sin6_family = AF_INET6;
88 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
89 a->size = sizeof(struct sockaddr_in6);
91 } else if (*s == '/') {
97 if (l >= sizeof(a->sockaddr.un.sun_path))
100 a->sockaddr.un.sun_family = AF_UNIX;
101 memcpy(a->sockaddr.un.sun_path, s, l);
102 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
104 } else if (*s == '@') {
105 /* Abstract AF_UNIX socket */
109 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
112 a->sockaddr.un.sun_family = AF_UNIX;
113 memcpy(a->sockaddr.un.sun_path+1, s+1, l);
114 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
119 r = safe_atou(e+1, &u);
123 if (u <= 0 || u > 0xFFFF)
126 n = strndupa(s, e-s);
128 /* IPv4 in w.x.y.z:p notation? */
129 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
134 /* Gotcha, it's a traditional IPv4 address */
135 a->sockaddr.in.sin_family = AF_INET;
136 a->sockaddr.in.sin_port = htons((uint16_t) u);
137 a->size = sizeof(struct sockaddr_in);
141 if (strlen(n) > IF_NAMESIZE-1)
144 /* Uh, our last resort, an interface name */
145 idx = if_nametoindex(n);
149 a->sockaddr.in6.sin6_family = AF_INET6;
150 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
151 a->sockaddr.in6.sin6_scope_id = idx;
152 a->sockaddr.in6.sin6_addr = in6addr_any;
153 a->size = sizeof(struct sockaddr_in6);
158 r = safe_atou(s, &u);
162 if (u <= 0 || u > 0xFFFF)
165 if (socket_ipv6_is_supported()) {
166 a->sockaddr.in6.sin6_family = AF_INET6;
167 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
168 a->sockaddr.in6.sin6_addr = in6addr_any;
169 a->size = sizeof(struct sockaddr_in6);
171 a->sockaddr.in.sin_family = AF_INET;
172 a->sockaddr.in.sin_port = htons((uint16_t) u);
173 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
174 a->size = sizeof(struct sockaddr_in);
182 int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
186 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
188 r = socket_address_parse(&b, s);
192 if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
193 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
194 return -EAFNOSUPPORT;
201 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
204 _cleanup_free_ char *sfamily = NULL;
212 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
213 return errno > 0 ? -errno : -EINVAL;
215 family = netlink_family_from_string(sfamily);
219 a->sockaddr.nl.nl_family = AF_NETLINK;
220 a->sockaddr.nl.nl_groups = group;
223 a->size = sizeof(struct sockaddr_nl);
224 a->protocol = family;
229 int socket_address_verify(const SocketAddress *a) {
232 switch (socket_address_family(a)) {
235 if (a->size != sizeof(struct sockaddr_in))
238 if (a->sockaddr.in.sin_port == 0)
241 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
247 if (a->size != sizeof(struct sockaddr_in6))
250 if (a->sockaddr.in6.sin6_port == 0)
253 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
259 if (a->size < offsetof(struct sockaddr_un, sun_path))
262 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
264 if (a->sockaddr.un.sun_path[0] != 0) {
268 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
272 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
277 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
284 if (a->size != sizeof(struct sockaddr_nl))
287 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
293 return -EAFNOSUPPORT;
297 int socket_address_print(const SocketAddress *a, char **ret) {
303 r = socket_address_verify(a);
307 if (socket_address_family(a) == AF_NETLINK) {
308 _cleanup_free_ char *sfamily = NULL;
310 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
314 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
321 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
324 bool socket_address_can_accept(const SocketAddress *a) {
328 a->type == SOCK_STREAM ||
329 a->type == SOCK_SEQPACKET;
332 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
336 /* Invalid addresses are unequal to all */
337 if (socket_address_verify(a) < 0 ||
338 socket_address_verify(b) < 0)
341 if (a->type != b->type)
344 if (socket_address_family(a) != socket_address_family(b))
347 switch (socket_address_family(a)) {
350 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
353 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
359 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
362 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
368 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
369 b->size <= offsetof(struct sockaddr_un, sun_path))
372 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
375 if (a->sockaddr.un.sun_path[0]) {
376 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
379 if (a->size != b->size)
382 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
389 if (a->protocol != b->protocol)
392 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
398 /* Cannot compare, so we assume the addresses are different */
405 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
406 struct SocketAddress b;
411 if (socket_address_parse(&b, s) < 0)
416 return socket_address_equal(a, &b);
419 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
420 struct SocketAddress b;
425 if (socket_address_parse_netlink(&b, s) < 0)
428 return socket_address_equal(a, &b);
431 const char* socket_address_get_path(const SocketAddress *a) {
434 if (socket_address_family(a) != AF_UNIX)
437 if (a->sockaddr.un.sun_path[0] == 0)
440 return a->sockaddr.un.sun_path;
444 bool socket_ipv6_is_supported(void) {
445 _cleanup_free_ char *l = NULL;
447 if (access("/sys/module/ipv6", F_OK) != 0)
450 /* If we can't check "disable" parameter, assume enabled */
451 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
454 /* If module was loaded with disable=1 no IPv6 available */
458 #if 0 /// UNNEEDED by elogind
459 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
466 b.size = sizeof(b.sockaddr);
467 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
470 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
473 solen = sizeof(b.type);
474 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
477 if (b.type != a->type)
480 if (a->protocol != 0) {
481 solen = sizeof(b.protocol);
482 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
485 if (b.protocol != a->protocol)
489 return socket_address_equal(a, &b);
492 int sockaddr_port(const struct sockaddr *_sa) {
493 union sockaddr_union *sa = (union sockaddr_union*) _sa;
497 if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
498 return -EAFNOSUPPORT;
500 return ntohs(sa->sa.sa_family == AF_INET6 ?
505 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
506 union sockaddr_union *sa = (union sockaddr_union*) _sa;
511 assert(salen >= sizeof(sa->sa.sa_family));
513 switch (sa->sa.sa_family) {
518 a = ntohl(sa->in.sin_addr.s_addr);
523 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
524 ntohs(sa->in.sin_port));
528 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
535 static const unsigned char ipv4_prefix[] = {
536 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
539 if (translate_ipv6 &&
540 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
541 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
545 a[0], a[1], a[2], a[3],
546 ntohs(sa->in6.sin6_port));
550 a[0], a[1], a[2], a[3]);
554 char a[INET6_ADDRSTRLEN];
556 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
562 ntohs(sa->in6.sin6_port));
576 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
577 p = strdup("<unnamed>");
581 } else if (sa->un.sun_path[0] == 0) {
584 /* FIXME: We assume we can print the
585 * socket path here and that it hasn't
586 * more than one NUL byte. That is
587 * actually an invalid assumption */
589 p = new(char, sizeof(sa->un.sun_path)+1);
594 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
595 p[sizeof(sa->un.sun_path)] = 0;
598 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
614 int getpeername_pretty(int fd, bool include_port, char **ret) {
615 union sockaddr_union sa;
616 socklen_t salen = sizeof(sa);
622 if (getpeername(fd, &sa.sa, &salen) < 0)
625 if (sa.sa.sa_family == AF_UNIX) {
626 struct ucred ucred = {};
628 /* UNIX connection sockets are anonymous, so let's use
629 * PID/UID as pretty credentials instead */
631 r = getpeercred(fd, &ucred);
635 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
641 /* For remote sockets we translate IPv6 addresses back to IPv4
642 * if applicable, since that's nicer. */
644 return sockaddr_pretty(&sa.sa, salen, true, include_port, ret);
647 int getsockname_pretty(int fd, char **ret) {
648 union sockaddr_union sa;
649 socklen_t salen = sizeof(sa);
654 if (getsockname(fd, &sa.sa, &salen) < 0)
657 /* For local sockets we do not translate IPv6 addresses back
658 * to IPv6 if applicable, since this is usually used for
659 * listening sockets where the difference between IPv4 and
662 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
665 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
667 char host[NI_MAXHOST], *ret;
671 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
672 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
674 int saved_errno = errno;
676 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
680 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
691 int getnameinfo_pretty(int fd, char **ret) {
692 union sockaddr_union sa;
693 socklen_t salen = sizeof(sa);
698 if (getsockname(fd, &sa.sa, &salen) < 0)
701 return socknameinfo_pretty(&sa, salen, ret);
704 int socket_address_unlink(SocketAddress *a) {
707 if (socket_address_family(a) != AF_UNIX)
710 if (a->sockaddr.un.sun_path[0] == 0)
713 if (unlink(a->sockaddr.un.sun_path) < 0)
719 static const char* const netlink_family_table[] = {
720 [NETLINK_ROUTE] = "route",
721 [NETLINK_FIREWALL] = "firewall",
722 [NETLINK_INET_DIAG] = "inet-diag",
723 [NETLINK_NFLOG] = "nflog",
724 [NETLINK_XFRM] = "xfrm",
725 [NETLINK_SELINUX] = "selinux",
726 [NETLINK_ISCSI] = "iscsi",
727 [NETLINK_AUDIT] = "audit",
728 [NETLINK_FIB_LOOKUP] = "fib-lookup",
729 [NETLINK_CONNECTOR] = "connector",
730 [NETLINK_NETFILTER] = "netfilter",
731 [NETLINK_IP6_FW] = "ip6-fw",
732 [NETLINK_DNRTMSG] = "dnrtmsg",
733 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
734 [NETLINK_GENERIC] = "generic",
735 [NETLINK_SCSITRANSPORT] = "scsitransport",
736 [NETLINK_ECRYPTFS] = "ecryptfs"
739 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
741 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
742 [SOCKET_ADDRESS_DEFAULT] = "default",
743 [SOCKET_ADDRESS_BOTH] = "both",
744 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
747 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
749 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
753 if (a->sa.sa_family != b->sa.sa_family)
756 if (a->sa.sa_family == AF_INET)
757 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
759 if (a->sa.sa_family == AF_INET6)
760 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
766 int fd_inc_sndbuf(int fd, size_t n) {
768 socklen_t l = sizeof(value);
770 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
771 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
774 /* If we have the privileges we will ignore the kernel limit. */
777 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
778 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
784 int fd_inc_rcvbuf(int fd, size_t n) {
786 socklen_t l = sizeof(value);
788 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
789 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
792 /* If we have the privileges we will ignore the kernel limit. */
795 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
796 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
801 #if 0 /// UNNEEDED by elogind
802 static const char* const ip_tos_table[] = {
803 [IPTOS_LOWDELAY] = "low-delay",
804 [IPTOS_THROUGHPUT] = "throughput",
805 [IPTOS_RELIABILITY] = "reliability",
806 [IPTOS_LOWCOST] = "low-cost",
809 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
812 int getpeercred(int fd, struct ucred *ucred) {
813 socklen_t n = sizeof(struct ucred);
820 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
824 if (n != sizeof(struct ucred))
827 /* Check if the data is actually useful and not suppressed due
828 * to namespacing issues */
831 if (u.uid == UID_INVALID)
833 if (u.gid == GID_INVALID)
840 int getpeersec(int fd, char **ret) {
852 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
863 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
882 const struct sockaddr *sa, socklen_t len,
886 struct cmsghdr cmsghdr;
887 uint8_t buf[CMSG_SPACE(sizeof(int))];
889 struct cmsghdr *cmsg;
892 .msg_name = (struct sockaddr*) sa,
894 .msg_control = &control,
895 .msg_controllen = sizeof(control),
898 assert(transport_fd >= 0);
901 cmsg = CMSG_FIRSTHDR(&mh);
902 cmsg->cmsg_level = SOL_SOCKET;
903 cmsg->cmsg_type = SCM_RIGHTS;
904 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
905 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
907 mh.msg_controllen = CMSG_SPACE(sizeof(int));
908 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
914 #if 0 /// UNNEEDED by elogind
915 int receive_one_fd(int transport_fd, int flags) {
917 struct cmsghdr cmsghdr;
918 uint8_t buf[CMSG_SPACE(sizeof(int))];
921 .msg_control = &control,
922 .msg_controllen = sizeof(control),
924 struct cmsghdr *cmsg, *found = NULL;
926 assert(transport_fd >= 0);
929 * Receive a single FD via @transport_fd. We don't care for
930 * the transport-type. We retrieve a single FD at most, so for
931 * packet-based transports, the caller must ensure to send
932 * only a single FD per packet. This is best used in
933 * combination with send_one_fd().
936 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
939 CMSG_FOREACH(cmsg, &mh) {
940 if (cmsg->cmsg_level == SOL_SOCKET &&
941 cmsg->cmsg_type == SCM_RIGHTS &&
942 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
954 return *(int*) CMSG_DATA(found);