• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 15263807472

26 May 2025 08:53PM UTC coverage: 72.046% (-0.002%) from 72.048%
15263807472

push

github

yuwata
src/core/manager.c: log preset activity on first boot

This gives us a little more information about what units were enabled
or disabled on that first boot and will be useful for OS developers
tracking down the source of unit state.

An example with this enabled looks like:

```
NET: Registered PF_VSOCK protocol family
systemd[1]: Applying preset policy.
systemd[1]: Unit /etc/systemd/system/dnsmasq.service is masked, ignoring.
systemd[1]: Unit /etc/systemd/system/systemd-repart.service is masked, ignoring.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket'.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir.mount' → '/etc/systemd/system/var-mnt-workdir.mount'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir\x2dtmp.mount' → '/etc/systemd/system/var-mnt-workdir\x2dtmp.mount'.
systemd[1]: Created symlink '/etc/systemd/system/afterburn-sshkeys.target.requires/afterburn-sshkeys@core.service' → '/usr/lib/systemd/system/afterburn-sshkeys@.service'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket' → '/usr/lib/systemd/system/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket' → '/usr/lib/systemd/system/systemd-resolved-monitor.socket'.
systemd[1]: Populated /etc with preset unit settings.
```

Considering it only happens on first boot and not on every boot I think
the extra information is worth the extra verbosity in the logs just for
that boot.

5 of 6 new or added lines in 1 file covered. (83.33%)

5463 existing lines in 165 files now uncovered.

299151 of 415222 relevant lines covered (72.05%)

702386.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.9
/src/basic/in-addr-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <arpa/inet.h>
4
#include <endian.h>
5
#include <stdio.h>
6

7
#include "alloc-util.h"
8
#include "errno-util.h"
9
#include "hash-funcs.h"
10
#include "in-addr-util.h"
11
#include "logarithm.h"
12
#include "memory-util.h"
13
#include "parse-util.h"
14
#include "random-util.h"
15
#include "siphash24.h"
16
#include "stdio-util.h"
17
#include "string-util.h"
18

19
bool in4_addr_is_null(const struct in_addr *a) {
120,327✔
20
        assert(a);
120,327✔
21

22
        return a->s_addr == 0;
120,327✔
23
}
24

25
bool in6_addr_is_null(const struct in6_addr *a) {
71,635✔
26
        assert(a);
71,635✔
27

28
        return eqzero(a->in6_u.u6_addr32);
71,635✔
29
}
30

31
int in_addr_is_null(int family, const union in_addr_union *u) {
108,301✔
32
        assert(u);
108,301✔
33

34
        if (family == AF_INET)
108,301✔
35
                return in4_addr_is_null(&u->in);
51,843✔
36

37
        if (family == AF_INET6)
56,458✔
38
                return in6_addr_is_null(&u->in6);
39,355✔
39

40
        return -EAFNOSUPPORT;
41
}
42

43
bool in4_addr_is_link_local(const struct in_addr *a) {
8,589✔
44
        assert(a);
8,589✔
45

46
        return (be32toh(a->s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
8,589✔
47
}
48

49
bool in4_addr_is_link_local_dynamic(const struct in_addr *a) {
89✔
50
        assert(a);
89✔
51

52
        if (!in4_addr_is_link_local(a))
89✔
53
                return false;
54

55
        /* 169.254.0.0/24 and 169.254.255.0/24 must not be used for the dynamic IPv4LL assignment.
56
         * See RFC 3927 Section 2.1:
57
         * The IPv4 prefix 169.254/16 is registered with the IANA for this purpose. The first 256 and last
58
         * 256 addresses in the 169.254/16 prefix are reserved for future use and MUST NOT be selected by a
59
         * host using this dynamic configuration mechanism. */
60
        return !IN_SET(be32toh(a->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U);
88✔
61
}
62

63
bool in6_addr_is_link_local(const struct in6_addr *a) {
5,084✔
64
        assert(a);
5,084✔
65

66
        return (a->in6_u.u6_addr32[0] & htobe32(0xffc00000)) == htobe32(0xfe800000);
5,084✔
67
}
68

69
int in_addr_is_link_local(int family, const union in_addr_union *u) {
4,299✔
70
        assert(u);
4,299✔
71

72
        if (family == AF_INET)
4,299✔
73
                return in4_addr_is_link_local(&u->in);
3,116✔
74

75
        if (family == AF_INET6)
1,183✔
76
                return in6_addr_is_link_local(&u->in6);
1,183✔
77

78
        return -EAFNOSUPPORT;
79
}
80

81
bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a) {
2✔
82
        assert(a);
2✔
83

84
        /* ff02::1 */
85
        return be32toh(a->s6_addr32[0]) == UINT32_C(0xff020000) &&
2✔
UNCOV
86
                a->s6_addr32[1] == 0 &&
×
87
                a->s6_addr32[2] == 0 &&
2✔
UNCOV
88
                be32toh(a->s6_addr32[3]) == UINT32_C(0x00000001);
×
89
}
90

91
bool in4_addr_is_multicast(const struct in_addr *a) {
15✔
92
        assert(a);
15✔
93

94
        return IN_MULTICAST(be32toh(a->s_addr));
15✔
95
}
96

97
bool in6_addr_is_multicast(const struct in6_addr *a) {
182✔
98
        assert(a);
182✔
99

100
        return a->in6_u.u6_addr8[0] == 0xff;
182✔
101
}
102

103
int in_addr_is_multicast(int family, const union in_addr_union *u) {
24✔
104
        assert(u);
24✔
105

106
        if (family == AF_INET)
24✔
107
                return in4_addr_is_multicast(&u->in);
15✔
108

109
        if (family == AF_INET6)
9✔
110
                return in6_addr_is_multicast(&u->in6);
9✔
111

112
        return -EAFNOSUPPORT;
113
}
114

115
bool in4_addr_is_local_multicast(const struct in_addr *a) {
2✔
116
        assert(a);
2✔
117

118
        return (be32toh(a->s_addr) & UINT32_C(0xffffff00)) == UINT32_C(0xe0000000);
2✔
119
}
120

121
bool in4_addr_is_localhost(const struct in_addr *a) {
20,169✔
122
        assert(a);
20,169✔
123

124
        /* All of 127.x.x.x is localhost. */
125
        return (be32toh(a->s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24;
20,169✔
126
}
127

128
bool in4_addr_is_non_local(const struct in_addr *a) {
780✔
129
        /* Whether the address is not null and not localhost.
130
         *
131
         * As such, it is suitable to configure as DNS/NTP server from DHCP. */
132
        return !in4_addr_is_null(a) &&
1,560✔
133
               !in4_addr_is_localhost(a);
780✔
134
}
135

136
static bool in6_addr_is_loopback(const struct in6_addr *a) {
13,698✔
137
        return memcmp(a, &(struct in6_addr) IN6ADDR_LOOPBACK_INIT, sizeof(struct in6_addr)) == 0;
13,698✔
138
}
139

140
int in_addr_is_localhost(int family, const union in_addr_union *u) {
30,727✔
141
        assert(u);
30,727✔
142

143
        if (family == AF_INET)
30,727✔
144
                return in4_addr_is_localhost(&u->in);
17,029✔
145

146
        if (family == AF_INET6)
13,698✔
147
                return in6_addr_is_loopback(&u->in6);
13,698✔
148

149
        return -EAFNOSUPPORT;
150
}
151

UNCOV
152
int in_addr_is_localhost_one(int family, const union in_addr_union *u) {
×
UNCOV
153
        assert(u);
×
154

UNCOV
155
        if (family == AF_INET)
×
156
                /* 127.0.0.1 */
157
                return be32toh(u->in.s_addr) == UINT32_C(0x7F000001);
×
158

159
        if (family == AF_INET6)
×
UNCOV
160
                return in6_addr_is_loopback(&u->in6);
×
161

162
        return -EAFNOSUPPORT;
163
}
164

165
bool in6_addr_is_ipv4_mapped_address(const struct in6_addr *a) {
5✔
166
        return a->s6_addr32[0] == 0 &&
6✔
167
                a->s6_addr32[1] == 0 &&
5✔
168
                a->s6_addr32[2] == htobe32(UINT32_C(0x0000ffff));
1✔
169
}
170

171
bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b) {
117,166✔
172
        assert(a);
117,166✔
173
        assert(b);
117,166✔
174

175
        return a->s_addr == b->s_addr;
117,166✔
176
}
177

178
bool in6_addr_equal(const struct in6_addr *a, const struct in6_addr *b) {
14,848✔
179
        assert(a);
14,848✔
180
        assert(b);
14,848✔
181

182
        return memcmp(a, b, sizeof(struct in6_addr)) == 0;
14,848✔
183
}
184

185
int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) {
117,876✔
186
        assert(a);
117,876✔
187
        assert(b);
117,876✔
188

189
        if (family == AF_INET)
117,876✔
190
                return in4_addr_equal(&a->in, &b->in);
108,397✔
191

192
        if (family == AF_INET6)
9,479✔
193
                return in6_addr_equal(&a->in6, &b->in6);
9,479✔
194

195
        return -EAFNOSUPPORT;
196
}
197

198
bool in4_addr_prefix_intersect(
824✔
199
                const struct in_addr *a,
200
                unsigned aprefixlen,
201
                const struct in_addr *b,
202
                unsigned bprefixlen) {
203

204
        assert(a);
824✔
205
        assert(b);
824✔
206

207
        unsigned m = MIN3(aprefixlen, bprefixlen, (unsigned) (sizeof(struct in_addr) * 8));
824✔
208
        if (m == 0)
824✔
209
                return true; /* Let's return earlier, to avoid shift by 32. */
210

211
        uint32_t x = be32toh(a->s_addr ^ b->s_addr);
822✔
212
        uint32_t n = 0xFFFFFFFFUL << (32 - m);
822✔
213
        return (x & n) == 0;
822✔
214
}
215

216
bool in6_addr_prefix_intersect(
521✔
217
                const struct in6_addr *a,
218
                unsigned aprefixlen,
219
                const struct in6_addr *b,
220
                unsigned bprefixlen) {
221

222
        assert(a);
521✔
223
        assert(b);
521✔
224

225
        unsigned m = MIN3(aprefixlen, bprefixlen, (unsigned) (sizeof(struct in6_addr) * 8));
521✔
226
        if (m == 0)
521✔
227
                return true;
228

229
        for (size_t i = 0; i < sizeof(struct in6_addr); i++) {
845✔
230
                uint8_t x = a->s6_addr[i] ^ b->s6_addr[i];
845✔
231
                uint8_t n = m < 8 ? (0xFF << (8 - m)) : 0xFF;
845✔
232
                if ((x & n) != 0)
845✔
233
                        return false;
234

235
                if (m <= 8)
345✔
236
                        break;
237

238
                m -= 8;
326✔
239
        }
240

241
        return true;
242
}
243

244
int in_addr_prefix_intersect(
1,311✔
245
                int family,
246
                const union in_addr_union *a,
247
                unsigned aprefixlen,
248
                const union in_addr_union *b,
249
                unsigned bprefixlen) {
250

251
        assert(a);
1,311✔
252
        assert(b);
1,311✔
253

254
        /* Checks whether there are any addresses that are in both networks. */
255

256
        if (family == AF_INET)
1,311✔
257
                return in4_addr_prefix_intersect(&a->in, aprefixlen, &b->in, bprefixlen);
824✔
258

259
        if (family == AF_INET6)
487✔
260
                return in6_addr_prefix_intersect(&a->in6, aprefixlen, &b->in6, bprefixlen);
487✔
261

262
        return -EAFNOSUPPORT;
263
}
264

265
int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) {
15✔
266
        assert(u);
15✔
267

268
        /* Increases the network part of an address by one. Returns 0 if that succeeds, or -ERANGE if
269
         * this overflows. */
270

271
        return in_addr_prefix_nth(family, u, prefixlen, 1);
15✔
272
}
273

274
/*
275
 * Calculates the nth prefix of size prefixlen starting from the address denoted by u.
276
 *
277
 * On success 0 will be returned and the calculated prefix will be available in
278
 * u. In case the calculation cannot be performed (invalid prefix length,
279
 * overflows would occur) -ERANGE is returned. If the address family given isn't
280
 * supported -EAFNOSUPPORT will be returned.
281
 *
282
 * Examples:
283
 *   - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 2), returns 0, writes 192.168.2.0 to u
284
 *   - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 0), returns 0, no data written
285
 *   - in_addr_prefix_nth(AF_INET, 255.255.255.0, 24, 1), returns -ERANGE, no data written
286
 *   - in_addr_prefix_nth(AF_INET, 255.255.255.0, 0, 1), returns -ERANGE, no data written
287
 *   - in_addr_prefix_nth(AF_INET6, 2001:db8, 64, 0xff00) returns 0, writes 2001:0db8:0000:ff00:: to u
288
 */
289
int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth) {
138✔
290
        assert(u);
138✔
291

292
        if (prefixlen <= 0)
138✔
293
                return -ERANGE;
294

295
        if (family == AF_INET) {
136✔
296
                uint32_t c, n, t;
19✔
297

298
                if (prefixlen > 32)
19✔
299
                        return -ERANGE;
300

301
                c = be32toh(u->in.s_addr);
19✔
302

303
                t = nth << (32 - prefixlen);
19✔
304

305
                /* Check for wrap */
306
                if (c > UINT32_MAX - t)
19✔
307
                        return -ERANGE;
308

309
                n = c + t;
16✔
310

311
                n &= UINT32_C(0xFFFFFFFF) << (32 - prefixlen);
16✔
312
                u->in.s_addr = htobe32(n);
16✔
313
                return 0;
16✔
314
        }
315

316
        if (family == AF_INET6) {
117✔
317
                bool overflow = false;
117✔
318

319
                if (prefixlen > 128)
117✔
320
                        return -ERANGE;
321

322
                for (unsigned i = 16; i > 0; i--) {
1,989✔
323
                        unsigned t, j = i - 1, p = j * 8;
1,872✔
324

325
                        if (p >= prefixlen) {
1,872✔
326
                                u->in6.s6_addr[j] = 0;
909✔
327
                                continue;
909✔
328
                        }
329

330
                        if (prefixlen - p < 8) {
963✔
331
                                u->in6.s6_addr[j] &= 0xff << (8 - (prefixlen - p));
14✔
332
                                t = u->in6.s6_addr[j] + ((nth & 0xff) << (8 - (prefixlen - p)));
14✔
333
                                nth >>= prefixlen - p;
14✔
334
                        } else {
335
                                t = u->in6.s6_addr[j] + (nth & 0xff) + overflow;
949✔
336
                                nth >>= 8;
949✔
337
                        }
338

339
                        overflow = t > UINT8_MAX;
963✔
340
                        u->in6.s6_addr[j] = (uint8_t) (t & 0xff);
963✔
341
                }
342

343
                if (overflow || nth != 0)
117✔
344
                        return -ERANGE;
345

346
                return 0;
113✔
347
        }
348

349
        return -EAFNOSUPPORT;
350
}
351

352
int in_addr_random_prefix(
42✔
353
                int family,
354
                union in_addr_union *u,
355
                unsigned prefixlen_fixed_part,
356
                unsigned prefixlen) {
357

358
        assert(u);
42✔
359

360
        /* Random network part of an address by one. */
361

362
        if (prefixlen <= 0)
42✔
363
                return 0;
364

365
        if (family == AF_INET) {
42✔
366
                uint32_t c, n;
23✔
367

368
                if (prefixlen_fixed_part > 32)
23✔
UNCOV
369
                        prefixlen_fixed_part = 32;
×
370
                if (prefixlen > 32)
23✔
UNCOV
371
                        prefixlen = 32;
×
372
                if (prefixlen_fixed_part >= prefixlen)
23✔
373
                        return -EINVAL;
23✔
374

375
                c = be32toh(u->in.s_addr);
23✔
376
                c &= ((UINT32_C(1) << prefixlen_fixed_part) - 1) << (32 - prefixlen_fixed_part);
23✔
377

378
                random_bytes(&n, sizeof(n));
23✔
379
                n &= ((UINT32_C(1) << (prefixlen - prefixlen_fixed_part)) - 1) << (32 - prefixlen);
23✔
380

381
                u->in.s_addr = htobe32(n | c);
23✔
382
                return 1;
23✔
383
        }
384

385
        if (family == AF_INET6) {
19✔
386
                struct in6_addr n;
19✔
387
                unsigned i, j;
19✔
388

389
                if (prefixlen_fixed_part > 128)
19✔
UNCOV
390
                        prefixlen_fixed_part = 128;
×
391
                if (prefixlen > 128)
19✔
UNCOV
392
                        prefixlen = 128;
×
393
                if (prefixlen_fixed_part >= prefixlen)
19✔
394
                        return -EINVAL;
19✔
395

396
                random_bytes(&n, sizeof(n));
19✔
397

398
                for (i = 0; i < 16; i++) {
323✔
399
                        uint8_t mask_fixed_part = 0, mask = 0;
304✔
400

401
                        if (i < (prefixlen_fixed_part + 7) / 8) {
304✔
402
                                if (i < prefixlen_fixed_part / 8)
20✔
403
                                        mask_fixed_part = 0xffu;
404
                                else {
UNCOV
405
                                        j = prefixlen_fixed_part % 8;
×
UNCOV
406
                                        mask_fixed_part = ((UINT8_C(1) << (j + 1)) - 1) << (8 - j);
×
407
                                }
408
                        }
409

410
                        if (i < (prefixlen + 7) / 8) {
304✔
411
                                if (i < prefixlen / 8)
178✔
412
                                        mask = 0xffu ^ mask_fixed_part;
162✔
413
                                else {
414
                                        j = prefixlen % 8;
16✔
415
                                        mask = (((UINT8_C(1) << (j + 1)) - 1) << (8 - j)) ^ mask_fixed_part;
16✔
416
                                }
417
                        }
418

419
                        u->in6.s6_addr[i] &= mask_fixed_part;
304✔
420
                        u->in6.s6_addr[i] |= n.s6_addr[i] & mask;
304✔
421
                }
422

423
                return 1;
424
        }
425

426
        return -EAFNOSUPPORT;
427
}
428

429
int in_addr_prefix_range(
51✔
430
                int family,
431
                const union in_addr_union *in,
432
                unsigned prefixlen,
433
                union in_addr_union *ret_start,
434
                union in_addr_union *ret_end) {
435

436
        union in_addr_union start, end;
51✔
437
        int r;
51✔
438

439
        assert(in);
51✔
440

441
        if (!IN_SET(family, AF_INET, AF_INET6))
51✔
442
                return -EAFNOSUPPORT;
51✔
443

444
        if (ret_start) {
51✔
445
                start = *in;
51✔
446
                r = in_addr_prefix_nth(family, &start, prefixlen, 0);
51✔
447
                if (r < 0)
51✔
448
                        return r;
449
        }
450

451
        if (ret_end) {
51✔
452
                end = *in;
51✔
453
                r = in_addr_prefix_nth(family, &end, prefixlen, 1);
51✔
454
                if (r < 0)
51✔
455
                        return r;
456
        }
457

458
        if (ret_start)
51✔
459
                *ret_start = start;
51✔
460
        if (ret_end)
51✔
461
                *ret_end = end;
51✔
462

463
        return 0;
464
}
465

466
int in_addr_to_string(int family, const union in_addr_union *u, char **ret) {
9,646✔
467
        _cleanup_free_ char *x = NULL;
9,646✔
468
        size_t l;
9,646✔
469

470
        assert(u);
9,646✔
471
        assert(ret);
9,646✔
472

473
        if (family == AF_INET)
9,646✔
474
                l = INET_ADDRSTRLEN;
475
        else if (family == AF_INET6)
1,501✔
476
                l = INET6_ADDRSTRLEN;
477
        else
478
                return -EAFNOSUPPORT;
479

480
        x = new(char, l);
9,646✔
481
        if (!x)
9,646✔
482
                return -ENOMEM;
483

484
        errno = 0;
9,646✔
485
        if (!typesafe_inet_ntop(family, u, x, l))
9,646✔
UNCOV
486
                return errno_or_else(EINVAL);
×
487

488
        *ret = TAKE_PTR(x);
9,646✔
489
        return 0;
9,646✔
490
}
491

492
const char* typesafe_inet_ntop(int family, const union in_addr_union *a, char *buf, size_t len) {
445,192✔
493
        return inet_ntop(family, a, buf, len);
445,192✔
494
}
495

496
const char* typesafe_inet_ntop4(const struct in_addr *a, char *buf, size_t len) {
6,873✔
497
        return inet_ntop(AF_INET, a, buf, len);
6,873✔
498
}
499

500
const char* typesafe_inet_ntop6(const struct in6_addr *a, char *buf, size_t len) {
661✔
501
        return inet_ntop(AF_INET6, a, buf, len);
661✔
502
}
503

504
int in_addr_prefix_to_string(
414,547✔
505
                int family,
506
                const union in_addr_union *u,
507
                unsigned prefixlen,
508
                char *buf,
509
                size_t buf_len) {
510

511
        assert(u);
414,547✔
512
        assert(buf);
414,547✔
513

514
        if (!IN_SET(family, AF_INET, AF_INET6))
414,547✔
515
                return -EAFNOSUPPORT;
516

517
        errno = 0;
414,547✔
518
        if (!typesafe_inet_ntop(family, u, buf, buf_len))
414,547✔
UNCOV
519
                return errno_or_else(ENOSPC);
×
520

521
        size_t l = strlen(buf);
414,547✔
522
        if (!snprintf_ok(buf + l, buf_len - l, "/%u", prefixlen))
414,547✔
UNCOV
523
                return -ENOSPC;
×
524
        return 0;
525
}
526

527
int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret) {
1,831✔
528
        _cleanup_free_ char *ip_str = NULL, *x = NULL;
1,831✔
529
        int r;
1,831✔
530

531
        assert(IN_SET(family, AF_INET, AF_INET6));
1,831✔
532
        assert(u);
1,831✔
533
        assert(ret);
1,831✔
534

535
        /* Much like in_addr_to_string(), but optionally appends the zone interface index to the address, to properly
536
         * handle IPv6 link-local addresses. */
537

538
        r = in_addr_to_string(family, u, &ip_str);
1,831✔
539
        if (r < 0)
1,831✔
540
                return r;
541

542
        if (family == AF_INET6) {
1,831✔
543
                r = in_addr_is_link_local(family, u);
779✔
544
                if (r < 0)
779✔
545
                        return r;
546
                if (r == 0)
779✔
547
                        ifindex = 0;
726✔
548
        } else
549
                ifindex = 0; /* For IPv4 address, ifindex is always ignored. */
550

551
        if (port == 0 && ifindex == 0 && isempty(server_name)) {
1,831✔
552
                *ret = TAKE_PTR(ip_str);
1,461✔
553
                return 0;
1,461✔
554
        }
555

556
        const char *separator = isempty(server_name) ? "" : "#";
370✔
557
        server_name = strempty(server_name);
370✔
558

559
        if (port > 0) {
370✔
560
                if (family == AF_INET6) {
26✔
561
                        if (ifindex > 0)
16✔
562
                                r = asprintf(&x, "[%s]:%"PRIu16"%%%i%s%s", ip_str, port, ifindex, separator, server_name);
10✔
563
                        else
564
                                r = asprintf(&x, "[%s]:%"PRIu16"%s%s", ip_str, port, separator, server_name);
6✔
565
                } else
566
                        r = asprintf(&x, "%s:%"PRIu16"%s%s", ip_str, port, separator, server_name);
10✔
567
        } else {
568
                if (ifindex > 0)
344✔
569
                        r = asprintf(&x, "%s%%%i%s%s", ip_str, ifindex, separator, server_name);
24✔
570
                else {
571
                        x = strjoin(ip_str, separator, server_name);
320✔
572
                        r = x ? 0 : -ENOMEM;
320✔
573
                }
574
        }
575
        if (r < 0)
50✔
UNCOV
576
                return -ENOMEM;
×
577

578
        *ret = TAKE_PTR(x);
370✔
579
        return 0;
370✔
580
}
581

582
int in_addr_from_string(int family, const char *s, union in_addr_union *ret) {
216,919✔
583
        union in_addr_union buffer;
216,919✔
584
        assert(s);
216,919✔
585

586
        if (!IN_SET(family, AF_INET, AF_INET6))
216,919✔
587
                return -EAFNOSUPPORT;
216,919✔
588

589
        errno = 0;
216,919✔
590
        if (inet_pton(family, s, ret ?: &buffer) <= 0)
218,117✔
591
                return errno_or_else(EINVAL);
71,518✔
592

593
        return 0;
594
}
595

596
int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret) {
140,236✔
597
        int r;
140,236✔
598

599
        assert(s);
140,236✔
600

601
        r = in_addr_from_string(AF_INET, s, ret);
140,236✔
602
        if (r >= 0) {
140,236✔
603
                if (ret_family)
72,014✔
604
                        *ret_family = AF_INET;
71,794✔
605
                return 0;
72,014✔
606
        }
607

608
        r = in_addr_from_string(AF_INET6, s, ret);
68,222✔
609
        if (r >= 0) {
68,222✔
610
                if (ret_family)
67,645✔
611
                        *ret_family = AF_INET6;
67,631✔
612
                return 0;
67,645✔
613
        }
614

615
        return -EINVAL;
616
}
617

618
unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr) {
342✔
619
        assert(addr);
342✔
620

621
        return 32U - u32ctz(be32toh(addr->s_addr));
342✔
622
}
623

624
/* Calculate an IPv4 netmask from prefix length, for example /8 -> 255.0.0.0. */
625
struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen) {
185,105✔
626
        assert(addr);
185,105✔
627
        assert(prefixlen <= 32);
185,105✔
628

629
        /* Shifting beyond 32 is not defined, handle this specially. */
630
        if (prefixlen == 0)
185,105✔
631
                addr->s_addr = 0;
2,012✔
632
        else
633
                addr->s_addr = htobe32((0xffffffff << (32 - prefixlen)) & 0xffffffff);
183,093✔
634

635
        return addr;
185,105✔
636
}
637

638
/* Calculate an IPv6 netmask from prefix length, for example /16 -> ffff::. */
639
struct in6_addr* in6_addr_prefixlen_to_netmask(struct in6_addr *addr, unsigned char prefixlen) {
165✔
640
        assert(addr);
165✔
641
        assert(prefixlen <= 128);
165✔
642

643
        for (unsigned i = 0; i < 16; i++) {
2,805✔
644
                uint8_t mask;
2,640✔
645

646
                if (prefixlen >= 8) {
2,640✔
647
                        mask = 0xFF;
1,264✔
648
                        prefixlen -= 8;
1,264✔
649
                } else if (prefixlen > 0) {
1,376✔
650
                        mask = 0xFF << (8 - prefixlen);
112✔
651
                        prefixlen = 0;
112✔
652
                } else {
653
                        assert(prefixlen == 0);
654
                        mask = 0;
655
                }
656

657
                addr->s6_addr[i] = mask;
2,640✔
658
        }
659

660
        return addr;
165✔
661
}
662

663
/* Calculate an IPv4 or IPv6 netmask from prefix length, for example /8 -> 255.0.0.0 or /16 -> ffff::. */
664
int in_addr_prefixlen_to_netmask(int family, union in_addr_union *addr, unsigned char prefixlen) {
226✔
665
        assert(addr);
226✔
666

667
        switch (family) {
226✔
668
        case AF_INET:
61✔
669
                in4_addr_prefixlen_to_netmask(&addr->in, prefixlen);
61✔
670
                return 0;
61✔
671
        case AF_INET6:
165✔
672
                in6_addr_prefixlen_to_netmask(&addr->in6, prefixlen);
165✔
673
                return 0;
165✔
674
        default:
675
                return -EAFNOSUPPORT;
676
        }
677
}
678

679
int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen) {
32✔
680
        uint8_t msb_octet = *(uint8_t*) addr;
32✔
681

682
        /* addr may not be aligned, so make sure we only access it byte-wise */
683

684
        assert(addr);
32✔
685
        assert(prefixlen);
32✔
686

687
        if (msb_octet < 128)
32✔
688
                /* class A, leading bits: 0 */
689
                *prefixlen = 8;
16✔
690
        else if (msb_octet < 192)
16✔
691
                /* class B, leading bits 10 */
UNCOV
692
                *prefixlen = 16;
×
693
        else if (msb_octet < 224)
16✔
694
                /* class C, leading bits 110 */
695
                *prefixlen = 24;
16✔
696
        else
697
                /* class D or E, no default prefixlen */
698
                return -ERANGE;
699

700
        return 0;
701
}
702

703
int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask) {
×
704
        unsigned char prefixlen;
×
UNCOV
705
        int r;
×
706

UNCOV
707
        assert(addr);
×
UNCOV
708
        assert(mask);
×
709

UNCOV
710
        r = in4_addr_default_prefixlen(addr, &prefixlen);
×
UNCOV
711
        if (r < 0)
×
UNCOV
712
                return r;
×
713

UNCOV
714
        in4_addr_prefixlen_to_netmask(mask, prefixlen);
×
715
        return 0;
716
}
717

718
int in4_addr_mask(struct in_addr *addr, unsigned char prefixlen) {
185,012✔
719
        struct in_addr mask;
185,012✔
720

721
        assert(addr);
185,012✔
722

723
        if (!in4_addr_prefixlen_to_netmask(&mask, prefixlen))
185,012✔
724
                return -EINVAL;
185,012✔
725

726
        addr->s_addr &= mask.s_addr;
185,012✔
727
        return 0;
185,012✔
728
}
729

730
int in6_addr_mask(struct in6_addr *addr, unsigned char prefixlen) {
141,367✔
731
        unsigned i;
141,367✔
732

733
        for (i = 0; i < 16; i++) {
2,403,239✔
734
                uint8_t mask;
2,261,872✔
735

736
                if (prefixlen >= 8) {
2,261,872✔
737
                        mask = 0xFF;
424,788✔
738
                        prefixlen -= 8;
424,788✔
739
                } else if (prefixlen > 0) {
1,837,084✔
740
                        mask = 0xFF << (8 - prefixlen);
270✔
741
                        prefixlen = 0;
270✔
742
                } else {
743
                        assert(prefixlen == 0);
744
                        mask = 0;
745
                }
746

747
                addr->s6_addr[i] &= mask;
2,261,872✔
748
        }
749

750
        return 0;
141,367✔
751
}
752

753
int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen) {
267,544✔
754
        assert(addr);
267,544✔
755

756
        switch (family) {
267,544✔
757
        case AF_INET:
133,761✔
758
                return in4_addr_mask(&addr->in, prefixlen);
133,761✔
759
        case AF_INET6:
133,783✔
760
                return in6_addr_mask(&addr->in6, prefixlen);
133,783✔
761
        default:
762
                return -EAFNOSUPPORT;
763
        }
764
}
765

766
int in4_addr_prefix_covers_full(
3,876✔
767
                const struct in_addr *prefix,
768
                unsigned char prefixlen,
769
                const struct in_addr *address,
770
                unsigned char address_prefixlen) {
771

772
        struct in_addr masked_prefix, masked_address;
3,876✔
773
        int r;
3,876✔
774

775
        assert(prefix);
3,876✔
776
        assert(address);
3,876✔
777

778
        if (prefixlen > address_prefixlen)
3,876✔
779
                return false;
3,876✔
780

781
        masked_prefix = *prefix;
3,348✔
782
        r = in4_addr_mask(&masked_prefix, prefixlen);
3,348✔
783
        if (r < 0)
3,348✔
784
                return r;
785

786
        masked_address = *address;
3,348✔
787
        r = in4_addr_mask(&masked_address, prefixlen);
3,348✔
788
        if (r < 0)
3,348✔
789
                return r;
790

791
        return in4_addr_equal(&masked_prefix, &masked_address);
3,348✔
792
}
793

794
int in6_addr_prefix_covers_full(
3,563✔
795
                const struct in6_addr *prefix,
796
                unsigned char prefixlen,
797
                const struct in6_addr *address,
798
                unsigned char address_prefixlen) {
799

800
        struct in6_addr masked_prefix, masked_address;
3,563✔
801
        int r;
3,563✔
802

803
        assert(prefix);
3,563✔
804
        assert(address);
3,563✔
805

806
        if (prefixlen > address_prefixlen)
3,563✔
807
                return false;
3,563✔
808

809
        masked_prefix = *prefix;
3,563✔
810
        r = in6_addr_mask(&masked_prefix, prefixlen);
3,563✔
811
        if (r < 0)
3,563✔
812
                return r;
813

814
        masked_address = *address;
3,563✔
815
        r = in6_addr_mask(&masked_address, prefixlen);
3,563✔
816
        if (r < 0)
3,563✔
817
                return r;
818

819
        return in6_addr_equal(&masked_prefix, &masked_address);
3,563✔
820
}
821

822
int in_addr_prefix_covers_full(
7,169✔
823
                int family,
824
                const union in_addr_union *prefix,
825
                unsigned char prefixlen,
826
                const union in_addr_union *address,
827
                unsigned char address_prefixlen) {
828

829
        assert(prefix);
7,169✔
830
        assert(address);
7,169✔
831

832
        switch (family) {
7,169✔
833
        case AF_INET:
3,677✔
834
                return in4_addr_prefix_covers_full(&prefix->in, prefixlen, &address->in, address_prefixlen);
3,677✔
835
        case AF_INET6:
3,492✔
836
                return in6_addr_prefix_covers_full(&prefix->in6, prefixlen, &address->in6, address_prefixlen);
3,492✔
837
        default:
838
                return -EAFNOSUPPORT;
839
        }
840
}
841

842
int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret) {
140,072✔
843
        uint8_t u;
140,072✔
844
        int r;
140,072✔
845

846
        if (!IN_SET(family, AF_INET, AF_INET6))
140,072✔
847
                return -EAFNOSUPPORT;
140,072✔
848

849
        r = safe_atou8(p, &u);
140,072✔
850
        if (r < 0)
140,072✔
851
                return r;
852

853
        if (u > FAMILY_ADDRESS_SIZE(family) * 8)
140,068✔
854
                return -ERANGE;
855

856
        *ret = u;
140,064✔
857
        return 0;
140,064✔
858
}
859

860
int in_addr_prefix_from_string(
1,418✔
861
                const char *p,
862
                int family,
863
                union in_addr_union *ret_prefix,
864
                unsigned char *ret_prefixlen) {
865

866
        _cleanup_free_ char *str = NULL;
1,418✔
867
        union in_addr_union buffer;
1,418✔
868
        const char *e, *l;
1,418✔
869
        unsigned char k;
1,418✔
870
        int r;
1,418✔
871

872
        assert(p);
1,418✔
873

874
        if (!IN_SET(family, AF_INET, AF_INET6))
1,418✔
875
                return -EAFNOSUPPORT;
876

877
        e = strchr(p, '/');
1,418✔
878
        if (e) {
1,418✔
879
                str = strndup(p, e - p);
1,402✔
880
                if (!str)
1,402✔
881
                        return -ENOMEM;
882

883
                l = str;
884
        } else
885
                l = p;
886

887
        r = in_addr_from_string(family, l, &buffer);
1,418✔
888
        if (r < 0)
1,418✔
889
                return r;
890

891
        if (e) {
1,410✔
892
                r = in_addr_parse_prefixlen(family, e+1, &k);
1,397✔
893
                if (r < 0)
1,397✔
894
                        return r;
895
        } else
896
                k = FAMILY_ADDRESS_SIZE(family) * 8;
13✔
897

898
        if (ret_prefix)
1,406✔
899
                *ret_prefix = buffer;
1,406✔
900
        if (ret_prefixlen)
1,406✔
901
                *ret_prefixlen = k;
1,406✔
902

903
        return 0;
904
}
905

906
int in_addr_prefix_from_string_auto_full(
138,971✔
907
                const char *p,
908
                InAddrPrefixLenMode mode,
909
                int *ret_family,
910
                union in_addr_union *ret_prefix,
911
                unsigned char *ret_prefixlen) {
912

913
        _cleanup_free_ char *str = NULL;
138,971✔
914
        union in_addr_union buffer;
138,971✔
915
        const char *e, *l;
138,971✔
916
        unsigned char k;
138,971✔
917
        int family, r;
138,971✔
918

919
        assert(p);
138,971✔
920

921
        e = strchr(p, '/');
138,971✔
922
        if (e) {
138,971✔
923
                str = strndup(p, e - p);
138,679✔
924
                if (!str)
138,679✔
925
                        return -ENOMEM;
926

927
                l = str;
928
        } else
929
                l = p;
930

931
        r = in_addr_from_string_auto(l, &family, &buffer);
138,971✔
932
        if (r < 0)
138,971✔
933
                return r;
934

935
        if (e) {
138,940✔
936
                r = in_addr_parse_prefixlen(family, e+1, &k);
138,675✔
937
                if (r < 0)
138,675✔
938
                        return r;
939
        } else
940
                switch (mode) {
265✔
941
                case PREFIXLEN_FULL:
249✔
942
                        k = FAMILY_ADDRESS_SIZE(family) * 8;
249✔
943
                        break;
249✔
944
                case PREFIXLEN_REFUSE:
945
                        return -ENOANO; /* To distinguish this error from others. */
UNCOV
946
                default:
×
UNCOV
947
                        assert_not_reached();
×
948
                }
949

950
        if (ret_family)
138,920✔
951
                *ret_family = family;
138,920✔
952
        if (ret_prefix)
138,920✔
953
                *ret_prefix = buffer;
138,920✔
954
        if (ret_prefixlen)
138,920✔
955
                *ret_prefixlen = k;
138,920✔
956

957
        return 0;
958
}
959

960
void in_addr_hash_func(const union in_addr_union *u, int family, struct siphash *state) {
831,197✔
961
        assert(u);
831,197✔
962
        assert(state);
831,197✔
963

964
        siphash24_compress(u->bytes, FAMILY_ADDRESS_SIZE(family), state);
831,197✔
965
}
831,197✔
966

967
void in_addr_data_hash_func(const struct in_addr_data *a, struct siphash *state) {
1,112✔
968
        assert(a);
1,112✔
969
        assert(state);
1,112✔
970

971
        siphash24_compress_typesafe(a->family, state);
1,112✔
972
        in_addr_hash_func(&a->address, a->family, state);
1,112✔
973
}
1,112✔
974

975
int in_addr_data_compare_func(const struct in_addr_data *x, const struct in_addr_data *y) {
560✔
976
        int r;
560✔
977

978
        assert(x);
560✔
979
        assert(y);
560✔
980

981
        r = CMP(x->family, y->family);
560✔
982
        if (r != 0)
444✔
983
                return r;
129✔
984

985
        return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
431✔
986
}
987

988
DEFINE_HASH_OPS(
989
        in_addr_data_hash_ops,
990
        struct in_addr_data,
991
        in_addr_data_hash_func,
992
        in_addr_data_compare_func);
993

994
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
227✔
995
        in_addr_data_hash_ops_free,
996
        struct in_addr_data,
997
        in_addr_data_hash_func,
998
        in_addr_data_compare_func,
999
        free);
1000

1001
void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state) {
444✔
1002
        assert(addr);
444✔
1003
        assert(state);
444✔
1004

1005
        siphash24_compress_typesafe(*addr, state);
444✔
1006
}
444✔
1007

1008
int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b) {
162✔
1009
        assert(a);
162✔
1010
        assert(b);
162✔
1011

1012
        return memcmp(a, b, sizeof(*a));
162✔
1013
}
1014

1015
DEFINE_HASH_OPS(
1016
        in6_addr_hash_ops,
1017
        struct in6_addr,
1018
        in6_addr_hash_func,
1019
        in6_addr_compare_func);
1020

1021
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
5✔
1022
        in6_addr_hash_ops_free,
1023
        struct in6_addr,
1024
        in6_addr_hash_func,
1025
        in6_addr_compare_func,
1026
        free);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc