20 #include "ns3/assert.h"
22 #include "ns3/nstime.h"
24 #include "ns3/packet.h"
26 #include "ns3/ipv4-route.h"
28 #include "ns3/object-vector.h"
29 #include "ns3/string.h"
30 #include "tcp-header.h"
31 #include "ipv4-end-point-demux.h"
32 #include "ipv4-end-point.h"
33 #include "ipv4-l3-protocol.h"
34 #include "nsc-tcp-l4-protocol.h"
35 #include "nsc-tcp-socket-impl.h"
36 #include "nsc-sysctl.h"
37 #include "nsc-tcp-socket-factory-impl.h"
38 #include "sim_interface.h"
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
52 NS_OBJECT_ENSURE_REGISTERED (NscTcpL4Protocol);
55 const uint8_t NscTcpL4Protocol::PROT_NUMBER = 6;
62 virtual void send_callback (
const void *data,
int datalen);
63 virtual void wakeup ();
64 virtual void gettime (
unsigned int *,
unsigned int *);
75 NscInterfaceImpl::send_callback (
const void *data,
int datalen)
77 m_prot->send_callback (data, datalen);
80 NscInterfaceImpl::wakeup ()
85 NscInterfaceImpl::gettime (
unsigned int *sec,
unsigned int *usec)
87 m_prot->gettime (sec,usec);
91 #undef NS_LOG_APPEND_CONTEXT
92 #define NS_LOG_APPEND_CONTEXT \
93 if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
96 NscTcpL4Protocol::GetTypeId (
void)
98 static TypeId tid = TypeId (
"ns3::NscTcpL4Protocol")
99 .SetParent<IpL4Protocol> ()
100 .AddConstructor<NscTcpL4Protocol>()
101 .AddAttribute (
"SocketList",
"The list of sockets associated to this protocol.",
102 ObjectVectorValue (),
103 MakeObjectVectorAccessor (&NscTcpL4Protocol::m_sockets),
104 MakeObjectVectorChecker<NscTcpSocketImpl> ())
105 .AddAttribute (
"Library",
106 "Set the linux library to be used to create the stack",
108 StringValue (
"liblinux2.6.26.so"),
109 MakeStringAccessor (&NscTcpL4Protocol::GetNscLibrary,&NscTcpL4Protocol::SetNscLibrary),
110 MakeStringChecker ())
124 m_softTimer (
Timer::CANCEL_ON_DESTROY)
126 m_dlopenHandle = NULL;
130 NscTcpL4Protocol::~NscTcpL4Protocol ()
133 dlclose (m_dlopenHandle);
137 NscTcpL4Protocol::SetNscLibrary (
const std::string &soname)
141 m_nscLibrary = soname;
143 m_dlopenHandle = dlopen (soname.c_str (), RTLD_NOW);
144 if (m_dlopenHandle == NULL)
150 NscTcpL4Protocol::GetNscLibrary ()
const
155 NscTcpL4Protocol::SetNode (Ptr<Node> node)
166 FCreateStack create = (FCreateStack)dlsym (m_dlopenHandle,
"nsc_create_stack");
168 m_nscStack = create (m_nscInterface, m_nscInterface, external_rand);
169 int hzval = m_nscStack->
get_hz ();
173 m_softTimer.
SetFunction (&NscTcpL4Protocol::SoftInterrupt,
this);
175 m_nscStack->init (hzval);
179 Ptr<Ns3NscStack> nscStack = Create<Ns3NscStack> ();
180 nscStack->SetStack (m_nscStack);
181 node->AggregateObject (nscStack);
195 Ptr<Node>node = this->GetObject<Node> ();
199 if (ipv4 != 0 && m_downTarget.IsNull ())
201 this->SetNode (node);
204 tcpFactory->SetTcp (
this);
219 NscTcpL4Protocol::GetVersion (
void)
const
229 for (std::vector<
Ptr<NscTcpSocketImpl> >::iterator i = m_sockets.begin (); i != m_sockets.end (); i++)
236 if (m_endPoints != 0)
242 delete m_nscInterface;
244 m_downTarget.Nullify ();
254 socket->SetNode (m_node);
255 socket->SetTcp (
this);
256 m_sockets.push_back (socket);
261 NscTcpL4Protocol::Allocate (
void)
264 return m_endPoints->Allocate ();
268 NscTcpL4Protocol::Allocate (Ipv4Address address)
271 return m_endPoints->Allocate (address);
275 NscTcpL4Protocol::Allocate (uint16_t port)
278 return m_endPoints->Allocate (port);
282 NscTcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
285 return m_endPoints->Allocate (address, port);
289 NscTcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
290 Ipv4Address peerAddress, uint16_t peerPort)
292 NS_LOG_FUNCTION (
this << localAddress << localPort << peerAddress << peerPort);
293 return m_endPoints->Allocate (localAddress, localPort,
294 peerAddress, peerPort);
298 NscTcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
304 IpL4Protocol::RxStatus
311 uint32_t packetSize = packet->
GetSize ();
327 packetSize = packet->
GetSize ();
329 uint8_t *buf =
new uint8_t[packetSize];
331 const uint8_t *data =
const_cast<uint8_t *
>(buf);
334 m_nscStack->if_receive_packet (0, data, packetSize);
338 return IpL4Protocol::RX_OK;
341 IpL4Protocol::RxStatus
344 return IpL4Protocol::RX_ENDPOINT_UNREACH;
347 void NscTcpL4Protocol::SoftInterrupt (
void)
349 m_nscStack->timer_interrupt ();
350 m_nscStack->increment_ticks ();
354 void NscTcpL4Protocol::send_callback (
const void* data,
int datalen)
357 uint32_t ipv4Saddr, ipv4Daddr;
365 const uint8_t *rawdata =
reinterpret_cast<const uint8_t *
>(data);
368 p = Create<Packet> (rawdata, datalen);
371 const uint32_t *ipheader =
reinterpret_cast<const uint32_t *
>(data);
372 ipv4Saddr = *(ipheader+3);
373 ipv4Daddr = *(ipheader+4);
375 Ipv4Address saddr (ntohl (ipv4Saddr));
376 Ipv4Address daddr (ntohl (ipv4Daddr));
378 Ptr<Ipv4L3Protocol> ipv4 = m_node->
GetObject<Ipv4L3Protocol> ();
379 NS_ASSERT_MSG (ipv4,
"nsc callback invoked, but node has no ipv4 object");
381 m_downTarget (p, saddr, daddr, PROT_NUMBER, 0);
382 m_nscStack->if_send_finish (0);
385 void NscTcpL4Protocol::wakeup ()
391 Ipv4EndPointDemux::EndPoints endPoints = m_endPoints->GetAllEndPoints ();
392 for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
393 endPoint != endPoints.end (); endPoint++) {
395 (*endPoint)->ForwardUp (NULL, Ipv4Header (), 0, 0);
399 void NscTcpL4Protocol::gettime (
unsigned int* sec,
unsigned int* usec)
405 int64_t us = t.GetMicroSeconds ();
406 *sec = us / (1000*1000);
407 *usec = us - *sec * (1000*1000);
411 void NscTcpL4Protocol::AddInterface (
void)
413 Ptr<Ipv4> ip = m_node->
GetObject<Ipv4> ();
414 const uint32_t nInterfaces = ip->GetNInterfaces ();
416 NS_ASSERT_MSG (nInterfaces <= 2,
"nsc does not support multiple interfaces per node");
421 for (uint32_t i = 1; i < nInterfaces; i++)
423 Ipv4InterfaceAddress ifAddr = ip->GetAddress (i, 0);
424 Ipv4Address addr = ifAddr.GetLocal ();
425 Ipv4Mask mask = ifAddr.GetMask ();
426 uint16_t mtu = ip->GetMtu (i);
428 std::ostringstream addrOss, maskOss;
430 addr.Print (addrOss);
431 mask.Print (maskOss);
433 NS_LOG_LOGIC (
"if_attach " << addrOss.str ().c_str () <<
" " << maskOss.str ().c_str () <<
" " << mtu);
435 std::string addrStr = addrOss.str ();
436 std::string maskStr = maskOss.str ();
437 const char* addrCStr = addrStr.c_str ();
438 const char* maskCStr = maskStr.c_str ();
439 m_nscStack->if_attach (addrCStr, maskCStr, mtu);
454 m_nscStack->add_default_gateway (addrOss.str ().c_str ());
462 m_downTarget = callback;
470 IpL4Protocol::DownTargetCallback
477 NscTcpL4Protocol::GetDownTarget6 (
void)
const
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_FUNCTION(parameters)
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
Ptr< Socket > CreateSocket(void)
uint32_t GetSize(void) const
virtual void DoDispose(void)
#define NS_FATAL_ERROR(msg)
fatal error handling
Demultiplexes packets to various transport layer endpoints.
virtual void NotifyNewAggregate()
virtual void DoDispose(void)
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
void AggregateObject(Ptr< Object > other)
void SetDelay(const Time &delay)
#define NS_LOG_LOGIC(msg)
virtual void NotifyNewAggregate(void)
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
virtual IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Receive a packet up the protocol stack.
NscTcpL4Protocol()
Constructor.
#define NS_ASSERT_MSG(condition, message)
virtual int GetProtocolNumber(void) const
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Ptr< T > GetObject(void) const
void AddHeader(const Header &header)
A representation of an internet endpoint/connection.
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const