diff options
author | Adam <Adam@anope.org> | 2010-11-20 21:45:30 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2010-12-12 19:35:27 -0500 |
commit | 246f44b9888161aecefc81f0ff17ddd893287e3c (patch) | |
tree | b89607a9ad9c91914f292fc54cc32213a8d9f5c4 /src/sockets.cpp | |
parent | a85112172d842aa74aa5531788d383328d153e74 (diff) |
Added cs_mode, rewrote the old list mode code, and added CIDR support
Diffstat (limited to 'src/sockets.cpp')
-rw-r--r-- | src/sockets.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/sockets.cpp b/src/sockets.cpp index 9e32f85eb..0eb7733cf 100644 --- a/src/sockets.cpp +++ b/src/sockets.cpp @@ -171,6 +171,80 @@ void sockaddrs::ntop(int type, const void *src) throw CoreException("Invalid socket type"); } +cidr::cidr(const Anope::string &ip) +{ + if (ip.find_first_not_of("01234567890:./") != Anope::string::npos) + throw SocketException("Invalid IP"); + + bool ipv6 = ip.find(':') != Anope::string::npos; + size_t sl = ip.find_last_of('/'); + if (sl == Anope::string::npos) + { + this->cidr_ip = ip; + this->cidr_len = ipv6 ? 128 : 32; + this->addr.pton(ipv6 ? AF_INET6 : AF_INET, ip); + } + else + { + Anope::string real_ip = ip.substr(0, sl); + Anope::string cidr_range = ip.substr(sl + 1); + if (!cidr_range.is_pos_number_only()) + throw SocketException("Invalid CIDR range"); + + this->cidr_ip = real_ip; + this->cidr_len = convertTo<unsigned int>(cidr_range); + this->addr.pton(ipv6 ? AF_INET6 : AF_INET, real_ip); + } +} + +cidr::cidr(const Anope::string &ip, unsigned char len) +{ + bool ipv6 = ip.find(':') != Anope::string::npos; + this->addr.pton(ipv6 ? AF_INET6 : AF_INET, ip); + this->cidr_ip = ip; + this->cidr_len = len; +} + +Anope::string cidr::mask() const +{ + return this->cidr_ip + "/" + this->cidr_len; +} + +bool cidr::match(sockaddrs &other) +{ + if (this->addr.sa.sa_family != other.sa.sa_family) + return false; + + unsigned char *ip, *their_ip, byte; + + switch (this->addr.sa.sa_family) + { + case AF_INET: + ip = reinterpret_cast<unsigned char *>(&this->addr.sa4.sin_addr); + byte = this->cidr_len / 8; + their_ip = reinterpret_cast<unsigned char *>(&other.sa4.sin_addr); + break; + case AF_INET6: + ip = reinterpret_cast<unsigned char *>(&this->addr.sa6.sin6_addr); + byte = this->cidr_len / 8; + their_ip = reinterpret_cast<unsigned char *>(&other.sa6.sin6_addr); + break; + default: + throw SocketException("Invalid address type"); + } + + if (memcmp(ip, their_ip, byte)) + return false; + + ip += byte; + their_ip += byte; + byte = this->cidr_len % 8; + if ((*ip & byte) != (*their_ip & byte)) + return false; + + return true; +} + /** Default constructor */ SocketEngineBase::SocketEngineBase() |