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 "path-util.h"
39 #include "socket-util.h"
40 #include "string-util.h"
43 int socket_address_parse(SocketAddress
*a
, const char *s
) {
52 a
->type
= SOCK_STREAM
;
55 /* IPv6 in [x:.....:z]:p notation */
61 n
= strndupa(s
+1, e
-s
-1);
64 if (inet_pton(AF_INET6
, n
, &a
->sockaddr
.in6
.sin6_addr
) <= 0)
65 return errno
> 0 ? -errno
: -EINVAL
;
76 if (u
<= 0 || u
> 0xFFFF)
79 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
80 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
81 a
->size
= sizeof(struct sockaddr_in6
);
83 } else if (*s
== '/') {
89 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
))
92 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
93 memcpy(a
->sockaddr
.un
.sun_path
, s
, l
);
94 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + l
+ 1;
96 } else if (*s
== '@') {
97 /* Abstract AF_UNIX socket */
101 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
) - 1)
104 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
105 memcpy(a
->sockaddr
.un
.sun_path
+1, s
+1, l
);
106 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + 1 + l
;
111 r
= safe_atou(e
+1, &u
);
115 if (u
<= 0 || u
> 0xFFFF)
118 n
= strndupa(s
, e
-s
);
120 /* IPv4 in w.x.y.z:p notation? */
121 r
= inet_pton(AF_INET
, n
, &a
->sockaddr
.in
.sin_addr
);
126 /* Gotcha, it's a traditional IPv4 address */
127 a
->sockaddr
.in
.sin_family
= AF_INET
;
128 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
129 a
->size
= sizeof(struct sockaddr_in
);
133 if (strlen(n
) > IF_NAMESIZE
-1)
136 /* Uh, our last resort, an interface name */
137 idx
= if_nametoindex(n
);
141 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
142 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
143 a
->sockaddr
.in6
.sin6_scope_id
= idx
;
144 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
145 a
->size
= sizeof(struct sockaddr_in6
);
150 r
= safe_atou(s
, &u
);
154 if (u
<= 0 || u
> 0xFFFF)
157 if (socket_ipv6_is_supported()) {
158 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
159 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
160 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
161 a
->size
= sizeof(struct sockaddr_in6
);
163 a
->sockaddr
.in
.sin_family
= AF_INET
;
164 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
165 a
->sockaddr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
166 a
->size
= sizeof(struct sockaddr_in
);
174 int socket_address_parse_and_warn(SocketAddress
*a
, const char *s
) {
178 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
180 r
= socket_address_parse(&b
, s
);
184 if (!socket_ipv6_is_supported() && b
.sockaddr
.sa
.sa_family
== AF_INET6
) {
185 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
186 return -EAFNOSUPPORT
;
193 int socket_address_parse_netlink(SocketAddress
*a
, const char *s
) {
196 _cleanup_free_
char *sfamily
= NULL
;
204 if (sscanf(s
, "%ms %u", &sfamily
, &group
) < 1)
205 return errno
> 0 ? -errno
: -EINVAL
;
207 family
= netlink_family_from_string(sfamily
);
211 a
->sockaddr
.nl
.nl_family
= AF_NETLINK
;
212 a
->sockaddr
.nl
.nl_groups
= group
;
215 a
->size
= sizeof(struct sockaddr_nl
);
216 a
->protocol
= family
;
221 int socket_address_verify(const SocketAddress
*a
) {
224 switch (socket_address_family(a
)) {
227 if (a
->size
!= sizeof(struct sockaddr_in
))
230 if (a
->sockaddr
.in
.sin_port
== 0)
233 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
239 if (a
->size
!= sizeof(struct sockaddr_in6
))
242 if (a
->sockaddr
.in6
.sin6_port
== 0)
245 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
251 if (a
->size
< offsetof(struct sockaddr_un
, sun_path
))
254 if (a
->size
> offsetof(struct sockaddr_un
, sun_path
)) {
256 if (a
->sockaddr
.un
.sun_path
[0] != 0) {
260 e
= memchr(a
->sockaddr
.un
.sun_path
, 0, sizeof(a
->sockaddr
.un
.sun_path
));
264 if (a
->size
!= offsetof(struct sockaddr_un
, sun_path
) + (e
- a
->sockaddr
.un
.sun_path
) + 1)
269 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
&& a
->type
!= SOCK_SEQPACKET
)
276 if (a
->size
!= sizeof(struct sockaddr_nl
))
279 if (a
->type
!= SOCK_RAW
&& a
->type
!= SOCK_DGRAM
)
285 return -EAFNOSUPPORT
;
289 int socket_address_print(const SocketAddress
*a
, char **ret
) {
295 r
= socket_address_verify(a
);
299 if (socket_address_family(a
) == AF_NETLINK
) {
300 _cleanup_free_
char *sfamily
= NULL
;
302 r
= netlink_family_to_string_alloc(a
->protocol
, &sfamily
);
306 r
= asprintf(ret
, "%s %u", sfamily
, a
->sockaddr
.nl
.nl_groups
);
313 return sockaddr_pretty(&a
->sockaddr
.sa
, a
->size
, false, true, ret
);
316 bool socket_address_can_accept(const SocketAddress
*a
) {
320 a
->type
== SOCK_STREAM
||
321 a
->type
== SOCK_SEQPACKET
;
324 bool socket_address_equal(const SocketAddress
*a
, const SocketAddress
*b
) {
328 /* Invalid addresses are unequal to all */
329 if (socket_address_verify(a
) < 0 ||
330 socket_address_verify(b
) < 0)
333 if (a
->type
!= b
->type
)
336 if (socket_address_family(a
) != socket_address_family(b
))
339 switch (socket_address_family(a
)) {
342 if (a
->sockaddr
.in
.sin_addr
.s_addr
!= b
->sockaddr
.in
.sin_addr
.s_addr
)
345 if (a
->sockaddr
.in
.sin_port
!= b
->sockaddr
.in
.sin_port
)
351 if (memcmp(&a
->sockaddr
.in6
.sin6_addr
, &b
->sockaddr
.in6
.sin6_addr
, sizeof(a
->sockaddr
.in6
.sin6_addr
)) != 0)
354 if (a
->sockaddr
.in6
.sin6_port
!= b
->sockaddr
.in6
.sin6_port
)
360 if (a
->size
<= offsetof(struct sockaddr_un
, sun_path
) ||
361 b
->size
<= offsetof(struct sockaddr_un
, sun_path
))
364 if ((a
->sockaddr
.un
.sun_path
[0] == 0) != (b
->sockaddr
.un
.sun_path
[0] == 0))
367 if (a
->sockaddr
.un
.sun_path
[0]) {
368 if (!path_equal_or_files_same(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
))
371 if (a
->size
!= b
->size
)
374 if (memcmp(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
, a
->size
) != 0)
381 if (a
->protocol
!= b
->protocol
)
384 if (a
->sockaddr
.nl
.nl_groups
!= b
->sockaddr
.nl
.nl_groups
)
390 /* Cannot compare, so we assume the addresses are different */
397 bool socket_address_is(const SocketAddress
*a
, const char *s
, int type
) {
398 struct SocketAddress b
;
403 if (socket_address_parse(&b
, s
) < 0)
408 return socket_address_equal(a
, &b
);
411 bool socket_address_is_netlink(const SocketAddress
*a
, const char *s
) {
412 struct SocketAddress b
;
417 if (socket_address_parse_netlink(&b
, s
) < 0)
420 return socket_address_equal(a
, &b
);
423 const char* socket_address_get_path(const SocketAddress
*a
) {
426 if (socket_address_family(a
) != AF_UNIX
)
429 if (a
->sockaddr
.un
.sun_path
[0] == 0)
432 return a
->sockaddr
.un
.sun_path
;
435 bool socket_ipv6_is_supported(void) {
436 _cleanup_free_
char *l
= NULL
;
438 if (access("/sys/module/ipv6", F_OK
) != 0)
441 /* If we can't check "disable" parameter, assume enabled */
442 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l
) < 0)
445 /* If module was loaded with disable=1 no IPv6 available */
449 bool socket_address_matches_fd(const SocketAddress
*a
, int fd
) {
456 b
.size
= sizeof(b
.sockaddr
);
457 if (getsockname(fd
, &b
.sockaddr
.sa
, &b
.size
) < 0)
460 if (b
.sockaddr
.sa
.sa_family
!= a
->sockaddr
.sa
.sa_family
)
463 solen
= sizeof(b
.type
);
464 if (getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, &b
.type
, &solen
) < 0)
467 if (b
.type
!= a
->type
)
470 if (a
->protocol
!= 0) {
471 solen
= sizeof(b
.protocol
);
472 if (getsockopt(fd
, SOL_SOCKET
, SO_PROTOCOL
, &b
.protocol
, &solen
) < 0)
475 if (b
.protocol
!= a
->protocol
)
479 return socket_address_equal(a
, &b
);
482 int sockaddr_port(const struct sockaddr
*_sa
) {
483 union sockaddr_union
*sa
= (union sockaddr_union
*) _sa
;
487 if (!IN_SET(sa
->sa
.sa_family
, AF_INET
, AF_INET6
))
488 return -EAFNOSUPPORT
;
490 return ntohs(sa
->sa
.sa_family
== AF_INET6
?
495 int sockaddr_pretty(const struct sockaddr
*_sa
, socklen_t salen
, bool translate_ipv6
, bool include_port
, char **ret
) {
496 union sockaddr_union
*sa
= (union sockaddr_union
*) _sa
;
501 assert(salen
>= sizeof(sa
->sa
.sa_family
));
503 switch (sa
->sa
.sa_family
) {
508 a
= ntohl(sa
->in
.sin_addr
.s_addr
);
513 a
>> 24, (a
>> 16) & 0xFF, (a
>> 8) & 0xFF, a
& 0xFF,
514 ntohs(sa
->in
.sin_port
));
518 a
>> 24, (a
>> 16) & 0xFF, (a
>> 8) & 0xFF, a
& 0xFF);
525 static const unsigned char ipv4_prefix
[] = {
526 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
529 if (translate_ipv6
&&
530 memcmp(&sa
->in6
.sin6_addr
, ipv4_prefix
, sizeof(ipv4_prefix
)) == 0) {
531 const uint8_t *a
= sa
->in6
.sin6_addr
.s6_addr
+12;
535 a
[0], a
[1], a
[2], a
[3],
536 ntohs(sa
->in6
.sin6_port
));
540 a
[0], a
[1], a
[2], a
[3]);
544 char a
[INET6_ADDRSTRLEN
];
546 inet_ntop(AF_INET6
, &sa
->in6
.sin6_addr
, a
, sizeof(a
));
552 ntohs(sa
->in6
.sin6_port
));
566 if (salen
<= offsetof(struct sockaddr_un
, sun_path
)) {
567 p
= strdup("<unnamed>");
571 } else if (sa
->un
.sun_path
[0] == 0) {
574 /* FIXME: We assume we can print the
575 * socket path here and that it hasn't
576 * more than one NUL byte. That is
577 * actually an invalid assumption */
579 p
= new(char, sizeof(sa
->un
.sun_path
)+1);
584 memcpy(p
+1, sa
->un
.sun_path
+1, sizeof(sa
->un
.sun_path
)-1);
585 p
[sizeof(sa
->un
.sun_path
)] = 0;
588 p
= strndup(sa
->un
.sun_path
, sizeof(sa
->un
.sun_path
));
604 int getpeername_pretty(int fd
, char **ret
) {
605 union sockaddr_union sa
;
606 socklen_t salen
= sizeof(sa
);
612 if (getpeername(fd
, &sa
.sa
, &salen
) < 0)
615 if (sa
.sa
.sa_family
== AF_UNIX
) {
616 struct ucred ucred
= {};
618 /* UNIX connection sockets are anonymous, so let's use
619 * PID/UID as pretty credentials instead */
621 r
= getpeercred(fd
, &ucred
);
625 if (asprintf(ret
, "PID "PID_FMT
"/UID "UID_FMT
, ucred
.pid
, ucred
.uid
) < 0)
631 /* For remote sockets we translate IPv6 addresses back to IPv4
632 * if applicable, since that's nicer. */
634 return sockaddr_pretty(&sa
.sa
, salen
, true, true, ret
);
637 int getsockname_pretty(int fd
, char **ret
) {
638 union sockaddr_union sa
;
639 socklen_t salen
= sizeof(sa
);
644 if (getsockname(fd
, &sa
.sa
, &salen
) < 0)
647 /* For local sockets we do not translate IPv6 addresses back
648 * to IPv6 if applicable, since this is usually used for
649 * listening sockets where the difference between IPv4 and
652 return sockaddr_pretty(&sa
.sa
, salen
, false, true, ret
);
655 int socknameinfo_pretty(union sockaddr_union
*sa
, socklen_t salen
, char **_ret
) {
657 char host
[NI_MAXHOST
], *ret
;
661 r
= getnameinfo(&sa
->sa
, salen
, host
, sizeof(host
), NULL
, 0,
662 NI_IDN
|NI_IDN_USE_STD3_ASCII_RULES
);
664 int saved_errno
= errno
;
666 r
= sockaddr_pretty(&sa
->sa
, salen
, true, true, &ret
);
670 log_debug_errno(saved_errno
, "getnameinfo(%s) failed: %m", ret
);
681 int getnameinfo_pretty(int fd
, char **ret
) {
682 union sockaddr_union sa
;
683 socklen_t salen
= sizeof(sa
);
688 if (getsockname(fd
, &sa
.sa
, &salen
) < 0)
691 return socknameinfo_pretty(&sa
, salen
, ret
);
694 int socket_address_unlink(SocketAddress
*a
) {
697 if (socket_address_family(a
) != AF_UNIX
)
700 if (a
->sockaddr
.un
.sun_path
[0] == 0)
703 if (unlink(a
->sockaddr
.un
.sun_path
) < 0)
709 static const char* const netlink_family_table
[] = {
710 [NETLINK_ROUTE
] = "route",
711 [NETLINK_FIREWALL
] = "firewall",
712 [NETLINK_INET_DIAG
] = "inet-diag",
713 [NETLINK_NFLOG
] = "nflog",
714 [NETLINK_XFRM
] = "xfrm",
715 [NETLINK_SELINUX
] = "selinux",
716 [NETLINK_ISCSI
] = "iscsi",
717 [NETLINK_AUDIT
] = "audit",
718 [NETLINK_FIB_LOOKUP
] = "fib-lookup",
719 [NETLINK_CONNECTOR
] = "connector",
720 [NETLINK_NETFILTER
] = "netfilter",
721 [NETLINK_IP6_FW
] = "ip6-fw",
722 [NETLINK_DNRTMSG
] = "dnrtmsg",
723 [NETLINK_KOBJECT_UEVENT
] = "kobject-uevent",
724 [NETLINK_GENERIC
] = "generic",
725 [NETLINK_SCSITRANSPORT
] = "scsitransport",
726 [NETLINK_ECRYPTFS
] = "ecryptfs"
729 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family
, int, INT_MAX
);
731 static const char* const socket_address_bind_ipv6_only_table
[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX
] = {
732 [SOCKET_ADDRESS_DEFAULT
] = "default",
733 [SOCKET_ADDRESS_BOTH
] = "both",
734 [SOCKET_ADDRESS_IPV6_ONLY
] = "ipv6-only"
737 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only
, SocketAddressBindIPv6Only
);
739 bool sockaddr_equal(const union sockaddr_union
*a
, const union sockaddr_union
*b
) {
743 if (a
->sa
.sa_family
!= b
->sa
.sa_family
)
746 if (a
->sa
.sa_family
== AF_INET
)
747 return a
->in
.sin_addr
.s_addr
== b
->in
.sin_addr
.s_addr
;
749 if (a
->sa
.sa_family
== AF_INET6
)
750 return memcmp(&a
->in6
.sin6_addr
, &b
->in6
.sin6_addr
, sizeof(a
->in6
.sin6_addr
)) == 0;
755 int fd_inc_sndbuf(int fd
, size_t n
) {
757 socklen_t l
= sizeof(value
);
759 r
= getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, &l
);
760 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
763 /* If we have the privileges we will ignore the kernel limit. */
766 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUFFORCE
, &value
, sizeof(value
)) < 0)
767 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, sizeof(value
)) < 0)
773 int fd_inc_rcvbuf(int fd
, size_t n
) {
775 socklen_t l
= sizeof(value
);
777 r
= getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, &l
);
778 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
781 /* If we have the privileges we will ignore the kernel limit. */
784 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUFFORCE
, &value
, sizeof(value
)) < 0)
785 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, sizeof(value
)) < 0)
790 static const char* const ip_tos_table
[] = {
791 [IPTOS_LOWDELAY
] = "low-delay",
792 [IPTOS_THROUGHPUT
] = "throughput",
793 [IPTOS_RELIABILITY
] = "reliability",
794 [IPTOS_LOWCOST
] = "low-cost",
797 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos
, int, 0xff);
799 int getpeercred(int fd
, struct ucred
*ucred
) {
800 socklen_t n
= sizeof(struct ucred
);
807 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERCRED
, &u
, &n
);
811 if (n
!= sizeof(struct ucred
))
814 /* Check if the data is actually useful and not suppressed due
815 * to namespacing issues */
818 if (u
.uid
== UID_INVALID
)
820 if (u
.gid
== GID_INVALID
)
827 int getpeersec(int fd
, char **ret
) {
839 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
850 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
866 int send_one_fd(int transport_fd
, int fd
, int flags
) {
868 struct cmsghdr cmsghdr
;
869 uint8_t buf
[CMSG_SPACE(sizeof(int))];
872 .msg_control
= &control
,
873 .msg_controllen
= sizeof(control
),
875 struct cmsghdr
*cmsg
;
877 assert(transport_fd
>= 0);
880 cmsg
= CMSG_FIRSTHDR(&mh
);
881 cmsg
->cmsg_level
= SOL_SOCKET
;
882 cmsg
->cmsg_type
= SCM_RIGHTS
;
883 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
884 memcpy(CMSG_DATA(cmsg
), &fd
, sizeof(int));
886 mh
.msg_controllen
= CMSG_SPACE(sizeof(int));
887 if (sendmsg(transport_fd
, &mh
, MSG_NOSIGNAL
| flags
) < 0)
893 int receive_one_fd(int transport_fd
, int flags
) {
895 struct cmsghdr cmsghdr
;
896 uint8_t buf
[CMSG_SPACE(sizeof(int))];
899 .msg_control
= &control
,
900 .msg_controllen
= sizeof(control
),
902 struct cmsghdr
*cmsg
, *found
= NULL
;
904 assert(transport_fd
>= 0);
907 * Receive a single FD via @transport_fd. We don't care for
908 * the transport-type. We retrieve a single FD at most, so for
909 * packet-based transports, the caller must ensure to send
910 * only a single FD per packet. This is best used in
911 * combination with send_one_fd().
914 if (recvmsg(transport_fd
, &mh
, MSG_NOSIGNAL
| MSG_CMSG_CLOEXEC
| flags
) < 0)
917 CMSG_FOREACH(cmsg
, &mh
) {
918 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
919 cmsg
->cmsg_type
== SCM_RIGHTS
&&
920 cmsg
->cmsg_len
== CMSG_LEN(sizeof(int))) {
932 return *(int*) CMSG_DATA(found
);