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