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