+ std::string::size_type bits_chars = mask.rfind('/');
+ irc::sockets::sockaddrs sa;
+
+ if (bits_chars == std::string::npos)
+ {
+ irc::sockets::aptosa(mask, 0, sa);
+ sa2cidr(*this, sa, 128);
+ }
+ else
+ {
+ unsigned char range = ConvToNum<unsigned char>(mask.substr(bits_chars + 1));
+ irc::sockets::aptosa(mask.substr(0, bits_chars), 0, sa);
+ sa2cidr(*this, sa, range);
+ }
+}
+
+std::string irc::sockets::cidr_mask::str() const
+{
+ irc::sockets::sockaddrs sa;
+ sa.sa.sa_family = type;
+
+ unsigned char* base;
+ size_t len;
+ switch (type)
+ {
+ case AF_INET:
+ base = (unsigned char*)&sa.in4.sin_addr;
+ len = 4;
+ break;
+
+ case AF_INET6:
+ base = (unsigned char*)&sa.in6.sin6_addr;
+ len = 16;
+ break;
+
+ case AF_UNIX:
+ return sa.un.sun_path;
+
+ default:
+ // If we have reached this point then we have encountered a bug.
+ ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "BUG: irc::sockets::cidr_mask::str(): socket type %d is unknown!", type);
+ return "<unknown>";
+ }
+
+ memcpy(base, bits, len);
+ return sa.addr() + "/" + ConvToStr((int)length);