mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-15 20:45:32 +00:00
glib-aux: fix various nm_ip_addr_*() functions for unaligned addresses
Most of our nm_ip_addr_*() functions take an opaque pointer, that can be either in_addr_t, struct in6_addr or NMIPAddr. They also tend to support that their argument pointer is not aligned. The reason is not very strong, except that usually it's simple to support and it allows the caller to use those low-level functions for pointers of unknown alignment (e.g. from a package on the network). Fix a few cases for that.
This commit is contained in:
parent
232df1c08d
commit
b02aeaf2f3
|
@ -138,20 +138,22 @@ nm_ip4_addr_get_default_prefix(in_addr_t ip)
|
|||
gboolean
|
||||
nm_ip_addr_is_site_local(int addr_family, const void *address)
|
||||
{
|
||||
in_addr_t addr4;
|
||||
NMIPAddr a;
|
||||
|
||||
nm_ip_addr_set(addr_family, &a, address);
|
||||
|
||||
switch (addr_family) {
|
||||
case AF_INET:
|
||||
/* RFC1918 private addresses
|
||||
* 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */
|
||||
addr4 = ntohl(*((const in_addr_t *) address));
|
||||
return (addr4 & 0xff000000) == 0x0a000000 || (addr4 & 0xfff00000) == 0xac100000
|
||||
|| (addr4 & 0xffff0000) == 0xc0a80000;
|
||||
return (a.addr4 & htonl(0xff000000)) == htonl(0x0a000000)
|
||||
|| (a.addr4 & htonl(0xfff00000)) == htonl(0xac100000)
|
||||
|| (a.addr4 & htonl(0xffff0000)) == htonl(0xc0a80000);
|
||||
case AF_INET6:
|
||||
/* IN6_IS_ADDR_SITELOCAL() is for deprecated fec0::/10 addresses (see rfc3879, 4.).
|
||||
* Note that for unique local IPv6 addresses (ULA, fc00::/7) this returns false,
|
||||
* which may or may not be a bug. */
|
||||
return IN6_IS_ADDR_SITELOCAL(address);
|
||||
* Note that for unique local IPv6 addresses (ULA, fc00::/7) this returns false.
|
||||
* This may or may not be a bug of this function. */
|
||||
return IN6_IS_ADDR_SITELOCAL(&a.addr6);
|
||||
default:
|
||||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
@ -169,25 +171,33 @@ nm_ip6_addr_is_ula(const struct in6_addr *address)
|
|||
gconstpointer
|
||||
nm_ip_addr_clear_host_address(int family, gpointer dst, gconstpointer src, guint32 plen)
|
||||
{
|
||||
NMIPAddr a;
|
||||
NMIPAddr a2;
|
||||
|
||||
g_return_val_if_fail(dst, NULL);
|
||||
|
||||
if (!src) {
|
||||
/* allow "self-assignment", by specifying %NULL as source. */
|
||||
src = dst;
|
||||
}
|
||||
|
||||
nm_ip_addr_set(family, &a, src);
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
g_return_val_if_fail(plen <= 32, NULL);
|
||||
|
||||
if (!src) {
|
||||
/* allow "self-assignment", by specifying %NULL as source. */
|
||||
src = dst;
|
||||
}
|
||||
|
||||
*((guint32 *) dst) = nm_ip4_addr_clear_host_address(*((guint32 *) src), plen);
|
||||
a2.addr4 = nm_ip4_addr_clear_host_address(a.addr4, plen);
|
||||
break;
|
||||
case AF_INET6:
|
||||
nm_ip6_addr_clear_host_address(dst, src, plen);
|
||||
nm_ip6_addr_clear_host_address(&a2.addr6, &a.addr6, plen);
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached(NULL);
|
||||
}
|
||||
|
||||
nm_ip_addr_set(family, dst, &a2);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,23 +50,6 @@ nm_ip_addr_equal(int addr_family, gconstpointer a, gconstpointer b)
|
|||
return nm_ip_addr_cmp(addr_family, a, b) == 0;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
nm_ip_addr_is_null(int addr_family, gconstpointer addr)
|
||||
{
|
||||
nm_assert(addr);
|
||||
|
||||
if (NM_IS_IPv4(addr_family)) {
|
||||
in_addr_t t;
|
||||
|
||||
/* also for in_addr_t type (AF_INET), we accept that the pointer might
|
||||
* be unaligned. */
|
||||
memcpy(&t, addr, sizeof(t));
|
||||
return t == 0;
|
||||
}
|
||||
|
||||
return IN6_IS_ADDR_UNSPECIFIED((const struct in6_addr *) addr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nm_ip_addr_set(int addr_family, gpointer dst, gconstpointer src)
|
||||
{
|
||||
|
@ -84,6 +67,19 @@ nm_ip_addr_set(int addr_family, gpointer dst, gconstpointer src)
|
|||
* uninitalized bytes. Avoid that by using nm_ip_addr_init() instead. */
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
nm_ip_addr_is_null(int addr_family, gconstpointer addr)
|
||||
{
|
||||
NMIPAddr a;
|
||||
|
||||
nm_ip_addr_set(addr_family, &a, addr);
|
||||
|
||||
if (NM_IS_IPv4(addr_family))
|
||||
return a.addr4 == 0;
|
||||
|
||||
return IN6_IS_ADDR_UNSPECIFIED(&a.addr6);
|
||||
}
|
||||
|
||||
static inline NMIPAddr
|
||||
nm_ip_addr_init(int addr_family, gconstpointer src)
|
||||
{
|
||||
|
@ -201,15 +197,18 @@ nm_ip6_addr_same_prefix(const struct in6_addr *addr_a, const struct in6_addr *ad
|
|||
static inline int
|
||||
nm_ip_addr_same_prefix_cmp(int addr_family, gconstpointer addr_a, gconstpointer addr_b, guint8 plen)
|
||||
{
|
||||
NMIPAddr a;
|
||||
NMIPAddr b;
|
||||
|
||||
NM_CMP_SELF(addr_a, addr_b);
|
||||
|
||||
if (NM_IS_IPv4(addr_family)) {
|
||||
return nm_ip4_addr_same_prefix_cmp(*((const in_addr_t *) addr_a),
|
||||
*((const in_addr_t *) addr_b),
|
||||
plen);
|
||||
}
|
||||
nm_ip_addr_set(addr_family, &a, addr_a);
|
||||
nm_ip_addr_set(addr_family, &b, addr_b);
|
||||
|
||||
return nm_ip6_addr_same_prefix_cmp(addr_a, addr_b, plen);
|
||||
if (NM_IS_IPv4(addr_family))
|
||||
return nm_ip4_addr_same_prefix_cmp(a.addr4, b.addr4, plen);
|
||||
|
||||
return nm_ip6_addr_same_prefix_cmp(&a.addr6, &b.addr6, plen);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
|
|
Loading…
Reference in a new issue