IPv6Address Class Reference

#include <IPv6Address.h>

List of all members.


Detailed Description

Stores an IPv6 address. Compliant to RFC 3513 - Internet Protocol Version 6 (IPv6) Addressing Architecture.

Storage is efficient: an object occupies size of an IPv6 address (128bits=16 bytes).

Public Types

enum  Scope {
  UNSPECIFIED, LOOPBACK, MULTICAST, LINK,
  SITE, GLOBAL
}

Public Member Functions

 IPv6Address ()
 IPv6Address (uint32 segment0, uint32 segment1, uint32 segment2, uint32 segment3)
 IPv6Address (const char *addr)
bool operator< (const IPv6Address &addr) const
bool operator> (const IPv6Address &addr) const
bool operator== (const IPv6Address &addr) const
bool operator!= (const IPv6Address &addr) const
int compare (const IPv6Address &addr) const
bool tryParse (const char *addr)
bool tryParseAddrWithPrefix (const char *addr, int &prefixLen)
void set (const char *addr)
std::string str () const
void set (uint32 d0, uint32 d1, uint32 d2, uint32 d3)
uint32 * words ()
const uint32 * words () const
Scope getScope () const
IPv6Address getPrefix (int prefixLength) const
IPv6Address getSuffix (int prefixLength) const
const IPv6AddresssetPrefix (const IPv6Address &fromAddr, int prefixLength)
const IPv6AddresssetSuffix (const IPv6Address &fromAddr, int prefixLength)
IPv6Address formSolicitedNodeMulticastAddress () const
IPv6Address formSubnetRouterAnycastAddress (int prefixLength) const
bool matches (const IPv6Address &prefix, int prefixLength) const
bool isUnspecified () const
bool isMulticast () const
bool isUnicast () const
bool isLoopback () const
bool isLinkLocal () const
bool isSiteLocal () const
bool isGlobal () const
int getMulticastScope () const

Static Public Member Functions

static const char * scopeName (Scope s)
static void constructMask (int prefixLength, uint32 *mask)
static IPv6Address formLinkLocalAddress (const InterfaceToken &ident)

Static Public Attributes

Predefined addresses


static const IPv6Address UNSPECIFIED_ADDRESS
static const IPv6Address LOOPBACK_ADDRESS
static const IPv6Address ALL_NODES_1
static const IPv6Address ALL_NODES_2
static const IPv6Address ALL_ROUTERS_1
static const IPv6Address ALL_ROUTERS_2
static const IPv6Address ALL_ROUTERS_5
static const IPv6Address SOLICITED_NODE_PREFIX
static const IPv6Address LINKLOCAL_PREFIX

Protected Member Functions

bool doTryParse (const char *&addr)

Private Attributes

uint32 d [4]


Member Enumeration Documentation

IPv6 address scope (RFC 3513)

Enumerator:
UNSPECIFIED 
LOOPBACK 
MULTICAST 
LINK 
SITE 
GLOBAL 
00053         {
00054             UNSPECIFIED,
00055             LOOPBACK,
00056             MULTICAST,
00057             LINK,
00058             SITE,
00059             GLOBAL
00060         };


Constructor & Destructor Documentation

IPv6Address::IPv6Address (  )  [inline]

Constructor Set all 128 bits of the IPv6 address to '0'. 0:0:0:0:0:0:0:0

Referenced by getPrefix(), and getSuffix().

00097                        {
00098             d[0]=d[1]=d[2]=d[3]=0;
00099         }

IPv6Address::IPv6Address ( uint32  segment0,
uint32  segment1,
uint32  segment2,
uint32  segment3 
) [inline]

Constructor. Constructs an IPv6 address based from the 4 given segments.

00105                                                                                          {
00106             d[0] = segment0;
00107             d[1] = segment1;
00108             d[2] = segment2;
00109             d[3] = segment3;
00110         }

IPv6Address::IPv6Address ( const char *  addr  )  [inline]

Constructor. Sets the address from the given text representation. See documentation of tryParse() for supported syntax.

00116 {set(addr);}


Member Function Documentation

bool IPv6Address::doTryParse ( const char *&  addr  )  [protected]

Referenced by tryParse(), and tryParseAddrWithPrefix().

00071 {
00072     if (!strcmp(addr,"<unspec>"))
00073     {
00074         addr += 8;
00075         d[0] = d[1] = d[2] = d[3] = 0;
00076         return true;
00077     }
00078 
00079     // parse and store 16-bit units
00080     int octals[8];
00081     int numOctals = parseOctals(addr, octals);
00082 
00083     // if address string contains "::", parse and store second half too
00084     if (*addr==':' && *(addr+1)==':')
00085     {
00086         addr += 2;
00087         int suffixOctals[8];
00088         int numSuffixOctals = parseOctals(addr, suffixOctals);
00089 
00090         // merge suffixOctals[] into octals[]
00091         if (numOctals+numSuffixOctals>8)
00092             return false; // too many
00093         for (int i=numOctals; i<8; i++) {
00094             int j = i-8+numSuffixOctals;
00095             octals[i] = j<0 ? 0 : suffixOctals[j];
00096         }
00097         numOctals = 8;
00098     }
00099 
00100     if (numOctals!=8)
00101         return false; // too few
00102 
00103     // copy octets to d[]
00104     for (unsigned int i=0; i<4; i++)
00105         d[i] = (octals[i*2]<<16) + octals[2*i + 1];
00106 
00107     return true;
00108 }

bool IPv6Address::operator< ( const IPv6Address addr  )  const [inline]

00118 {return compare(addr)<0;}

bool IPv6Address::operator> ( const IPv6Address addr  )  const [inline]

00119 {return compare(addr)>0;}

bool IPv6Address::operator== ( const IPv6Address addr  )  const [inline]

00120                                                        {
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         }

bool IPv6Address::operator!= ( const IPv6Address addr  )  const [inline]

00123 {return !operator==(addr);}

int IPv6Address::compare ( const IPv6Address addr  )  const [inline]

Returns -1, 0 or 1.

00128                                                     {
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         }

bool IPv6Address::tryParse ( const char *  addr  ) 

Try parsing an IPv6 address. Return true if the string contained a well-formed IPv6 address, and false otherwise.

TBD: explain syntax (refer to RFC?)

Referenced by set(), and IPvXAddress::tryParse().

00111 {
00112     if (!addr)
00113         return false;
00114     if (!doTryParse(addr))
00115         return false;
00116     if (*addr!=0)
00117         return false; // illegal trailing character
00118     return true;
00119 }

bool IPv6Address::tryParseAddrWithPrefix ( const char *  addr,
int &  prefixLen 
)

FIXME

Referenced by RoutingTable6::configureInterfaceFromXML().

00122 {
00123     if (!addr)
00124         return false;
00125     if (!doTryParse(addr))
00126         return false;
00127     if (*addr!='/')
00128         return false; // no '/' after address
00129     addr++;
00130 
00131     // parse prefix
00132     char *e;
00133     prefixLen = strtoul(addr,&e,10);
00134     if (addr==e)
00135         return false; // no number after '/'
00136     if (*e!=0)
00137         return false; // garbage after number
00138     if (prefixLen<0 || prefixLen>128)
00139         return false; // wrong len value
00140     return true;
00141 }

void IPv6Address::set ( const char *  addr  ) 

Sets the IPv6 address. Given a string.

00144 {
00145     if (!tryParse(addr))
00146         throw cRuntimeError("IPv6Address: cannot interpret address string `%s'", addr);
00147 }

std::string IPv6Address::str (  )  const

Get the IPv6 address as a "standard string".

Referenced by RoutingTable6::doLongestPrefixMatch(), IPv6::encapsulate(), RoutingTable6::getInterfaceByAddress(), getMulticastScope(), RoutingTable6::isLocalAddress(), RoutingTable6::lookupDestCache(), operator<<(), IPv6NeighbourDiscovery::reachabilityConfirmed(), and IPv6NeighbourDiscovery::resolveNeighbour().

00178 {
00179     if (isUnspecified())
00180         return std::string("<unspec>");
00181 
00182     // convert to 16-bit octals
00183     int octals[8] = {
00184         (d[0]>>16), (d[0]&0xffff), (d[1]>>16), (d[1]&0xffff),
00185         (d[2]>>16), (d[2]&0xffff), (d[3]>>16), (d[3]&0xffff)
00186     };
00187 
00188     // find longest sequence of zeros in octals[]
00189     int start, end;
00190     findGap(octals, start, end);
00191     if (start==0 && end==8)
00192         return "::0";  // the unspecified address is a special case
00193 
00194     // print octals, replacing gap with "::"
00195     std::stringstream os;
00196     os << std::hex;
00197     for (int i=0; i<start; i++)
00198         os << (i==0?"":":") << octals[i];
00199     if (start!=end)
00200         os << "::";
00201     for (int j=end; j<8; j++)
00202         os << (j==end?"":":") << octals[j];
00203     return os.str();
00204 }

void IPv6Address::set ( uint32  d0,
uint32  d1,
uint32  d2,
uint32  d3 
) [inline]

Set the address to the given four 32-bit integers.

00162                                                              {
00163             d[0]=d0; d[1]=d1; d[2]=d2; d[3]=d3;
00164         }

uint32* IPv6Address::words (  )  [inline]

Returns pointer to internal binary representation of address, four 32-bit unsigned integers.

Referenced by doPacking(), and doUnpacking().

00170 {return d;}

const uint32* IPv6Address::words (  )  const [inline]

Returns pointer to internal binary representation of address, four 32-bit unsigned integers.

00176 {return d;}

IPv6Address::Scope IPv6Address::getScope (  )  const

Get the IPv6 address scope.

Referenced by IPv6InterfaceData::addrLess(), and SCTPAssociation::getLevel().

00207 {
00208     //Mask the given IPv6 address with the different mask types
00209     //to get only the IPv6 address scope. Compare the masked
00210     //address with the different prefixes.
00211 
00212     if ((d[0] & LINK_LOCAL_MASK) == LINK_LOCAL_PREFIX )
00213     {
00214         return LINK;
00215     }
00216     else if ((d[0] & SITE_LOCAL_MASK) == SITE_LOCAL_PREFIX )
00217     {
00218         return SITE;
00219     }
00220     else if ((d[0] & MULTICAST_MASK) == MULTICAST_PREFIX )
00221     {
00222         return MULTICAST;
00223     }
00224     else if (d[0] == 0x00000000 && d[1] == 0x00000000 && d[2] == 0x00000000)
00225     {
00226         if (d[3] == 0x00000000)
00227         {
00228             return UNSPECIFIED;
00229         }
00230         else if (d[3] == 0x00000001)
00231         {
00232             return LOOPBACK;
00233         }
00234         else
00235         {
00236             return GLOBAL; // actually an "IPv4-compatible IPv6 address"
00237         }
00238     }
00239     else
00240     {
00241         return GLOBAL;
00242     }
00243 }

const char * IPv6Address::scopeName ( Scope  s  )  [static]

Return the string representation of the given scope.

Referenced by IPv6InterfaceData::info().

00246 {
00247     switch (scope)
00248     {
00249         case UNSPECIFIED:        return "unspec";
00250         case LOOPBACK:           return "loopback";
00251         case MULTICAST:          return "mcast";
00252         case LINK:               return "link";
00253         case SITE:               return "site";
00254         case GLOBAL:             return "global";
00255         default:                 return "???";
00256     }
00257 }

void IPv6Address::constructMask ( int  prefixLength,
uint32 *  mask 
) [static]

Construct a 128 bit mask based on the prefix length. Mask should point to an array of four 32-bit unsigned integers.

Referenced by getPrefix(), getSuffix(), matches(), setPrefix(), and setSuffix().

00260 {
00261     ASSERT(prefixLength>=0 && prefixLength<=128 && mask!=NULL);
00262 
00263     // create a mask based on the prefix length.
00264     if (prefixLength==0)
00265     {
00266         mask[0] = mask[1] = mask[2] = mask[3] = 0x00000000;
00267     }
00268     else if (prefixLength<=32)
00269     {
00270         int num_of_shifts = 32 - prefixLength;
00271         mask[0] = 0xFFFFFFFFU << num_of_shifts;
00272         mask[1] = 0x00000000;
00273         mask[2] = 0x00000000;
00274         mask[3] = 0x00000000;
00275     }
00276     else if (prefixLength<=64)
00277     {
00278         int num_of_shifts = 64 - prefixLength;
00279         mask[0] = 0xFFFFFFFFU;
00280         mask[1] = 0xFFFFFFFFU << num_of_shifts;
00281         mask[2] = 0x00000000;
00282         mask[3] = 0x00000000;
00283     }
00284     else if (prefixLength<=96)
00285     {
00286         int num_of_shifts = 96 - prefixLength;
00287         mask[0] = 0xFFFFFFFFU;
00288         mask[1] = 0xFFFFFFFFU;
00289         mask[2] = 0xFFFFFFFFU << num_of_shifts;
00290         mask[3] = 0x00000000;
00291     }
00292     else
00293     {
00294         int num_of_shifts = 128 - prefixLength;
00295         mask[0] = 0xFFFFFFFFU;
00296         mask[1] = 0xFFFFFFFFU;
00297         mask[2] = 0xFFFFFFFFU;
00298         mask[3] = 0xFFFFFFFFU << num_of_shifts;
00299     }
00300 }

IPv6Address IPv6Address::getPrefix ( int  prefixLength  )  const

Get the IPv6 first prefixLength bits of the address, with the rest set to zero.

00303 {
00304     // First we construct a mask.
00305     uint32 mask[4];
00306     constructMask(prefixLength, mask);
00307 
00308     // Now we mask each IPv6 address segment and create a new IPv6 Address!
00309     return IPv6Address(d[0]&mask[0],d[1]&mask[1],d[2]&mask[2],d[3]&mask[3] );
00310 }

IPv6Address IPv6Address::getSuffix ( int  prefixLength  )  const

Get the last 128-prefixLength bits of the address, with the first bits set to zero.

00313 {
00314     // First we construct a mask.
00315     uint32 mask[4];
00316     constructMask(prefixLength, mask);
00317 
00318     // Now we mask each IPv6 address segment, inverse it
00319     // and create a new IPv6 Address!
00320     return IPv6Address(d[0]&~mask[0],d[1]&~mask[1],d[2]&~mask[2],d[3]&~mask[3] );
00321 }

const IPv6Address & IPv6Address::setPrefix ( const IPv6Address fromAddr,
int  prefixLength 
)

Overwrites the first prefixLength bits of the address with the bits from the address passed as argument. Return value is the object itself.

Referenced by IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf().

00324 {
00325     // first we construct a mask.
00326     uint32 mask[4];
00327     constructMask(prefixLength, mask);
00328 
00329     // combine the addresses
00330     d[0] = (d[0]&~mask[0]) | (fromAddr.d[0]&mask[0]);
00331     d[1] = (d[1]&~mask[1]) | (fromAddr.d[1]&mask[1]);
00332     d[2] = (d[2]&~mask[2]) | (fromAddr.d[2]&mask[2]);
00333     d[3] = (d[3]&~mask[3]) | (fromAddr.d[3]&mask[3]);
00334     return *this;
00335 }

const IPv6Address & IPv6Address::setSuffix ( const IPv6Address fromAddr,
int  prefixLength 
)

Overwrites the last 128-prefixLength bits of the address with the bits from address passed as argument. Return value is the object itself.

Referenced by formLinkLocalAddress().

00339 {
00340     // first we construct a mask.
00341     uint32 mask[4];
00342     constructMask(prefixLength, mask);
00343 
00344     // combine the addresses
00345     d[0] = (d[0]&mask[0]) | (fromAddr.d[0]&~mask[0]);
00346     d[1] = (d[1]&mask[1]) | (fromAddr.d[1]&~mask[1]);
00347     d[2] = (d[2]&mask[2]) | (fromAddr.d[2]&~mask[2]);
00348     d[3] = (d[3]&mask[3]) | (fromAddr.d[3]&~mask[3]);
00349     return *this;
00350 }

IPv6Address IPv6Address::formSolicitedNodeMulticastAddress (  )  const [inline]

Create solicited-node multicast address for this address. This function replaces the prefix with FF02:0:0:0:0:1:FF00:0/104.

Referenced by IPv6NeighbourDiscovery::initiateAddressResolution(), IPv6NeighbourDiscovery::initiateDAD(), IPv6NeighbourDiscovery::processARTimeout(), and IPv6NeighbourDiscovery::processDADTimeout().

00224                                                               {
00225             return IPv6Address(*this).setPrefix(SOLICITED_NODE_PREFIX, 104);
00226         };

IPv6Address IPv6Address::formSubnetRouterAnycastAddress ( int  prefixLength  )  const [inline]

RFC 3513: Section 2.6.1 The Subnet-Router anycast address is predefined. Its format is as follows:

 |                         n bits                 |   128-n bits   |
 +------------------------------------------------+----------------+
 |                   subnet prefix                | 00000000000000 |
 +------------------------------------------------+----------------+
 
00240                                                                            {
00241             return IPv6Address(*this).setSuffix(UNSPECIFIED_ADDRESS, prefixLength);
00242         }

IPv6Address IPv6Address::formLinkLocalAddress ( const InterfaceToken ident  )  [static]

Forms a link-local address using the given interface identifier.

Referenced by IPv6NeighbourDiscovery::assignLinkLocalAddress(), and FlatNetworkConfigurator6::configureAdvPrefixes().

00353 {
00354     IPv6Address suffix(0, 0, ident.normal(), ident.low());
00355     IPv6Address linkLocalAddr = IPv6Address::LINKLOCAL_PREFIX;
00356     linkLocalAddr.setSuffix(suffix, 128-ident.length());
00357     return linkLocalAddr;
00358 }

bool IPv6Address::matches ( const IPv6Address prefix,
int  prefixLength 
) const

Returns true if the address matches the given prefix.

Referenced by IPv6NeighbourDiscovery::createAndSendNSPacket(), RoutingTable6::doLongestPrefixMatch(), RoutingTable6::isLocalAddress(), RoutingTable6::isPrefixPresent(), and IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf().

00361 {
00362     // first we construct a mask.
00363     uint32 mask[4];
00364     constructMask(prefixLength, mask);
00365 
00366     // xor the bits of the 2 addresses, and the result should be zero wherever
00367     // the mask has 1 bits
00368     return (((d[0]^prefix.d[0])&mask[0]) | ((d[1]^prefix.d[1])&mask[1]) |
00369             ((d[2]^prefix.d[2])&mask[2]) | ((d[3]^prefix.d[3])&mask[3]))==0;
00370 }

bool IPv6Address::isUnspecified (  )  const [inline]

bool IPv6Address::isMulticast (  )  const [inline]

Utility function based on getScope()

00260 {return getScope()==MULTICAST;}

bool IPv6Address::isUnicast (  )  const [inline]

Utility function based on getScope()

Referenced by IPv6NeighbourDiscovery::processNSForTentativeAddress().

00263 {return getScope()!=MULTICAST && getScope()!=UNSPECIFIED;}

bool IPv6Address::isLoopback (  )  const [inline]

Utility function based on getScope()

Referenced by IPv6::routePacket().

00266 {return getScope()==LOOPBACK;}

bool IPv6Address::isLinkLocal (  )  const [inline]

Utility function based on getScope()

Referenced by IPv6NeighbourDiscovery::processRAPrefixInfo(), and IPv6::routePacket().

00269 {return getScope()==LINK;}

bool IPv6Address::isSiteLocal (  )  const [inline]

Utility function based on getScope()

00272 {return getScope()==SITE;}

bool IPv6Address::isGlobal (  )  const [inline]

Utility function based on getScope()

Referenced by IPAddressResolver::getIPv6AddressFrom().

00275 {return getScope()==GLOBAL;}

int IPv6Address::getMulticastScope (  )  const

Get the 4-bit scope field of an IPv6 multicast address.

00373 {
00374     if ((d[0] & MULTICAST_MASK)!=MULTICAST_PREFIX)
00375         throw cRuntimeError("IPv6Address::getMulticastScope(): %s is not a multicast address", str().c_str());
00376     return (d[0] >> 16) & 0x0F;
00377 }


Member Data Documentation

uint32 IPv6Address::d[4] [private]

The loopback address

Referenced by ICMPv6::sendErrorMessage().

All-nodes multicast address, scope 1 (interface-local)

Referenced by RoutingTable6::isLocalAddress().

All-nodes multicast address, scope 2 (link-local)

Referenced by RoutingTable6::isLocalAddress(), and IPv6NeighbourDiscovery::sendSolicitedNA().

All-routers multicast address, scope 1 (interface-local)

Referenced by RoutingTable6::isLocalAddress().

All-routers multicast address, scope 2 (link-local)

Referenced by IPv6NeighbourDiscovery::createAndSendRSPacket(), and RoutingTable6::isLocalAddress().

All-routers multicast address, scope 5 (site-local)

Referenced by RoutingTable6::isLocalAddress().

The solicited-node multicast address prefix (prefix length = 104)

Referenced by RoutingTable6::isLocalAddress(), and IPv6NeighbourDiscovery::validateNSPacket().

The link-local prefix (fe80::)

Referenced by formLinkLocalAddress().


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5