#include <IPv6Address.h>
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 () |
| Scope | scope () const |
| IPv6Address | getPrefix (int prefixLength) const |
| IPv6Address | getSuffix (int prefixLength) const |
| const IPv6Address & | setPrefix (const IPv6Address &fromAddr, int prefixLength) |
| const IPv6Address & | setSuffix (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 | multicastScope () 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] |
|
|
IPv6 address scope (RFC 3513) 00054 {
00055 UNSPECIFIED,
00056 LOOPBACK,
00057 MULTICAST,
00058 LINK,
00059 SITE,
00060 GLOBAL
00061 };
|
|
|
Constructor Set all 128 bits of the IPv6 address to '0'. 0:0:0:0:0:0:0:0
|
|
||||||||||||||||||||
|
Constructor Construct an IPv6 Address based on 4 given segments. 00106 {
00107 d[0] = segment0;
00108 d[1] = segment1;
00109 d[2] = segment2;
00110 d[3] = segment3;
00111 }
|
|
|
Constructor. Sets the address from the given text representation. See documentation of tryParse() for supported syntax. 00117 {set(addr);}
|
|
|
Returns -1, 0 or 1. 00129 {
00130 return d[0]<addr.d[0] ? -1 : d[0]>addr.d[0] ? 1 :
00131 d[1]<addr.d[1] ? -1 : d[1]>addr.d[1] ? 1 :
00132 d[2]<addr.d[2] ? -1 : d[2]>addr.d[2] ? 1 :
00133 d[3]<addr.d[3] ? -1 : d[3]>addr.d[3] ? 1 : 0;
00134 }
|
|
||||||||||||
|
Construct a 128 bit mask based on the prefix length. Mask should point to an array of four 32-bit unsigned integers. 00261 {
00262 ASSERT(prefixLength>=0 && prefixLength<=128 && mask!=NULL);
00263
00264 // create a mask based on the prefix length.
00265 if (prefixLength==0)
00266 {
00267 mask[0] = mask[1] = mask[2] = mask[3] = 0x00000000;
00268 }
00269 else if (prefixLength<=32)
00270 {
00271 int num_of_shifts = 32 - prefixLength;
00272 mask[0] = 0xFFFFFFFFU << num_of_shifts;
00273 mask[1] = 0x00000000;
00274 mask[2] = 0x00000000;
00275 mask[3] = 0x00000000;
00276 }
00277 else if (prefixLength<=64)
00278 {
00279 int num_of_shifts = 64 - prefixLength;
00280 mask[0] = 0xFFFFFFFFU;
00281 mask[1] = 0xFFFFFFFFU << num_of_shifts;
00282 mask[2] = 0x00000000;
00283 mask[3] = 0x00000000;
00284 }
00285 else if (prefixLength<=96)
00286 {
00287 int num_of_shifts = 96 - prefixLength;
00288 mask[0] = 0xFFFFFFFFU;
00289 mask[1] = 0xFFFFFFFFU;
00290 mask[2] = 0xFFFFFFFFU << num_of_shifts;
00291 mask[3] = 0x00000000;
00292 }
00293 else
00294 {
00295 int num_of_shifts = 128 - prefixLength;
00296 mask[0] = 0xFFFFFFFFU;
00297 mask[1] = 0xFFFFFFFFU;
00298 mask[2] = 0xFFFFFFFFU;
00299 mask[3] = 0xFFFFFFFFU << num_of_shifts;
00300 }
00301 }
|
|
|
00072 {
00073 if (!strcmp(addr,"<unspec>"))
00074 {
00075 addr += 8;
00076 d[0] = d[1] = d[2] = d[3] = 0;
00077 return true;
00078 }
00079
00080 // parse and store 16-bit units
00081 int octals[8];
00082 int numOctals = parseOctals(addr, octals);
00083
00084 // if address string contains "::", parse and store second half too
00085 if (*addr==':' && *(addr+1)==':')
00086 {
00087 addr += 2;
00088 int suffixOctals[8];
00089 int numSuffixOctals = parseOctals(addr, suffixOctals);
00090
00091 // merge suffixOctals[] into octals[]
00092 if (numOctals+numSuffixOctals>8)
00093 return false; // too many
00094 for (int i=numOctals; i<8; i++) {
00095 int j = i-8+numSuffixOctals;
00096 octals[i] = j<0 ? 0 : suffixOctals[j];
00097 }
00098 numOctals = 8;
00099 }
00100
00101 if (numOctals!=8)
00102 return false; // too few
00103
00104 // copy octets to d[]
00105 for (unsigned int i=0; i<4; i++)
00106 d[i] = (octals[i*2]<<16) + octals[2*i + 1];
00107
00108 return true;
00109 }
|
|
|
Forms a link-local address using the given interface identifier. 00354 {
00355 IPv6Address suffix(0, 0, ident.normal(), ident.low());
00356 IPv6Address linkLocalAddr = IPv6Address::LINKLOCAL_PREFIX;
00357 linkLocalAddr.setSuffix(suffix, 128-ident.length());
00358 return linkLocalAddr;
00359 }
|
|
|
Create solicited-node multicast address for this address. This function replaces the prefix with FF02:0:0:0:0:1:FF00:0/104. 00219 {
00220 return IPv6Address(*this).setPrefix(SOLICITED_NODE_PREFIX, 104);
00221 };
|
|
|
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 | +------------------------------------------------+----------------+ 00235 {
00236 return IPv6Address(*this).setSuffix(UNSPECIFIED_ADDRESS, prefixLength);
00237 }
|
|
|
Get the IPv6 first prefixLength bits of the address, with the rest set to zero. 00304 {
00305 // First we construct a mask.
00306 uint32 mask[4];
00307 constructMask(prefixLength, mask);
00308
00309 // Now we mask each IPv6 address segment and create a new IPv6 Address!
00310 return IPv6Address(d[0]&mask[0],d[1]&mask[1],d[2]&mask[2],d[3]&mask[3] );
00311 }
|
|
|
Get the last 128-prefixLength bits of the address, with the first bits set to zero. 00314 {
00315 // First we construct a mask.
00316 uint32 mask[4];
00317 constructMask(prefixLength, mask);
00318
00319 // Now we mask each IPv6 address segment, inverse it
00320 // and create a new IPv6 Address!
00321 return IPv6Address(d[0]&~mask[0],d[1]&~mask[1],d[2]&~mask[2],d[3]&~mask[3] );
00322 }
|
|
|
Utility function based on scope()
|
|
|
Utility function based on scope()
|
|
|
Utility function based on scope()
|
|
|
Utility function based on scope()
|
|
|
Utility function based on scope()
|
|
|
Utility function based on scope() 00258 {return scope()!=MULTICAST && scope()!=UNSPECIFIED;}
|
|
|
Check if the IPv6 Address is undefined. 00252 {return (d[0]|d[1]|d[2]|d[3])==0;}
|
|
||||||||||||
|
Returns true if the address matches the given prefix. 00362 {
00363 // first we construct a mask.
00364 uint32 mask[4];
00365 constructMask(prefixLength, mask);
00366
00367 // xor the bits of the 2 addresses, and the result should be zero wherever
00368 // the mask has 1 bits
00369 return (((d[0]^prefix.d[0])&mask[0]) | ((d[1]^prefix.d[1])&mask[1]) |
00370 ((d[2]^prefix.d[2])&mask[2]) | ((d[3]^prefix.d[3])&mask[3]))==0;
00371 }
|
|
|
Get the 4-bit scope field of an IPv6 multicast address. 00374 {
00375 if ((d[0] & MULTICAST_MASK)!=MULTICAST_PREFIX)
00376 throw cRuntimeError("IPv6Address::multicastScope(): %s is not a multicast address", str().c_str());
00377 return (d[0] >> 16) & 0x0F;
00378 }
|
|
|
00124 {return !operator==(addr);}
|
|
|
00119 {return compare(addr)<0;}
|
|
|
00121 {
00122 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
00123 }
|
|
|
00120 {return compare(addr)>0;}
|
|
|
Get the IPv6 address scope. 00208 {
00209 //Mask the given IPv6 address with the different mask types
00210 //to get only the IPv6 address scope. Compare the masked
00211 //address with the different prefixes.
00212
00213 if ((d[0] & LINK_LOCAL_MASK) == LINK_LOCAL_PREFIX )
00214 {
00215 return LINK;
00216 }
00217 else if ((d[0] & SITE_LOCAL_MASK) == SITE_LOCAL_PREFIX )
00218 {
00219 return SITE;
00220 }
00221 else if ((d[0] & MULTICAST_MASK) == MULTICAST_PREFIX )
00222 {
00223 return MULTICAST;
00224 }
00225 else if (d[0] == 0x00000000 && d[1] == 0x00000000 && d[2] == 0x00000000)
00226 {
00227 if (d[3] == 0x00000000)
00228 {
00229 return UNSPECIFIED;
00230 }
00231 else if (d[3] == 0x00000001)
00232 {
00233 return LOOPBACK;
00234 }
00235 else
00236 {
00237 return GLOBAL; // actually an "IPv4-compatible IPv6 address"
00238 }
00239 }
00240 else
00241 {
00242 return GLOBAL;
00243 }
00244 }
|
|
|
Return the string representation of the given scope. 00247 {
00248 switch (scope)
00249 {
00250 case UNSPECIFIED: return "unspec";
00251 case LOOPBACK: return "loopback";
00252 case MULTICAST: return "mcast";
00253 case LINK: return "link";
00254 case SITE: return "site";
00255 case GLOBAL: return "global";
00256 default: return "???";
00257 }
00258 }
|
|
||||||||||||||||||||
|
Set the address to the given four 32-bit integers.
|
|
|
Sets the IPv6 address. Given a string. 00145 {
00146 if (!tryParse(addr))
00147 throw new cRuntimeError("IPv6Address: cannot interpret address string `%s'", addr);
00148 }
|
|
||||||||||||
|
Overwrites the first prefixLength bits of the address with the bits from the address passed as argument. Return value is the object itself. 00325 {
00326 // first we construct a mask.
00327 uint32 mask[4];
00328 constructMask(prefixLength, mask);
00329
00330 // combine the addresses
00331 d[0] = (d[0]&~mask[0]) | (fromAddr.d[0]&mask[0]);
00332 d[1] = (d[1]&~mask[1]) | (fromAddr.d[1]&mask[1]);
00333 d[2] = (d[2]&~mask[2]) | (fromAddr.d[2]&mask[2]);
00334 d[3] = (d[3]&~mask[3]) | (fromAddr.d[3]&mask[3]);
00335 return *this;
00336 }
|
|
||||||||||||
|
Overwrites the last 128-prefixLength bits of the address with the bits from address passed as argument. Return value is the object itself. 00340 {
00341 // first we construct a mask.
00342 uint32 mask[4];
00343 constructMask(prefixLength, mask);
00344
00345 // combine the addresses
00346 d[0] = (d[0]&mask[0]) | (fromAddr.d[0]&~mask[0]);
00347 d[1] = (d[1]&mask[1]) | (fromAddr.d[1]&~mask[1]);
00348 d[2] = (d[2]&mask[2]) | (fromAddr.d[2]&~mask[2]);
00349 d[3] = (d[3]&mask[3]) | (fromAddr.d[3]&~mask[3]);
00350 return *this;
00351 }
|
|
|
Get the IPv6 address as a "standard string". 00179 {
00180 if (isUnspecified())
00181 return std::string("<unspec>");
00182
00183 // convert to 16-bit octals
00184 int octals[8] = {
00185 (d[0]>>16), (d[0]&0xffff), (d[1]>>16), (d[1]&0xffff),
00186 (d[2]>>16), (d[2]&0xffff), (d[3]>>16), (d[3]&0xffff)
00187 };
00188
00189 // find longest sequence of zeros in octals[]
00190 int start, end;
00191 findGap(octals, start, end);
00192 if (start==0 && end==8)
00193 return "::0"; // the unspecified address is a special case
00194
00195 // print octals, replacing gap with "::"
00196 std::stringstream os;
00197 os << std::hex;
00198 for (int i=0; i<start; i++)
00199 os << (i==0?"":":") << octals[i];
00200 if (start!=end)
00201 os << "::";
00202 for (int j=end; j<8; j++)
00203 os << (j==end?"":":") << octals[j];
00204 return os.str();
00205 }
|
|
|
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?) 00112 {
00113 if (!addr)
00114 return false;
00115 if (!doTryParse(addr))
00116 return false;
00117 if (*addr!=0)
00118 return false; // illegal trailing character
00119 return true;
00120 }
|
|
||||||||||||
|
FIXME 00123 {
00124 if (!addr)
00125 return false;
00126 if (!doTryParse(addr))
00127 return false;
00128 if (*addr!='/')
00129 return false; // no '/' after address
00130 addr++;
00131
00132 // parse prefix
00133 char *e;
00134 prefixLen = strtoul(addr,&e,10);
00135 if (addr==e)
00136 return false; // no number after '/'
00137 if (*e!=0)
00138 return false; // garbage after number
00139 if (prefixLen<0 || prefixLen>128)
00140 return false; // wrong len value
00141 return true;
00142 }
|
|
|
Returns pointer to internal binary representation of address, four 32-bit unsigned integers. 00171 {return d;}
|
|
|
All-nodes multicast address, scope 1 (interface-local) |
|
|
All-nodes multicast address, scope 2 (link-local) |
|
|
All-routers multicast address, scope 1 (interface-local) |
|
|
All-routers multicast address, scope 2 (link-local) |
|
|
All-routers multicast address, scope 5 (site-local) |
|
|
|
|
|
The link-local prefix (fe80::) |
|
|
The loopback address |
|
|
The solicited-node multicast address prefix (prefix length = 104) |
|
|
The unspecified address |
1.4.1