--- a/AUTHORS Thu Nov 06 15:04:25 2008 -0800
+++ b/AUTHORS Fri Nov 07 11:36:15 2008 -0800
@@ -9,4 +9,8 @@
George F. Riley (riley@ece.gatech.edu)
Guillaume Vu-Brugier (gvubrugier@gmail.com)
Florian Westphal (fw@strlen.de)
+Sebastien Vincent (vincent@lsiit.u-strasbg.fr)
+David Gross (gdavid.devel@gmail.com)
+Mehdi Benamor (mehdi.benamor@telecom-bretagne.eu)
+Angelos Chatzipapas (chatzipa@ceid.upatras.gr)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/test-ipv6.cc Fri Nov 07 11:36:15 2008 -0800
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Louis Pasteur University / Telecom Bretagne
+ *
+ * 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: Angelos Chatzipapas <Angelos.CHATZIPAPAS@enst-bretagne.fr> /
+ * <chatzipa@ceid.upatras.gr>
+ */
+
+#include "ns3/log.h"
+//#include "ns3/ipv6.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/node.h"
+#include "ns3/mac48-address.h"
+
+NS_LOG_COMPONENT_DEFINE ("TestIpv6");
+
+using namespace ns3;
+
+int
+main (int argc, char *argv[])
+{
+ LogComponentEnable ("TestIpv6", LOG_LEVEL_ALL);
+
+ NS_LOG_INFO ("Test Ipv6");
+
+ Mac48Address m_addresses[10];
+
+ m_addresses[0]=("00:00:00:00:00:01");
+ m_addresses[1]=("00:00:00:00:00:02");
+ m_addresses[2]=("00:00:00:00:00:03");
+ m_addresses[3]=("00:00:00:00:00:04");
+ m_addresses[4]=("00:00:00:00:00:05");
+ m_addresses[5]=("00:00:00:00:00:06");
+ m_addresses[6]=("00:00:00:00:00:07");
+ m_addresses[7]=("00:00:00:00:00:08");
+ m_addresses[8]=("00:00:00:00:00:09");
+ m_addresses[9]=("00:00:00:00:00:10");
+
+ Ipv6Address prefix1 ("2001:1::");
+ NS_LOG_INFO ("prefix = " << prefix1);
+ for (uint32_t i = 0; i < 10 ; ++i)
+ {
+ NS_LOG_INFO ("address = " <<m_addresses[i]);
+ Ipv6Address ipv6address=Ipv6Address::MakeAutoconfiguredAddress(m_addresses[i], prefix1);
+ NS_LOG_INFO ("address = " <<ipv6address);
+ }
+
+ Ipv6Address prefix2 ("2002:1:1::");
+
+ NS_LOG_INFO ("prefix = " << prefix2);
+ for (uint32_t i = 0; i < 10 ; ++i)
+ {
+ Ipv6Address ipv6address=Ipv6Address::MakeAutoconfiguredAddress(m_addresses[i], prefix2);
+ NS_LOG_INFO ("address = " <<ipv6address);
+ }
+}
+
--- a/examples/wscript Thu Nov 06 15:04:25 2008 -0800
+++ b/examples/wscript Fri Nov 07 11:36:15 2008 -0800
@@ -106,3 +106,7 @@
obj = bld.create_ns3_program('csma-ping',
['csma', 'internet-stack', 'v4ping'])
obj.source = 'csma-ping.cc'
+
+ obj = bld.create_ns3_program('test-ipv6',
+ ['point-to-point', 'internet-stack'])
+ obj.source = 'test-ipv6.cc'
--- a/src/devices/bridge/bridge-net-device.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/bridge/bridge-net-device.cc Fri Nov 07 11:36:15 2008 -0800
@@ -380,6 +380,10 @@
NetDevice::DoDispose ();
}
-
+Address BridgeNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ NS_LOG_FUNCTION (this << addr);
+ return Mac48Address::GetMulticast (addr);
+}
} // namespace ns3
--- a/src/devices/bridge/bridge-net-device.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/bridge/bridge-net-device.h Fri Nov 07 11:36:15 2008 -0800
@@ -106,6 +106,7 @@
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
virtual bool SupportsSendFrom () const;
+ virtual Address GetMulticast (Ipv6Address addr) const;
protected:
virtual void DoDispose (void);
--- a/src/devices/csma/csma-net-device.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/csma/csma-net-device.cc Fri Nov 07 11:36:15 2008 -0800
@@ -600,6 +600,20 @@
NS_LOG_FUNCTION (packet << senderDevice);
NS_LOG_LOGIC ("UID is " << packet->GetUid ());
+ /* IPv6 support*/
+ uint8_t mac[6];
+ Mac48Address multicast6AllNodes("33:33:00:00:00:01");
+ Mac48Address multicast6AllRouters("33:33:00:00:00:02");
+ Mac48Address multicast6AllHosts("33:33:00:00:00:03");
+ Mac48Address multicast6Node; /* multicast address addressed to our MAC address */
+
+ /* generate IPv6 multicast ethernet destination that nodes will accept */
+ GetAddress().CopyTo(mac);
+ mac[0]=0x33;
+ mac[1]=0x33;
+ /* mac[2]=0xff; */
+ multicast6Node.CopyFrom(mac);
+
//
// We never forward up packets that we sent. Real devices don't do this since
// their receivers are disabled during send, so we don't. Drop the packet
@@ -672,7 +686,11 @@
packetType = PACKET_BROADCAST;
m_rxTrace (originalPacket);
}
- else if (header.GetDestination ().IsMulticast ())
+ else if (header.GetDestination ().IsMulticast () ||
+ header.GetDestination() == multicast6Node ||
+ header.GetDestination() == multicast6AllNodes ||
+ header.GetDestination() == multicast6AllRouters ||
+ header.GetDestination() == multicast6AllHosts)
{
packetType = PACKET_MULTICAST;
m_rxTrace (originalPacket);
@@ -922,6 +940,14 @@
m_rxCallback = cb;
}
+Address CsmaNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ Mac48Address ad = Mac48Address::GetMulticast (addr);
+
+ NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
+ return ad;
+}
+
void
CsmaNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
{
--- a/src/devices/csma/csma-net-device.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/csma/csma-net-device.h Fri Nov 07 11:36:15 2008 -0800
@@ -392,6 +392,15 @@
*/
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+ /**
+ * \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;
+
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
virtual bool SupportsSendFrom (void) const;
--- a/src/devices/emu/emu-net-device.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/emu/emu-net-device.cc Fri Nov 07 11:36:15 2008 -0800
@@ -865,6 +865,17 @@
return ad;
}
+Address
+EmuNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ NS_LOG_FUNCTION(this << addr);
+
+ Mac48Address ad = Mac48Address::GetMulticast (addr);
+ NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
+
+ return ad;
+}
+
bool
EmuNetDevice::IsPointToPoint (void) const
{
--- a/src/devices/emu/emu-net-device.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/emu/emu-net-device.h Fri Nov 07 11:36:15 2008 -0800
@@ -151,6 +151,15 @@
virtual Address GetMulticast (Ipv4Address multicastGroup) const;
/**
+ * \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;
+
+ /**
* Is this a point to point link?
* \returns false.
*/
--- a/src/devices/point-to-point/point-to-point-net-device.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/point-to-point/point-to-point-net-device.cc Fri Nov 07 11:36:15 2008 -0800
@@ -378,6 +378,13 @@
return Mac48Address ("01:00:5e:00:00:00");
}
+Address
+PointToPointNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ NS_LOG_FUNCTION(this << addr);
+ return Mac48Address ("33:33:00:00:00:00");
+}
+
bool
PointToPointNetDevice::IsPointToPoint (void) const
{
--- a/src/devices/point-to-point/point-to-point-net-device.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/point-to-point/point-to-point-net-device.h Fri Nov 07 11:36:15 2008 -0800
@@ -263,6 +263,8 @@
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+ virtual Address GetMulticast (Ipv6Address addr) const;
+
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
virtual bool SupportsSendFrom (void) const;
--- a/src/devices/wifi/wifi-net-device.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/wifi/wifi-net-device.cc Fri Nov 07 11:36:15 2008 -0800
@@ -257,6 +257,10 @@
{
return Mac48Address::GetMulticast (multicastGroup);
}
+Address WifiNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ return Mac48Address::GetMulticast (addr);
+}
bool
WifiNetDevice::IsPointToPoint (void) const
{
--- a/src/devices/wifi/wifi-net-device.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/devices/wifi/wifi-net-device.h Fri Nov 07 11:36:15 2008 -0800
@@ -100,6 +100,8 @@
virtual bool NeedsArp (void) const;
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+ virtual Address GetMulticast (Ipv6Address addr) const;
+
virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
virtual bool SupportsSendFrom (void) const;
--- a/src/node/address-utils.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/address-utils.cc Fri Nov 07 11:36:15 2008 -0800
@@ -25,6 +25,12 @@
{
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 @@
{
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];
--- a/src/node/address-utils.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/address-utils.h Fri Nov 07 11:36:15 2008 -0800
@@ -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);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/icmp-socket.cc Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/icmp-socket.h Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/inet6-socket-address.cc Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/inet6-socket-address.h Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-address.cc Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-address.h Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-header.cc Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-header.h Fri Nov 07 11:36:15 2008 -0800
@@ -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 */
+
--- a/src/node/mac48-address.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/mac48-address.cc Fri Nov 07 11:36:15 2008 -0800
@@ -170,6 +170,12 @@
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 @@
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)
{
--- a/src/node/mac48-address.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/mac48-address.h Fri Nov 07 11:36:15 2008 -0800
@@ -25,6 +25,7 @@
#include "ns3/attribute.h"
#include "ns3/attribute-helper.h"
#include "ipv4-address.h"
+#include "ipv6-address.h"
namespace ns3 {
@@ -109,9 +110,21 @@
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
--- a/src/node/net-device.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/net-device.h Fri Nov 07 11:36:15 2008 -0800
@@ -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 @@
*/
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
*/
--- a/src/node/simple-net-device.cc Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/simple-net-device.cc Fri Nov 07 11:36:15 2008 -0800
@@ -152,6 +152,12 @@
{
return Mac48Address::GetMulticast (multicastGroup);
}
+
+Address SimpleNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ return Mac48Address::GetMulticast (addr);
+}
+
bool
SimpleNetDevice::IsPointToPoint (void) const
{
--- a/src/node/simple-net-device.h Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/simple-net-device.h Fri Nov 07 11:36:15 2008 -0800
@@ -67,6 +67,9 @@
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;
--- a/src/node/wscript Thu Nov 06 15:04:25 2008 -0800
+++ b/src/node/wscript Fri Nov 07 11:36:15 2008 -0800
@@ -34,6 +34,10 @@
'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 @@
'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',
]