summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-06-15 11:21:13 -0400
committerAdam <Adam@anope.org>2013-06-15 23:27:01 -0400
commita93b315bd3ede4dfec190ec4d3e25db2b028384a (patch)
tree203af4f511191a7b2f0bb38d45ae0f887c3a7b39
parent5246424dc0c0029c3596307fd812097e0835c4f4 (diff)
Fix cidr::match with odd cidr ranges
-rw-r--r--src/sockets.cpp21
1 files changed, 11 insertions, 10 deletions
diff --git a/src/sockets.cpp b/src/sockets.cpp
index 8729303bf..e136324f9 100644
--- a/src/sockets.cpp
+++ b/src/sockets.cpp
@@ -226,24 +226,24 @@ bool cidr::match(const sockaddrs &other)
if (!valid() || !other.valid() || this->addr.sa.sa_family != other.sa.sa_family)
return false;
- const unsigned char *ip, *their_ip;
- unsigned char byte, len = this->cidr_len;
+ const uint8_t *ip, *their_ip;
+ uint8_t byte, len = this->cidr_len;
switch (this->addr.sa.sa_family)
{
case AF_INET:
- ip = reinterpret_cast<const unsigned char *>(&this->addr.sa4.sin_addr);
+ ip = reinterpret_cast<const uint8_t *>(&this->addr.sa4.sin_addr);
if (len > 32)
len = 32;
byte = len / 8;
- their_ip = reinterpret_cast<const unsigned char *>(&other.sa4.sin_addr);
+ their_ip = reinterpret_cast<const uint8_t *>(&other.sa4.sin_addr);
break;
case AF_INET6:
- ip = reinterpret_cast<const unsigned char *>(&this->addr.sa6.sin6_addr);
+ ip = reinterpret_cast<const uint8_t *>(&this->addr.sa6.sin6_addr);
if (len > 128)
len = 128;
byte = len / 8;
- their_ip = reinterpret_cast<const unsigned char *>(&other.sa6.sin6_addr);
+ their_ip = reinterpret_cast<const uint8_t *>(&other.sa6.sin6_addr);
break;
default:
return false;
@@ -252,13 +252,14 @@ bool cidr::match(const sockaddrs &other)
if (memcmp(ip, their_ip, byte))
return false;
+ ip += byte;
+ their_ip += byte;
+
byte = len % 8;
if (byte)
{
- ip += byte;
- their_ip += byte;
- if ((*ip & byte) != (*their_ip & byte))
- return false;
+ uint8_t m = ~0 << (8 - byte);
+ return *ip & m == *their_ip & m;
}
return true;