1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <netinet/in.h>
6 #include <sys/socket.h>
8 #include "hash-funcs.h"
15 uint8_t bytes
[CONST_MAX(sizeof(struct in_addr
), sizeof(struct in6_addr
))];
20 union in_addr_union address
;
23 struct in_addr_prefix
{
26 union in_addr_union address
;
29 bool in4_addr_is_null(const struct in_addr
*a
);
30 static inline bool in4_addr_is_set(const struct in_addr
*a
) {
31 return !in4_addr_is_null(a
);
33 bool in6_addr_is_null(const struct in6_addr
*a
);
34 static inline bool in6_addr_is_set(const struct in6_addr
*a
) {
35 return !in6_addr_is_null(a
);
37 int in_addr_is_null(int family
, const union in_addr_union
*u
);
38 static inline bool in_addr_is_set(int family
, const union in_addr_union
*u
) {
39 return in_addr_is_null(family
, u
) == 0;
41 static inline int in_addr_data_is_null(const struct in_addr_data
*a
) {
43 return in_addr_is_null(a
->family
, &a
->address
);
45 static inline bool in_addr_data_is_set(const struct in_addr_data
*a
) {
46 return in_addr_data_is_null(a
);
49 int in_addr_is_multicast(int family
, const union in_addr_union
*u
);
51 bool in4_addr_is_link_local(const struct in_addr
*a
);
52 bool in6_addr_is_link_local(const struct in6_addr
*a
);
53 int in_addr_is_link_local(int family
, const union in_addr_union
*u
);
54 bool in6_addr_is_link_local_all_nodes(const struct in6_addr
*a
);
56 bool in4_addr_is_localhost(const struct in_addr
*a
);
57 int in_addr_is_localhost(int family
, const union in_addr_union
*u
);
59 bool in4_addr_is_local_multicast(const struct in_addr
*a
);
60 bool in4_addr_is_non_local(const struct in_addr
*a
);
61 bool in6_addr_is_ipv4_mapped_address(const struct in6_addr
*a
);
63 bool in4_addr_equal(const struct in_addr
*a
, const struct in_addr
*b
);
64 bool in6_addr_equal(const struct in6_addr
*a
, const struct in6_addr
*b
);
65 int in_addr_equal(int family
, const union in_addr_union
*a
, const union in_addr_union
*b
);
66 int in_addr_prefix_intersect(int family
, const union in_addr_union
*a
, unsigned aprefixlen
, const union in_addr_union
*b
, unsigned bprefixlen
);
67 int in_addr_prefix_next(int family
, union in_addr_union
*u
, unsigned prefixlen
);
68 int in_addr_prefix_nth(int family
, union in_addr_union
*u
, unsigned prefixlen
, uint64_t nth
);
69 int in_addr_random_prefix(int family
, union in_addr_union
*u
, unsigned prefixlen_fixed_part
, unsigned prefixlen
);
70 int in_addr_prefix_range(
72 const union in_addr_union
*in
,
74 union in_addr_union
*ret_start
,
75 union in_addr_union
*ret_end
);
76 int in_addr_to_string(int family
, const union in_addr_union
*u
, char **ret
);
77 static inline int in6_addr_to_string(const struct in6_addr
*u
, char **ret
) {
78 return in_addr_to_string(AF_INET6
, (const union in_addr_union
*) u
, ret
);
80 int in_addr_prefix_to_string(int family
, const union in_addr_union
*u
, unsigned prefixlen
, char **ret
);
81 static inline int in6_addr_prefix_to_string(const struct in6_addr
*u
, unsigned prefixlen
, char **ret
) {
82 return in_addr_prefix_to_string(AF_INET6
, (const union in_addr_union
*) u
, prefixlen
, ret
);
84 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
);
85 static inline int in_addr_ifindex_to_string(int family
, const union in_addr_union
*u
, int ifindex
, char **ret
) {
86 return in_addr_port_ifindex_name_to_string(family
, u
, 0, ifindex
, NULL
, ret
);
88 static inline int in_addr_port_to_string(int family
, const union in_addr_union
*u
, uint16_t port
, char **ret
) {
89 return in_addr_port_ifindex_name_to_string(family
, u
, port
, 0, NULL
, ret
);
91 int in_addr_from_string(int family
, const char *s
, union in_addr_union
*ret
);
92 int in_addr_from_string_auto(const char *s
, int *ret_family
, union in_addr_union
*ret
);
94 unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr
*addr
);
95 struct in_addr
* in4_addr_prefixlen_to_netmask(struct in_addr
*addr
, unsigned char prefixlen
);
96 int in4_addr_default_prefixlen(const struct in_addr
*addr
, unsigned char *prefixlen
);
97 int in4_addr_default_subnet_mask(const struct in_addr
*addr
, struct in_addr
*mask
);
98 int in_addr_mask(int family
, union in_addr_union
*addr
, unsigned char prefixlen
);
99 int in_addr_prefix_covers(int family
, const union in_addr_union
*prefix
, unsigned char prefixlen
, const union in_addr_union
*address
);
100 int in_addr_parse_prefixlen(int family
, const char *p
, unsigned char *ret
);
101 int in_addr_prefix_from_string(const char *p
, int family
, union in_addr_union
*ret_prefix
, unsigned char *ret_prefixlen
);
103 typedef enum InAddrPrefixLenMode
{
104 PREFIXLEN_FULL
, /* Default to prefixlen of address size, 32 for IPv4 or 128 for IPv6, if not specified. */
105 PREFIXLEN_REFUSE
, /* Fail with -ENOANO if prefixlen is not specified. */
106 PREFIXLEN_LEGACY
, /* Default to legacy default prefixlen calculation from address if not specified. */
107 } InAddrPrefixLenMode
;
109 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
);
110 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
) {
111 return in_addr_prefix_from_string_auto_internal(p
, PREFIXLEN_FULL
, ret_family
, ret_prefix
, ret_prefixlen
);
114 static inline size_t FAMILY_ADDRESS_SIZE(int family
) {
115 assert(IN_SET(family
, AF_INET
, AF_INET6
));
116 return family
== AF_INET6
? 16 : 4;
119 /* Workaround for clang, explicitly specify the maximum-size element here.
120 * See also oss-fuzz#11344. */
121 #define IN_ADDR_NULL ((union in_addr_union) { .in6 = {} })
123 void in6_addr_hash_func(const struct in6_addr
*addr
, struct siphash
*state
);
124 int in6_addr_compare_func(const struct in6_addr
*a
, const struct in6_addr
*b
);
126 extern const struct hash_ops in_addr_data_hash_ops
;
127 extern const struct hash_ops in_addr_prefix_hash_ops
;
128 extern const struct hash_ops in_addr_prefix_hash_ops_free
;
129 extern const struct hash_ops in6_addr_hash_ops
;
131 #define IPV4_ADDRESS_FMT_STR "%u.%u.%u.%u"
132 #define IPV4_ADDRESS_FMT_VAL(address) \
133 be32toh((address).s_addr) >> 24, \
134 (be32toh((address).s_addr) >> 16) & 0xFFu, \
135 (be32toh((address).s_addr) >> 8) & 0xFFu, \
136 be32toh((address).s_addr) & 0xFFu