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 int socket_address_parse(SocketAddress
*a
, const char *s
) {
59 a
->type
= SOCK_STREAM
;
62 /* IPv6 in [x:.....:z]:p notation */
68 n
= strndupa(s
+1, e
-s
-1);
71 if (inet_pton(AF_INET6
, n
, &a
->sockaddr
.in6
.sin6_addr
) <= 0)
72 return errno
> 0 ? -errno
: -EINVAL
;
83 if (u
<= 0 || u
> 0xFFFF)
86 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
87 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
88 a
->size
= sizeof(struct sockaddr_in6
);
90 } else if (*s
== '/') {
96 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
))
99 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
100 memcpy(a
->sockaddr
.un
.sun_path
, s
, l
);
101 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + l
+ 1;
103 } else if (*s
== '@') {
104 /* Abstract AF_UNIX socket */
108 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
) - 1)
111 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
112 memcpy(a
->sockaddr
.un
.sun_path
+1, s
+1, l
);
113 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + 1 + l
;
118 r
= safe_atou(e
+1, &u
);
122 if (u
<= 0 || u
> 0xFFFF)
125 n
= strndupa(s
, e
-s
);
127 /* IPv4 in w.x.y.z:p notation? */
128 r
= inet_pton(AF_INET
, n
, &a
->sockaddr
.in
.sin_addr
);
133 /* Gotcha, it's a traditional IPv4 address */
134 a
->sockaddr
.in
.sin_family
= AF_INET
;
135 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
136 a
->size
= sizeof(struct sockaddr_in
);
140 if (strlen(n
) > IF_NAMESIZE
-1)
143 /* Uh, our last resort, an interface name */
144 idx
= if_nametoindex(n
);
148 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
149 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
150 a
->sockaddr
.in6
.sin6_scope_id
= idx
;
151 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
152 a
->size
= sizeof(struct sockaddr_in6
);
157 r
= safe_atou(s
, &u
);
161 if (u
<= 0 || u
> 0xFFFF)
164 if (socket_ipv6_is_supported()) {
165 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
166 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
167 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
168 a
->size
= sizeof(struct sockaddr_in6
);
170 a
->sockaddr
.in
.sin_family
= AF_INET
;
171 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
172 a
->sockaddr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
173 a
->size
= sizeof(struct sockaddr_in
);
181 int socket_address_parse_and_warn(SocketAddress
*a
, const char *s
) {
185 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
187 r
= socket_address_parse(&b
, s
);
191 if (!socket_ipv6_is_supported() && b
.sockaddr
.sa
.sa_family
== AF_INET6
) {
192 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
193 return -EAFNOSUPPORT
;
200 int socket_address_parse_netlink(SocketAddress
*a
, const char *s
) {
203 _cleanup_free_
char *sfamily
= NULL
;
211 if (sscanf(s
, "%ms %u", &sfamily
, &group
) < 1)
212 return errno
> 0 ? -errno
: -EINVAL
;
214 family
= netlink_family_from_string(sfamily
);
218 a
->sockaddr
.nl
.nl_family
= AF_NETLINK
;
219 a
->sockaddr
.nl
.nl_groups
= group
;
222 a
->size
= sizeof(struct sockaddr_nl
);
223 a
->protocol
= family
;
228 int socket_address_verify(const SocketAddress
*a
) {
231 switch (socket_address_family(a
)) {
234 if (a
->size
!= sizeof(struct sockaddr_in
))
237 if (a
->sockaddr
.in
.sin_port
== 0)
240 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
246 if (a
->size
!= sizeof(struct sockaddr_in6
))
249 if (a
->sockaddr
.in6
.sin6_port
== 0)
252 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
258 if (a
->size
< offsetof(struct sockaddr_un
, sun_path
))
261 if (a
->size
> offsetof(struct sockaddr_un
, sun_path
)) {
263 if (a
->sockaddr
.un
.sun_path
[0] != 0) {
267 e
= memchr(a
->sockaddr
.un
.sun_path
, 0, sizeof(a
->sockaddr
.un
.sun_path
));
271 if (a
->size
!= offsetof(struct sockaddr_un
, sun_path
) + (e
- a
->sockaddr
.un
.sun_path
) + 1)
276 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
&& a
->type
!= SOCK_SEQPACKET
)
283 if (a
->size
!= sizeof(struct sockaddr_nl
))
286 if (a
->type
!= SOCK_RAW
&& a
->type
!= SOCK_DGRAM
)
292 return -EAFNOSUPPORT
;
296 int socket_address_print(const SocketAddress
*a
, char **ret
) {
302 r
= socket_address_verify(a
);
306 if (socket_address_family(a
) == AF_NETLINK
) {
307 _cleanup_free_
char *sfamily
= NULL
;
309 r
= netlink_family_to_string_alloc(a
->protocol
, &sfamily
);
313 r
= asprintf(ret
, "%s %u", sfamily
, a
->sockaddr
.nl
.nl_groups
);
320 return sockaddr_pretty(&a
->sockaddr
.sa
, a
->size
, false, true, ret
);
323 bool socket_address_can_accept(const SocketAddress
*a
) {
327 a
->type
== SOCK_STREAM
||
328 a
->type
== SOCK_SEQPACKET
;
331 bool socket_address_equal(const SocketAddress
*a
, const SocketAddress
*b
) {
335 /* Invalid addresses are unequal to all */
336 if (socket_address_verify(a
) < 0 ||
337 socket_address_verify(b
) < 0)
340 if (a
->type
!= b
->type
)
343 if (socket_address_family(a
) != socket_address_family(b
))
346 switch (socket_address_family(a
)) {
349 if (a
->sockaddr
.in
.sin_addr
.s_addr
!= b
->sockaddr
.in
.sin_addr
.s_addr
)
352 if (a
->sockaddr
.in
.sin_port
!= b
->sockaddr
.in
.sin_port
)
358 if (memcmp(&a
->sockaddr
.in6
.sin6_addr
, &b
->sockaddr
.in6
.sin6_addr
, sizeof(a
->sockaddr
.in6
.sin6_addr
)) != 0)
361 if (a
->sockaddr
.in6
.sin6_port
!= b
->sockaddr
.in6
.sin6_port
)
367 if (a
->size
<= offsetof(struct sockaddr_un
, sun_path
) ||
368 b
->size
<= offsetof(struct sockaddr_un
, sun_path
))
371 if ((a
->sockaddr
.un
.sun_path
[0] == 0) != (b
->sockaddr
.un
.sun_path
[0] == 0))
374 if (a
->sockaddr
.un
.sun_path
[0]) {
375 if (!path_equal_or_files_same(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
))
378 if (a
->size
!= b
->size
)
381 if (memcmp(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
, a
->size
) != 0)
388 if (a
->protocol
!= b
->protocol
)
391 if (a
->sockaddr
.nl
.nl_groups
!= b
->sockaddr
.nl
.nl_groups
)
397 /* Cannot compare, so we assume the addresses are different */
404 bool socket_address_is(const SocketAddress
*a
, const char *s
, int type
) {
405 struct SocketAddress b
;
410 if (socket_address_parse(&b
, s
) < 0)
415 return socket_address_equal(a
, &b
);
418 bool socket_address_is_netlink(const SocketAddress
*a
, const char *s
) {
419 struct SocketAddress b
;
424 if (socket_address_parse_netlink(&b
, s
) < 0)
427 return socket_address_equal(a
, &b
);
430 const char* socket_address_get_path(const SocketAddress
*a
) {
433 if (socket_address_family(a
) != AF_UNIX
)
436 if (a
->sockaddr
.un
.sun_path
[0] == 0)
439 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 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;
762 int fd_inc_sndbuf(int fd
, size_t n
) {
764 socklen_t l
= sizeof(value
);
766 r
= getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, &l
);
767 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
770 /* If we have the privileges we will ignore the kernel limit. */
773 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUFFORCE
, &value
, sizeof(value
)) < 0)
774 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, sizeof(value
)) < 0)
780 int fd_inc_rcvbuf(int fd
, size_t n
) {
782 socklen_t l
= sizeof(value
);
784 r
= getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, &l
);
785 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
788 /* If we have the privileges we will ignore the kernel limit. */
791 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUFFORCE
, &value
, sizeof(value
)) < 0)
792 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, sizeof(value
)) < 0)
797 static const char* const ip_tos_table
[] = {
798 [IPTOS_LOWDELAY
] = "low-delay",
799 [IPTOS_THROUGHPUT
] = "throughput",
800 [IPTOS_RELIABILITY
] = "reliability",
801 [IPTOS_LOWCOST
] = "low-cost",
804 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos
, int, 0xff);
806 int getpeercred(int fd
, struct ucred
*ucred
) {
807 socklen_t n
= sizeof(struct ucred
);
814 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERCRED
, &u
, &n
);
818 if (n
!= sizeof(struct ucred
))
821 /* Check if the data is actually useful and not suppressed due
822 * to namespacing issues */
825 if (u
.uid
== UID_INVALID
)
827 if (u
.gid
== GID_INVALID
)
834 int getpeersec(int fd
, char **ret
) {
846 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
857 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
876 const struct sockaddr
*sa
, socklen_t len
,
880 struct cmsghdr cmsghdr
;
881 uint8_t buf
[CMSG_SPACE(sizeof(int))];
883 struct cmsghdr
*cmsg
;
886 .msg_name
= (struct sockaddr
*) sa
,
888 .msg_control
= &control
,
889 .msg_controllen
= sizeof(control
),
892 assert(transport_fd
>= 0);
895 cmsg
= CMSG_FIRSTHDR(&mh
);
896 cmsg
->cmsg_level
= SOL_SOCKET
;
897 cmsg
->cmsg_type
= SCM_RIGHTS
;
898 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
899 memcpy(CMSG_DATA(cmsg
), &fd
, sizeof(int));
901 mh
.msg_controllen
= CMSG_SPACE(sizeof(int));
902 if (sendmsg(transport_fd
, &mh
, MSG_NOSIGNAL
| flags
) < 0)
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
);