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/>.
27 #include <arpa/inet.h>
30 #include <sys/types.h>
33 #include <sys/ioctl.h>
39 #include "path-util.h"
40 #include "socket-util.h"
44 int socket_address_parse(SocketAddress *a, const char *s) {
53 a->type = SOCK_STREAM;
56 /* IPv6 in [x:.....:z]:p notation */
58 if (!socket_ipv6_is_supported()) {
59 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
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 if (!socket_ipv6_is_supported()) {
148 log_warning("Binding to interface is not available since kernel does not support IPv6.");
149 return -EAFNOSUPPORT;
152 a->sockaddr.in6.sin6_family = AF_INET6;
153 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
154 a->sockaddr.in6.sin6_scope_id = idx;
155 a->sockaddr.in6.sin6_addr = in6addr_any;
156 a->size = sizeof(struct sockaddr_in6);
161 r = safe_atou(s, &u);
165 if (u <= 0 || u > 0xFFFF)
168 if (socket_ipv6_is_supported()) {
169 a->sockaddr.in6.sin6_family = AF_INET6;
170 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
171 a->sockaddr.in6.sin6_addr = in6addr_any;
172 a->size = sizeof(struct sockaddr_in6);
174 a->sockaddr.in.sin_family = AF_INET;
175 a->sockaddr.in.sin_port = htons((uint16_t) u);
176 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
177 a->size = sizeof(struct sockaddr_in);
185 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
188 _cleanup_free_ char *sfamily = NULL;
196 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
197 return errno > 0 ? -errno : -EINVAL;
199 family = netlink_family_from_string(sfamily);
203 a->sockaddr.nl.nl_family = AF_NETLINK;
204 a->sockaddr.nl.nl_groups = group;
207 a->size = sizeof(struct sockaddr_nl);
208 a->protocol = family;
213 int socket_address_verify(const SocketAddress *a) {
216 switch (socket_address_family(a)) {
219 if (a->size != sizeof(struct sockaddr_in))
222 if (a->sockaddr.in.sin_port == 0)
225 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
231 if (a->size != sizeof(struct sockaddr_in6))
234 if (a->sockaddr.in6.sin6_port == 0)
237 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
243 if (a->size < offsetof(struct sockaddr_un, sun_path))
246 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
248 if (a->sockaddr.un.sun_path[0] != 0) {
252 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
256 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
261 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
268 if (a->size != sizeof(struct sockaddr_nl))
271 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
277 return -EAFNOSUPPORT;
281 int socket_address_print(const SocketAddress *a, char **ret) {
287 r = socket_address_verify(a);
291 if (socket_address_family(a) == AF_NETLINK) {
292 _cleanup_free_ char *sfamily = NULL;
294 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
298 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
305 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, ret);
308 bool socket_address_can_accept(const SocketAddress *a) {
312 a->type == SOCK_STREAM ||
313 a->type == SOCK_SEQPACKET;
316 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
320 /* Invalid addresses are unequal to all */
321 if (socket_address_verify(a) < 0 ||
322 socket_address_verify(b) < 0)
325 if (a->type != b->type)
328 if (socket_address_family(a) != socket_address_family(b))
331 switch (socket_address_family(a)) {
334 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
337 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
343 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
346 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
352 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
355 if (a->sockaddr.un.sun_path[0]) {
356 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
359 if (a->size != b->size)
362 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
369 if (a->protocol != b->protocol)
372 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
378 /* Cannot compare, so we assume the addresses are different */
385 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
386 struct SocketAddress b;
391 if (socket_address_parse(&b, s) < 0)
396 return socket_address_equal(a, &b);
399 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
400 struct SocketAddress b;
405 if (socket_address_parse_netlink(&b, s) < 0)
408 return socket_address_equal(a, &b);
411 const char* socket_address_get_path(const SocketAddress *a) {
414 if (socket_address_family(a) != AF_UNIX)
417 if (a->sockaddr.un.sun_path[0] == 0)
420 return a->sockaddr.un.sun_path;
423 bool socket_ipv6_is_supported(void) {
424 _cleanup_free_ char *l = NULL;
426 if (access("/sys/module/ipv6", F_OK) != 0)
429 /* If we can't check "disable" parameter, assume enabled */
430 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
433 /* If module was loaded with disable=1 no IPv6 available */
437 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
444 b.size = sizeof(b.sockaddr);
445 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
448 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
451 solen = sizeof(b.type);
452 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
455 if (b.type != a->type)
458 if (a->protocol != 0) {
459 solen = sizeof(b.protocol);
460 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
463 if (b.protocol != a->protocol)
467 return socket_address_equal(a, &b);
470 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, char **ret) {
471 union sockaddr_union *sa = (union sockaddr_union*) _sa;
475 assert(salen >= sizeof(sa->sa.sa_family));
477 switch (sa->sa.sa_family) {
482 a = ntohl(sa->in.sin_addr.s_addr);
486 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
487 ntohs(sa->in.sin_port)) < 0)
494 static const unsigned char ipv4_prefix[] = {
495 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
498 if (translate_ipv6 && memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
499 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
503 a[0], a[1], a[2], a[3],
504 ntohs(sa->in6.sin6_port)) < 0)
507 char a[INET6_ADDRSTRLEN];
511 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a)),
512 ntohs(sa->in6.sin6_port)) < 0)
520 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
521 p = strdup("<unnamed>");
525 } else if (sa->un.sun_path[0] == 0) {
528 /* FIXME: We assume we can print the
529 * socket path here and that it hasn't
530 * more than one NUL byte. That is
531 * actually an invalid assumption */
533 p = new(char, sizeof(sa->un.sun_path)+1);
538 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
539 p[sizeof(sa->un.sun_path)] = 0;
542 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
558 int getpeername_pretty(int fd, char **ret) {
559 union sockaddr_union sa;
560 socklen_t salen = sizeof(sa);
566 if (getpeername(fd, &sa.sa, &salen) < 0)
569 if (sa.sa.sa_family == AF_UNIX) {
570 struct ucred ucred = {};
572 /* UNIX connection sockets are anonymous, so let's use
573 * PID/UID as pretty credentials instead */
575 r = getpeercred(fd, &ucred);
579 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
585 /* For remote sockets we translate IPv6 addresses back to IPv4
586 * if applicable, since that's nicer. */
588 return sockaddr_pretty(&sa.sa, salen, true, ret);
591 int getsockname_pretty(int fd, char **ret) {
592 union sockaddr_union sa;
593 socklen_t salen = sizeof(sa);
598 if (getsockname(fd, &sa.sa, &salen) < 0)
601 /* For local sockets we do not translate IPv6 addresses back
602 * to IPv6 if applicable, since this is usually used for
603 * listening sockets where the difference between IPv4 and
606 return sockaddr_pretty(&sa.sa, salen, false, ret);
609 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
611 char host[NI_MAXHOST], *ret;
615 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
616 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
618 int saved_errno = errno;
620 r = sockaddr_pretty(&sa->sa, salen, true, &ret);
622 return log_error_errno(r, "sockadd_pretty() failed: %m");
624 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
635 int getnameinfo_pretty(int fd, char **ret) {
636 union sockaddr_union sa;
637 socklen_t salen = sizeof(sa);
642 if (getsockname(fd, &sa.sa, &salen) < 0)
643 return log_error_errno(errno, "getsockname(%d) failed: %m", fd);
645 return socknameinfo_pretty(&sa, salen, ret);
648 int socket_address_unlink(SocketAddress *a) {
651 if (socket_address_family(a) != AF_UNIX)
654 if (a->sockaddr.un.sun_path[0] == 0)
657 if (unlink(a->sockaddr.un.sun_path) < 0)
663 static const char* const netlink_family_table[] = {
664 [NETLINK_ROUTE] = "route",
665 [NETLINK_FIREWALL] = "firewall",
666 [NETLINK_INET_DIAG] = "inet-diag",
667 [NETLINK_NFLOG] = "nflog",
668 [NETLINK_XFRM] = "xfrm",
669 [NETLINK_SELINUX] = "selinux",
670 [NETLINK_ISCSI] = "iscsi",
671 [NETLINK_AUDIT] = "audit",
672 [NETLINK_FIB_LOOKUP] = "fib-lookup",
673 [NETLINK_CONNECTOR] = "connector",
674 [NETLINK_NETFILTER] = "netfilter",
675 [NETLINK_IP6_FW] = "ip6-fw",
676 [NETLINK_DNRTMSG] = "dnrtmsg",
677 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
678 [NETLINK_GENERIC] = "generic",
679 [NETLINK_SCSITRANSPORT] = "scsitransport",
680 [NETLINK_ECRYPTFS] = "ecryptfs"
683 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
685 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
686 [SOCKET_ADDRESS_DEFAULT] = "default",
687 [SOCKET_ADDRESS_BOTH] = "both",
688 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
691 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
693 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
697 if (a->sa.sa_family != b->sa.sa_family)
700 if (a->sa.sa_family == AF_INET)
701 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
703 if (a->sa.sa_family == AF_INET6)
704 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
709 char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
713 /* Like ether_ntoa() but uses %02x instead of %x to print
714 * ethernet addresses, which makes them look less funny. Also,
715 * doesn't use a static buffer. */
717 sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
718 addr->ether_addr_octet[0],
719 addr->ether_addr_octet[1],
720 addr->ether_addr_octet[2],
721 addr->ether_addr_octet[3],
722 addr->ether_addr_octet[4],
723 addr->ether_addr_octet[5]);