Bug 932 - Support IP_HDRINCL option for Ipv4RawSocket
This commit is contained in:
@@ -518,6 +518,17 @@ Ipv4L3Protocol::IsUnicast (Ipv4Address ad, Ipv4Mask interfaceMask) const
|
||||
return !ad.IsMulticast () && !ad.IsSubnetDirectedBroadcast (interfaceMask);
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@@ -162,6 +162,15 @@ public:
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -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 @@ Ipv4RawSocketImpl::GetTypeId (void)
|
||||
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 @@ Ipv4RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags,
|
||||
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 @@ Ipv4RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags,
|
||||
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();
|
||||
|
||||
@@ -59,6 +59,7 @@ private:
|
||||
bool m_shutdownSend;
|
||||
bool m_shutdownRecv;
|
||||
uint32_t m_icmpFilter;
|
||||
bool m_iphdrincl;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -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 @@ class Ipv4RawSocketImplTest: public TestCase
|
||||
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 @@ Ipv4RawSocketImplTest::SendData (Ptr<Socket> socket, std::string to)
|
||||
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 @@ Ipv4RawSocketImplTest::DoRun (void)
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user