INET Framework for OMNeT++/OMNEST
|
#include <IPv6Address.h>
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] |
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).
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.
{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.
Referenced by getPrefix(), getSuffix(), matches(), setPrefix(), and setSuffix().
{ ASSERT(prefixLength>=0 && prefixLength<=128 && mask!=NULL); // create a mask based on the prefix length. if (prefixLength==0) { mask[0] = mask[1] = mask[2] = mask[3] = 0x00000000; } else if (prefixLength<=32) { int num_of_shifts = 32 - prefixLength; mask[0] = 0xFFFFFFFFU << num_of_shifts; mask[1] = 0x00000000; mask[2] = 0x00000000; mask[3] = 0x00000000; } else if (prefixLength<=64) { int num_of_shifts = 64 - prefixLength; mask[0] = 0xFFFFFFFFU; mask[1] = 0xFFFFFFFFU << num_of_shifts; mask[2] = 0x00000000; mask[3] = 0x00000000; } else if (prefixLength<=96) { int num_of_shifts = 96 - prefixLength; mask[0] = 0xFFFFFFFFU; mask[1] = 0xFFFFFFFFU; mask[2] = 0xFFFFFFFFU << num_of_shifts; mask[3] = 0x00000000; } else { int num_of_shifts = 128 - prefixLength; mask[0] = 0xFFFFFFFFU; mask[1] = 0xFFFFFFFFU; mask[2] = 0xFFFFFFFFU; mask[3] = 0xFFFFFFFFU << num_of_shifts; } }
bool IPv6Address::doTryParse | ( | const char *& | addr | ) | [protected] |
Referenced by tryParse(), and tryParseAddrWithPrefix().
{ if (!strcmp(addr,"<unspec>")) { addr += 8; d[0] = d[1] = d[2] = d[3] = 0; return true; } // parse and store 16-bit units int octals[8]; int numOctals = parseOctals(addr, octals); // if address string contains "::", parse and store second half too if (*addr==':' && *(addr+1)==':') { addr += 2; int suffixOctals[8]; int numSuffixOctals = parseOctals(addr, suffixOctals); // merge suffixOctals[] into octals[] if (numOctals+numSuffixOctals>8) return false; // too many for (int i=numOctals; i<8; i++) { int j = i-8+numSuffixOctals; octals[i] = j<0 ? 0 : suffixOctals[j]; } numOctals = 8; } if (numOctals!=8) return false; // too few // copy octets to d[] for (unsigned int i=0; i<4; i++) d[i] = (octals[i*2]<<16) + octals[2*i + 1]; return true; }
IPv6Address IPv6Address::formLinkLocalAddress | ( | const InterfaceToken & | ident | ) | [static] |
Forms a link-local address using the given interface identifier.
Referenced by IPv6NeighbourDiscovery::assignLinkLocalAddress(), and FlatNetworkConfigurator6::configureAdvPrefixes().
{ IPv6Address suffix(0, 0, ident.normal(), ident.low()); IPv6Address linkLocalAddr = IPv6Address::LINKLOCAL_PREFIX; linkLocalAddr.setSuffix(suffix, 128-ident.length()); return linkLocalAddr; }
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().
{ return IPv6Address(*this).setPrefix(SOLICITED_NODE_PREFIX, 104); };
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 | +------------------------------------------------+----------------+
{ return IPv6Address(*this).setSuffix(UNSPECIFIED_ADDRESS, prefixLength); }
int IPv6Address::getMulticastScope | ( | ) | const |
Get the 4-bit scope field of an IPv6 multicast address.
{ if ((d[0] & MULTICAST_MASK)!=MULTICAST_PREFIX) throw cRuntimeError("IPv6Address::getMulticastScope(): %s is not a multicast address", str().c_str()); return (d[0] >> 16) & 0x0F; }
IPv6Address IPv6Address::getPrefix | ( | int | prefixLength | ) | const |
Get the IPv6 first prefixLength bits of the address, with the rest set to zero.
Referenced by IPv6NeighbourDiscovery::processRAPrefixInfo(), and IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf().
{ // First we construct a mask. uint32 mask[4]; constructMask(prefixLength, mask); // Now we mask each IPv6 address segment and create a new IPv6 Address! return IPv6Address(d[0]&mask[0],d[1]&mask[1],d[2]&mask[2],d[3]&mask[3] ); }
IPv6Address::Scope IPv6Address::getScope | ( | ) | const |
Get the IPv6 address scope.
Referenced by IPv6InterfaceData::addrLess(), and getLevel().
{ //Mask the given IPv6 address with the different mask types //to get only the IPv6 address scope. Compare the masked //address with the different prefixes. if ((d[0] & LINK_LOCAL_MASK) == LINK_LOCAL_PREFIX ) { return LINK; } else if ((d[0] & SITE_LOCAL_MASK) == SITE_LOCAL_PREFIX ) { return SITE; } else if ((d[0] & MULTICAST_MASK) == MULTICAST_PREFIX ) { return MULTICAST; } else if (d[0] == 0x00000000 && d[1] == 0x00000000 && d[2] == 0x00000000) { if (d[3] == 0x00000000) { return UNSPECIFIED; } else if (d[3] == 0x00000001) { return LOOPBACK; } else { return GLOBAL; // actually an "IPv4-compatible IPv6 address" } } else { return GLOBAL; } }
IPv6Address IPv6Address::getSuffix | ( | int | prefixLength | ) | const |
Get the last 128-prefixLength bits of the address, with the first bits set to zero.
{ // First we construct a mask. uint32 mask[4]; constructMask(prefixLength, mask); // Now we mask each IPv6 address segment, inverse it // and create a new IPv6 Address! return IPv6Address(d[0]&~mask[0],d[1]&~mask[1],d[2]&~mask[2],d[3]&~mask[3] ); }
bool IPv6Address::isGlobal | ( | ) | const [inline] |
Utility function based on getScope()
Referenced by IPAddressResolver::getIPv6AddressFrom().
bool IPv6Address::isLinkLocal | ( | ) | const [inline] |
Utility function based on getScope()
Referenced by IPv6NeighbourDiscovery::processRAPrefixInfo(), and IPv6::routePacket().
bool IPv6Address::isLoopback | ( | ) | const [inline] |
Utility function based on getScope()
Referenced by IPv6::routePacket().
bool IPv6Address::isMulticast | ( | ) | const [inline] |
Utility function based on getScope()
bool IPv6Address::isSiteLocal | ( | ) | const [inline] |
Utility function based on getScope()
bool IPv6Address::isUnicast | ( | ) | const [inline] |
Utility function based on getScope()
Referenced by IPv6NeighbourDiscovery::processNSForTentativeAddress().
{return getScope()!=MULTICAST && getScope()!=UNSPECIFIED;}
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::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().
{ // first we construct a mask. uint32 mask[4]; constructMask(prefixLength, mask); // xor the bits of the 2 addresses, and the result should be zero wherever // the mask has 1 bits return (((d[0]^prefix.d[0])&mask[0]) | ((d[1]^prefix.d[1])&mask[1]) | ((d[2]^prefix.d[2])&mask[2]) | ((d[3]^prefix.d[3])&mask[3]))==0; }
bool IPv6Address::operator!= | ( | const IPv6Address & | addr | ) | const [inline] |
{return !operator==(addr);}
bool IPv6Address::operator< | ( | const IPv6Address & | addr | ) | const [inline] |
{return compare(addr)<0;}
bool IPv6Address::operator== | ( | const IPv6Address & | addr | ) | const [inline] |
bool IPv6Address::operator> | ( | const IPv6Address & | addr | ) | const [inline] |
{return compare(addr)>0;}
const char * IPv6Address::scopeName | ( | Scope | s | ) | [static] |
Return the string representation of the given scope.
Referenced by IPv6InterfaceData::info().
void IPv6Address::set | ( | const char * | addr | ) |
void IPv6Address::set | ( | uint32 | d0, |
uint32 | d1, | ||
uint32 | d2, | ||
uint32 | d3 | ||
) | [inline] |
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 formSolicitedNodeMulticastAddress(), and IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf().
{ // first we construct a mask. uint32 mask[4]; constructMask(prefixLength, mask); // combine the addresses d[0] = (d[0]&~mask[0]) | (fromAddr.d[0]&mask[0]); d[1] = (d[1]&~mask[1]) | (fromAddr.d[1]&mask[1]); d[2] = (d[2]&~mask[2]) | (fromAddr.d[2]&mask[2]); d[3] = (d[3]&~mask[3]) | (fromAddr.d[3]&mask[3]); return *this; }
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(), and formSubnetRouterAnycastAddress().
{ // first we construct a mask. uint32 mask[4]; constructMask(prefixLength, mask); // combine the addresses d[0] = (d[0]&mask[0]) | (fromAddr.d[0]&~mask[0]); d[1] = (d[1]&mask[1]) | (fromAddr.d[1]&~mask[1]); d[2] = (d[2]&mask[2]) | (fromAddr.d[2]&~mask[2]); d[3] = (d[3]&mask[3]) | (fromAddr.d[3]&~mask[3]); return *this; }
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().
{ if (isUnspecified()) return std::string("<unspec>"); // convert to 16-bit octals int octals[8] = { (d[0]>>16), (d[0]&0xffff), (d[1]>>16), (d[1]&0xffff), (d[2]>>16), (d[2]&0xffff), (d[3]>>16), (d[3]&0xffff) }; // find longest sequence of zeros in octals[] int start, end; findGap(octals, start, end); if (start==0 && end==8) return "::0"; // the unspecified address is a special case // print octals, replacing gap with "::" std::stringstream os; os << std::hex; for (int i=0; i<start; i++) os << (i==0?"":":") << octals[i]; if (start!=end) os << "::"; for (int j=end; j<8; j++) os << (j==end?"":":") << octals[j]; return os.str(); }
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().
{ if (!addr) return false; if (!doTryParse(addr)) return false; if (*addr!=0) return false; // illegal trailing character return true; }
bool IPv6Address::tryParseAddrWithPrefix | ( | const char * | addr, |
int & | prefixLen | ||
) |
FIXME
Referenced by RoutingTable6::configureInterfaceFromXML().
{ if (!addr) return false; if (!doTryParse(addr)) return false; if (*addr!='/') return false; // no '/' after address addr++; // parse prefix char *e; prefixLen = strtoul(addr,&e,10); if (addr==e) return false; // no number after '/' if (*e!=0) return false; // garbage after number if (prefixLen<0 || prefixLen>128) return false; // wrong len value return true; }
uint32* IPv6Address::words | ( | ) | [inline] |
Returns pointer to internal binary representation of address, four 32-bit unsigned integers.
Referenced by doPacking(), and doUnpacking().
{return d;}
const uint32* IPv6Address::words | ( | ) | const [inline] |
Returns pointer to internal binary representation of address, four 32-bit unsigned integers.
{return d;}
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().
uint32 IPv6Address::d[4] [private] |
Referenced by compare(), doTryParse(), getMulticastScope(), getPrefix(), getScope(), getSuffix(), matches(), operator==(), IPvXAddress::set(), setPrefix(), setSuffix(), and str().
const IPv6Address IPv6Address::LINKLOCAL_PREFIX [static] |
The link-local prefix (fe80::)
Referenced by formLinkLocalAddress().
const IPv6Address IPv6Address::LOOPBACK_ADDRESS [static] |
The loopback address
Referenced by ICMPv6::sendErrorMessage().
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::UNSPECIFIED_ADDRESS [static] |
The unspecified address
Referenced by IPv6NeighbourDiscovery::createAndSendRSPacket(), IPv6InterfaceData::getLinkLocalAddress(), IPv6NeighbourDiscovery::initiateDAD(), RoutingTable6::lookupDestCache(), and IPv6NeighbourDiscovery::processDADTimeout().