--- a/src/internet-stack/ipv4-l3-protocol.cc Fri Jun 04 07:05:22 2010 +0900
+++ b/src/internet-stack/ipv4-l3-protocol.cc Fri Jun 04 07:09:30 2010 +0900
@@ -520,6 +520,17 @@
void
Ipv4L3Protocol::Send (Ptr<Packet> packet,
+ Ipv4Header ipHeader,
+ Ptr<Ipv4Route> route)
+{
+ NS_LOG_FUNCTION (this << packet << ipHeader << route);
+ Ipv4Header hdr;
+ packet->RemoveHeader (hdr);
+ SendRealOut (route, packet, hdr);
+}
+
+void
+Ipv4L3Protocol::Send (Ptr<Packet> packet,
Ipv4Address source,
Ipv4Address destination,
uint8_t protocol,
--- a/src/internet-stack/ipv4-l3-protocol.h Fri Jun 04 07:05:22 2010 +0900
+++ b/src/internet-stack/ipv4-l3-protocol.h Fri Jun 04 07:09:30 2010 +0900
@@ -162,6 +162,15 @@
*/
void Send (Ptr<Packet> packet, Ipv4Address source,
Ipv4Address destination, uint8_t protocol, Ptr<Ipv4Route> route);
+ /**
+ * \param packet packet to send
+ * \param ipHeader IP Heeader
+ * \param route route entry
+ *
+ * Higher-level layers call this method to send a packet with IPv4 Header
+ * (Intend to be used with IpHeaderInclude attribute.)
+ */
+ void Send (Ptr<Packet> packet, Ipv4Header ipHeader, Ptr<Ipv4Route> route);
uint32_t AddInterface (Ptr<NetDevice> device);
Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
--- a/src/internet-stack/ipv4-raw-socket-impl.cc Fri Jun 04 07:05:22 2010 +0900
+++ b/src/internet-stack/ipv4-raw-socket-impl.cc Fri Jun 04 07:09:30 2010 +0900
@@ -6,6 +6,7 @@
#include "ns3/node.h"
#include "ns3/packet.h"
#include "ns3/uinteger.h"
+#include "ns3/boolean.h"
#include "ns3/log.h"
NS_LOG_COMPONENT_DEFINE ("Ipv4RawSocketImpl");
@@ -28,6 +29,19 @@
UintegerValue (0),
MakeUintegerAccessor (&Ipv4RawSocketImpl::m_icmpFilter),
MakeUintegerChecker<uint32_t> ())
+ //
+ // from raw (7), linux, returned length of Send/Recv should be
+ //
+ // | IP_HDRINC on | off |
+ // ----------+---------------+-------------+-
+ // Send(Ipv4)| hdr + payload | payload |
+ // Recv(Ipv4)| hdr + payload | hdr+payload |
+ // ----------+---------------+-------------+-
+ .AddAttribute ("IpHeaderInclude",
+ "Include IP Header information (a.k.a setsockopt (IP_HDRINCL)).",
+ BooleanValue (false),
+ MakeBooleanAccessor (&Ipv4RawSocketImpl::m_iphdrincl),
+ MakeBooleanChecker ())
;
return tid;
}
@@ -174,8 +188,16 @@
if (ipv4->GetRoutingProtocol ())
{
Ipv4Header header;
- header.SetDestination (dst);
- header.SetProtocol (m_protocol);
+ if (!m_iphdrincl)
+ {
+ header.SetDestination (dst);
+ header.SetProtocol (m_protocol);
+ }
+ else
+ {
+ p->PeekHeader (header);
+ dst = header.GetDestination ();
+ }
SocketErrno errno_ = ERROR_NOTERROR;//do not use errno as it is the standard C last error number
Ptr<Ipv4Route> route;
Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a source address
@@ -192,7 +214,14 @@
if (route != 0)
{
NS_LOG_LOGIC ("Route exists");
- ipv4->Send (p, route->GetSource (), dst, m_protocol, route);
+ if (!m_iphdrincl)
+ {
+ ipv4->Send (p, route->GetSource (), dst, m_protocol, route);
+ }
+ else
+ {
+ ipv4->Send (p, header, route);
+ }
NotifyDataSent (p->GetSize ());
NotifySend (GetTxAvailable ());
return p->GetSize();
--- a/src/internet-stack/ipv4-raw-socket-impl.h Fri Jun 04 07:05:22 2010 +0900
+++ b/src/internet-stack/ipv4-raw-socket-impl.h Fri Jun 04 07:09:30 2010 +0900
@@ -59,6 +59,7 @@
bool m_shutdownSend;
bool m_shutdownRecv;
uint32_t m_icmpFilter;
+ bool m_iphdrincl;
};
} // namespace ns3
--- a/src/internet-stack/ipv4-raw-test.cc Fri Jun 04 07:05:22 2010 +0900
+++ b/src/internet-stack/ipv4-raw-test.cc Fri Jun 04 07:09:30 2010 +0900
@@ -33,6 +33,7 @@
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/boolean.h"
#include "arp-l3-protocol.h"
#include "ipv4-l3-protocol.h"
@@ -74,6 +75,8 @@
Ptr<Packet> m_receivedPacket2;
void DoSendData (Ptr<Socket> socket, std::string to);
void SendData (Ptr<Socket> socket, std::string to);
+ void DoSendData_IpHdr (Ptr<Socket> socket, std::string to);
+ void SendData_IpHdr (Ptr<Socket> socket, std::string to);
public:
virtual bool DoRun (void);
@@ -139,6 +142,35 @@
Simulator::Run ();
}
+void
+Ipv4RawSocketImplTest::DoSendData_IpHdr (Ptr<Socket> socket, std::string to)
+{
+ Address realTo = InetSocketAddress (Ipv4Address(to.c_str()), 0);
+ socket->SetAttribute ("IpHeaderInclude", BooleanValue (true));
+ Ptr<Packet> p = Create<Packet> (123);
+ Ipv4Header ipHeader;
+ ipHeader.SetSource (Ipv4Address ("10.0.0.2"));
+ ipHeader.SetDestination (Ipv4Address (to.c_str ()));
+ ipHeader.SetProtocol (0);
+ ipHeader.SetPayloadSize (p->GetSize ());
+ ipHeader.SetTtl (255);
+ p->AddHeader (ipHeader);
+
+ NS_TEST_EXPECT_MSG_EQ (socket->SendTo (p, 0, realTo),
+ 143, to);
+ socket->SetAttribute ("IpHeaderInclude", BooleanValue (false));
+}
+
+void
+Ipv4RawSocketImplTest::SendData_IpHdr (Ptr<Socket> socket, std::string to)
+{
+ m_receivedPacket = Create<Packet> ();
+ m_receivedPacket2 = Create<Packet> ();
+ Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0),
+ &Ipv4RawSocketImplTest::DoSendData_IpHdr, this, socket, to);
+ Simulator::Run ();
+}
+
bool
Ipv4RawSocketImplTest::DoRun (void)
{
@@ -229,6 +261,14 @@
m_receivedPacket->RemoveAllByteTags ();
m_receivedPacket2->RemoveAllByteTags ();
+ // Unicast w/ header test
+ SendData_IpHdr (txSocket, "10.0.0.1");
+ NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 143, "recv(hdrincl): 10.0.0.1");
+ NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second interface should not receive it");
+
+ m_receivedPacket->RemoveAllByteTags ();
+ m_receivedPacket2->RemoveAllByteTags ();
+
#if 0
// Simple broadcast test