summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/socket.h13
-rw-r--r--include/users.h13
-rw-r--r--src/dns.cpp2
-rw-r--r--src/inspsocket.cpp4
-rw-r--r--src/listensocket.cpp6
-rw-r--r--src/modules/m_check.cpp4
-rw-r--r--src/modules/m_connectban.cpp11
-rw-r--r--src/modules/m_httpd.cpp2
-rw-r--r--src/modules/m_httpd_stats.cpp2
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp2
-rw-r--r--src/modules/m_spanningtree/utils.cpp4
-rw-r--r--src/socket.cpp98
-rw-r--r--src/usermanager.cpp68
-rw-r--r--src/users.cpp115
14 files changed, 123 insertions, 221 deletions
diff --git a/include/socket.h b/include/socket.h
index a9b0a472e..bfde750ea 100644
--- a/include/socket.h
+++ b/include/socket.h
@@ -107,20 +107,27 @@ namespace irc
* @param sa The structure to place the result in. Will be zeroed prior to conversion
* @return true if the conversion was successful, false if not.
*/
- CoreExport bool aptosa(const std::string& addr, int port, irc::sockets::sockaddrs* sa);
+ CoreExport bool aptosa(const std::string& addr, int port, irc::sockets::sockaddrs& sa);
+
/** Convert a binary sockaddr to an address-port pair
* @param sa The structure to convert
* @param addr the IP address
* @param port the port
* @return true if the conversion was successful, false if unknown address family
*/
- CoreExport bool satoap(const irc::sockets::sockaddrs* sa, std::string& addr, int &port);
+ CoreExport bool satoap(const irc::sockets::sockaddrs& sa, std::string& addr, int &port);
+
/** Convert a binary sockaddr to a user-readable string.
* This means IPv6 addresses are written as [::1]:6667, and *:6668 is used for 0.0.0.0:6668
* @param sa The structure to convert
* @return The string; "<unknown>" if not a valid address
*/
- CoreExport std::string satouser(const irc::sockets::sockaddrs* sa);
+ CoreExport std::string satouser(const irc::sockets::sockaddrs& sa);
+
+ /** Create a CIDR mask from the given address, of length <range>
+ * Result will be of the form 192.0.5.0/24 or 2001:af35::/48
+ */
+ CoreExport std::string mask(irc::sockets::sockaddrs sa, unsigned int range);
}
}
diff --git a/include/users.h b/include/users.h
index 49e43f0bf..fa56abc0e 100644
--- a/include/users.h
+++ b/include/users.h
@@ -388,20 +388,15 @@ class CoreExport User : public StreamSocket
*/
const char* GetIPString();
+ /** Get CIDR mask, using default range, for this user
+ */
+ irc::string GetCIDRMask();
+
/** Sets the client IP for this user
* @return true if the conversion was successful
*/
bool SetClientIP(const char* sip);
- /** Get a CIDR mask from the IP of this user, using a static internal buffer.
- * e.g., GetCIDRMask(16) for 223.254.214.52 returns 223.254.0.0/16
- * This may be used for CIDR clone detection, etc.
- *
- * (XXX, brief note: when we do the sockets rewrite, this should move down a
- * level so it may be used on more derived objects. -- w00t)
- */
- const char *GetCIDRMask(int range);
-
/** Default constructor
* @throw CoreException if the UID allocated to the user already exists
* @param Instance Creator instance
diff --git a/src/dns.cpp b/src/dns.cpp
index e4d0b73fb..7be0f6874 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -303,7 +303,7 @@ void DNS::Rehash()
this->cache = new dnscache();
}
- irc::sockets::aptosa(ServerInstance->Config->DNSServer, DNS::QUERY_PORT, &myserver);
+ irc::sockets::aptosa(ServerInstance->Config->DNSServer, DNS::QUERY_PORT, myserver);
/* Initialize mastersocket */
int s = irc::sockets::OpenTCPSocket(ServerInstance->Config->DNSServer, SOCK_DGRAM);
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index a37cb9ea0..7485324a2 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -52,7 +52,7 @@ void BufferedSocket::DoConnect(const std::string &ipaddr, int aport, unsigned lo
BufferedSocketError BufferedSocket::BeginConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip)
{
irc::sockets::sockaddrs addr, bind;
- if (!irc::sockets::aptosa(ipaddr, aport, &addr))
+ if (!irc::sockets::aptosa(ipaddr, aport, addr))
{
ServerInstance->Logs->Log("SOCKET", DEBUG, "BUG: Hostname passed to BufferedSocket, rather than an IP address!");
return I_ERR_CONNECT;
@@ -61,7 +61,7 @@ BufferedSocketError BufferedSocket::BeginConnect(const std::string &ipaddr, int
bind.sa.sa_family = 0;
if (!connectbindip.empty())
{
- if (!irc::sockets::aptosa(connectbindip, 0, &bind))
+ if (!irc::sockets::aptosa(connectbindip, 0, bind))
{
return I_ERR_BIND;
}
diff --git a/src/listensocket.cpp b/src/listensocket.cpp
index 8b7053d8f..0d6bf89b6 100644
--- a/src/listensocket.cpp
+++ b/src/listensocket.cpp
@@ -23,13 +23,13 @@ ListenSocket::ListenSocket(ConfigTag* tag, const std::string& addr, int port)
irc::sockets::sockaddrs bind_to;
// canonicalize address if it is defined
- if (!irc::sockets::aptosa(addr, port, &bind_to))
+ if (!irc::sockets::aptosa(addr, port, bind_to))
{
fd = -1;
return;
}
- irc::sockets::satoap(&bind_to, bind_addr, bind_port);
- bind_desc = irc::sockets::satouser(&bind_to);
+ irc::sockets::satoap(bind_to, bind_addr, bind_port);
+ bind_desc = irc::sockets::satouser(bind_to);
fd = irc::sockets::OpenTCPSocket(bind_addr);
diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp
index 158b0c533..0a0ecab2b 100644
--- a/src/modules/m_check.cpp
+++ b/src/modules/m_check.cpp
@@ -104,8 +104,8 @@ class CommandCheck : public Command
LocalUser* loctarg = IS_LOCAL(targuser);
if (loctarg)
{
- user->SendText(checkstr + " clientaddr " + irc::sockets::satouser(&loctarg->client_sa));
- user->SendText(checkstr + " serveraddr " + irc::sockets::satouser(&loctarg->server_sa));
+ user->SendText(checkstr + " clientaddr " + irc::sockets::satouser(loctarg->client_sa));
+ user->SendText(checkstr + " serveraddr " + irc::sockets::satouser(loctarg->server_sa));
std::string classname = loctarg->GetClass()->name;
if (!classname.empty())
diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp
index 9506bc2fe..735f3da99 100644
--- a/src/modules/m_connectban.cpp
+++ b/src/modules/m_connectban.cpp
@@ -81,7 +81,8 @@ class ModuleConnectBan : public Module
break;
}
- i = connects.find(u->GetCIDRMask(range));
+ irc::string mask = assign(irc::sockets::mask(u->client_sa, range));
+ i = connects.find(mask);
if (i != connects.end())
{
@@ -90,21 +91,21 @@ class ModuleConnectBan : public Module
if (i->second >= threshold)
{
// Create zline for set duration.
- ZLine* zl = new ZLine(ServerInstance->Time(), banduration, ServerInstance->Config->ServerName.c_str(), "Connect flooding", u->GetCIDRMask(range));
+ ZLine* zl = new ZLine(ServerInstance->Time(), banduration, ServerInstance->Config->ServerName.c_str(), "Connect flooding", mask.c_str());
if (ServerInstance->XLines->AddLine(zl,NULL))
ServerInstance->XLines->ApplyLines();
else
delete zl;
ServerInstance->SNO->WriteGlobalSno('x',"Module m_connectban added Z:line on *@%s to expire on %s: Connect flooding",
- u->GetCIDRMask(range), ServerInstance->TimeString(zl->expiry).c_str());
- ServerInstance->SNO->WriteGlobalSno('a', "Connect flooding from IP range %s (%d)", u->GetCIDRMask(range), threshold);
+ mask.c_str(), ServerInstance->TimeString(zl->expiry).c_str());
+ ServerInstance->SNO->WriteGlobalSno('a', "Connect flooding from IP range %s (%d)", mask.c_str(), threshold);
connects.erase(i);
}
}
else
{
- connects[u->GetCIDRMask(range)] = 1;
+ connects[mask] = 1;
}
}
diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp
index 7fc342e04..748f530ca 100644
--- a/src/modules/m_httpd.cpp
+++ b/src/modules/m_httpd.cpp
@@ -343,7 +343,7 @@ class ModuleHttpServer : public Module
return MOD_RES_PASSTHRU;
int port;
std::string incomingip;
- irc::sockets::satoap(client, incomingip, port);
+ irc::sockets::satoap(*client, incomingip, port);
new HttpServerSocket(nfd, incomingip, from, client, server);
return MOD_RES_ALLOW;
}
diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp
index 7e478ade4..a0aa202ab 100644
--- a/src/modules/m_httpd_stats.cpp
+++ b/src/modules/m_httpd_stats.cpp
@@ -171,7 +171,7 @@ class ModuleHttpStats : public Module
LocalUser* lu = IS_LOCAL(u);
if (lu)
data << "<port>" << lu->GetServerPort() << "</port><servaddr>"
- << irc::sockets::satouser(&lu->server_sa) << "</servaddr>";
+ << irc::sockets::satouser(lu->server_sa) << "</servaddr>";
data << "<ipaddress>" << u->GetIPString() << "</ipaddress>";
DumpMeta(data, u);
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index 962b63984..b8633ae14 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -73,7 +73,7 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, int newfd, ListenSocket* via
: BufferedSocket(newfd), Utils(Util)
{
int dummy;
- irc::sockets::satoap(client, IP, dummy);
+ irc::sockets::satoap(*client, IP, dummy);
age = ServerInstance->Time();
LinkState = WAIT_AUTH_1;
capab_phase = 0;
diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp
index 11c96bf7c..0b9b8da3b 100644
--- a/src/modules/m_spanningtree/utils.cpp
+++ b/src/modules/m_spanningtree/utils.cpp
@@ -32,7 +32,7 @@ ModResult ModuleSpanningTree::OnAcceptConnection(int newsock, ListenSocket* from
bool found = false;
int port;
std::string incomingip;
- irc::sockets::satoap(client, incomingip, port);
+ irc::sockets::satoap(*client, incomingip, port);
found = (std::find(Utils->ValidIPs.begin(), Utils->ValidIPs.end(), incomingip) != Utils->ValidIPs.end());
if (!found)
@@ -335,7 +335,7 @@ void SpanningTreeUtilities::RefreshIPCache()
ValidIPs.push_back(L->AllowMask);
irc::sockets::sockaddrs dummy;
- bool ipvalid = irc::sockets::aptosa(L->IPAddr, L->Port, &dummy);
+ bool ipvalid = irc::sockets::aptosa(L->IPAddr, L->Port, dummy);
if (ipvalid)
ValidIPs.push_back(L->IPAddr);
else
diff --git a/src/socket.cpp b/src/socket.cpp
index 167d90b4f..a92343d91 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -35,7 +35,7 @@ bool InspIRCd::BindSocket(int sockfd, int port, const char* addr, bool dolisten)
memset(&servaddr, 0, sizeof(servaddr));
servaddr.in4.sin_family = AF_INET;
}
- else if (!irc::sockets::aptosa(addr, port, &servaddr))
+ else if (!irc::sockets::aptosa(addr, port, servaddr))
return false;
ret = SE->Bind(sockfd, &servaddr.sa, sa_size(servaddr));
@@ -122,8 +122,8 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports)
while (0 != (portno = portrange.GetToken()))
{
irc::sockets::sockaddrs bindspec;
- irc::sockets::aptosa(Addr, portno, &bindspec);
- std::string bind_readable = irc::sockets::satouser(&bindspec);
+ irc::sockets::aptosa(Addr, portno, bindspec);
+ std::string bind_readable = irc::sockets::satouser(bindspec);
bool skip = false;
for (std::vector<ListenSocket*>::iterator n = old_ports.begin(); n != old_ports.end(); ++n)
@@ -174,51 +174,52 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports)
return bound;
}
-bool irc::sockets::aptosa(const std::string& addr, int port, irc::sockets::sockaddrs* sa)
+bool irc::sockets::aptosa(const std::string& addr, int port, irc::sockets::sockaddrs& sa)
{
- memset(sa, 0, sizeof(*sa));
+ memset(&sa, 0, sizeof(sa));
if (addr.empty())
{
#ifdef IPV6
- sa->in6.sin6_family = AF_INET6;
- sa->in6.sin6_port = htons(port);
+ sa.in6.sin6_family = AF_INET6;
+ sa.in6.sin6_port = htons(port);
#else
- sa->in4.sin_family = AF_INET;
- sa->in4.sin_port = htons(port);
+ sa.in4.sin_family = AF_INET;
+ sa.in4.sin_port = htons(port);
#endif
return true;
}
- else if (inet_pton(AF_INET, addr.c_str(), &sa->in4.sin_addr) > 0)
+ else if (inet_pton(AF_INET, addr.c_str(), &sa.in4.sin_addr) > 0)
{
- sa->in4.sin_family = AF_INET;
- sa->in4.sin_port = htons(port);
+ sa.in4.sin_family = AF_INET;
+ sa.in4.sin_port = htons(port);
return true;
}
- else if (inet_pton(AF_INET6, addr.c_str(), &sa->in6.sin6_addr) > 0)
+ else if (inet_pton(AF_INET6, addr.c_str(), &sa.in6.sin6_addr) > 0)
{
- sa->in6.sin6_family = AF_INET6;
- sa->in6.sin6_port = htons(port);
+ sa.in6.sin6_family = AF_INET6;
+ sa.in6.sin6_port = htons(port);
return true;
}
return false;
}
-bool irc::sockets::satoap(const irc::sockets::sockaddrs* sa, std::string& addr, int &port) {
+bool irc::sockets::satoap(const irc::sockets::sockaddrs& sa, std::string& addr, int &port)
+{
char addrv[INET6_ADDRSTRLEN+1];
- if (sa->sa.sa_family == AF_INET)
+ if (sa.sa.sa_family == AF_INET)
{
- if (!inet_ntop(AF_INET, &sa->in4.sin_addr, addrv, sizeof(addrv)))
+ if (!inet_ntop(AF_INET, &sa.in4.sin_addr, addrv, sizeof(addrv)))
return false;
addr = addrv;
- port = ntohs(sa->in4.sin_port);
+ port = ntohs(sa.in4.sin_port);
return true;
}
- else if (sa->sa.sa_family == AF_INET6)
+ else if (sa.sa.sa_family == AF_INET6)
{
- if (!inet_ntop(AF_INET6, &sa->in6.sin6_addr, addrv, sizeof(addrv)))
+ if (!inet_ntop(AF_INET6, &sa.in6.sin6_addr, addrv, sizeof(addrv)))
return false;
addr = addrv;
- port = ntohs(sa->in6.sin6_port);
+ port = ntohs(sa.in6.sin6_port);
return true;
}
return false;
@@ -226,34 +227,35 @@ bool irc::sockets::satoap(const irc::sockets::sockaddrs* sa, std::string& addr,
static const char all_zero[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
-std::string irc::sockets::satouser(const irc::sockets::sockaddrs* sa) {
+std::string irc::sockets::satouser(const irc::sockets::sockaddrs& sa)
+{
char buffer[MAXBUF];
- if (sa->sa.sa_family == AF_INET)
+ if (sa.sa.sa_family == AF_INET)
{
- if (sa->in4.sin_addr.s_addr == 0)
+ if (sa.in4.sin_addr.s_addr == 0)
{
- sprintf(buffer, "*:%u", ntohs(sa->in4.sin_port));
+ sprintf(buffer, "*:%u", ntohs(sa.in4.sin_port));
}
else
{
- const uint8_t* bits = reinterpret_cast<const uint8_t*>(&sa->in4.sin_addr);
- sprintf(buffer, "%d.%d.%d.%d:%u", bits[0], bits[1], bits[2], bits[3], ntohs(sa->in4.sin_port));
+ const uint8_t* bits = reinterpret_cast<const uint8_t*>(&sa.in4.sin_addr);
+ sprintf(buffer, "%d.%d.%d.%d:%u", bits[0], bits[1], bits[2], bits[3], ntohs(sa.in4.sin_port));
}
}
- else if (sa->sa.sa_family == AF_INET6)
+ else if (sa.sa.sa_family == AF_INET6)
{
- if (!memcmp(all_zero, &sa->in6.sin6_addr, 16))
+ if (!memcmp(all_zero, &sa.in6.sin6_addr, 16))
{
- sprintf(buffer, "*:%u", ntohs(sa->in6.sin6_port));
+ sprintf(buffer, "*:%u", ntohs(sa.in6.sin6_port));
}
else
{
buffer[0] = '[';
- if (!inet_ntop(AF_INET6, &sa->in6.sin6_addr, buffer+1, MAXBUF - 10))
+ if (!inet_ntop(AF_INET6, &sa.in6.sin6_addr, buffer+1, MAXBUF - 10))
return "<unknown>"; // should never happen, buffer is large enough
int len = strlen(buffer);
// no need for snprintf, buffer has at least 9 chars left, max short len = 5
- sprintf(buffer + len, "]:%u", ntohs(sa->in6.sin6_port));
+ sprintf(buffer + len, "]:%u", ntohs(sa.in6.sin6_port));
}
}
else
@@ -269,3 +271,33 @@ int irc::sockets::sa_size(const irc::sockets::sockaddrs& sa)
return sizeof(sa.in6);
return 0;
}
+
+std::string irc::sockets::mask(irc::sockets::sockaddrs sa, unsigned int range)
+{
+ unsigned char* base;
+ unsigned int len;
+ if (sa.sa.sa_family == AF_INET)
+ {
+ base = (unsigned char*)&sa.in4.sin_addr;
+ len = 4;
+ }
+ else if (sa.sa.sa_family == AF_INET6)
+ {
+ base = (unsigned char*)&sa.in6.sin6_addr;
+ len = 16;
+ }
+ else
+ return "";
+ if (range > 8*len)
+ range = 8*len;
+ unsigned int byte = range / 8;
+ unsigned int bits = (-1 << (range & 7));
+ base[byte++] &= bits;
+ while (byte < len)
+ base[byte++] = 0;
+ int dummy;
+ std::string rv;
+ irc::sockets::satoap(sa, rv, dummy);
+ return rv + "/" + ConvToStr(range);
+}
+
diff --git a/src/usermanager.cpp b/src/usermanager.cpp
index bc058a462..511037596 100644
--- a/src/usermanager.cpp
+++ b/src/usermanager.cpp
@@ -254,60 +254,28 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
void UserManager::AddLocalClone(User *user)
{
- int range = 32;
clonemap::iterator x;
- switch (user->client_sa.sa.sa_family)
- {
- case AF_INET6:
- range = ServerInstance->Config->c_ipv6_range;
- break;
- case AF_INET:
- range = ServerInstance->Config->c_ipv4_range;
- break;
- }
-
- x = local_clones.find(user->GetCIDRMask(range));
+ x = local_clones.find(user->GetCIDRMask());
if (x != local_clones.end())
x->second++;
else
- local_clones[user->GetCIDRMask(range)] = 1;
+ local_clones[user->GetCIDRMask()] = 1;
}
void UserManager::AddGlobalClone(User *user)
{
- int range = 32;
clonemap::iterator x;
- switch (user->client_sa.sa.sa_family)
- {
- case AF_INET6:
- range = ServerInstance->Config->c_ipv6_range;
- break;
- case AF_INET:
- range = ServerInstance->Config->c_ipv4_range;
- break;
- }
- x = global_clones.find(user->GetCIDRMask(range));
+ x = global_clones.find(user->GetCIDRMask());
if (x != global_clones.end())
x->second++;
else
- global_clones[user->GetCIDRMask(range)] = 1;
+ global_clones[user->GetCIDRMask()] = 1;
}
void UserManager::RemoveCloneCounts(User *user)
{
- int range = 32;
- switch (user->client_sa.sa.sa_family)
- {
- case AF_INET6:
- range = ServerInstance->Config->c_ipv6_range;
- break;
- case AF_INET:
- range = ServerInstance->Config->c_ipv4_range;
- break;
- }
-
- clonemap::iterator x = local_clones.find(user->GetCIDRMask(range));
+ clonemap::iterator x = local_clones.find(user->GetCIDRMask());
if (x != local_clones.end())
{
x->second--;
@@ -317,7 +285,7 @@ void UserManager::RemoveCloneCounts(User *user)
}
}
- clonemap::iterator y = global_clones.find(user->GetCIDRMask(range));
+ clonemap::iterator y = global_clones.find(user->GetCIDRMask());
if (y != global_clones.end())
{
y->second--;
@@ -330,17 +298,7 @@ void UserManager::RemoveCloneCounts(User *user)
unsigned long UserManager::GlobalCloneCount(User *user)
{
- int range = 32;
- switch (user->client_sa.sa.sa_family)
- {
- case AF_INET6:
- range = ServerInstance->Config->c_ipv6_range;
- break;
- case AF_INET:
- range = ServerInstance->Config->c_ipv4_range;
- break;
- }
- clonemap::iterator x = global_clones.find(user->GetCIDRMask(range));
+ clonemap::iterator x = global_clones.find(user->GetCIDRMask());
if (x != global_clones.end())
return x->second;
else
@@ -349,17 +307,7 @@ unsigned long UserManager::GlobalCloneCount(User *user)
unsigned long UserManager::LocalCloneCount(User *user)
{
- int range = 32;
- switch (user->client_sa.sa.sa_family)
- {
- case AF_INET6:
- range = ServerInstance->Config->c_ipv6_range;
- break;
- case AF_INET:
- range = ServerInstance->Config->c_ipv4_range;
- break;
- }
- clonemap::iterator x = local_clones.find(user->GetCIDRMask(range));
+ clonemap::iterator x = local_clones.find(user->GetCIDRMask());
if (x != local_clones.end())
return x->second;
else
diff --git a/src/users.cpp b/src/users.cpp
index e8e4a4825..d1a4b2528 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -936,108 +936,12 @@ int LocalUser::GetServerPort()
return 0;
}
-const char* User::GetCIDRMask(int range)
-{
- static char buf[44];
-
- if (range < 0)
- throw "Negative range, sorry, no.";
-
- /*
- * Original code written by Oliver Lupton (Om).
- * Integrated by me. Thanks. :) -- w00t
- */
- switch (this->client_sa.sa.sa_family)
- {
- case AF_INET6:
- {
- /* unsigned char s6_addr[16]; */
- struct in6_addr v6;
- int i, bytestozero, extrabits;
- char buffer[40];
-
- if(range > 128)
- throw "CIDR mask width greater than address width (IPv6, 128 bit)";
-
- /* To create the CIDR mask we want to set all the bits after 'range' bits of the address
- * to zero. This means the last (128 - range) bits of the address must be set to zero.
- * Hence this number divided by 8 is the number of whole bytes from the end of the address
- * which must be set to zero.
- */
- bytestozero = (128 - range) / 8;
-
- /* Some of the least significant bits of the next most significant byte may also have to
- * be zeroed. The number of bits is the remainder of the above division.
- */
- extrabits = (128 - range) % 8;
-
- /* Populate our working struct with the parts of the user's IP which are required in the
- * final CIDR mask. Set all the subsequent bytes to zero.
- * (16 - bytestozero) is the number of bytes which must be populated with actual IP data.
- */
- for(i = 0; i < (16 - bytestozero); i++)
- {
- v6.s6_addr[i] = client_sa.in6.sin6_addr.s6_addr[i];
- }
-
- /* And zero all the remaining bytes in the IP. */
- for(; i < 16; i++)
- {
- v6.s6_addr[i] = 0;
- }
-
- /* And finally, zero the extra bits required. */
- v6.s6_addr[15 - bytestozero] = (v6.s6_addr[15 - bytestozero] >> extrabits) << extrabits;
-
- snprintf(buf, 44, "%s/%d", inet_ntop(AF_INET6, &v6, buffer, 40), range);
- return buf;
- }
- break;
- case AF_INET:
- {
- struct in_addr v4;
- char buffer[16];
-
- if (range > 32)
- throw "CIDR mask width greater than address width (IPv4, 32 bit)";
-
- /* Users already have a sockaddr* pointer (User::ip) which contains either a v4 or v6 structure */
- v4.s_addr = client_sa.in4.sin_addr.s_addr;
-
- /* To create the CIDR mask we want to set all the bits after 'range' bits of the address
- * to zero. This means the last (32 - range) bits of the address must be set to zero.
- * This is done by shifting the value right and then back left by (32 - range) bits.
- */
- if(range > 0)
- {
- v4.s_addr = ntohl(v4.s_addr);
- v4.s_addr = (v4.s_addr >> (32 - range)) << (32 - range);
- v4.s_addr = htonl(v4.s_addr);
- }
- else
- {
- /* a range of zero would cause a 32 bit value to be shifted by 32 bits.
- * this has undefined behaviour, but for CIDR purposes the resulting mask
- * from a.b.c.d/0 is 0.0.0.0/0
- */
- v4.s_addr = 0;
- }
-
- snprintf(buf, 44, "%s/%d", inet_ntop(AF_INET, &v4, buffer, 16), range);
- return buf;
- }
- break;
- }
-
- return ""; // unused, but oh well
-}
-
const char* User::GetIPString()
{
int port;
if (cachedip.empty())
{
- irc::sockets::satoap(&client_sa, cachedip, port);
+ irc::sockets::satoap(client_sa, cachedip, port);
/* IP addresses starting with a : on irc are a Bad Thing (tm) */
if (cachedip.c_str()[0] == ':')
cachedip.insert(0,1,'0');
@@ -1046,10 +950,25 @@ const char* User::GetIPString()
return cachedip.c_str();
}
+irc::string User::GetCIDRMask()
+{
+ int range = 0;
+ switch (client_sa.sa.sa_family)
+ {
+ case AF_INET6:
+ range = ServerInstance->Config->c_ipv6_range;
+ break;
+ case AF_INET:
+ range = ServerInstance->Config->c_ipv4_range;
+ break;
+ }
+ return assign(irc::sockets::mask(client_sa, range));
+}
+
bool User::SetClientIP(const char* sip)
{
this->cachedip = "";
- return irc::sockets::aptosa(sip, 0, &client_sa);
+ return irc::sockets::aptosa(sip, 0, client_sa);
}
static std::string wide_newline("\r\n");