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>
35 #include "formats-util.h"
38 #include "parse-util.h"
39 #include "path-util.h"
40 #include "socket-util.h"
41 #include "string-table.h"
42 #include "string-util.h"
43 #include "user-util.h"
46 int socket_address_parse(SocketAddress
*a
, const char *s
) {
55 a
->type
= SOCK_STREAM
;
58 /* IPv6 in [x:.....:z]:p notation */
64 n
= strndupa(s
+1, e
-s
-1);
67 if (inet_pton(AF_INET6
, n
, &a
->sockaddr
.in6
.sin6_addr
) <= 0)
68 return errno
> 0 ? -errno
: -EINVAL
;
79 if (u
<= 0 || u
> 0xFFFF)
82 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
83 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
84 a
->size
= sizeof(struct sockaddr_in6
);
86 } else if (*s
== '/') {
92 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
))
95 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
96 memcpy(a
->sockaddr
.un
.sun_path
, s
, l
);
97 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + l
+ 1;
99 } else if (*s
== '@') {
100 /* Abstract AF_UNIX socket */
104 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
) - 1)
107 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
108 memcpy(a
->sockaddr
.un
.sun_path
+1, s
+1, l
);
109 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + 1 + l
;
114 r
= safe_atou(e
+1, &u
);
118 if (u
<= 0 || u
> 0xFFFF)
121 n
= strndupa(s
, e
-s
);
123 /* IPv4 in w.x.y.z:p notation? */
124 r
= inet_pton(AF_INET
, n
, &a
->sockaddr
.in
.sin_addr
);
129 /* Gotcha, it's a traditional IPv4 address */
130 a
->sockaddr
.in
.sin_family
= AF_INET
;
131 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
132 a
->size
= sizeof(struct sockaddr_in
);
136 if (strlen(n
) > IF_NAMESIZE
-1)
139 /* Uh, our last resort, an interface name */
140 idx
= if_nametoindex(n
);
144 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
145 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
146 a
->sockaddr
.in6
.sin6_scope_id
= idx
;
147 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
148 a
->size
= sizeof(struct sockaddr_in6
);
153 r
= safe_atou(s
, &u
);
157 if (u
<= 0 || u
> 0xFFFF)
160 if (socket_ipv6_is_supported()) {
161 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
162 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
163 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
164 a
->size
= sizeof(struct sockaddr_in6
);
166 a
->sockaddr
.in
.sin_family
= AF_INET
;
167 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
168 a
->sockaddr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
169 a
->size
= sizeof(struct sockaddr_in
);
177 int socket_address_parse_and_warn(SocketAddress
*a
, const char *s
) {
181 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
183 r
= socket_address_parse(&b
, s
);
187 if (!socket_ipv6_is_supported() && b
.sockaddr
.sa
.sa_family
== AF_INET6
) {
188 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
189 return -EAFNOSUPPORT
;
196 int socket_address_parse_netlink(SocketAddress
*a
, const char *s
) {
199 _cleanup_free_
char *sfamily
= NULL
;
207 if (sscanf(s
, "%ms %u", &sfamily
, &group
) < 1)
208 return errno
> 0 ? -errno
: -EINVAL
;
210 family
= netlink_family_from_string(sfamily
);
214 a
->sockaddr
.nl
.nl_family
= AF_NETLINK
;
215 a
->sockaddr
.nl
.nl_groups
= group
;
218 a
->size
= sizeof(struct sockaddr_nl
);
219 a
->protocol
= family
;
224 int socket_address_verify(const SocketAddress
*a
) {
227 switch (socket_address_family(a
)) {
230 if (a
->size
!= sizeof(struct sockaddr_in
))
233 if (a
->sockaddr
.in
.sin_port
== 0)
236 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
242 if (a
->size
!= sizeof(struct sockaddr_in6
))
245 if (a
->sockaddr
.in6
.sin6_port
== 0)
248 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
254 if (a
->size
< offsetof(struct sockaddr_un
, sun_path
))
257 if (a
->size
> offsetof(struct sockaddr_un
, sun_path
)) {
259 if (a
->sockaddr
.un
.sun_path
[0] != 0) {
263 e
= memchr(a
->sockaddr
.un
.sun_path
, 0, sizeof(a
->sockaddr
.un
.sun_path
));
267 if (a
->size
!= offsetof(struct sockaddr_un
, sun_path
) + (e
- a
->sockaddr
.un
.sun_path
) + 1)
272 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
&& a
->type
!= SOCK_SEQPACKET
)
279 if (a
->size
!= sizeof(struct sockaddr_nl
))
282 if (a
->type
!= SOCK_RAW
&& a
->type
!= SOCK_DGRAM
)
288 return -EAFNOSUPPORT
;
292 int socket_address_print(const SocketAddress
*a
, char **ret
) {
298 r
= socket_address_verify(a
);
302 if (socket_address_family(a
) == AF_NETLINK
) {
303 _cleanup_free_
char *sfamily
= NULL
;
305 r
= netlink_family_to_string_alloc(a
->protocol
, &sfamily
);
309 r
= asprintf(ret
, "%s %u", sfamily
, a
->sockaddr
.nl
.nl_groups
);
316 return sockaddr_pretty(&a
->sockaddr
.sa
, a
->size
, false, true, ret
);
319 bool socket_address_can_accept(const SocketAddress
*a
) {
323 a
->type
== SOCK_STREAM
||
324 a
->type
== SOCK_SEQPACKET
;
327 bool socket_address_equal(const SocketAddress
*a
, const SocketAddress
*b
) {
331 /* Invalid addresses are unequal to all */
332 if (socket_address_verify(a
) < 0 ||
333 socket_address_verify(b
) < 0)
336 if (a
->type
!= b
->type
)
339 if (socket_address_family(a
) != socket_address_family(b
))
342 switch (socket_address_family(a
)) {
345 if (a
->sockaddr
.in
.sin_addr
.s_addr
!= b
->sockaddr
.in
.sin_addr
.s_addr
)
348 if (a
->sockaddr
.in
.sin_port
!= b
->sockaddr
.in
.sin_port
)
354 if (memcmp(&a
->sockaddr
.in6
.sin6_addr
, &b
->sockaddr
.in6
.sin6_addr
, sizeof(a
->sockaddr
.in6
.sin6_addr
)) != 0)
357 if (a
->sockaddr
.in6
.sin6_port
!= b
->sockaddr
.in6
.sin6_port
)
363 if (a
->size
<= offsetof(struct sockaddr_un
, sun_path
) ||
364 b
->size
<= offsetof(struct sockaddr_un
, sun_path
))
367 if ((a
->sockaddr
.un
.sun_path
[0] == 0) != (b
->sockaddr
.un
.sun_path
[0] == 0))
370 if (a
->sockaddr
.un
.sun_path
[0]) {
371 if (!path_equal_or_files_same(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
))
374 if (a
->size
!= b
->size
)
377 if (memcmp(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
, a
->size
) != 0)
384 if (a
->protocol
!= b
->protocol
)
387 if (a
->sockaddr
.nl
.nl_groups
!= b
->sockaddr
.nl
.nl_groups
)
393 /* Cannot compare, so we assume the addresses are different */
400 bool socket_address_is(const SocketAddress
*a
, const char *s
, int type
) {
401 struct SocketAddress b
;
406 if (socket_address_parse(&b
, s
) < 0)
411 return socket_address_equal(a
, &b
);
414 bool socket_address_is_netlink(const SocketAddress
*a
, const char *s
) {
415 struct SocketAddress b
;
420 if (socket_address_parse_netlink(&b
, s
) < 0)
423 return socket_address_equal(a
, &b
);
426 const char* socket_address_get_path(const SocketAddress
*a
) {
429 if (socket_address_family(a
) != AF_UNIX
)
432 if (a
->sockaddr
.un
.sun_path
[0] == 0)
435 return a
->sockaddr
.un
.sun_path
;
438 bool socket_ipv6_is_supported(void) {
439 _cleanup_free_
char *l
= NULL
;
441 if (access("/sys/module/ipv6", F_OK
) != 0)
444 /* If we can't check "disable" parameter, assume enabled */
445 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l
) < 0)
448 /* If module was loaded with disable=1 no IPv6 available */
452 bool socket_address_matches_fd(const SocketAddress
*a
, int fd
) {
459 b
.size
= sizeof(b
.sockaddr
);
460 if (getsockname(fd
, &b
.sockaddr
.sa
, &b
.size
) < 0)
463 if (b
.sockaddr
.sa
.sa_family
!= a
->sockaddr
.sa
.sa_family
)
466 solen
= sizeof(b
.type
);
467 if (getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, &b
.type
, &solen
) < 0)
470 if (b
.type
!= a
->type
)
473 if (a
->protocol
!= 0) {
474 solen
= sizeof(b
.protocol
);
475 if (getsockopt(fd
, SOL_SOCKET
, SO_PROTOCOL
, &b
.protocol
, &solen
) < 0)
478 if (b
.protocol
!= a
->protocol
)
482 return socket_address_equal(a
, &b
);
485 int sockaddr_port(const struct sockaddr
*_sa
) {
486 union sockaddr_union
*sa
= (union sockaddr_union
*) _sa
;
490 if (!IN_SET(sa
->sa
.sa_family
, AF_INET
, AF_INET6
))
491 return -EAFNOSUPPORT
;
493 return ntohs(sa
->sa
.sa_family
== AF_INET6
?
498 int sockaddr_pretty(const struct sockaddr
*_sa
, socklen_t salen
, bool translate_ipv6
, bool include_port
, char **ret
) {
499 union sockaddr_union
*sa
= (union sockaddr_union
*) _sa
;
504 assert(salen
>= sizeof(sa
->sa
.sa_family
));
506 switch (sa
->sa
.sa_family
) {
511 a
= ntohl(sa
->in
.sin_addr
.s_addr
);
516 a
>> 24, (a
>> 16) & 0xFF, (a
>> 8) & 0xFF, a
& 0xFF,
517 ntohs(sa
->in
.sin_port
));
521 a
>> 24, (a
>> 16) & 0xFF, (a
>> 8) & 0xFF, a
& 0xFF);
528 static const unsigned char ipv4_prefix
[] = {
529 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
532 if (translate_ipv6
&&
533 memcmp(&sa
->in6
.sin6_addr
, ipv4_prefix
, sizeof(ipv4_prefix
)) == 0) {
534 const uint8_t *a
= sa
->in6
.sin6_addr
.s6_addr
+12;
538 a
[0], a
[1], a
[2], a
[3],
539 ntohs(sa
->in6
.sin6_port
));
543 a
[0], a
[1], a
[2], a
[3]);
547 char a
[INET6_ADDRSTRLEN
];
549 inet_ntop(AF_INET6
, &sa
->in6
.sin6_addr
, a
, sizeof(a
));
555 ntohs(sa
->in6
.sin6_port
));
569 if (salen
<= offsetof(struct sockaddr_un
, sun_path
)) {
570 p
= strdup("<unnamed>");
574 } else if (sa
->un
.sun_path
[0] == 0) {
577 /* FIXME: We assume we can print the
578 * socket path here and that it hasn't
579 * more than one NUL byte. That is
580 * actually an invalid assumption */
582 p
= new(char, sizeof(sa
->un
.sun_path
)+1);
587 memcpy(p
+1, sa
->un
.sun_path
+1, sizeof(sa
->un
.sun_path
)-1);
588 p
[sizeof(sa
->un
.sun_path
)] = 0;
591 p
= strndup(sa
->un
.sun_path
, sizeof(sa
->un
.sun_path
));
607 int getpeername_pretty(int fd
, char **ret
) {
608 union sockaddr_union sa
;
609 socklen_t salen
= sizeof(sa
);
615 if (getpeername(fd
, &sa
.sa
, &salen
) < 0)
618 if (sa
.sa
.sa_family
== AF_UNIX
) {
619 struct ucred ucred
= {};
621 /* UNIX connection sockets are anonymous, so let's use
622 * PID/UID as pretty credentials instead */
624 r
= getpeercred(fd
, &ucred
);
628 if (asprintf(ret
, "PID "PID_FMT
"/UID "UID_FMT
, ucred
.pid
, ucred
.uid
) < 0)
634 /* For remote sockets we translate IPv6 addresses back to IPv4
635 * if applicable, since that's nicer. */
637 return sockaddr_pretty(&sa
.sa
, salen
, true, true, ret
);
640 int getsockname_pretty(int fd
, char **ret
) {
641 union sockaddr_union sa
;
642 socklen_t salen
= sizeof(sa
);
647 if (getsockname(fd
, &sa
.sa
, &salen
) < 0)
650 /* For local sockets we do not translate IPv6 addresses back
651 * to IPv6 if applicable, since this is usually used for
652 * listening sockets where the difference between IPv4 and
655 return sockaddr_pretty(&sa
.sa
, salen
, false, true, ret
);
658 int socknameinfo_pretty(union sockaddr_union
*sa
, socklen_t salen
, char **_ret
) {
660 char host
[NI_MAXHOST
], *ret
;
664 r
= getnameinfo(&sa
->sa
, salen
, host
, sizeof(host
), NULL
, 0,
665 NI_IDN
|NI_IDN_USE_STD3_ASCII_RULES
);
667 int saved_errno
= errno
;
669 r
= sockaddr_pretty(&sa
->sa
, salen
, true, true, &ret
);
673 log_debug_errno(saved_errno
, "getnameinfo(%s) failed: %m", ret
);
684 int getnameinfo_pretty(int fd
, char **ret
) {
685 union sockaddr_union sa
;
686 socklen_t salen
= sizeof(sa
);
691 if (getsockname(fd
, &sa
.sa
, &salen
) < 0)
694 return socknameinfo_pretty(&sa
, salen
, ret
);
697 int socket_address_unlink(SocketAddress
*a
) {
700 if (socket_address_family(a
) != AF_UNIX
)
703 if (a
->sockaddr
.un
.sun_path
[0] == 0)
706 if (unlink(a
->sockaddr
.un
.sun_path
) < 0)
712 static const char* const netlink_family_table
[] = {
713 [NETLINK_ROUTE
] = "route",
714 [NETLINK_FIREWALL
] = "firewall",
715 [NETLINK_INET_DIAG
] = "inet-diag",
716 [NETLINK_NFLOG
] = "nflog",
717 [NETLINK_XFRM
] = "xfrm",
718 [NETLINK_SELINUX
] = "selinux",
719 [NETLINK_ISCSI
] = "iscsi",
720 [NETLINK_AUDIT
] = "audit",
721 [NETLINK_FIB_LOOKUP
] = "fib-lookup",
722 [NETLINK_CONNECTOR
] = "connector",
723 [NETLINK_NETFILTER
] = "netfilter",
724 [NETLINK_IP6_FW
] = "ip6-fw",
725 [NETLINK_DNRTMSG
] = "dnrtmsg",
726 [NETLINK_KOBJECT_UEVENT
] = "kobject-uevent",
727 [NETLINK_GENERIC
] = "generic",
728 [NETLINK_SCSITRANSPORT
] = "scsitransport",
729 [NETLINK_ECRYPTFS
] = "ecryptfs"
732 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family
, int, INT_MAX
);
734 static const char* const socket_address_bind_ipv6_only_table
[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX
] = {
735 [SOCKET_ADDRESS_DEFAULT
] = "default",
736 [SOCKET_ADDRESS_BOTH
] = "both",
737 [SOCKET_ADDRESS_IPV6_ONLY
] = "ipv6-only"
740 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only
, SocketAddressBindIPv6Only
);
742 bool sockaddr_equal(const union sockaddr_union
*a
, const union sockaddr_union
*b
) {
746 if (a
->sa
.sa_family
!= b
->sa
.sa_family
)
749 if (a
->sa
.sa_family
== AF_INET
)
750 return a
->in
.sin_addr
.s_addr
== b
->in
.sin_addr
.s_addr
;
752 if (a
->sa
.sa_family
== AF_INET6
)
753 return memcmp(&a
->in6
.sin6_addr
, &b
->in6
.sin6_addr
, sizeof(a
->in6
.sin6_addr
)) == 0;
758 int fd_inc_sndbuf(int fd
, size_t n
) {
760 socklen_t l
= sizeof(value
);
762 r
= getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, &l
);
763 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
766 /* If we have the privileges we will ignore the kernel limit. */
769 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUFFORCE
, &value
, sizeof(value
)) < 0)
770 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, sizeof(value
)) < 0)
776 int fd_inc_rcvbuf(int fd
, size_t n
) {
778 socklen_t l
= sizeof(value
);
780 r
= getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, &l
);
781 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
784 /* If we have the privileges we will ignore the kernel limit. */
787 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUFFORCE
, &value
, sizeof(value
)) < 0)
788 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, sizeof(value
)) < 0)
793 static const char* const ip_tos_table
[] = {
794 [IPTOS_LOWDELAY
] = "low-delay",
795 [IPTOS_THROUGHPUT
] = "throughput",
796 [IPTOS_RELIABILITY
] = "reliability",
797 [IPTOS_LOWCOST
] = "low-cost",
800 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos
, int, 0xff);
802 int getpeercred(int fd
, struct ucred
*ucred
) {
803 socklen_t n
= sizeof(struct ucred
);
810 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERCRED
, &u
, &n
);
814 if (n
!= sizeof(struct ucred
))
817 /* Check if the data is actually useful and not suppressed due
818 * to namespacing issues */
821 if (u
.uid
== UID_INVALID
)
823 if (u
.gid
== GID_INVALID
)
830 int getpeersec(int fd
, char **ret
) {
842 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
853 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
869 int send_one_fd(int transport_fd
, int fd
, int flags
) {
871 struct cmsghdr cmsghdr
;
872 uint8_t buf
[CMSG_SPACE(sizeof(int))];
875 .msg_control
= &control
,
876 .msg_controllen
= sizeof(control
),
878 struct cmsghdr
*cmsg
;
880 assert(transport_fd
>= 0);
883 cmsg
= CMSG_FIRSTHDR(&mh
);
884 cmsg
->cmsg_level
= SOL_SOCKET
;
885 cmsg
->cmsg_type
= SCM_RIGHTS
;
886 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
887 memcpy(CMSG_DATA(cmsg
), &fd
, sizeof(int));
889 mh
.msg_controllen
= CMSG_SPACE(sizeof(int));
890 if (sendmsg(transport_fd
, &mh
, MSG_NOSIGNAL
| flags
) < 0)
896 int receive_one_fd(int transport_fd
, int flags
) {
898 struct cmsghdr cmsghdr
;
899 uint8_t buf
[CMSG_SPACE(sizeof(int))];
902 .msg_control
= &control
,
903 .msg_controllen
= sizeof(control
),
905 struct cmsghdr
*cmsg
, *found
= NULL
;
907 assert(transport_fd
>= 0);
910 * Receive a single FD via @transport_fd. We don't care for
911 * the transport-type. We retrieve a single FD at most, so for
912 * packet-based transports, the caller must ensure to send
913 * only a single FD per packet. This is best used in
914 * combination with send_one_fd().
917 if (recvmsg(transport_fd
, &mh
, MSG_NOSIGNAL
| MSG_CMSG_CLOEXEC
| flags
) < 0)
920 CMSG_FOREACH(cmsg
, &mh
) {
921 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
922 cmsg
->cmsg_type
== SCM_RIGHTS
&&
923 cmsg
->cmsg_len
== CMSG_LEN(sizeof(int))) {
935 return *(int*) CMSG_DATA(found
);