--- a/CHANGES.html Sun Feb 19 16:22:51 2012 +0100
+++ b/CHANGES.html Mon Feb 20 14:05:07 2012 +0100
@@ -51,6 +51,74 @@
<li> The Ipv6RawSocketImpl "IcmpFilter" attribute has been removed. Six
new member functions have been added to enable the same functionality.
</li>
+<li> IPv6 support for TCP and UDP has been implemented. Socket functions
+that take an address [e.g. Send (), Connect (), Bind ()] can accept an
+ns3::Ipv6Address or a ns3::Address in addition to taking an ns3::Ipv4Address.
+(Note that the ns3::Address must contain a ns3::Ipv6Address or a ns3::Ipv4Address,
+otherwise these functions will return an error).
+Internally, the socket now stores the remote address as a type "ns3::Address"
+instead of a type "ns3::Ipv4Address". The IPv6 Routing Header extension is not
+currently supported in ns3 and will not be reflected in the TCP and UDP checksum
+calculations per RFC 2460. Also note that UDP checksums for IPv6 packets are
+required per RFC, but remain optional and disabled by default in ns3 (in the
+interest of performance).
+</li>
+<li>
+When calling Bind () on a socket without an address, the behavior remains the
+same: it will bind to the IPv4 "any" address (0.0.0.0). In order to Bind () to
+the IPv6 "any" address in a similar fashion, use "Bind6 ()".
+</li>
+<li>
+The prototype for the RxCallback function in the Ipv6EndPoint was changed.
+It now includes the destination IPv6 address of the end point which was
+needed for TCP. This lead to a small change in the UDP and ICMPv6 L4
+protocols as well.
+</li>
+</ul>
+
+<h2>Changes to build system:</h2>
+<ul>
+<li> The following files are removed:
+<pre>
+ src/internet/model/ipv4-l4-protocol.cc
+ src/internet/model/ipv4-l4-protocol.h
+ src/internet/model/ipv6-l4-protocol.cc
+ src/internet/model/ipv6-l4-protocol.h
+</pre>
+and replaced with:
+<pre>
+ src/internet/model/ip-l4-protocol.cc
+ src/internet/model/ip-l4-protocol.h
+</pre>
+</li>
+</ul>
+<h2>Changed behavior:</h2>
+<ul>
+<li> Dual-stacked IPv6 sockets are implemented. An IPv6 socket can accept
+an IPv4 connection, returning the senders address as an IPv4-mapped address
+(IPV6_V6ONLY socket option is not implemented).
+</li>
+<li>
+The following examples/application/helpers were modified to support IPv6:
+<pre>
+csma-layout/examples/csma-star [*]
+netanim/examples/star-animation [*]
+point-to-point-layout/model/point-to-point-star.cc
+point-to-point-layout/model/point-to-point-grid.cc
+point-to-point-layout/model/point-to-point-dumbbell.cc
+examples/udp/udp-echo [*]
+examples/udp-client-server/udp-client-server [*]
+examples/udp-client-server/udp-trace-client-server [*]
+applications/helper/udp-echo-helper
+applications/model/udp-client
+applications/model/udp-echo-client
+applications/model/udp-echo-server
+applications/model/udp-server
+applications/model/udp-trace-client
+
+[*] Added '--useIpv6' flag to switch between IPv4 and IPv6
+</pre>
+</li>
</ul>
<hr>
--- a/RELEASE_NOTES Sun Feb 19 16:22:51 2012 +0100
+++ b/RELEASE_NOTES Mon Feb 20 14:05:07 2012 +0100
@@ -21,6 +21,9 @@
New user-visible features
-------------------------
+- Dual-stacked IPv6 sockets are implemented. An IPv6 socket can accept an IPv4
+ connection, returning the senders address as an IPv4-mapped address
+ (IPV6_V6ONLY socket option is not implemented).
Bugs fixed
----------
--- a/examples/udp-client-server/udp-client-server.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/examples/udp-client-server/udp-client-server.cc Mon Feb 20 14:05:07 2012 +0100
@@ -43,6 +43,13 @@
LogComponentEnable ("UdpClient", LOG_LEVEL_INFO);
LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
+ bool useV6 = false;
+ Address serverAddress;
+
+ CommandLine cmd;
+ cmd.AddValue ("useIpv6", "Use Ipv6", useV6);
+ cmd.Parse (argc, argv);
+
//
// Explicitly create the nodes required by the topology (shown above).
//
@@ -63,13 +70,24 @@
csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
NetDeviceContainer d = csma.Install (n);
- Ipv4AddressHelper ipv4;
//
// We've got the "hardware" in place. Now we need to add IP addresses.
//
NS_LOG_INFO ("Assign IP Addresses.");
- ipv4.SetBase ("10.1.1.0", "255.255.255.0");
- Ipv4InterfaceContainer i = ipv4.Assign (d);
+ if (useV6 == false)
+ {
+ Ipv4AddressHelper ipv4;
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (d);
+ serverAddress = Address (i.GetAddress (1));
+ }
+ else
+ {
+ Ipv6AddressHelper ipv6;
+ ipv6.NewNetwork ("2001:0000:f00d:cafe::", 64);
+ Ipv6InterfaceContainer i6 = ipv6.Assign (d);
+ serverAddress = Address(i6.GetAddress (1,1));
+ }
NS_LOG_INFO ("Create Applications.");
//
@@ -88,7 +106,7 @@
uint32_t MaxPacketSize = 1024;
Time interPacketInterval = Seconds (0.05);
uint32_t maxPacketCount = 320;
- UdpClientHelper client (i.GetAddress (1), port);
+ UdpClientHelper client (serverAddress, port);
client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
client.SetAttribute ("Interval", TimeValue (interPacketInterval));
client.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
--- a/examples/udp-client-server/udp-trace-client-server.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/examples/udp-client-server/udp-trace-client-server.cc Mon Feb 20 14:05:07 2012 +0100
@@ -42,6 +42,13 @@
LogComponentEnable ("UdpTraceClient", LOG_LEVEL_INFO);
LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
+ bool useV6 = false;
+ Address serverAddress;
+
+ CommandLine cmd;
+ cmd.AddValue ("useIpv6", "Use Ipv6", useV6);
+ cmd.Parse (argc, argv);
+
//
// Explicitly create the nodes required by the topology (shown above).
//
@@ -62,13 +69,24 @@
csma.SetDeviceAttribute ("Mtu", UintegerValue (1500));
NetDeviceContainer d = csma.Install (n);
- Ipv4AddressHelper ipv4;
//
// We've got the "hardware" in place. Now we need to add IP addresses.
//
NS_LOG_INFO ("Assign IP Addresses.");
- ipv4.SetBase ("10.1.1.0", "255.255.255.0");
- Ipv4InterfaceContainer i = ipv4.Assign (d);
+ if (useV6 == false)
+ {
+ Ipv4AddressHelper ipv4;
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (d);
+ serverAddress = Address (i.GetAddress (1));
+ }
+ else
+ {
+ Ipv6AddressHelper ipv6;
+ ipv6.NewNetwork ("2001:0000:f00d:cafe::", 64);
+ Ipv6InterfaceContainer i6 = ipv6.Assign (d);
+ serverAddress = Address(i6.GetAddress (1,1));
+ }
NS_LOG_INFO ("Create Applications.");
//
@@ -85,7 +103,7 @@
// node one.
//
uint32_t MaxPacketSize = 1472; // Back off 20 (IP) + 8 (UDP) bytes from MTU
- UdpTraceClientHelper client (i.GetAddress (1), port,"");
+ UdpTraceClientHelper client (serverAddress, port,"");
client.SetAttribute ("MaxPacketSize", UintegerValue (MaxPacketSize));
apps = client.Install (n.Get (0));
apps.Start (Seconds (2.0));
--- a/examples/udp/udp-echo.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/examples/udp/udp-echo.cc Mon Feb 20 14:05:07 2012 +0100
@@ -51,7 +51,11 @@
// Allow the user to override any of the defaults and the above Bind() at
// run-time, via command-line arguments
//
+ bool useV6 = false;
+ Address serverAddress;
+
CommandLine cmd;
+ cmd.AddValue ("useIpv6", "Use Ipv6", useV6);
cmd.Parse (argc, argv);
//
// Explicitly create the nodes required by the topology (shown above).
@@ -73,13 +77,24 @@
csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
NetDeviceContainer d = csma.Install (n);
- Ipv4AddressHelper ipv4;
//
// We've got the "hardware" in place. Now we need to add IP addresses.
//
NS_LOG_INFO ("Assign IP Addresses.");
- ipv4.SetBase ("10.1.1.0", "255.255.255.0");
- Ipv4InterfaceContainer i = ipv4.Assign (d);
+ if (useV6 == false)
+ {
+ Ipv4AddressHelper ipv4;
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (d);
+ serverAddress = Address(i.GetAddress (1));
+ }
+ else
+ {
+ Ipv6AddressHelper ipv6;
+ ipv6.NewNetwork ("2001:0000:f00d:cafe::", 64);
+ Ipv6InterfaceContainer i6 = ipv6.Assign (d);
+ serverAddress = Address(i6.GetAddress (1,1));
+ }
NS_LOG_INFO ("Create Applications.");
//
@@ -98,7 +113,7 @@
uint32_t packetSize = 1024;
uint32_t maxPacketCount = 1;
Time interPacketInterval = Seconds (1.);
- UdpEchoClientHelper client (i.GetAddress (1), port);
+ UdpEchoClientHelper client (serverAddress, port);
client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
client.SetAttribute ("Interval", TimeValue (interPacketInterval));
client.SetAttribute ("PacketSize", UintegerValue (packetSize));
--- a/src/applications/helper/udp-client-server-helper.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/helper/udp-client-server-helper.cc Mon Feb 20 14:05:07 2012 +0100
@@ -68,10 +68,24 @@
{
}
+UdpClientHelper::UdpClientHelper (Address address, uint16_t port)
+{
+ m_factory.SetTypeId (UdpClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", AddressValue (address));
+ SetAttribute ("RemotePort", UintegerValue (port));
+}
+
UdpClientHelper::UdpClientHelper (Ipv4Address address, uint16_t port)
{
m_factory.SetTypeId (UdpClient::GetTypeId ());
- SetAttribute ("RemoteAddress", Ipv4AddressValue (address));
+ SetAttribute ("RemoteAddress", AddressValue (Address(address)));
+ SetAttribute ("RemotePort", UintegerValue (port));
+}
+
+UdpClientHelper::UdpClientHelper (Ipv6Address address, uint16_t port)
+{
+ m_factory.SetTypeId (UdpClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", AddressValue (Address(address)));
SetAttribute ("RemotePort", UintegerValue (port));
}
@@ -99,10 +113,26 @@
{
}
+UdpTraceClientHelper::UdpTraceClientHelper (Address address, uint16_t port, std::string filename)
+{
+ m_factory.SetTypeId (UdpTraceClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", AddressValue (address));
+ SetAttribute ("RemotePort", UintegerValue (port));
+ SetAttribute ("TraceFilename", StringValue (filename));
+}
+
UdpTraceClientHelper::UdpTraceClientHelper (Ipv4Address address, uint16_t port, std::string filename)
{
m_factory.SetTypeId (UdpTraceClient::GetTypeId ());
- SetAttribute ("RemoteAddress", Ipv4AddressValue (address));
+ SetAttribute ("RemoteAddress", AddressValue (Address (address)));
+ SetAttribute ("RemotePort", UintegerValue (port));
+ SetAttribute ("TraceFilename", StringValue (filename));
+}
+
+UdpTraceClientHelper::UdpTraceClientHelper (Ipv6Address address, uint16_t port, std::string filename)
+{
+ m_factory.SetTypeId (UdpTraceClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", AddressValue (Address (address)));
SetAttribute ("RemotePort", UintegerValue (port));
SetAttribute ("TraceFilename", StringValue (filename));
}
--- a/src/applications/helper/udp-client-server-helper.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/helper/udp-client-server-helper.h Mon Feb 20 14:05:07 2012 +0100
@@ -100,6 +100,8 @@
*/
UdpClientHelper (Ipv4Address ip, uint16_t port);
+ UdpClientHelper (Ipv6Address ip, uint16_t port);
+ UdpClientHelper (Address ip, uint16_t port);
/**
* Record an attribute to be set in each Application after it is is created.
@@ -150,7 +152,9 @@
* \param port The port number of the remote udp server
* \param filename the file from which packet traces will be loaded
*/
+ UdpTraceClientHelper (Address ip, uint16_t port, std::string filename);
UdpTraceClientHelper (Ipv4Address ip, uint16_t port, std::string filename);
+ UdpTraceClientHelper (Ipv6Address ip, uint16_t port, std::string filename);
/**
* Record an attribute to be set in each Application after it is is created.
--- a/src/applications/helper/udp-echo-helper.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/helper/udp-echo-helper.cc Mon Feb 20 14:05:07 2012 +0100
@@ -73,10 +73,24 @@
return app;
}
+UdpEchoClientHelper::UdpEchoClientHelper (Address address, uint16_t port)
+{
+ m_factory.SetTypeId (UdpEchoClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", AddressValue (address));
+ SetAttribute ("RemotePort", UintegerValue (port));
+}
+
UdpEchoClientHelper::UdpEchoClientHelper (Ipv4Address address, uint16_t port)
{
m_factory.SetTypeId (UdpEchoClient::GetTypeId ());
- SetAttribute ("RemoteAddress", Ipv4AddressValue (address));
+ SetAttribute ("RemoteAddress", AddressValue (Address(address)));
+ SetAttribute ("RemotePort", UintegerValue (port));
+}
+
+UdpEchoClientHelper::UdpEchoClientHelper (Ipv6Address address, uint16_t port)
+{
+ m_factory.SetTypeId (UdpEchoClient::GetTypeId ());
+ SetAttribute ("RemoteAddress", AddressValue (Address(address)));
SetAttribute ("RemotePort", UintegerValue (port));
}
--- a/src/applications/helper/udp-echo-helper.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/helper/udp-echo-helper.h Mon Feb 20 14:05:07 2012 +0100
@@ -25,6 +25,7 @@
#include "ns3/node-container.h"
#include "ns3/object-factory.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
namespace ns3 {
@@ -106,7 +107,9 @@
* \param ip The IP address of the remote udp echo server
* \param port The port number of the remote udp echo server
*/
+ UdpEchoClientHelper (Address ip, uint16_t port);
UdpEchoClientHelper (Ipv4Address ip, uint16_t port);
+ UdpEchoClientHelper (Ipv6Address ip, uint16_t port);
/**
* Record an attribute to be set in each Application after it is is created.
--- a/src/applications/model/packet-sink.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/packet-sink.cc Mon Feb 20 14:05:07 2012 +0100
@@ -21,6 +21,7 @@
#include "ns3/address-utils.h"
#include "ns3/log.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/node.h"
#include "ns3/socket.h"
#include "ns3/udp-socket.h"
@@ -178,6 +179,17 @@
m_totalRx += packet->GetSize ();
NS_LOG_INFO (PrintStats (from, packet->GetSize (), m_totalRx));
}
+ else if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ m_totalRx += packet->GetSize ();
+ Inet6SocketAddress address = Inet6SocketAddress::ConvertFrom (from);
+ NS_LOG_INFO ("Received " << packet->GetSize () << " bytes from " <<
+ address.GetIpv6 () << " [" << address << "]"
+ << " total Rx " << m_totalRx);
+ //cast address to void , to suppress 'address' set but not used
+ //compiler warning in optimized builds
+ (void) address;
+ }
m_rxTrace (packet, from);
}
}
--- a/src/applications/model/udp-client.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-client.cc Mon Feb 20 14:05:07 2012 +0100
@@ -22,6 +22,7 @@
#include "ns3/ipv4-address.h"
#include "ns3/nstime.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/socket.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
@@ -54,10 +55,10 @@
MakeTimeChecker ())
.AddAttribute (
"RemoteAddress",
- "The destination Ipv4Address of the outbound packets",
- Ipv4AddressValue (),
- MakeIpv4AddressAccessor (&UdpClient::m_peerAddress),
- MakeIpv4AddressChecker ())
+ "The destination Address of the outbound packets",
+ AddressValue (),
+ MakeAddressAccessor (&UdpClient::m_peerAddress),
+ MakeAddressChecker ())
.AddAttribute ("RemotePort", "The destination port of the outbound packets",
UintegerValue (100),
MakeUintegerAccessor (&UdpClient::m_peerPort),
@@ -87,6 +88,20 @@
void
UdpClient::SetRemote (Ipv4Address ip, uint16_t port)
{
+ m_peerAddress = Address(ip);
+ m_peerPort = port;
+}
+
+void
+UdpClient::SetRemote (Ipv6Address ip, uint16_t port)
+{
+ m_peerAddress = Address(ip);
+ m_peerPort = port;
+}
+
+void
+UdpClient::SetRemote (Address ip, uint16_t port)
+{
m_peerAddress = ip;
m_peerPort = port;
}
@@ -107,8 +122,16 @@
{
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
m_socket = Socket::CreateSocket (GetNode (), tid);
- m_socket->Bind ();
- m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
+ if (Ipv4Address::IsMatchingType(m_peerAddress) == true)
+ {
+ m_socket->Bind ();
+ m_socket->Connect (InetSocketAddress (Ipv4Address::ConvertFrom(m_peerAddress), m_peerPort));
+ }
+ else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
+ {
+ m_socket->Bind6 ();
+ m_socket->Connect (Inet6SocketAddress (Ipv6Address::ConvertFrom(m_peerAddress), m_peerPort));
+ }
}
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
@@ -132,18 +155,29 @@
Ptr<Packet> p = Create<Packet> (m_size-(8+4)); // 8+4 : the size of the seqTs header
p->AddHeader (seqTs);
+ std::stringstream peerAddressStringStream;
+ if (Ipv4Address::IsMatchingType (m_peerAddress))
+ {
+ peerAddressStringStream << Ipv4Address::ConvertFrom (m_peerAddress);
+ }
+ else if (Ipv6Address::IsMatchingType (m_peerAddress))
+ {
+ peerAddressStringStream << Ipv6Address::ConvertFrom (m_peerAddress);
+ }
+
if ((m_socket->Send (p)) >= 0)
{
++m_sent;
NS_LOG_INFO ("TraceDelay TX " << m_size << " bytes to "
- << m_peerAddress << " Uid: " << p->GetUid ()
- << " Time: " << (Simulator::Now ()).GetSeconds ());
+ << peerAddressStringStream.str () << " Uid: "
+ << p->GetUid () << " Time: "
+ << (Simulator::Now ()).GetSeconds ());
}
else
{
NS_LOG_INFO ("Error while sending " << m_size << " bytes to "
- << m_peerAddress);
+ << peerAddressStringStream.str ());
}
if (m_sent < m_count)
--- a/src/applications/model/udp-client.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-client.h Mon Feb 20 14:05:07 2012 +0100
@@ -56,6 +56,8 @@
* \param port remote port
*/
void SetRemote (Ipv4Address ip, uint16_t port);
+ void SetRemote (Ipv6Address ip, uint16_t port);
+ void SetRemote (Address ip, uint16_t port);
protected:
virtual void DoDispose (void);
@@ -74,7 +76,7 @@
uint32_t m_sent;
Ptr<Socket> m_socket;
- Ipv4Address m_peerAddress;
+ Address m_peerAddress;
uint16_t m_peerPort;
EventId m_sendEvent;
--- a/src/applications/model/udp-echo-client.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-echo-client.cc Mon Feb 20 14:05:07 2012 +0100
@@ -17,8 +17,10 @@
*/
#include "ns3/log.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
#include "ns3/nstime.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/socket.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
@@ -49,10 +51,10 @@
MakeTimeAccessor (&UdpEchoClient::m_interval),
MakeTimeChecker ())
.AddAttribute ("RemoteAddress",
- "The destination Ipv4Address of the outbound packets",
- Ipv4AddressValue (),
- MakeIpv4AddressAccessor (&UdpEchoClient::m_peerAddress),
- MakeIpv4AddressChecker ())
+ "The destination Address of the outbound packets",
+ AddressValue (),
+ MakeAddressAccessor (&UdpEchoClient::m_peerAddress),
+ MakeAddressChecker ())
.AddAttribute ("RemotePort",
"The destination port of the outbound packets",
UintegerValue (0),
@@ -90,9 +92,23 @@
}
void
+UdpEchoClient::SetRemote (Address ip, uint16_t port)
+{
+ m_peerAddress = ip;
+ m_peerPort = port;
+}
+
+void
UdpEchoClient::SetRemote (Ipv4Address ip, uint16_t port)
{
- m_peerAddress = ip;
+ m_peerAddress = Address (ip);
+ m_peerPort = port;
+}
+
+void
+UdpEchoClient::SetRemote (Ipv6Address ip, uint16_t port)
+{
+ m_peerAddress = Address (ip);
m_peerPort = port;
}
@@ -112,8 +128,16 @@
{
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
m_socket = Socket::CreateSocket (GetNode (), tid);
- m_socket->Bind ();
- m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
+ if (Ipv4Address::IsMatchingType(m_peerAddress) == true)
+ {
+ m_socket->Bind();
+ m_socket->Connect (InetSocketAddress (Ipv4Address::ConvertFrom(m_peerAddress), m_peerPort));
+ }
+ else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
+ {
+ m_socket->Bind6();
+ m_socket->Connect (Inet6SocketAddress (Ipv6Address::ConvertFrom(m_peerAddress), m_peerPort));
+ }
}
m_socket->SetRecvCallback (MakeCallback (&UdpEchoClient::HandleRead, this));
@@ -281,7 +305,16 @@
++m_sent;
- NS_LOG_INFO ("Sent " << m_size << " bytes to " << m_peerAddress);
+ if (InetSocketAddress::IsMatchingType (m_peerAddress))
+ {
+ NS_LOG_INFO ("Sent " << m_size << " bytes to " <<
+ InetSocketAddress::ConvertFrom (m_peerAddress));
+ }
+ else if (Inet6SocketAddress::IsMatchingType (m_peerAddress))
+ {
+ NS_LOG_INFO ("Sent " << m_size << " bytes to " <<
+ Inet6SocketAddress::ConvertFrom (m_peerAddress));
+ }
if (m_sent < m_count)
{
@@ -302,6 +335,11 @@
NS_LOG_INFO ("Received " << packet->GetSize () << " bytes from " <<
InetSocketAddress::ConvertFrom (from).GetIpv4 ());
}
+ else if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ NS_LOG_INFO ("Received " << packet->GetSize () << " bytes from " <<
+ Inet6SocketAddress::ConvertFrom (from).GetIpv6 ());
+ }
}
}
--- a/src/applications/model/udp-echo-client.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-echo-client.h Mon Feb 20 14:05:07 2012 +0100
@@ -49,7 +49,9 @@
* \param ip destination ipv4 address
* \param port destination port
*/
+ void SetRemote (Address ip, uint16_t port);
void SetRemote (Ipv4Address ip, uint16_t port);
+ void SetRemote (Ipv6Address ip, uint16_t port);
/**
* Set the data size of the packet (the number of bytes that are sent as data
@@ -142,7 +144,7 @@
uint32_t m_sent;
Ptr<Socket> m_socket;
- Ipv4Address m_peerAddress;
+ Address m_peerAddress;
uint16_t m_peerPort;
EventId m_sendEvent;
/// Callbacks for tracing the packet Tx events
--- a/src/applications/model/udp-echo-server.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-echo-server.cc Mon Feb 20 14:05:07 2012 +0100
@@ -18,9 +18,11 @@
#include "ns3/log.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
#include "ns3/address-utils.h"
#include "ns3/nstime.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/socket.h"
#include "ns3/udp-socket.h"
#include "ns3/simulator.h"
@@ -58,6 +60,7 @@
{
NS_LOG_FUNCTION_NOARGS ();
m_socket = 0;
+ m_socket6 = 0;
}
void
@@ -88,12 +91,34 @@
}
else
{
- NS_FATAL_ERROR ("Error: joining multicast on a non-UDP socket");
+ NS_FATAL_ERROR ("Error: Failed to join multicast group");
+ }
+ }
+ }
+
+ if (m_socket6 == 0)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ m_socket6 = Socket::CreateSocket (GetNode (), tid);
+ Inet6SocketAddress local6 = Inet6SocketAddress (Ipv6Address::GetAny (), m_port);
+ m_socket6->Bind (local6);
+ if (addressUtils::IsMulticast (local6))
+ {
+ Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket> (m_socket6);
+ if (udpSocket)
+ {
+ // equivalent to setsockopt (MCAST_JOIN_GROUP)
+ udpSocket->MulticastJoinGroup (0, local6);
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Error: Failed to join multicast group");
}
}
}
m_socket->SetRecvCallback (MakeCallback (&UdpEchoServer::HandleRead, this));
+ m_socket6->SetRecvCallback (MakeCallback (&UdpEchoServer::HandleRead, this));
}
void
@@ -106,6 +131,11 @@
m_socket->Close ();
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
}
+ if (m_socket6 != 0)
+ {
+ m_socket6->Close ();
+ m_socket6->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+ }
}
void
@@ -126,6 +156,17 @@
NS_LOG_LOGIC ("Echoing packet");
socket->SendTo (packet, 0, from);
}
+ else if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ NS_LOG_INFO ("Received " << packet->GetSize () << " bytes from " <<
+ Inet6SocketAddress::ConvertFrom (from).GetIpv6 ());
+
+ packet->RemoveAllPacketTags ();
+ packet->RemoveAllByteTags ();
+
+ NS_LOG_LOGIC ("Echoing packet");
+ socket->SendTo (packet, 0, from);
+ }
}
}
--- a/src/applications/model/udp-echo-server.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-echo-server.h Mon Feb 20 14:05:07 2012 +0100
@@ -59,6 +59,7 @@
uint16_t m_port;
Ptr<Socket> m_socket;
+ Ptr<Socket> m_socket6;
Address m_local;
};
--- a/src/applications/model/udp-server.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-server.cc Mon Feb 20 14:05:07 2012 +0100
@@ -23,6 +23,7 @@
#include "ns3/ipv4-address.h"
#include "ns3/nstime.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/socket.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
@@ -121,6 +122,17 @@
m_socket->SetRecvCallback (MakeCallback (&UdpServer::HandleRead, this));
+ if (m_socket6 == 0)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ m_socket6 = Socket::CreateSocket (GetNode (), tid);
+ Inet6SocketAddress local = Inet6SocketAddress (Ipv6Address::GetAny (),
+ m_port);
+ m_socket6->Bind (local);
+ }
+
+ m_socket6->SetRecvCallback (MakeCallback (&UdpServer::HandleRead, this));
+
}
void
@@ -147,13 +159,26 @@
SeqTsHeader seqTs;
packet->RemoveHeader (seqTs);
uint32_t currentSequenceNumber = seqTs.GetSeq ();
- NS_LOG_INFO ("TraceDelay: RX " << packet->GetSize () <<
- " bytes from "<< InetSocketAddress::ConvertFrom (from).GetIpv4 () <<
- " Sequence Number: " << currentSequenceNumber <<
- " Uid: " << packet->GetUid () <<
- " TXtime: " << seqTs.GetTs () <<
- " RXtime: " << Simulator::Now () <<
- " Delay: " << Simulator::Now () - seqTs.GetTs ());
+ if (InetSocketAddress::IsMatchingType (from))
+ {
+ NS_LOG_INFO ("TraceDelay: RX " << packet->GetSize () <<
+ " bytes from "<< InetSocketAddress::ConvertFrom (from).GetIpv4 () <<
+ " Sequence Number: " << currentSequenceNumber <<
+ " Uid: " << packet->GetUid () <<
+ " TXtime: " << seqTs.GetTs () <<
+ " RXtime: " << Simulator::Now () <<
+ " Delay: " << Simulator::Now () - seqTs.GetTs ());
+ }
+ else if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ NS_LOG_INFO ("TraceDelay: RX " << packet->GetSize () <<
+ " bytes from "<< Inet6SocketAddress::ConvertFrom (from).GetIpv6 () <<
+ " Sequence Number: " << currentSequenceNumber <<
+ " Uid: " << packet->GetUid () <<
+ " TXtime: " << seqTs.GetTs () <<
+ " RXtime: " << Simulator::Now () <<
+ " Delay: " << Simulator::Now () - seqTs.GetTs ());
+ }
m_lossCounter.NotifyReceived (currentSequenceNumber);
m_received++;
--- a/src/applications/model/udp-server.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-server.h Mon Feb 20 14:05:07 2012 +0100
@@ -84,6 +84,7 @@
uint16_t m_port;
Ptr<Socket> m_socket;
+ Ptr<Socket> m_socket6;
Address m_local;
uint32_t m_received;
PacketLossCounter m_lossCounter;
--- a/src/applications/model/udp-trace-client.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-trace-client.cc Mon Feb 20 14:05:07 2012 +0100
@@ -22,6 +22,7 @@
#include "ns3/ipv4-address.h"
#include "ns3/nstime.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/socket.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
@@ -59,10 +60,10 @@
.SetParent<Application> ()
.AddConstructor<UdpTraceClient> ()
.AddAttribute ("RemoteAddress",
- "The destination Ipv4Address of the outbound packets",
- Ipv4AddressValue (),
- MakeIpv4AddressAccessor (&UdpTraceClient::m_peerAddress),
- MakeIpv4AddressChecker ())
+ "The destination Address of the outbound packets",
+ AddressValue (),
+ MakeAddressAccessor (&UdpTraceClient::m_peerAddress),
+ MakeAddressChecker ())
.AddAttribute ("RemotePort",
"The destination port of the outbound packets",
UintegerValue (100),
@@ -116,10 +117,26 @@
}
void
+UdpTraceClient::SetRemote (Address ip, uint16_t port)
+{
+ m_entries.clear ();
+ m_peerAddress = ip;
+ m_peerPort = port;
+}
+
+void
UdpTraceClient::SetRemote (Ipv4Address ip, uint16_t port)
{
m_entries.clear ();
- m_peerAddress = ip;
+ m_peerAddress = Address (ip);
+ m_peerPort = port;
+}
+
+void
+UdpTraceClient::SetRemote (Ipv6Address ip, uint16_t port)
+{
+ m_entries.clear ();
+ m_peerAddress = Address (ip);
m_peerPort = port;
}
@@ -223,8 +240,16 @@
{
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
m_socket = Socket::CreateSocket (GetNode (), tid);
- m_socket->Bind ();
- m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
+ if (Ipv4Address::IsMatchingType(m_peerAddress) == true)
+ {
+ m_socket->Bind ();
+ m_socket->Connect (InetSocketAddress (Ipv4Address::ConvertFrom (m_peerAddress), m_peerPort));
+ }
+ else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
+ {
+ m_socket->Bind6 ();
+ m_socket->Connect (Inet6SocketAddress (Ipv6Address::ConvertFrom (m_peerAddress), m_peerPort));
+ }
}
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
m_sendEvent = Simulator::Schedule (Seconds (0.0), &UdpTraceClient::Send, this);
@@ -255,16 +280,31 @@
SeqTsHeader seqTs;
seqTs.SetSeq (m_sent);
p->AddHeader (seqTs);
+
+ std::stringstream addressString;
+ if (Ipv4Address::IsMatchingType(m_peerAddress) == true)
+ {
+ addressString << Ipv4Address::ConvertFrom (m_peerAddress);
+ }
+ else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
+ {
+ addressString << Ipv6Address::ConvertFrom (m_peerAddress);
+ }
+ else
+ {
+ addressString << m_peerAddress;
+ }
+
if ((m_socket->Send (p)) >= 0)
{
++m_sent;
NS_LOG_INFO ("Sent " << size << " bytes to "
- << m_peerAddress);
+ << addressString.str ());
}
else
{
NS_LOG_INFO ("Error while sending " << size << " bytes to "
- << m_peerAddress);
+ << addressString.str ());
}
}
--- a/src/applications/model/udp-trace-client.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/applications/model/udp-trace-client.h Mon Feb 20 14:05:07 2012 +0100
@@ -80,7 +80,9 @@
* \param ip the destination ip address to which the stream will be sent
* \param port the destination udp port to which the stream will be sent
*/
+ void SetRemote (Address ip, uint16_t port);
void SetRemote (Ipv4Address ip, uint16_t port);
+ void SetRemote (Ipv6Address ip, uint16_t port);
/**
* \brief set the trace file to be used by the application
@@ -122,7 +124,7 @@
};
uint32_t m_sent;
Ptr<Socket> m_socket;
- Ipv4Address m_peerAddress;
+ Address m_peerAddress;
uint16_t m_peerPort;
EventId m_sendEvent;
std::vector<struct TraceEntry> m_entries;
--- a/src/csma-layout/examples/csma-star.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/csma-layout/examples/csma-star.cc Mon Feb 20 14:05:07 2012 +0100
@@ -22,6 +22,7 @@
#include "ns3/applications-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
+#include "ns3/ipv6-address-generator.h"
// Network topology (default)
//
@@ -61,9 +62,13 @@
// Default number of nodes in the star. Overridable by command line argument.
//
uint32_t nSpokes = 7;
+ uint32_t useIpv6 = 0;
+ Ipv6Address ipv6AddressBase = Ipv6Address("2001::");
+ Ipv6Prefix ipv6AddressPrefix = Ipv6Prefix(64);
CommandLine cmd;
cmd.AddValue ("nSpokes", "Number of spoke nodes to place in the star", nSpokes);
+ cmd.AddValue ("useIpv6", "Use Ipv6", useIpv6);
cmd.Parse (argc, argv);
NS_LOG_INFO ("Build star topology.");
@@ -98,7 +103,14 @@
internet.Install (fillNodes);
NS_LOG_INFO ("Assign IP Addresses.");
- star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.0.0", "255.255.255.0"));
+ if (useIpv6 == 0)
+ {
+ star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.0.0", "255.255.255.0"));
+ }
+ else
+ {
+ star.AssignIpv6Addresses (ipv6AddressBase, ipv6AddressPrefix);
+ }
//
// We assigned addresses to the logical hub and the first "drop" of the
@@ -111,16 +123,31 @@
// etc.
//
Ipv4AddressHelper address;
+ Ipv6AddressHelper address6;
for(uint32_t i = 0; i < star.SpokeCount (); ++i)
{
- std::ostringstream subnet;
- subnet << "10.1." << i << ".0";
- NS_LOG_INFO ("Assign IP Addresses for CSMA subnet " << subnet.str ());
- address.SetBase (subnet.str ().c_str (), "255.255.255.0", "0.0.0.3");
+ if (useIpv6 == 0)
+ {
+ std::ostringstream subnet;
+ subnet << "10.1." << i << ".0";
+ NS_LOG_INFO ("Assign IP Addresses for CSMA subnet " << subnet.str ());
+ address.SetBase (subnet.str ().c_str (), "255.255.255.0", "0.0.0.3");
- for (uint32_t j = 0; j < nFill; ++j)
+ for (uint32_t j = 0; j < nFill; ++j)
+ {
+ address.Assign (fillDevices.Get (i * nFill + j));
+ }
+ }
+ else
{
- address.Assign (fillDevices.Get (i * nFill + j));
+ Ipv6AddressGenerator::Init (ipv6AddressBase, ipv6AddressPrefix);
+ Ipv6Address v6network = Ipv6AddressGenerator::GetNetwork (ipv6AddressPrefix);
+ address6.NewNetwork(v6network, ipv6AddressPrefix);
+
+ for (uint32_t j = 0; j < nFill; ++j)
+ {
+ address6.Assign(fillDevices.Get (i * nFill + j));
+ }
}
}
@@ -129,11 +156,23 @@
// Create a packet sink on the star "hub" to receive packets.
//
uint16_t port = 50000;
- Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
- PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
- ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ());
- hubApp.Start (Seconds (1.0));
- hubApp.Stop (Seconds (10.0));
+
+ if (useIpv6 == 0)
+ {
+ Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+ PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
+ ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ());
+ hubApp.Start (Seconds (1.0));
+ hubApp.Stop (Seconds (10.0));
+ }
+ else
+ {
+ Address hubLocalAddress6 (Inet6SocketAddress (Ipv6Address::GetAny (), port));
+ PacketSinkHelper packetSinkHelper6 ("ns3::TcpSocketFactory", hubLocalAddress6);
+ ApplicationContainer hubApp6 = packetSinkHelper6.Install (star.GetHub ());
+ hubApp6.Start (Seconds (1.0));
+ hubApp6.Stop (Seconds (10.0));
+ }
//
// Create OnOff applications to send TCP to the hub, one on each spoke node.
@@ -146,8 +185,16 @@
for (uint32_t i = 0; i < star.SpokeCount (); ++i)
{
- AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port));
- onOffHelper.SetAttribute ("Remote", remoteAddress);
+ if (useIpv6 == 0)
+ {
+ AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port));
+ onOffHelper.SetAttribute ("Remote", remoteAddress);
+ }
+ else
+ {
+ AddressValue remoteAddress (Inet6SocketAddress (star.GetHubIpv6Address (i), port));
+ onOffHelper.SetAttribute ("Remote", remoteAddress);
+ }
spokeApps.Add (onOffHelper.Install (star.GetSpokeNode (i)));
}
@@ -166,7 +213,15 @@
for (uint32_t i = 0; i < fillNodes.GetN (); ++i)
{
- AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i / nFill), port));
+ AddressValue remoteAddress;
+ if (useIpv6 == 0)
+ {
+ remoteAddress = AddressValue(InetSocketAddress (star.GetHubIpv4Address (i / nFill), port));
+ }
+ else
+ {
+ remoteAddress = AddressValue(Inet6SocketAddress (star.GetHubIpv6Address (i / nFill), port));
+ }
onOffHelper.SetAttribute ("Remote", remoteAddress);
fillApps.Add (onOffHelper.Install (fillNodes.Get (i)));
}
@@ -178,7 +233,10 @@
//
// Turn on global static routing so we can actually be routed across the star.
//
- Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ if (useIpv6 == 0)
+ {
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ }
NS_LOG_INFO ("Enable pcap tracing.");
//
--- a/src/csma-layout/model/csma-star-helper.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/csma-layout/model/csma-star-helper.cc Mon Feb 20 14:05:07 2012 +0100
@@ -83,6 +83,18 @@
return m_spokeInterfaces.GetAddress (i);
}
+Ipv6Address
+CsmaStarHelper::GetHubIpv6Address (uint32_t i) const
+{
+ return m_hubInterfaces6.GetAddress (i, 1);
+}
+
+Ipv6Address
+CsmaStarHelper::GetSpokeIpv6Address (uint32_t i) const
+{
+ return m_spokeInterfaces6.GetAddress (i, 1);
+}
+
uint32_t
CsmaStarHelper::SpokeCount () const
{
@@ -107,4 +119,25 @@
}
}
+void
+CsmaStarHelper::AssignIpv6Addresses (Ipv6Address network, Ipv6Prefix prefix)
+{
+ Ipv6AddressGenerator::Init(network, prefix);
+ Ipv6Address v6network;
+ Ipv6AddressHelper addressHelper;
+
+ for (uint32_t i = 0; i < m_spokes.GetN (); ++i)
+ {
+ v6network = Ipv6AddressGenerator::GetNetwork (prefix);
+ addressHelper.NewNetwork(v6network, prefix);
+
+ Ipv6InterfaceContainer ic = addressHelper.Assign (m_hubDevices.Get (i));
+ m_hubInterfaces6.Add (ic);
+ ic = addressHelper.Assign (m_spokeDevices.Get (i));
+ m_spokeInterfaces6.Add (ic);
+
+ Ipv6AddressGenerator::NextNetwork (prefix);
+ }
+}
+
} // namespace ns3
--- a/src/csma-layout/model/csma-star-helper.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/csma-layout/model/csma-star-helper.h Mon Feb 20 14:05:07 2012 +0100
@@ -23,8 +23,11 @@
#include "csma-helper.h"
#include "ipv4-address-helper.h"
+#include "ipv6-address-helper.h"
#include "internet-stack-helper.h"
#include "ipv4-interface-container.h"
+#include "ipv6-interface-container.h"
+#include "ipv6-address-generator.h"
namespace ns3 {
@@ -92,6 +95,13 @@
Ipv4Address GetHubIpv4Address (uint32_t i) const;
/**
+ * \param i index into the hub interfaces
+ *
+ * \returns Ipv6Address according to indexed hub interface
+ */
+ Ipv6Address GetHubIpv6Address (uint32_t i) const;
+
+ /**
* \param i index into the spoke interfaces
*
* \returns Ipv4Address according to indexed spoke interface
@@ -99,6 +109,13 @@
Ipv4Address GetSpokeIpv4Address (uint32_t i) const;
/**
+ * \param i index into the spoke interfaces
+ *
+ * \returns Ipv6Address according to indexed spoke interface
+ */
+ Ipv6Address GetSpokeIpv6Address (uint32_t i) const;
+
+ /**
* \returns the total number of spokes in the star
*/
uint32_t SpokeCount () const;
@@ -116,6 +133,13 @@
*/
void AssignIpv4Addresses (Ipv4AddressHelper address);
+ /**
+ * \param network an IPv6 Address representing the network portion
+ * of the Ipv6 Address
+ * \param prefix the prefix length
+ */
+ void AssignIpv6Addresses (Ipv6Address network, Ipv6Prefix prefix);
+
private:
NodeContainer m_hub;
NetDeviceContainer m_hubDevices;
@@ -123,6 +147,8 @@
NetDeviceContainer m_spokeDevices;
Ipv4InterfaceContainer m_hubInterfaces;
Ipv4InterfaceContainer m_spokeInterfaces;
+ Ipv6InterfaceContainer m_hubInterfaces6;
+ Ipv6InterfaceContainer m_spokeInterfaces6;
};
} // namespace ns3
--- a/src/internet/doc/internet-stack.rst Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/doc/internet-stack.rst Mon Feb 20 14:05:07 2012 +0100
@@ -70,7 +70,7 @@
~~~~~~~~~~~~~~~~~
At the lowest layer, sitting above the NetDevices, are the "layer 3" protocols,
-including IPv4, IPv6 (in the future), and ARP. The class
+including IPv4, IPv6, and ARP. The class
:cpp:class:`Ipv4L3Protocol` is an implementation class whose public interface is
typically class :cpp:class:`Ipv4`, but the
Ipv4L3Protocol public API is also used internally at present.
@@ -137,7 +137,12 @@
Config::SetDefault ("ns3::ArpCache::PendingQueueSize", UintegerValue (MAX_BURST_SIZE/L2MTU*3));
-The IPv6 implementation follows a similar architecture.
+The IPv6 implementation follows a similar architecture. Dual-stacked nodes (one with
+support for both IPv4 and IPv6) will allow an IPv6 socket to receive IPv4 connections
+as a standard dual-stacked system does. A socket bound and listening to an IPv6 endpoint
+can receive an IPv4 connection and will return the remote address as an IPv4-mapped address.
+Support for the IPV6_V6ONLY socket option does not currently exist.
+
Layer-4 protocols and sockets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -156,8 +161,14 @@
The above will query the node to get a pointer to its UDP socket factory, will
create one such socket, and will use the socket with an API similar to the
-C-based sockets API, such as ``Connect ()`` and ``Send ()``. See the chapter on
-|ns3| sockets for more information.
+C-based sockets API, such as ``Connect ()`` and ``Send ()``. The address passed
+to the ``Bind ()``, ``Connect ()``, or ``Send ()`` functions may be a
+:cpp:class:`Ipv4Address`, :cpp:class:`Ipv6Address`, or :cpp:class:`Address`.
+If a :cpp:class:`Address` is passed in and contains anything other than
+a :cpp:class:`Ipv4Address` or :cpp:class:`Ipv6Address`, these functions will
+return an error. The ``Bind (void)`` and ``Bind6 (void)`` functions bind to
+"0.0.0.0" and "::" respectively.
+See the chapter on |ns3| sockets for more information.
We have described so far a socket factory (e.g. ``class Udp``) and a socket,
which may be specialized (e.g., class :cpp:class:`UdpSocket`). There are a few
--- a/src/internet/doc/ipv6.rst Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/doc/ipv6.rst Mon Feb 20 14:05:07 2012 +0100
@@ -5,6 +5,3 @@
*Placeholder chapter*
-IPv6 models are being added to ns-3. A paper on the IPv6 models was published in
-WNS2 2008: `<http://lsiit.u-strasbg.fr/Publications/2008/VMM08/>`_.
-
--- a/src/internet/model/icmpv4-l4-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/icmpv4-l4-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -22,7 +22,7 @@
Icmpv4L4Protocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Icmpv4L4Protocol")
- .SetParent<Ipv4L4Protocol> ()
+ .SetParent<IpL4Protocol> ()
.AddConstructor<Icmpv4L4Protocol> ()
;
return tid;
@@ -180,7 +180,7 @@
const uint8_t payload[8])
{
Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
- Ptr<Ipv4L4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
+ Ptr<IpL4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
if (l4 != 0)
{
l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
@@ -219,7 +219,7 @@
Forward (source, icmp, 0, ipHeader, payload);
}
-enum Ipv4L4Protocol::RxStatus
+enum IpL4Protocol::RxStatus
Icmpv4L4Protocol::Receive (Ptr<Packet> p,
Ipv4Header const &header,
Ptr<Ipv4Interface> incomingInterface)
@@ -242,7 +242,16 @@
NS_LOG_DEBUG (icmp << " " << *p);
break;
}
- return Ipv4L4Protocol::RX_OK;
+ return IpL4Protocol::RX_OK;
+}
+enum IpL4Protocol::RxStatus
+Icmpv4L4Protocol::Receive (Ptr<Packet> p,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> incomingInterface)
+{
+ NS_LOG_FUNCTION (this << p << src << dst << incomingInterface);
+ return IpL4Protocol::RX_ENDPOINT_UNREACH;
}
void
Icmpv4L4Protocol::DoDispose (void)
@@ -250,19 +259,30 @@
NS_LOG_FUNCTION (this);
m_node = 0;
m_downTarget.Nullify ();
- Ipv4L4Protocol::DoDispose ();
+ IpL4Protocol::DoDispose ();
}
void
-Icmpv4L4Protocol::SetDownTarget (Ipv4L4Protocol::DownTargetCallback callback)
+Icmpv4L4Protocol::SetDownTarget (IpL4Protocol::DownTargetCallback callback)
{
m_downTarget = callback;
}
-Ipv4L4Protocol::DownTargetCallback
+void
+Icmpv4L4Protocol::SetDownTarget6 (IpL4Protocol::DownTargetCallback6 callback)
+{
+}
+
+IpL4Protocol::DownTargetCallback
Icmpv4L4Protocol::GetDownTarget (void) const
{
return m_downTarget;
}
+IpL4Protocol::DownTargetCallback6
+Icmpv4L4Protocol::GetDownTarget6 (void) const
+{
+ return (IpL4Protocol::DownTargetCallback6)NULL;
+}
+
} // namespace ns3
--- a/src/internet/model/icmpv4-l4-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/icmpv4-l4-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -1,7 +1,7 @@
#ifndef ICMPV4_L4_PROTOCOL_H
#define ICMPV4_L4_PROTOCOL_H
-#include "ipv4-l4-protocol.h"
+#include "ip-l4-protocol.h"
#include "icmpv4.h"
#include "ns3/ipv4-address.h"
@@ -11,7 +11,7 @@
class Ipv4Interface;
class Ipv4Route;
-class Icmpv4L4Protocol : public Ipv4L4Protocol
+class Icmpv4L4Protocol : public IpL4Protocol
{
public:
static TypeId GetTypeId (void);
@@ -24,18 +24,24 @@
static uint16_t GetStaticProtocolNumber (void);
virtual int GetProtocolNumber (void) const;
- virtual enum Ipv4L4Protocol::RxStatus Receive (Ptr<Packet> p,
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
Ipv4Header const &header,
Ptr<Ipv4Interface> incomingInterface);
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> incomingInterface);
void SendDestUnreachFragNeeded (Ipv4Header header, Ptr<const Packet> orgData, uint16_t nextHopMtu);
void SendTimeExceededTtl (Ipv4Header header, Ptr<const Packet> orgData);
void SendDestUnreachPort (Ipv4Header header, Ptr<const Packet> orgData);
- // From Ipv4L4Protocol
- virtual void SetDownTarget (Ipv4L4Protocol::DownTargetCallback cb);
- // From Ipv4L4Protocol
- virtual Ipv4L4Protocol::DownTargetCallback GetDownTarget (void) const;
+ // From IpL4Protocol
+ virtual void SetDownTarget (IpL4Protocol::DownTargetCallback cb);
+ virtual void SetDownTarget6 (IpL4Protocol::DownTargetCallback6 cb);
+ // From IpL4Protocol
+ virtual IpL4Protocol::DownTargetCallback GetDownTarget (void) const;
+ virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const;
protected:
/*
* This function will notify other components connected to the node that a new stack member is now connected
@@ -66,7 +72,7 @@
virtual void DoDispose (void);
Ptr<Node> m_node;
- Ipv4L4Protocol::DownTargetCallback m_downTarget;
+ IpL4Protocol::DownTargetCallback m_downTarget;
};
} // namespace ns3
--- a/src/internet/model/icmpv6-l4-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/icmpv6-l4-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -66,7 +66,7 @@
TypeId Icmpv6L4Protocol::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::Icmpv6L4Protocol")
- .SetParent<Ipv6L4Protocol> ()
+ .SetParent<IpL4Protocol> ()
.AddConstructor<Icmpv6L4Protocol> ()
.AddAttribute ("DAD", "Always do DAD check.",
BooleanValue (true),
@@ -97,9 +97,10 @@
cache = 0;
}
m_cacheList.clear ();
+ m_downTarget.Nullify();
m_node = 0;
- Ipv6L4Protocol::DoDispose ();
+ IpL4Protocol::DoDispose ();
}
void Icmpv6L4Protocol::NotifyNewAggregate ()
@@ -117,6 +118,7 @@
ipv6->Insert (this);
Ptr<Ipv6RawSocketFactoryImpl> rawFactory = CreateObject<Ipv6RawSocketFactoryImpl> ();
ipv6->AggregateObject (rawFactory);
+ this->SetDownTarget6 (MakeCallback (&Ipv6L3Protocol::Send, ipv6));
}
}
}
@@ -174,7 +176,13 @@
interface->Send (p, Ipv6Address::MakeSolicitedAddress (target));
}
-enum Ipv6L4Protocol::RxStatus_e Icmpv6L4Protocol::Receive (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+enum IpL4Protocol::RxStatus Icmpv6L4Protocol::Receive (Ptr<Packet> packet, Ipv4Header const &header, Ptr<Ipv4Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << header);
+ return IpL4Protocol::RX_ENDPOINT_UNREACH;
+}
+
+enum IpL4Protocol::RxStatus Icmpv6L4Protocol::Receive (Ptr<Packet> packet, Ipv6Address &src, Ipv6Address &dst, Ptr<Ipv6Interface> interface)
{
NS_LOG_FUNCTION (this << packet << src << dst << interface);
Ptr<Packet> p = packet->Copy ();
@@ -225,7 +233,7 @@
break;
}
- return Ipv6L4Protocol::RX_OK;
+ return IpL4Protocol::RX_OK;
}
void Icmpv6L4Protocol::HandleEchoRequest (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
@@ -751,7 +759,7 @@
tag.SetTtl (ttl);
packet->AddPacketTag (tag);
- ipv6->Send (packet, src, dst, PROT_NUMBER, 0);
+ m_downTarget (packet, src, dst, PROT_NUMBER, 0);
}
void Icmpv6L4Protocol::SendMessage (Ptr<Packet> packet, Ipv6Address dst, Icmpv6Header& icmpv6Hdr, uint8_t ttl)
@@ -777,7 +785,7 @@
icmpv6Hdr.CalculatePseudoHeaderChecksum (src, dst, packet->GetSize () + icmpv6Hdr.GetSerializedSize (), PROT_NUMBER);
packet->AddHeader (icmpv6Hdr);
- ipv6->Send (packet, src, dst, PROT_NUMBER, route);
+ m_downTarget (packet, src, dst, PROT_NUMBER, route);
}
else
{
@@ -1244,5 +1252,28 @@
}
}
+void
+Icmpv6L4Protocol::SetDownTarget (IpL4Protocol::DownTargetCallback callback)
+{
+}
+
+void
+Icmpv6L4Protocol::SetDownTarget6 (IpL4Protocol::DownTargetCallback6 callback)
+{
+ m_downTarget = callback;
+}
+
+IpL4Protocol::DownTargetCallback
+Icmpv6L4Protocol::GetDownTarget (void) const
+{
+ return (IpL4Protocol::DownTargetCallback)NULL;
+}
+
+IpL4Protocol::DownTargetCallback6
+Icmpv6L4Protocol::GetDownTarget6 (void) const
+{
+ return m_downTarget;
+}
+
} /* namespace ns3 */
--- a/src/internet/model/icmpv6-l4-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/icmpv6-l4-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -27,7 +27,7 @@
#include "ns3/ipv6-address.h"
#include "icmpv6-header.h"
-#include "ipv6-l4-protocol.h"
+#include "ip-l4-protocol.h"
namespace ns3
{
@@ -42,7 +42,7 @@
* \class Icmpv6L4Protocol
* \brief An implementation of the ICMPv6 protocol.
*/
-class Icmpv6L4Protocol : public Ipv6L4Protocol
+class Icmpv6L4Protocol : public IpL4Protocol
{
public:
/**
@@ -329,7 +329,12 @@
* \param dst destination address
* \param interface the interface from which the packet is coming
*/
- virtual enum Ipv6L4Protocol::RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv4Header const &header,
+ Ptr<Ipv4Interface> interface);
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv6Address &src, Ipv6Address &dst,
+ Ptr<Ipv6Interface> interface);
/**
* \brief Function called when DAD timeout.
@@ -477,6 +482,16 @@
* \param device the device
*/
Ptr<NdiscCache> FindCache (Ptr<NetDevice> device);
+
+ // From IpL4Protocol
+ virtual void SetDownTarget (IpL4Protocol::DownTargetCallback cb);
+ virtual void SetDownTarget6 (IpL4Protocol::DownTargetCallback6 cb);
+ // From IpL4Protocol
+ virtual IpL4Protocol::DownTargetCallback GetDownTarget (void) const;
+ virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const;
+
+ IpL4Protocol::DownTargetCallback6 m_downTarget;
+
};
} /* namespace ns3 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ip-l4-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -0,0 +1,61 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+// NS3 - Layer 4 Protocol base class
+// George F. Riley, Georgia Tech, Spring 2007
+
+#include "ip-l4-protocol.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (IpL4Protocol);
+
+TypeId
+IpL4Protocol::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::IpL4Protocol")
+ .SetParent<Object> ()
+ .AddAttribute ("ProtocolNumber", "The Ip protocol number.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&IpL4Protocol::GetProtocolNumber),
+ MakeUintegerChecker<int> ())
+ ;
+ return tid;
+}
+
+IpL4Protocol::~IpL4Protocol ()
+{
+}
+
+void
+IpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv4Address payloadSource,Ipv4Address payloadDestination,
+ const uint8_t payload[8])
+{}
+void
+IpL4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv6Address payloadSource, Ipv6Address payloadDestination,
+ const uint8_t payload[8])
+{}
+
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ip-l4-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -0,0 +1,127 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+// NS3 - Layer 4 Protocol base class
+// George F. Riley, Georgia Tech, Spring 2007
+
+#ifndef IP_L4_PROTOCOL_H
+#define IP_L4_PROTOCOL_H
+
+#include "ns3/object.h"
+#include "ns3/callback.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/ipv6-interface.h"
+
+namespace ns3 {
+
+class Packet;
+class Ipv4Address;
+class Ipv4Interface;
+class Ipv4Route;
+class Ipv6Route;
+
+/**
+ * \brief L4 Protocol abstract base class
+ *
+ * This is an abstract base class for layer four protocols which use IP as
+ * the network layer.
+ */
+class IpL4Protocol : public Object
+{
+public:
+ enum RxStatus {
+ RX_OK,
+ RX_CSUM_FAILED,
+ RX_ENDPOINT_CLOSED,
+ RX_ENDPOINT_UNREACH
+ };
+
+ static TypeId GetTypeId (void);
+
+ virtual ~IpL4Protocol ();
+
+ /**
+ * \returns the protocol number of this protocol.
+ */
+ virtual int GetProtocolNumber (void) const = 0;
+
+ /**
+ * \param p packet to forward up
+ * \param header IPv4 Header information
+ * \param incomingInterface the Ipv4Interface on which the packet arrived
+ *
+ * Called from lower-level layers to send the packet up
+ * in the stack.
+ */
+ virtual enum RxStatus Receive (Ptr<Packet> p,
+ Ipv4Header const &header,
+ Ptr<Ipv4Interface> incomingInterface) = 0;
+ virtual enum RxStatus Receive (Ptr<Packet> p,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> incomingInterface) = 0;
+
+ /**
+ * \param icmpSource the source address of the icmp message
+ * \param icmpTtl the ttl of the icmp message
+ * \param icmpType the 'type' field of the icmp message
+ * \param icmpCode the 'code' field of the icmp message
+ * \param icmpInfo extra information dependent on the icmp message
+ * generated by Icmpv4L4Protocol
+ * \param payloadSource the source address of the packet which triggered
+ * the icmp message
+ * \param payloadDestination the destination address of the packet which
+ * triggered the icmp message.
+ * \param payload the first 8 bytes of the udp header of the packet
+ * which triggered the icmp message.
+ */
+ virtual void ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv4Address payloadSource, Ipv4Address payloadDestination,
+ const uint8_t payload[8]);
+ virtual void ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv6Address payloadSource, Ipv6Address payloadDestination,
+ const uint8_t payload[8]);
+
+ typedef Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint8_t, Ptr<Ipv4Route> > DownTargetCallback;
+ typedef Callback<void,Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route> > DownTargetCallback6;
+ /**
+ * This method allows a caller to set the current down target callback
+ * set for this L4 protocol
+ *
+ * \param cb current Callback for the L4 protocol
+ */
+ virtual void SetDownTarget (DownTargetCallback cb) = 0;
+ virtual void SetDownTarget6 (DownTargetCallback6 cb) = 0;
+ /**
+ * This method allows a caller to get the current down target callback
+ * set for this L4 protocol, for
+ *
+ * \return current Callback for the L4 protocol
+ */
+ virtual DownTargetCallback GetDownTarget (void) const = 0;
+ virtual DownTargetCallback6 GetDownTarget6 (void) const = 0;
+};
+
+} // Namespace ns3
+
+#endif
--- a/src/internet/model/ipv4-l3-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv4-l3-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -36,7 +36,6 @@
#include "loopback-net-device.h"
#include "arp-l3-protocol.h"
#include "ipv4-l3-protocol.h"
-#include "ipv4-l4-protocol.h"
#include "icmpv4-l4-protocol.h"
#include "ipv4-interface.h"
#include "ipv4-raw-socket-impl.h"
@@ -98,11 +97,11 @@
}
void
-Ipv4L3Protocol::Insert (Ptr<Ipv4L4Protocol> protocol)
+Ipv4L3Protocol::Insert (Ptr<IpL4Protocol> protocol)
{
m_protocols.push_back (protocol);
}
-Ptr<Ipv4L4Protocol>
+Ptr<IpL4Protocol>
Ipv4L3Protocol::GetProtocol (int protocolNumber) const
{
for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
@@ -115,7 +114,7 @@
return 0;
}
void
-Ipv4L3Protocol::Remove (Ptr<Ipv4L4Protocol> protocol)
+Ipv4L3Protocol::Remove (Ptr<IpL4Protocol> protocol)
{
m_protocols.remove (protocol);
}
@@ -512,7 +511,7 @@
Ptr<Icmpv4L4Protocol>
Ipv4L3Protocol::GetIcmp (void) const
{
- Ptr<Ipv4L4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
+ Ptr<IpL4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
if (prot != 0)
{
return prot->GetObject<Icmpv4L4Protocol> ();
@@ -863,22 +862,22 @@
m_localDeliverTrace (ip, packet, iif);
- Ptr<Ipv4L4Protocol> protocol = GetProtocol (ip.GetProtocol ());
+ Ptr<IpL4Protocol> protocol = GetProtocol (ip.GetProtocol ());
if (protocol != 0)
{
// we need to make a copy in the unlikely event we hit the
// RX_ENDPOINT_UNREACH codepath
Ptr<Packet> copy = p->Copy ();
- enum Ipv4L4Protocol::RxStatus status =
+ enum IpL4Protocol::RxStatus status =
protocol->Receive (p, ip, GetInterface (iif));
switch (status) {
- case Ipv4L4Protocol::RX_OK:
+ case IpL4Protocol::RX_OK:
// fall through
- case Ipv4L4Protocol::RX_ENDPOINT_CLOSED:
+ case IpL4Protocol::RX_ENDPOINT_CLOSED:
// fall through
- case Ipv4L4Protocol::RX_CSUM_FAILED:
+ case IpL4Protocol::RX_CSUM_FAILED:
break;
- case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
+ case IpL4Protocol::RX_ENDPOINT_UNREACH:
if (ip.GetDestination ().IsBroadcast () == true ||
ip.GetDestination ().IsMulticast () == true)
{
--- a/src/internet/model/ipv4-l3-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv4-l3-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -47,7 +47,7 @@
class Node;
class Socket;
class Ipv4RawSocketImpl;
-class Ipv4L4Protocol;
+class IpL4Protocol;
class Icmpv4L4Protocol;
@@ -117,7 +117,7 @@
* a working L4 Protocol and returned from this method.
* The caller does not get ownership of the returned pointer.
*/
- void Insert (Ptr<Ipv4L4Protocol> protocol);
+ void Insert (Ptr<IpL4Protocol> protocol);
/**
* \param protocolNumber number of protocol to lookup
* in this L4 Demux
@@ -127,14 +127,14 @@
* to forward packets up the stack to the right protocol.
* It is also called from NodeImpl::GetUdp for example.
*/
- Ptr<Ipv4L4Protocol> GetProtocol (int protocolNumber) const;
+ Ptr<IpL4Protocol> GetProtocol (int protocolNumber) const;
/**
* \param protocol protocol to remove from this demux.
*
* The input value to this method should be the value
* returned from the Ipv4L4Protocol::Insert method.
*/
- void Remove (Ptr<Ipv4L4Protocol> protocol);
+ void Remove (Ptr<IpL4Protocol> protocol);
/**
* \param ttl default ttl to use
@@ -292,7 +292,7 @@
typedef std::vector<Ptr<Ipv4Interface> > Ipv4InterfaceList;
typedef std::list<Ptr<Ipv4RawSocketImpl> > SocketList;
- typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
+ typedef std::list<Ptr<IpL4Protocol> > L4List_t;
bool m_ipForward;
bool m_weakEsModel;
--- a/src/internet/model/ipv4-l4-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-// NS3 - Layer 4 Protocol base class
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ipv4-l4-protocol.h"
-#include "ns3/uinteger.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4L4Protocol);
-
-TypeId
-Ipv4L4Protocol::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::Ipv4L4Protocol")
- .SetParent<Object> ()
- .AddAttribute ("ProtocolNumber", "The Ipv4 protocol number.",
- UintegerValue (0),
- MakeUintegerAccessor (&Ipv4L4Protocol::GetProtocolNumber),
- MakeUintegerChecker<int> ())
- ;
- return tid;
-}
-
-Ipv4L4Protocol::~Ipv4L4Protocol ()
-{
-}
-
-void
-Ipv4L4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
- uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
- Ipv4Address payloadSource,Ipv4Address payloadDestination,
- const uint8_t payload[8])
-{}
-
-} // namespace ns3
--- a/src/internet/model/ipv4-l4-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-// NS3 - Layer 4 Protocol base class
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef IPV4_L4_PROTOCOL_H
-#define IPV4_L4_PROTOCOL_H
-
-#include "ns3/object.h"
-#include "ns3/callback.h"
-#include "ns3/ipv4-header.h"
-
-namespace ns3 {
-
-class Packet;
-class Ipv4Address;
-class Ipv4Interface;
-class Ipv4Route;
-
-/**
- * \brief L4 Protocol abstract base class
- *
- * This is an abstract base class for layer four protocols which use IPv4 as
- * the network layer.
- */
-class Ipv4L4Protocol : public Object
-{
-public:
- enum RxStatus {
- RX_OK,
- RX_CSUM_FAILED,
- RX_ENDPOINT_CLOSED,
- RX_ENDPOINT_UNREACH
- };
-
- static TypeId GetTypeId (void);
-
- virtual ~Ipv4L4Protocol ();
-
- /**
- * \returns the protocol number of this protocol.
- */
- virtual int GetProtocolNumber (void) const = 0;
-
- /**
- * \param p packet to forward up
- * \param header IPv4 Header information
- * \param incomingInterface the Ipv4Interface on which the packet arrived
- *
- * Called from lower-level layers to send the packet up
- * in the stack.
- */
- virtual enum RxStatus Receive (Ptr<Packet> p,
- Ipv4Header const &header,
- Ptr<Ipv4Interface> incomingInterface) = 0;
-
- /**
- * \param icmpSource the source address of the icmp message
- * \param icmpTtl the ttl of the icmp message
- * \param icmpType the 'type' field of the icmp message
- * \param icmpCode the 'code' field of the icmp message
- * \param icmpInfo extra information dependent on the icmp message
- * generated by Icmpv4L4Protocol
- * \param payloadSource the source address of the packet which triggered
- * the icmp message
- * \param payloadDestination the destination address of the packet which
- * triggered the icmp message.
- * \param payload the first 8 bytes of the udp header of the packet
- * which triggered the icmp message.
- */
- virtual void ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
- uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
- Ipv4Address payloadSource, Ipv4Address payloadDestination,
- const uint8_t payload[8]);
-
- typedef Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint8_t, Ptr<Ipv4Route> > DownTargetCallback;
- /**
- * This method allows a caller to set the current down target callback
- * set for this L4 protocol
- *
- * \param cb current Callback for the L4 protocol
- */
- virtual void SetDownTarget (DownTargetCallback cb) = 0;
- /**
- * This method allows a caller to get the current down target callback
- * set for this L4 protocol, for
- *
- * \return current Callback for the L4 protocol
- */
- virtual DownTargetCallback GetDownTarget (void) const = 0;
-};
-
-} // Namespace ns3
-
-#endif
--- a/src/internet/model/ipv4-raw-socket-impl.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv4-raw-socket-impl.cc Mon Feb 20 14:05:07 2012 +0100
@@ -116,6 +116,11 @@
return 0;
}
int
+Ipv4RawSocketImpl::Bind6 (void)
+{
+ return (-1);
+}
+int
Ipv4RawSocketImpl::GetSockName (Address &address) const
{
address = InetSocketAddress (m_src, 0);
--- a/src/internet/model/ipv4-raw-socket-impl.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv4-raw-socket-impl.h Mon Feb 20 14:05:07 2012 +0100
@@ -27,6 +27,7 @@
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (const Address &address);
virtual int Bind ();
+ virtual int Bind6 ();
virtual int GetSockName (Address &address) const;
virtual int Close (void);
virtual int ShutdownSend (void);
--- a/src/internet/model/ipv4.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv4.h Mon Feb 20 14:05:07 2012 +0100
@@ -24,7 +24,7 @@
#include "ns3/object.h"
#include "ns3/socket.h"
#include "ns3/callback.h"
-#include "ns3/ipv4-l4-protocol.h"
+#include "ns3/ip-l4-protocol.h"
#include "ns3/ipv4-address.h"
#include "ipv4-route.h"
#include "ipv4-interface-address.h"
@@ -149,7 +149,7 @@
* Adds a protocol to an internal list of L4 protocols.
*
*/
- virtual void Insert (Ptr<Ipv4L4Protocol> protocol) = 0;
+ virtual void Insert (Ptr<IpL4Protocol> protocol) = 0;
/**
* \brief Determine whether address and interface corresponding to
--- a/src/internet/model/ipv6-end-point.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv6-end-point.cc Mon Feb 20 14:05:07 2012 +0100
@@ -81,7 +81,7 @@
m_peerPort = port;
}
-void Ipv6EndPoint::SetRxCallback (Callback<void, Ptr<Packet>, Ipv6Address, uint16_t> callback)
+void Ipv6EndPoint::SetRxCallback (Callback<void, Ptr<Packet>, Ipv6Address, Ipv6Address, uint16_t> callback)
{
m_rxCallback = callback;
}
@@ -96,11 +96,11 @@
m_destroyCallback = callback;
}
-void Ipv6EndPoint::ForwardUp (Ptr<Packet> p, Ipv6Address addr, uint16_t port)
+void Ipv6EndPoint::ForwardUp (Ptr<Packet> p, Ipv6Address srcAddr, Ipv6Address dstAddr, uint16_t port)
{
if (!m_rxCallback.IsNull ())
{
- m_rxCallback (p, addr, port);
+ m_rxCallback (p, srcAddr, dstAddr, port);
}
}
@@ -114,9 +114,9 @@
}
}
-void Ipv6EndPoint::DoForwardUp (Ptr<Packet> p, Ipv6Address saddr, uint16_t sport)
+void Ipv6EndPoint::DoForwardUp (Ptr<Packet> p, Ipv6Address saddr, Ipv6Address daddr, uint16_t sport)
{
- m_rxCallback (p, saddr, sport);
+ m_rxCallback (p, saddr, daddr, sport);
}
void Ipv6EndPoint::DoForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type,
--- a/src/internet/model/ipv6-end-point.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv6-end-point.h Mon Feb 20 14:05:07 2012 +0100
@@ -98,7 +98,7 @@
* \brief Set the reception callback.
* \param callback callback function
*/
- void SetRxCallback (Callback<void, Ptr<Packet>, Ipv6Address, uint16_t> callback);
+ void SetRxCallback (Callback<void, Ptr<Packet>, Ipv6Address, Ipv6Address, uint16_t> callback);
/**
* \brief Set the ICMP callback.
@@ -115,10 +115,11 @@
/**
* \brief Forward the packet to the upper level.
* \param p the packet
- * \param addr source address
+ * \param srcAddr source address
+ * \param dstAddr source address
* \param port source port
*/
- void ForwardUp (Ptr<Packet> p, Ipv6Address addr, uint16_t port);
+ void ForwardUp (Ptr<Packet> p, Ipv6Address srcAddr, Ipv6Address dstAddr, uint16_t port);
/**
* \brief Function called from an L4Protocol implementation
@@ -137,9 +138,10 @@
* \brief ForwardUp wrapper.
* \param p packet
* \param saddr source IPv6 address
+ * \param daddr dest IPv6 address
* \param sport source port
*/
- void DoForwardUp (Ptr<Packet> p, Ipv6Address saddr, uint16_t sport);
+ void DoForwardUp (Ptr<Packet> p, Ipv6Address saddr, Ipv6Address daddr, uint16_t sport);
/**
* \brief ForwardIcmp wrapper.
@@ -175,7 +177,7 @@
/**
* \brief The RX callback.
*/
- Callback<void, Ptr<Packet>, Ipv6Address, uint16_t> m_rxCallback;
+ Callback<void, Ptr<Packet>, Ipv6Address, Ipv6Address, uint16_t> m_rxCallback;
/**
* \brief The ICMPv6 callback.
--- a/src/internet/model/ipv6-l3-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv6-l3-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -30,7 +30,6 @@
#include "loopback-net-device.h"
#include "ipv6-l3-protocol.h"
-#include "ipv6-l4-protocol.h"
#include "ipv6-interface.h"
#include "ipv6-raw-socket-impl.h"
#include "ipv6-autoconfigured-prefix.h"
@@ -519,19 +518,19 @@
SetupLoopback ();
}
-void Ipv6L3Protocol::Insert (Ptr<Ipv6L4Protocol> protocol)
+void Ipv6L3Protocol::Insert (Ptr<IpL4Protocol> protocol)
{
NS_LOG_FUNCTION (this << protocol);
m_protocols.push_back (protocol);
}
-void Ipv6L3Protocol::Remove (Ptr<Ipv6L4Protocol> protocol)
+void Ipv6L3Protocol::Remove (Ptr<IpL4Protocol> protocol)
{
NS_LOG_FUNCTION (this << protocol);
m_protocols.remove (protocol);
}
-Ptr<Ipv6L4Protocol> Ipv6L3Protocol::GetProtocol (int protocolNumber) const
+Ptr<IpL4Protocol> Ipv6L3Protocol::GetProtocol (int protocolNumber) const
{
NS_LOG_FUNCTION (this << protocolNumber);
@@ -571,7 +570,7 @@
Ptr<Icmpv6L4Protocol> Ipv6L3Protocol::GetIcmpv6 () const
{
NS_LOG_FUNCTION_NOARGS ();
- Ptr<Ipv6L4Protocol> protocol = GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber ());
+ Ptr<IpL4Protocol> protocol = GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber ());
if (protocol)
{
@@ -941,7 +940,7 @@
{
NS_LOG_FUNCTION (this << packet << ip << iif);
Ptr<Packet> p = packet->Copy ();
- Ptr<Ipv6L4Protocol> protocol = 0;
+ Ptr<IpL4Protocol> protocol = 0;
Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
Ptr<Ipv6Extension> ipv6Extension = 0;
Ipv6Address src = ip.GetSourceAddress ();
@@ -1009,15 +1008,17 @@
/* L4 protocol */
Ptr<Packet> copy = p->Copy ();
- enum Ipv6L4Protocol::RxStatus_e status = protocol->Receive (p, ip.GetSourceAddress (), ip.GetDestinationAddress (), GetInterface (iif));
+ enum IpL4Protocol::RxStatus status = protocol->Receive (p, src, dst, GetInterface (iif));
switch (status)
{
- case Ipv6L4Protocol::RX_OK:
+ case IpL4Protocol::RX_OK:
+ break;
+ case IpL4Protocol::RX_CSUM_FAILED:
break;
- case Ipv6L4Protocol::RX_CSUM_FAILED:
+ case IpL4Protocol::RX_ENDPOINT_CLOSED:
break;
- case Ipv6L4Protocol::RX_ENDPOINT_UNREACH:
+ case IpL4Protocol::RX_ENDPOINT_UNREACH:
if (ip.GetDestinationAddress ().IsMulticast ())
{
/* do not rely on multicast address */
--- a/src/internet/model/ipv6-l3-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv6-l3-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -34,7 +34,7 @@
class Node;
class Ipv6Interface;
-class Ipv6L4Protocol;
+class IpL4Protocol;
class Ipv6Route;
class Ipv6MulticastRoute;
class Ipv6RawSocketImpl;
@@ -102,20 +102,20 @@
* \brief Add an L4 protocol.
* \param protocol L4 protocol
*/
- void Insert (Ptr<Ipv6L4Protocol> protocol);
+ void Insert (Ptr<IpL4Protocol> protocol);
/**
* \brief Remove an L4 protocol.
* \param protocol L4 protocol to remove
*/
- void Remove (Ptr<Ipv6L4Protocol> protocol);
+ void Remove (Ptr<IpL4Protocol> protocol);
/**
* \brief Get L4 protocol by protocol number.
* \param protocolNumber protocol number
* \return corresponding Ipv6L4Protocol or 0 if not found
*/
- Ptr<Ipv6L4Protocol> GetProtocol (int protocolNumber) const;
+ Ptr<IpL4Protocol> GetProtocol (int protocolNumber) const;
/**
* \brief Create raw IPv6 socket.
@@ -360,7 +360,7 @@
typedef std::list<Ptr<Ipv6Interface> > Ipv6InterfaceList;
typedef std::list<Ptr<Ipv6RawSocketImpl> > SocketList;
- typedef std::list<Ptr<Ipv6L4Protocol> > L4List_t;
+ typedef std::list<Ptr<IpL4Protocol> > L4List_t;
typedef std::list< Ptr<Ipv6AutoconfiguredPrefix> > Ipv6AutoconfiguredPrefixList;
typedef std::list< Ptr<Ipv6AutoconfiguredPrefix> >::iterator Ipv6AutoconfiguredPrefixListI;
--- a/src/internet/model/ipv6-l4-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg 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/uinteger.h"
-
-#include "ipv6-l4-protocol.h"
-
-namespace ns3
-{
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv6L4Protocol);
-
-TypeId Ipv6L4Protocol::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::Ipv6L4Protocol")
- .SetParent<Object> ()
- .AddAttribute ("ProtocolNumber", "The IPv6 protocol number.",
- UintegerValue (0),
- MakeUintegerAccessor (&Ipv6L4Protocol::GetProtocolNumber),
- MakeUintegerChecker<int> ())
- ;
- return tid;
-}
-
-Ipv6L4Protocol::~Ipv6L4Protocol ()
-{
-}
-
-void Ipv6L4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
- uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
- Ipv6Address payloadSource, Ipv6Address payloadDestination,
- const uint8_t* payload)
-{}
-
-} /* namespace ns3 */
-
--- a/src/internet/model/ipv6-l4-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007-2009 Strasbourg 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_L4_PROTOCOL_H
-#define IPV6_L4_PROTOCOL_H
-
-#include "ns3/object.h"
-#include "ns3/ipv6-header.h"
-
-namespace ns3
-{
-
-class Packet;
-class Ipv6Address;
-class Ipv6Interface;
-
-/**
- * \class Ipv6L4Protocol
- * \brief IPv6 L4 protocol abstract class
- */
-class Ipv6L4Protocol : public Object
-{
-public:
- /**
- * \enum RxStatus_e
- * \brief Status of receive.
- */
- enum RxStatus_e
- {
- RX_OK, /**< Receive OK */
- RX_CSUM_FAILED, /**< Checksum of layer 4 protocol failed */
- RX_ENDPOINT_UNREACH /**< Destination unreachable */
- };
-
- /**
- * \brief Get the type identifier.
- * \return type identifier
- */
- static TypeId GetTypeId (void);
-
- /**
- * \brief Destructor.
- */
- virtual ~Ipv6L4Protocol ();
-
- /**
- * \brief Get the protocol number.
- * \return protocol number
- */
- virtual int GetProtocolNumber () const = 0;
-
- /**
- * \brief Receive method.
- *
- * Called from lower-level layers to send the packet up
- * in the stack.
- * \param p packet to forward up
- * \param src source address of packet received
- * \param dst address of packet received
- * \param incomingInterface the Ipv6Interface on which the packet arrived
- * \return status (OK, destination unreachable or checksum failed)
- */
- virtual enum RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src,
- Ipv6Address const &dst,
- Ptr<Ipv6Interface> incomingInterface) = 0;
-
- /**
- * \brief ICMPv6 receive method.
- * \param icmpSource the source address of the ICMPv6 message
- * \param icmpTtl the ttl of the ICMPv6 message
- * \param icmpType the 'type' field of the ICMPv6 message
- * \param icmpCode the 'code' field of the ICMPv6 message
- * \param icmpInfo extra information dependent on the ICMPv6 message
- * generated by Icmpv6L4Protocol
- * \param payloadSource the source address of the packet which triggered
- * the ICMPv6 message
- * \param payloadDestination the destination address of the packet which
- * triggered the ICMPv6 message.
- * \param payload the first 8 bytes of the UDP header of the packet
- * which triggered the ICMPv6 message.
- */
- virtual void ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
- uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
- Ipv6Address payloadSource, Ipv6Address payloadDestination,
- const uint8_t* payload);
-
-};
-
-} /* namespace ns3 */
-
-#endif /* IPV6_L4_PROTOCOL_H */
-
--- a/src/internet/model/ipv6-raw-socket-impl.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv6-raw-socket-impl.cc Mon Feb 20 14:05:07 2012 +0100
@@ -122,6 +122,11 @@
return 0;
}
+int Ipv6RawSocketImpl::Bind6 ()
+{
+ return(Bind());
+}
+
int Ipv6RawSocketImpl::GetSockName (Address& address) const
{
NS_LOG_FUNCTION_NOARGS ();
--- a/src/internet/model/ipv6-raw-socket-impl.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/ipv6-raw-socket-impl.h Mon Feb 20 14:05:07 2012 +0100
@@ -116,6 +116,7 @@
* \return 0 if success, -1 otherwise
*/
virtual int Bind ();
+ virtual int Bind6 ();
/**
* \brief Get socket address.
--- a/src/internet/model/nsc-tcp-l4-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/nsc-tcp-l4-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -96,7 +96,7 @@
NscTcpL4Protocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::NscTcpL4Protocol")
- .SetParent<Ipv4L4Protocol> ()
+ .SetParent<IpL4Protocol> ()
.AddConstructor<NscTcpL4Protocol>()
.AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
ObjectVectorValue (),
@@ -242,7 +242,7 @@
delete m_nscInterface;
m_nscInterface = 0;
m_downTarget.Nullify ();
- Ipv4L4Protocol::DoDispose ();
+ IpL4Protocol::DoDispose ();
}
Ptr<Socket>
@@ -301,7 +301,7 @@
// NSC m_endPoints->DeAllocate (endPoint);
}
-Ipv4L4Protocol::RxStatus
+IpL4Protocol::RxStatus
NscTcpL4Protocol::Receive (Ptr<Packet> packet,
Ipv4Header const &header,
Ptr<Ipv4Interface> incomingInterface)
@@ -335,7 +335,13 @@
delete[] buf;
wakeup ();
- return Ipv4L4Protocol::RX_OK;
+ return IpL4Protocol::RX_OK;
+}
+
+IpL4Protocol::RxStatus
+NscTcpL4Protocol::Receive(Ptr<Packet>, Ipv6Address&, Ipv6Address&, Ptr<Ipv6Interface>)
+{
+ return IpL4Protocol::RX_ENDPOINT_UNREACH;
}
void NscTcpL4Protocol::SoftInterrupt (void)
@@ -457,16 +463,27 @@
}
void
-NscTcpL4Protocol::SetDownTarget (Ipv4L4Protocol::DownTargetCallback callback)
+NscTcpL4Protocol::SetDownTarget (IpL4Protocol::DownTargetCallback callback)
{
m_downTarget = callback;
}
-Ipv4L4Protocol::DownTargetCallback
+void
+NscTcpL4Protocol::SetDownTarget6 (IpL4Protocol::DownTargetCallback6 callback)
+{
+}
+
+IpL4Protocol::DownTargetCallback
NscTcpL4Protocol::GetDownTarget (void) const
{
return m_downTarget;
}
+IpL4Protocol::DownTargetCallback6
+NscTcpL4Protocol::GetDownTarget6 (void) const
+{
+ return (IpL4Protocol::DownTargetCallback6)0;
+}
+
} // namespace ns3
--- a/src/internet/model/nsc-tcp-l4-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/nsc-tcp-l4-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -24,7 +24,7 @@
#include "ns3/ptr.h"
#include "ns3/object-factory.h"
#include "ns3/timer.h"
-#include "ipv4-l4-protocol.h"
+#include "ip-l4-protocol.h"
struct INetStack;
@@ -43,7 +43,7 @@
*
* \brief Nsc wrapper glue, to interface with the Ipv4 protocol underneath.
*/
-class NscTcpL4Protocol : public Ipv4L4Protocol {
+class NscTcpL4Protocol : public IpL4Protocol {
public:
static const uint8_t PROT_NUMBER;
static TypeId GetTypeId (void);
@@ -80,14 +80,20 @@
* \param header IPv4 Header information
* \param incomingInterface The Ipv4Interface it was received on
*/
- virtual Ipv4L4Protocol::RxStatus Receive (Ptr<Packet> p,
+ virtual IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
Ipv4Header const &header,
Ptr<Ipv4Interface> incomingInterface);
+ virtual IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> interface);
- // From Ipv4L4Protocol
- virtual void SetDownTarget (Ipv4L4Protocol::DownTargetCallback cb);
- // From Ipv4L4Protocol
- virtual Ipv4L4Protocol::DownTargetCallback GetDownTarget (void) const;
+ // From IpL4Protocol
+ virtual void SetDownTarget (IpL4Protocol::DownTargetCallback cb);
+ virtual void SetDownTarget6 (IpL4Protocol::DownTargetCallback6 cb);
+ // From IpL4Protocol
+ virtual IpL4Protocol::DownTargetCallback GetDownTarget (void) const;
+ virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const;
protected:
virtual void DoDispose (void);
virtual void NotifyNewAggregate ();
@@ -123,7 +129,7 @@
std::string m_nscLibrary;
Timer m_softTimer;
std::vector<Ptr<NscTcpSocketImpl> > m_sockets;
- Ipv4L4Protocol::DownTargetCallback m_downTarget;
+ IpL4Protocol::DownTargetCallback m_downTarget;
};
} // namespace ns3
--- a/src/internet/model/nsc-tcp-socket-impl.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/nsc-tcp-socket-impl.cc Mon Feb 20 14:05:07 2012 +0100
@@ -214,6 +214,13 @@
m_endPoint = m_tcp->Allocate ();
return FinishBind ();
}
+int
+NscTcpSocketImpl::Bind6 ()
+{
+ NS_LOG_LOGIC ("NscTcpSocketImpl: ERROR_AFNOSUPPORT - Bind6 not supported".);
+ m_errno = ERROR_AFNOSUPPORT;
+ return (-1);
+}
int
NscTcpSocketImpl::Bind (const Address &address)
{
--- a/src/internet/model/nsc-tcp-socket-impl.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/nsc-tcp-socket-impl.h Mon Feb 20 14:05:07 2012 +0100
@@ -68,6 +68,7 @@
virtual enum SocketType GetSocketType (void) const;
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
+ virtual int Bind6 (void);
virtual int Bind (const Address &address);
virtual int Close (void);
virtual int ShutdownSend (void);
--- a/src/internet/model/tcp-header.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/tcp-header.cc Mon Feb 20 14:05:07 2012 +0100
@@ -128,23 +128,67 @@
m_protocol = protocol;
}
+void
+TcpHeader::InitializeChecksum (Ipv6Address source,
+ Ipv6Address destination,
+ uint8_t protocol)
+{
+ m_source = source;
+ m_destination = destination;
+ m_protocol = protocol;
+}
+
+void
+TcpHeader::InitializeChecksum (Address source,
+ Address destination,
+ uint8_t protocol)
+{
+ m_source = source;
+ m_destination = destination;
+ m_protocol = protocol;
+}
+
uint16_t
TcpHeader::CalculateHeaderChecksum (uint16_t size) const
{
- Buffer buf = Buffer (12);
- buf.AddAtStart (12);
+ /* Buffer size must be at least as large as the largest IP pseudo-header */
+ /* [per RFC2460, but without consideration for IPv6 extension hdrs] */
+ /* Src address 16 bytes (more generally, Address::MAX_SIZE) */
+ /* Dst address 16 bytes (more generally, Address::MAX_SIZE) */
+ /* Upper layer pkt len 4 bytes */
+ /* Zero 3 bytes */
+ /* Next header 1 byte */
+
+ uint32_t maxHdrSz = (2 * Address::MAX_SIZE) + 8;
+ Buffer buf = Buffer (maxHdrSz);
+ buf.AddAtStart (maxHdrSz);
Buffer::Iterator it = buf.Begin ();
+ uint32_t hdrSize = 0;
WriteTo (it, m_source);
WriteTo (it, m_destination);
- it.WriteU8 (0); /* protocol */
- it.WriteU8 (m_protocol); /* protocol */
- it.WriteU8 (size >> 8); /* length */
- it.WriteU8 (size & 0xff); /* length */
+ if (Ipv4Address::IsMatchingType(m_source))
+ {
+ it.WriteU8 (0); /* protocol */
+ it.WriteU8 (m_protocol); /* protocol */
+ it.WriteU8 (size >> 8); /* length */
+ it.WriteU8 (size & 0xff); /* length */
+ hdrSize = 12;
+ }
+ else
+ {
+ it.WriteU16 (0);
+ it.WriteU8 (size >> 8); /* length */
+ it.WriteU8 (size & 0xff); /* length */
+ it.WriteU16 (0);
+ it.WriteU8 (0);
+ it.WriteU8 (m_protocol); /* protocol */
+ hdrSize = 40;
+ }
it = buf.Begin ();
/* we don't CompleteChecksum ( ~ ) now */
- return ~(it.CalculateIpChecksum (12));
+ return ~(it.CalculateIpChecksum (hdrSize));
}
bool
--- a/src/internet/model/tcp-header.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/tcp-header.h Mon Feb 20 14:05:07 2012 +0100
@@ -26,6 +26,7 @@
#include "ns3/buffer.h"
#include "ns3/tcp-socket-factory.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
#include "ns3/sequence-number.h"
namespace ns3 {
@@ -132,6 +133,12 @@
void InitializeChecksum (Ipv4Address source,
Ipv4Address destination,
uint8_t protocol);
+ void InitializeChecksum (Ipv6Address source,
+ Ipv6Address destination,
+ uint8_t protocol);
+ void InitializeChecksum (Address source,
+ Address destination,
+ uint8_t protocol);
typedef enum { NONE = 0, FIN = 1, SYN = 2, RST = 4, PSH = 8, ACK = 16,
URG = 32, ECE = 64, CWR = 128} Flags_t;
@@ -160,8 +167,8 @@
uint16_t m_windowSize;
uint16_t m_urgentPointer;
- Ipv4Address m_source;
- Ipv4Address m_destination;
+ Address m_source;
+ Address m_destination;
uint8_t m_protocol;
uint16_t m_initialChecksum;
--- a/src/internet/model/tcp-l4-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/tcp-l4-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -28,12 +28,17 @@
#include "ns3/node.h"
#include "ns3/simulator.h"
#include "ns3/ipv4-route.h"
+#include "ns3/ipv6-route.h"
#include "tcp-l4-protocol.h"
#include "tcp-header.h"
#include "ipv4-end-point-demux.h"
+#include "ipv6-end-point-demux.h"
#include "ipv4-end-point.h"
+#include "ipv6-end-point.h"
#include "ipv4-l3-protocol.h"
+#include "ipv6-l3-protocol.h"
+#include "ipv6-routing-protocol.h"
#include "tcp-socket-factory-impl.h"
#include "tcp-newreno.h"
#include "rtt-estimator.h"
@@ -61,7 +66,7 @@
TcpL4Protocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::TcpL4Protocol")
- .SetParent<Ipv4L4Protocol> ()
+ .SetParent<IpL4Protocol> ()
.AddConstructor<TcpL4Protocol> ()
.AddAttribute ("RttEstimatorType",
"Type of RttEstimator objects.",
@@ -82,7 +87,7 @@
}
TcpL4Protocol::TcpL4Protocol ()
- : m_endPoints (new Ipv4EndPointDemux ())
+ : m_endPoints (new Ipv4EndPointDemux ()), m_endPoints6 (new Ipv6EndPointDemux ())
{
NS_LOG_FUNCTION_NOARGS ();
NS_LOG_LOGIC ("Made a TcpL4Protocol "<<this);
@@ -107,23 +112,36 @@
void
TcpL4Protocol::NotifyNewAggregate ()
{
+ Ptr<Node> node = this->GetObject<Node> ();
+ Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
+ Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol> ();
+
if (m_node == 0)
{
- Ptr<Node> node = this->GetObject<Node> ();
- if (node != 0)
+ if ((node != 0) && (ipv4 != 0 || ipv6 != 0))
{
- Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
- if (ipv4 != 0)
- {
- this->SetNode (node);
- ipv4->Insert (this);
- Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
- tcpFactory->SetTcp (this);
- node->AggregateObject (tcpFactory);
- this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
- }
+ this->SetNode (node);
+ Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
+ tcpFactory->SetTcp (this);
+ node->AggregateObject (tcpFactory);
}
}
+
+ // We set at least one of our 2 down targets to the IPv4/IPv6 send
+ // functions. Since these functions have different prototypes, we
+ // need to keep track of whether we are connected to an IPv4 or
+ // IPv6 lower layer and call the appropriate one.
+
+ if (ipv4 != 0)
+ {
+ ipv4->Insert(this);
+ this->SetDownTarget(MakeCallback(&Ipv4::Send, ipv4));
+ }
+ if (ipv6 != 0)
+ {
+ ipv6->Insert(this);
+ this->SetDownTarget6(MakeCallback(&Ipv6L3Protocol::Send, ipv6));
+ }
Object::NotifyNewAggregate ();
}
@@ -145,9 +163,16 @@
m_endPoints = 0;
}
+ if (m_endPoints6 != 0)
+ {
+ delete m_endPoints6;
+ m_endPoints6 = 0;
+ }
+
m_node = 0;
m_downTarget.Nullify ();
- Ipv4L4Protocol::DoDispose ();
+ m_downTarget6.Nullify ();
+ IpL4Protocol::DoDispose ();
}
Ptr<Socket>
@@ -216,7 +241,51 @@
m_endPoints->DeAllocate (endPoint);
}
-enum Ipv4L4Protocol::RxStatus
+Ipv6EndPoint *
+TcpL4Protocol::Allocate6 (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_endPoints6->Allocate ();
+}
+
+Ipv6EndPoint *
+TcpL4Protocol::Allocate6 (Ipv6Address address)
+{
+ NS_LOG_FUNCTION (this << address);
+ return m_endPoints6->Allocate (address);
+}
+
+Ipv6EndPoint *
+TcpL4Protocol::Allocate6 (uint16_t port)
+{
+ NS_LOG_FUNCTION (this << port);
+ return m_endPoints6->Allocate (port);
+}
+
+Ipv6EndPoint *
+TcpL4Protocol::Allocate6 (Ipv6Address address, uint16_t port)
+{
+ NS_LOG_FUNCTION (this << address << port);
+ return m_endPoints6->Allocate (address, port);
+}
+
+Ipv6EndPoint *
+TcpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
+ Ipv6Address peerAddress, uint16_t peerPort)
+{
+ NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+ return m_endPoints6->Allocate (localAddress, localPort,
+ peerAddress, peerPort);
+}
+
+void
+TcpL4Protocol::DeAllocate (Ipv6EndPoint *endPoint)
+{
+ NS_LOG_FUNCTION (this << endPoint);
+ m_endPoints6->DeAllocate (endPoint);
+}
+
+enum IpL4Protocol::RxStatus
TcpL4Protocol::Receive (Ptr<Packet> packet,
Ipv4Header const &ipHeader,
Ptr<Ipv4Interface> incomingInterface)
@@ -241,7 +310,7 @@
if(!tcpHeader.IsChecksumOk ())
{
NS_LOG_INFO ("Bad checksum, dropping packet!");
- return Ipv4L4Protocol::RX_CSUM_FAILED;
+ return IpL4Protocol::RX_CSUM_FAILED;
}
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
@@ -250,6 +319,15 @@
ipHeader.GetSource (), tcpHeader.GetSourcePort (),incomingInterface);
if (endPoints.empty ())
{
+ if (this->GetObject<Ipv6L3Protocol> () != 0)
+ {
+ NS_LOG_LOGIC (" No Ipv4 endpoints matched on TcpL4Protocol, trying Ipv6 "<<this);
+ Ptr<Ipv6Interface> fakeInterface;
+ Ipv6Address src = Ipv6Address::MakeIpv4MappedAddress (ipHeader.GetSource ());
+ Ipv6Address dst = Ipv6Address::MakeIpv4MappedAddress (ipHeader.GetDestination ());
+ return (this->Receive (packet, src, dst, fakeInterface));
+ }
+
NS_LOG_LOGIC (" No endpoints matched on TcpL4Protocol "<<this);
std::ostringstream oss;
oss<<" destination IP: ";
@@ -279,18 +357,100 @@
header.SetSourcePort (tcpHeader.GetDestinationPort ());
header.SetDestinationPort (tcpHeader.GetSourcePort ());
SendPacket (rstPacket, header, ipHeader.GetDestination (), ipHeader.GetSource ());
- return Ipv4L4Protocol::RX_ENDPOINT_CLOSED;
+ return IpL4Protocol::RX_ENDPOINT_CLOSED;
}
else
{
- return Ipv4L4Protocol::RX_ENDPOINT_CLOSED;
+ return IpL4Protocol::RX_ENDPOINT_CLOSED;
}
}
NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
(*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort (),
incomingInterface);
- return Ipv4L4Protocol::RX_OK;
+ return IpL4Protocol::RX_OK;
+}
+
+enum IpL4Protocol::RxStatus
+TcpL4Protocol::Receive (Ptr<Packet> packet,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst);
+
+ TcpHeader tcpHeader;
+
+ // If we are receving a v4-mapped packet, we will re-calculate the TCP checksum
+ // Is it worth checking every received "v6" packet to see if it is v4-mapped in
+ // order to avoid re-calculating TCP checksums for v4-mapped packets?
+
+ if(Node::ChecksumEnabled ())
+ {
+ tcpHeader.EnableChecksums ();
+ tcpHeader.InitializeChecksum (src, dst, PROT_NUMBER);
+ }
+
+ packet->PeekHeader (tcpHeader);
+
+ NS_LOG_LOGIC ("TcpL4Protocol " << this
+ << " receiving seq " << tcpHeader.GetSequenceNumber ()
+ << " ack " << tcpHeader.GetAckNumber ()
+ << " flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
+ << " data size " << packet->GetSize ());
+
+ if(!tcpHeader.IsChecksumOk ())
+ {
+ NS_LOG_INFO ("Bad checksum, dropping packet!");
+ return IpL4Protocol::RX_CSUM_FAILED;
+ }
+
+ NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
+ Ipv6EndPointDemux::EndPoints endPoints =
+ m_endPoints6->Lookup (dst, tcpHeader.GetDestinationPort (),
+ src, tcpHeader.GetSourcePort (),interface);
+ if (endPoints.empty ())
+ {
+ NS_LOG_LOGIC (" No IPv6 endpoints matched on TcpL4Protocol "<<this);
+ std::ostringstream oss;
+ oss<<" destination IP: ";
+ dst.Print (oss);
+ oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
+ src.Print (oss);
+ oss<<" source port: "<<tcpHeader.GetSourcePort ();
+ NS_LOG_LOGIC (oss.str ());
+
+ if (!(tcpHeader.GetFlags () & TcpHeader::RST))
+ {
+ // build a RST packet and send
+ Ptr<Packet> rstPacket = Create<Packet> ();
+ TcpHeader header;
+ if (tcpHeader.GetFlags () & TcpHeader::ACK)
+ {
+ // ACK bit was set
+ header.SetFlags (TcpHeader::RST);
+ header.SetSequenceNumber (header.GetAckNumber ());
+ }
+ else
+ {
+ header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
+ header.SetSequenceNumber (SequenceNumber32 (0));
+ header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
+ }
+ header.SetSourcePort (tcpHeader.GetDestinationPort ());
+ header.SetDestinationPort (tcpHeader.GetSourcePort ());
+ SendPacket (rstPacket, header, dst, src);
+ return IpL4Protocol::RX_ENDPOINT_CLOSED;
+ }
+ else
+ {
+ return IpL4Protocol::RX_ENDPOINT_CLOSED;
+ }
+ }
+ NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
+ NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
+ (*endPoints.begin ())->ForwardUp (packet, src, dst, tcpHeader.GetSourcePort ());
+ return IpL4Protocol::RX_OK;
}
void
@@ -338,6 +498,50 @@
}
void
+TcpL4Protocol::Send (Ptr<Packet> packet,
+ Ipv6Address saddr, Ipv6Address daddr,
+ uint16_t sport, uint16_t dport, Ptr<NetDevice> oif)
+{
+ NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << oif);
+
+ TcpHeader tcpHeader;
+ tcpHeader.SetDestinationPort (dport);
+ tcpHeader.SetSourcePort (sport);
+ if(Node::ChecksumEnabled ())
+ {
+ tcpHeader.EnableChecksums ();
+ }
+ tcpHeader.InitializeChecksum (saddr,
+ daddr,
+ PROT_NUMBER);
+ tcpHeader.SetFlags (TcpHeader::ACK);
+ tcpHeader.SetAckNumber (SequenceNumber32 (0));
+
+ packet->AddHeader (tcpHeader);
+
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ if (ipv6 != 0)
+ {
+ Ipv6Header header;
+ header.SetDestinationAddress (daddr);
+ header.SetNextHeader (PROT_NUMBER);
+ Socket::SocketErrno errno_;
+ Ptr<Ipv6Route> route;
+ Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
+ if (ipv6->GetRoutingProtocol () != 0)
+ {
+ route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
+ }
+ else
+ {
+ NS_LOG_ERROR ("No IPV6 Routing Protocol");
+ route = 0;
+ }
+ ipv6->Send (packet, saddr, daddr, PROT_NUMBER, route);
+ }
+}
+
+void
TcpL4Protocol::SendPacket (Ptr<Packet> packet, const TcpHeader &outgoing,
Ipv4Address saddr, Ipv4Address daddr, Ptr<NetDevice> oif)
{
@@ -385,16 +589,79 @@
}
void
-TcpL4Protocol::SetDownTarget (Ipv4L4Protocol::DownTargetCallback callback)
+TcpL4Protocol::SendPacket (Ptr<Packet> packet, const TcpHeader &outgoing,
+ Ipv6Address saddr, Ipv6Address daddr, Ptr<NetDevice> oif)
+{
+ NS_LOG_LOGIC ("TcpL4Protocol " << this
+ << " sending seq " << outgoing.GetSequenceNumber ()
+ << " ack " << outgoing.GetAckNumber ()
+ << " flags " << std::hex << (int)outgoing.GetFlags () << std::dec
+ << " data size " << packet->GetSize ());
+ NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
+ // XXX outgoingHeader cannot be logged
+
+ if (daddr.IsIpv4MappedAddress ())
+ {
+ return (SendPacket (packet, outgoing, saddr.GetIpv4MappedAddress(), daddr.GetIpv4MappedAddress(), oif));
+ }
+ TcpHeader outgoingHeader = outgoing;
+ outgoingHeader.SetLength (5); //header length in units of 32bit words
+ /* outgoingHeader.SetUrgentPointer (0); //XXX */
+ if(Node::ChecksumEnabled ())
+ {
+ outgoingHeader.EnableChecksums ();
+ }
+ outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
+
+ packet->AddHeader (outgoingHeader);
+
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ if (ipv6 != 0)
+ {
+ Ipv6Header header;
+ header.SetDestinationAddress (daddr);
+ header.SetSourceAddress (saddr);
+ header.SetNextHeader (PROT_NUMBER);
+ Socket::SocketErrno errno_;
+ Ptr<Ipv6Route> route;
+ if (ipv6->GetRoutingProtocol () != 0)
+ {
+ route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
+ }
+ else
+ {
+ NS_LOG_ERROR ("No IPV6 Routing Protocol");
+ route = 0;
+ }
+ m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, route);
+ }
+ else
+ NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv6 interface");
+}
+
+void
+TcpL4Protocol::SetDownTarget (IpL4Protocol::DownTargetCallback callback)
{
m_downTarget = callback;
}
-Ipv4L4Protocol::DownTargetCallback
+IpL4Protocol::DownTargetCallback
TcpL4Protocol::GetDownTarget (void) const
{
return m_downTarget;
}
+void
+TcpL4Protocol::SetDownTarget6 (IpL4Protocol::DownTargetCallback6 callback)
+{
+ m_downTarget6 = callback;
+}
+
+IpL4Protocol::DownTargetCallback6
+TcpL4Protocol::GetDownTarget6 (void) const
+{
+ return m_downTarget6;
+}
+
} // namespace ns3
--- a/src/internet/model/tcp-l4-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/tcp-l4-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -25,9 +25,10 @@
#include "ns3/packet.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
#include "ns3/ptr.h"
#include "ns3/object-factory.h"
-#include "ipv4-l4-protocol.h"
+#include "ip-l4-protocol.h"
#include "ns3/net-device.h"
namespace ns3 {
@@ -36,9 +37,11 @@
class Socket;
class TcpHeader;
class Ipv4EndPointDemux;
+class Ipv6EndPointDemux;
class Ipv4Interface;
class TcpSocketBase;
class Ipv4EndPoint;
+class Ipv6EndPoint;
/**
* \ingroup tcp
@@ -50,7 +53,7 @@
* packets from IP, and forwards them up to the endpoints.
*/
-class TcpL4Protocol : public Ipv4L4Protocol {
+class TcpL4Protocol : public IpL4Protocol {
public:
static TypeId GetTypeId (void);
static const uint8_t PROT_NUMBER;
@@ -77,8 +80,15 @@
Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort);
+ Ipv6EndPoint *Allocate6 (void);
+ Ipv6EndPoint *Allocate6 (Ipv6Address address);
+ Ipv6EndPoint *Allocate6 (uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ipv6Address address, uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ipv6Address localAddress, uint16_t localPort,
+ Ipv6Address peerAddress, uint16_t peerPort);
void DeAllocate (Ipv4EndPoint *endPoint);
+ void DeAllocate (Ipv6EndPoint *endPoint);
/**
* \brief Send a packet via TCP
@@ -92,20 +102,29 @@
void Send (Ptr<Packet> packet,
Ipv4Address saddr, Ipv4Address daddr,
uint16_t sport, uint16_t dport, Ptr<NetDevice> oif = 0);
+ void Send (Ptr<Packet> packet,
+ Ipv6Address saddr, Ipv6Address daddr,
+ uint16_t sport, uint16_t dport, Ptr<NetDevice> oif = 0);
/**
* \brief Receive a packet up the protocol stack
* \param p The Packet to dump the contents into
* \param header IPv4 Header information
* \param incomingInterface The Ipv4Interface it was received on
*/
- virtual enum Ipv4L4Protocol::RxStatus Receive (Ptr<Packet> p,
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
Ipv4Header const &header,
Ptr<Ipv4Interface> incomingInterface);
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> interface);
- // From Ipv4L4Protocol
- virtual void SetDownTarget (Ipv4L4Protocol::DownTargetCallback cb);
- // From Ipv4L4Protocol
- virtual Ipv4L4Protocol::DownTargetCallback GetDownTarget (void) const;
+ // From IpL4Protocol
+ virtual void SetDownTarget (IpL4Protocol::DownTargetCallback cb);
+ virtual void SetDownTarget6 (IpL4Protocol::DownTargetCallback6 cb);
+ // From IpL4Protocol
+ virtual IpL4Protocol::DownTargetCallback GetDownTarget (void) const;
+ virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const;
protected:
virtual void DoDispose (void);
@@ -117,17 +136,21 @@
private:
Ptr<Node> m_node;
Ipv4EndPointDemux *m_endPoints;
+ Ipv6EndPointDemux *m_endPoints6;
TypeId m_rttTypeId;
TypeId m_socketTypeId;
private:
friend class TcpSocketBase;
void SendPacket (Ptr<Packet>, const TcpHeader &,
Ipv4Address, Ipv4Address, Ptr<NetDevice> oif = 0);
+ void SendPacket (Ptr<Packet>, const TcpHeader &,
+ Ipv6Address, Ipv6Address, Ptr<NetDevice> oif = 0);
TcpL4Protocol (const TcpL4Protocol &o);
TcpL4Protocol &operator = (const TcpL4Protocol &o);
std::vector<Ptr<TcpSocketBase> > m_sockets;
- Ipv4L4Protocol::DownTargetCallback m_downTarget;
+ IpL4Protocol::DownTargetCallback m_downTarget;
+ IpL4Protocol::DownTargetCallback6 m_downTarget6;
};
} // namespace ns3
--- a/src/internet/model/tcp-socket-base.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/tcp-socket-base.cc Mon Feb 20 14:05:07 2012 +0100
@@ -25,11 +25,15 @@
#include "ns3/abort.h"
#include "ns3/node.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/log.h"
#include "ns3/ipv4.h"
+#include "ns3/ipv6.h"
#include "ns3/ipv4-interface-address.h"
#include "ns3/ipv4-route.h"
+#include "ns3/ipv6-route.h"
#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/ipv6-routing-protocol.h"
#include "ns3/simulation-singleton.h"
#include "ns3/simulator.h"
#include "ns3/packet.h"
@@ -39,6 +43,8 @@
#include "tcp-socket-base.h"
#include "tcp-l4-protocol.h"
#include "ipv4-end-point.h"
+#include "ipv6-end-point.h"
+#include "ipv6-l3-protocol.h"
#include "tcp-header.h"
#include "rtt-estimator.h"
@@ -95,6 +101,7 @@
: m_dupAckCount (0),
m_delAckCount (0),
m_endPoint (0),
+ m_endPoint6 (0),
m_node (0),
m_tcp (0),
m_rtt (0),
@@ -126,6 +133,7 @@
m_persistTimeout (sock.m_persistTimeout),
m_cnTimeout (sock.m_cnTimeout),
m_endPoint (0),
+ m_endPoint6 (0),
m_node (sock.m_node),
m_tcp (sock.m_tcp),
m_rtt (0),
@@ -180,6 +188,13 @@
m_tcp->DeAllocate (m_endPoint);
NS_ASSERT (m_endPoint == 0);
}
+ if (m_endPoint6 != 0)
+ {
+ NS_ASSERT (m_tcp != 0);
+ NS_ASSERT (m_endPoint6 != 0);
+ m_tcp->DeAllocate (m_endPoint6);
+ NS_ASSERT (m_endPoint6 == 0);
+ }
m_tcp = 0;
CancelAllTimers ();
}
@@ -233,7 +248,8 @@
{
NS_LOG_FUNCTION_NOARGS ();
m_endPoint = m_tcp->Allocate ();
- if (0 == m_endPoint)
+ m_endPoint6 = m_tcp->Allocate6 ();
+ if (0 == m_endPoint || 0 == m_endPoint6)
{
m_errno = ERROR_ADDRNOTAVAIL;
return -1;
@@ -242,40 +258,76 @@
return SetupCallback ();
}
+int
+TcpSocketBase::Bind6 (void)
+{
+ return Bind ();
+}
+
/** Inherit from Socket class: Bind socket (with specific address) to an end-point in TcpL4Protocol */
int
TcpSocketBase::Bind (const Address &address)
{
NS_LOG_FUNCTION (this << address);
- if (!InetSocketAddress::IsMatchingType (address))
+ if (InetSocketAddress::IsMatchingType (address))
+ {
+ InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+ Ipv4Address ipv4 = transport.GetIpv4 ();
+ uint16_t port = transport.GetPort ();
+ if (ipv4 == Ipv4Address::GetAny () && port == 0)
+ {
+ m_endPoint = m_tcp->Allocate ();
+ }
+ else if (ipv4 == Ipv4Address::GetAny () && port != 0)
+ {
+ m_endPoint = m_tcp->Allocate (port);
+ }
+ else if (ipv4 != Ipv4Address::GetAny () && port == 0)
+ {
+ m_endPoint = m_tcp->Allocate (ipv4);
+ }
+ else if (ipv4 != Ipv4Address::GetAny () && port != 0)
+ {
+ m_endPoint = m_tcp->Allocate (ipv4, port);
+ }
+ if (0 == m_endPoint)
+ {
+ m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
+ return -1;
+ }
+ }
+ else if (Inet6SocketAddress::IsMatchingType (address))
+ {
+ Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
+ Ipv6Address ipv6 = transport.GetIpv6 ();
+ uint16_t port = transport.GetPort ();
+ if (ipv6 == Ipv6Address::GetAny () && port == 0)
+ {
+ m_endPoint6 = m_tcp->Allocate6 ();
+ }
+ else if (ipv6 == Ipv6Address::GetAny () && port != 0)
+ {
+ m_endPoint6 = m_tcp->Allocate6 (port);
+ }
+ else if (ipv6 != Ipv6Address::GetAny () && port == 0)
+ {
+ m_endPoint6 = m_tcp->Allocate6 (ipv6);
+ }
+ else if (ipv6 != Ipv6Address::GetAny () && port != 0)
+ {
+ m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
+ }
+ if (0 == m_endPoint6)
+ {
+ m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
+ return -1;
+ }
+ }
+ else
{
m_errno = ERROR_INVAL;
return -1;
}
- InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- Ipv4Address ipv4 = transport.GetIpv4 ();
- uint16_t port = transport.GetPort ();
- if (ipv4 == Ipv4Address::GetAny () && port == 0)
- {
- m_endPoint = m_tcp->Allocate ();
- }
- else if (ipv4 == Ipv4Address::GetAny () && port != 0)
- {
- m_endPoint = m_tcp->Allocate (port);
- }
- else if (ipv4 != Ipv4Address::GetAny () && port == 0)
- {
- m_endPoint = m_tcp->Allocate (ipv4);
- }
- else if (ipv4 != Ipv4Address::GetAny () && port != 0)
- {
- m_endPoint = m_tcp->Allocate (ipv4, port);
- }
- if (0 == m_endPoint)
- {
- m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
- return -1;
- }
m_tcp->m_sockets.push_back (this);
NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
@@ -289,22 +341,60 @@
NS_LOG_FUNCTION (this << address);
// If haven't do so, Bind() this socket first
- if (m_endPoint == 0)
+ if (InetSocketAddress::IsMatchingType (address))
{
- if (Bind () == -1)
+ if (m_endPoint == 0)
{
- NS_ASSERT (m_endPoint == 0);
- return -1; // Bind() failed
+ if (Bind () == -1)
+ {
+ NS_ASSERT (m_endPoint == 0);
+ return -1; // Bind() failed
+ }
+ NS_ASSERT (m_endPoint != 0);
+ }
+ InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+ m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
+ m_endPoint6 = 0;
+
+ // Get the appropriate local address and port number from the routing protocol and set up endpoint
+ if (SetupEndpoint () != 0)
+ { // Route to destination does not exist
+ return -1;
}
- NS_ASSERT (m_endPoint != 0);
}
+ else if (Inet6SocketAddress::IsMatchingType (address) )
+ {
+ // If we are operating on a v4-mapped address, translate the address to
+ // a v4 address and re-call this function
+ Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
+ Ipv6Address v6Addr = transport.GetIpv6 ();
+ if (v6Addr.IsIpv4MappedAddress () == true)
+ {
+ Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
+ return Connect(InetSocketAddress(v4Addr, transport.GetPort ()));
+ }
- InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
+ if (m_endPoint6 == 0)
+ {
+ if (Bind6 () == -1)
+ {
+ NS_ASSERT (m_endPoint6 == 0);
+ return -1; // Bind() failed
+ }
+ NS_ASSERT (m_endPoint6 != 0);
+ }
+ m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
+ m_endPoint = 0;
- // Get the appropriate local address and port number from the routing protocol and set up endpoint
- if (SetupEndpoint () != 0)
- { // Route to destination does not exist
+ // Get the appropriate local address and port number from the routing protocol and set up endpoint
+ if (SetupEndpoint6 () != 0)
+ { // Route to destination does not exist
+ return -1;
+ }
+ }
+ else
+ {
+ m_errno = ERROR_INVAL;
return -1;
}
@@ -427,7 +517,14 @@
if (outPacket != 0 && outPacket->GetSize () != 0)
{
SocketAddressTag tag;
- tag.SetAddress (InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ()));
+ if (m_endPoint != 0)
+ {
+ tag.SetAddress (InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ()));
+ }
+ else if (m_endPoint6 != 0)
+ {
+ tag.SetAddress (Inet6SocketAddress (m_endPoint6->GetPeerAddress (), m_endPoint6->GetPeerPort ()));
+ }
outPacket->AddPacketTag (tag);
}
return outPacket;
@@ -446,6 +543,10 @@
{
fromAddress = InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
}
+ else if (m_endPoint6 != 0)
+ {
+ fromAddress = Inet6SocketAddress (m_endPoint6->GetPeerAddress (), m_endPoint6->GetPeerPort ());
+ }
else
{
fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
@@ -479,9 +580,14 @@
{
address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->GetLocalPort ());
}
+ else if (m_endPoint6 != 0)
+ {
+ address = Inet6SocketAddress (m_endPoint6->GetLocalAddress (), m_endPoint6->GetLocalPort ());
+ }
else
{ // It is possible to call this method on a socket without a name
// in which case, behavior is unspecified
+ // Should this return an InetSocketAddress or an Inet6SocketAddress?
address = InetSocketAddress (Ipv4Address::GetZero (), 0);
}
return 0;
@@ -493,16 +599,21 @@
{
NS_LOG_FUNCTION (netdevice);
Socket::BindToNetDevice (netdevice); // Includes sanity check
- if (m_endPoint == 0)
+ if (m_endPoint == 0 && m_endPoint6 == 0)
{
if (Bind () == -1)
{
- NS_ASSERT (m_endPoint == 0);
+ NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
return;
}
- NS_ASSERT (m_endPoint != 0);
+ NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
}
- m_endPoint->BindToNetDevice (netdevice);
+
+ if (m_endPoint != 0)
+ {
+ m_endPoint->BindToNetDevice (netdevice);
+ }
+ // No BindToNetDevice() for Ipv6EndPoint
return;
}
@@ -511,12 +622,22 @@
TcpSocketBase::SetupCallback (void)
{
NS_LOG_FUNCTION (this);
- if (m_endPoint == 0)
+
+ if (m_endPoint == 0 && m_endPoint6 == 0)
{
return -1;
}
- m_endPoint->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr<TcpSocketBase> (this)));
- m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
+ if (m_endPoint != 0)
+ {
+ m_endPoint->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr<TcpSocketBase> (this)));
+ m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
+ }
+ if (m_endPoint6 != 0)
+ {
+ m_endPoint6->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp6, Ptr<TcpSocketBase> (this)));
+ m_endPoint6->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
+ }
+
return 0;
}
@@ -629,6 +750,12 @@
DoForwardUp (packet, header, port, incomingInterface);
}
+void
+TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port)
+{
+ DoForwardUp (packet, saddr, daddr, port);
+}
+
/** The real function to handle the incoming packet from lower layers. This is
wrapped by ForwardUp() so that this function can be overloaded by daughter
classes. */
@@ -728,6 +855,101 @@
}
}
+void
+TcpSocketBase::DoForwardUp (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port)
+{
+ NS_LOG_LOGIC ("Socket " << this << " forward up " <<
+ m_endPoint6->GetPeerAddress () <<
+ ":" << m_endPoint6->GetPeerPort () <<
+ " to " << m_endPoint6->GetLocalAddress () <<
+ ":" << m_endPoint6->GetLocalPort ());
+ Address fromAddress = Inet6SocketAddress (saddr, port);
+ Address toAddress = Inet6SocketAddress (daddr, m_endPoint6->GetLocalPort ());
+
+ // Peel off TCP header and do validity checking
+ TcpHeader tcpHeader;
+ packet->RemoveHeader (tcpHeader);
+ if (tcpHeader.GetFlags () & TcpHeader::ACK)
+ {
+ EstimateRtt (tcpHeader);
+ }
+ ReadOptions (tcpHeader);
+
+ // Update Rx window size, i.e. the flow control window
+ if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
+ { // persist probes end
+ NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
+ m_persistEvent.Cancel ();
+ }
+ m_rWnd = tcpHeader.GetWindowSize ();
+
+ // Discard fully out of range packets
+ if (packet->GetSize () &&
+ OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
+ {
+ NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
+ " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
+ ":" << tcpHeader.GetSequenceNumber () + packet->GetSize() <<
+ ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
+ m_rxBuffer.MaxRxSequence () << ")");
+ // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
+ if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
+ {
+ SendEmptyPacket (TcpHeader::ACK);
+ }
+ return;
+ }
+
+ // TCP state machine code in different process functions
+ // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
+ switch (m_state)
+ {
+ case ESTABLISHED:
+ ProcessEstablished (packet, tcpHeader);
+ break;
+ case LISTEN:
+ ProcessListen (packet, tcpHeader, fromAddress, toAddress);
+ break;
+ case TIME_WAIT:
+ // Do nothing
+ break;
+ case CLOSED:
+ // Send RST if the incoming packet is not a RST
+ if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
+ { // Since m_endPoint is not configured yet, we cannot use SendRST here
+ TcpHeader h;
+ h.SetFlags (TcpHeader::RST);
+ h.SetSequenceNumber (m_nextTxSequence);
+ h.SetAckNumber (m_rxBuffer.NextRxSequence ());
+ h.SetSourcePort (tcpHeader.GetDestinationPort ());
+ h.SetDestinationPort (tcpHeader.GetSourcePort ());
+ h.SetWindowSize (AdvertisedWindowSize ());
+ AddOptions (h);
+ m_tcp->SendPacket (Create<Packet> (), h, daddr, saddr, m_boundnetdevice);
+ }
+ break;
+ case SYN_SENT:
+ ProcessSynSent (packet, tcpHeader);
+ break;
+ case SYN_RCVD:
+ ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
+ break;
+ case FIN_WAIT_1:
+ case FIN_WAIT_2:
+ case CLOSE_WAIT:
+ ProcessWait (packet, tcpHeader);
+ break;
+ case CLOSING:
+ ProcessClosing (packet, tcpHeader);
+ break;
+ case LAST_ACK:
+ ProcessLastAck (packet, tcpHeader);
+ break;
+ default: // mute compiler
+ break;
+ }
+}
+
/** Received a packet upon ESTABLISHED state. This function is mimicking the
role of tcp_rcv_established() in tcp_input.c in Linux kernel. */
void
@@ -915,8 +1137,16 @@
m_retxEvent.Cancel ();
m_highTxMark = ++m_nextTxSequence;
m_txBuffer.SetHeadSequence (m_nextTxSequence);
- m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
- InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ if (m_endPoint)
+ {
+ m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ }
+ else if (m_endPoint6)
+ {
+ m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
+ Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
+ }
// Always respond to first data packet to speed up the connection.
// Remove to get the behaviour of old NS-3 code.
m_delAckCount = m_delAckMaxCount;
@@ -941,8 +1171,16 @@
m_retxEvent.Cancel ();
m_highTxMark = ++m_nextTxSequence;
m_txBuffer.SetHeadSequence (m_nextTxSequence);
- m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
- InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ if (m_endPoint)
+ {
+ m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ }
+ else if (m_endPoint6)
+ {
+ m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
+ Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
+ }
PeerClose (packet, tcpHeader);
}
}
@@ -951,8 +1189,16 @@
if (tcpflags != TcpHeader::RST)
{ // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
- m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
- InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ if (m_endPoint)
+ {
+ m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ }
+ else if (m_endPoint6)
+ {
+ m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
+ Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
+ }
SendRST ();
}
CloseAndNotify ();
@@ -1178,13 +1424,17 @@
NS_LOG_FUNCTION (this);
m_node = 0;
m_endPoint = 0;
- std::vector<Ptr<TcpSocketBase> >::iterator it
- = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
- if (it != m_tcp->m_sockets.end ())
+ m_endPoint6 = 0;
+ if (m_tcp != 0)
{
- m_tcp->m_sockets.erase (it);
+ std::vector<Ptr<TcpSocketBase> >::iterator it
+ = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
+ if (it != m_tcp->m_sockets.end ())
+ {
+ m_tcp->m_sockets.erase (it);
+ }
+ m_tcp = 0;
}
- m_tcp = 0;
NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
(Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
CancelAllTimers ();
@@ -1199,7 +1449,7 @@
TcpHeader header;
SequenceNumber32 s = m_nextTxSequence;
- if (m_endPoint == 0)
+ if (m_endPoint == 0 && m_endPoint6 == 0)
{
NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
return;
@@ -1216,8 +1466,16 @@
header.SetFlags (flags);
header.SetSequenceNumber (s);
header.SetAckNumber (m_rxBuffer.NextRxSequence ());
- header.SetSourcePort (m_endPoint->GetLocalPort ());
- header.SetDestinationPort (m_endPoint->GetPeerPort ());
+ if (m_endPoint != 0)
+ {
+ header.SetSourcePort (m_endPoint->GetLocalPort ());
+ header.SetDestinationPort (m_endPoint->GetPeerPort ());
+ }
+ else
+ {
+ header.SetSourcePort (m_endPoint6->GetLocalPort ());
+ header.SetDestinationPort (m_endPoint6->GetPeerPort ());
+ }
header.SetWindowSize (AdvertisedWindowSize ());
AddOptions (header);
m_rto = m_rtt->RetransmitTimeout ();
@@ -1239,7 +1497,16 @@
m_cnCount--;
}
}
- m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ if (m_endPoint != 0)
+ {
+ m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
+ m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ }
+ else
+ {
+ m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
+ m_endPoint6->GetPeerAddress (), m_boundnetdevice);
+ }
if (flags & TcpHeader::ACK)
{ // If sending an ACK, cancel the delay ACK as well
m_delAckEvent.Cancel ();
@@ -1281,6 +1548,19 @@
}
CancelAllTimers ();
}
+ if (m_endPoint6 != 0)
+ {
+ m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
+ m_tcp->DeAllocate (m_endPoint6);
+ m_endPoint6 = 0;
+ std::vector<Ptr<TcpSocketBase> >::iterator it
+ = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
+ if (it != m_tcp->m_sockets.end ())
+ {
+ m_tcp->m_sockets.erase (it);
+ }
+ CancelAllTimers ();
+ }
}
/** Configure the endpoint to a local address. Called by Connect() if Bind() didn't specify one. */
@@ -1314,6 +1594,36 @@
return 0;
}
+int
+TcpSocketBase::SetupEndpoint6 ()
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ NS_ASSERT (ipv6 != 0);
+ if (ipv6->GetRoutingProtocol () == 0)
+ {
+ NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
+ }
+ // Create a dummy packet, then ask the routing function for the best output
+ // interface's address
+ Ipv6Header header;
+ header.SetDestinationAddress (m_endPoint6->GetPeerAddress ());
+ Socket::SocketErrno errno_;
+ Ptr<Ipv6Route> route;
+ Ptr<NetDevice> oif = m_boundnetdevice;
+ route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
+ if (route == 0)
+ {
+ NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
+ NS_LOG_ERROR (errno_);
+ m_errno = errno_;
+ return -1;
+ }
+ NS_LOG_LOGIC ("Route exists");
+ m_endPoint6->SetLocalAddress (route->GetSource ());
+ return 0;
+}
+
/** This function is called only if a SYN received in LISTEN state. After
TcpSocketBase cloned, allocate a new end point to handle the incoming
connection and send a SYN+ACK to complete the handshake. */
@@ -1322,10 +1632,22 @@
const Address& fromAddress, const Address& toAddress)
{
// Get port and address from peer (connecting host)
- m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
- InetSocketAddress::ConvertFrom (toAddress).GetPort (),
- InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
- InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ if (InetSocketAddress::IsMatchingType (toAddress))
+ {
+ m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (toAddress).GetPort (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ m_endPoint6 = 0;
+ }
+ else if (Inet6SocketAddress::IsMatchingType (toAddress))
+ {
+ m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
+ Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
+ Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
+ Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
+ m_endPoint = 0;
+ }
m_tcp->m_sockets.push_back (this);
// Change the cloned socket from LISTEN state to SYN_RCVD
@@ -1381,8 +1703,16 @@
header.SetFlags (flags);
header.SetSequenceNumber (seq);
header.SetAckNumber (m_rxBuffer.NextRxSequence ());
- header.SetSourcePort (m_endPoint->GetLocalPort ());
- header.SetDestinationPort (m_endPoint->GetPeerPort ());
+ if (m_endPoint)
+ {
+ header.SetSourcePort (m_endPoint->GetLocalPort ());
+ header.SetDestinationPort (m_endPoint->GetPeerPort ());
+ }
+ else
+ {
+ header.SetSourcePort (m_endPoint6->GetLocalPort ());
+ header.SetDestinationPort (m_endPoint6->GetPeerPort ());
+ }
header.SetWindowSize (AdvertisedWindowSize ());
AddOptions (header);
if (m_retxEvent.IsExpired () )
@@ -1394,8 +1724,16 @@
m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
}
NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
- m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
- m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ if (m_endPoint)
+ {
+ m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
+ m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ }
+ else
+ {
+ m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
+ m_endPoint6->GetPeerAddress (), m_boundnetdevice);
+ }
m_rtt->SentSeq (seq, sz); // notify the RTT
// Notify the application of the data being sent unless this is a retransmit
if (seq == m_nextTxSequence)
@@ -1415,7 +1753,8 @@
{
NS_LOG_FUNCTION (this << withAck);
if (m_txBuffer.Size () == 0) return false; // Nothing to send
- if (m_endPoint == 0)
+
+ if (m_endPoint == 0 && m_endPoint6 == 0)
{
NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
return false; // Is this the right way to handle this condition?
@@ -1438,7 +1777,7 @@
m_errno = ERROR_SHUTDOWN;
return false;
}
- // Stop sending if we need to wait for a larger Tx window
+ // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
if (w < m_segmentSize && m_txBuffer.SizeFromSequence (m_nextTxSequence) > w)
{
break; // No more
@@ -1664,13 +2003,29 @@
TcpHeader tcpHeader;
tcpHeader.SetSequenceNumber (m_nextTxSequence);
tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
- tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
- tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
tcpHeader.SetWindowSize (AdvertisedWindowSize ());
+ if (m_endPoint != 0)
+ {
+ tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
+ tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
+ }
+ else
+ {
+ tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
+ tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
+ }
AddOptions (tcpHeader);
- m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
- m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ if (m_endPoint != 0)
+ {
+ m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
+ m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ }
+ else
+ {
+ m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
+ m_endPoint6->GetPeerAddress (), m_boundnetdevice);
+ }
NS_LOG_LOGIC ("Schedule persist timeout at time "
<< Simulator::Now ().GetSeconds () << " to expire at time "
<< (Simulator::Now () + m_persistTimeout).GetSeconds ());
--- a/src/internet/model/tcp-socket-base.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/tcp-socket-base.h Mon Feb 20 14:05:07 2012 +0100
@@ -38,6 +38,7 @@
namespace ns3 {
class Ipv4EndPoint;
+class Ipv6EndPoint;
class Node;
class Packet;
class TcpL4Protocol;
@@ -81,6 +82,7 @@
virtual enum SocketType GetSocketType (void) const; // returns socket type
virtual Ptr<Node> GetNode (void) const; // returns m_node
virtual int Bind (void); // Bind a socket by setting up endpoint in TcpL4Protocol
+ virtual int Bind6 (void); // Bind a socket by setting up endpoint in TcpL4Protocol
virtual int Bind (const Address &address); // ... endpoint of specific addr or port
virtual int Connect (const Address &address); // Setup endpoint and call ProcessAction() to connect
virtual int Listen (void); // Verify the socket is in a correct state and call ProcessAction() to listen
@@ -128,11 +130,14 @@
int DoConnect (void); // Sending a SYN packet to make a connection if the state allows
void ConnectionSucceeded (void); // Schedule-friendly wrapper for Socket::NotifyConnectionSucceeded()
int SetupEndpoint (void); // Configure m_endpoint for local addr for given remote addr
+ int SetupEndpoint6 (void); // Configure m_endpoint6 for local addr for given remote addr
void CompleteFork (Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAdress);
// Helper functions: Transfer operation
void ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface);
+ void ForwardUp6 (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port);
virtual void DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface); //Get a pkt from L3
+ virtual void DoForwardUp (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port); // Ipv6 version
bool SendPendingData (bool withAck = false); // Send as much as the window allows
uint32_t SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck); // Send a data packet
void SendEmptyPacket (uint8_t flags); // Send a empty packet that carries a flag, e.g. ACK
@@ -202,6 +207,7 @@
// Connections to other layers of TCP/IP
Ipv4EndPoint* m_endPoint;
+ Ipv6EndPoint* m_endPoint6;
Ptr<Node> m_node;
Ptr<TcpL4Protocol> m_tcp;
--- a/src/internet/model/udp-header.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/udp-header.cc Mon Feb 20 14:05:07 2012 +0100
@@ -70,9 +70,27 @@
{
return m_destinationPort;
}
+void
+UdpHeader::InitializeChecksum (Address source,
+ Address destination,
+ uint8_t protocol)
+{
+ m_source = source;
+ m_destination = destination;
+ m_protocol = protocol;
+}
+void
+UdpHeader::InitializeChecksum (Ipv4Address source,
+ Ipv4Address destination,
+ uint8_t protocol)
+{
+ m_source = source;
+ m_destination = destination;
+ m_protocol = protocol;
+}
void
-UdpHeader::InitializeChecksum (Ipv4Address source,
- Ipv4Address destination,
+UdpHeader::InitializeChecksum (Ipv6Address source,
+ Ipv6Address destination,
uint8_t protocol)
{
m_source = source;
@@ -82,20 +100,35 @@
uint16_t
UdpHeader::CalculateHeaderChecksum (uint16_t size) const
{
- Buffer buf = Buffer (12);
- buf.AddAtStart (12);
+ Buffer buf = Buffer ((2 * Address::MAX_SIZE) + 8);
+ buf.AddAtStart ((2 * Address::MAX_SIZE) + 8);
Buffer::Iterator it = buf.Begin ();
+ uint32_t hdrSize = 0;
WriteTo (it, m_source);
WriteTo (it, m_destination);
- it.WriteU8 (0); /* protocol */
- it.WriteU8 (m_protocol); /* protocol */
- it.WriteU8 (size >> 8); /* length */
- it.WriteU8 (size & 0xff); /* length */
+ if (Ipv4Address::IsMatchingType(m_source))
+ {
+ it.WriteU8 (0); /* protocol */
+ it.WriteU8 (m_protocol); /* protocol */
+ it.WriteU8 (size >> 8); /* length */
+ it.WriteU8 (size & 0xff); /* length */
+ hdrSize = 12;
+ }
+ else if (Ipv6Address::IsMatchingType(m_source))
+ {
+ it.WriteU16 (0);
+ it.WriteU8 (size >> 8); /* length */
+ it.WriteU8 (size & 0xff); /* length */
+ it.WriteU16 (0);
+ it.WriteU8 (0);
+ it.WriteU8 (m_protocol); /* protocol */
+ hdrSize = 40;
+ }
it = buf.Begin ();
/* we don't CompleteChecksum ( ~ ) now */
- return ~(it.CalculateIpChecksum (12));
+ return ~(it.CalculateIpChecksum (hdrSize));
}
bool
--- a/src/internet/model/udp-header.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/udp-header.h Mon Feb 20 14:05:07 2012 +0100
@@ -25,6 +25,7 @@
#include <string>
#include "ns3/header.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
namespace ns3 {
/**
@@ -79,10 +80,40 @@
* If you want to use udp checksums, you should call this
* method prior to adding the header to a packet.
*/
+ void InitializeChecksum (Address source,
+ Address destination,
+ uint8_t protocol);
+
+ /**
+ * \param source the ip source to use in the underlying
+ * ip packet.
+ * \param destination the ip destination to use in the
+ * underlying ip packet.
+ * \param protocol the protocol number to use in the underlying
+ * ip packet.
+ *
+ * If you want to use udp checksums, you should call this
+ * method prior to adding the header to a packet.
+ */
void InitializeChecksum (Ipv4Address source,
Ipv4Address destination,
uint8_t protocol);
+ /**
+ * \param source the ip source to use in the underlying
+ * ip packet.
+ * \param destination the ip destination to use in the
+ * underlying ip packet.
+ * \param protocol the protocol number to use in the underlying
+ * ip packet.
+ *
+ * If you want to use udp checksums, you should call this
+ * method prior to adding the header to a packet.
+ */
+ void InitializeChecksum (Ipv6Address source,
+ Ipv6Address destination,
+ uint8_t protocol);
+
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual void Print (std::ostream &os) const;
@@ -102,8 +133,8 @@
uint16_t m_destinationPort;
uint16_t m_payloadSize;
- Ipv4Address m_source;
- Ipv4Address m_destination;
+ Address m_source;
+ Address m_destination;
uint8_t m_protocol;
bool m_calcChecksum;
bool m_goodChecksum;
--- a/src/internet/model/udp-l4-protocol.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/udp-l4-protocol.cc Mon Feb 20 14:05:07 2012 +0100
@@ -24,14 +24,20 @@
#include "ns3/node.h"
#include "ns3/boolean.h"
#include "ns3/object-vector.h"
+#include "ns3/ipv6.h"
#include "ns3/ipv4-route.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-header.h"
#include "udp-l4-protocol.h"
#include "udp-header.h"
#include "udp-socket-factory-impl.h"
#include "ipv4-end-point-demux.h"
#include "ipv4-end-point.h"
+#include "ipv6-end-point-demux.h"
+#include "ipv6-end-point.h"
#include "ipv4-l3-protocol.h"
+#include "ipv6-l3-protocol.h"
#include "udp-socket-impl.h"
NS_LOG_COMPONENT_DEFINE ("UdpL4Protocol");
@@ -47,7 +53,7 @@
UdpL4Protocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::UdpL4Protocol")
- .SetParent<Ipv4L4Protocol> ()
+ .SetParent<IpL4Protocol> ()
.AddConstructor<UdpL4Protocol> ()
.AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
ObjectVectorValue (),
@@ -58,7 +64,7 @@
}
UdpL4Protocol::UdpL4Protocol ()
- : m_endPoints (new Ipv4EndPointDemux ())
+ : m_endPoints (new Ipv4EndPointDemux ()), m_endPoints6 (new Ipv6EndPointDemux ())
{
NS_LOG_FUNCTION_NOARGS ();
}
@@ -82,23 +88,36 @@
void
UdpL4Protocol::NotifyNewAggregate ()
{
+ Ptr<Node> node = this->GetObject<Node> ();
+ Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
+ Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol> ();
+
if (m_node == 0)
{
- Ptr<Node> node = this->GetObject<Node> ();
- if (node != 0)
+ if ((node != 0) && (ipv4 != 0 || ipv6 != 0))
{
- Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
- if (ipv4 != 0)
- {
- this->SetNode (node);
- ipv4->Insert (this);
- Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
- udpFactory->SetUdp (this);
- node->AggregateObject (udpFactory);
- this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
- }
+ this->SetNode (node);
+ Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
+ udpFactory->SetUdp (this);
+ node->AggregateObject (udpFactory);
}
}
+
+ // We set at least one of our 2 down targets to the IPv4/IPv6 send
+ // functions. Since these functions have different prototypes, we
+ // need to keep track of whether we are connected to an IPv4 or
+ // IPv6 lower layer and call the appropriate one.
+
+ if (ipv4 != 0)
+ {
+ ipv4->Insert (this);
+ this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
+ }
+ if (ipv6 != 0)
+ {
+ ipv6->Insert (this);
+ this->SetDownTarget6 (MakeCallback (&Ipv6L3Protocol::Send, ipv6));
+ }
Object::NotifyNewAggregate ();
}
@@ -124,12 +143,18 @@
delete m_endPoints;
m_endPoints = 0;
}
+ if (m_endPoints6 != 0)
+ {
+ delete m_endPoints6;
+ m_endPoints6 = 0;
+ }
m_node = 0;
m_downTarget.Nullify ();
+ m_downTarget6.Nullify ();
/*
= MakeNullCallback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint8_t, Ptr<Ipv4Route> > ();
*/
- Ipv4L4Protocol::DoDispose ();
+ IpL4Protocol::DoDispose ();
}
Ptr<Socket>
@@ -186,6 +211,49 @@
m_endPoints->DeAllocate (endPoint);
}
+Ipv6EndPoint *
+UdpL4Protocol::Allocate6 (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_endPoints6->Allocate ();
+}
+
+Ipv6EndPoint *
+UdpL4Protocol::Allocate6 (Ipv6Address address)
+{
+ NS_LOG_FUNCTION (this << address);
+ return m_endPoints6->Allocate (address);
+}
+
+Ipv6EndPoint *
+UdpL4Protocol::Allocate6 (uint16_t port)
+{
+ NS_LOG_FUNCTION (this << port);
+ return m_endPoints6->Allocate (port);
+}
+
+Ipv6EndPoint *
+UdpL4Protocol::Allocate6 (Ipv6Address address, uint16_t port)
+{
+ NS_LOG_FUNCTION (this << address << port);
+ return m_endPoints6->Allocate (address, port);
+}
+Ipv6EndPoint *
+UdpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
+ Ipv6Address peerAddress, uint16_t peerPort)
+{
+ NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+ return m_endPoints6->Allocate (localAddress, localPort,
+ peerAddress, peerPort);
+}
+
+void
+UdpL4Protocol::DeAllocate (Ipv6EndPoint *endPoint)
+{
+ NS_LOG_FUNCTION (this << endPoint);
+ m_endPoints6->DeAllocate (endPoint);
+}
+
void
UdpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
@@ -213,7 +281,34 @@
}
}
-enum Ipv4L4Protocol::RxStatus
+void
+UdpL4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv6Address payloadSource,Ipv6Address payloadDestination,
+ const uint8_t payload[8])
+{
+ NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
+ << payloadSource << payloadDestination);
+ uint16_t src, dst;
+ src = payload[0] << 8;
+ src |= payload[1];
+ dst = payload[2] << 8;
+ dst |= payload[3];
+
+ Ipv6EndPoint *endPoint = m_endPoints6->SimpleLookup (payloadSource, src, payloadDestination, dst);
+ if (endPoint != 0)
+ {
+ endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
+ ", destination="<<payloadDestination<<
+ ", src=" << src << ", dst=" << dst);
+ }
+}
+
+enum IpL4Protocol::RxStatus
UdpL4Protocol::Receive (Ptr<Packet> packet,
Ipv4Header const &header,
Ptr<Ipv4Interface> interface)
@@ -227,12 +322,17 @@
udpHeader.InitializeChecksum (header.GetSource (), header.GetDestination (), PROT_NUMBER);
- packet->RemoveHeader (udpHeader);
+ // We only peek at the header for now (instead of removing it) so that it will be intact
+ // if we have to pass it to a IPv6 endpoint via:
+ //
+ // UdpL4Protocol::Receive (Ptr<Packet> packet, Ipv6Address &src, Ipv6Address &dst, ...)
+
+ packet->PeekHeader (udpHeader);
if(!udpHeader.IsChecksumOk ())
{
NS_LOG_INFO ("Bad checksum : dropping packet!");
- return Ipv4L4Protocol::RX_CSUM_FAILED;
+ return IpL4Protocol::RX_CSUM_FAILED;
}
NS_LOG_DEBUG ("Looking up dst " << header.GetDestination () << " port " << udpHeader.GetDestinationPort ());
@@ -241,16 +341,67 @@
header.GetSource (), udpHeader.GetSourcePort (), interface);
if (endPoints.empty ())
{
+ if (this->GetObject<Ipv6L3Protocol> () != 0)
+ {
+ NS_LOG_LOGIC (" No Ipv4 endpoints matched on UdpL4Protocol, trying Ipv6 "<<this);
+ Ptr<Ipv6Interface> fakeInterface;
+ Ipv6Address src = Ipv6Address::MakeIpv4MappedAddress (header.GetSource ());
+ Ipv6Address dst = Ipv6Address::MakeIpv4MappedAddress (header.GetDestination ());
+ return (this->Receive (packet, src, dst, fakeInterface));
+ }
+
NS_LOG_LOGIC ("RX_ENDPOINT_UNREACH");
- return Ipv4L4Protocol::RX_ENDPOINT_UNREACH;
+ return IpL4Protocol::RX_ENDPOINT_UNREACH;
}
+
+ packet->RemoveHeader(udpHeader);
for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
endPoint != endPoints.end (); endPoint++)
{
(*endPoint)->ForwardUp (packet->Copy (), header, udpHeader.GetSourcePort (),
interface);
}
- return Ipv4L4Protocol::RX_OK;
+ return IpL4Protocol::RX_OK;
+}
+
+enum IpL4Protocol::RxStatus
+UdpL4Protocol::Receive (Ptr<Packet> packet,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst);
+ UdpHeader udpHeader;
+ if(Node::ChecksumEnabled ())
+ {
+ udpHeader.EnableChecksums ();
+ }
+
+ udpHeader.InitializeChecksum (src, dst, PROT_NUMBER);
+
+ packet->RemoveHeader (udpHeader);
+
+ if(!udpHeader.IsChecksumOk () && !src.IsIpv4MappedAddress ())
+ {
+ NS_LOG_INFO ("Bad checksum : dropping packet!");
+ return IpL4Protocol::RX_CSUM_FAILED;
+ }
+
+ NS_LOG_DEBUG ("Looking up dst " << dst << " port " << udpHeader.GetDestinationPort ());
+ Ipv6EndPointDemux::EndPoints endPoints =
+ m_endPoints6->Lookup (dst, udpHeader.GetDestinationPort (),
+ src, udpHeader.GetSourcePort (), interface);
+ if (endPoints.empty ())
+ {
+ NS_LOG_LOGIC ("RX_ENDPOINT_UNREACH");
+ return IpL4Protocol::RX_ENDPOINT_UNREACH;
+ }
+ for (Ipv6EndPointDemux::EndPointsI endPoint = endPoints.begin ();
+ endPoint != endPoints.end (); endPoint++)
+ {
+ (*endPoint)->ForwardUp (packet->Copy (), src, dst, udpHeader.GetSourcePort ());
+ }
+ return IpL4Protocol::RX_OK;
}
void
@@ -300,16 +451,74 @@
}
void
-UdpL4Protocol::SetDownTarget (Ipv4L4Protocol::DownTargetCallback callback)
+UdpL4Protocol::Send (Ptr<Packet> packet,
+ Ipv6Address saddr, Ipv6Address daddr,
+ uint16_t sport, uint16_t dport)
+{
+ NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
+
+ UdpHeader udpHeader;
+ if(Node::ChecksumEnabled ())
+ {
+ udpHeader.EnableChecksums ();
+ udpHeader.InitializeChecksum (saddr,
+ daddr,
+ PROT_NUMBER);
+ }
+ udpHeader.SetDestinationPort (dport);
+ udpHeader.SetSourcePort (sport);
+
+ packet->AddHeader (udpHeader);
+
+ m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, 0);
+}
+
+void
+UdpL4Protocol::Send (Ptr<Packet> packet,
+ Ipv6Address saddr, Ipv6Address daddr,
+ uint16_t sport, uint16_t dport, Ptr<Ipv6Route> route)
+{
+ NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << route);
+
+ UdpHeader udpHeader;
+ if(Node::ChecksumEnabled ())
+ {
+ udpHeader.EnableChecksums ();
+ udpHeader.InitializeChecksum (saddr,
+ daddr,
+ PROT_NUMBER);
+ }
+ udpHeader.SetDestinationPort (dport);
+ udpHeader.SetSourcePort (sport);
+
+ packet->AddHeader (udpHeader);
+
+ m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, route);
+}
+
+void
+UdpL4Protocol::SetDownTarget (IpL4Protocol::DownTargetCallback callback)
{
m_downTarget = callback;
}
-Ipv4L4Protocol::DownTargetCallback
+IpL4Protocol::DownTargetCallback
UdpL4Protocol::GetDownTarget (void) const
{
return m_downTarget;
}
+void
+UdpL4Protocol::SetDownTarget6 (IpL4Protocol::DownTargetCallback6 callback)
+{
+ m_downTarget6 = callback;
+}
+
+IpL4Protocol::DownTargetCallback6
+UdpL4Protocol::GetDownTarget6 (void) const
+{
+ return m_downTarget6;
+}
+
} // namespace ns3
--- a/src/internet/model/udp-l4-protocol.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/udp-l4-protocol.h Mon Feb 20 14:05:07 2012 +0100
@@ -25,8 +25,11 @@
#include "ns3/packet.h"
#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
#include "ns3/ptr.h"
-#include "ipv4-l4-protocol.h"
+#include "ns3/ip-l4-protocol.h"
+#include "ipv6-interface.h"
+#include "ipv6-header.h"
namespace ns3 {
@@ -34,13 +37,15 @@
class Socket;
class Ipv4EndPointDemux;
class Ipv4EndPoint;
+class Ipv6EndPointDemux;
+class Ipv6EndPoint;
class UdpSocketImpl;
/**
* \ingroup udp
* \brief Implementation of the UDP protocol
*/
-class UdpL4Protocol : public Ipv4L4Protocol {
+class UdpL4Protocol : public IpL4Protocol {
public:
static TypeId GetTypeId (void);
static const uint8_t PROT_NUMBER;
@@ -64,8 +69,15 @@
Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort);
+ Ipv6EndPoint *Allocate6 (void);
+ Ipv6EndPoint *Allocate6 (Ipv6Address address);
+ Ipv6EndPoint *Allocate6 (uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ipv6Address address, uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ipv6Address localAddress, uint16_t localPort,
+ Ipv6Address peerAddress, uint16_t peerPort);
void DeAllocate (Ipv4EndPoint *endPoint);
+ void DeAllocate (Ipv6EndPoint *endPoint);
// called by UdpSocket.
/**
@@ -82,6 +94,12 @@
void Send (Ptr<Packet> packet,
Ipv4Address saddr, Ipv4Address daddr,
uint16_t sport, uint16_t dport, Ptr<Ipv4Route> route);
+ void Send (Ptr<Packet> packet,
+ Ipv6Address saddr, Ipv6Address daddr,
+ uint16_t sport, uint16_t dport);
+ void Send (Ptr<Packet> packet,
+ Ipv6Address saddr, Ipv6Address daddr,
+ uint16_t sport, uint16_t dport, Ptr<Ipv6Route> route);
/**
* \brief Receive a packet up the protocol stack
* \param p The Packet to dump the contents into
@@ -89,9 +107,13 @@
* \param interface the interface from which the packet is coming.
*/
// inherited from Ipv4L4Protocol
- virtual enum Ipv4L4Protocol::RxStatus Receive (Ptr<Packet> p,
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
Ipv4Header const &header,
Ptr<Ipv4Interface> interface);
+ virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv6Address &src,
+ Ipv6Address &dst,
+ Ptr<Ipv6Interface> interface);
/**
* \brief Receive an ICMP packet
@@ -108,11 +130,17 @@
uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
Ipv4Address payloadSource,Ipv4Address payloadDestination,
const uint8_t payload[8]);
+ virtual void ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv6Address payloadSource,Ipv6Address payloadDestination,
+ const uint8_t payload[8]);
- // From Ipv4L4Protocol
- virtual void SetDownTarget (Ipv4L4Protocol::DownTargetCallback cb);
- // From Ipv4L4Protocol
- virtual Ipv4L4Protocol::DownTargetCallback GetDownTarget (void) const;
+ // From IpL4Protocol
+ virtual void SetDownTarget (IpL4Protocol::DownTargetCallback cb);
+ virtual void SetDownTarget6 (IpL4Protocol::DownTargetCallback6 cb);
+ // From IpL4Protocol
+ virtual IpL4Protocol::DownTargetCallback GetDownTarget (void) const;
+ virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const;
protected:
virtual void DoDispose (void);
@@ -124,10 +152,12 @@
private:
Ptr<Node> m_node;
Ipv4EndPointDemux *m_endPoints;
+ Ipv6EndPointDemux *m_endPoints6;
UdpL4Protocol (const UdpL4Protocol &o);
UdpL4Protocol &operator = (const UdpL4Protocol &o);
std::vector<Ptr<UdpSocketImpl> > m_sockets;
- Ipv4L4Protocol::DownTargetCallback m_downTarget;
+ IpL4Protocol::DownTargetCallback m_downTarget;
+ IpL4Protocol::DownTargetCallback6 m_downTarget6;
};
} // namespace ns3
--- a/src/internet/model/udp-socket-impl.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/udp-socket-impl.cc Mon Feb 20 14:05:07 2012 +0100
@@ -21,16 +21,21 @@
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/ipv4-route.h"
+#include "ns3/ipv6-route.h"
#include "ns3/ipv4.h"
+#include "ns3/ipv6.h"
#include "ns3/ipv4-header.h"
#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/ipv6-routing-protocol.h"
#include "ns3/udp-socket-factory.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/ipv4-packet-info-tag.h"
#include "udp-socket-impl.h"
#include "udp-l4-protocol.h"
#include "ipv4-end-point.h"
+#include "ipv6-end-point.h"
#include <limits>
NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl");
@@ -52,12 +57,17 @@
CallbackValue (),
MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback),
MakeCallbackChecker ())
+ .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
+ CallbackValue (),
+ MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback6),
+ MakeCallbackChecker ())
;
return tid;
}
UdpSocketImpl::UdpSocketImpl ()
: m_endPoint (0),
+ m_endPoint6 (0),
m_node (0),
m_udp (0),
m_errno (ERROR_NOTERROR),
@@ -142,14 +152,21 @@
UdpSocketImpl::FinishBind (void)
{
NS_LOG_FUNCTION_NOARGS ();
- if (m_endPoint == 0)
+ if (m_endPoint != 0)
{
- return -1;
+ m_endPoint->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp, Ptr<UdpSocketImpl> (this)));
+ m_endPoint->SetIcmpCallback (MakeCallback (&UdpSocketImpl::ForwardIcmp, Ptr<UdpSocketImpl> (this)));
+ m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
+ return 0;
}
- m_endPoint->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp, Ptr<UdpSocketImpl> (this)));
- m_endPoint->SetIcmpCallback (MakeCallback (&UdpSocketImpl::ForwardIcmp, Ptr<UdpSocketImpl> (this)));
- m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
- return 0;
+ else if (m_endPoint6 != 0)
+ {
+ m_endPoint6->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp6, Ptr<UdpSocketImpl> (this)));
+ m_endPoint6->SetIcmpCallback (MakeCallback (&UdpSocketImpl::ForwardIcmp6, Ptr<UdpSocketImpl> (this)));
+ m_endPoint6->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
+ return 0;
+ }
+ return -1;
}
int
@@ -160,36 +177,69 @@
return FinishBind ();
}
+int
+UdpSocketImpl::Bind6 (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_endPoint6 = m_udp->Allocate6 ();
+ return FinishBind ();
+}
+
int
UdpSocketImpl::Bind (const Address &address)
{
NS_LOG_FUNCTION (this << address);
- if (!InetSocketAddress::IsMatchingType (address))
+ if (InetSocketAddress::IsMatchingType (address))
+ {
+ InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+ Ipv4Address ipv4 = transport.GetIpv4 ();
+ uint16_t port = transport.GetPort ();
+ if (ipv4 == Ipv4Address::GetAny () && port == 0)
+ {
+ m_endPoint = m_udp->Allocate ();
+ }
+ else if (ipv4 == Ipv4Address::GetAny () && port != 0)
+ {
+ m_endPoint = m_udp->Allocate (port);
+ }
+ else if (ipv4 != Ipv4Address::GetAny () && port == 0)
+ {
+ m_endPoint = m_udp->Allocate (ipv4);
+ }
+ else if (ipv4 != Ipv4Address::GetAny () && port != 0)
+ {
+ m_endPoint = m_udp->Allocate (ipv4, port);
+ }
+ }
+ else if (Inet6SocketAddress::IsMatchingType (address))
+ {
+ Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
+ Ipv6Address ipv6 = transport.GetIpv6 ();
+ uint16_t port = transport.GetPort ();
+ if (ipv6 == Ipv6Address::GetAny () && port == 0)
+ {
+ m_endPoint6 = m_udp->Allocate6 ();
+ }
+ else if (ipv6 == Ipv6Address::GetAny () && port != 0)
+ {
+ m_endPoint6 = m_udp->Allocate6 (port);
+ }
+ else if (ipv6 != Ipv6Address::GetAny () && port == 0)
+ {
+ m_endPoint6 = m_udp->Allocate6 (ipv6);
+ }
+ else if (ipv6 != Ipv6Address::GetAny () && port != 0)
+ {
+ m_endPoint6 = m_udp->Allocate6 (ipv6, port);
+ }
+ }
+ else
{
NS_LOG_ERROR ("Not IsMatchingType");
m_errno = ERROR_INVAL;
return -1;
}
- InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- Ipv4Address ipv4 = transport.GetIpv4 ();
- uint16_t port = transport.GetPort ();
- if (ipv4 == Ipv4Address::GetAny () && port == 0)
- {
- m_endPoint = m_udp->Allocate ();
- }
- else if (ipv4 == Ipv4Address::GetAny () && port != 0)
- {
- m_endPoint = m_udp->Allocate (port);
- }
- else if (ipv4 != Ipv4Address::GetAny () && port == 0)
- {
- m_endPoint = m_udp->Allocate (ipv4);
- }
- else if (ipv4 != Ipv4Address::GetAny () && port != 0)
- {
- m_endPoint = m_udp->Allocate (ipv4, port);
- }
return FinishBind ();
}
@@ -228,11 +278,26 @@
UdpSocketImpl::Connect (const Address & address)
{
NS_LOG_FUNCTION (this << address);
- InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- m_defaultAddress = transport.GetIpv4 ();
- m_defaultPort = transport.GetPort ();
- m_connected = true;
- NotifyConnectionSucceeded ();
+ if (InetSocketAddress::IsMatchingType(address) == true)
+ {
+ InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+ m_defaultAddress = Address(transport.GetIpv4 ());
+ m_defaultPort = transport.GetPort ();
+ m_connected = true;
+ NotifyConnectionSucceeded ();
+ }
+ else if (Inet6SocketAddress::IsMatchingType(address) == true)
+ {
+ Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
+ m_defaultAddress = Address(transport.GetIpv6 ());
+ m_defaultPort = transport.GetPort ();
+ m_connected = true;
+ NotifyConnectionSucceeded ();
+ }
+ else
+ {
+ return -1;
+ }
return 0;
}
@@ -261,7 +326,7 @@
UdpSocketImpl::DoSend (Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p);
- if (m_endPoint == 0)
+ if ((m_endPoint == 0) && (InetSocketAddress::IsMatchingType(m_defaultAddress) == true))
{
if (Bind () == -1)
{
@@ -270,13 +335,22 @@
}
NS_ASSERT (m_endPoint != 0);
}
+ else if ((m_endPoint6 == 0) && (Inet6SocketAddress::IsMatchingType(m_defaultAddress) == true))
+ {
+ if (Bind6 () == -1)
+ {
+ NS_ASSERT (m_endPoint6 == 0);
+ return -1;
+ }
+ NS_ASSERT (m_endPoint6 != 0);
+ }
if (m_shutdownSend)
{
m_errno = ERROR_SHUTDOWN;
return -1;
}
- return DoSendTo (p, m_defaultAddress, m_defaultPort);
+ return DoSendTo (p, (const Address)m_defaultAddress);
}
int
@@ -287,17 +361,40 @@
if (!m_connected)
{
NS_LOG_LOGIC ("Not connected");
- InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- Ipv4Address ipv4 = transport.GetIpv4 ();
- uint16_t port = transport.GetPort ();
- return DoSendTo (p, ipv4, port);
+ if (InetSocketAddress::IsMatchingType(address) == true)
+ {
+ InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+ Ipv4Address ipv4 = transport.GetIpv4 ();
+ uint16_t port = transport.GetPort ();
+ return DoSendTo (p, ipv4, port);
+ }
+ else if (Inet6SocketAddress::IsMatchingType(address) == true)
+ {
+ Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
+ Ipv6Address ipv6 = transport.GetIpv6 ();
+ uint16_t port = transport.GetPort ();
+ return DoSendTo (p, ipv6, port);
+ }
+ else
+ {
+ return -1;
+ }
}
else
{
// connected UDP socket must use default addresses
NS_LOG_LOGIC ("Connected");
- return DoSendTo (p, m_defaultAddress, m_defaultPort);
+ if (Ipv4Address::IsMatchingType(m_defaultAddress))
+ {
+ return DoSendTo (p, Ipv4Address::ConvertFrom(m_defaultAddress), m_defaultPort);
+ }
+ else if (Ipv6Address::IsMatchingType(m_defaultAddress))
+ {
+ return DoSendTo (p, Ipv6Address::ConvertFrom(m_defaultAddress), m_defaultPort);
+ }
}
+ m_errno = ERROR_AFNOSUPPORT;
+ return(-1);
}
int
@@ -483,6 +580,113 @@
return 0;
}
+int
+UdpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv6Address dest, uint16_t port)
+{
+ NS_LOG_FUNCTION (this << p << dest << port);
+
+ if (dest.IsIpv4MappedAddress ())
+ {
+ return (DoSendTo(p, dest.GetIpv4MappedAddress (), port));
+ }
+ if (m_boundnetdevice)
+ {
+ NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
+ }
+ if (m_endPoint6 == 0)
+ {
+ if (Bind6 () == -1)
+ {
+ NS_ASSERT (m_endPoint6 == 0);
+ return -1;
+ }
+ NS_ASSERT (m_endPoint6 != 0);
+ }
+ if (m_shutdownSend)
+ {
+ m_errno = ERROR_SHUTDOWN;
+ return -1;
+ }
+
+ if (p->GetSize () > GetTxAvailable () )
+ {
+ m_errno = ERROR_MSGSIZE;
+ return -1;
+ }
+
+ Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
+
+ // Locally override the IP TTL for this socket
+ // We cannot directly modify the TTL at this stage, so we set a Packet tag
+ // The destination can be either multicast, unicast/anycast, or
+ // either all-hosts broadcast or limited (subnet-directed) broadcast.
+ // For the latter two broadcast types, the TTL will later be set to one
+ // irrespective of what is set in these socket options. So, this tagging
+ // may end up setting the TTL of a limited broadcast packet to be
+ // the same as a unicast, but it will be fixed further down the stack
+ if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
+ {
+ SocketIpTtlTag tag;
+ tag.SetTtl (m_ipMulticastTtl);
+ p->AddPacketTag (tag);
+ }
+ else if (m_ipTtl != 0 && !dest.IsMulticast ())
+ {
+ SocketIpTtlTag tag;
+ tag.SetTtl (m_ipTtl);
+ p->AddPacketTag (tag);
+ }
+ // There is no analgous to an IPv4 broadcast address in IPv6.
+ // Instead, we use a set of link-local, site-local, and global
+ // multicast addresses. The Ipv6 routing layers should all
+ // provide an interface-specific route to these addresses such
+ // that we can treat these multicast addresses as "not broadcast"
+
+ if (m_endPoint6->GetLocalAddress () != Ipv6Address::GetAny ())
+ {
+ m_udp->Send (p->Copy (), m_endPoint6->GetLocalAddress (), dest,
+ m_endPoint6->GetLocalPort (), port, 0);
+ NotifyDataSent (p->GetSize ());
+ NotifySend (GetTxAvailable ());
+ return p->GetSize ();
+ }
+ else if (ipv6->GetRoutingProtocol () != 0)
+ {
+ Ipv6Header header;
+ header.SetDestinationAddress (dest);
+ header.SetNextHeader (UdpL4Protocol::PROT_NUMBER);
+ Socket::SocketErrno errno_;
+ Ptr<Ipv6Route> route;
+ Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
+ // TBD-- we could cache the route and just check its validity
+ route = ipv6->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
+ if (route != 0)
+ {
+ NS_LOG_LOGIC ("Route exists");
+ header.SetSourceAddress (route->GetSource ());
+ m_udp->Send (p->Copy (), header.GetSourceAddress (), header.GetDestinationAddress (),
+ m_endPoint6->GetLocalPort (), port, route);
+ NotifyDataSent (p->GetSize ());
+ return p->GetSize ();
+ }
+ else
+ {
+ NS_LOG_LOGIC ("No route to destination");
+ NS_LOG_ERROR (errno_);
+ m_errno = errno_;
+ return -1;
+ }
+ }
+ else
+ {
+ NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
+ m_errno = ERROR_NOROUTETOHOST;
+ return -1;
+ }
+
+ return 0;
+}
+
// XXX maximum message size for UDP broadcast is limited by MTU
// size of underlying link; we are not checking that now.
uint32_t
@@ -498,10 +702,21 @@
UdpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
{
NS_LOG_FUNCTION (this << p << flags << address);
- InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- Ipv4Address ipv4 = transport.GetIpv4 ();
- uint16_t port = transport.GetPort ();
- return DoSendTo (p, ipv4, port);
+ if (InetSocketAddress::IsMatchingType (address))
+ {
+ InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+ Ipv4Address ipv4 = transport.GetIpv4 ();
+ uint16_t port = transport.GetPort ();
+ return DoSendTo (p, ipv4, port);
+ }
+ else if (Inet6SocketAddress::IsMatchingType (address))
+ {
+ Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
+ Ipv6Address ipv6 = transport.GetIpv6 ();
+ uint16_t port = transport.GetPort ();
+ return DoSendTo (p, ipv6, port);
+ }
+ return -1;
}
uint32_t
@@ -657,6 +872,38 @@
}
}
+void
+UdpSocketImpl::ForwardUp6 (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port)
+{
+ NS_LOG_FUNCTION (this << packet << saddr << port);
+
+ if (m_shutdownRecv)
+ {
+ return;
+ }
+
+ if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
+ {
+ Address address = Inet6SocketAddress (saddr, port);
+ SocketAddressTag tag;
+ tag.SetAddress (address);
+ packet->AddPacketTag (tag);
+ m_deliveryQueue.push (packet);
+ m_rxAvailable += packet->GetSize ();
+ NotifyDataRecv ();
+ }
+ else
+ {
+ // In general, this case should not occur unless the
+ // receiving application reads data from this socket slowly
+ // in comparison to the arrival rate
+ //
+ // drop and trace packet
+ NS_LOG_WARN ("No receive buffer space available. Drop.");
+ m_dropTrace (packet);
+ }
+}
+
void
UdpSocketImpl::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
uint8_t icmpType, uint8_t icmpCode,
@@ -670,6 +917,19 @@
}
}
+void
+UdpSocketImpl::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode,
+ uint32_t icmpInfo)
+{
+ NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
+ (uint32_t)icmpCode << icmpInfo);
+ if (!m_icmpCallback6.IsNull ())
+ {
+ m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
+ }
+}
+
void
UdpSocketImpl::SetRcvBufSize (uint32_t size)
--- a/src/internet/model/udp-socket-impl.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/model/udp-socket-impl.h Mon Feb 20 14:05:07 2012 +0100
@@ -34,6 +34,7 @@
namespace ns3 {
class Ipv4EndPoint;
+class Ipv6EndPoint;
class Node;
class Packet;
class UdpL4Protocol;
@@ -63,6 +64,7 @@
virtual enum SocketType GetSocketType (void) const;
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
+ virtual int Bind6 (void);
virtual int Bind (const Address &address);
virtual int Close (void);
virtual int ShutdownSend (void);
@@ -104,18 +106,24 @@
int FinishBind (void);
void ForwardUp (Ptr<Packet> p, Ipv4Header header, uint16_t port,
Ptr<Ipv4Interface> incomingInterface);
+ void ForwardUp6 (Ptr<Packet> p, Ipv6Address saddr, Ipv6Address daddr, uint16_t port);
void Destroy (void);
int DoSend (Ptr<Packet> p);
int DoSendTo (Ptr<Packet> p, const Address &daddr);
int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
+ int DoSendTo (Ptr<Packet> p, Ipv6Address daddr, uint16_t dport);
void ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
uint8_t icmpType, uint8_t icmpCode,
uint32_t icmpInfo);
+ void ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode,
+ uint32_t icmpInfo);
Ipv4EndPoint *m_endPoint;
+ Ipv6EndPoint *m_endPoint6;
Ptr<Node> m_node;
Ptr<UdpL4Protocol> m_udp;
- Ipv4Address m_defaultAddress;
+ Address m_defaultAddress;
uint16_t m_defaultPort;
TracedCallback<Ptr<const Packet> > m_dropTrace;
@@ -136,6 +144,7 @@
bool m_ipMulticastLoop;
bool m_mtuDiscover;
Callback<void, Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
+ Callback<void, Ipv6Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback6;
};
} // namespace ns3
--- a/src/internet/test/error-net-device.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/test/error-net-device.cc Mon Feb 20 14:05:07 2012 +0100
@@ -61,7 +61,7 @@
ErrorNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol,
Mac48Address to, Mac48Address from)
{
- NS_LOG_FUNCTION (packet << protocol << to << from);
+ NS_LOG_FUNCTION (packet << protocol << to << from << *packet);
NetDevice::PacketType packetType;
if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
@@ -194,7 +194,7 @@
bool
ErrorNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
{
- NS_LOG_FUNCTION (packet << dest << protocolNumber);
+ NS_LOG_FUNCTION (packet << dest << protocolNumber << *packet);
Mac48Address to = Mac48Address::ConvertFrom (dest);
m_channel->Send (packet, protocolNumber, to, m_address, this);
return true;
@@ -202,6 +202,7 @@
bool
ErrorNetDevice::SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
{
+ NS_LOG_FUNCTION (packet << source << dest << protocolNumber << *packet);
Mac48Address to = Mac48Address::ConvertFrom (dest);
Mac48Address from = Mac48Address::ConvertFrom (source);
m_channel->Send (packet, protocolNumber, to, from, this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/test/ipv6-dual-stack-test-suite.cc Mon Feb 20 14:05:07 2012 +0100
@@ -0,0 +1,312 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ * Copyright (c) 2009 INRIA
+ *
+ * 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: Ken Renard <kenneth.d.renard.ctr@mail.mil>
+ *
+ */
+
+#include "ns3/test.h"
+#include "ns3/socket-factory.h"
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/simulator.h"
+#include "ns3/simple-channel.h"
+#include "ns3/simple-net-device.h"
+#include "ns3/config.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/node.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+
+#include "ns3/ipv4-end-point.h"
+#include "ns3/arp-l3-protocol.h"
+#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/icmpv4-l4-protocol.h"
+#include "ns3/icmpv6-l4-protocol.h"
+#include "ns3/udp-l4-protocol.h"
+#include "ns3/tcp-l4-protocol.h"
+
+#include <string>
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6DualStackTestSuite");
+
+namespace ns3 {
+
+class DualStackTestCase : public TestCase
+{
+public:
+ DualStackTestCase ();
+private:
+ virtual void DoRun (void);
+ virtual void DoTeardown (void);
+
+ void SetUpSim ();
+ Ptr<Node> node0;
+ Ptr<Node> node1;
+
+ void ServerHandleConnectionCreated1 (Ptr<Socket> s, const Address & addr);
+ void ServerHandleConnectionCreated2 (Ptr<Socket> s, const Address & addr);
+ void ServerHandleConnectionCreated3 (Ptr<Socket> s, const Address & addr);
+ void ServerHandleConnectionCreated4 (Ptr<Socket> s, const Address & addr);
+
+ Ptr<Socket> server1;
+ Ptr<Socket> server2;
+ Ptr<Socket> server3;
+ Ptr<Socket> server4;
+
+ Ptr<Socket> source1;
+ Ptr<Socket> source2;
+ Ptr<Socket> source3;
+ Ptr<Socket> source4;
+
+ Address receivedAddr1;
+ Address receivedAddr2;
+ Address receivedAddr3;
+ Address receivedAddr4;
+};
+
+Ptr<Node>
+CreateDualStackNode ()
+{
+ Ptr<Node> node = CreateObject<Node> ();
+
+ //ARP
+ Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
+ node->AggregateObject (arp);
+
+ //IPV4
+ Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
+ //Routing for Ipv4
+ Ptr<Ipv4ListRouting> ipv4Routing = CreateObject<Ipv4ListRouting> ();
+ ipv4->SetRoutingProtocol (ipv4Routing);
+ Ptr<Ipv4StaticRouting> ipv4staticRouting = CreateObject<Ipv4StaticRouting> ();
+ ipv4Routing->AddRoutingProtocol (ipv4staticRouting, 0);
+ node->AggregateObject (ipv4);
+
+ //ICMPv4
+ Ptr<Icmpv4L4Protocol> icmp = CreateObject<Icmpv4L4Protocol> ();
+ node->AggregateObject (icmp);
+
+ //UDP
+ Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
+ node->AggregateObject (udp);
+
+ //TCP
+ Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
+ node->AggregateObject (tcp);
+
+ //IPV6
+ Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
+
+ //Routing for Ipv6
+ Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
+ ipv6->SetRoutingProtocol (ipv6Routing);
+ Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
+ ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
+ node->AggregateObject (ipv6);
+
+ //ICMPv6
+ Ptr<Icmpv6L4Protocol> icmp6 = CreateObject<Icmpv6L4Protocol> ();
+ node->AggregateObject (icmp6);
+
+ //Ipv6 Extensions
+ ipv6->RegisterExtensions ();
+ ipv6->RegisterOptions ();
+
+ return node;
+}
+
+Ptr<SimpleNetDevice>
+AddSimpleNetDevice (Ptr<Node> node, Ipv4Address v4Addr, Ipv4Mask v4Mask,
+ Ipv6Address v6Addr, Ipv6Prefix v6Prefix)
+{
+ Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
+ dev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ node->AddDevice (dev);
+
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ uint32_t ndid = ipv4->AddInterface (dev);
+ Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (v4Addr, v4Mask);
+ ipv4->AddAddress (ndid, ipv4Addr);
+ ipv4->SetUp (ndid);
+
+ Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+ ndid = ipv6->AddInterface (dev);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (v6Addr, v6Prefix);
+ ipv6->AddAddress (ndid, ipv6Addr);
+ ipv6->SetUp (ndid);
+
+ return dev;
+}
+
+void
+DualStackTestCase::SetUpSim ()
+{
+ node0 = CreateDualStackNode ();
+ node1 = CreateDualStackNode ();
+
+ Ptr<SimpleNetDevice> dev0 = AddSimpleNetDevice(node0, Ipv4Address("10.0.0.1"),
+ Ipv4Mask(0xffffff00), Ipv6Address("2001::1"), Ipv6Prefix(64));
+ Ptr<SimpleNetDevice> dev1 = AddSimpleNetDevice(node1, Ipv4Address("10.0.0.2"),
+ Ipv4Mask(0xffffff00), Ipv6Address("2001::2"), Ipv6Prefix(64));
+
+ Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
+ dev0->SetChannel (channel);
+ dev1->SetChannel (channel);
+
+ Ptr<SocketFactory> sockFactory0 = node0->GetObject<TcpSocketFactory> ();
+ Ptr<SocketFactory> sockFactory1 = node1->GetObject<TcpSocketFactory> ();
+
+ server1 = sockFactory0->CreateSocket ();
+ server2 = sockFactory0->CreateSocket ();
+ server3 = sockFactory0->CreateSocket ();
+ server4 = sockFactory0->CreateSocket ();
+
+ source1 = sockFactory1->CreateSocket ();
+ source2 = sockFactory1->CreateSocket ();
+ source3 = sockFactory1->CreateSocket ();
+ source4 = sockFactory1->CreateSocket ();
+
+ return;
+}
+
+void
+DualStackTestCase::ServerHandleConnectionCreated1 (Ptr<Socket> s, const Address & addr)
+{
+ receivedAddr1 = addr;
+ return;
+}
+
+void
+DualStackTestCase::ServerHandleConnectionCreated2 (Ptr<Socket> s, const Address & addr)
+{
+ receivedAddr2 = addr;
+ return;
+}
+
+void
+DualStackTestCase::ServerHandleConnectionCreated3 (Ptr<Socket> s, const Address & addr)
+{
+ receivedAddr3 = addr;
+ return;
+}
+
+void
+DualStackTestCase::ServerHandleConnectionCreated4 (Ptr<Socket> s, const Address & addr)
+{
+ receivedAddr4 = addr;
+ return;
+}
+
+
+DualStackTestCase::DualStackTestCase ()
+ : TestCase ("DualStackTestCase")
+{
+ receivedAddr1 = Address ();
+ receivedAddr2 = Address ();
+ receivedAddr3 = Address ();
+ receivedAddr4 = Address ();
+}
+
+void
+DualStackTestCase::DoRun (void)
+{
+ SetUpSim ();
+
+ uint16_t port1 = 5000;
+ uint16_t port2 = 5001;
+ uint16_t port3 = 5002;
+ uint16_t port4 = 5003;
+
+ /* Server 1: listen on 0.0.0.0 for IPv4 connection */
+ server1->Bind (InetSocketAddress(Ipv4Address::GetAny(), port1));
+ server1->Listen ();
+ server1->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
+ MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated1, this));
+
+ /* Server 2: listen on 0.0.0.0 for IPv4 connection - should reject IPv6 */
+ server2->Bind (InetSocketAddress(Ipv4Address::GetAny(), port2));
+ server2->Listen ();
+ server2->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
+ MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated2, this));
+
+ /* Server 3: listen on :: for IPv4 (mapped into IPv6 address) connection */
+ server3->Bind (Inet6SocketAddress(Ipv6Address::GetAny(), port3));
+ server3->Listen ();
+ server3->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
+ MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated3, this));
+
+ /* Server 4: listen on :: for IPv6 connection */
+ server4->Bind (Inet6SocketAddress(Ipv6Address::GetAny(), port4));
+ server4->Listen ();
+ server4->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
+ MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated4, this));
+
+
+ /* Source 1: connect to server 1 via IPv4 */
+ source1->Connect(InetSocketAddress(Ipv4Address("10.0.0.1"), port1));
+
+ /* Source 2: connect to server 2 via IPv6 */
+ source2->Connect(Inet6SocketAddress(Ipv6Address("2001::1"), port2));
+
+ /* Source 3: connect to server 3 via IPv4 */
+ source3->Connect(InetSocketAddress(Ipv4Address("10.0.0.1"), port3));
+
+ /* Source 4: connect to server 4 via IPv6 */
+ source4->Connect(Inet6SocketAddress(Ipv6Address("2001::1"), port4));
+
+ Simulator::Run();
+
+ /* Server 1: should have connection from Ipv4 address of Node 1 */
+ NS_TEST_EXPECT_MSG_EQ (InetSocketAddress::IsMatchingType(receivedAddr1), true, "Accepted address is of proper type");
+ NS_TEST_EXPECT_MSG_EQ(InetSocketAddress::ConvertFrom(receivedAddr1).GetIpv4 (), Ipv4Address("10.0.0.2"), "Accepted address is correct");
+
+ /* Server 2: should have no connection */
+ NS_TEST_EXPECT_MSG_EQ(receivedAddr2.IsInvalid(), true, "IPv4 socket correctly ignored IPv6 connection");
+
+ /* Server 3: should have connection from Ipv4-mapped IPv6 address of Node 1 */
+ NS_TEST_EXPECT_MSG_EQ (Inet6SocketAddress::IsMatchingType(receivedAddr3), true, "Accepted address is of proper type");
+ NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::ConvertFrom(receivedAddr3).GetIpv6 (), Ipv6Address("::ffff:0a00:0002"), "Accepted address is correct");
+
+ /* Server 4: should have connection from IPv6 address of Node 1 */
+ NS_TEST_EXPECT_MSG_EQ (Inet6SocketAddress::IsMatchingType(receivedAddr4), true, "Accepted address is of proper type");
+ NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::ConvertFrom(receivedAddr4).GetIpv6 (), Ipv6Address("2001::2"), "Accepted address is correct");
+}
+
+void
+DualStackTestCase::DoTeardown (void)
+{
+}
+
+
+static class Ipv6DualStackTestSuite : public TestSuite
+{
+public:
+ Ipv6DualStackTestSuite ()
+ : TestSuite ("ipv6-dual-stack", UNIT)
+ {
+ AddTestCase (new DualStackTestCase());
+ }
+} g_ipv6DualStackTestSuite;
+
+} // namespace ns3
--- a/src/internet/test/tcp-test.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/test/tcp-test.cc Mon Feb 20 14:05:07 2012 +0100
@@ -30,15 +30,20 @@
#include "ns3/config.h"
#include "ns3/ipv4-static-routing.h"
#include "ns3/ipv4-list-routing.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ns3/ipv6-list-routing.h"
#include "ns3/node.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/uinteger.h"
#include "ns3/log.h"
#include "ns3/ipv4-end-point.h"
#include "ns3/arp-l3-protocol.h"
#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/ipv6-l3-protocol.h"
#include "ns3/icmpv4-l4-protocol.h"
+#include "ns3/icmpv6-l4-protocol.h"
#include "ns3/udp-l4-protocol.h"
#include "ns3/tcp-l4-protocol.h"
@@ -55,14 +60,18 @@
uint32_t sourceWriteSize,
uint32_t sourceReadSize,
uint32_t serverWriteSize,
- uint32_t serverReadSize);
+ uint32_t serverReadSize,
+ bool useIpv6);
private:
virtual void DoRun (void);
virtual void DoTeardown (void);
void SetupDefaultSim (void);
+ void SetupDefaultSim6 (void);
Ptr<Node> CreateInternetNode (void);
+ Ptr<Node> CreateInternetNode6 (void);
Ptr<SimpleNetDevice> AddSimpleNetDevice (Ptr<Node> node, const char* ipaddr, const char* netmask);
+ Ptr<SimpleNetDevice> AddSimpleNetDevice6 (Ptr<Node> node, Ipv6Address ipaddr, Ipv6Prefix prefix);
void ServerHandleConnectionCreated (Ptr<Socket> s, const Address & addr);
void ServerHandleRecv (Ptr<Socket> sock);
void ServerHandleSend (Ptr<Socket> sock, uint32_t available);
@@ -81,18 +90,21 @@
uint8_t *m_sourceTxPayload;
uint8_t *m_sourceRxPayload;
uint8_t* m_serverRxPayload;
+
+ bool m_useIpv6;
};
static std::string Name (std::string str, uint32_t totalStreamSize,
uint32_t sourceWriteSize,
uint32_t serverReadSize,
uint32_t serverWriteSize,
- uint32_t sourceReadSize)
+ uint32_t sourceReadSize,
+ bool useIpv6)
{
std::ostringstream oss;
oss << str << " total=" << totalStreamSize << " sourceWrite=" << sourceWriteSize
<< " sourceRead=" << sourceReadSize << " serverRead=" << serverReadSize
- << " serverWrite=" << serverWriteSize;
+ << " serverWrite=" << serverWriteSize << " useIpv6=" << useIpv6;
return oss.str ();
}
@@ -109,18 +121,21 @@
uint32_t sourceWriteSize,
uint32_t sourceReadSize,
uint32_t serverWriteSize,
- uint32_t serverReadSize)
+ uint32_t serverReadSize,
+ bool useIpv6)
: TestCase (Name ("Send string data from client to server and back",
totalStreamSize,
sourceWriteSize,
serverReadSize,
serverWriteSize,
- sourceReadSize)),
+ sourceReadSize,
+ useIpv6)),
m_totalBytes (totalStreamSize),
m_sourceWriteSize (sourceWriteSize),
m_sourceReadSize (sourceReadSize),
m_serverWriteSize (serverWriteSize),
- m_serverReadSize (serverReadSize)
+ m_serverReadSize (serverReadSize),
+ m_useIpv6 (useIpv6)
{
}
@@ -142,7 +157,14 @@
memset (m_sourceRxPayload, 0, m_totalBytes);
memset (m_serverRxPayload, 0, m_totalBytes);
- SetupDefaultSim ();
+ if (m_useIpv6 == true)
+ {
+ SetupDefaultSim6 ();
+ }
+ else
+ {
+ SetupDefaultSim ();
+ }
Simulator::Run ();
@@ -326,6 +348,83 @@
source->Connect (serverremoteaddr);
}
+void
+TcpTestCase::SetupDefaultSim6 (void)
+{
+ Ipv6Prefix prefix = Ipv6Prefix(64);
+ Ipv6Address ipaddr0 = Ipv6Address("2001:0100:f00d:cafe::1");
+ Ipv6Address ipaddr1 = Ipv6Address("2001:0100:f00d:cafe::2");
+ Ptr<Node> node0 = CreateInternetNode6 ();
+ Ptr<Node> node1 = CreateInternetNode6 ();
+ Ptr<SimpleNetDevice> dev0 = AddSimpleNetDevice6 (node0, ipaddr0, prefix);
+ Ptr<SimpleNetDevice> dev1 = AddSimpleNetDevice6 (node1, ipaddr1, prefix);
+
+ Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
+ dev0->SetChannel (channel);
+ dev1->SetChannel (channel);
+
+ Ptr<SocketFactory> sockFactory0 = node0->GetObject<TcpSocketFactory> ();
+ Ptr<SocketFactory> sockFactory1 = node1->GetObject<TcpSocketFactory> ();
+
+ Ptr<Socket> server = sockFactory0->CreateSocket ();
+ Ptr<Socket> source = sockFactory1->CreateSocket ();
+
+ uint16_t port = 50000;
+ Inet6SocketAddress serverlocaladdr (Ipv6Address::GetAny (), port);
+ Inet6SocketAddress serverremoteaddr (ipaddr0, port);
+
+ server->Bind (serverlocaladdr);
+ server->Listen ();
+ server->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
+ MakeCallback (&TcpTestCase::ServerHandleConnectionCreated,this));
+
+ source->SetRecvCallback (MakeCallback (&TcpTestCase::SourceHandleRecv, this));
+ source->SetSendCallback (MakeCallback (&TcpTestCase::SourceHandleSend, this));
+
+ source->Connect (serverremoteaddr);
+}
+
+Ptr<Node>
+TcpTestCase::CreateInternetNode6 ()
+{
+ Ptr<Node> node = CreateObject<Node> ();
+ //IPV6
+ Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
+ //Routing for Ipv6
+ Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
+ ipv6->SetRoutingProtocol (ipv6Routing);
+ Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
+ ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
+ node->AggregateObject (ipv6);
+ //ICMP
+ Ptr<Icmpv6L4Protocol> icmp = CreateObject<Icmpv6L4Protocol> ();
+ node->AggregateObject (icmp);
+ //Ipv6 Extensions
+ ipv6->RegisterExtensions ();
+ ipv6->RegisterOptions ();
+ //UDP
+ Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
+ node->AggregateObject (udp);
+ //TCP
+ Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
+ node->AggregateObject (tcp);
+ return node;
+}
+
+Ptr<SimpleNetDevice>
+TcpTestCase::AddSimpleNetDevice6 (Ptr<Node> node, Ipv6Address ipaddr, Ipv6Prefix prefix)
+{
+ Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
+ dev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ node->AddDevice (dev);
+ Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+ uint32_t ndid = ipv6->AddInterface (dev);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (ipaddr, prefix);
+ ipv6->AddAddress (ndid, ipv6Addr);
+ ipv6->SetUp (ndid);
+ return dev;
+}
+
static class TcpTestSuite : public TestSuite
{
public:
@@ -336,9 +435,13 @@
// 2) source write size, 3) source read size
// 4) server write size, and 5) server read size
// with units of bytes
- AddTestCase (new TcpTestCase (13, 200, 200, 200, 200));
- AddTestCase (new TcpTestCase (13, 1, 1, 1, 1));
- AddTestCase (new TcpTestCase (100000, 100, 50, 100, 20));
+ AddTestCase (new TcpTestCase (13, 200, 200, 200, 200, false));
+ AddTestCase (new TcpTestCase (13, 1, 1, 1, 1, false));
+ AddTestCase (new TcpTestCase (100000, 100, 50, 100, 20, false));
+
+ AddTestCase (new TcpTestCase (13, 200, 200, 200, 200, true));
+ AddTestCase (new TcpTestCase (13, 1, 1, 1, 1, true));
+ AddTestCase (new TcpTestCase (100000, 100, 50, 100, 20, true));
}
} g_tcpTestSuite;
--- a/src/internet/test/udp-test.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/test/udp-test.cc Mon Feb 20 14:05:07 2012 +0100
@@ -34,14 +34,19 @@
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/inet6-socket-address.h"
#include "ns3/arp-l3-protocol.h"
#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/ipv6-l3-protocol.h"
#include "ns3/icmpv4-l4-protocol.h"
+#include "ns3/icmpv6-l4-protocol.h"
#include "ns3/udp-l4-protocol.h"
#include "ns3/tcp-l4-protocol.h"
#include "ns3/ipv4-list-routing.h"
#include "ns3/ipv4-static-routing.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/ipv6-static-routing.h"
#include <string>
#include <limits>
@@ -72,6 +77,31 @@
node->AggregateObject (tcp);
}
+static void
+AddInternetStack6 (Ptr<Node> node)
+{
+ //IPV6
+ Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
+ //Routing for Ipv6
+ Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
+ ipv6->SetRoutingProtocol (ipv6Routing);
+ Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
+ ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
+ node->AggregateObject (ipv6);
+ //ICMP
+ Ptr<Icmpv6L4Protocol> icmp = CreateObject<Icmpv6L4Protocol> ();
+ node->AggregateObject (icmp);
+ //Ipv6 Extensions
+ ipv6->RegisterExtensions ();
+ ipv6->RegisterOptions ();
+ //UDP
+ Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
+ node->AggregateObject (udp);
+ //TCP
+ Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
+ node->AggregateObject (tcp);
+}
+
class UdpSocketLoopbackTest : public TestCase
{
@@ -114,6 +144,50 @@
NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 246, "first socket should not receive it (it is bound specifically to the second interface's address");
}
+class Udp6SocketLoopbackTest : public TestCase
+{
+public:
+ Udp6SocketLoopbackTest ();
+ virtual void DoRun (void);
+
+ void ReceivePkt (Ptr<Socket> socket);
+ Ptr<Packet> m_receivedPacket;
+};
+
+Udp6SocketLoopbackTest::Udp6SocketLoopbackTest ()
+ : TestCase ("UDP6 loopback test")
+{
+}
+
+void Udp6SocketLoopbackTest::ReceivePkt (Ptr<Socket> socket)
+{
+ uint32_t availableData;
+ availableData = socket->GetRxAvailable ();
+ m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max (), 0);
+ NS_ASSERT (availableData == m_receivedPacket->GetSize ());
+ //cast availableData to void, to suppress 'availableData' set but not used
+ //compiler warning
+ (void) availableData;
+}
+
+void
+Udp6SocketLoopbackTest::DoRun ()
+{
+ Ptr<Node> rxNode = CreateObject<Node> ();
+ AddInternetStack6 (rxNode);
+
+ Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
+ Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
+ rxSocket->Bind (Inet6SocketAddress (Ipv6Address::GetAny (), 80));
+ rxSocket->SetRecvCallback (MakeCallback (&Udp6SocketLoopbackTest::ReceivePkt, this));
+
+ Ptr<Socket> txSocket = rxSocketFactory->CreateSocket ();
+ txSocket->SendTo (Create<Packet> (246), 0, Inet6SocketAddress ("::1", 80));
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 246, "first socket should not receive it (it is bound specifically to the second interface's address");
+}
+
class UdpSocketImplTest : public TestCase
{
Ptr<Packet> m_receivedPacket;
@@ -311,6 +385,190 @@
}
+class Udp6SocketImplTest : public TestCase
+{
+ Ptr<Packet> m_receivedPacket;
+ Ptr<Packet> m_receivedPacket2;
+ void DoSendData (Ptr<Socket> socket, std::string to);
+ void SendData (Ptr<Socket> socket, std::string to);
+
+public:
+ virtual void DoRun (void);
+ Udp6SocketImplTest ();
+
+ void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
+ void ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
+ void ReceivePkt (Ptr<Socket> socket);
+ void ReceivePkt2 (Ptr<Socket> socket);
+};
+
+Udp6SocketImplTest::Udp6SocketImplTest ()
+ : TestCase ("UDP6 socket implementation")
+{
+}
+
+void Udp6SocketImplTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
+{
+ m_receivedPacket = packet;
+}
+
+void Udp6SocketImplTest::ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
+{
+ m_receivedPacket2 = packet;
+}
+
+void Udp6SocketImplTest::ReceivePkt (Ptr<Socket> socket)
+{
+ uint32_t availableData;
+ availableData = socket->GetRxAvailable ();
+ m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max (), 0);
+ NS_ASSERT (availableData == m_receivedPacket->GetSize ());
+ //cast availableData to void, to suppress 'availableData' set but not used
+ //compiler warning
+ (void) availableData;
+}
+
+void Udp6SocketImplTest::ReceivePkt2 (Ptr<Socket> socket)
+{
+ uint32_t availableData;
+ availableData = socket->GetRxAvailable ();
+ m_receivedPacket2 = socket->Recv (std::numeric_limits<uint32_t>::max (), 0);
+ NS_ASSERT (availableData == m_receivedPacket2->GetSize ());
+ //cast availableData to void, to suppress 'availableData' set but not used
+ //compiler warning
+ (void) availableData;
+}
+
+void
+Udp6SocketImplTest::DoSendData (Ptr<Socket> socket, std::string to)
+{
+ Address realTo = Inet6SocketAddress (Ipv6Address (to.c_str ()), 1234);
+ NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create<Packet> (123), 0, realTo),
+ 123, "XXX");
+}
+
+void
+Udp6SocketImplTest::SendData (Ptr<Socket> socket, std::string to)
+{
+ m_receivedPacket = Create<Packet> ();
+ m_receivedPacket2 = Create<Packet> ();
+ Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0),
+ &Udp6SocketImplTest::DoSendData, this, socket, to);
+ Simulator::Run ();
+}
+
+void
+Udp6SocketImplTest::DoRun (void)
+{
+ // Create topology
+
+ // Receiver Node
+ Ptr<Node> rxNode = CreateObject<Node> ();
+ AddInternetStack6 (rxNode);
+ Ptr<SimpleNetDevice> rxDev1, rxDev2;
+ { // first interface
+ rxDev1 = CreateObject<SimpleNetDevice> ();
+ rxDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ rxNode->AddDevice (rxDev1);
+ Ptr<Ipv6> ipv6 = rxNode->GetObject<Ipv6> ();
+ uint32_t netdev_idx = ipv6->AddInterface (rxDev1);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::1"), Ipv6Prefix (64));
+ ipv6->AddAddress (netdev_idx, ipv6Addr);
+ ipv6->SetUp (netdev_idx);
+ }
+ { // second interface
+ rxDev2 = CreateObject<SimpleNetDevice> ();
+ rxDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ rxNode->AddDevice (rxDev2);
+ Ptr<Ipv6> ipv6 = rxNode->GetObject<Ipv6> ();
+ uint32_t netdev_idx = ipv6->AddInterface (rxDev2);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100:1::1"), Ipv6Prefix (64));
+ ipv6->AddAddress (netdev_idx, ipv6Addr);
+ ipv6->SetUp (netdev_idx);
+ }
+
+ // Sender Node
+ Ptr<Node> txNode = CreateObject<Node> ();
+ AddInternetStack6 (txNode);
+ Ptr<SimpleNetDevice> txDev1;
+ {
+ txDev1 = CreateObject<SimpleNetDevice> ();
+ txDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ txNode->AddDevice (txDev1);
+ Ptr<Ipv6> ipv6 = txNode->GetObject<Ipv6> ();
+ uint32_t netdev_idx = ipv6->AddInterface (txDev1);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::2"), Ipv6Prefix (64));
+ ipv6->AddAddress (netdev_idx, ipv6Addr);
+ ipv6->SetUp (netdev_idx);
+ }
+ Ptr<SimpleNetDevice> txDev2;
+ {
+ txDev2 = CreateObject<SimpleNetDevice> ();
+ txDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
+ txNode->AddDevice (txDev2);
+ Ptr<Ipv6> ipv6 = txNode->GetObject<Ipv6> ();
+ uint32_t netdev_idx = ipv6->AddInterface (txDev2);
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100:1::2"), Ipv6Prefix (64));
+ ipv6->AddAddress (netdev_idx, ipv6Addr);
+ ipv6->SetUp (netdev_idx);
+ }
+
+ // link the two nodes
+ Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
+ rxDev1->SetChannel (channel1);
+ txDev1->SetChannel (channel1);
+
+ Ptr<SimpleChannel> channel2 = CreateObject<SimpleChannel> ();
+ rxDev2->SetChannel (channel2);
+ txDev2->SetChannel (channel2);
+
+
+ // Create the UDP sockets
+ Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
+ Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
+ NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("2001:0100::1"), 1234)), 0, "trivial");
+ rxSocket->SetRecvCallback (MakeCallback (&Udp6SocketImplTest::ReceivePkt, this));
+
+ Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
+ rxSocket2->SetRecvCallback (MakeCallback (&Udp6SocketImplTest::ReceivePkt2, this));
+ NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (Inet6SocketAddress (Ipv6Address ("2001:0100:1::1"), 1234)), 0, "trivial");
+
+ Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
+ Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
+ txSocket->SetAllowBroadcast (true);
+ // ------ Now the tests ------------
+
+ // Unicast test
+ SendData (txSocket, "2001:0100::1");
+ NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
+ NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second interface should receive it");
+
+ m_receivedPacket->RemoveAllByteTags ();
+ m_receivedPacket2->RemoveAllByteTags ();
+
+ // Simple Link-local multicast test
+
+ // When receiving broadcast packets, all sockets sockets bound to
+ // the address/port should receive a copy of the same packet -- if
+ // the socket address matches.
+ rxSocket2->Dispose ();
+ rxSocket2 = rxSocketFactory->CreateSocket ();
+ rxSocket2->SetRecvCallback (MakeCallback (&Udp6SocketImplTest::ReceivePkt2, this));
+ NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (Inet6SocketAddress (Ipv6Address ("::"), 1234)), 0, "trivial");
+
+ txSocket->BindToNetDevice (txDev1);
+ SendData (txSocket, "ff02::1");
+ NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "first socket should not receive it (it is bound specifically to the second interface's address");
+ NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 123, "recv2: ff02::1");
+
+ m_receivedPacket->RemoveAllByteTags ();
+ m_receivedPacket2->RemoveAllByteTags ();
+
+ Simulator::Destroy ();
+
+}
+
+
//-----------------------------------------------------------------------------
class UdpTestSuite : public TestSuite
{
@@ -319,6 +577,8 @@
{
AddTestCase (new UdpSocketImplTest);
AddTestCase (new UdpSocketLoopbackTest);
+ AddTestCase (new Udp6SocketImplTest);
+ AddTestCase (new Udp6SocketLoopbackTest);
}
} g_udpTestSuite;
--- a/src/internet/wscript Sun Feb 19 16:22:51 2012 +0100
+++ b/src/internet/wscript Mon Feb 20 14:05:07 2012 +0100
@@ -94,7 +94,7 @@
# bridge and mpi dependencies are due to global routing
obj = bld.create_ns3_module('internet', ['bridge', 'mpi', 'network', 'core'])
obj.source = [
- 'model/ipv4-l4-protocol.cc',
+ 'model/ip-l4-protocol.cc',
'model/udp-header.cc',
'model/tcp-header.cc',
'model/ipv4-interface.cc',
@@ -122,7 +122,6 @@
'model/ipv6-l3-protocol.cc',
'model/ipv6-end-point.cc',
'model/ipv6-end-point-demux.cc',
- 'model/ipv6-l4-protocol.cc',
'model/ipv6-raw-socket-factory-impl.cc',
'model/ipv6-raw-socket-impl.cc',
'model/ipv6-autoconfigured-prefix.cc',
@@ -206,6 +205,7 @@
'test/tcp-test.cc',
'test/udp-test.cc',
'test/ipv6-address-generator-test-suite.cc',
+ 'test/ipv6-dual-stack-test-suite.cc',
]
headers = bld.new_task_gen(features=['ns3header'])
@@ -226,11 +226,10 @@
'model/udp-l4-protocol.h',
'model/tcp-l4-protocol.h',
'model/icmpv4-l4-protocol.h',
- 'model/ipv4-l4-protocol.h',
+ 'model/ip-l4-protocol.h',
'model/arp-header.h',
'model/arp-cache.h',
'model/icmpv6-l4-protocol.h',
- 'model/ipv6-l4-protocol.h',
'model/ipv6-interface.h',
'model/ndisc-cache.h',
'model/loopback-net-device.h',
--- a/src/netanim/examples/star-animation.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/netanim/examples/star-animation.cc Mon Feb 20 14:05:07 2012 +0100
@@ -56,10 +56,14 @@
//
uint32_t nSpokes = 8;
std::string animFile = "star-animation.xml";
+ uint8_t useIpv6 = 0;
+ Ipv6Address ipv6AddressBase = Ipv6Address("2001::");
+ Ipv6Prefix ipv6AddressPrefix = Ipv6Prefix(64);
CommandLine cmd;
cmd.AddValue ("nSpokes", "Number of spoke nodes to place in the star", nSpokes);
cmd.AddValue ("animFile", "File Name for Animation Output", animFile);
+ cmd.AddValue ("useIpv6", "use Ipv6", useIpv6);
cmd.Parse (argc, argv);
@@ -74,14 +78,29 @@
star.InstallStack (internet);
NS_LOG_INFO ("Assign IP Addresses.");
- star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.1.0", "255.255.255.0"));
+ if (useIpv6 == 0)
+ {
+ star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.1.0", "255.255.255.0"));
+ }
+ else
+ {
+ star.AssignIpv6Addresses (ipv6AddressBase, ipv6AddressPrefix);
+ }
NS_LOG_INFO ("Create applications.");
//
// Create a packet sink on the star "hub" to receive packets.
//
uint16_t port = 50000;
- Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+ Address hubLocalAddress;
+ if (useIpv6 == 0)
+ {
+ hubLocalAddress = InetSocketAddress (Ipv4Address::GetAny (), port);
+ }
+ else
+ {
+ hubLocalAddress = Inet6SocketAddress (Ipv6Address::GetAny (), port);
+ }
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ());
hubApp.Start (Seconds (1.0));
@@ -98,7 +117,15 @@
for (uint32_t i = 0; i < star.SpokeCount (); ++i)
{
- AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port));
+ AddressValue remoteAddress;
+ if (useIpv6 == 0)
+ {
+ remoteAddress = AddressValue(InetSocketAddress (star.GetHubIpv4Address (i), port));
+ }
+ else
+ {
+ remoteAddress = AddressValue(Inet6SocketAddress (star.GetHubIpv6Address (i), port));
+ }
onOffHelper.SetAttribute ("Remote", remoteAddress);
spokeApps.Add (onOffHelper.Install (star.GetSpokeNode (i)));
}
@@ -109,7 +136,10 @@
//
// Turn on global static routing so we can actually be routed across the star.
//
- Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ if (useIpv6 == 0)
+ {
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ }
// Set the bounding box for animation
star.BoundingBox (1, 1, 100, 100);
--- a/src/network/model/socket.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/network/model/socket.h Mon Feb 20 14:05:07 2012 +0100
@@ -202,20 +202,25 @@
*/
void SetRecvCallback (Callback<void, Ptr<Socket> >);
/**
+ * \brief Allocate a local endpoint for this socket.
* \param address the address to try to allocate
* \returns 0 on success, -1 on failure.
*
- * Allocate a local endpoint for this socket.
*/
virtual int Bind (const Address &address) = 0;
/**
- * Allocate a local endpoint for this socket.
- *
+ * \brief Allocate a local IPv4 endpoint for this socket.
* \returns 0 on success, -1 on failure.
*/
virtual int Bind () = 0;
+ /**
+ * \brief Allocate a local IPv6 endpoint for this socket.
+ * \returns 0 on success, -1 on failure.
+ */
+ virtual int Bind6 () = 0;
+
/**
* \brief Close a socket.
* \returns zero on success, -1 on failure.
--- a/src/network/utils/ipv6-address.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/network/utils/ipv6-address.cc Mon Feb 20 14:05:07 2012 +0100
@@ -301,6 +301,24 @@
return ipv6;
}
+Ipv6Address Ipv6Address::MakeIpv4MappedAddress(Ipv4Address addr)
+{
+ uint8_t buf[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
+ addr.Serialize (&buf[12]);
+ return (Ipv6Address (buf));
+}
+
+Ipv4Address Ipv6Address::GetIpv4MappedAddress() const
+{
+ uint8_t buf[16];
+ Ipv4Address v4Addr;
+
+ Serialize (buf);
+ v4Addr = Ipv4Address::Deserialize (&buf[12]);
+ return (v4Addr);
+}
+
Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix)
{
Ipv6Address ret;
@@ -398,6 +416,26 @@
return false;
}
+bool Ipv6Address::IsLinkLocalMulticast () const
+{
+ if (m_address[0] == 0xff && m_address[1] == 0x02)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool Ipv6Address::IsIpv4MappedAddress ()
+{
+ uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xff };
+ if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
+ {
+ return (true);
+ }
+ return (false);
+}
+
Ipv6Address Ipv6Address::CombinePrefix (Ipv6Prefix const& prefix)
{
Ipv6Address ipv6;
--- a/src/network/utils/ipv6-address.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/network/utils/ipv6-address.h Mon Feb 20 14:05:07 2012 +0100
@@ -28,6 +28,7 @@
#include "ns3/attribute-helper.h"
#include "ns3/address.h"
+#include "ns3/ipv4-address.h"
namespace ns3 {
@@ -122,6 +123,19 @@
static Ipv6Address MakeSolicitedAddress (Ipv6Address addr);
/**
+ * \brief Make the Ipv4-mapped IPv6 address.
+ * \param addr the IPv4 address
+ * \return Ipv4-mapped IPv6 address
+ */
+ static Ipv6Address MakeIpv4MappedAddress (Ipv4Address addr);
+
+ /**
+ * \brief Return the Ipv4 address.
+ * \return Ipv4 address
+ */
+ Ipv4Address GetIpv4MappedAddress () const;
+
+ /**
* \brief Make the autoconfigured IPv6 address with Mac48Address.
* \param addr the MAC address (48 bits).
* \param prefix the IPv6 prefix
@@ -157,6 +171,12 @@
bool IsMulticast () const;
/**
+ * \brief If the IPv6 address is link-local multicast (ff02::/16).
+ * \return true if link-local multicast, false otherwise
+ */
+ bool IsLinkLocalMulticast () const;
+
+ /**
* \brief If the IPv6 address is "all nodes multicast" (ff02::1/8).
* \return true if "all nodes multicast", false otherwise
*/
@@ -208,6 +228,12 @@
static bool IsMatchingType (const Address& address);
/**
+ * \brief If the address is an IPv4-mapped address
+ * \return true if address is an IPv4-mapped address, otherwise false.
+ */
+ bool IsIpv4MappedAddress();
+
+ /**
* \brief Convert to Address object
*/
operator Address () const;
--- a/src/network/utils/packet-socket.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/network/utils/packet-socket.cc Mon Feb 20 14:05:07 2012 +0100
@@ -113,6 +113,12 @@
}
int
+PacketSocket::Bind6 (void)
+{
+ return(Bind());
+}
+
+int
PacketSocket::Bind (const Address &address)
{
NS_LOG_FUNCTION (this << address);
--- a/src/network/utils/packet-socket.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/network/utils/packet-socket.h Mon Feb 20 14:05:07 2012 +0100
@@ -89,6 +89,7 @@
virtual enum SocketType GetSocketType (void) const;
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
+ virtual int Bind6 (void);
virtual int Bind (const Address & address);
virtual int Close (void);
virtual int ShutdownSend (void);
--- a/src/point-to-point-layout/model/point-to-point-dumbbell.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/point-to-point-layout/model/point-to-point-dumbbell.cc Mon Feb 20 14:05:07 2012 +0100
@@ -29,6 +29,7 @@
#include "ns3/node-list.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/vector.h"
+#include "ns3/ipv6-address-generator.h"
NS_LOG_COMPONENT_DEFINE ("PointToPointDumbbellHelper");
@@ -100,6 +101,16 @@
return m_rightLeafInterfaces.GetAddress (i);
}
+Ipv6Address PointToPointDumbbellHelper::GetLeftIpv6Address (uint32_t i) const
+{
+ return m_leftLeafInterfaces6.GetAddress (i, 1);
+}
+
+Ipv6Address PointToPointDumbbellHelper::GetRightIpv6Address (uint32_t i) const
+{
+ return m_rightLeafInterfaces6.GetAddress (i, 1);
+}
+
uint32_t PointToPointDumbbellHelper::LeftCount () const
{ // Number of left side nodes
return m_leftLeaf.GetN ();
@@ -147,6 +158,52 @@
}
}
+void PointToPointDumbbellHelper::AssignIpv6Addresses (Ipv6Address addrBase, Ipv6Prefix prefix)
+{
+ // Assign the router network
+ Ipv6AddressGenerator::Init (addrBase, prefix);
+ Ipv6Address v6network;
+ Ipv6AddressHelper addressHelper;
+
+ v6network = Ipv6AddressGenerator::GetNetwork (prefix);
+ addressHelper.NewNetwork (v6network, prefix);
+ m_routerInterfaces6 = addressHelper.Assign (m_routerDevices);
+ Ipv6AddressGenerator::NextNetwork (prefix);
+
+ // Assign to left side
+ for (uint32_t i = 0; i < LeftCount (); ++i)
+ {
+ v6network = Ipv6AddressGenerator::GetNetwork (prefix);
+ addressHelper.NewNetwork (v6network, prefix);
+
+ NetDeviceContainer ndc;
+ ndc.Add (m_leftLeafDevices.Get (i));
+ ndc.Add (m_leftRouterDevices.Get (i));
+ Ipv6InterfaceContainer ifc = addressHelper.Assign (ndc);
+ Ipv6InterfaceContainer::Iterator it = ifc.Begin ();
+ m_leftLeafInterfaces6.Add ((*it).first, (*it).second);
+ it++;
+ m_leftRouterInterfaces6.Add ((*it).first, (*it).second);
+ Ipv6AddressGenerator::NextNetwork (prefix);
+ }
+ // Assign to right side
+ for (uint32_t i = 0; i < RightCount (); ++i)
+ {
+ v6network = Ipv6AddressGenerator::GetNetwork (prefix);
+ addressHelper.NewNetwork (v6network, prefix);
+
+ NetDeviceContainer ndc;
+ ndc.Add (m_rightLeafDevices.Get (i));
+ ndc.Add (m_rightRouterDevices.Get (i));
+ Ipv6InterfaceContainer ifc = addressHelper.Assign (ndc);
+ Ipv6InterfaceContainer::Iterator it = ifc.Begin ();
+ m_rightLeafInterfaces6.Add ((*it).first, (*it).second);
+ it++;
+ m_rightRouterInterfaces6.Add ((*it).first, (*it).second);
+ Ipv6AddressGenerator::NextNetwork (prefix);
+ }
+}
+
void PointToPointDumbbellHelper::BoundingBox (double ulx, double uly, // Upper left x/y
double lrx, double lry) // Lower right y
--- a/src/point-to-point-layout/model/point-to-point-dumbbell.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/point-to-point-layout/model/point-to-point-dumbbell.h Mon Feb 20 14:05:07 2012 +0100
@@ -25,8 +25,10 @@
#include "point-to-point-helper.h"
#include "ipv4-address-helper.h"
+#include "ipv6-address-helper.h"
#include "internet-stack-helper.h"
#include "ipv4-interface-container.h"
+#include "ipv6-interface-container.h"
namespace ns3 {
@@ -101,6 +103,16 @@
Ipv4Address GetRightIpv4Address (uint32_t i) const; // Get right leaf address
/**
+ * \returns an Ipv6Address of the i'th left leaf
+ */
+ Ipv6Address GetLeftIpv6Address (uint32_t i ) const; // Get left leaf address
+
+ /**
+ * \returns an Ipv6Address of the i'th right leaf
+ */
+ Ipv6Address GetRightIpv6Address (uint32_t i) const; // Get right leaf address
+
+ /**
* \returns total number of left side leaf nodes
*/
uint32_t LeftCount () const;
@@ -131,6 +143,13 @@
Ipv4AddressHelper routerIp);
/**
+ * \param network an IPv6 address representing the network portion
+ * of the IPv6 Address
+ * \param prefix the prefix length
+ */
+ void AssignIpv6Addresses (Ipv6Address network, Ipv6Prefix prefix);
+
+ /**
* Sets up the node canvas locations for every node in the dumbbell.
* This is needed for use with the animation interface
*
@@ -155,6 +174,11 @@
Ipv4InterfaceContainer m_rightLeafInterfaces;
Ipv4InterfaceContainer m_rightRouterInterfaces;
Ipv4InterfaceContainer m_routerInterfaces;
+ Ipv6InterfaceContainer m_leftLeafInterfaces6;
+ Ipv6InterfaceContainer m_leftRouterInterfaces6;
+ Ipv6InterfaceContainer m_rightLeafInterfaces6;
+ Ipv6InterfaceContainer m_rightRouterInterfaces6;
+ Ipv6InterfaceContainer m_routerInterfaces6;
};
} // namespace ns3
--- a/src/point-to-point-layout/model/point-to-point-grid.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/point-to-point-layout/model/point-to-point-grid.cc Mon Feb 20 14:05:07 2012 +0100
@@ -24,6 +24,7 @@
#include "ns3/string.h"
#include "ns3/vector.h"
#include "ns3/log.h"
+#include "ns3/ipv6-address-generator.h"
NS_LOG_COMPONENT_DEFINE ("PointToPointGridHelper");
@@ -131,6 +132,56 @@
}
void
+PointToPointGridHelper::AssignIpv6Addresses(Ipv6Address addrBase, Ipv6Prefix prefix)
+{
+ Ipv6AddressGenerator::Init(addrBase, prefix);
+ Ipv6Address v6network;
+ Ipv6AddressHelper addrHelper;
+
+ // Assign addresses to all row devices in the grid.
+ // These devices are stored in a vector. Each row
+ // of the grid has all the row devices in one entry
+ // of the vector. These entries come in pairs.
+ for (uint32_t i = 0; i < m_rowDevices.size (); ++i)
+ {
+ Ipv6InterfaceContainer rowInterfaces;
+ NetDeviceContainer rowContainer = m_rowDevices[i];
+ for (uint32_t j = 0; j < rowContainer.GetN (); j+=2)
+ {
+ v6network = Ipv6AddressGenerator::GetNetwork (prefix);
+ addrHelper.NewNetwork(v6network, prefix);
+ Ipv6InterfaceContainer ic = addrHelper.Assign (rowContainer.Get (j));
+ rowInterfaces.Add (ic);
+ ic = addrHelper.Assign (rowContainer.Get (j+1));
+ rowInterfaces.Add (ic);
+ Ipv6AddressGenerator::NextNetwork (prefix);
+ }
+ m_rowInterfaces6.push_back (rowInterfaces);
+ }
+
+ // Assign addresses to all col devices in the grid.
+ // These devices are stored in a vector. Each col
+ // of the grid has all the col devices in one entry
+ // of the vector. These entries come in pairs.
+ for (uint32_t i = 0; i < m_colDevices.size (); ++i)
+ {
+ Ipv6InterfaceContainer colInterfaces;
+ NetDeviceContainer colContainer = m_colDevices[i];
+ for (uint32_t j = 0; j < colContainer.GetN (); j+=2)
+ {
+ v6network = Ipv6AddressGenerator::GetNetwork (prefix);
+ addrHelper.NewNetwork(v6network, prefix);
+ Ipv6InterfaceContainer ic = addrHelper.Assign (colContainer.Get (j));
+ colInterfaces.Add (ic);
+ ic = addrHelper.Assign (colContainer.Get (j+1));
+ colInterfaces.Add (ic);
+ Ipv6AddressGenerator::NextNetwork (prefix);
+ }
+ m_colInterfaces6.push_back (colInterfaces);
+ }
+}
+
+void
PointToPointGridHelper::BoundingBox (double ulx, double uly,
double lrx, double lry)
{
@@ -214,4 +265,30 @@
}
}
+Ipv6Address
+PointToPointGridHelper::GetIpv6Address (uint32_t row, uint32_t col)
+{
+ if (row > m_nodes.size () - 1 ||
+ col > m_nodes.at (row).GetN () - 1)
+ {
+ NS_FATAL_ERROR ("Index out of bounds in PointToPointGridHelper::GetIpv4Address.");
+ }
+
+ // Right now this just gets one of the addresses of the
+ // specified node. The exact device can't be specified.
+ // If you picture the grid, the address returned is the
+ // address of the left (row) device of all nodes, with
+ // the exception of the left-most nodes in the grid;
+ // in which case the right (row) device address is
+ // returned
+ if (col == 0)
+ {
+ return (m_rowInterfaces6.at (row)).GetAddress (0, 1);
+ }
+ else
+ {
+ return (m_rowInterfaces6.at (row)).GetAddress ((2*col)-1, 1);
+ }
+}
+
} // namespace ns3
--- a/src/point-to-point-layout/model/point-to-point-grid.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/point-to-point-layout/model/point-to-point-grid.h Mon Feb 20 14:05:07 2012 +0100
@@ -24,7 +24,9 @@
#include "internet-stack-helper.h"
#include "point-to-point-helper.h"
#include "ipv4-address-helper.h"
+#include "ipv6-address-helper.h"
#include "ipv4-interface-container.h"
+#include "ipv6-interface-container.h"
#include "net-device-container.h"
namespace ns3 {
@@ -85,6 +87,24 @@
Ipv4Address GetIpv4Address (uint32_t row, uint32_t col);
/**
+ * This returns an Ipv6 address at the node specified by
+ * the (row, col) address. Technically, a node will have
+ * multiple interfaces in the grid; therefore, it also has
+ * multiple Ipv6 addresses. This method only returns one of
+ * the addresses. If you picture the grid, the address returned
+ * is the left row device of all the nodes, except the left-most
+ * grid nodes, which returns the right row device.
+ *
+ * \param row the row address of the node desired
+ *
+ * \param col the column address of the node desired
+ *
+ * \returns Ipv6Address of one of the interfaces of the node
+ * specified by the (row, col) address
+ */
+ Ipv6Address GetIpv6Address (uint32_t row, uint32_t col);
+
+ /**
* \param stack an InternetStackHelper which is used to install
* on every node in the grid
*/
@@ -102,6 +122,15 @@
void AssignIpv4Addresses (Ipv4AddressHelper rowIp, Ipv4AddressHelper colIp);
/**
+ * Assigns Ipv6 addresses to all the row and column interfaces
+ *
+ * \param network an IPv6 address representing the network portion
+ * of the IPv6 Address
+ * \param prefix the prefix length
+ */
+ void AssignIpv6Addresses (Ipv6Address network, Ipv6Prefix prefix);
+
+ /**
* Sets up the node canvas locations for every node in the grid.
* This is needed for use with the animation interface
*
@@ -119,6 +148,8 @@
std::vector<NetDeviceContainer> m_colDevices;
std::vector<Ipv4InterfaceContainer> m_rowInterfaces;
std::vector<Ipv4InterfaceContainer> m_colInterfaces;
+ std::vector<Ipv6InterfaceContainer> m_rowInterfaces6;
+ std::vector<Ipv6InterfaceContainer> m_colInterfaces6;
std::vector<NodeContainer> m_nodes;
};
--- a/src/point-to-point-layout/model/point-to-point-star.cc Sun Feb 19 16:22:51 2012 +0100
+++ b/src/point-to-point-layout/model/point-to-point-star.cc Mon Feb 20 14:05:07 2012 +0100
@@ -25,6 +25,7 @@
#include "ns3/node-list.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/vector.h"
+#include "ns3/ipv6-address-generator.h"
NS_LOG_COMPONENT_DEFINE ("PointToPointStarHelper");
@@ -72,6 +73,18 @@
return m_spokeInterfaces.GetAddress (i);
}
+Ipv6Address
+PointToPointStarHelper::GetHubIpv6Address (uint32_t i) const
+{
+ return m_hubInterfaces6.GetAddress (i, 1);
+}
+
+Ipv6Address
+PointToPointStarHelper::GetSpokeIpv6Address (uint32_t i) const
+{
+ return m_spokeInterfaces6.GetAddress (i, 1);
+}
+
uint32_t
PointToPointStarHelper::SpokeCount () const
{
@@ -97,6 +110,27 @@
}
void
+PointToPointStarHelper::AssignIpv6Addresses (Ipv6Address addrBase, Ipv6Prefix prefix)
+{
+ Ipv6AddressGenerator::Init (addrBase, prefix);
+ Ipv6Address v6network;
+ Ipv6AddressHelper addressHelper;
+
+ for (uint32_t i = 0; i < m_spokes.GetN (); ++i)
+ {
+ v6network = Ipv6AddressGenerator::GetNetwork (prefix);
+ addressHelper.NewNetwork(v6network, prefix);
+
+ Ipv6InterfaceContainer ic = addressHelper.Assign (m_hubDevices.Get (i));
+ m_hubInterfaces6.Add (ic);
+ ic = addressHelper.Assign (m_spokeDevices.Get (i));
+ m_spokeInterfaces6.Add (ic);
+
+ Ipv6AddressGenerator::NextNetwork (prefix);
+ }
+}
+
+void
PointToPointStarHelper::BoundingBox (double ulx, double uly,
double lrx, double lry)
{
--- a/src/point-to-point-layout/model/point-to-point-star.h Sun Feb 19 16:22:51 2012 +0100
+++ b/src/point-to-point-layout/model/point-to-point-star.h Mon Feb 20 14:05:07 2012 +0100
@@ -23,8 +23,10 @@
#include "point-to-point-helper.h"
#include "ipv4-address-helper.h"
+#include "ipv6-address-helper.h"
#include "internet-stack-helper.h"
#include "ipv4-interface-container.h"
+#include "ipv6-interface-container.h"
namespace ns3 {
@@ -87,6 +89,20 @@
Ipv4Address GetSpokeIpv4Address (uint32_t i) const;
/**
+ * \param i index into the hub interfaces
+ *
+ * \returns Ipv6Address according to indexed hub interface
+ */
+ Ipv6Address GetHubIpv6Address (uint32_t i) const;
+
+ /**
+ * \param i index into the spoke interfaces
+ *
+ * \returns Ipv6Address according to indexed spoke interface
+ */
+ Ipv6Address GetSpokeIpv6Address (uint32_t i) const;
+
+ /**
* \returns the total number of spokes in the star
*/
uint32_t SpokeCount () const;
@@ -105,6 +121,13 @@
void AssignIpv4Addresses (Ipv4AddressHelper address);
/**
+ * \param network an IPv6 address representing the network portion
+ * of the IPv6 Address
+ * \param prefix the prefix length
+ */
+ void AssignIpv6Addresses (Ipv6Address network, Ipv6Prefix prefix);
+
+ /**
* Sets up the node canvas locations for every node in the star.
* This is needed for use with the animation interface
*
@@ -122,6 +145,8 @@
NetDeviceContainer m_spokeDevices;
Ipv4InterfaceContainer m_hubInterfaces;
Ipv4InterfaceContainer m_spokeInterfaces;
+ Ipv6InterfaceContainer m_hubInterfaces6;
+ Ipv6InterfaceContainer m_spokeInterfaces6;
};
} // namespace ns3