IPvXAddress.h

Go to the documentation of this file.
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