00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ns3/assert.h"
00021 #include "ns3/log.h"
00022 #include "ns3/nstime.h"
00023
00024 #include "ns3/packet.h"
00025 #include "ns3/node.h"
00026
00027 #include "tcp-header.h"
00028 #include "ipv4-end-point-demux.h"
00029 #include "ipv4-end-point.h"
00030 #include "ipv4-l3-protocol.h"
00031 #include "nsc-tcp-l4-protocol.h"
00032 #include "nsc-tcp-socket-impl.h"
00033 #include "nsc-sysctl.h"
00034
00035 #include "tcp-typedefs.h"
00036
00037 #include <vector>
00038 #include <sstream>
00039 #include <dlfcn.h>
00040 #include <iomanip>
00041
00042 #include <netinet/in.h>
00043 #include <arpa/inet.h>
00044
00045 NS_LOG_COMPONENT_DEFINE ("NscTcpL4Protocol");
00046
00047 namespace ns3 {
00048
00049 NS_OBJECT_ENSURE_REGISTERED (NscTcpL4Protocol);
00050
00051
00052 const uint8_t NscTcpL4Protocol::PROT_NUMBER = 6;
00053
00054 ObjectFactory
00055 NscTcpL4Protocol::GetDefaultRttEstimatorFactory (void)
00056 {
00057 ObjectFactory factory;
00058 factory.SetTypeId (RttMeanDeviation::GetTypeId ());
00059 return factory;
00060 }
00061
00062 TypeId
00063 NscTcpL4Protocol::GetTypeId (void)
00064 {
00065 static TypeId tid = TypeId ("ns3::NscTcpL4Protocol")
00066 .SetParent<Ipv4L4Protocol> ()
00067
00068 .AddAttribute ("RttEstimatorFactory",
00069 "How RttEstimator objects are created.",
00070 ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
00071 MakeObjectFactoryAccessor (&NscTcpL4Protocol::m_rttFactory),
00072 MakeObjectFactoryChecker ())
00073 ;
00074 return tid;
00075 }
00076
00077 int external_rand()
00078 {
00079 return 1;
00080 }
00081
00082 NscTcpL4Protocol::NscTcpL4Protocol ()
00083 : m_endPoints (new Ipv4EndPointDemux ()),
00084 m_nscStack (0),
00085 m_softTimer (Timer::CANCEL_ON_DESTROY)
00086 {
00087 m_dlopenHandle = NULL;
00088 NS_LOG_LOGIC("Made a NscTcpL4Protocol "<<this);
00089 }
00090
00091 NscTcpL4Protocol::~NscTcpL4Protocol ()
00092 {
00093 NS_LOG_FUNCTION (this);
00094 dlclose(m_dlopenHandle);
00095 }
00096
00097 void
00098 NscTcpL4Protocol::SetNscLibrary(const std::string &soname)
00099 {
00100 NS_ASSERT(!m_dlopenHandle);
00101 m_dlopenHandle = dlopen(soname.c_str (), RTLD_NOW);
00102 if (m_dlopenHandle == NULL)
00103 NS_FATAL_ERROR (dlerror());
00104 }
00105
00106 void
00107 NscTcpL4Protocol::SetNode (Ptr<Node> node)
00108 {
00109 m_node = node;
00110
00111 if (m_nscStack)
00112 {
00113 return;
00114 }
00115
00116 NS_ASSERT(m_dlopenHandle);
00117
00118 FCreateStack create = (FCreateStack)dlsym(m_dlopenHandle, "nsc_create_stack");
00119 NS_ASSERT(create);
00120 m_nscStack = create(this, this, external_rand);
00121 int hzval = m_nscStack->get_hz();
00122
00123 NS_ASSERT(hzval > 0);
00124
00125 m_softTimer.SetFunction (&NscTcpL4Protocol::SoftInterrupt, this);
00126 m_softTimer.SetDelay (MilliSeconds (1000/hzval));
00127 m_nscStack->init(hzval);
00128
00129
00130
00131 Ptr<Ns3NscStack> nscStack = Create<Ns3NscStack> ();
00132 nscStack->SetStack (m_nscStack);
00133 node->AggregateObject (nscStack);
00134
00135 m_softTimer.Schedule ();
00136
00137
00138
00139 Simulator::ScheduleNow (&NscTcpL4Protocol::AddInterface, this);
00140 }
00141
00142 int
00143 NscTcpL4Protocol::GetProtocolNumber (void) const
00144 {
00145 return PROT_NUMBER;
00146 }
00147 int
00148 NscTcpL4Protocol::GetVersion (void) const
00149 {
00150 return 2;
00151 }
00152
00153 void
00154 NscTcpL4Protocol::DoDispose (void)
00155 {
00156 NS_LOG_FUNCTION (this);
00157 if (m_endPoints != 0)
00158 {
00159 delete m_endPoints;
00160 m_endPoints = 0;
00161 }
00162 m_node = 0;
00163 Ipv4L4Protocol::DoDispose ();
00164 }
00165
00166 Ptr<Socket>
00167 NscTcpL4Protocol::CreateSocket (void)
00168 {
00169 NS_LOG_FUNCTION (this);
00170
00171 Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
00172 Ptr<NscTcpSocketImpl> socket = CreateObject<NscTcpSocketImpl> ();
00173 socket->SetNode (m_node);
00174 socket->SetTcp (this);
00175 socket->SetRtt (rtt);
00176 return socket;
00177 }
00178
00179 Ipv4EndPoint *
00180 NscTcpL4Protocol::Allocate (void)
00181 {
00182 NS_LOG_FUNCTION (this);
00183 return m_endPoints->Allocate ();
00184 }
00185
00186 Ipv4EndPoint *
00187 NscTcpL4Protocol::Allocate (Ipv4Address address)
00188 {
00189 NS_LOG_FUNCTION (this << address);
00190 return m_endPoints->Allocate (address);
00191 }
00192
00193 Ipv4EndPoint *
00194 NscTcpL4Protocol::Allocate (uint16_t port)
00195 {
00196 NS_LOG_FUNCTION (this << port);
00197 return m_endPoints->Allocate (port);
00198 }
00199
00200 Ipv4EndPoint *
00201 NscTcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
00202 {
00203 NS_LOG_FUNCTION (this << address << port);
00204 return m_endPoints->Allocate (address, port);
00205 }
00206
00207 Ipv4EndPoint *
00208 NscTcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
00209 Ipv4Address peerAddress, uint16_t peerPort)
00210 {
00211 NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
00212 return m_endPoints->Allocate (localAddress, localPort,
00213 peerAddress, peerPort);
00214 }
00215
00216 void
00217 NscTcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
00218 {
00219 NS_LOG_FUNCTION (this << endPoint);
00220
00221 }
00222
00223 Ipv4L4Protocol::RxStatus
00224 NscTcpL4Protocol::Receive (Ptr<Packet> packet,
00225 Ipv4Address const &source,
00226 Ipv4Address const &destination,
00227 Ptr<Ipv4Interface> incomingInterface)
00228 {
00229 NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
00230 Ipv4Header ipHeader;
00231 uint32_t packetSize = packet->GetSize();
00232
00233
00234
00235
00236
00237
00238 ipHeader.SetSource (source);
00239 ipHeader.SetDestination (destination);
00240 ipHeader.SetProtocol (PROT_NUMBER);
00241 ipHeader.SetPayloadSize (packetSize);
00242 ipHeader.SetTtl (1);
00243
00244 ipHeader.EnableChecksum ();
00245
00246 packet->AddHeader(ipHeader);
00247 packetSize = packet->GetSize();
00248
00249 const uint8_t *data = const_cast<uint8_t *>(packet->PeekData());
00250
00251
00252 m_nscStack->if_receive_packet(0, data, packetSize);
00253 wakeup ();
00254 return Ipv4L4Protocol::RX_OK;
00255 }
00256
00257 void NscTcpL4Protocol::SoftInterrupt (void)
00258 {
00259 m_nscStack->timer_interrupt ();
00260 m_nscStack->increment_ticks ();
00261 m_softTimer.Schedule ();
00262 }
00263
00264 void NscTcpL4Protocol::send_callback(const void* data, int datalen)
00265 {
00266 Ptr<Packet> p;
00267 uint32_t ipv4Saddr, ipv4Daddr;
00268
00269 NS_ASSERT(datalen > 20);
00270
00271
00272
00273
00274
00275 const uint8_t *rawdata = reinterpret_cast<const uint8_t *>(data);
00276 rawdata += 20;
00277 datalen -= 20;
00278 p = Create<Packet> (rawdata, datalen);
00279
00280
00281 const uint32_t *ipheader = reinterpret_cast<const uint32_t *>(data);
00282 ipv4Saddr = *(ipheader+3);
00283 ipv4Daddr = *(ipheader+4);
00284
00285 Ipv4Address saddr(ntohl(ipv4Saddr));
00286 Ipv4Address daddr(ntohl(ipv4Daddr));
00287
00288 Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
00289 NS_ASSERT_MSG (ipv4, "nsc callback invoked, but node has no ipv4 object");
00290
00291 ipv4->Send (p, saddr, daddr, PROT_NUMBER);
00292 m_nscStack->if_send_finish(0);
00293 }
00294
00295 void NscTcpL4Protocol::wakeup()
00296 {
00297
00298
00299
00300
00301 Ipv4EndPointDemux::EndPoints endPoints = m_endPoints->GetAllEndPoints ();
00302 for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
00303 endPoint != endPoints.end (); endPoint++) {
00304
00305 (*endPoint)->ForwardUp (NULL, Ipv4Address(), 0);
00306 }
00307 }
00308
00309 void NscTcpL4Protocol::gettime(unsigned int* sec, unsigned int* usec)
00310 {
00311
00312
00313
00314 Time t = Simulator::Now ();
00315 int64_t us = t.GetMicroSeconds ();
00316 *sec = us / (1000*1000);
00317 *usec = us - *sec * (1000*1000);
00318 }
00319
00320
00321 void NscTcpL4Protocol::AddInterface(void)
00322 {
00323 Ptr<Ipv4> ip = m_node->GetObject<Ipv4> ();
00324 const uint32_t nInterfaces = ip->GetNInterfaces ();
00325
00326 NS_ASSERT_MSG (nInterfaces <= 2, "nsc does not support multiple interfaces per node");
00327
00328
00329
00330
00331 for (uint32_t i = 1; i < nInterfaces; i++)
00332 {
00333 Ipv4Address addr = ip->GetAddress(i);
00334 Ipv4Mask mask = ip->GetNetworkMask(i);
00335 uint16_t mtu = ip->GetMtu (i);
00336
00337 std::ostringstream addrOss, maskOss;
00338
00339 addr.Print(addrOss);
00340 mask.Print(maskOss);
00341
00342 NS_LOG_LOGIC ("if_attach " << addrOss.str().c_str() << " " << maskOss.str().c_str() << " " << mtu);
00343
00344 std::string addrStr = addrOss.str();
00345 std::string maskStr = maskOss.str();
00346 const char* addrCStr = addrStr.c_str();
00347 const char* maskCStr = maskStr.c_str();
00348 m_nscStack->if_attach(addrCStr, maskCStr, mtu);
00349
00350 if (i == 1)
00351 {
00352
00353
00354
00355 uint8_t addrBytes[4];
00356 addr.Serialize(addrBytes);
00357
00358
00359
00360
00361
00362
00363
00364
00365 addrBytes[3]++;
00366 addr.Deserialize(addrBytes);
00367 addrOss.str("");
00368 addr.Print(addrOss);
00369 m_nscStack->add_default_gateway(addrOss.str().c_str());
00370 }
00371 }
00372 }
00373
00374 };
00375