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