Initial IPv6 capability
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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
58
src/node/icmp-socket.cc
Normal 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
177
src/node/icmp-socket.h
Normal 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 */
|
||||
|
||||
112
src/node/inet6-socket-address.cc
Normal file
112
src/node/inet6-socket-address.cc
Normal 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 */
|
||||
|
||||
140
src/node/inet6-socket-address.h
Normal file
140
src/node/inet6-socket-address.h
Normal 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
686
src/node/ipv6-address.cc
Normal 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
427
src/node/ipv6-address.h
Normal 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
187
src/node/ipv6-header.cc
Normal 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
237
src/node/ipv6-header.h
Normal 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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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',
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user