}
}
else
- this->WriteNumeric(501, "%s %c :is unknown snomask char to me", this->nick.c_str(), *c);
+ this->WriteNumeric(ERR_UNKNOWNSNOMASK, "%s %c :is unknown snomask char to me", this->nick.c_str(), *c);
oldadding = adding;
break;
return;
this->WriteServ("NOTICE Auth :Welcome to \002%s\002!",ServerInstance->Config->Network);
- this->WriteNumeric(001, "%s :Welcome to the %s IRC Network %s!%s@%s",this->nick.c_str(), ServerInstance->Config->Network, this->nick.c_str(), this->ident.c_str(), this->host.c_str());
- this->WriteNumeric(002, "%s :Your host is %s, running version InspIRCd-1.2",this->nick.c_str(),ServerInstance->Config->ServerName);
- this->WriteNumeric(003, "%s :This server was created %s %s", this->nick.c_str(), __TIME__, __DATE__);
- this->WriteNumeric(004, "%s %s InspIRCd-1.2 %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str());
+ this->WriteNumeric(RPL_WELCOME, "%s :Welcome to the %s IRC Network %s!%s@%s",this->nick.c_str(), ServerInstance->Config->Network, this->nick.c_str(), this->ident.c_str(), this->host.c_str());
+ this->WriteNumeric(RPL_YOURHOSTIS, "%s :Your host is %s, running version InspIRCd-1.2",this->nick.c_str(),ServerInstance->Config->ServerName);
+ this->WriteNumeric(RPL_SERVERCREATED, "%s :This server was created %s %s", this->nick.c_str(), __TIME__, __DATE__);
+ this->WriteNumeric(RPL_SERVERVERSION, "%s %s InspIRCd-1.2 %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str());
ServerInstance->Config->Send005(this);
- this->WriteNumeric(42, "%s %s :your unique ID", this->nick.c_str(), this->uuid.c_str());
+ this->WriteNumeric(RPL_YOURUUID, "%s %s :your unique ID", this->nick.c_str(), this->uuid.c_str());
this->ShowMOTD();
const char* User::GetCIDRMask(int range)
{
- static char buf[40];
+ static char buf[44];
if (this->ip == NULL)
return "";
#ifdef SUPPORT_IP6LINKS
case AF_INET6:
{
+ /* unsigned char s6_addr[16]; */
struct in6_addr v6;
-
+ sockaddr_in6* sin;
+ int i, bytestozero, extrabits;
+ char buffer[40];
+
if(range > 128)
- {
- printf("Error, range given (%d) larger than address length (128)\n", range);
- return 0;
- }
-
- if(inet_pton(AF_INET6, this->GetIPString(), &v6))
- {
- /* unsigned char s6_addr[16]; */
- int i;
- int bytestoblank;
- int extrabits;
- char buffer[64];
+ throw "CIDR mask width greater than address width (IPv6, 128 bit)";
- if(range > 0)
- {
- /* (128 - range) bits must be blanked, so ((128 - range) / 8) of the bytes, working backwards, must be blanked. */
- bytestoblank = (128 - range) / 8;
-
- /* ((128 - range) % 8) bits of the next byte must also be blanked. */
- extrabits = (128 - range) % 8;
- v6.s6_addr[15 - bytestoblank] = (v6.s6_addr[15 - bytestoblank] >> extrabits) << extrabits;
-
- for(i = 0; i < bytestoblank; i++)
- {
- v6.s6_addr[15 - i] = 0;
- }
- }
- else
- {
- for(i = 0; i < 15; i++)
- {
- v6.s6_addr[i] = 0;
- }
- }
+ /* Access the user's IP structure directly */
+ sin = (sockaddr_in6*)this->ip;
- sprintf(buf, "%s/%d\n", inet_ntop(AF_INET6, &v6, buffer, 64), range);
- return buf;
+ /* 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] = sin->sin6_addr.s6_addr[i];
}
- else
+
+ /* And zero all the remaining bytes in the IP. */
+ for(; i < 16; i++)
{
- throw "CIDR mask for v6 failed";
+ 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;
#endif
case AF_INET:
{
struct in_addr v4;
+ sockaddr_in* sin;
+ char buffer[16];
if (range > 32)
- throw "more than 32 bits on an ipv4 connection, can't do that..";
+ throw "CIDR mask width greater than address width (IPv4, 32 bit)";
- if(inet_pton(AF_INET, this->GetIPString(), &v4))
- {
- char buffer[16];
- uint32_t temp;
-
- /* (32 - range) is the number of bits we are *ignoring*. We shift this left and then right to wipe off these bits. */
+ /* Users already have a sockaddr* pointer (User::ip) which contains either a v4 or v6 structure */
+ sin = (sockaddr_in*)this->ip;
+ v4.s_addr = sin->sin_addr.s_addr;
- if(range > 0)
- {
- temp = ntohl(v4.s_addr);
- temp = (temp >> (32 - range)) << (32 - range);
- v4.s_addr = htonl(temp);
- }
- else
- {
- v4.s_addr = 0;
- }
-
- sprintf(buf, "%s/%d\n", inet_ntop(AF_INET, &v4, buffer, 16), range);
- return buf;
+ /* 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
{
- throw "CIDR mask for v4 failed";
+ /* 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;
}
}
if (IS_LOCAL(this))
- this->WriteNumeric(396, "%s %s :is now your displayed host",this->nick.c_str(),this->dhost.c_str());
+ this->WriteNumeric(RPL_YOURDISPLAYEDHOST, "%s %s :is now your displayed host",this->nick.c_str(),this->dhost.c_str());
return true;
}
{
if (!ServerInstance->Config->MOTD.size())
{
- this->WriteNumeric(422, "%s :Message of the day file is missing.",this->nick.c_str());
+ this->WriteNumeric(ERR_NOMOTD, "%s :Message of the day file is missing.",this->nick.c_str());
return;
}
- this->WriteNumeric(375, "%s :%s message of the day", this->nick.c_str(), ServerInstance->Config->ServerName);
+ this->WriteNumeric(RPL_MOTDSTART, "%s :%s message of the day", this->nick.c_str(), ServerInstance->Config->ServerName);
for (file_cache::iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); i++)
- this->WriteNumeric(372, "%s :- %s",this->nick.c_str(),i->c_str());
+ this->WriteNumeric(RPL_MOTD, "%s :- %s",this->nick.c_str(),i->c_str());
- this->WriteNumeric(376, "%s :End of message of the day.", this->nick.c_str());
+ this->WriteNumeric(RPL_ENDOFMOTD, "%s :End of message of the day.", this->nick.c_str());
}
void User::ShowRULES()
{
if (!ServerInstance->Config->RULES.size())
{
- this->WriteNumeric(434, "%s :RULES File is missing",this->nick.c_str());
+ this->WriteNumeric(ERR_NORULES, "%s :RULES File is missing",this->nick.c_str());
return;
}
- this->WriteNumeric(308, "%s :- %s Server Rules -",this->nick.c_str(),ServerInstance->Config->ServerName);
+ this->WriteNumeric(RPL_RULESTART, "%s :- %s Server Rules -",this->nick.c_str(),ServerInstance->Config->ServerName);
for (file_cache::iterator i = ServerInstance->Config->RULES.begin(); i != ServerInstance->Config->RULES.end(); i++)
- this->WriteNumeric(232, "%s :- %s",this->nick.c_str(),i->c_str());
+ this->WriteNumeric(RPL_RULES, "%s :- %s",this->nick.c_str(),i->c_str());
- this->WriteNumeric(309, "%s :End of RULES command.",this->nick.c_str());
+ this->WriteNumeric(RPL_RULESEND, "%s :End of RULES command.",this->nick.c_str());
}
void User::HandleEvent(EventType et, int errornum)