Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "IPAddress.h"
00030
00034 static const int IPADDRESS_STRING_SIZE = 20;
00035
00036
00037 const IPAddress IPAddress::UNSPECIFIED_ADDRESS;
00038 const IPAddress IPAddress::LOOPBACK_ADDRESS("127.0.0.1");
00039 const IPAddress IPAddress::LOOPBACK_NETMASK("255.0.0.0");
00040 const IPAddress IPAddress::ALLONES_ADDRESS("255.255.255.255");
00041
00042 const IPAddress IPAddress::ALL_HOSTS_MCAST("224.0.0.1");
00043 const IPAddress IPAddress::ALL_ROUTERS_MCAST("224.0.0.2");
00044 const IPAddress IPAddress::ALL_DVMRP_ROUTERS_MCAST("224.0.0.4");
00045 const IPAddress IPAddress::ALL_OSPF_ROUTERS_MCAST("224.0.0.5");
00046 const IPAddress IPAddress::ALL_OSPF_DESIGNATED_ROUTERS_MCAST("224.0.0.6");
00047
00048
00049 void IPAddress::set(int i0, int i1, int i2, int i3)
00050 {
00051 addr = (i0 << 24) | (i1 << 16) | (i2 << 8) | i3;
00052 }
00053
00054 bool IPAddress::parseIPAddress(const char *text, unsigned char tobytes[])
00055 {
00056 if (!text)
00057 return false;
00058
00059 if (!strcmp(text,"<unspec>"))
00060 {
00061 tobytes[0] = tobytes[1] = tobytes[2] = tobytes[3] = 0;
00062 return true;
00063 }
00064
00065 const char *s = text;
00066 int i=0;
00067 while(true)
00068 {
00069 if (*s<'0' || *s>'9')
00070 return false;
00071
00072
00073 int num = 0;
00074 while (*s>='0' && *s<='9')
00075 num = 10*num + (*s++ - '0');
00076 if (num>255)
00077 return false;
00078 tobytes[i++] = (unsigned char) num;
00079
00080 if (!*s)
00081 break;
00082 if (*s!='.')
00083 return false;
00084 if (i==4)
00085 return false;
00086
00087
00088 s++;
00089 }
00090 return i==4;
00091 }
00092
00093 void IPAddress::set(const char *text)
00094 {
00095 unsigned char buf[4];
00096 if (!text)
00097 opp_error("IP address string is NULL");
00098 bool ok = parseIPAddress(text, buf);
00099 if (!ok)
00100 opp_error("Invalid IP address string `%s'", text);
00101 set(buf[0], buf[1], buf[2], buf[3]);
00102 }
00103
00104 std::string IPAddress::str() const
00105 {
00106 if (isUnspecified())
00107 return std::string("<unspec>");
00108
00109 char buf[IPADDRESS_STRING_SIZE];
00110 sprintf(buf, "%u.%u.%u.%u", (addr>>24)&255, (addr>>16)&255, (addr>>8)&255, addr&255);
00111 return std::string(buf);
00112 }
00113
00114 char IPAddress::getIPClass() const
00115 {
00116 unsigned char buf = getDByte(0);
00117 if ((buf & 0x80) == 0x00)
00118 return 'A';
00119 else if ((buf & 0xC0) == 0x80)
00120 return 'B';
00121 else if ((buf & 0xE0) == 0xC0)
00122 return 'C';
00123 else if ((buf & 0xF0) == 0xE0)
00124 return 'D';
00125 else if ((buf & 0xF8) == 0xF0)
00126 return 'E';
00127 else
00128 return '?';
00129 }
00130
00131 IPAddress IPAddress::getNetwork() const
00132 {
00133 switch (getIPClass())
00134 {
00135 case 'A':
00136
00137 return IPAddress(getDByte(0), 0, 0, 0);
00138 case 'B':
00139
00140 return IPAddress(getDByte(0), getDByte(1), 0, 0);
00141 case 'C':
00142
00143 return IPAddress(getDByte(0), getDByte(1), getDByte(2), 0);
00144 default:
00145
00146 return IPAddress();
00147 }
00148 }
00149
00150 IPAddress IPAddress::getNetworkMask() const
00151 {
00152 switch (getIPClass())
00153 {
00154 case 'A':
00155
00156 return IPAddress(255, 0, 0, 0);
00157 case 'B':
00158
00159 return IPAddress(255, 255, 0, 0);
00160 case 'C':
00161
00162 return IPAddress(255, 255, 255, 0);
00163 default:
00164
00165 return IPAddress();
00166 }
00167 }
00168
00169
00170 bool IPAddress::isNetwork(const IPAddress& toCmp) const
00171 {
00172 IPAddress netmask = getNetworkMask();
00173 if (netmask.isUnspecified()) return false;
00174 return maskedAddrAreEqual(*this, toCmp, netmask);
00175 }
00176
00177
00178 bool IPAddress::prefixMatches(const IPAddress& to_cmp, int numbits) const
00179 {
00180 if (numbits<1)
00181 return true;
00182
00183 uint32 addr2 = to_cmp.getInt();
00184
00185 if (numbits > 31)
00186 return addr==addr2;
00187
00188
00189 uint32 mask = 0xFFFFFFFF;
00190 mask = ~(mask >> numbits);
00191
00192 return (addr & mask) == (addr2 & mask);
00193 }
00194
00195 int IPAddress::getNumMatchingPrefixBits(const IPAddress& to_cmp) const
00196 {
00197 uint32 addr2 = to_cmp.getInt();
00198
00199 uint32 res = addr ^ addr2;
00200
00201
00202 for (int i = 31; i >= 0; i--) {
00203 if (res & (1 << i)) {
00204
00205 return 31 - i;
00206 }
00207 }
00208 return 32;
00209 }
00210
00211 int IPAddress::getNetmaskLength() const
00212 {
00213 int i;
00214 for (i=0; i<31; i++)
00215 if (addr & (1 << i))
00216 return 32-i;
00217 return 0;
00218 }
00219
00220 void IPAddress::keepFirstBits(unsigned int n)
00221 {
00222 addr &= 0xFFFFFFFF << n;
00223 }
00224
00225 bool IPAddress::maskedAddrAreEqual(const IPAddress& addr1,
00226 const IPAddress& addr2,
00227 const IPAddress& netmask)
00228 {
00229
00230
00231 return !(bool)((addr1.addr ^ addr2.addr) & netmask.addr);
00232 }
00233
00234 bool IPAddress::isWellFormed(const char *text)
00235 {
00236 unsigned char dummy[4];
00237 return parseIPAddress(text, dummy);
00238 }
00239
00240