/src/systemd/src/basic/in-addr-util.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | #pragma once |
3 | | |
4 | | #include <arpa/inet.h> |
5 | | #include <netinet/in.h> |
6 | | #include <stddef.h> |
7 | | #include <sys/socket.h> |
8 | | |
9 | | #include "hash-funcs.h" |
10 | | #include "macro.h" |
11 | | #include "util.h" |
12 | | |
13 | | union in_addr_union { |
14 | | struct in_addr in; |
15 | | struct in6_addr in6; |
16 | | uint8_t bytes[CONST_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; |
17 | | }; |
18 | | |
19 | | struct in_addr_data { |
20 | | int family; |
21 | | union in_addr_union address; |
22 | | }; |
23 | | |
24 | | bool in4_addr_is_null(const struct in_addr *a); |
25 | 0 | static inline bool in4_addr_is_set(const struct in_addr *a) { |
26 | 0 | return !in4_addr_is_null(a); |
27 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in4_addr_is_set Unexecuted instantiation: link-config.c:in4_addr_is_set Unexecuted instantiation: link-config-gperf.c:in4_addr_is_set |
28 | | bool in6_addr_is_null(const struct in6_addr *a); |
29 | 0 | static inline bool in6_addr_is_set(const struct in6_addr *a) { |
30 | 0 | return !in6_addr_is_null(a); |
31 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in6_addr_is_set Unexecuted instantiation: link-config.c:in6_addr_is_set Unexecuted instantiation: link-config-gperf.c:in6_addr_is_set |
32 | | int in_addr_is_null(int family, const union in_addr_union *u); |
33 | 0 | static inline bool in_addr_is_set(int family, const union in_addr_union *u) { |
34 | 0 | return in_addr_is_null(family, u) == 0; |
35 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in_addr_is_set Unexecuted instantiation: link-config.c:in_addr_is_set Unexecuted instantiation: link-config-gperf.c:in_addr_is_set |
36 | 0 | static inline int in_addr_data_is_null(const struct in_addr_data *a) { |
37 | 0 | assert(a); |
38 | 0 | return in_addr_is_null(a->family, &a->address); |
39 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in_addr_data_is_null Unexecuted instantiation: link-config.c:in_addr_data_is_null Unexecuted instantiation: link-config-gperf.c:in_addr_data_is_null |
40 | 0 | static inline bool in_addr_data_is_set(const struct in_addr_data *a) { |
41 | 0 | return in_addr_data_is_null(a); |
42 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in_addr_data_is_set Unexecuted instantiation: link-config.c:in_addr_data_is_set Unexecuted instantiation: link-config-gperf.c:in_addr_data_is_set |
43 | | |
44 | | int in_addr_is_multicast(int family, const union in_addr_union *u); |
45 | | |
46 | | bool in4_addr_is_link_local(const struct in_addr *a); |
47 | | bool in4_addr_is_link_local_dynamic(const struct in_addr *a); |
48 | | bool in6_addr_is_link_local(const struct in6_addr *a); |
49 | | int in_addr_is_link_local(int family, const union in_addr_union *u); |
50 | | bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a); |
51 | | |
52 | | bool in4_addr_is_localhost(const struct in_addr *a); |
53 | | int in_addr_is_localhost(int family, const union in_addr_union *u); |
54 | | int in_addr_is_localhost_one(int family, const union in_addr_union *u); |
55 | | |
56 | | bool in4_addr_is_local_multicast(const struct in_addr *a); |
57 | | bool in4_addr_is_non_local(const struct in_addr *a); |
58 | | bool in6_addr_is_ipv4_mapped_address(const struct in6_addr *a); |
59 | | |
60 | | bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b); |
61 | | bool in6_addr_equal(const struct in6_addr *a, const struct in6_addr *b); |
62 | | int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); |
63 | | int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); |
64 | | int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); |
65 | | int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth); |
66 | | int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen); |
67 | | int in_addr_prefix_range( |
68 | | int family, |
69 | | const union in_addr_union *in, |
70 | | unsigned prefixlen, |
71 | | union in_addr_union *ret_start, |
72 | | union in_addr_union *ret_end); |
73 | | |
74 | | int in_addr_to_string(int family, const union in_addr_union *u, char **ret); |
75 | 0 | static inline int in6_addr_to_string(const struct in6_addr *u, char **ret) { |
76 | 0 | return in_addr_to_string(AF_INET6, (const union in_addr_union*) u, ret); |
77 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in6_addr_to_string Unexecuted instantiation: link-config.c:in6_addr_to_string Unexecuted instantiation: link-config-gperf.c:in6_addr_to_string |
78 | | |
79 | 0 | static inline const char* typesafe_inet_ntop(int family, const union in_addr_union *a, char *buf, size_t len) { |
80 | 0 | return inet_ntop(family, a, buf, len); |
81 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:typesafe_inet_ntop Unexecuted instantiation: link-config.c:typesafe_inet_ntop Unexecuted instantiation: link-config-gperf.c:typesafe_inet_ntop |
82 | 0 | static inline const char* typesafe_inet_ntop4(const struct in_addr *a, char *buf, size_t len) { |
83 | 0 | return inet_ntop(AF_INET, a, buf, len); |
84 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:typesafe_inet_ntop4 Unexecuted instantiation: link-config.c:typesafe_inet_ntop4 Unexecuted instantiation: link-config-gperf.c:typesafe_inet_ntop4 |
85 | 0 | static inline const char* typesafe_inet_ntop6(const struct in6_addr *a, char *buf, size_t len) { |
86 | 0 | return inet_ntop(AF_INET6, a, buf, len); |
87 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:typesafe_inet_ntop6 Unexecuted instantiation: link-config.c:typesafe_inet_ntop6 Unexecuted instantiation: link-config-gperf.c:typesafe_inet_ntop6 |
88 | | |
89 | | /* Note: the lifetime of the compound literal is the immediately surrounding block, |
90 | | * see C11 ยง6.5.2.5, and |
91 | | * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */ |
92 | | #define IN_ADDR_MAX CONST_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) |
93 | | #define IN_ADDR_TO_STRING(family, addr) typesafe_inet_ntop(family, addr, (char[IN_ADDR_MAX]){}, IN_ADDR_MAX) |
94 | | #define IN4_ADDR_TO_STRING(addr) typesafe_inet_ntop4(addr, (char[INET_ADDRSTRLEN]){}, INET_ADDRSTRLEN) |
95 | | #define IN6_ADDR_TO_STRING(addr) typesafe_inet_ntop6(addr, (char[INET6_ADDRSTRLEN]){}, INET6_ADDRSTRLEN) |
96 | | |
97 | | int in_addr_prefix_to_string( |
98 | | int family, |
99 | | const union in_addr_union *u, |
100 | | unsigned prefixlen, |
101 | | char *buf, |
102 | | size_t buf_len); |
103 | | |
104 | | static inline const char* _in_addr_prefix_to_string( |
105 | | int family, |
106 | | const union in_addr_union *u, |
107 | | unsigned prefixlen, |
108 | | char *buf, |
109 | 0 | size_t buf_len) { |
110 | 0 | /* We assume that this is called with an appropriately sized buffer and can never fail. */ |
111 | 0 | assert_se(in_addr_prefix_to_string(family, u, prefixlen, buf, buf_len) == 0); |
112 | 0 | return buf; |
113 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:_in_addr_prefix_to_string Unexecuted instantiation: link-config.c:_in_addr_prefix_to_string Unexecuted instantiation: link-config-gperf.c:_in_addr_prefix_to_string |
114 | 0 | static inline const char* _in4_addr_prefix_to_string(const struct in_addr *a, unsigned prefixlen, char *buf, size_t buf_len) { |
115 | 0 | return _in_addr_prefix_to_string(AF_INET, (const union in_addr_union *) a, prefixlen, buf, buf_len); |
116 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:_in4_addr_prefix_to_string Unexecuted instantiation: link-config.c:_in4_addr_prefix_to_string Unexecuted instantiation: link-config-gperf.c:_in4_addr_prefix_to_string |
117 | 0 | static inline const char* _in6_addr_prefix_to_string(const struct in6_addr *a, unsigned prefixlen, char *buf, size_t buf_len) { |
118 | 0 | return _in_addr_prefix_to_string(AF_INET6, (const union in_addr_union *) a, prefixlen, buf, buf_len); |
119 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:_in6_addr_prefix_to_string Unexecuted instantiation: link-config.c:_in6_addr_prefix_to_string Unexecuted instantiation: link-config-gperf.c:_in6_addr_prefix_to_string |
120 | | |
121 | | #define PREFIX_SUFFIX_MAX (1 + DECIMAL_STR_MAX(unsigned)) |
122 | | #define IN_ADDR_PREFIX_TO_STRING(family, addr, prefixlen) \ |
123 | | _in_addr_prefix_to_string(family, addr, prefixlen, (char[IN_ADDR_MAX + PREFIX_SUFFIX_MAX]){}, IN_ADDR_MAX + PREFIX_SUFFIX_MAX) |
124 | | #define IN4_ADDR_PREFIX_TO_STRING(addr, prefixlen) \ |
125 | | _in4_addr_prefix_to_string(addr, prefixlen, (char[INET_ADDRSTRLEN + PREFIX_SUFFIX_MAX]){}, INET_ADDRSTRLEN + PREFIX_SUFFIX_MAX) |
126 | | #define IN6_ADDR_PREFIX_TO_STRING(addr, prefixlen) \ |
127 | | _in6_addr_prefix_to_string(addr, prefixlen, (char[INET6_ADDRSTRLEN + PREFIX_SUFFIX_MAX]){}, INET6_ADDRSTRLEN + PREFIX_SUFFIX_MAX) |
128 | | |
129 | | 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); |
130 | 0 | static inline int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) { |
131 | 0 | return in_addr_port_ifindex_name_to_string(family, u, 0, ifindex, NULL, ret); |
132 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in_addr_ifindex_to_string Unexecuted instantiation: link-config.c:in_addr_ifindex_to_string Unexecuted instantiation: link-config-gperf.c:in_addr_ifindex_to_string |
133 | 0 | static inline int in_addr_port_to_string(int family, const union in_addr_union *u, uint16_t port, char **ret) { |
134 | 0 | return in_addr_port_ifindex_name_to_string(family, u, port, 0, NULL, ret); |
135 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in_addr_port_to_string Unexecuted instantiation: link-config.c:in_addr_port_to_string Unexecuted instantiation: link-config-gperf.c:in_addr_port_to_string |
136 | | int in_addr_from_string(int family, const char *s, union in_addr_union *ret); |
137 | | int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret); |
138 | | |
139 | | unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr); |
140 | | struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen); |
141 | | struct in6_addr* in6_addr_prefixlen_to_netmask(struct in6_addr *addr, unsigned char prefixlen); |
142 | | int in_addr_prefixlen_to_netmask(int family, union in_addr_union *addr, unsigned char prefixlen); |
143 | | int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen); |
144 | | int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask); |
145 | | int in4_addr_mask(struct in_addr *addr, unsigned char prefixlen); |
146 | | int in6_addr_mask(struct in6_addr *addr, unsigned char prefixlen); |
147 | | int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen); |
148 | | int in4_addr_prefix_covers(const struct in_addr *prefix, unsigned char prefixlen, const struct in_addr *address); |
149 | | int in6_addr_prefix_covers(const struct in6_addr *prefix, unsigned char prefixlen, const struct in6_addr *address); |
150 | | int in_addr_prefix_covers(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address); |
151 | | int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret); |
152 | | int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen); |
153 | | |
154 | | typedef enum InAddrPrefixLenMode { |
155 | | PREFIXLEN_FULL, /* Default to prefixlen of address size, 32 for IPv4 or 128 for IPv6, if not specified. */ |
156 | | PREFIXLEN_REFUSE, /* Fail with -ENOANO if prefixlen is not specified. */ |
157 | | PREFIXLEN_LEGACY, /* Default to legacy default prefixlen calculation from address if not specified. */ |
158 | | } InAddrPrefixLenMode; |
159 | | |
160 | | int in_addr_prefix_from_string_auto_internal(const char *p, InAddrPrefixLenMode mode, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen); |
161 | 0 | static inline int in_addr_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) { |
162 | 0 | return in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_FULL, ret_family, ret_prefix, ret_prefixlen); |
163 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:in_addr_prefix_from_string_auto Unexecuted instantiation: link-config.c:in_addr_prefix_from_string_auto Unexecuted instantiation: link-config-gperf.c:in_addr_prefix_from_string_auto |
164 | | |
165 | 0 | static inline size_t FAMILY_ADDRESS_SIZE(int family) { |
166 | 0 | assert(IN_SET(family, AF_INET, AF_INET6)); |
167 | 0 | return family == AF_INET6 ? 16 : 4; |
168 | 0 | } Unexecuted instantiation: fuzz-link-parser.c:FAMILY_ADDRESS_SIZE Unexecuted instantiation: link-config.c:FAMILY_ADDRESS_SIZE Unexecuted instantiation: link-config-gperf.c:FAMILY_ADDRESS_SIZE |
169 | | |
170 | | #define FAMILY_ADDRESS_SIZE_SAFE(f) \ |
171 | | ({ \ |
172 | | int _f = (f); \ |
173 | | _f == AF_INET ? sizeof(struct in_addr) : \ |
174 | | _f == AF_INET6 ? sizeof(struct in6_addr) : 0; \ |
175 | | }) |
176 | | |
177 | | /* Workaround for clang, explicitly specify the maximum-size element here. |
178 | | * See also oss-fuzz#11344. */ |
179 | | #define IN_ADDR_NULL ((union in_addr_union) { .in6 = {} }) |
180 | | |
181 | | void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state); |
182 | | int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b); |
183 | | |
184 | | extern const struct hash_ops in_addr_data_hash_ops; |
185 | | extern const struct hash_ops in6_addr_hash_ops; |
186 | | extern const struct hash_ops in6_addr_hash_ops_free; |
187 | | |
188 | | #define IPV4_ADDRESS_FMT_STR "%u.%u.%u.%u" |
189 | | #define IPV4_ADDRESS_FMT_VAL(address) \ |
190 | | be32toh((address).s_addr) >> 24, \ |
191 | | (be32toh((address).s_addr) >> 16) & 0xFFu, \ |
192 | | (be32toh((address).s_addr) >> 8) & 0xFFu, \ |
193 | | be32toh((address).s_addr) & 0xFFu |