IPv6Address.h

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2005 Wei Yang, Ng
00003 // Copyright (C) 2005 Andras Varga
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this program; if not, see <http://www.gnu.org/licenses/>.
00017 //
00018 
00019 
00020 #ifndef __IPv6ADDRESS_H
00021 #define __IPv6ADDRESS_H
00022 
00023 #include <omnetpp.h>
00024 #include <iostream>
00025 #include <string>
00026 #include "INETDefs.h"
00027 
00028 class InterfaceToken;
00029 
00037 class INET_API IPv6Address
00038 {
00039     private:
00040         // Declare an unsigned 32 bit integer array of size 4.
00041         // 32x4 = 128 bits, which is the size of an IPv6 Address.
00042         uint32 d[4];
00043 
00044     protected:
00045         bool doTryParse(const char *&addr);
00046 
00047     public:
00051         // FIXME TBD add multicast address scopes!!! rfc 3513, section 2.7
00052         enum Scope
00053         {
00054             UNSPECIFIED,
00055             LOOPBACK,
00056             MULTICAST,
00057             LINK,
00058             SITE,
00059             GLOBAL
00060         };
00061 
00065         static const IPv6Address UNSPECIFIED_ADDRESS;
00066 
00068         static const IPv6Address LOOPBACK_ADDRESS;
00069 
00071         static const IPv6Address ALL_NODES_1;
00072 
00074         static const IPv6Address ALL_NODES_2;
00075 
00077         static const IPv6Address ALL_ROUTERS_1;
00078 
00080         static const IPv6Address ALL_ROUTERS_2;
00081 
00083         static const IPv6Address ALL_ROUTERS_5;
00084 
00086         static const IPv6Address SOLICITED_NODE_PREFIX;
00087 
00089         static const IPv6Address LINKLOCAL_PREFIX;
00091 
00097         IPv6Address()  {
00098             d[0]=d[1]=d[2]=d[3]=0;
00099         }
00100 
00105         IPv6Address(uint32 segment0, uint32 segment1, uint32 segment2, uint32 segment3)  {
00106             d[0] = segment0;
00107             d[1] = segment1;
00108             d[2] = segment2;
00109             d[3] = segment3;
00110         }
00111 
00116         IPv6Address(const char *addr) {set(addr);}
00117 
00118         bool operator<(const IPv6Address& addr) const {return compare(addr)<0;}
00119         bool operator>(const IPv6Address& addr) const {return compare(addr)>0;}
00120         bool operator==(const IPv6Address& addr) const {
00121             return d[3]==addr.d[3] && d[0]==addr.d[0] && d[1]==addr.d[1] && d[2]==addr.d[2]; // d[3] differs most often, compare it first
00122         }
00123         bool operator!=(const IPv6Address& addr) const {return !operator==(addr);}
00124 
00128         int compare(const IPv6Address& addr) const  {
00129             return d[0]<addr.d[0] ? -1 : d[0]>addr.d[0] ? 1 :
00130                    d[1]<addr.d[1] ? -1 : d[1]>addr.d[1] ? 1 :
00131                    d[2]<addr.d[2] ? -1 : d[2]>addr.d[2] ? 1 :
00132                    d[3]<addr.d[3] ? -1 : d[3]>addr.d[3] ? 1 : 0;
00133         }
00134 
00142         bool tryParse(const char *addr);
00143 
00147          bool tryParseAddrWithPrefix(const char *addr, int& prefixLen);
00148 
00152         void set(const char *addr);
00153 
00157         std::string str() const;
00158 
00162         void set(uint32 d0, uint32 d1, uint32 d2, uint32 d3) {
00163             d[0]=d0; d[1]=d1; d[2]=d2; d[3]=d3;
00164         }
00165 
00170         uint32 *words() {return d;}
00171 
00176         const uint32 *words() const {return d;}
00177 
00181         Scope getScope() const;
00182 
00186         static const char *scopeName(Scope s);
00187 
00192         static void constructMask(int prefixLength, uint32* mask);
00193 
00198         IPv6Address getPrefix(int prefixLength) const;
00199 
00204         IPv6Address getSuffix(int prefixLength) const;
00205 
00211         const IPv6Address& setPrefix(const IPv6Address& fromAddr, int prefixLength);
00212 
00218         const IPv6Address& setSuffix(const IPv6Address& fromAddr, int prefixLength);
00219 
00224         IPv6Address formSolicitedNodeMulticastAddress() const {
00225             return IPv6Address(*this).setPrefix(SOLICITED_NODE_PREFIX, 104);
00226         };
00227 
00239         // TODO revise doc, revise function! make static?  (Andras)
00240         IPv6Address formSubnetRouterAnycastAddress(int prefixLength) const {
00241             return IPv6Address(*this).setSuffix(UNSPECIFIED_ADDRESS, prefixLength);
00242         }
00243 
00247         static IPv6Address formLinkLocalAddress(const InterfaceToken& ident);
00248 
00252         bool matches(const IPv6Address& prefix, int prefixLength) const;
00253 
00257         bool isUnspecified() const  {return (d[0]|d[1]|d[2]|d[3])==0;}
00258 
00260         bool isMulticast() const {return getScope()==MULTICAST;}
00261 
00263         bool isUnicast() const {return getScope()!=MULTICAST && getScope()!=UNSPECIFIED;}
00264 
00266         bool isLoopback() const {return getScope()==LOOPBACK;}
00267 
00269         bool isLinkLocal() const {return getScope()==LINK;}
00270 
00272         bool isSiteLocal() const {return getScope()==SITE;}
00273 
00275         bool isGlobal() const {return getScope()==GLOBAL;}
00276 
00280         int getMulticastScope() const;
00281 };
00282 
00286 /*
00287 class INET_API IPv6AddressPrefix : public IPv6Address
00288 {
00289     public:
00290         char length;
00291 };
00292 */
00293 
00294 inline std::ostream& operator<<(std::ostream& os, const IPv6Address& ip)
00295 {
00296     return os << ip.str();
00297 }
00298 
00299 inline void doPacking(cCommBuffer *buf, const IPv6Address& addr)
00300 {
00301     buf->pack(addr.words(), 4);
00302 }
00303 
00304 inline void doUnpacking(cCommBuffer *buf, IPv6Address& addr)
00305 {
00306     buf->unpack(addr.words(), 4);
00307 }
00308 
00309 #endif
00310