#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 () |
const uint32 * | words () const |
Scope | getScope () 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 | 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] |
enum IPv6Address::Scope |
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().
IPv6Address::IPv6Address | ( | uint32 | segment0, | |
uint32 | segment1, | |||
uint32 | segment2, | |||
uint32 | segment3 | |||
) | [inline] |
IPv6Address::IPv6Address | ( | const char * | addr | ) | [inline] |
Constructor. Sets the address from the given text representation. See documentation of tryParse() for supported syntax.
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] |
bool IPv6Address::operator> | ( | const IPv6Address & | addr | ) | const [inline] |
bool IPv6Address::operator== | ( | const IPv6Address & | addr | ) | const [inline] |
bool IPv6Address::operator!= | ( | const IPv6Address & | addr | ) | const [inline] |
int IPv6Address::compare | ( | const IPv6Address & | addr | ) | const [inline] |
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 | ) |
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] |
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] |
Check if the IPv6 Address is undefined.
Referenced by IPv6NeighbourDiscovery::assignLinkLocalAddress(), FlatNetworkConfigurator6::configureAdvPrefixes(), IPv6NeighbourDiscovery::createAndSendNSPacket(), IPv6NeighbourDiscovery::determineNextHop(), IPv6::encapsulate(), RoutingTable6::getInterfaceByAddress(), IPAddressResolver::getIPv6AddressFrom(), IPv6NeighbourDiscovery::processNSForTentativeAddress(), IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf(), IPv6::routePacket(), and str().
bool IPv6Address::isMulticast | ( | ) | const [inline] |
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] |
bool IPv6Address::isLinkLocal | ( | ) | const [inline] |
Utility function based on getScope()
Referenced by IPv6NeighbourDiscovery::processRAPrefixInfo(), and IPv6::routePacket().
bool IPv6Address::isSiteLocal | ( | ) | const [inline] |
bool IPv6Address::isGlobal | ( | ) | const [inline] |
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 }
uint32 IPv6Address::d[4] [private] |
Referenced by compare(), doTryParse(), getMulticastScope(), getPrefix(), getScope(), getSuffix(), matches(), operator==(), setPrefix(), setSuffix(), and str().
const IPv6Address IPv6Address::UNSPECIFIED_ADDRESS [static] |
The unspecified address
Referenced by IPv6NeighbourDiscovery::createAndSendRSPacket(), IPv6InterfaceData::getLinkLocalAddress(), IPv6NeighbourDiscovery::initiateDAD(), RoutingTable6::lookupDestCache(), and IPv6NeighbourDiscovery::processDADTimeout().
const IPv6Address IPv6Address::LOOPBACK_ADDRESS [static] |
The loopback address
Referenced by ICMPv6::sendErrorMessage().
const IPv6Address IPv6Address::ALL_NODES_1 [static] |
All-nodes multicast address, scope 1 (interface-local)
Referenced by RoutingTable6::isLocalAddress().
const IPv6Address IPv6Address::ALL_NODES_2 [static] |
All-nodes multicast address, scope 2 (link-local)
Referenced by RoutingTable6::isLocalAddress(), and IPv6NeighbourDiscovery::sendSolicitedNA().
const IPv6Address IPv6Address::ALL_ROUTERS_1 [static] |
All-routers multicast address, scope 1 (interface-local)
Referenced by RoutingTable6::isLocalAddress().
const IPv6Address IPv6Address::ALL_ROUTERS_2 [static] |
All-routers multicast address, scope 2 (link-local)
Referenced by IPv6NeighbourDiscovery::createAndSendRSPacket(), and RoutingTable6::isLocalAddress().
const IPv6Address IPv6Address::ALL_ROUTERS_5 [static] |
All-routers multicast address, scope 5 (site-local)
Referenced by RoutingTable6::isLocalAddress().
const IPv6Address IPv6Address::SOLICITED_NODE_PREFIX [static] |
The solicited-node multicast address prefix (prefix length = 104)
Referenced by RoutingTable6::isLocalAddress(), and IPv6NeighbourDiscovery::validateNSPacket().
const IPv6Address IPv6Address::LINKLOCAL_PREFIX [static] |
The link-local prefix (fe80::)
Referenced by formLinkLocalAddress().