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/>.
25 #include <arpa/inet.h>
28 #include <sys/types.h>
33 #include "path-util.h"
35 #include "socket-util.h"
39 int socket_address_parse(SocketAddress *a, const char *s) {
48 a->type = SOCK_STREAM;
51 /* IPv6 in [x:.....:z]:p notation */
53 if (!socket_ipv6_is_supported()) {
54 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
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 if (!socket_ipv6_is_supported()) {
143 log_warning("Binding to interface is not available since kernel does not support IPv6.");
144 return -EAFNOSUPPORT;
147 a->sockaddr.in6.sin6_family = AF_INET6;
148 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
149 a->sockaddr.in6.sin6_scope_id = idx;
150 a->sockaddr.in6.sin6_addr = in6addr_any;
151 a->size = sizeof(struct sockaddr_in6);
156 r = safe_atou(s, &u);
160 if (u <= 0 || u > 0xFFFF)
163 if (socket_ipv6_is_supported()) {
164 a->sockaddr.in6.sin6_family = AF_INET6;
165 a->sockaddr.in6.sin6_port = htons((uint16_t) u);
166 a->sockaddr.in6.sin6_addr = in6addr_any;
167 a->size = sizeof(struct sockaddr_in6);
169 a->sockaddr.in.sin_family = AF_INET;
170 a->sockaddr.in.sin_port = htons((uint16_t) u);
171 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
172 a->size = sizeof(struct sockaddr_in);
180 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
183 _cleanup_free_ char *sfamily = NULL;
191 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
192 return errno > 0 ? -errno : -EINVAL;
194 family = netlink_family_from_string(sfamily);
198 a->sockaddr.nl.nl_family = AF_NETLINK;
199 a->sockaddr.nl.nl_groups = group;
202 a->size = sizeof(struct sockaddr_nl);
203 a->protocol = family;
208 int socket_address_verify(const SocketAddress *a) {
211 switch (socket_address_family(a)) {
214 if (a->size != sizeof(struct sockaddr_in))
217 if (a->sockaddr.in.sin_port == 0)
220 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
226 if (a->size != sizeof(struct sockaddr_in6))
229 if (a->sockaddr.in6.sin6_port == 0)
232 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
238 if (a->size < offsetof(struct sockaddr_un, sun_path))
241 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
243 if (a->sockaddr.un.sun_path[0] != 0) {
247 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
251 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
256 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
263 if (a->size != sizeof(struct sockaddr_nl))
266 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
272 return -EAFNOSUPPORT;
276 int socket_address_print(const SocketAddress *a, char **ret) {
282 r = socket_address_verify(a);
286 if (socket_address_family(a) == AF_NETLINK) {
287 _cleanup_free_ char *sfamily = NULL;
289 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
293 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
300 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
303 bool socket_address_can_accept(const SocketAddress *a) {
307 a->type == SOCK_STREAM ||
308 a->type == SOCK_SEQPACKET;
311 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
315 /* Invalid addresses are unequal to all */
316 if (socket_address_verify(a) < 0 ||
317 socket_address_verify(b) < 0)
320 if (a->type != b->type)
323 if (socket_address_family(a) != socket_address_family(b))
326 switch (socket_address_family(a)) {
329 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
332 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
338 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
341 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
347 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
348 b->size <= offsetof(struct sockaddr_un, sun_path))
351 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
354 if (a->sockaddr.un.sun_path[0]) {
355 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
358 if (a->size != b->size)
361 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
368 if (a->protocol != b->protocol)
371 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
377 /* Cannot compare, so we assume the addresses are different */
384 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
385 struct SocketAddress b;
390 if (socket_address_parse(&b, s) < 0)
395 return socket_address_equal(a, &b);
398 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
399 struct SocketAddress b;
404 if (socket_address_parse_netlink(&b, s) < 0)
407 return socket_address_equal(a, &b);
410 const char* socket_address_get_path(const SocketAddress *a) {
413 if (socket_address_family(a) != AF_UNIX)
416 if (a->sockaddr.un.sun_path[0] == 0)
419 return a->sockaddr.un.sun_path;
422 bool socket_ipv6_is_supported(void) {
423 _cleanup_free_ char *l = NULL;
425 if (access("/sys/module/ipv6", F_OK) != 0)
428 /* If we can't check "disable" parameter, assume enabled */
429 if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
432 /* If module was loaded with disable=1 no IPv6 available */
436 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
443 b.size = sizeof(b.sockaddr);
444 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
447 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
450 solen = sizeof(b.type);
451 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
454 if (b.type != a->type)
457 if (a->protocol != 0) {
458 solen = sizeof(b.protocol);
459 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
462 if (b.protocol != a->protocol)
466 return socket_address_equal(a, &b);
469 int sockaddr_port(const struct sockaddr *_sa) {
470 union sockaddr_union *sa = (union sockaddr_union*) _sa;
474 if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
475 return -EAFNOSUPPORT;
477 return ntohs(sa->sa.sa_family == AF_INET6 ?
482 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
483 union sockaddr_union *sa = (union sockaddr_union*) _sa;
488 assert(salen >= sizeof(sa->sa.sa_family));
490 switch (sa->sa.sa_family) {
495 a = ntohl(sa->in.sin_addr.s_addr);
500 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
501 ntohs(sa->in.sin_port));
505 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
512 static const unsigned char ipv4_prefix[] = {
513 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
516 if (translate_ipv6 &&
517 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
518 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
522 a[0], a[1], a[2], a[3],
523 ntohs(sa->in6.sin6_port));
527 a[0], a[1], a[2], a[3]);
531 char a[INET6_ADDRSTRLEN];
533 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
539 ntohs(sa->in6.sin6_port));
553 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
554 p = strdup("<unnamed>");
558 } else if (sa->un.sun_path[0] == 0) {
561 /* FIXME: We assume we can print the
562 * socket path here and that it hasn't
563 * more than one NUL byte. That is
564 * actually an invalid assumption */
566 p = new(char, sizeof(sa->un.sun_path)+1);
571 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
572 p[sizeof(sa->un.sun_path)] = 0;
575 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
591 int getpeername_pretty(int fd, char **ret) {
592 union sockaddr_union sa;
593 socklen_t salen = sizeof(sa);
599 if (getpeername(fd, &sa.sa, &salen) < 0)
602 if (sa.sa.sa_family == AF_UNIX) {
603 struct ucred ucred = {};
605 /* UNIX connection sockets are anonymous, so let's use
606 * PID/UID as pretty credentials instead */
608 r = getpeercred(fd, &ucred);
612 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
618 /* For remote sockets we translate IPv6 addresses back to IPv4
619 * if applicable, since that's nicer. */
621 return sockaddr_pretty(&sa.sa, salen, true, true, ret);
624 int getsockname_pretty(int fd, char **ret) {
625 union sockaddr_union sa;
626 socklen_t salen = sizeof(sa);
631 if (getsockname(fd, &sa.sa, &salen) < 0)
634 /* For local sockets we do not translate IPv6 addresses back
635 * to IPv6 if applicable, since this is usually used for
636 * listening sockets where the difference between IPv4 and
639 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
642 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
644 char host[NI_MAXHOST], *ret;
648 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
649 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
651 int saved_errno = errno;
653 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
655 return log_error_errno(r, "sockadd_pretty() failed: %m");
657 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
668 int getnameinfo_pretty(int fd, char **ret) {
669 union sockaddr_union sa;
670 socklen_t salen = sizeof(sa);
675 if (getsockname(fd, &sa.sa, &salen) < 0)
676 return log_error_errno(errno, "getsockname(%d) failed: %m", fd);
678 return socknameinfo_pretty(&sa, salen, ret);
681 int socket_address_unlink(SocketAddress *a) {
684 if (socket_address_family(a) != AF_UNIX)
687 if (a->sockaddr.un.sun_path[0] == 0)
690 if (unlink(a->sockaddr.un.sun_path) < 0)
696 static const char* const netlink_family_table[] = {
697 [NETLINK_ROUTE] = "route",
698 [NETLINK_FIREWALL] = "firewall",
699 [NETLINK_INET_DIAG] = "inet-diag",
700 [NETLINK_NFLOG] = "nflog",
701 [NETLINK_XFRM] = "xfrm",
702 [NETLINK_SELINUX] = "selinux",
703 [NETLINK_ISCSI] = "iscsi",
704 [NETLINK_AUDIT] = "audit",
705 [NETLINK_FIB_LOOKUP] = "fib-lookup",
706 [NETLINK_CONNECTOR] = "connector",
707 [NETLINK_NETFILTER] = "netfilter",
708 [NETLINK_IP6_FW] = "ip6-fw",
709 [NETLINK_DNRTMSG] = "dnrtmsg",
710 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
711 [NETLINK_GENERIC] = "generic",
712 [NETLINK_SCSITRANSPORT] = "scsitransport",
713 [NETLINK_ECRYPTFS] = "ecryptfs"
716 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
718 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
719 [SOCKET_ADDRESS_DEFAULT] = "default",
720 [SOCKET_ADDRESS_BOTH] = "both",
721 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
724 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
726 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
730 if (a->sa.sa_family != b->sa.sa_family)
733 if (a->sa.sa_family == AF_INET)
734 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
736 if (a->sa.sa_family == AF_INET6)
737 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
742 char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
746 /* Like ether_ntoa() but uses %02x instead of %x to print
747 * ethernet addresses, which makes them look less funny. Also,
748 * doesn't use a static buffer. */
750 sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
751 addr->ether_addr_octet[0],
752 addr->ether_addr_octet[1],
753 addr->ether_addr_octet[2],
754 addr->ether_addr_octet[3],
755 addr->ether_addr_octet[4],
756 addr->ether_addr_octet[5]);