|
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().