]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/socket-util.c
util: introduce memcmp_safe()
[thirdparty/systemd.git] / src / basic / socket-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <arpa/inet.h>
4 #include <errno.h>
5 #include <limits.h>
6 #include <net/if.h>
7 #include <netdb.h>
8 #include <netinet/ip.h>
9 #include <poll.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16
17 #include "alloc-util.h"
18 #include "fd-util.h"
19 #include "fileio.h"
20 #include "format-util.h"
21 #include "log.h"
22 #include "macro.h"
23 #include "missing.h"
24 #include "parse-util.h"
25 #include "path-util.h"
26 #include "process-util.h"
27 #include "socket-util.h"
28 #include "string-table.h"
29 #include "string-util.h"
30 #include "strv.h"
31 #include "user-util.h"
32 #include "utf8.h"
33 #include "util.h"
34
35 #if ENABLE_IDN
36 # define IDN_FLAGS NI_IDN
37 #else
38 # define IDN_FLAGS 0
39 #endif
40
41 static const char* const socket_address_type_table[] = {
42 [SOCK_STREAM] = "Stream",
43 [SOCK_DGRAM] = "Datagram",
44 [SOCK_RAW] = "Raw",
45 [SOCK_RDM] = "ReliableDatagram",
46 [SOCK_SEQPACKET] = "SequentialPacket",
47 [SOCK_DCCP] = "DatagramCongestionControl",
48 };
49
50 DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int);
51
52 int socket_address_parse(SocketAddress *a, const char *s) {
53 char *e, *n;
54 int r;
55
56 assert(a);
57 assert(s);
58
59 zero(*a);
60 a->type = SOCK_STREAM;
61
62 if (*s == '[') {
63 uint16_t port;
64
65 /* IPv6 in [x:.....:z]:p notation */
66
67 e = strchr(s+1, ']');
68 if (!e)
69 return -EINVAL;
70
71 n = strndupa(s+1, e-s-1);
72
73 errno = 0;
74 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
75 return errno > 0 ? -errno : -EINVAL;
76
77 e++;
78 if (*e != ':')
79 return -EINVAL;
80
81 e++;
82 r = parse_ip_port(e, &port);
83 if (r < 0)
84 return r;
85
86 a->sockaddr.in6.sin6_family = AF_INET6;
87 a->sockaddr.in6.sin6_port = htobe16(port);
88 a->size = sizeof(struct sockaddr_in6);
89
90 } else if (*s == '/') {
91 /* AF_UNIX socket */
92
93 size_t l;
94
95 l = strlen(s);
96 if (l >= sizeof(a->sockaddr.un.sun_path))
97 return -EINVAL;
98
99 a->sockaddr.un.sun_family = AF_UNIX;
100 memcpy(a->sockaddr.un.sun_path, s, l);
101 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
102
103 } else if (*s == '@') {
104 /* Abstract AF_UNIX socket */
105 size_t l;
106
107 l = strlen(s+1);
108 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
109 return -EINVAL;
110
111 a->sockaddr.un.sun_family = AF_UNIX;
112 memcpy(a->sockaddr.un.sun_path+1, s+1, l);
113 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
114
115 } else if (startswith(s, "vsock:")) {
116 /* AF_VSOCK socket in vsock:cid:port notation */
117 const char *cid_start = s + STRLEN("vsock:");
118 unsigned port;
119
120 e = strchr(cid_start, ':');
121 if (!e)
122 return -EINVAL;
123
124 r = safe_atou(e+1, &port);
125 if (r < 0)
126 return r;
127
128 n = strndupa(cid_start, e - cid_start);
129 if (!isempty(n)) {
130 r = safe_atou(n, &a->sockaddr.vm.svm_cid);
131 if (r < 0)
132 return r;
133 } else
134 a->sockaddr.vm.svm_cid = VMADDR_CID_ANY;
135
136 a->sockaddr.vm.svm_family = AF_VSOCK;
137 a->sockaddr.vm.svm_port = port;
138 a->size = sizeof(struct sockaddr_vm);
139
140 } else {
141 uint16_t port;
142
143 e = strchr(s, ':');
144 if (e) {
145 r = parse_ip_port(e + 1, &port);
146 if (r < 0)
147 return r;
148
149 n = strndupa(s, e-s);
150
151 /* IPv4 in w.x.y.z:p notation? */
152 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
153 if (r < 0)
154 return -errno;
155
156 if (r > 0) {
157 /* Gotcha, it's a traditional IPv4 address */
158 a->sockaddr.in.sin_family = AF_INET;
159 a->sockaddr.in.sin_port = htobe16(port);
160 a->size = sizeof(struct sockaddr_in);
161 } else {
162 unsigned idx;
163
164 if (strlen(n) > IF_NAMESIZE-1)
165 return -EINVAL;
166
167 /* Uh, our last resort, an interface name */
168 idx = if_nametoindex(n);
169 if (idx == 0)
170 return -EINVAL;
171
172 a->sockaddr.in6.sin6_family = AF_INET6;
173 a->sockaddr.in6.sin6_port = htobe16(port);
174 a->sockaddr.in6.sin6_scope_id = idx;
175 a->sockaddr.in6.sin6_addr = in6addr_any;
176 a->size = sizeof(struct sockaddr_in6);
177 }
178 } else {
179
180 /* Just a port */
181 r = parse_ip_port(s, &port);
182 if (r < 0)
183 return r;
184
185 if (socket_ipv6_is_supported()) {
186 a->sockaddr.in6.sin6_family = AF_INET6;
187 a->sockaddr.in6.sin6_port = htobe16(port);
188 a->sockaddr.in6.sin6_addr = in6addr_any;
189 a->size = sizeof(struct sockaddr_in6);
190 } else {
191 a->sockaddr.in.sin_family = AF_INET;
192 a->sockaddr.in.sin_port = htobe16(port);
193 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
194 a->size = sizeof(struct sockaddr_in);
195 }
196 }
197 }
198
199 return 0;
200 }
201
202 int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
203 SocketAddress b;
204 int r;
205
206 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
207
208 r = socket_address_parse(&b, s);
209 if (r < 0)
210 return r;
211
212 if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
213 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
214 return -EAFNOSUPPORT;
215 }
216
217 *a = b;
218 return 0;
219 }
220
221 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
222 int family;
223 unsigned group = 0;
224 _cleanup_free_ char *sfamily = NULL;
225 assert(a);
226 assert(s);
227
228 zero(*a);
229 a->type = SOCK_RAW;
230
231 errno = 0;
232 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
233 return errno > 0 ? -errno : -EINVAL;
234
235 family = netlink_family_from_string(sfamily);
236 if (family < 0)
237 return -EINVAL;
238
239 a->sockaddr.nl.nl_family = AF_NETLINK;
240 a->sockaddr.nl.nl_groups = group;
241
242 a->type = SOCK_RAW;
243 a->size = sizeof(struct sockaddr_nl);
244 a->protocol = family;
245
246 return 0;
247 }
248
249 int socket_address_verify(const SocketAddress *a) {
250 assert(a);
251
252 switch (socket_address_family(a)) {
253
254 case AF_INET:
255 if (a->size != sizeof(struct sockaddr_in))
256 return -EINVAL;
257
258 if (a->sockaddr.in.sin_port == 0)
259 return -EINVAL;
260
261 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
262 return -EINVAL;
263
264 return 0;
265
266 case AF_INET6:
267 if (a->size != sizeof(struct sockaddr_in6))
268 return -EINVAL;
269
270 if (a->sockaddr.in6.sin6_port == 0)
271 return -EINVAL;
272
273 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
274 return -EINVAL;
275
276 return 0;
277
278 case AF_UNIX:
279 if (a->size < offsetof(struct sockaddr_un, sun_path))
280 return -EINVAL;
281
282 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
283
284 if (a->sockaddr.un.sun_path[0] != 0) {
285 char *e;
286
287 /* path */
288 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
289 if (!e)
290 return -EINVAL;
291
292 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
293 return -EINVAL;
294 }
295 }
296
297 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
298 return -EINVAL;
299
300 return 0;
301
302 case AF_NETLINK:
303
304 if (a->size != sizeof(struct sockaddr_nl))
305 return -EINVAL;
306
307 if (!IN_SET(a->type, SOCK_RAW, SOCK_DGRAM))
308 return -EINVAL;
309
310 return 0;
311
312 case AF_VSOCK:
313 if (a->size != sizeof(struct sockaddr_vm))
314 return -EINVAL;
315
316 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
317 return -EINVAL;
318
319 return 0;
320
321 default:
322 return -EAFNOSUPPORT;
323 }
324 }
325
326 int socket_address_print(const SocketAddress *a, char **ret) {
327 int r;
328
329 assert(a);
330 assert(ret);
331
332 r = socket_address_verify(a);
333 if (r < 0)
334 return r;
335
336 if (socket_address_family(a) == AF_NETLINK) {
337 _cleanup_free_ char *sfamily = NULL;
338
339 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
340 if (r < 0)
341 return r;
342
343 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
344 if (r < 0)
345 return -ENOMEM;
346
347 return 0;
348 }
349
350 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
351 }
352
353 bool socket_address_can_accept(const SocketAddress *a) {
354 assert(a);
355
356 return
357 IN_SET(a->type, SOCK_STREAM, SOCK_SEQPACKET);
358 }
359
360 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
361 assert(a);
362 assert(b);
363
364 /* Invalid addresses are unequal to all */
365 if (socket_address_verify(a) < 0 ||
366 socket_address_verify(b) < 0)
367 return false;
368
369 if (a->type != b->type)
370 return false;
371
372 if (socket_address_family(a) != socket_address_family(b))
373 return false;
374
375 switch (socket_address_family(a)) {
376
377 case AF_INET:
378 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
379 return false;
380
381 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
382 return false;
383
384 break;
385
386 case AF_INET6:
387 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
388 return false;
389
390 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
391 return false;
392
393 break;
394
395 case AF_UNIX:
396 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
397 b->size <= offsetof(struct sockaddr_un, sun_path))
398 return false;
399
400 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
401 return false;
402
403 if (a->sockaddr.un.sun_path[0]) {
404 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0))
405 return false;
406 } else {
407 if (a->size != b->size)
408 return false;
409
410 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
411 return false;
412 }
413
414 break;
415
416 case AF_NETLINK:
417 if (a->protocol != b->protocol)
418 return false;
419
420 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
421 return false;
422
423 break;
424
425 case AF_VSOCK:
426 if (a->sockaddr.vm.svm_cid != b->sockaddr.vm.svm_cid)
427 return false;
428
429 if (a->sockaddr.vm.svm_port != b->sockaddr.vm.svm_port)
430 return false;
431
432 break;
433
434 default:
435 /* Cannot compare, so we assume the addresses are different */
436 return false;
437 }
438
439 return true;
440 }
441
442 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
443 struct SocketAddress b;
444
445 assert(a);
446 assert(s);
447
448 if (socket_address_parse(&b, s) < 0)
449 return false;
450
451 b.type = type;
452
453 return socket_address_equal(a, &b);
454 }
455
456 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
457 struct SocketAddress b;
458
459 assert(a);
460 assert(s);
461
462 if (socket_address_parse_netlink(&b, s) < 0)
463 return false;
464
465 return socket_address_equal(a, &b);
466 }
467
468 const char* socket_address_get_path(const SocketAddress *a) {
469 assert(a);
470
471 if (socket_address_family(a) != AF_UNIX)
472 return NULL;
473
474 if (a->sockaddr.un.sun_path[0] == 0)
475 return NULL;
476
477 return a->sockaddr.un.sun_path;
478 }
479
480 bool socket_ipv6_is_supported(void) {
481 if (access("/proc/net/if_inet6", F_OK) != 0)
482 return false;
483
484 return true;
485 }
486
487 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
488 SocketAddress b;
489 socklen_t solen;
490
491 assert(a);
492 assert(fd >= 0);
493
494 b.size = sizeof(b.sockaddr);
495 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
496 return false;
497
498 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
499 return false;
500
501 solen = sizeof(b.type);
502 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
503 return false;
504
505 if (b.type != a->type)
506 return false;
507
508 if (a->protocol != 0) {
509 solen = sizeof(b.protocol);
510 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
511 return false;
512
513 if (b.protocol != a->protocol)
514 return false;
515 }
516
517 return socket_address_equal(a, &b);
518 }
519
520 int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) {
521 union sockaddr_union *sa = (union sockaddr_union*) _sa;
522
523 /* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */
524
525 assert(sa);
526
527 switch (sa->sa.sa_family) {
528
529 case AF_INET:
530 *ret_port = be16toh(sa->in.sin_port);
531 return 0;
532
533 case AF_INET6:
534 *ret_port = be16toh(sa->in6.sin6_port);
535 return 0;
536
537 case AF_VSOCK:
538 *ret_port = sa->vm.svm_port;
539 return 0;
540
541 default:
542 return -EAFNOSUPPORT;
543 }
544 }
545
546 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
547 union sockaddr_union *sa = (union sockaddr_union*) _sa;
548 char *p;
549 int r;
550
551 assert(sa);
552 assert(salen >= sizeof(sa->sa.sa_family));
553
554 switch (sa->sa.sa_family) {
555
556 case AF_INET: {
557 uint32_t a;
558
559 a = be32toh(sa->in.sin_addr.s_addr);
560
561 if (include_port)
562 r = asprintf(&p,
563 "%u.%u.%u.%u:%u",
564 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
565 be16toh(sa->in.sin_port));
566 else
567 r = asprintf(&p,
568 "%u.%u.%u.%u",
569 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
570 if (r < 0)
571 return -ENOMEM;
572 break;
573 }
574
575 case AF_INET6: {
576 static const unsigned char ipv4_prefix[] = {
577 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
578 };
579
580 if (translate_ipv6 &&
581 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
582 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
583 if (include_port)
584 r = asprintf(&p,
585 "%u.%u.%u.%u:%u",
586 a[0], a[1], a[2], a[3],
587 be16toh(sa->in6.sin6_port));
588 else
589 r = asprintf(&p,
590 "%u.%u.%u.%u",
591 a[0], a[1], a[2], a[3]);
592 if (r < 0)
593 return -ENOMEM;
594 } else {
595 char a[INET6_ADDRSTRLEN];
596
597 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
598
599 if (include_port) {
600 r = asprintf(&p,
601 "[%s]:%u",
602 a,
603 be16toh(sa->in6.sin6_port));
604 if (r < 0)
605 return -ENOMEM;
606 } else {
607 p = strdup(a);
608 if (!p)
609 return -ENOMEM;
610 }
611 }
612
613 break;
614 }
615
616 case AF_UNIX:
617 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
618 p = strdup("<unnamed>");
619 if (!p)
620 return -ENOMEM;
621
622 } else if (sa->un.sun_path[0] == 0) {
623 /* abstract */
624
625 /* FIXME: We assume we can print the
626 * socket path here and that it hasn't
627 * more than one NUL byte. That is
628 * actually an invalid assumption */
629
630 p = new(char, sizeof(sa->un.sun_path)+1);
631 if (!p)
632 return -ENOMEM;
633
634 p[0] = '@';
635 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
636 p[sizeof(sa->un.sun_path)] = 0;
637
638 } else {
639 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
640 if (!p)
641 return -ENOMEM;
642 }
643
644 break;
645
646 case AF_VSOCK:
647 if (include_port)
648 r = asprintf(&p,
649 "vsock:%u:%u",
650 sa->vm.svm_cid,
651 sa->vm.svm_port);
652 else
653 r = asprintf(&p, "vsock:%u", sa->vm.svm_cid);
654 if (r < 0)
655 return -ENOMEM;
656 break;
657
658 default:
659 return -EOPNOTSUPP;
660 }
661
662 *ret = p;
663 return 0;
664 }
665
666 int getpeername_pretty(int fd, bool include_port, char **ret) {
667 union sockaddr_union sa;
668 socklen_t salen = sizeof(sa);
669 int r;
670
671 assert(fd >= 0);
672 assert(ret);
673
674 if (getpeername(fd, &sa.sa, &salen) < 0)
675 return -errno;
676
677 if (sa.sa.sa_family == AF_UNIX) {
678 struct ucred ucred = {};
679
680 /* UNIX connection sockets are anonymous, so let's use
681 * PID/UID as pretty credentials instead */
682
683 r = getpeercred(fd, &ucred);
684 if (r < 0)
685 return r;
686
687 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
688 return -ENOMEM;
689
690 return 0;
691 }
692
693 /* For remote sockets we translate IPv6 addresses back to IPv4
694 * if applicable, since that's nicer. */
695
696 return sockaddr_pretty(&sa.sa, salen, true, include_port, ret);
697 }
698
699 int getsockname_pretty(int fd, char **ret) {
700 union sockaddr_union sa;
701 socklen_t salen = sizeof(sa);
702
703 assert(fd >= 0);
704 assert(ret);
705
706 if (getsockname(fd, &sa.sa, &salen) < 0)
707 return -errno;
708
709 /* For local sockets we do not translate IPv6 addresses back
710 * to IPv6 if applicable, since this is usually used for
711 * listening sockets where the difference between IPv4 and
712 * IPv6 matters. */
713
714 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
715 }
716
717 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
718 int r;
719 char host[NI_MAXHOST], *ret;
720
721 assert(_ret);
722
723 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS);
724 if (r != 0) {
725 int saved_errno = errno;
726
727 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
728 if (r < 0)
729 return r;
730
731 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
732 } else {
733 ret = strdup(host);
734 if (!ret)
735 return -ENOMEM;
736 }
737
738 *_ret = ret;
739 return 0;
740 }
741
742 int socket_address_unlink(SocketAddress *a) {
743 assert(a);
744
745 if (socket_address_family(a) != AF_UNIX)
746 return 0;
747
748 if (a->sockaddr.un.sun_path[0] == 0)
749 return 0;
750
751 if (unlink(a->sockaddr.un.sun_path) < 0)
752 return -errno;
753
754 return 1;
755 }
756
757 static const char* const netlink_family_table[] = {
758 [NETLINK_ROUTE] = "route",
759 [NETLINK_FIREWALL] = "firewall",
760 [NETLINK_INET_DIAG] = "inet-diag",
761 [NETLINK_NFLOG] = "nflog",
762 [NETLINK_XFRM] = "xfrm",
763 [NETLINK_SELINUX] = "selinux",
764 [NETLINK_ISCSI] = "iscsi",
765 [NETLINK_AUDIT] = "audit",
766 [NETLINK_FIB_LOOKUP] = "fib-lookup",
767 [NETLINK_CONNECTOR] = "connector",
768 [NETLINK_NETFILTER] = "netfilter",
769 [NETLINK_IP6_FW] = "ip6-fw",
770 [NETLINK_DNRTMSG] = "dnrtmsg",
771 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
772 [NETLINK_GENERIC] = "generic",
773 [NETLINK_SCSITRANSPORT] = "scsitransport",
774 [NETLINK_ECRYPTFS] = "ecryptfs",
775 [NETLINK_RDMA] = "rdma",
776 };
777
778 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
779
780 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
781 [SOCKET_ADDRESS_DEFAULT] = "default",
782 [SOCKET_ADDRESS_BOTH] = "both",
783 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
784 };
785
786 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
787
788 SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *n) {
789 int r;
790
791 r = parse_boolean(n);
792 if (r > 0)
793 return SOCKET_ADDRESS_IPV6_ONLY;
794 if (r == 0)
795 return SOCKET_ADDRESS_BOTH;
796
797 return socket_address_bind_ipv6_only_from_string(n);
798 }
799
800 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
801 assert(a);
802 assert(b);
803
804 if (a->sa.sa_family != b->sa.sa_family)
805 return false;
806
807 if (a->sa.sa_family == AF_INET)
808 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
809
810 if (a->sa.sa_family == AF_INET6)
811 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
812
813 if (a->sa.sa_family == AF_VSOCK)
814 return a->vm.svm_cid == b->vm.svm_cid;
815
816 return false;
817 }
818
819 int fd_inc_sndbuf(int fd, size_t n) {
820 int r, value;
821 socklen_t l = sizeof(value);
822
823 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
824 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
825 return 0;
826
827 /* If we have the privileges we will ignore the kernel limit. */
828
829 value = (int) n;
830 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
831 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
832 return -errno;
833
834 return 1;
835 }
836
837 int fd_inc_rcvbuf(int fd, size_t n) {
838 int r, value;
839 socklen_t l = sizeof(value);
840
841 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
842 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
843 return 0;
844
845 /* If we have the privileges we will ignore the kernel limit. */
846
847 value = (int) n;
848 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
849 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
850 return -errno;
851 return 1;
852 }
853
854 static const char* const ip_tos_table[] = {
855 [IPTOS_LOWDELAY] = "low-delay",
856 [IPTOS_THROUGHPUT] = "throughput",
857 [IPTOS_RELIABILITY] = "reliability",
858 [IPTOS_LOWCOST] = "low-cost",
859 };
860
861 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
862
863 bool ifname_valid(const char *p) {
864 bool numeric = true;
865
866 /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
867 * but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
868 * also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
869
870 if (isempty(p))
871 return false;
872
873 if (strlen(p) >= IFNAMSIZ)
874 return false;
875
876 if (dot_or_dot_dot(p))
877 return false;
878
879 while (*p) {
880 if ((unsigned char) *p >= 127U)
881 return false;
882
883 if ((unsigned char) *p <= 32U)
884 return false;
885
886 if (IN_SET(*p, ':', '/'))
887 return false;
888
889 numeric = numeric && (*p >= '0' && *p <= '9');
890 p++;
891 }
892
893 if (numeric)
894 return false;
895
896 return true;
897 }
898
899 bool address_label_valid(const char *p) {
900
901 if (isempty(p))
902 return false;
903
904 if (strlen(p) >= IFNAMSIZ)
905 return false;
906
907 while (*p) {
908 if ((uint8_t) *p >= 127U)
909 return false;
910
911 if ((uint8_t) *p <= 31U)
912 return false;
913 p++;
914 }
915
916 return true;
917 }
918
919 int getpeercred(int fd, struct ucred *ucred) {
920 socklen_t n = sizeof(struct ucred);
921 struct ucred u;
922 int r;
923
924 assert(fd >= 0);
925 assert(ucred);
926
927 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
928 if (r < 0)
929 return -errno;
930
931 if (n != sizeof(struct ucred))
932 return -EIO;
933
934 /* Check if the data is actually useful and not suppressed due to namespacing issues */
935 if (!pid_is_valid(u.pid))
936 return -ENODATA;
937
938 /* Note that we don't check UID/GID here, as namespace translation works differently there: instead of
939 * receiving in "invalid" user/group we get the overflow UID/GID. */
940
941 *ucred = u;
942 return 0;
943 }
944
945 int getpeersec(int fd, char **ret) {
946 _cleanup_free_ char *s = NULL;
947 socklen_t n = 64;
948
949 assert(fd >= 0);
950 assert(ret);
951
952 for (;;) {
953 s = new0(char, n+1);
954 if (!s)
955 return -ENOMEM;
956
957 if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n) >= 0)
958 break;
959
960 if (errno != ERANGE)
961 return -errno;
962
963 s = mfree(s);
964 }
965
966 if (isempty(s))
967 return -EOPNOTSUPP;
968
969 *ret = TAKE_PTR(s);
970
971 return 0;
972 }
973
974 int getpeergroups(int fd, gid_t **ret) {
975 socklen_t n = sizeof(gid_t) * 64;
976 _cleanup_free_ gid_t *d = NULL;
977
978 assert(fd >= 0);
979 assert(ret);
980
981 for (;;) {
982 d = malloc(n);
983 if (!d)
984 return -ENOMEM;
985
986 if (getsockopt(fd, SOL_SOCKET, SO_PEERGROUPS, d, &n) >= 0)
987 break;
988
989 if (errno != ERANGE)
990 return -errno;
991
992 d = mfree(d);
993 }
994
995 assert_se(n % sizeof(gid_t) == 0);
996 n /= sizeof(gid_t);
997
998 if ((socklen_t) (int) n != n)
999 return -E2BIG;
1000
1001 *ret = TAKE_PTR(d);
1002
1003 return (int) n;
1004 }
1005
1006 int send_one_fd_sa(
1007 int transport_fd,
1008 int fd,
1009 const struct sockaddr *sa, socklen_t len,
1010 int flags) {
1011
1012 union {
1013 struct cmsghdr cmsghdr;
1014 uint8_t buf[CMSG_SPACE(sizeof(int))];
1015 } control = {};
1016 struct msghdr mh = {
1017 .msg_name = (struct sockaddr*) sa,
1018 .msg_namelen = len,
1019 .msg_control = &control,
1020 .msg_controllen = sizeof(control),
1021 };
1022 struct cmsghdr *cmsg;
1023
1024 assert(transport_fd >= 0);
1025 assert(fd >= 0);
1026
1027 cmsg = CMSG_FIRSTHDR(&mh);
1028 cmsg->cmsg_level = SOL_SOCKET;
1029 cmsg->cmsg_type = SCM_RIGHTS;
1030 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1031 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
1032
1033 mh.msg_controllen = CMSG_SPACE(sizeof(int));
1034 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
1035 return -errno;
1036
1037 return 0;
1038 }
1039
1040 int receive_one_fd(int transport_fd, int flags) {
1041 union {
1042 struct cmsghdr cmsghdr;
1043 uint8_t buf[CMSG_SPACE(sizeof(int))];
1044 } control = {};
1045 struct msghdr mh = {
1046 .msg_control = &control,
1047 .msg_controllen = sizeof(control),
1048 };
1049 struct cmsghdr *cmsg, *found = NULL;
1050
1051 assert(transport_fd >= 0);
1052
1053 /*
1054 * Receive a single FD via @transport_fd. We don't care for
1055 * the transport-type. We retrieve a single FD at most, so for
1056 * packet-based transports, the caller must ensure to send
1057 * only a single FD per packet. This is best used in
1058 * combination with send_one_fd().
1059 */
1060
1061 if (recvmsg(transport_fd, &mh, MSG_CMSG_CLOEXEC | flags) < 0)
1062 return -errno;
1063
1064 CMSG_FOREACH(cmsg, &mh) {
1065 if (cmsg->cmsg_level == SOL_SOCKET &&
1066 cmsg->cmsg_type == SCM_RIGHTS &&
1067 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
1068 assert(!found);
1069 found = cmsg;
1070 break;
1071 }
1072 }
1073
1074 if (!found) {
1075 cmsg_close_all(&mh);
1076 return -EIO;
1077 }
1078
1079 return *(int*) CMSG_DATA(found);
1080 }
1081
1082 ssize_t next_datagram_size_fd(int fd) {
1083 ssize_t l;
1084 int k;
1085
1086 /* This is a bit like FIONREAD/SIOCINQ, however a bit more powerful. The difference being: recv(MSG_PEEK) will
1087 * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't
1088 * do. This difference is actually of major importance as we need to be sure that the size returned here
1089 * actually matches what we will read with recvmsg() next, as otherwise we might end up allocating a buffer of
1090 * the wrong size. */
1091
1092 l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC);
1093 if (l < 0) {
1094 if (IN_SET(errno, EOPNOTSUPP, EFAULT))
1095 goto fallback;
1096
1097 return -errno;
1098 }
1099 if (l == 0)
1100 goto fallback;
1101
1102 return l;
1103
1104 fallback:
1105 k = 0;
1106
1107 /* Some sockets (AF_PACKET) do not support null-sized recv() with MSG_TRUNC set, let's fall back to FIONREAD
1108 * for them. Checksums don't matter for raw sockets anyway, hence this should be fine. */
1109
1110 if (ioctl(fd, FIONREAD, &k) < 0)
1111 return -errno;
1112
1113 return (ssize_t) k;
1114 }
1115
1116 int flush_accept(int fd) {
1117
1118 struct pollfd pollfd = {
1119 .fd = fd,
1120 .events = POLLIN,
1121 };
1122 int r;
1123
1124 /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
1125
1126 for (;;) {
1127 int cfd;
1128
1129 r = poll(&pollfd, 1, 0);
1130 if (r < 0) {
1131 if (errno == EINTR)
1132 continue;
1133
1134 return -errno;
1135
1136 } else if (r == 0)
1137 return 0;
1138
1139 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1140 if (cfd < 0) {
1141 if (errno == EINTR)
1142 continue;
1143
1144 if (errno == EAGAIN)
1145 return 0;
1146
1147 return -errno;
1148 }
1149
1150 close(cfd);
1151 }
1152 }
1153
1154 struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length) {
1155 struct cmsghdr *cmsg;
1156
1157 assert(mh);
1158
1159 CMSG_FOREACH(cmsg, mh)
1160 if (cmsg->cmsg_level == level &&
1161 cmsg->cmsg_type == type &&
1162 (length == (socklen_t) -1 || length == cmsg->cmsg_len))
1163 return cmsg;
1164
1165 return NULL;
1166 }
1167
1168 int socket_ioctl_fd(void) {
1169 int fd;
1170
1171 /* Create a socket to invoke the various network interface ioctl()s on. Traditionally only AF_INET was good for
1172 * that. Since kernel 4.6 AF_NETLINK works for this too. We first try to use AF_INET hence, but if that's not
1173 * available (for example, because it is made unavailable via SECCOMP or such), we'll fall back to the more
1174 * generic AF_NETLINK. */
1175
1176 fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
1177 if (fd < 0)
1178 fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC);
1179 if (fd < 0)
1180 return -errno;
1181
1182 return fd;
1183 }