diff --git a/include/common/standard.h b/include/common/standard.h index bf14369e8..962a759ca 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -843,10 +843,10 @@ void len2mask4(int len, struct in_addr *addr); 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); diff --git a/src/dns.c b/src/dns.c index 3b3dfc59e..bf5baa0c7 100644 --- a/src/dns.c +++ b/src/dns.c @@ -757,11 +757,11 @@ int dns_get_ip_from_response(unsigned char *resp, unsigned char *resp_end, 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; @@ -772,7 +772,7 @@ int dns_get_ip_from_response(unsigned char *resp, unsigned char *resp_end, /* 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; diff --git a/src/server.c b/src/server.c index 10957548e..39fc4db61 100644 --- a/src/server.c +++ b/src/server.c @@ -2631,7 +2631,7 @@ int update_server_addr(struct server *s, void *ip, int ip_sin_family, const char /* 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); diff --git a/src/standard.c b/src/standard.c index c9f68b544..4d0e3ed14 100644 --- a/src/standard.c +++ b/src/standard.c @@ -2426,22 +2426,29 @@ unsigned int full_hash(unsigned int a) } /* Return non-zero if IPv4 address is part of the network, - * otherwise zero. + * otherwise zero. Note that 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 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;