return (ret);
}
+void addr_mask(struct addr *a, const struct addr * const mask)
+{
+ assert(a->family == mask->family);
+ if (a->family == IPv4)
+ a->ip.v4 &= mask->ip.v4;
+ else {
+ size_t i;
+
+ assert(a->family == IPv6);
+ for (i=0; i<sizeof(a->ip.v6.s6_addr); i++)
+ a->ip.v6.s6_addr[i] &= mask->ip.v6.s6_addr[i];
+ }
+}
+
+int addr_inside(const struct addr * const a,
+ const struct addr * const net, const struct addr * const mask)
+{
+ struct addr masked;
+
+ assert(a->family == net->family);
+ assert(a->family == mask->family);
+
+ masked = *a;
+ addr_mask(&masked, mask);
+ return (addr_equal(&masked, net));
+}
+
/* vim:set ts=3 sw=3 tw=78 et: */
int addr_equal(const struct addr * const a, const struct addr * const b);
const char *addr_to_str(const struct addr * const a);
+void addr_mask(struct addr *a, const struct addr * const mask);
+int addr_inside(const struct addr * const a,
+ const struct addr * const net, const struct addr * const mask);
/* Returns 0 on success, gai_strerror() code otherwise. */
int str_to_addr(const char *s, struct addr *a);
printf("\n");
}
+void test_inside(const char *a, const char *net, const char *mask, int expect)
+{
+ struct addr aa, anet, amask;
+
+ str_to_addr(a, &aa);
+ str_to_addr(net, &anet);
+ str_to_addr(mask, &amask);
+
+ printf("%s: %s in %s/%s\n",
+ addr_inside(&aa, &anet, &amask) ? "PASS" : "FAIL",
+ a, net, mask);
+}
+
int main()
{
test("0.0.0.0", "0.0.0.0", 0);
test(":", NULL, EAI_NONAME);
test("23.75.345.200", NULL, EAI_NONAME);
+ test_inside("192.168.1.2", "192.168.0.0", "255.255.0.0", 1);
+ test_inside("2001:0200::3eff:feb1:44d7",
+ "2001:0200::",
+ "ffff:ffff::", 1);
+
return 0;
}