Initial IPv6 capability

This commit is contained in:
Unknown
2008-11-07 11:36:15 -08:00
parent d1b135a2d2
commit a9914ca540
29 changed files with 2260 additions and 2 deletions

View File

@@ -25,6 +25,12 @@ void WriteTo (Buffer::Iterator &i, Ipv4Address ad)
{
i.WriteHtonU32 (ad.Get ());
}
void WriteTo (Buffer::Iterator &i, Ipv6Address ad)
{
uint8_t buf[16];
ad.GetBytes(buf);
i.Write(buf, 16);
}
void WriteTo (Buffer::Iterator &i, const Address &ad)
{
uint8_t mac[Address::MAX_SIZE];
@@ -42,6 +48,12 @@ void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
{
ad.Set (i.ReadNtohU32 ());
}
void ReadFrom (Buffer::Iterator &i, Ipv6Address &ad)
{
uint8_t ipv6[16];
i.Read(ipv6, 16);
ad.Set (ipv6);
}
void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len)
{
uint8_t mac[Address::MAX_SIZE];

View File

@@ -22,16 +22,19 @@
#include "ns3/buffer.h"
#include "ipv4-address.h"
#include "ipv6-address.h"
#include "address.h"
#include "mac48-address.h"
namespace ns3 {
void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
void WriteTo (Buffer::Iterator &i, Ipv6Address ad);
void WriteTo (Buffer::Iterator &i, const Address &ad);
void WriteTo (Buffer::Iterator &i, Mac48Address ad);
void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
void ReadFrom (Buffer::Iterator &i, Ipv6Address &ad);
void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len);
void ReadFrom (Buffer::Iterator &i, Mac48Address &ad);

58
src/node/icmp-socket.cc Normal file
View File

@@ -0,0 +1,58 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#include "ns3/object.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
#include "ns3/trace-source-accessor.h"
#include "icmp-socket.h"
NS_LOG_COMPONENT_DEFINE ("IcmpSocket");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (IcmpSocket);
TypeId IcmpSocket::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::IcmpSocket")
.SetParent<Socket> ()
.AddAttribute ("RcvBufSize",
"IcmpSocket maximum receive buffer size (bytes)",
UintegerValue (0xffffffffl),
MakeUintegerAccessor (&IcmpSocket::GetRcvBufSize,
&IcmpSocket::SetRcvBufSize),
MakeUintegerChecker<uint32_t> ())
;
return tid;
}
IcmpSocket::IcmpSocket (void)
{
NS_LOG_FUNCTION_NOARGS ();
}
IcmpSocket::~IcmpSocket (void)
{
NS_LOG_FUNCTION_NOARGS ();
}
}; /* namespace ns3 */

177
src/node/icmp-socket.h Normal file
View File

@@ -0,0 +1,177 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Authors: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#ifndef ICMP_SOCKET_H
#define ICMP_SOCKET_H
#include "socket.h"
#include "ns3/traced-callback.h"
#include "ns3/callback.h"
#include "ns3/ptr.h"
#include "ns3/object.h"
namespace ns3 {
class Node;
class Packet;
/**
* \brief (abstract) base class of all IcmpSockets (for IPv4 or IPv6).
*
* This class exists solely for hosting IcmpSocket attributes that can
* be reused across different implementations.
*/
class IcmpSocket : public Socket
{
public:
/**
* \brief Get the UID of this class.
* \return UID
*/
static TypeId GetTypeId (void);
/**
* \brief Constructor.
*/
IcmpSocket (void);
/**
* \brief Destructor.
*/
virtual ~IcmpSocket (void);
/**
* \brief Get the error.
* \return the error.
*/
virtual enum Socket::SocketErrno GetErrno (void) const = 0;
/**
* \brief Get the node.
* \return the node
*/
virtual Ptr<Node> GetNode (void) const = 0;
/**
* \brief Bind the socket.
* \return 0 if OK, -1 otherwise
*/
virtual int Bind (void) = 0;
/**
* \brief Bind the socket on "addr".
* \param addr address
* \return 0 if OK, -1 otherwise
*/
virtual int Bind (const Address &addr) = 0;
/**
* \brief Close the socket.
* \return 0 if OK, -1 otherwise
*/
virtual int Close (void) = 0;
/**
* \brief Shutdown the socket on send.
* \return 0 if OK, -1 otherwise
*/
virtual int ShutdownSend (void) = 0;
/**
* \brief Shutdown the socket on receive.
* \return 0 if OK, -1 otherwise
*/
virtual int ShutdownRecv (void) = 0;
/**
* \brief Connect to another node.
* \param addr address
* \return 0 if OK, -1 otherwise
*/
virtual int Connect (const Address &addr) = 0;
/**
* \brief Send a packet.
* \param p the packet to send
* \param flags flags
* \return 0 if OK, -1 otherwise
*/
virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
/**
* \brief Get the maximum message size available.
* \return maximum message size
* \warning size of a message that could be sent is limited by the link MTU.
*/
virtual uint32_t GetTxAvailable (void) const = 0;
/**
* \brief Send a packet to a node.
* \param addr the address of the node
* \param flags flags
* \param p the packet to send
* \return 0 if OK, -1 otherwise
*/
virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address &addr) = 0;
/**
* \brief Receive method.
* \param maxSize maximum size we want to return
* \param flags flags
* \return a packet with at maximum maxSize size
*/
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
/**
* \brief Receive method.
* \param maxSize maximum size we want to return
* \param flags flags
* \param fromAddress sender address
* \return a packet with at maximum maxSize size
*/
virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress) = 0;
/**
* \brief Get the size we could receive.
* \return size we could receive at one moment
*/
virtual uint32_t GetRxAvailable (void) const = 0;
private:
/**
* \brief Get the receive buffer size.
* \return receive buffer size
*/
virtual uint32_t GetRcvBufSize (void) const = 0;
/**
* \brief Set the receive buffer size.
* \param rcvBufSize size to set
*/
virtual void SetRcvBufSize (uint32_t rcvBufSize) = 0;
/* FIXME : add ICMP basic attribute for socket */
/* Indirect the attribute setting and getting through private virtual methods */
};
} /* namespace ns3 */
#endif /* ICMP_SOCKET_H */

View File

@@ -0,0 +1,112 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007-2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#include "inet6-socket-address.h"
#include "ns3/assert.h"
namespace ns3 {
Inet6SocketAddress::Inet6SocketAddress (Ipv6Address ipv6, uint16_t port)
: m_ipv6(ipv6),
m_port(port)
{
}
Inet6SocketAddress::Inet6SocketAddress (Ipv6Address ipv6)
: m_ipv6(ipv6),
m_port(0)
{
}
Inet6SocketAddress::Inet6SocketAddress (const char* ipv6, uint16_t port)
: m_ipv6(Ipv6Address(ipv6)),
m_port(port)
{
}
Inet6SocketAddress::Inet6SocketAddress (const char* ipv6)
: m_ipv6(Ipv6Address(ipv6)),
m_port(0)
{
}
Inet6SocketAddress::Inet6SocketAddress (uint16_t port)
: m_ipv6(Ipv6Address::GetAny()),
m_port(port)
{
}
uint16_t Inet6SocketAddress::GetPort (void) const
{
return m_port;
}
void Inet6SocketAddress::SetPort (uint16_t port)
{
m_port=port;
}
Ipv6Address Inet6SocketAddress::GetIpv6 (void) const
{
return m_ipv6;
}
void Inet6SocketAddress::SetIpv6 (Ipv6Address ipv6)
{
m_ipv6=ipv6;
}
bool Inet6SocketAddress::IsMatchingType (const Address &addr)
{
return addr.CheckCompatible(GetType(), 18); /* 16 (address) + 2 (port) */
}
Inet6SocketAddress::operator Address (void) const
{
return ConvertTo();
}
Address Inet6SocketAddress::ConvertTo (void) const
{
uint8_t buf[18];
m_ipv6.Serialize(buf);
buf[16]=m_port & 0xff;
buf[17]=(m_port >> 8) &0xff;
return Address(GetType(), buf, 18);
}
Inet6SocketAddress Inet6SocketAddress::ConvertFrom (const Address &addr)
{
NS_ASSERT(addr.CheckCompatible(GetType(), 18));
uint8_t buf[18];
addr.CopyTo(buf);
Ipv6Address ipv6=Ipv6Address::Deserialize(buf);
uint16_t port= buf[16] | (buf[17] << 8);
return Inet6SocketAddress(ipv6, port);
}
uint8_t Inet6SocketAddress::GetType (void)
{
static uint8_t type=Address::Register();
return type;
}
} /* namespace ns3 */

View File

@@ -0,0 +1,140 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007-2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#ifndef INET6_SOCKET_ADDRESS_H
#define INET6_SOCKET_ADDRESS_H
#include "address.h"
#include "ipv6-address.h"
#include <stdint.h>
namespace ns3 {
/**
* \class Inet6SocketAddress
* \brief An Inet6 address class.
*/
class Inet6SocketAddress
{
public:
/**
* \brief Constructor.
* \param ipv6 the IPv6 address
* \param port the port
*/
Inet6SocketAddress (Ipv6Address ipv6, uint16_t port);
/**
* \brief Constructor (the port is set to zero).
* \param ipv6 the IPv6 address
*/
Inet6SocketAddress (Ipv6Address ipv6);
/**
* \brief Constructor (the address is set to "any").
* \param port the port
*/
Inet6SocketAddress (uint16_t port);
/**
* \brief Constructor.
* \param ipv6 string which represents an IPv6 address
* \param port the port
*/
Inet6SocketAddress (const char* ipv6, uint16_t port);
/**
* \brief Constructor.
* \param ipv6 string which represents an IPv6 address
*/
Inet6SocketAddress (const char* ipv6);
/**
* \brief Get the port.
* \return the port
*/
uint16_t GetPort (void) const;
/**
* \brief Set the port
* \param port the port
*/
void SetPort (uint16_t port);
/**
* \brief Get the IPv6 address.
* \return the IPv6 address
*/
Ipv6Address GetIpv6 (void) const;
/**
* \brief Set the IPv6 address.
* \param ipv6 the address
*/
void SetIpv6 (Ipv6Address ipv6);
/**
* \brief If the address match.
* \param addr the address to test
* \return true if the address match, false otherwise
*/
static bool IsMatchingType (const Address &addr);
/**
* \brief Get an Address instance which represents this
* Inet6SocketAddress instance.
*/
operator Address (void) const;
/**
* \brief Convert the address to a InetSocketAddress.
* \param addr the address to convert
* \return an Inet6SocketAddress instance corresponding to address
*/
static Inet6SocketAddress ConvertFrom (const Address &addr);
private:
/**
* \brief Convert to Address.
* \return Address instance
*/
Address ConvertTo (void) const;
/**
* \brief Get the type.
* \return the type of Inet6SocketAddress
*/
static uint8_t GetType (void);
/**
* \brief The IPv6 address.
*/
Ipv6Address m_ipv6;
/**
* \brief The port.
*/
uint16_t m_port;
};
} /* namespace ns3 */
#endif /* INET6_SOCKET_ADDRESS_H */

686
src/node/ipv6-address.cc Normal file
View File

@@ -0,0 +1,686 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007-2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#include <string.h>
#include "ns3/log.h"
#include "ipv6-address.h"
#include "ns3/assert.h"
#include "mac48-address.h"
#include <iomanip>
NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
namespace ns3 {
#ifdef __cplusplus
extern "C"
{
#endif
/**
* \brief Get a hash key.
* \param k the key
* \param length the length of the key
* \param level the previous hash, or an arbitrary value
* \return hash
* \note Adpated from Jens Jakobsen implementation (chillispot).
*/
static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level)
{
#define mix(a,b,c) \
{ \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
typedef uint32_t ub4; /* unsigned 4-byte quantities */
typedef unsigned char ub1; /* unsigned 1-byte quantities */
uint32_t a,b,c,len;
/* Set up the internal state */
len = length;
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
c = level; /* the previous hash value */
/*---------------------------------------- handle most of the key */
while (len >= 12)
{
a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
mix(a,b,c);
k += 12; len -= 12;
}
/*------------------------------------- handle the last 11 bytes */
c += length;
switch(len) /* all the case statements fall through */
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
case 9 : c+=((ub4)k[8]<<8);
/* the first byte of c is reserved for the length */
case 8 : b+=((ub4)k[7]<<24);
case 7 : b+=((ub4)k[6]<<16);
case 6 : b+=((ub4)k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=((ub4)k[3]<<24);
case 3 : a+=((ub4)k[2]<<16);
case 2 : a+=((ub4)k[1]<<8);
case 1 : a+=k[0];
/* case 0: nothing left to add */
}
mix(a,b,c);
/*-------------------------------------------- report the result */
return c;
}
#ifdef __cplusplus
}
#endif
/**
* \brief Convert an IPv6 C-string into a 128-bit representation.
* \return 1 if OK, 0 if failure (bad format, ...)
* \note This function is strongly inspired by inet_pton6() from Paul Vixie.
* \todo Handle IPv6 address with decimal value for last four bytes.
*/
static int AsciiToIpv6Host (char const *address, uint8_t addr[16])
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[16 /*NS_IN6ADDRSZ*/], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, seen_xdigits;
unsigned int val;
memset((tp = tmp), '\0', 16 /* NS_IN6ADDRSZ*/);
endp = tp + 16 /*NS_IN6ADDRSZ*/;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*address == ':')
if (*++address != ':')
return (0);
curtok = address;
seen_xdigits = 0;
val = 0;
while ((ch = *address++) != '\0')
{
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL)
{
val <<= 4;
val |= (pch - xdigits);
if (++seen_xdigits > 4)
return (0);
continue;
}
if (ch == ':')
{
curtok = address;
if (!seen_xdigits)
{
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + 2 /*NS_INT16SZ*/ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
seen_xdigits = 0;
val = 0;
continue;
}
/* TODO Handle address like 2001::xxx.xxx.xxx.xxxx */
#if 0
if (ch == '.' && ((tp + 4 /*NS_INADDRSZ*/) <= endp) &&
inet_pton4(curtok, tp) > 0)
{
tp += 4 /*NS_INADDRSZ*/;
seen_xdigits = 0;
break;/* '\0' was seen by inet_pton4(). */
}
#endif
return (0);
}
if (seen_xdigits)
{
if (tp + 2/* NS_INT16SZ*/ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if (colonp != NULL)
{
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
if (tp == endp)
return (0);
for (i = 1; i <= n; i++)
{
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
/* memcpy(dst, tmp, NS_IN6ADDRSZ); */
memcpy(addr, tmp, 16);
return (1);
}
Ipv6Address::Ipv6Address ()
{
memset(m_address, 0x00, 16);
}
Ipv6Address::Ipv6Address (Ipv6Address const& addr)
{
memcpy(m_address, addr.m_address, 16);
}
Ipv6Address::Ipv6Address (Ipv6Address const* addr)
{
memcpy(m_address, addr->m_address, 16);
}
Ipv6Address::Ipv6Address (char const* address)
{
AsciiToIpv6Host (address, m_address);
}
Ipv6Address::Ipv6Address (uint8_t address[16])
{
/* 128 bit => 16 bytes */
memcpy(m_address, address, 16);
}
Ipv6Address::~Ipv6Address ()
{
/* do nothing */
}
void Ipv6Address::Set (char const* address)
{
AsciiToIpv6Host (address, m_address);
}
void Ipv6Address::Set (uint8_t address[16])
{
/* 128 bit => 16 bytes */
memcpy(m_address, address, 16);
}
void Ipv6Address::Serialize (uint8_t buf[16]) const
{
memcpy(buf, m_address, 16);
}
Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
{
Ipv6Address ipv6((uint8_t*)buf);
return ipv6;
}
Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix)
{
Ipv6Address ret;
uint8_t buf[16];
uint8_t buf2[16];
addr.CopyTo(buf);
prefix.GetBytes(buf2);
memcpy(buf2 + 8, buf, 3);
buf2[11] = 0xff;
buf2[12] = 0xfe;
memcpy(buf2 + 13, buf + 3, 3);
buf2[8] |= 0x02;
ret.Set(buf2);
return ret;
}
Ipv6Address Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address addr)
{
Ipv6Address ret;
uint8_t buf[16];
uint8_t buf2[16];
addr.CopyTo(buf);
memset(buf2, 0x00, sizeof(buf2));
buf2[0] = 0xfe;
buf2[1] = 0x80;
memcpy(buf2 + 8, buf, 3);
buf2[11] = 0xff;
buf2[12] = 0xfe;
memcpy(buf2 + 13, buf + 3, 3);
buf2[8] |= 0x02;
ret.Set(buf2);
return ret;
}
Ipv6Address Ipv6Address::MakeSolicitedAddress (Ipv6Address addr)
{
uint8_t buf[16];
uint8_t buf2[16];
Ipv6Address ret;
addr.Serialize(buf2);
memset(buf, 0x00, sizeof(buf));
buf[0] = 0xff;
buf[1] = 0x02;
buf[11] = 0x01;
buf[12] = 0xff;
buf[13] = buf2[13];
buf[14] = buf2[14];
buf[15] = buf2[15];
ret.Set(buf);
return ret;
}
void Ipv6Address::Print (std::ostream& os) const
{
os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[0]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[1] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[2]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[3] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[4]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[5] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[6]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[7] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[8]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[9] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[10]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[11] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[12]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[13] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[14]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[15];
}
bool Ipv6Address::IsLocalhost () const
{
static Ipv6Address localhost("::1");
return (*this == localhost);
}
bool Ipv6Address::IsMulticast () const
{
if(m_address[0] == 0xff)
{
return true;
}
return false;
}
Ipv6Address Ipv6Address::CombinePrefix (Ipv6Prefix const & prefix)
{
Ipv6Address ipv6;
uint8_t addr[16];
uint8_t pref[16];
unsigned int i = 0;
memcpy(addr, m_address, 16);
((Ipv6Prefix)prefix).GetBytes(pref);
/* a little bit ugly... */
for(i = 0 ; i < 16 ; i++)
{
addr[i] = addr[i] & pref[i];
}
ipv6.Set(addr);
return ipv6;
}
bool Ipv6Address::IsSolicitedMulticast () const
{
uint8_t buf[16];
Serialize(buf);
if(buf[0] == 0xff &&
buf[1] == 0x02 &&
buf[11] == 0x01 &&
buf[12] == 0xff)
{
return true;
}
return false;
}
bool Ipv6Address::IsAllNodesMulticast () const
{
static Ipv6Address allnodes("ff02::1");
return (*this == allnodes);
}
bool Ipv6Address::IsAllRoutersMulticast () const
{
static Ipv6Address allrouters("ff02::2");
return (*this == allrouters);
}
bool Ipv6Address::IsAllHostsMulticast () const
{
static Ipv6Address allhosts("ff02::3");
return (*this == allhosts);
}
bool Ipv6Address::IsAny () const
{
static Ipv6Address any("::");
return (*this == any);
}
bool Ipv6Address::IsMatchingType (const Address& address)
{
return address.CheckCompatible(GetType(), 16);
}
Ipv6Address::operator Address () const
{
return ConvertTo ();
}
Address Ipv6Address::ConvertTo (void) const
{
uint8_t buf[16];
Serialize (buf);
return Address(GetType(), buf, 16);
}
Ipv6Address Ipv6Address::ConvertFrom (const Address &address)
{
NS_ASSERT (address.CheckCompatible (GetType (), 16));
uint8_t buf[16];
address.CopyTo (buf);
return Deserialize (buf);
}
uint8_t Ipv6Address::GetType (void)
{
static uint8_t type = Address::Register();
return type;
}
Ipv6Address Ipv6Address::GetZero ()
{
Ipv6Address zero("::");
return zero;
}
Ipv6Address Ipv6Address::GetAny ()
{
Ipv6Address any("::");
return any;
}
Ipv6Address Ipv6Address::GetAllNodesMulticast ()
{
Ipv6Address nmc("ff02::1");
return nmc;
}
Ipv6Address Ipv6Address::GetAllRoutersMulticast ()
{
Ipv6Address rmc("ff02::2");
return rmc;
}
Ipv6Address Ipv6Address::GetAllHostsMulticast ()
{
Ipv6Address hmc("ff02::3");
return hmc;
}
Ipv6Address Ipv6Address::GetLoopback ()
{
static Ipv6Address loopback("::1");
return loopback;
}
void Ipv6Address::GetBytes (uint8_t buf[16]) const
{
memcpy(buf, m_address, 16);
}
bool Ipv6Address::IsLinkLocal () const
{
Ipv6Address linkLocal("fe80::0");
if(!IsMulticast() && ((Ipv6Address*)this)->CombinePrefix(Ipv6Prefix(64))==linkLocal)
{
return true;
}
return false;
}
bool Ipv6Address::IsEqual (const Ipv6Address& other) const
{
if(!memcmp(m_address, other.m_address, 16))
{
return true;
}
return false;
}
std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
{
address.Print(os);
return os;
}
std::istream& operator >> (std::istream& is, Ipv6Address& address)
{
std::string str;
is >> str;
address = Ipv6Address (str.c_str ());
return is;
}
Ipv6Prefix::Ipv6Prefix ()
{
memset(m_prefix, 0x00, 16);
}
Ipv6Prefix::Ipv6Prefix (char const* prefix)
{
AsciiToIpv6Host(prefix, m_prefix);
}
Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
{
memcpy(m_prefix, prefix, 16);
}
Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
{
unsigned int nb=0;
unsigned int mod=0;
unsigned int i=0;
memset(m_prefix, 0x00, 16);
NS_ASSERT(prefix <= 128);
nb = prefix / 8;
mod = prefix % 8;
memset(m_prefix, 0xff, nb);
if(mod)
{
m_prefix[nb] = 0xff << (8-mod);
}
if(nb < 16)
{
nb++;
for(i = nb; i < 16 ; i++)
{
m_prefix[i] = 0x00;
}
}
}
Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const& prefix)
{
memcpy(m_prefix, prefix.m_prefix, 16);
}
Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const* prefix)
{
memcpy(m_prefix, prefix->m_prefix, 16);
}
Ipv6Prefix::~Ipv6Prefix ()
{
/* do nothing */
}
bool Ipv6Prefix::IsMatch (Ipv6Address a, Ipv6Address b) const
{
uint8_t addrA[16];
uint8_t addrB[16];
unsigned int i = 0;
a.GetBytes(addrA);
b.GetBytes(addrB);
/* a little bit ugly... */
for(i = 0 ; i < 16 ; i++)
{
if((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
{
return false;
}
}
return true;
}
void Ipv6Prefix::Print (std::ostream &os) const
{
os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[0]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[1] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[2]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[3] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[4]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[5] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[6]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[7] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[8]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[9] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[10]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[11] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[12]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[13] << ":"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[14]
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[15];
}
Ipv6Prefix Ipv6Prefix::GetLoopback ()
{
Ipv6Prefix prefix((uint8_t)128);
return prefix;
}
Ipv6Prefix Ipv6Prefix::GetZero ()
{
Ipv6Prefix prefix((uint8_t)0);
return prefix;
}
void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
{
memcpy(buf, m_prefix, 16);
}
bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
{
if(!memcmp(m_prefix, other.m_prefix, 16))
{
return true;
}
return false;
}
std::ostream& operator<< (std::ostream& os, Ipv6Prefix const& prefix)
{
prefix.Print (os);
return os;
}
std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
{
std::string str;
is >> str;
prefix = Ipv6Prefix (str.c_str ());
return is;
}
bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b)
{
return a.IsEqual (b);
}
bool operator != (Ipv6Prefix const &a, Ipv6Prefix const &b)
{
return !a.IsEqual (b);
}
size_t Ipv6AddressHash::operator() (Ipv6Address const &x) const
{
uint8_t buf[16];
x.GetBytes(buf);
return lookuphash(buf, sizeof(buf), 0);
}
ATTRIBUTE_HELPER_CPP (Ipv6Address);
ATTRIBUTE_HELPER_CPP (Ipv6Prefix);
} /* namespace ns3 */

427
src/node/ipv6-address.h Normal file
View File

@@ -0,0 +1,427 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007-2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#ifndef IPV6_ADDRESS_H
#define IPV6_ADDRESS_H
#include <stdint.h>
#include <string.h>
#include <ostream>
#include "address.h"
#include "ns3/attribute-helper.h"
namespace ns3 {
class Ipv6Prefix;
class Mac48Address;
/**
* \class Ipv6Address
* \brief Describes an IPv6 address.
* \see Ipv6Prefix
*/
class Ipv6Address
{
public :
/**
* \brief Default constructor.
*/
Ipv6Address ();
/**
* \brief Constructs an Ipv6Address by parsing the input C-string.
* \param address the C-string containing the IPv6 address (e.g. 2001:660:4701::1).
*/
Ipv6Address (char const* address);
/**
* \brief Constructs an Ipv6Address by using the input 16 bytes.
* \param address the 128-bit address
* \warning the parameter must point on a 16 bytes integer array!
*/
Ipv6Address (uint8_t address[16]);
/**
* \brief Copy constructor.
* \param addr Ipv6Address object
*/
Ipv6Address (Ipv6Address const & addr);
/**
* \brief Copy constructor.
* \param addr Ipv6Address pointer
*/
Ipv6Address (Ipv6Address const* addr);
/**
* \brief Destructor.
*/
~Ipv6Address ();
/**
* \brief Sets an Ipv6Address by parsing the input C-string.
* \param address the C-string containing the IPv6 address (e.g. 2001:660:4701::1).
*/
void Set (char const* address);
/**
* \brief Set an Ipv6Address by using the input 16 bytes.
*
* \param address the 128-bit address
* \warning the parameter must point on a 16 bytes integer array!
*/
void Set (uint8_t address[16]);
/**
* \brief Comparison operation between two Ipv6Addresses.
*
* \param other the IPv6 address to which to compare thisaddress
* \return true if the addresses are equal, false otherwise
*/
bool IsEqual (const Ipv6Address& other) const;
/**
* \brief Serialize this address to a 16-byte buffer.
* \param buf the output buffer to which this address gets overwritter with this
* Ipv6Address
*/
void Serialize (uint8_t buf[16]) const;
/**
* \brief Deserialize this address.
* \param buf buffer to read address from
* \return an Ipv6Address
*/
static Ipv6Address Deserialize (const uint8_t buf[16]);
/**
* \brief Make the solicited IPv6 address.
* \param addr the IPv6 address
* \return Solicited IPv6 address
*/
static Ipv6Address MakeSolicitedAddress (Ipv6Address addr);
/**
* \brief Make the autoconfigured IPv6 address with Mac48Address.
* \param addr the MAC address (48 bits).
* \param prefix the IPv6 prefix
* \return autoconfigured IPv6 address
*/
static Ipv6Address MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix);
/**
* \brief Make the autoconfigured link-local IPv6 address with Mac48Address.
* \param mac the MAC address (48 bits).
* \return autoconfigured link-local IPv6 address
*/
static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac48Address mac);
/**
* \brief Print this address to the given output stream.
*
* The print format is in the typical "2001:660:4701::1".
* \param os the output stream to which this Ipv6Address is printed
*/
void Print (std::ostream& os) const;
/**
* \brief If the IPv6 address is localhost (::1).
* \return true if localhost, false otherwise
*/
bool IsLocalhost () const;
/**
* \brief If the IPv6 address is multicast (ff00::/8).
* \return true if multicast, false otherwise
*/
bool IsMulticast () const;
/**
* \brief If the IPv6 address is "all nodes multicast" (ff02::1/8).
* \return true if "all nodes multicast", false otherwise
*/
bool IsAllNodesMulticast () const;
/**
* \brief If the IPv6 address is "all routers multicast" (ff02::2/8).
* \return true if "all routers multicast", false otherwise
*/
bool IsAllRoutersMulticast () const;
/**
* \brief If the IPv6 address is "all hosts multicast" (ff02::3/8).
* \return true if "all hosts multicast", false otherwise
*/
bool IsAllHostsMulticast () const;
/**
* \brief If the IPv6 address is a link-local address (fe80::/64).
* \return true if the address is link-local, false otherwise
*/
bool IsLinkLocal () const;
/**
* \brief If the IPv6 address is a Solicited multicast address.
* \return true if it is, false otherwise
*/
bool IsSolicitedMulticast () const;
/**
* \brief If the IPv6 address is the "Any" address.
* \return true if it is, false otherwise
*/
bool IsAny () const;
/**
* \brief Combine this address with a prefix.
* \param prefix a IPv6 prefix
* \return an IPv6 address that is this address combined
* (bitwise AND) with a prefix, yielding an IPv6 network address.
*/
Ipv6Address CombinePrefix (Ipv6Prefix const & prefix);
/**
* \brief If the Address matches the type.
* \param address other address
* \return true if the type matches, false otherwise
*/
static bool IsMatchingType (const Address& address);
/**
* \brief Convert to Address object
*/
operator Address () const;
/**
* \brief Convert the Address object into an Ipv6Address one.
* \return an Ipv6Address
*/
static Ipv6Address ConvertFrom (const Address& address);
/**
* \brief Get the 0 (::) Ipv6Address.
* \return the :: Ipv6Address representation
*/
static Ipv6Address GetZero ();
/**
* \brief Get the "any" (::) Ipv6Address.
* \return the "any" (::) Ipv6Address
*/
static Ipv6Address GetAny ();
/**
* \brief Get the "all nodes multicast" address.
* \return the "ff02::2/8" Ipv6Address representation
*/
static Ipv6Address GetAllNodesMulticast ();
/**
* \brief Get the "all routers multicast" address.
* \return the "ff02::2/8" Ipv6Address representation
*/
static Ipv6Address GetAllRoutersMulticast ();
/**
* \brief Get the "all hosts multicast" address.
* \return the "ff02::3/8" Ipv6Address representation
*/
static Ipv6Address GetAllHostsMulticast ();
/**
* \brief Get the loopback address.
* \return the "::1/128" Ipv6Address representation.
*/
static Ipv6Address GetLoopback ();
/**
* \brief Get the bytes corresponding to the address.
* \param buf buffer to store the data
* \return bytes of the address
*/
void GetBytes (uint8_t buf[16]) const;
private:
/**
* \brief convert the IPv6Address object to an Address object.
* \return the Address object corresponding to this object.
*/
Address ConvertTo (void) const;
/**
* \brief Return the Type of address.
* \return type of address
*/
static uint8_t GetType (void);
/**
* \brief The address representation on 128 bits (16 bytes).
*/
uint8_t m_address[16];
friend bool operator == (Ipv6Address const &a, Ipv6Address const &b);
friend bool operator != (Ipv6Address const &a, Ipv6Address const &b);
friend bool operator < (Ipv6Address const &a, Ipv6Address const &b);
};
/**
* \class Ipv6Prefix
* \brief Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
* \see Ipv6Address
*/
class Ipv6Prefix
{
public:
/**
* \brief Default constructor.
*/
Ipv6Prefix ();
/**
* \brief Constructs an Ipv6Prefix by using the input 16 bytes.
* \param prefix the 128-bit prefix
*/
Ipv6Prefix (uint8_t prefix[16]);
/**
* \brief Constructs an Ipv6Prefix by using the input string.
* \param prefix the 128-bit prefix
*/
Ipv6Prefix (char const* prefix);
/**
* \brief Constructs an Ipv6Prefix by using the input number of bits.
* \param prefix number of bits of the prefix (0 - 128)
* \note A valid number of bits is between 0 and 128).
*/
Ipv6Prefix (uint8_t prefix);
/**
* \brief Copy constructor.
* \param prefix Ipv6Prefix object
*/
Ipv6Prefix (Ipv6Prefix const& prefix);
/**
* \brief Copy constructor.
* \param prefix Ipv6Prefix pointer
*/
Ipv6Prefix (Ipv6Prefix const* prefix);
/**
* \brief Destructor.
*/
~Ipv6Prefix ();
/**
* \brief If the Address match the type.
* \param a a first address
* \param b a second address
* \return true if the type match, false otherwise
*/
bool IsMatch (Ipv6Address a, Ipv6Address b) const;
/**
* \brief Get the bytes corresponding to the prefix.
* \param buf buffer to store the data
*/
void GetBytes (uint8_t buf[16]) const;
/**
* \brief Comparison operation between two Ipv6Prefix.
* \param other the IPv6 prefix to which to compare this prefix
* \return true if the prefixes are equal, false otherwise
*/
bool IsEqual (const Ipv6Prefix& other) const;
/**
* \brief Print this address to the given output stream.
*
* The print format is in the typicall "2001:660:4701::1".
* \param os the output stream to which this Ipv6Address is printed
*/
void Print (std::ostream &os) const;
/**
* \brief Get the loopback prefix ( /128).
* \return a Ipv6Prefix corresponding to loopback prefix
*/
static Ipv6Prefix GetLoopback ();
/**
* \brief Get the zero prefix ( /0).
* \return an Ipv6Prefix
*/
static Ipv6Prefix GetZero ();
private:
/**
* \brief The prefix representation.
*/
uint8_t m_prefix[16];
};
/**
* \class ns3::Ipv6AddressValue
* \brief hold objects of type ns3::Ipv6Address
*/
ATTRIBUTE_HELPER_HEADER (Ipv6Address);
/**
* \class ns3::Ipv6PrefixValue
* \brief hold objects of type ns3::Ipv6Prefix
*/
ATTRIBUTE_HELPER_HEADER (Ipv6Prefix);
std::ostream& operator << (std::ostream& os, Ipv6Address const& address);
std::ostream& operator<< (std::ostream& os, Ipv6Prefix const& prefix);
std::istream & operator >> (std::istream &is, Ipv6Address &address);
std::istream & operator >> (std::istream &is, Ipv6Prefix &prefix);
inline bool operator == (const Ipv6Address& a, const Ipv6Address& b)
{
return (!memcmp (a.m_address, b.m_address, 16));
}
inline bool operator != (const Ipv6Address& a, const Ipv6Address& b)
{
return memcmp (a.m_address, b.m_address, 16);
}
inline bool operator < (const Ipv6Address& a, const Ipv6Address& b)
{
return (memcmp (a.m_address, b.m_address, 16) < 0);
}
class Ipv6AddressHash : public std::unary_function<Ipv6Address, size_t>
{
public:
size_t operator() (Ipv6Address const &x) const;
};
bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b);
bool operator != (Ipv6Prefix const &a, Ipv6Prefix const &b);
} /* namespace ns3 */
#endif /* IPV6_ADDRESS_H */

187
src/node/ipv6-header.cc Normal file
View File

@@ -0,0 +1,187 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007-2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#include "ns3/assert.h"
#include "ns3/log.h"
#include "ns3/header.h"
#include "address-utils.h"
#include "ipv6-header.h"
NS_LOG_COMPONENT_DEFINE ("Ipv6Header");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (Ipv6Header);
Ipv6Header::Ipv6Header ()
: m_version (6),
m_trafficClass (0),
m_flowLabel (1),
m_payloadLength (0),
m_nextHeader (0),
m_hopLimit (0)
{
SetSourceAddress (Ipv6Address("::"));
SetDestinationAddress(Ipv6Address ("::"));
}
void Ipv6Header::SetTrafficClass (uint8_t traffic)
{
m_trafficClass = traffic;
}
uint8_t Ipv6Header::GetTrafficClass () const
{
return m_trafficClass;
}
void Ipv6Header::SetFlowLabel (uint32_t flow)
{
m_flowLabel = flow;
}
uint32_t Ipv6Header::GetFlowLabel () const
{
return m_flowLabel;
}
void Ipv6Header::SetPayloadLength (uint16_t len)
{
m_payloadLength = len;
}
uint16_t Ipv6Header::GetPayloadLength () const
{
return m_payloadLength;
}
void Ipv6Header::SetNextHeader (uint8_t next)
{
m_nextHeader = next;
}
uint8_t Ipv6Header::GetNextHeader () const
{
return m_nextHeader;
}
void Ipv6Header::SetHopLimit (uint8_t limit)
{
m_hopLimit = limit;
}
uint8_t Ipv6Header::GetHopLimit () const
{
return m_hopLimit;
}
void Ipv6Header::SetSourceAddress (Ipv6Address src)
{
m_sourceAddress = src;
}
Ipv6Address Ipv6Header::GetSourceAddress () const
{
return m_sourceAddress;
}
void Ipv6Header::SetDestinationAddress (Ipv6Address dst)
{
m_destinationAddress = dst;
}
Ipv6Address Ipv6Header::GetDestinationAddress () const
{
return m_destinationAddress;
}
TypeId Ipv6Header::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Ipv6Header")
.SetParent<Header> ()
.AddConstructor<Ipv6Header> ()
;
return tid;
}
TypeId Ipv6Header::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
void Ipv6Header::Print (std::ostream& os) const
{
os << "("
"Version " << m_version << " "
<< "Traffic class 0x" << std::hex << m_trafficClass << std::dec << " "
<< "Flow Label 0x" << std::hex << m_flowLabel << std::dec << " "
<< "Payload Length " << m_payloadLength << " "
<< "Next Header " << std::dec << (uint32_t) m_nextHeader << " "
<< "Hop Limit " << std::dec << (uint32_t)m_hopLimit << " )"
<< m_sourceAddress << " > " << m_destinationAddress
;
}
uint32_t Ipv6Header::GetSerializedSize () const
{
return 10 * 4;
}
void Ipv6Header::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
uint32_t vTcFl = 0; /* version, Traffic Class and Flow Label fields */
vTcFl= (6 << 28) | (m_trafficClass << 20) | (m_flowLabel);
i.WriteHtonU32(vTcFl);
i.WriteHtonU16(m_payloadLength);
i.WriteU8(m_nextHeader);
i.WriteU8(m_hopLimit);
WriteTo(i, m_sourceAddress);
WriteTo(i, m_destinationAddress);
}
uint32_t Ipv6Header::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
uint32_t vTcFl = 0;
vTcFl = i.ReadNtohU32();
m_version = vTcFl >> 28;
NS_ASSERT((m_version) == 6);
m_trafficClass = (uint8_t)((vTcFl >> 20) & 0x000000ff);
m_flowLabel = vTcFl & 0xfff00000;
m_payloadLength = i.ReadNtohU16();
m_nextHeader = i.ReadU8();
m_hopLimit = i.ReadU8();
ReadFrom(i, m_sourceAddress);
ReadFrom(i, m_destinationAddress);
return GetSerializedSize();
}
} /* namespace ns3 */

237
src/node/ipv6-header.h Normal file
View File

@@ -0,0 +1,237 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007-2008 Louis Pasteur University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
#ifndef IPV6_HEADER_H
#define IPV6_HEADER_H
#include "ns3/header.h"
#include "ns3/ipv6-address.h"
namespace ns3 {
/**
* \class Ipv6Header
* \brief Packet header for IPv6
*/
class Ipv6Header : public Header
{
public:
/**
* \enum NextHeader_e
* \brief IPv6 next-header value
*/
enum NextHeader_e
{
IPV6_EXT_HOP_BY_HOP=0,
IPV6_IPV4=4,
IPV6_TCP=6,
IPV6_UDP=17,
IPV6_IPV6=41,
IPV6_EXT_ROUTING=43,
IPV6_EXT_FRAGMENTATION=44,
IPV6_EXT_CONFIDENTIALITY=50,
IPV6_EXT_AUTHENTIFICATION,
IPV6_ICMPV6=58,
IPV6_EXT_END,
IPV6_EXT_DESTINATION,
IPV6_SCTP=135,
IPV6_EXT_MOBILITY=135,
IPV6_UDP_LITE,
};
/**
* \brief Get the type identifier.
* \return type identifier
*/
static TypeId GetTypeId (void);
/**
* \brief Return the instance type identifier.
* \return instance type ID
*/
virtual TypeId GetInstanceTypeId (void) const;
/**
* \brief Constructor.
*/
Ipv6Header (void);
/**
* \brief Set the "Traffic class" field.
* \param traffic the 8-bit value
*/
void SetTrafficClass (uint8_t traffic);
/**
* \brief Get the "Traffic class" field.
* \return the traffic value
*/
uint8_t GetTrafficClass (void) const;
/**
* \brief Set the "Flow label" field.
* \param flow the 20-bit value
*/
void SetFlowLabel (uint32_t flow);
/**
* \brief Get the "Flow label" field.
* \return the flow label value
*/
uint32_t GetFlowLabel (void) const;
/**
* \brief Set the "Payload length" field.
* \param len the length of the payload in bytes
*/
void SetPayloadLength (uint16_t len);
/**
* \brief Get the "Payload length" field.
* \return the payload length
*/
uint16_t GetPayloadLength (void) const;
/**
* \brief Set the "Next header" field.
* \param next the next header number
*/
void SetNextHeader (uint8_t next);
/**
* \brief Get the next header.
* \return the next header number
*/
uint8_t GetNextHeader (void) const;
/**
* \brief Set the "Hop limit" field (TTL).
* \param limit the 8-bit value
*/
void SetHopLimit (uint8_t limit);
/**
* \brief Get the "Hop limit" field (TTL).
* \return the hop limit value
*/
uint8_t GetHopLimit (void) const;
/**
* \brief Set the "Source address" field.
* \param src the source address
*/
void SetSourceAddress (Ipv6Address src);
/**
* \brief Get the "Source address" field.
* \return the source address
*/
Ipv6Address GetSourceAddress (void) const;
/**
* \brief Set the "Destination address" field.
* \param dst the destination address
*/
void SetDestinationAddress (Ipv6Address dst);
/**
* \brief Get the "Destination address" field.
* \return the destination address
*/
Ipv6Address GetDestinationAddress (void) const;
/**
* \brief Get the name.
* \return the name
*/
std::string GetName (void) const;
/**
* \brief Print some informations about the packet.
* \param os output stream
* \return info about this packet
*/
virtual void Print (std::ostream& os) const;
/**
* \brief Get the serialized size of the packet.
* \return size
*/
virtual uint32_t GetSerializedSize (void) const;
/**
* \brief Serialize the packet.
* \param start Buffer iterator
*/
virtual void Serialize (Buffer::Iterator start) const;
/**
* \brief Deserialize the packet.
* \param start Buffer iterator
* \return size of the packet
*/
virtual uint32_t Deserialize (Buffer::Iterator start);
private:
/**
* \brief The version (always equal to 6).
*/
uint32_t m_version : 4;
/**
* \brief The traffic class.
*/
uint32_t m_trafficClass : 8;
/**
* \brief The flow label.
* \note This is 20-bit value.
*/
uint32_t m_flowLabel : 20;
/**
* \brief The payload length.
*/
uint16_t m_payloadLength;
/**
* \brief The Next header number.
*/
uint8_t m_nextHeader;
/**
* \brief The Hop limit value.
*/
uint8_t m_hopLimit;
/**
* \brief The source address.
*/
Ipv6Address m_sourceAddress;
/**
* \brief The destination address.
*/
Ipv6Address m_destinationAddress;
};
} /* namespace ns3 */
#endif /* IPV6_HEADER_H */

View File

@@ -170,6 +170,12 @@ Mac48Address::GetMulticastPrefix (void)
static Mac48Address multicast = Mac48Address ("01:00:5e:00:00:00");
return multicast;
}
Mac48Address
Mac48Address::GetMulticast6Prefix (void)
{
static Mac48Address multicast = Mac48Address ("33:33:00:00:00:00");
return multicast;
}
Mac48Address
Mac48Address::GetMulticast (Ipv4Address multicastGroup)
{
@@ -206,6 +212,26 @@ Mac48Address::GetMulticast (Ipv4Address multicastGroup)
result.CopyFrom (etherBuffer);
return result;
}
Mac48Address Mac48Address::GetMulticast(Ipv6Address addr)
{
Mac48Address etherAddr = Mac48Address::GetMulticast6Prefix();
uint8_t etherBuffer[6];
uint8_t ipBuffer[16];
/* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
/* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
etherAddr.CopyTo (etherBuffer);
addr.Serialize (ipBuffer);
etherBuffer[2] = ipBuffer[12];
etherBuffer[3] = ipBuffer[13];
etherBuffer[4] = ipBuffer[14];
etherBuffer[5] = ipBuffer[15];
etherAddr.CopyFrom (etherBuffer);
return etherAddr;
}
bool operator == (const Mac48Address &a, const Mac48Address &b)
{

View File

@@ -25,6 +25,7 @@
#include "ns3/attribute.h"
#include "ns3/attribute-helper.h"
#include "ipv4-address.h"
#include "ipv6-address.h"
namespace ns3 {
@@ -108,10 +109,22 @@ public:
*/
static Mac48Address GetMulticast (Ipv4Address address);
/**
* \brief Get multicast address from IPv6 address.
* \returns a multicast address
*/
static Mac48Address GetMulticast (Ipv6Address address);
/**
* \returns the multicast prefix (01:00:5e:00:00:00).
*/
static Mac48Address GetMulticastPrefix (void);
/**
* \brief Get the multicast prefix for IPv6 (33:33:00:00:00:00).
* \returns a multicast address.
*/
static Mac48Address GetMulticast6Prefix (void);
private:
/**
* \returns a new Address instance

View File

@@ -28,6 +28,7 @@
#include "ns3/ptr.h"
#include "address.h"
#include "ipv4-address.h"
#include "ipv6-address.h"
namespace ns3 {
@@ -173,6 +174,15 @@ public:
*/
virtual Address GetMulticast (Ipv4Address multicastGroup) const = 0;
/**
* \brief Get the MAC multicast address corresponding
* to the IPv6 address provided.
* \param addr IPv6 address
* \return the MAC multicast address
* \warning Calling this method is invalid if IsMulticast returns not true.
*/
virtual Address GetMulticast (Ipv6Address addr) const = 0;
/**
* \return value of m_isPointToPoint flag
*/

View File

@@ -152,6 +152,12 @@ SimpleNetDevice::GetMulticast (Ipv4Address multicastGroup) const
{
return Mac48Address::GetMulticast (multicastGroup);
}
Address SimpleNetDevice::GetMulticast (Ipv6Address addr) const
{
return Mac48Address::GetMulticast (addr);
}
bool
SimpleNetDevice::IsPointToPoint (void) const
{

View File

@@ -67,6 +67,9 @@ public:
virtual void SetNode (Ptr<Node> node);
virtual bool NeedsArp (void) const;
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
virtual Address GetMulticast (Ipv6Address addr) const;
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
virtual bool SupportsSendFrom (void) const;

View File

@@ -34,6 +34,10 @@ def build(bld):
'application.cc',
'simple-channel.cc',
'simple-net-device.cc',
'inet6-socket-address.cc',
'ipv6-address.cc',
'ipv6-header.cc',
'icmp-socket.cc',
'ipv4-raw-socket-factory.cc',
]
@@ -70,5 +74,9 @@ def build(bld):
'application.h',
'simple-channel.h',
'simple-net-device.h',
'inet6-socket-address.h',
'ipv6-address.h',
'ipv6-header.h',
'icmp-socket.h',
'ipv4-raw-socket-factory.h',
]