diff src/lib/network.c @ 7517:e0007da64cdc HEAD

Moved net_is_in_network() to lib/network.c.
author Timo Sirainen <tss@iki.fi>
date Thu, 15 May 2008 07:43:13 +0300
parents da971cec0395
children 85203e817f90
line wrap: on
line diff
--- a/src/lib/network.c	Thu May 15 07:01:40 2008 +0300
+++ b/src/lib/network.c	Thu May 15 07:43:13 2008 +0300
@@ -703,3 +703,50 @@
 
 	return TRUE;
 }
+
+bool net_is_in_network(const struct ip_addr *ip,
+		       const struct ip_addr *net_ip, unsigned int bits)
+{
+	const uint32_t *ip1, *ip2;
+	uint32_t mask;
+	unsigned int pos, i;
+
+	if (IPADDR_IS_V4(ip) != IPADDR_IS_V4(net_ip)) {
+		/* one is IPv6 and one is IPv4 */
+		return FALSE;
+	}
+	i_assert(IPADDR_IS_V6(ip) == IPADDR_IS_V6(net_ip));
+
+	if (IPADDR_IS_V4(ip)) {
+		ip1 = &ip->u.ip4.s_addr;
+		ip2 = &net_ip->u.ip4.s_addr;
+	} else {
+#ifdef HAVE_IPV6
+		ip1 = (const void *)&ip->u.ip6;
+		ip2 = (const void *)&net_ip->u.ip6;
+#else
+		/* shouldn't get here */
+		return FALSE;
+#endif
+	}
+
+	/* check first the full 32bit ints */
+	for (pos = 0, i = 0; pos + 32 <= bits; pos += 32, i++) {
+		if (ip1[i] != ip2[i])
+			return FALSE;
+	}
+
+	/* check the last full bytes */
+	for (mask = 0xff; pos + 8 <= bits; pos += 8, mask <<= 8) {
+		if ((ip1[i] & mask) != (ip2[i] & mask))
+			return FALSE;
+	}
+
+	/* check the last bits, they're reversed in bytes */
+	bits -= pos;
+	for (mask = 0x80 << (pos % 32); bits > 0; bits--, mask >>= 1) {
+		if ((ip1[i] & mask) != (ip2[i] & mask))
+			return FALSE;
+	}
+	return TRUE;
+}