]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/socket-util.c
tree-wide: remove Lennart's copyright lines
[thirdparty/systemd.git] / src / basic / socket-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a7334b09 2
42f4e3c4 3#include <arpa/inet.h>
07630cea 4#include <errno.h>
11c3a366 5#include <limits.h>
542563ba 6#include <net/if.h>
b31f535c 7#include <netdb.h>
2583fbea 8#include <netinet/ip.h>
60d9771c 9#include <poll.h>
07630cea 10#include <stddef.h>
11c3a366 11#include <stdint.h>
07630cea 12#include <stdio.h>
11c3a366 13#include <stdlib.h>
07630cea 14#include <string.h>
07630cea 15#include <unistd.h>
42f4e3c4 16
b5efdb8a 17#include "alloc-util.h"
2583fbea 18#include "fd-util.h"
07630cea 19#include "fileio.h"
f97b34a6 20#include "format-util.h"
93cc7779 21#include "log.h"
42f4e3c4 22#include "macro.h"
07630cea 23#include "missing.h"
6bedfcbb 24#include "parse-util.h"
9eb977db 25#include "path-util.h"
dccca82b 26#include "process-util.h"
2583fbea 27#include "socket-util.h"
8b43440b 28#include "string-table.h"
07630cea 29#include "string-util.h"
ef76dff2 30#include "strv.h"
ee104e11 31#include "user-util.h"
ef76dff2 32#include "utf8.h"
2eec67ac 33#include "util.h"
42f4e3c4 34
349cc4a5 35#if ENABLE_IDN
cadc80b8 36# define IDN_FLAGS NI_IDN
6326a143
WB
37#else
38# define IDN_FLAGS 0
39#endif
40
398ce0bc
YW
41static 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
50DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int);
51
542563ba 52int socket_address_parse(SocketAddress *a, const char *s) {
42f4e3c4 53 char *e, *n;
4d49b48c 54 int r;
42f4e3c4
LP
55
56 assert(a);
57 assert(s);
58
9152c765 59 zero(*a);
542563ba 60 a->type = SOCK_STREAM;
42f4e3c4
LP
61
62 if (*s == '[') {
89220e2f
LP
63 uint16_t port;
64
42f4e3c4
LP
65 /* IPv6 in [x:.....:z]:p notation */
66
4d49b48c
LP
67 e = strchr(s+1, ']');
68 if (!e)
42f4e3c4
LP
69 return -EINVAL;
70
4d49b48c 71 n = strndupa(s+1, e-s-1);
42f4e3c4
LP
72
73 errno = 0;
4d49b48c 74 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
8333c77e 75 return errno > 0 ? -errno : -EINVAL;
42f4e3c4
LP
76
77 e++;
78 if (*e != ':')
79 return -EINVAL;
80
81 e++;
89220e2f 82 r = parse_ip_port(e, &port);
4d49b48c 83 if (r < 0)
42f4e3c4
LP
84 return r;
85
42f4e3c4 86 a->sockaddr.in6.sin6_family = AF_INET6;
89220e2f 87 a->sockaddr.in6.sin6_port = htobe16(port);
42f4e3c4 88 a->size = sizeof(struct sockaddr_in6);
42f4e3c4
LP
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);
0e098b15 101 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
42f4e3c4 102
1c24e7bd 103 } else if (*s == '@') {
42f4e3c4
LP
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);
0e098b15 113 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
42f4e3c4 114
0fc0f14b
SH
115 } else if (startswith(s, "vsock:")) {
116 /* AF_VSOCK socket in vsock:cid:port notation */
fbd0b64f 117 const char *cid_start = s + STRLEN("vsock:");
89220e2f 118 unsigned port;
0fc0f14b
SH
119
120 e = strchr(cid_start, ':');
121 if (!e)
122 return -EINVAL;
123
89220e2f 124 r = safe_atou(e+1, &port);
0fc0f14b
SH
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;
89220e2f 137 a->sockaddr.vm.svm_port = port;
0fc0f14b
SH
138 a->size = sizeof(struct sockaddr_vm);
139
42f4e3c4 140 } else {
89220e2f
LP
141 uint16_t port;
142
4d49b48c
LP
143 e = strchr(s, ':');
144 if (e) {
89220e2f 145 r = parse_ip_port(e + 1, &port);
4d49b48c 146 if (r < 0)
542563ba
LP
147 return r;
148
4d49b48c 149 n = strndupa(s, e-s);
42f4e3c4 150
542563ba 151 /* IPv4 in w.x.y.z:p notation? */
4d49b48c
LP
152 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
153 if (r < 0)
542563ba 154 return -errno;
42f4e3c4 155
542563ba
LP
156 if (r > 0) {
157 /* Gotcha, it's a traditional IPv4 address */
4d49b48c 158 a->sockaddr.in.sin_family = AF_INET;
89220e2f 159 a->sockaddr.in.sin_port = htobe16(port);
542563ba
LP
160 a->size = sizeof(struct sockaddr_in);
161 } else {
162 unsigned idx;
42f4e3c4 163
4d49b48c 164 if (strlen(n) > IF_NAMESIZE-1)
acbb0225 165 return -EINVAL;
acbb0225 166
542563ba
LP
167 /* Uh, our last resort, an interface name */
168 idx = if_nametoindex(n);
83c60c9f 169 if (idx == 0)
542563ba 170 return -EINVAL;
42f4e3c4 171
542563ba 172 a->sockaddr.in6.sin6_family = AF_INET6;
89220e2f 173 a->sockaddr.in6.sin6_port = htobe16(port);
542563ba 174 a->sockaddr.in6.sin6_scope_id = idx;
83c60c9f 175 a->sockaddr.in6.sin6_addr = in6addr_any;
542563ba
LP
176 a->size = sizeof(struct sockaddr_in6);
177 }
42f4e3c4
LP
178 } else {
179
180 /* Just a port */
89220e2f 181 r = parse_ip_port(s, &port);
5198dabc 182 if (r < 0)
42f4e3c4
LP
183 return r;
184
5bfcc1c6
FF
185 if (socket_ipv6_is_supported()) {
186 a->sockaddr.in6.sin6_family = AF_INET6;
89220e2f 187 a->sockaddr.in6.sin6_port = htobe16(port);
5bfcc1c6
FF
188 a->sockaddr.in6.sin6_addr = in6addr_any;
189 a->size = sizeof(struct sockaddr_in6);
190 } else {
4d49b48c 191 a->sockaddr.in.sin_family = AF_INET;
89220e2f 192 a->sockaddr.in.sin_port = htobe16(port);
4d49b48c 193 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
5bfcc1c6
FF
194 a->size = sizeof(struct sockaddr_in);
195 }
42f4e3c4
LP
196 }
197 }
198
199 return 0;
200}
201
7693146d
LP
202int 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
7a22745a
LP
221int socket_address_parse_netlink(SocketAddress *a, const char *s) {
222 int family;
223 unsigned group = 0;
f8b69d1d 224 _cleanup_free_ char *sfamily = NULL;
7a22745a
LP
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)
bcb161b0 233 return errno > 0 ? -errno : -EINVAL;
7a22745a 234
f8b69d1d
MS
235 family = netlink_family_from_string(sfamily);
236 if (family < 0)
237 return -EINVAL;
7a22745a
LP
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
542563ba 249int socket_address_verify(const SocketAddress *a) {
42f4e3c4
LP
250 assert(a);
251
542563ba 252 switch (socket_address_family(a)) {
42f4e3c4 253
7a22745a
LP
254 case AF_INET:
255 if (a->size != sizeof(struct sockaddr_in))
256 return -EINVAL;
42f4e3c4 257
4d49b48c 258 if (a->sockaddr.in.sin_port == 0)
7a22745a 259 return -EINVAL;
42f4e3c4 260
ec2ce0c5 261 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
7a22745a 262 return -EINVAL;
42f4e3c4 263
7a22745a
LP
264 return 0;
265
266 case AF_INET6:
267 if (a->size != sizeof(struct sockaddr_in6))
268 return -EINVAL;
42f4e3c4 269
7a22745a
LP
270 if (a->sockaddr.in6.sin6_port == 0)
271 return -EINVAL;
42f4e3c4 272
ec2ce0c5 273 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
7a22745a 274 return -EINVAL;
42f4e3c4 275
7a22745a 276 return 0;
42f4e3c4 277
7a22745a
LP
278 case AF_UNIX:
279 if (a->size < offsetof(struct sockaddr_un, sun_path))
280 return -EINVAL;
42f4e3c4 281
7a22745a 282 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
42f4e3c4 283
7a22745a
LP
284 if (a->sockaddr.un.sun_path[0] != 0) {
285 char *e;
286
287 /* path */
4d49b48c
LP
288 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
289 if (!e)
7a22745a
LP
290 return -EINVAL;
291
292 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
293 return -EINVAL;
42f4e3c4 294 }
7a22745a 295 }
42f4e3c4 296
ec2ce0c5 297 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
7a22745a 298 return -EINVAL;
42f4e3c4 299
7a22745a
LP
300 return 0;
301
302 case AF_NETLINK:
303
304 if (a->size != sizeof(struct sockaddr_nl))
305 return -EINVAL;
306
ec2ce0c5 307 if (!IN_SET(a->type, SOCK_RAW, SOCK_DGRAM))
7a22745a
LP
308 return -EINVAL;
309
310 return 0;
311
0fc0f14b
SH
312 case AF_VSOCK:
313 if (a->size != sizeof(struct sockaddr_vm))
314 return -EINVAL;
315
ec2ce0c5 316 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
0fc0f14b
SH
317 return -EINVAL;
318
319 return 0;
320
7a22745a
LP
321 default:
322 return -EAFNOSUPPORT;
42f4e3c4
LP
323 }
324}
325
4d49b48c 326int socket_address_print(const SocketAddress *a, char **ret) {
42f4e3c4 327 int r;
4d49b48c 328
42f4e3c4 329 assert(a);
4d49b48c 330 assert(ret);
42f4e3c4 331
4d49b48c
LP
332 r = socket_address_verify(a);
333 if (r < 0)
42f4e3c4
LP
334 return r;
335
4d49b48c 336 if (socket_address_family(a) == AF_NETLINK) {
7fd1b19b 337 _cleanup_free_ char *sfamily = NULL;
7a22745a 338
f8b69d1d 339 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
7a22745a 340 if (r < 0)
f8b69d1d 341 return r;
4d49b48c
LP
342
343 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
8520cfa5
MS
344 if (r < 0)
345 return -ENOMEM;
7a22745a
LP
346
347 return 0;
348 }
349
3b1c5241 350 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
42f4e3c4
LP
351}
352
4f2d528d
LP
353bool socket_address_can_accept(const SocketAddress *a) {
354 assert(a);
355
356 return
3742095b 357 IN_SET(a->type, SOCK_STREAM, SOCK_SEQPACKET);
4f2d528d 358}
a16e1123
LP
359
360bool 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
a16e1123
LP
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:
4d49b48c 378 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
a16e1123
LP
379 return false;
380
4d49b48c 381 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
a16e1123
LP
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:
710708a5
MS
396 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
397 b->size <= offsetof(struct sockaddr_un, sun_path))
398 return false;
399
a16e1123
LP
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]) {
e3f791a2 404 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0))
a16e1123
LP
405 return false;
406 } else {
c78e47a6
MS
407 if (a->size != b->size)
408 return false;
409
b12c1e7c 410 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
a16e1123
LP
411 return false;
412 }
413
414 break;
415
7a22745a 416 case AF_NETLINK:
7a22745a
LP
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
0fc0f14b
SH
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
a16e1123
LP
434 default:
435 /* Cannot compare, so we assume the addresses are different */
436 return false;
437 }
438
439 return true;
440}
441
27ca8d7a 442bool socket_address_is(const SocketAddress *a, const char *s, int type) {
a16e1123
LP
443 struct SocketAddress b;
444
445 assert(a);
446 assert(s);
447
448 if (socket_address_parse(&b, s) < 0)
449 return false;
450
27ca8d7a
LP
451 b.type = type;
452
a16e1123 453 return socket_address_equal(a, &b);
6e2ef85b
LP
454}
455
7a22745a
LP
456bool 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
a57f7e2c 468const char* socket_address_get_path(const SocketAddress *a) {
6e2ef85b
LP
469 assert(a);
470
471 if (socket_address_family(a) != AF_UNIX)
a57f7e2c 472 return NULL;
6e2ef85b
LP
473
474 if (a->sockaddr.un.sun_path[0] == 0)
a57f7e2c 475 return NULL;
a16e1123 476
a57f7e2c 477 return a->sockaddr.un.sun_path;
a16e1123 478}
c0120d99 479
5bfcc1c6 480bool socket_ipv6_is_supported(void) {
629abfc2 481 if (access("/proc/net/if_inet6", F_OK) != 0)
90ab5042 482 return false;
f89f1e8f 483
7377964d 484 return true;
5bfcc1c6
FF
485}
486
01e10de3 487bool socket_address_matches_fd(const SocketAddress *a, int fd) {
dbafedac
MS
488 SocketAddress b;
489 socklen_t solen;
01e10de3
LP
490
491 assert(a);
492 assert(fd >= 0);
493
dbafedac
MS
494 b.size = sizeof(b.sockaddr);
495 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
01e10de3
LP
496 return false;
497
dbafedac 498 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
01e10de3
LP
499 return false;
500
dbafedac
MS
501 solen = sizeof(b.type);
502 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
01e10de3
LP
503 return false;
504
dbafedac 505 if (b.type != a->type)
01e10de3
LP
506 return false;
507
508 if (a->protocol != 0) {
dbafedac
MS
509 solen = sizeof(b.protocol);
510 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
01e10de3
LP
511 return false;
512
dbafedac 513 if (b.protocol != a->protocol)
01e10de3
LP
514 return false;
515 }
516
02233928 517 return socket_address_equal(a, &b);
01e10de3
LP
518}
519
f6aac5bf 520int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) {
3b1c5241
SL
521 union sockaddr_union *sa = (union sockaddr_union*) _sa;
522
f6aac5bf
LP
523 /* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */
524
3b1c5241
SL
525 assert(sa);
526
0fc0f14b 527 switch (sa->sa.sa_family) {
f6aac5bf 528
0fc0f14b 529 case AF_INET:
f6aac5bf 530 *ret_port = be16toh(sa->in.sin_port);
0fc0f14b 531 return 0;
3b1c5241 532
0fc0f14b 533 case AF_INET6:
f6aac5bf 534 *ret_port = be16toh(sa->in6.sin6_port);
0fc0f14b
SH
535 return 0;
536
537 case AF_VSOCK:
f6aac5bf 538 *ret_port = sa->vm.svm_port;
0fc0f14b
SH
539 return 0;
540
541 default:
542 return -EAFNOSUPPORT;
543 }
3b1c5241
SL
544}
545
546int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
4d49b48c 547 union sockaddr_union *sa = (union sockaddr_union*) _sa;
8569a776 548 char *p;
fc25ad25 549 int r;
8569a776 550
4d49b48c
LP
551 assert(sa);
552 assert(salen >= sizeof(sa->sa.sa_family));
8569a776 553
4d49b48c 554 switch (sa->sa.sa_family) {
8569a776
LP
555
556 case AF_INET: {
557 uint32_t a;
558
8e38570e 559 a = be32toh(sa->in.sin_addr.s_addr);
8569a776 560
fc25ad25
ZJS
561 if (include_port)
562 r = asprintf(&p,
3b1c5241
SL
563 "%u.%u.%u.%u:%u",
564 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
8e38570e 565 be16toh(sa->in.sin_port));
fc25ad25
ZJS
566 else
567 r = asprintf(&p,
3b1c5241 568 "%u.%u.%u.%u",
fc25ad25
ZJS
569 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
570 if (r < 0)
571 return -ENOMEM;
8569a776
LP
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
fc25ad25
ZJS
580 if (translate_ipv6 &&
581 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
4d49b48c 582 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
fc25ad25
ZJS
583 if (include_port)
584 r = asprintf(&p,
3b1c5241
SL
585 "%u.%u.%u.%u:%u",
586 a[0], a[1], a[2], a[3],
8e38570e 587 be16toh(sa->in6.sin6_port));
fc25ad25
ZJS
588 else
589 r = asprintf(&p,
3b1c5241 590 "%u.%u.%u.%u",
fc25ad25
ZJS
591 a[0], a[1], a[2], a[3]);
592 if (r < 0)
593 return -ENOMEM;
8569a776
LP
594 } else {
595 char a[INET6_ADDRSTRLEN];
596
3b1c5241
SL
597 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
598
599 if (include_port) {
fc25ad25 600 r = asprintf(&p,
3b1c5241
SL
601 "[%s]:%u",
602 a,
8e38570e 603 be16toh(sa->in6.sin6_port));
fc25ad25 604 if (r < 0)
3b1c5241
SL
605 return -ENOMEM;
606 } else {
607 p = strdup(a);
608 if (!p)
609 return -ENOMEM;
610 }
8569a776
LP
611 }
612
613 break;
614 }
615
4d49b48c
LP
616 case AF_UNIX:
617 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
618 p = strdup("<unnamed>");
619 if (!p)
620 return -ENOMEM;
8569a776 621
4d49b48c
LP
622 } else if (sa->un.sun_path[0] == 0) {
623 /* abstract */
8569a776 624
4d49b48c
LP
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));
0810bc56 640 if (!p)
4d49b48c
LP
641 return -ENOMEM;
642 }
8569a776
LP
643
644 break;
8569a776 645
0fc0f14b
SH
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
8569a776 658 default:
15411c0c 659 return -EOPNOTSUPP;
8569a776
LP
660 }
661
662 *ret = p;
663 return 0;
664}
665
366b7db4 666int getpeername_pretty(int fd, bool include_port, char **ret) {
4d49b48c 667 union sockaddr_union sa;
b31f535c 668 socklen_t salen = sizeof(sa);
eff05270 669 int r;
4d49b48c
LP
670
671 assert(fd >= 0);
672 assert(ret);
673
4d49b48c
LP
674 if (getpeername(fd, &sa.sa, &salen) < 0)
675 return -errno;
676
677 if (sa.sa.sa_family == AF_UNIX) {
39883f62 678 struct ucred ucred = {};
4d49b48c
LP
679
680 /* UNIX connection sockets are anonymous, so let's use
681 * PID/UID as pretty credentials instead */
682
eff05270
LP
683 r = getpeercred(fd, &ucred);
684 if (r < 0)
685 return r;
4d49b48c 686
de0671ee 687 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
4d49b48c
LP
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
366b7db4 696 return sockaddr_pretty(&sa.sa, salen, true, include_port, ret);
4d49b48c
LP
697}
698
699int getsockname_pretty(int fd, char **ret) {
700 union sockaddr_union sa;
b31f535c 701 socklen_t salen = sizeof(sa);
4d49b48c
LP
702
703 assert(fd >= 0);
704 assert(ret);
705
4d49b48c
LP
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
3b1c5241 714 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
4d49b48c
LP
715}
716
b31f535c
ZJS
717int 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
6326a143 723 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS);
b31f535c 724 if (r != 0) {
b31f535c
ZJS
725 int saved_errno = errno;
726
3b1c5241 727 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
f647962d 728 if (r < 0)
1938ac51 729 return r;
b31f535c 730
279d3c9c 731 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
cb651834
ZJS
732 } else {
733 ret = strdup(host);
734 if (!ret)
1938ac51 735 return -ENOMEM;
cb651834 736 }
b31f535c
ZJS
737
738 *_ret = ret;
739 return 0;
740}
741
bd1fe7c7
LP
742int 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
7a22745a
LP
757static 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",
5570d7f9
JG
774 [NETLINK_ECRYPTFS] = "ecryptfs",
775 [NETLINK_RDMA] = "rdma",
7a22745a
LP
776};
777
f8b69d1d 778DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
7a22745a 779
c0120d99
LP
780static 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
786DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
f01e5736 787
b54e98ef 788SocketAddressBindIPv6Only socket_address_bind_ipv6_only_or_bool_from_string(const char *n) {
6f90844f
YW
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
f01e5736
LP
800bool 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
0fc0f14b
SH
813 if (a->sa.sa_family == AF_VSOCK)
814 return a->vm.svm_cid == b->vm.svm_cid;
815
f01e5736
LP
816 return false;
817}
2583fbea
LP
818
819int 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
837int 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
854static 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
861DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
862
ef76dff2
LP
863bool 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
49bfc877 876 if (dot_or_dot_dot(p))
ef76dff2
LP
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
4c701096 886 if (IN_SET(*p, ':', '/'))
ef76dff2
LP
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
26808948
SS
899bool 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
2583fbea
LP
919int 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
bbcc701e
LP
934 /* Check if the data is actually useful and not suppressed due to namespacing issues */
935 if (!pid_is_valid(u.pid))
2583fbea
LP
936 return -ENODATA;
937
bbcc701e
LP
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
2583fbea
LP
941 *ucred = u;
942 return 0;
943}
944
945int getpeersec(int fd, char **ret) {
217d8967 946 _cleanup_free_ char *s = NULL;
2583fbea 947 socklen_t n = 64;
2583fbea
LP
948
949 assert(fd >= 0);
950 assert(ret);
951
217d8967
LP
952 for (;;) {
953 s = new0(char, n+1);
954 if (!s)
955 return -ENOMEM;
2583fbea 956
217d8967
LP
957 if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n) >= 0)
958 break;
2583fbea
LP
959
960 if (errno != ERANGE)
961 return -errno;
962
217d8967 963 s = mfree(s);
2583fbea
LP
964 }
965
217d8967 966 if (isempty(s))
2583fbea 967 return -EOPNOTSUPP;
2583fbea 968
ae2a15bc 969 *ret = TAKE_PTR(s);
217d8967 970
2583fbea
LP
971 return 0;
972}
973
43f2c88d
LP
974int getpeergroups(int fd, gid_t **ret) {
975 socklen_t n = sizeof(gid_t) * 64;
976 _cleanup_free_ gid_t *d = NULL;
977
75f40779 978 assert(fd >= 0);
43f2c88d
LP
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
1cc6c93a 1001 *ret = TAKE_PTR(d);
43f2c88d
LP
1002
1003 return (int) n;
1004}
1005
726f4c47
ZJS
1006int send_one_fd_sa(
1007 int transport_fd,
1008 int fd,
1009 const struct sockaddr *sa, socklen_t len,
1010 int flags) {
1011
2583fbea
LP
1012 union {
1013 struct cmsghdr cmsghdr;
1014 uint8_t buf[CMSG_SPACE(sizeof(int))];
1015 } control = {};
1016 struct msghdr mh = {
726f4c47
ZJS
1017 .msg_name = (struct sockaddr*) sa,
1018 .msg_namelen = len,
2583fbea
LP
1019 .msg_control = &control,
1020 .msg_controllen = sizeof(control),
1021 };
3c171f0b 1022 struct cmsghdr *cmsg;
2583fbea
LP
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
1040int 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_NOSIGNAL | 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}
4edc2c9b
LP
1081
1082ssize_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
96d49011 1087 * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't
4edc2c9b
LP
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) {
3742095b 1094 if (IN_SET(errno, EOPNOTSUPP, EFAULT))
4edc2c9b
LP
1095 goto fallback;
1096
1097 return -errno;
1098 }
1099 if (l == 0)
1100 goto fallback;
1101
1102 return l;
1103
1104fallback:
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}
60d9771c
LP
1115
1116int flush_accept(int fd) {
1117
1118 struct pollfd pollfd = {
1119 .fd = fd,
1120 .events = POLLIN,
1121 };
1122 int r;
1123
60d9771c
LP
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}
29206d46
LP
1153
1154struct 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}
429b4350
LP
1167
1168int 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}