void len2mask6(int len, struct in6_addr *addr);
/* Return true if IPv4 address is part of the network */
-extern int in_net_ipv4(struct in_addr *addr, struct in_addr *mask, struct in_addr *net);
+extern int in_net_ipv4(const void *addr, const struct in_addr *mask, const struct in_addr *net);
/* Return true if IPv6 address is part of the network */
-extern int in_net_ipv6(struct in6_addr *addr, struct in6_addr *mask, struct in6_addr *net);
+extern int in_net_ipv6(const void *addr, const struct in6_addr *mask, const struct in6_addr *net);
/* Map IPv4 adress on IPv6 address, as specified in RFC 3513. */
extern void v4tov6(struct in6_addr *sin6_addr, struct in_addr *sin_addr);
continue;
if ((rec[i].type == AF_INET &&
- in_net_ipv4((struct in_addr *)rec[i].ip,
+ in_net_ipv4(rec[i].ip,
&resol->opts->pref_net[j].mask.in4,
&resol->opts->pref_net[j].addr.in4)) ||
(rec[i].type == AF_INET6 &&
- in_net_ipv6((struct in6_addr *)rec[i].ip,
+ in_net_ipv6(rec[i].ip,
&resol->opts->pref_net[j].mask.in6,
&resol->opts->pref_net[j].addr.in6))) {
score += 2;
/* Check for current ip matching. */
if (rec[i].type == currentip_sin_family &&
((currentip_sin_family == AF_INET &&
- *(uint32_t *)rec[i].ip == *(uint32_t *)currentip) ||
+ memcmp(rec[i].ip, currentip, 4) == 0) ||
(currentip_sin_family == AF_INET6 &&
memcmp(rec[i].ip, currentip, 16) == 0))) {
score += 1;
/* save the new IP address */
switch (ip_sin_family) {
case AF_INET:
- ((struct sockaddr_in *)&s->addr)->sin_addr.s_addr = *(uint32_t *)ip;
+ memcpy(&((struct sockaddr_in *)&s->addr)->sin_addr.s_addr, ip, 4);
break;
case AF_INET6:
memcpy(((struct sockaddr_in6 *)&s->addr)->sin6_addr.s6_addr, ip, 16);
}
/* Return non-zero if IPv4 address is part of the network,
- * otherwise zero.
+ * otherwise zero. Note that <addr> may not necessarily be aligned
+ * while the two other ones must.
*/
-int in_net_ipv4(struct in_addr *addr, struct in_addr *mask, struct in_addr *net)
+int in_net_ipv4(const void *addr, const struct in_addr *mask, const struct in_addr *net)
{
- return((addr->s_addr & mask->s_addr) == (net->s_addr & mask->s_addr));
+ struct in_addr addr_copy;
+
+ memcpy(&addr_copy, addr, sizeof(addr_copy));
+ return((addr_copy.s_addr & mask->s_addr) == (net->s_addr & mask->s_addr));
}
/* Return non-zero if IPv6 address is part of the network,
- * otherwise zero.
+ * otherwise zero. Note that <addr> may not necessarily be aligned
+ * while the two other ones must.
*/
-int in_net_ipv6(struct in6_addr *addr, struct in6_addr *mask, struct in6_addr *net)
+int in_net_ipv6(const void *addr, const struct in6_addr *mask, const struct in6_addr *net)
{
int i;
+ struct in6_addr addr_copy;
+ memcpy(&addr_copy, addr, sizeof(addr_copy));
for (i = 0; i < sizeof(struct in6_addr) / sizeof(int); i++)
- if (((((int *)addr)[i] & ((int *)mask)[i])) !=
+ if (((((int *)&addr_copy)[i] & ((int *)mask)[i])) !=
(((int *)net)[i] & ((int *)mask)[i]))
return 0;
return 1;