+ irc::sockets::sockaddrs sa;
+ sa.sa.sa_family = type;
+ unsigned char* base;
+ int len;
+ if (type == AF_INET)
+ {
+ base = (unsigned char*)&sa.in4.sin_addr;
+ len = 4;
+ }
+ else if (type == AF_INET6)
+ {
+ base = (unsigned char*)&sa.in6.sin6_addr;
+ len = 16;
+ }
+ else
+ return "";
+ memcpy(base, bits, len);
+ return sa.addr() + "/" + ConvToStr((int)length);
+}
+
+bool irc::sockets::cidr_mask::operator==(const cidr_mask& other) const
+{
+ return type == other.type && length == other.length &&
+ 0 == memcmp(bits, other.bits, 16);
+}
+
+bool irc::sockets::cidr_mask::operator<(const cidr_mask& other) const
+{
+ if (type != other.type)
+ return type < other.type;
+ if (length != other.length)
+ return length < other.length;
+ return memcmp(bits, other.bits, 16) < 0;
+}
+
+bool irc::sockets::cidr_mask::match(const irc::sockets::sockaddrs& addr) const
+{
+ if (addr.sa.sa_family != type)
+ return false;
+ irc::sockets::cidr_mask tmp(addr, length);
+ return tmp == *this;