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 /// UNNEEDED by elogind
49 int socket_address_parse(SocketAddress *a, const char *s) {
58 a->type = SOCK_STREAM;
61 /* IPv6 in [x:.....:z]:p notation */
67 n = strndupa(s+1, e-s-1);
70 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
71 return errno > 0 ? -errno : -EINVAL;
82 if (u <= 0 || u > 0xFFFF)
85 a->sockaddr.in6.sin6_family = AF_INET6;
86 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
87 a->size = sizeof(struct sockaddr_in6);
89 } else if (*s == '/') {
95 if (l >= sizeof(a->sockaddr.un.sun_path))
98 a->sockaddr.un.sun_family = AF_UNIX;
99 memcpy(a->sockaddr.un.sun_path, s, l);
100 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
102 } else if (*s == '@') {
103 /* Abstract AF_UNIX socket */
107 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
110 a->sockaddr.un.sun_family = AF_UNIX;
111 memcpy(a->sockaddr.un.sun_path+1, s+1, l);
112 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
117 r = safe_atou(e+1, &u);
121 if (u <= 0 || u > 0xFFFF)
124 n = strndupa(s, e-s);
126 /* IPv4 in w.x.y.z:p notation? */
127 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
132 /* Gotcha, it's a traditional IPv4 address */
133 a->sockaddr.in.sin_family = AF_INET;
134 a->sockaddr.in.sin_port = htons((uint16_t) u);
135 a->size = sizeof(struct sockaddr_in);
139 if (strlen(n) > IF_NAMESIZE-1)
142 /* Uh, our last resort, an interface name */
143 idx = if_nametoindex(n);
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_and_warn(SocketAddress *a, const char *s) {
184 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
186 r = socket_address_parse(&b, s);
190 if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
191 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
192 return -EAFNOSUPPORT;
199 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
202 _cleanup_free_ char *sfamily = NULL;
210 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
211 return errno > 0 ? -errno : -EINVAL;
213 family = netlink_family_from_string(sfamily);
217 a->sockaddr.nl.nl_family = AF_NETLINK;
218 a->sockaddr.nl.nl_groups = group;
221 a->size = sizeof(struct sockaddr_nl);
222 a->protocol = family;
227 int socket_address_verify(const SocketAddress *a) {
230 switch (socket_address_family(a)) {
233 if (a->size != sizeof(struct sockaddr_in))
236 if (a->sockaddr.in.sin_port == 0)
239 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
245 if (a->size != sizeof(struct sockaddr_in6))
248 if (a->sockaddr.in6.sin6_port == 0)
251 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
257 if (a->size < offsetof(struct sockaddr_un, sun_path))
260 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
262 if (a->sockaddr.un.sun_path[0] != 0) {
266 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
270 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
275 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
282 if (a->size != sizeof(struct sockaddr_nl))
285 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
291 return -EAFNOSUPPORT;
295 int socket_address_print(const SocketAddress *a, char **ret) {
301 r = socket_address_verify(a);
305 if (socket_address_family(a) == AF_NETLINK) {
306 _cleanup_free_ char *sfamily = NULL;
308 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
312 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
319 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
322 bool socket_address_can_accept(const SocketAddress *a) {
326 a->type == SOCK_STREAM ||
327 a->type == SOCK_SEQPACKET;
330 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
334 /* Invalid addresses are unequal to all */
335 if (socket_address_verify(a) < 0 ||
336 socket_address_verify(b) < 0)
339 if (a->type != b->type)
342 if (socket_address_family(a) != socket_address_family(b))
345 switch (socket_address_family(a)) {
348 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
351 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
357 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
360 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
366 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
367 b->size <= offsetof(struct sockaddr_un, sun_path))
370 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
373 if (a->sockaddr.un.sun_path[0]) {
374 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
377 if (a->size != b->size)
380 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
387 if (a->protocol != b->protocol)
390 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
396 /* Cannot compare, so we assume the addresses are different */
403 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
404 struct SocketAddress b;
409 if (socket_address_parse(&b, s) < 0)
414 return socket_address_equal(a, &b);
417 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
418 struct SocketAddress b;
423 if (socket_address_parse_netlink(&b, s) < 0)
426 return socket_address_equal(a, &b);
429 const char* socket_address_get_path(const SocketAddress *a) {
432 if (socket_address_family(a) != AF_UNIX)
435 if (a->sockaddr.un.sun_path[0] == 0)
438 return a->sockaddr.un.sun_path;
442 bool socket_ipv6_is_supported(void) {
443 _cleanup_free_ char *l = NULL;
445 if (access("/sys/module/ipv6", F_OK) != 0)
448 /* If we can't check "disable" parameter, assume enabled */
449 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
452 /* If module was loaded with disable=1 no IPv6 available */
456 /// UNNEEDED by elogind
458 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
465 b.size = sizeof(b.sockaddr);
466 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
469 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
472 solen = sizeof(b.type);
473 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
476 if (b.type != a->type)
479 if (a->protocol != 0) {
480 solen = sizeof(b.protocol);
481 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
484 if (b.protocol != a->protocol)
488 return socket_address_equal(a, &b);
491 int sockaddr_port(const struct sockaddr *_sa) {
492 union sockaddr_union *sa = (union sockaddr_union*) _sa;
496 if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
497 return -EAFNOSUPPORT;
499 return ntohs(sa->sa.sa_family == AF_INET6 ?
504 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
505 union sockaddr_union *sa = (union sockaddr_union*) _sa;
510 assert(salen >= sizeof(sa->sa.sa_family));
512 switch (sa->sa.sa_family) {
517 a = ntohl(sa->in.sin_addr.s_addr);
522 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
523 ntohs(sa->in.sin_port));
527 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
534 static const unsigned char ipv4_prefix[] = {
535 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
538 if (translate_ipv6 &&
539 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
540 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
544 a[0], a[1], a[2], a[3],
545 ntohs(sa->in6.sin6_port));
549 a[0], a[1], a[2], a[3]);
553 char a[INET6_ADDRSTRLEN];
555 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
561 ntohs(sa->in6.sin6_port));
575 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
576 p = strdup("<unnamed>");
580 } else if (sa->un.sun_path[0] == 0) {
583 /* FIXME: We assume we can print the
584 * socket path here and that it hasn't
585 * more than one NUL byte. That is
586 * actually an invalid assumption */
588 p = new(char, sizeof(sa->un.sun_path)+1);
593 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
594 p[sizeof(sa->un.sun_path)] = 0;
597 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
613 int getpeername_pretty(int fd, char **ret) {
614 union sockaddr_union sa;
615 socklen_t salen = sizeof(sa);
621 if (getpeername(fd, &sa.sa, &salen) < 0)
624 if (sa.sa.sa_family == AF_UNIX) {
625 struct ucred ucred = {};
627 /* UNIX connection sockets are anonymous, so let's use
628 * PID/UID as pretty credentials instead */
630 r = getpeercred(fd, &ucred);
634 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
640 /* For remote sockets we translate IPv6 addresses back to IPv4
641 * if applicable, since that's nicer. */
643 return sockaddr_pretty(&sa.sa, salen, true, true, ret);
646 int getsockname_pretty(int fd, char **ret) {
647 union sockaddr_union sa;
648 socklen_t salen = sizeof(sa);
653 if (getsockname(fd, &sa.sa, &salen) < 0)
656 /* For local sockets we do not translate IPv6 addresses back
657 * to IPv6 if applicable, since this is usually used for
658 * listening sockets where the difference between IPv4 and
661 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
664 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
666 char host[NI_MAXHOST], *ret;
670 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
671 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
673 int saved_errno = errno;
675 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
679 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
690 int getnameinfo_pretty(int fd, char **ret) {
691 union sockaddr_union sa;
692 socklen_t salen = sizeof(sa);
697 if (getsockname(fd, &sa.sa, &salen) < 0)
700 return socknameinfo_pretty(&sa, salen, ret);
703 int socket_address_unlink(SocketAddress *a) {
706 if (socket_address_family(a) != AF_UNIX)
709 if (a->sockaddr.un.sun_path[0] == 0)
712 if (unlink(a->sockaddr.un.sun_path) < 0)
718 static const char* const netlink_family_table[] = {
719 [NETLINK_ROUTE] = "route",
720 [NETLINK_FIREWALL] = "firewall",
721 [NETLINK_INET_DIAG] = "inet-diag",
722 [NETLINK_NFLOG] = "nflog",
723 [NETLINK_XFRM] = "xfrm",
724 [NETLINK_SELINUX] = "selinux",
725 [NETLINK_ISCSI] = "iscsi",
726 [NETLINK_AUDIT] = "audit",
727 [NETLINK_FIB_LOOKUP] = "fib-lookup",
728 [NETLINK_CONNECTOR] = "connector",
729 [NETLINK_NETFILTER] = "netfilter",
730 [NETLINK_IP6_FW] = "ip6-fw",
731 [NETLINK_DNRTMSG] = "dnrtmsg",
732 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
733 [NETLINK_GENERIC] = "generic",
734 [NETLINK_SCSITRANSPORT] = "scsitransport",
735 [NETLINK_ECRYPTFS] = "ecryptfs"
738 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
740 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
741 [SOCKET_ADDRESS_DEFAULT] = "default",
742 [SOCKET_ADDRESS_BOTH] = "both",
743 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
746 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
748 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
752 if (a->sa.sa_family != b->sa.sa_family)
755 if (a->sa.sa_family == AF_INET)
756 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
758 if (a->sa.sa_family == AF_INET6)
759 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
765 int fd_inc_sndbuf(int fd, size_t n) {
767 socklen_t l = sizeof(value);
769 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
770 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
773 /* If we have the privileges we will ignore the kernel limit. */
776 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
777 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
783 int fd_inc_rcvbuf(int fd, size_t n) {
785 socklen_t l = sizeof(value);
787 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
788 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
791 /* If we have the privileges we will ignore the kernel limit. */
794 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
795 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
800 /// 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);
879 int send_one_fd(int transport_fd, int fd, int flags) {
881 struct cmsghdr cmsghdr;
882 uint8_t buf[CMSG_SPACE(sizeof(int))];
885 .msg_control = &control,
886 .msg_controllen = sizeof(control),
888 struct cmsghdr *cmsg;
890 assert(transport_fd >= 0);
893 cmsg = CMSG_FIRSTHDR(&mh);
894 cmsg->cmsg_level = SOL_SOCKET;
895 cmsg->cmsg_type = SCM_RIGHTS;
896 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
897 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
899 mh.msg_controllen = CMSG_SPACE(sizeof(int));
900 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
906 /// UNNEEDED by elogind
908 int receive_one_fd(int transport_fd, int flags) {
910 struct cmsghdr cmsghdr;
911 uint8_t buf[CMSG_SPACE(sizeof(int))];
914 .msg_control = &control,
915 .msg_controllen = sizeof(control),
917 struct cmsghdr *cmsg, *found = NULL;
919 assert(transport_fd >= 0);
922 * Receive a single FD via @transport_fd. We don't care for
923 * the transport-type. We retrieve a single FD at most, so for
924 * packet-based transports, the caller must ensure to send
925 * only a single FD per packet. This is best used in
926 * combination with send_one_fd().
929 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
932 CMSG_FOREACH(cmsg, &mh) {
933 if (cmsg->cmsg_level == SOL_SOCKET &&
934 cmsg->cmsg_type == SCM_RIGHTS &&
935 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
947 return *(int*) CMSG_DATA(found);