#include <IPv6Address.h>
Storage is efficient: an object occupies size of an IPv6 address (128bits=16 bytes).
Public Types | |
UNSPECIFIED | |
LOOPBACK | |
MULTICAST | |
LINK | |
SITE | |
GLOBAL | |
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] |
enum IPv6Address::Scope |
IPv6Address::IPv6Address | ( | ) | [inline] |
IPv6Address::IPv6Address | ( | const char * | addr | ) | [inline] |
Constructor. Sets the address from the given text representation. See documentation of tryParse() for supported syntax.
00117 {set(addr);}
int IPv6Address::compare | ( | const IPv6Address & | addr | ) | const [inline] |
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.
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 }
bool IPv6Address::doTryParse | ( | const char *& | addr | ) | [protected] |
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 }
IPv6Address IPv6Address::formLinkLocalAddress | ( | const InterfaceToken & | ident | ) | [static] |
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 }
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.
00219 { 00220 return IPv6Address(*this).setPrefix(SOLICITED_NODE_PREFIX, 104); 00221 };
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 | +------------------------------------------------+----------------+
00235 { 00236 return IPv6Address(*this).setSuffix(UNSPECIFIED_ADDRESS, prefixLength); 00237 }
IPv6Address IPv6Address::getPrefix | ( | int | prefixLength | ) | const |
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 }
IPv6Address IPv6Address::getSuffix | ( | int | prefixLength | ) | const |
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 }
bool IPv6Address::isGlobal | ( | ) | const [inline] |
bool IPv6Address::isLinkLocal | ( | ) | const [inline] |
bool IPv6Address::isLoopback | ( | ) | const [inline] |
bool IPv6Address::isMulticast | ( | ) | const [inline] |
bool IPv6Address::isSiteLocal | ( | ) | const [inline] |
bool IPv6Address::isUnicast | ( | ) | const [inline] |
bool IPv6Address::isUnspecified | ( | ) | const [inline] |
bool IPv6Address::matches | ( | const IPv6Address & | prefix, | |
int | prefixLength | |||
) | const |
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 }
int IPv6Address::multicastScope | ( | ) | const |
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 }
bool IPv6Address::operator!= | ( | const IPv6Address & | addr | ) | const [inline] |
bool IPv6Address::operator< | ( | const IPv6Address & | addr | ) | const [inline] |
bool IPv6Address::operator== | ( | const IPv6Address & | addr | ) | const [inline] |
bool IPv6Address::operator> | ( | const IPv6Address & | addr | ) | const [inline] |
IPv6Address::Scope IPv6Address::scope | ( | ) | const |
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 }
const char * IPv6Address::scopeName | ( | Scope | s | ) | [static] |
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 }
void IPv6Address::set | ( | const char * | addr | ) |
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.
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 }
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.
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 }
std::string IPv6Address::str | ( | ) | const |
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 }
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?)
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 }
bool IPv6Address::tryParseAddrWithPrefix | ( | const char * | addr, | |
int & | prefixLen | |||
) |
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 }
uint32* IPv6Address::words | ( | ) | [inline] |
Returns pointer to internal binary representation of address, four 32-bit unsigned integers.
00171 {return d;}
const IPv6Address IPv6Address::ALL_NODES_1 [static] |
All-nodes multicast address, scope 1 (interface-local)
const IPv6Address IPv6Address::ALL_NODES_2 [static] |
All-nodes multicast address, scope 2 (link-local)
const IPv6Address IPv6Address::ALL_ROUTERS_1 [static] |
All-routers multicast address, scope 1 (interface-local)
const IPv6Address IPv6Address::ALL_ROUTERS_2 [static] |
All-routers multicast address, scope 2 (link-local)
const IPv6Address IPv6Address::ALL_ROUTERS_5 [static] |
All-routers multicast address, scope 5 (site-local)
uint32 IPv6Address::d[4] [private] |
const IPv6Address IPv6Address::LINKLOCAL_PREFIX [static] |
The link-local prefix (fe80::)
const IPv6Address IPv6Address::LOOPBACK_ADDRESS [static] |
The loopback address
const IPv6Address IPv6Address::SOLICITED_NODE_PREFIX [static] |
The solicited-node multicast address prefix (prefix length = 104)
const IPv6Address IPv6Address::UNSPECIFIED_ADDRESS [static] |
The unspecified address