mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-31 15:32:37 +01:00
ie: Extract same-subnet check code to util.h
This commit is contained in:
parent
d383a49b7b
commit
eb1149ca1f
22
src/ie.c
22
src/ie.c
@ -2309,8 +2309,10 @@ int ie_parse_fils_ip_addr_response(struct ie_tlv_iter *iter,
|
||||
memcpy(info.ipv4_gateway_mac, ptr + 4, 6);
|
||||
|
||||
/* Check gateway is on the same subnet */
|
||||
if (info.ipv4_addr && (ntohl(info.ipv4_addr ^ info.ipv4_gateway) &
|
||||
util_netmask_from_prefix(info.ipv4_prefix_len)))
|
||||
if (info.ipv4_addr &&
|
||||
!util_ip_subnet_match(info.ipv4_prefix_len,
|
||||
&info.ipv4_addr,
|
||||
&info.ipv4_gateway))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -2330,17 +2332,11 @@ int ie_parse_fils_ip_addr_response(struct ie_tlv_iter *iter,
|
||||
memcpy(info.ipv6_gateway_mac, ptr + 16, 6);
|
||||
|
||||
/* Check gateway is on the same subnet */
|
||||
if (!l_memeqzero(info.ipv6_addr, 12)) {
|
||||
int n = info.ipv6_prefix_len / 8;
|
||||
uint8_t mask = (1 << (info.ipv6_prefix_len & 7)) - 1;
|
||||
|
||||
if (n && memcmp(info.ipv6_addr, info.ipv6_gateway, n))
|
||||
return -EINVAL;
|
||||
|
||||
if (mask && ((info.ipv6_addr[n] ^
|
||||
info.ipv6_gateway[n]) & mask))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!l_memeqzero(info.ipv6_addr, 16) &&
|
||||
!util_ip_subnet_match(info.ipv6_prefix_len,
|
||||
info.ipv6_addr,
|
||||
info.ipv6_gateway))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*resp_ctrl & IE_FILS_IP_ADDR_RESP_CTRL_IPV4_LIFETIME_INCLUDED)
|
||||
|
14
src/util.h
14
src/util.h
@ -82,9 +82,23 @@ static inline uint32_t util_secure_fill_with_msb(uint32_t val)
|
||||
bool util_ip_prefix_tohl(const char *ip, uint8_t *prefix, uint32_t *start_out,
|
||||
uint32_t *end_out, uint32_t *mask_out);
|
||||
|
||||
/* Host byte-order IPv4 netmask */
|
||||
static inline uint32_t util_netmask_from_prefix(uint8_t prefix_len)
|
||||
{
|
||||
return ~((1ull << (32 - prefix_len)) - 1);
|
||||
}
|
||||
|
||||
/* Expects network byte-order (big-endian) addresses */
|
||||
static inline bool util_ip_subnet_match(uint8_t prefix_len,
|
||||
const void *addr1, const void *addr2)
|
||||
{
|
||||
const uint8_t *u8_1 = addr1;
|
||||
const uint8_t *u8_2 = addr2;
|
||||
uint8_t pref_bytes = prefix_len / 8;
|
||||
|
||||
return (!pref_bytes || !memcmp(u8_1, u8_2, pref_bytes)) &&
|
||||
!((u8_1[pref_bytes] ^ u8_2[pref_bytes]) &
|
||||
~((1u << (8 - (prefix_len % 8))) - 1));
|
||||
}
|
||||
|
||||
#endif /* __UTIL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user