#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 |