Donc, pour mettre Olis réponse dans le code:
// Check if 192.168.0.1 is inside 192.168.0.0/24
in_addr ip, net, netmask;
inet_aton("192.168.0.1", &ip);
inet_aton("192.168.0.0", &net);
il a dit:
inet_cidrtoaddr(24, &netmask);
bool is_inside = ((ip.s_addr & netmask.s_addr) == (net.s_addr & netmask.s_addr));
Je préfère la méthode addr4_match si:
bool cidr_match(const in_addr &addr, const in_addr &net, uint8_t bits) {
if (bits == 0) {
// C99 6.5.7 (3): u32 << 32 is undefined behaviour
return true;
}
return !((addr.s_addr^net.s_addr) & htonl(0xFFFFFFFFu << (32 - bits)));
}
bool is_inside = cidr_match(ip, net, 24);
J'ai expérimenté avec un groupe d'entrée différent: https://gist.github.com/duedal/b83303b4988a4afb2a75
Si quelqu'un trouver ce manque une solution IPv6 aussi:
bool cidr6_match(const in6_addr &address, const in6_addr &network, uint8_t bits) {
#ifdef LINUX
const uint32_t *a = address.s6_addr32;
const uint32_t *n = network.s6_addr32;
#else
const uint32_t *a = address.__u6_addr.__u6_addr32;
const uint32_t *n = network.__u6_addr.__u6_addr32;
#endif
int bits_whole, bits_incomplete;
bits_whole = bits >> 5; // number of whole u32
bits_incomplete = bits & 0x1F; // number of bits in incomplete u32
if (bits_whole) {
if (memcmp(a, n, bits_whole << 2)) {
return false;
}
}
if (bits_incomplete) {
uint32_t mask = htonl((0xFFFFFFFFu) << (32 - bits_incomplete));
if ((a[bits_whole]^n[bits_whole]) & mask) {
return false;
}
}
return true;
}
Vérifiez si 2001: DB8 :: FF00: 42: 8329 est présent en 2001: db8/32. Méfiez-vous inet_net_pton est très pointilleux, c'est 2001: db8/32 pas 2001: db8 ::/32. Cependant 2001: db8 ::/48 est parfaitement valide (aussi connu comme 2001: db8: 0/48).
in6_addr ip6, net6, net6_48;
memset(&net6, 0, sizeof(net6));
memset(&net6_48, 0, sizeof(net6_48));
assert(inet_pton(AF_INET6, "2001:db8::ff00:42:8329", &ip6));
int bits = inet_net_pton(AF_INET6, "2001:db8/32", &net6, sizeof(net6));
assert((bits != -1)); // assert that inet_net_pton understood us
bool is_inside6 = cidr6_match(ip6, net6, bits);
int bits_48 = inet_net_pton(AF_INET6, "2001:db8::/48", &net6_48, sizeof(net6_48));
assert((bits_48 == 48));
bool is_inside6_48 = cidr6_match(ip6, net6_48, bits_48);
forme plus facile de cette fonction: 'addr-> s_addr = 0xffffffffU << (32 - Longueur du préfixe)' –
@ Steve-o: Cela conduit à des résultats non définis si 'prefixLength' est 0. –