|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2001 Vincent Oberle (vincent@oberle.com) 00003 // Institute of Telematics, University of Karlsruhe, Germany. 00004 // University Comillas, Madrid, Spain. 00005 // Copyright (C) 2004, 2008 Andras Varga 00006 // Copyright (C) 2008 Ingmar Baumgart 00007 // 00008 // This program is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Lesser General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2.1 of the License, or (at your option) any later version. 00012 // 00013 // This program is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU Lesser General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Lesser General Public 00019 // License along with this program; if not, see <http://www.gnu.org/licenses/>. 00020 // 00021 00022 00023 // 00024 // Author: Vincent Oberle 00025 // Date: Jan-March 2001 00026 // Cleanup and rewrite: Andras Varga, 2004 00027 // 00028 00029 #include "IPAddress.h" 00030 00034 static const int IPADDRESS_STRING_SIZE = 20; 00035 00036 // predefined addresses 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; // missing number 00071 00072 // read and store number 00073 int num = 0; 00074 while (*s>='0' && *s<='9') 00075 num = 10*num + (*s++ - '0'); 00076 if (num>255) 00077 return false; // number too big 00078 tobytes[i++] = (unsigned char) num; 00079 00080 if (!*s) 00081 break; // end of string 00082 if (*s!='.') 00083 return false; // invalid char after number 00084 if (i==4) 00085 return false; // read 4th number and not yet EOS 00086 00087 // skip '.' 00088 s++; 00089 } 00090 return i==4; // must have all 4 numbers 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) // 0xxxx 00118 return 'A'; 00119 else if ((buf & 0xC0) == 0x80) // 10xxx 00120 return 'B'; 00121 else if ((buf & 0xE0) == 0xC0) // 110xx 00122 return 'C'; 00123 else if ((buf & 0xF0) == 0xE0) // 1110x 00124 return 'D'; 00125 else if ((buf & 0xF8) == 0xF0) // 11110 00126 return 'E'; 00127 else 00128 return '?'; 00129 } 00130 00131 IPAddress IPAddress::getNetwork() const 00132 { 00133 switch (getIPClass()) 00134 { 00135 case 'A': 00136 // Class A: network = 7 bits 00137 return IPAddress(getDByte(0), 0, 0, 0); 00138 case 'B': 00139 // Class B: network = 14 bits 00140 return IPAddress(getDByte(0), getDByte(1), 0, 0); 00141 case 'C': 00142 // Class C: network = 21 bits 00143 return IPAddress(getDByte(0), getDByte(1), getDByte(2), 0); 00144 default: 00145 // Class D or E 00146 return IPAddress(); 00147 } 00148 } 00149 00150 IPAddress IPAddress::getNetworkMask() const 00151 { 00152 switch (getIPClass()) 00153 { 00154 case 'A': 00155 // Class A: network = 7 bits 00156 return IPAddress(255, 0, 0, 0); 00157 case 'B': 00158 // Class B: network = 14 bits 00159 return IPAddress(255, 255, 0, 0); 00160 case 'C': 00161 // Class C: network = 21 bits 00162 return IPAddress(255, 255, 255, 0); 00163 default: 00164 // Class D or E: return null address 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; // Class is D or E 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 // The right shift on an unsigned int produces 0 on the left 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 // If the bits are equal, there is a 0, so counting 00201 // the zeros from the left 00202 for (int i = 31; i >= 0; i--) { 00203 if (res & (1 << i)) { 00204 // 1, means not equal, so stop 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 // return addr1.doAnd(netmask).equals(addr2.doAnd(netmask)); 00230 // Looks weird, but is the same and is faster 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