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-util.h"
44 int socket_address_parse(SocketAddress
*a
, const char *s
) {
53 a
->type
= SOCK_STREAM
;
56 /* IPv6 in [x:.....:z]:p notation */
62 n
= strndupa(s
+1, e
-s
-1);
65 if (inet_pton(AF_INET6
, n
, &a
->sockaddr
.in6
.sin6_addr
) <= 0)
66 return errno
> 0 ? -errno
: -EINVAL
;
77 if (u
<= 0 || u
> 0xFFFF)
80 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
81 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
82 a
->size
= sizeof(struct sockaddr_in6
);
84 } else if (*s
== '/') {
90 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
))
93 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
94 memcpy(a
->sockaddr
.un
.sun_path
, s
, l
);
95 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + l
+ 1;
97 } else if (*s
== '@') {
98 /* Abstract AF_UNIX socket */
102 if (l
>= sizeof(a
->sockaddr
.un
.sun_path
) - 1)
105 a
->sockaddr
.un
.sun_family
= AF_UNIX
;
106 memcpy(a
->sockaddr
.un
.sun_path
+1, s
+1, l
);
107 a
->size
= offsetof(struct sockaddr_un
, sun_path
) + 1 + l
;
112 r
= safe_atou(e
+1, &u
);
116 if (u
<= 0 || u
> 0xFFFF)
119 n
= strndupa(s
, e
-s
);
121 /* IPv4 in w.x.y.z:p notation? */
122 r
= inet_pton(AF_INET
, n
, &a
->sockaddr
.in
.sin_addr
);
127 /* Gotcha, it's a traditional IPv4 address */
128 a
->sockaddr
.in
.sin_family
= AF_INET
;
129 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
130 a
->size
= sizeof(struct sockaddr_in
);
134 if (strlen(n
) > IF_NAMESIZE
-1)
137 /* Uh, our last resort, an interface name */
138 idx
= if_nametoindex(n
);
142 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
143 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
144 a
->sockaddr
.in6
.sin6_scope_id
= idx
;
145 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
146 a
->size
= sizeof(struct sockaddr_in6
);
151 r
= safe_atou(s
, &u
);
155 if (u
<= 0 || u
> 0xFFFF)
158 if (socket_ipv6_is_supported()) {
159 a
->sockaddr
.in6
.sin6_family
= AF_INET6
;
160 a
->sockaddr
.in6
.sin6_port
= htons((uint16_t) u
);
161 a
->sockaddr
.in6
.sin6_addr
= in6addr_any
;
162 a
->size
= sizeof(struct sockaddr_in6
);
164 a
->sockaddr
.in
.sin_family
= AF_INET
;
165 a
->sockaddr
.in
.sin_port
= htons((uint16_t) u
);
166 a
->sockaddr
.in
.sin_addr
.s_addr
= INADDR_ANY
;
167 a
->size
= sizeof(struct sockaddr_in
);
175 int socket_address_parse_and_warn(SocketAddress
*a
, const char *s
) {
179 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
181 r
= socket_address_parse(&b
, s
);
185 if (!socket_ipv6_is_supported() && b
.sockaddr
.sa
.sa_family
== AF_INET6
) {
186 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
187 return -EAFNOSUPPORT
;
194 int socket_address_parse_netlink(SocketAddress
*a
, const char *s
) {
197 _cleanup_free_
char *sfamily
= NULL
;
205 if (sscanf(s
, "%ms %u", &sfamily
, &group
) < 1)
206 return errno
> 0 ? -errno
: -EINVAL
;
208 family
= netlink_family_from_string(sfamily
);
212 a
->sockaddr
.nl
.nl_family
= AF_NETLINK
;
213 a
->sockaddr
.nl
.nl_groups
= group
;
216 a
->size
= sizeof(struct sockaddr_nl
);
217 a
->protocol
= family
;
222 int socket_address_verify(const SocketAddress
*a
) {
225 switch (socket_address_family(a
)) {
228 if (a
->size
!= sizeof(struct sockaddr_in
))
231 if (a
->sockaddr
.in
.sin_port
== 0)
234 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
240 if (a
->size
!= sizeof(struct sockaddr_in6
))
243 if (a
->sockaddr
.in6
.sin6_port
== 0)
246 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
)
252 if (a
->size
< offsetof(struct sockaddr_un
, sun_path
))
255 if (a
->size
> offsetof(struct sockaddr_un
, sun_path
)) {
257 if (a
->sockaddr
.un
.sun_path
[0] != 0) {
261 e
= memchr(a
->sockaddr
.un
.sun_path
, 0, sizeof(a
->sockaddr
.un
.sun_path
));
265 if (a
->size
!= offsetof(struct sockaddr_un
, sun_path
) + (e
- a
->sockaddr
.un
.sun_path
) + 1)
270 if (a
->type
!= SOCK_STREAM
&& a
->type
!= SOCK_DGRAM
&& a
->type
!= SOCK_SEQPACKET
)
277 if (a
->size
!= sizeof(struct sockaddr_nl
))
280 if (a
->type
!= SOCK_RAW
&& a
->type
!= SOCK_DGRAM
)
286 return -EAFNOSUPPORT
;
290 int socket_address_print(const SocketAddress
*a
, char **ret
) {
296 r
= socket_address_verify(a
);
300 if (socket_address_family(a
) == AF_NETLINK
) {
301 _cleanup_free_
char *sfamily
= NULL
;
303 r
= netlink_family_to_string_alloc(a
->protocol
, &sfamily
);
307 r
= asprintf(ret
, "%s %u", sfamily
, a
->sockaddr
.nl
.nl_groups
);
314 return sockaddr_pretty(&a
->sockaddr
.sa
, a
->size
, false, true, ret
);
317 bool socket_address_can_accept(const SocketAddress
*a
) {
321 a
->type
== SOCK_STREAM
||
322 a
->type
== SOCK_SEQPACKET
;
325 bool socket_address_equal(const SocketAddress
*a
, const SocketAddress
*b
) {
329 /* Invalid addresses are unequal to all */
330 if (socket_address_verify(a
) < 0 ||
331 socket_address_verify(b
) < 0)
334 if (a
->type
!= b
->type
)
337 if (socket_address_family(a
) != socket_address_family(b
))
340 switch (socket_address_family(a
)) {
343 if (a
->sockaddr
.in
.sin_addr
.s_addr
!= b
->sockaddr
.in
.sin_addr
.s_addr
)
346 if (a
->sockaddr
.in
.sin_port
!= b
->sockaddr
.in
.sin_port
)
352 if (memcmp(&a
->sockaddr
.in6
.sin6_addr
, &b
->sockaddr
.in6
.sin6_addr
, sizeof(a
->sockaddr
.in6
.sin6_addr
)) != 0)
355 if (a
->sockaddr
.in6
.sin6_port
!= b
->sockaddr
.in6
.sin6_port
)
361 if (a
->size
<= offsetof(struct sockaddr_un
, sun_path
) ||
362 b
->size
<= offsetof(struct sockaddr_un
, sun_path
))
365 if ((a
->sockaddr
.un
.sun_path
[0] == 0) != (b
->sockaddr
.un
.sun_path
[0] == 0))
368 if (a
->sockaddr
.un
.sun_path
[0]) {
369 if (!path_equal_or_files_same(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
))
372 if (a
->size
!= b
->size
)
375 if (memcmp(a
->sockaddr
.un
.sun_path
, b
->sockaddr
.un
.sun_path
, a
->size
) != 0)
382 if (a
->protocol
!= b
->protocol
)
385 if (a
->sockaddr
.nl
.nl_groups
!= b
->sockaddr
.nl
.nl_groups
)
391 /* Cannot compare, so we assume the addresses are different */
398 bool socket_address_is(const SocketAddress
*a
, const char *s
, int type
) {
399 struct SocketAddress b
;
404 if (socket_address_parse(&b
, s
) < 0)
409 return socket_address_equal(a
, &b
);
412 bool socket_address_is_netlink(const SocketAddress
*a
, const char *s
) {
413 struct SocketAddress b
;
418 if (socket_address_parse_netlink(&b
, s
) < 0)
421 return socket_address_equal(a
, &b
);
424 const char* socket_address_get_path(const SocketAddress
*a
) {
427 if (socket_address_family(a
) != AF_UNIX
)
430 if (a
->sockaddr
.un
.sun_path
[0] == 0)
433 return a
->sockaddr
.un
.sun_path
;
436 bool socket_ipv6_is_supported(void) {
437 _cleanup_free_
char *l
= NULL
;
439 if (access("/sys/module/ipv6", F_OK
) != 0)
442 /* If we can't check "disable" parameter, assume enabled */
443 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l
) < 0)
446 /* If module was loaded with disable=1 no IPv6 available */
450 bool socket_address_matches_fd(const SocketAddress
*a
, int fd
) {
457 b
.size
= sizeof(b
.sockaddr
);
458 if (getsockname(fd
, &b
.sockaddr
.sa
, &b
.size
) < 0)
461 if (b
.sockaddr
.sa
.sa_family
!= a
->sockaddr
.sa
.sa_family
)
464 solen
= sizeof(b
.type
);
465 if (getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, &b
.type
, &solen
) < 0)
468 if (b
.type
!= a
->type
)
471 if (a
->protocol
!= 0) {
472 solen
= sizeof(b
.protocol
);
473 if (getsockopt(fd
, SOL_SOCKET
, SO_PROTOCOL
, &b
.protocol
, &solen
) < 0)
476 if (b
.protocol
!= a
->protocol
)
480 return socket_address_equal(a
, &b
);
483 int sockaddr_port(const struct sockaddr
*_sa
) {
484 union sockaddr_union
*sa
= (union sockaddr_union
*) _sa
;
488 if (!IN_SET(sa
->sa
.sa_family
, AF_INET
, AF_INET6
))
489 return -EAFNOSUPPORT
;
491 return ntohs(sa
->sa
.sa_family
== AF_INET6
?
496 int sockaddr_pretty(const struct sockaddr
*_sa
, socklen_t salen
, bool translate_ipv6
, bool include_port
, char **ret
) {
497 union sockaddr_union
*sa
= (union sockaddr_union
*) _sa
;
502 assert(salen
>= sizeof(sa
->sa
.sa_family
));
504 switch (sa
->sa
.sa_family
) {
509 a
= ntohl(sa
->in
.sin_addr
.s_addr
);
514 a
>> 24, (a
>> 16) & 0xFF, (a
>> 8) & 0xFF, a
& 0xFF,
515 ntohs(sa
->in
.sin_port
));
519 a
>> 24, (a
>> 16) & 0xFF, (a
>> 8) & 0xFF, a
& 0xFF);
526 static const unsigned char ipv4_prefix
[] = {
527 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
530 if (translate_ipv6
&&
531 memcmp(&sa
->in6
.sin6_addr
, ipv4_prefix
, sizeof(ipv4_prefix
)) == 0) {
532 const uint8_t *a
= sa
->in6
.sin6_addr
.s6_addr
+12;
536 a
[0], a
[1], a
[2], a
[3],
537 ntohs(sa
->in6
.sin6_port
));
541 a
[0], a
[1], a
[2], a
[3]);
545 char a
[INET6_ADDRSTRLEN
];
547 inet_ntop(AF_INET6
, &sa
->in6
.sin6_addr
, a
, sizeof(a
));
553 ntohs(sa
->in6
.sin6_port
));
567 if (salen
<= offsetof(struct sockaddr_un
, sun_path
)) {
568 p
= strdup("<unnamed>");
572 } else if (sa
->un
.sun_path
[0] == 0) {
575 /* FIXME: We assume we can print the
576 * socket path here and that it hasn't
577 * more than one NUL byte. That is
578 * actually an invalid assumption */
580 p
= new(char, sizeof(sa
->un
.sun_path
)+1);
585 memcpy(p
+1, sa
->un
.sun_path
+1, sizeof(sa
->un
.sun_path
)-1);
586 p
[sizeof(sa
->un
.sun_path
)] = 0;
589 p
= strndup(sa
->un
.sun_path
, sizeof(sa
->un
.sun_path
));
605 int getpeername_pretty(int fd
, char **ret
) {
606 union sockaddr_union sa
;
607 socklen_t salen
= sizeof(sa
);
613 if (getpeername(fd
, &sa
.sa
, &salen
) < 0)
616 if (sa
.sa
.sa_family
== AF_UNIX
) {
617 struct ucred ucred
= {};
619 /* UNIX connection sockets are anonymous, so let's use
620 * PID/UID as pretty credentials instead */
622 r
= getpeercred(fd
, &ucred
);
626 if (asprintf(ret
, "PID "PID_FMT
"/UID "UID_FMT
, ucred
.pid
, ucred
.uid
) < 0)
632 /* For remote sockets we translate IPv6 addresses back to IPv4
633 * if applicable, since that's nicer. */
635 return sockaddr_pretty(&sa
.sa
, salen
, true, true, ret
);
638 int getsockname_pretty(int fd
, char **ret
) {
639 union sockaddr_union sa
;
640 socklen_t salen
= sizeof(sa
);
645 if (getsockname(fd
, &sa
.sa
, &salen
) < 0)
648 /* For local sockets we do not translate IPv6 addresses back
649 * to IPv6 if applicable, since this is usually used for
650 * listening sockets where the difference between IPv4 and
653 return sockaddr_pretty(&sa
.sa
, salen
, false, true, ret
);
656 int socknameinfo_pretty(union sockaddr_union
*sa
, socklen_t salen
, char **_ret
) {
658 char host
[NI_MAXHOST
], *ret
;
662 r
= getnameinfo(&sa
->sa
, salen
, host
, sizeof(host
), NULL
, 0,
663 NI_IDN
|NI_IDN_USE_STD3_ASCII_RULES
);
665 int saved_errno
= errno
;
667 r
= sockaddr_pretty(&sa
->sa
, salen
, true, true, &ret
);
671 log_debug_errno(saved_errno
, "getnameinfo(%s) failed: %m", ret
);
682 int getnameinfo_pretty(int fd
, char **ret
) {
683 union sockaddr_union sa
;
684 socklen_t salen
= sizeof(sa
);
689 if (getsockname(fd
, &sa
.sa
, &salen
) < 0)
692 return socknameinfo_pretty(&sa
, salen
, ret
);
695 int socket_address_unlink(SocketAddress
*a
) {
698 if (socket_address_family(a
) != AF_UNIX
)
701 if (a
->sockaddr
.un
.sun_path
[0] == 0)
704 if (unlink(a
->sockaddr
.un
.sun_path
) < 0)
710 static const char* const netlink_family_table
[] = {
711 [NETLINK_ROUTE
] = "route",
712 [NETLINK_FIREWALL
] = "firewall",
713 [NETLINK_INET_DIAG
] = "inet-diag",
714 [NETLINK_NFLOG
] = "nflog",
715 [NETLINK_XFRM
] = "xfrm",
716 [NETLINK_SELINUX
] = "selinux",
717 [NETLINK_ISCSI
] = "iscsi",
718 [NETLINK_AUDIT
] = "audit",
719 [NETLINK_FIB_LOOKUP
] = "fib-lookup",
720 [NETLINK_CONNECTOR
] = "connector",
721 [NETLINK_NETFILTER
] = "netfilter",
722 [NETLINK_IP6_FW
] = "ip6-fw",
723 [NETLINK_DNRTMSG
] = "dnrtmsg",
724 [NETLINK_KOBJECT_UEVENT
] = "kobject-uevent",
725 [NETLINK_GENERIC
] = "generic",
726 [NETLINK_SCSITRANSPORT
] = "scsitransport",
727 [NETLINK_ECRYPTFS
] = "ecryptfs"
730 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family
, int, INT_MAX
);
732 static const char* const socket_address_bind_ipv6_only_table
[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX
] = {
733 [SOCKET_ADDRESS_DEFAULT
] = "default",
734 [SOCKET_ADDRESS_BOTH
] = "both",
735 [SOCKET_ADDRESS_IPV6_ONLY
] = "ipv6-only"
738 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only
, SocketAddressBindIPv6Only
);
740 bool sockaddr_equal(const union sockaddr_union
*a
, const union sockaddr_union
*b
) {
744 if (a
->sa
.sa_family
!= b
->sa
.sa_family
)
747 if (a
->sa
.sa_family
== AF_INET
)
748 return a
->in
.sin_addr
.s_addr
== b
->in
.sin_addr
.s_addr
;
750 if (a
->sa
.sa_family
== AF_INET6
)
751 return memcmp(&a
->in6
.sin6_addr
, &b
->in6
.sin6_addr
, sizeof(a
->in6
.sin6_addr
)) == 0;
756 int fd_inc_sndbuf(int fd
, size_t n
) {
758 socklen_t l
= sizeof(value
);
760 r
= getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, &l
);
761 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
764 /* If we have the privileges we will ignore the kernel limit. */
767 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUFFORCE
, &value
, sizeof(value
)) < 0)
768 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &value
, sizeof(value
)) < 0)
774 int fd_inc_rcvbuf(int fd
, size_t n
) {
776 socklen_t l
= sizeof(value
);
778 r
= getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, &l
);
779 if (r
>= 0 && l
== sizeof(value
) && (size_t) value
>= n
*2)
782 /* If we have the privileges we will ignore the kernel limit. */
785 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUFFORCE
, &value
, sizeof(value
)) < 0)
786 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &value
, sizeof(value
)) < 0)
791 static const char* const ip_tos_table
[] = {
792 [IPTOS_LOWDELAY
] = "low-delay",
793 [IPTOS_THROUGHPUT
] = "throughput",
794 [IPTOS_RELIABILITY
] = "reliability",
795 [IPTOS_LOWCOST
] = "low-cost",
798 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos
, int, 0xff);
800 int getpeercred(int fd
, struct ucred
*ucred
) {
801 socklen_t n
= sizeof(struct ucred
);
808 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERCRED
, &u
, &n
);
812 if (n
!= sizeof(struct ucred
))
815 /* Check if the data is actually useful and not suppressed due
816 * to namespacing issues */
819 if (u
.uid
== UID_INVALID
)
821 if (u
.gid
== GID_INVALID
)
828 int getpeersec(int fd
, char **ret
) {
840 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
851 r
= getsockopt(fd
, SOL_SOCKET
, SO_PEERSEC
, s
, &n
);
867 int send_one_fd(int transport_fd
, int fd
, int flags
) {
869 struct cmsghdr cmsghdr
;
870 uint8_t buf
[CMSG_SPACE(sizeof(int))];
873 .msg_control
= &control
,
874 .msg_controllen
= sizeof(control
),
876 struct cmsghdr
*cmsg
;
878 assert(transport_fd
>= 0);
881 cmsg
= CMSG_FIRSTHDR(&mh
);
882 cmsg
->cmsg_level
= SOL_SOCKET
;
883 cmsg
->cmsg_type
= SCM_RIGHTS
;
884 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
885 memcpy(CMSG_DATA(cmsg
), &fd
, sizeof(int));
887 mh
.msg_controllen
= CMSG_SPACE(sizeof(int));
888 if (sendmsg(transport_fd
, &mh
, MSG_NOSIGNAL
| flags
) < 0)
894 int receive_one_fd(int transport_fd
, int flags
) {
896 struct cmsghdr cmsghdr
;
897 uint8_t buf
[CMSG_SPACE(sizeof(int))];
900 .msg_control
= &control
,
901 .msg_controllen
= sizeof(control
),
903 struct cmsghdr
*cmsg
, *found
= NULL
;
905 assert(transport_fd
>= 0);
908 * Receive a single FD via @transport_fd. We don't care for
909 * the transport-type. We retrieve a single FD at most, so for
910 * packet-based transports, the caller must ensure to send
911 * only a single FD per packet. This is best used in
912 * combination with send_one_fd().
915 if (recvmsg(transport_fd
, &mh
, MSG_NOSIGNAL
| MSG_CMSG_CLOEXEC
| flags
) < 0)
918 CMSG_FOREACH(cmsg
, &mh
) {
919 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
920 cmsg
->cmsg_type
== SCM_RIGHTS
&&
921 cmsg
->cmsg_len
== CMSG_LEN(sizeof(int))) {
933 return *(int*) CMSG_DATA(found
);