|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2005 Andras Varga 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 #ifndef __INET_IPVXADDRESS_H 00019 #define __INET_IPVXADDRESS_H 00020 00021 #include <omnetpp.h> 00022 #include <string.h> 00023 #include "INETDefs.h" 00024 #include "IPAddress.h" 00025 #include "IPv6Address.h" 00026 00027 00035 class INET_API IPvXAddress 00036 { 00037 protected: 00038 uint32 d[4]; 00039 bool isv6; 00040 00041 public: 00047 IPvXAddress() {isv6 = false; d[0] = 0;} 00048 00052 IPvXAddress(const IPAddress& addr) {set(addr);} 00053 00057 IPvXAddress(const IPv6Address& addr) {set(addr);} 00058 00064 IPvXAddress(const char *addr) {set(addr);} 00065 00069 IPvXAddress(const IPvXAddress& addr) {set(addr);} 00070 00074 ~IPvXAddress() {} 00076 00082 bool isIPv6() const {return isv6;} 00083 00087 IPAddress get4() const { 00088 if (isv6) 00089 throw cRuntimeError("IPvXAddress: cannot return IPv6 address %s as IPv4", str().c_str()); 00090 return IPAddress(d[0]); 00091 } 00092 00096 IPv6Address get6() const { 00097 if (!isv6) { 00098 if (d[0]==0) // allow null address to be returned as IPv6 00099 return IPv6Address(); 00100 throw cRuntimeError("IPvXAddress: cannot return IPv4 address %s as IPv6", str().c_str()); 00101 } 00102 return IPv6Address(d[0], d[1], d[2], d[3]); 00103 } 00104 00108 void set(const IPAddress& addr) { 00109 isv6 = false; 00110 d[0] = addr.getInt(); 00111 } 00112 00116 void set(const IPv6Address& addr) { 00117 if (addr.isUnspecified()) { 00118 // we always represent nulls as IPv4 null 00119 isv6 = false; d[0] = 0; 00120 return; 00121 } 00122 isv6 = true; 00123 uint32 *w = const_cast<IPv6Address&>(addr).words(); 00124 d[0] = w[0]; d[1] = w[1]; d[2] = w[2]; d[3] = w[3]; 00125 } 00126 00130 void set(const IPvXAddress& addr) { 00131 isv6 = addr.isv6; 00132 d[0] = addr.d[0]; 00133 if (isv6) { 00134 d[1] = addr.d[1]; d[2] = addr.d[2]; d[3] = addr.d[3]; 00135 } 00136 } 00137 00143 void set(const char *addr) { 00144 if (!tryParse(addr)) 00145 throw cRuntimeError("IPvXAddress: cannot interpret address string `%s'", addr); 00146 } 00147 00151 IPvXAddress& operator=(const IPAddress& addr) {set(addr); return *this;} 00152 00156 IPvXAddress& operator=(const IPv6Address& addr) {set(addr); return *this;} 00157 00161 IPvXAddress& operator=(const IPvXAddress& addr) {set(addr); return *this;} 00162 00167 bool tryParse(const char *addr); 00168 00172 std::string str() const {return isv6 ? get6().str() : get4().str();} 00174 00180 bool isUnspecified() const { 00181 return !isv6 && d[0]==0; 00182 } 00183 00188 int wordCount() const {return isv6 ? 4 : 1;} 00189 00194 const uint32 *words() const {return d;} 00195 00199 bool equals(const IPAddress& addr) const { 00200 return !isv6 && d[0]==addr.getInt(); 00201 } 00202 00206 bool equals(const IPv6Address& addr) const { 00207 uint32 *w = const_cast<IPv6Address&>(addr).words(); 00208 return isv6 && d[0]==w[0] && d[1]==w[1] && d[2]==w[2] && d[3]==w[3]; 00209 } 00210 00214 bool equals(const IPvXAddress& addr) const { 00215 return (isv6 == addr.isv6) && (d[0]==addr.d[0]) && (!isv6 || (d[1]==addr.d[1] && d[2]==addr.d[2] && d[3]==addr.d[3])); 00216 } 00217 00221 bool operator==(const IPAddress& addr) const {return equals(addr);} 00222 00226 bool operator!=(const IPAddress& addr) const {return !equals(addr);} 00227 00231 bool operator==(const IPv6Address& addr) const {return equals(addr);} 00232 00236 bool operator!=(const IPv6Address& addr) const {return !equals(addr);} 00237 00241 bool operator==(const IPvXAddress& addr) const {return equals(addr);} 00242 00246 bool operator!=(const IPvXAddress& addr) const {return !equals(addr);} 00247 00251 bool operator<(const IPvXAddress& addr) const { 00252 if (isv6!=addr.isv6) 00253 return !isv6; 00254 else if (!isv6) 00255 return d[0]<addr.d[0]; 00256 else 00257 return memcmp(&d, &addr.d, 16) < 0; // this provides an ordering, though not surely the one one would expect 00258 } 00260 }; 00261 00262 inline std::ostream& operator<<(std::ostream& os, const IPvXAddress& ip) 00263 { 00264 return os << ip.str(); 00265 } 00266 00267 inline void doPacking(cCommBuffer *buf, const IPvXAddress& addr) 00268 { 00269 if (buf->packFlag(addr.isIPv6())) 00270 doPacking(buf, addr.get6()); 00271 else 00272 doPacking(buf, addr.get4()); 00273 } 00274 00275 inline void doUnpacking(cCommBuffer *buf, IPvXAddress& addr) 00276 { 00277 if (buf->checkFlag()) { 00278 IPv6Address tmp; 00279 doUnpacking(buf, tmp); 00280 addr.set(tmp); 00281 } 00282 else { 00283 IPAddress tmp; 00284 doUnpacking(buf, tmp); 00285 addr.set(tmp); 00286 } 00287 } 00288 00289 #endif 00290 00291