A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
tcp-l4-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 Georgia Tech Research Corporation
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Raj Bhattacharjea <raj.b@gatech.edu>
19  */
20 
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/nstime.h"
24 #include "ns3/boolean.h"
25 #include "ns3/object-vector.h"
26 
27 #include "ns3/packet.h"
28 #include "ns3/node.h"
29 #include "ns3/simulator.h"
30 #include "ns3/ipv4-route.h"
31 #include "ns3/ipv6-route.h"
32 
33 #include "tcp-l4-protocol.h"
34 #include "tcp-header.h"
35 #include "ipv4-end-point-demux.h"
36 #include "ipv6-end-point-demux.h"
37 #include "ipv4-end-point.h"
38 #include "ipv6-end-point.h"
39 #include "ipv4-l3-protocol.h"
40 #include "ipv6-l3-protocol.h"
41 #include "ipv6-routing-protocol.h"
43 #include "tcp-newreno.h"
44 #include "rtt-estimator.h"
45 
46 #include <vector>
47 #include <sstream>
48 #include <iomanip>
49 
50 NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol");
51 
52 namespace ns3 {
53 
54 NS_OBJECT_ENSURE_REGISTERED (TcpL4Protocol);
55 
56 //TcpL4Protocol stuff----------------------------------------------------------
57 
58 #undef NS_LOG_APPEND_CONTEXT
59 #define NS_LOG_APPEND_CONTEXT \
60  if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
61 
62 /* see http://www.iana.org/assignments/protocol-numbers */
63 const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
64 
65 TypeId
67 {
68  static TypeId tid = TypeId ("ns3::TcpL4Protocol")
70  .AddConstructor<TcpL4Protocol> ()
71  .AddAttribute ("RttEstimatorType",
72  "Type of RttEstimator objects.",
74  MakeTypeIdAccessor (&TcpL4Protocol::m_rttTypeId),
75  MakeTypeIdChecker ())
76  .AddAttribute ("SocketType",
77  "Socket type of TCP objects.",
79  MakeTypeIdAccessor (&TcpL4Protocol::m_socketTypeId),
80  MakeTypeIdChecker ())
81  .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
84  MakeObjectVectorChecker<TcpSocketBase> ())
85  ;
86  return tid;
87 }
88 
90  : m_endPoints (new Ipv4EndPointDemux ()), m_endPoints6 (new Ipv6EndPointDemux ())
91 {
93  NS_LOG_LOGIC ("Made a TcpL4Protocol "<<this);
94 }
95 
97 {
99 }
100 
101 void
103 {
104  m_node = node;
105 }
106 
107 /*
108  * This method is called by AddAgregate and completes the aggregation
109  * by setting the node in the TCP stack, link it to the ipv4 stack and
110  * adding TCP socket factory to the node.
111  */
112 void
114 {
115  Ptr<Node> node = this->GetObject<Node> ();
116  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
118 
119  if (m_node == 0)
120  {
121  if ((node != 0) && (ipv4 != 0 || ipv6 != 0))
122  {
123  this->SetNode (node);
124  Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
125  tcpFactory->SetTcp (this);
126  node->AggregateObject (tcpFactory);
127  }
128  }
129 
130  // We set at least one of our 2 down targets to the IPv4/IPv6 send
131  // functions. Since these functions have different prototypes, we
132  // need to keep track of whether we are connected to an IPv4 or
133  // IPv6 lower layer and call the appropriate one.
134 
135  if (ipv4 != 0 && m_downTarget.IsNull ())
136  {
137  ipv4->Insert(this);
138  this->SetDownTarget(MakeCallback(&Ipv4::Send, ipv4));
139  }
140  if (ipv6 != 0 && m_downTarget6.IsNull ())
141  {
142  ipv6->Insert(this);
144  }
146 }
147 
148 int
150 {
151  return PROT_NUMBER;
152 }
153 
154 void
156 {
158  m_sockets.clear ();
159 
160  if (m_endPoints != 0)
161  {
162  delete m_endPoints;
163  m_endPoints = 0;
164  }
165 
166  if (m_endPoints6 != 0)
167  {
168  delete m_endPoints6;
169  m_endPoints6 = 0;
170  }
171 
172  m_node = 0;
176 }
177 
180 {
182  ObjectFactory rttFactory;
183  ObjectFactory socketFactory;
184  rttFactory.SetTypeId (m_rttTypeId);
185  socketFactory.SetTypeId (socketTypeId);
186  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();
187  Ptr<TcpSocketBase> socket = socketFactory.Create<TcpSocketBase> ();
188  socket->SetNode (m_node);
189  socket->SetTcp (this);
190  socket->SetRtt (rtt);
191  m_sockets.push_back (socket);
192  return socket;
193 }
194 
197 {
198  return CreateSocket (m_socketTypeId);
199 }
200 
201 Ipv4EndPoint *
203 {
205  return m_endPoints->Allocate ();
206 }
207 
208 Ipv4EndPoint *
210 {
211  NS_LOG_FUNCTION (this << address);
212  return m_endPoints->Allocate (address);
213 }
214 
215 Ipv4EndPoint *
217 {
218  NS_LOG_FUNCTION (this << port);
219  return m_endPoints->Allocate (port);
220 }
221 
222 Ipv4EndPoint *
224 {
225  NS_LOG_FUNCTION (this << address << port);
226  return m_endPoints->Allocate (address, port);
227 }
228 
229 Ipv4EndPoint *
230 TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
231  Ipv4Address peerAddress, uint16_t peerPort)
232 {
233  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
234  return m_endPoints->Allocate (localAddress, localPort,
235  peerAddress, peerPort);
236 }
237 
238 void
240 {
241  NS_LOG_FUNCTION (this << endPoint);
242  m_endPoints->DeAllocate (endPoint);
243 }
244 
245 Ipv6EndPoint *
247 {
249  return m_endPoints6->Allocate ();
250 }
251 
252 Ipv6EndPoint *
254 {
255  NS_LOG_FUNCTION (this << address);
256  return m_endPoints6->Allocate (address);
257 }
258 
259 Ipv6EndPoint *
261 {
262  NS_LOG_FUNCTION (this << port);
263  return m_endPoints6->Allocate (port);
264 }
265 
266 Ipv6EndPoint *
268 {
269  NS_LOG_FUNCTION (this << address << port);
270  return m_endPoints6->Allocate (address, port);
271 }
272 
273 Ipv6EndPoint *
274 TcpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
275  Ipv6Address peerAddress, uint16_t peerPort)
276 {
277  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
278  return m_endPoints6->Allocate (localAddress, localPort,
279  peerAddress, peerPort);
280 }
281 
282 void
284 {
285  NS_LOG_FUNCTION (this << endPoint);
286  m_endPoints6->DeAllocate (endPoint);
287 }
288 
289 void
290 TcpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
291  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
292  Ipv4Address payloadSource,Ipv4Address payloadDestination,
293  const uint8_t payload[8])
294 {
295  NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
296  << payloadSource << payloadDestination);
297  uint16_t src, dst;
298  src = payload[0] << 8;
299  src |= payload[1];
300  dst = payload[2] << 8;
301  dst |= payload[3];
302 
303  Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst);
304  if (endPoint != 0)
305  {
306  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
307  }
308  else
309  {
310  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
311  ", destination="<<payloadDestination<<
312  ", src=" << src << ", dst=" << dst);
313  }
314 }
315 
316 void
317 TcpL4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
318  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
319  Ipv6Address payloadSource,Ipv6Address payloadDestination,
320  const uint8_t payload[8])
321 {
322  NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
323  << payloadSource << payloadDestination);
324  uint16_t src, dst;
325  src = payload[0] << 8;
326  src |= payload[1];
327  dst = payload[2] << 8;
328  dst |= payload[3];
329 
330  Ipv6EndPoint *endPoint = m_endPoints6->SimpleLookup (payloadSource, src, payloadDestination, dst);
331  if (endPoint != 0)
332  {
333  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
334  }
335  else
336  {
337  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
338  ", destination="<<payloadDestination<<
339  ", src=" << src << ", dst=" << dst);
340  }
341 }
342 
345  Ipv4Header const &ipHeader,
346  Ptr<Ipv4Interface> incomingInterface)
347 {
348  NS_LOG_FUNCTION (this << packet << ipHeader << incomingInterface);
349 
350  TcpHeader tcpHeader;
351  if(Node::ChecksumEnabled ())
352  {
353  tcpHeader.EnableChecksums ();
354  tcpHeader.InitializeChecksum (ipHeader.GetSource (), ipHeader.GetDestination (), PROT_NUMBER);
355  }
356 
357  packet->PeekHeader (tcpHeader);
358 
359  NS_LOG_LOGIC ("TcpL4Protocol " << this
360  << " receiving seq " << tcpHeader.GetSequenceNumber ()
361  << " ack " << tcpHeader.GetAckNumber ()
362  << " flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
363  << " data size " << packet->GetSize ());
364 
365  if(!tcpHeader.IsChecksumOk ())
366  {
367  NS_LOG_INFO ("Bad checksum, dropping packet!");
369  }
370 
371  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
372  Ipv4EndPointDemux::EndPoints endPoints =
373  m_endPoints->Lookup (ipHeader.GetDestination (), tcpHeader.GetDestinationPort (),
374  ipHeader.GetSource (), tcpHeader.GetSourcePort (),incomingInterface);
375  if (endPoints.empty ())
376  {
377  if (this->GetObject<Ipv6L3Protocol> () != 0)
378  {
379  NS_LOG_LOGIC (" No Ipv4 endpoints matched on TcpL4Protocol, trying Ipv6 "<<this);
380  Ptr<Ipv6Interface> fakeInterface;
381  Ipv6Header ipv6Header;
384  ipv6Header.SetSourceAddress (src);
385  ipv6Header.SetDestinationAddress (dst);
386  return (this->Receive (packet, ipv6Header, fakeInterface));
387  }
388 
389  NS_LOG_LOGIC (" No endpoints matched on TcpL4Protocol "<<this);
390  std::ostringstream oss;
391  oss<<" destination IP: ";
392  ipHeader.GetDestination ().Print (oss);
393  oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
394  ipHeader.GetSource ().Print (oss);
395  oss<<" source port: "<<tcpHeader.GetSourcePort ();
396  NS_LOG_LOGIC (oss.str ());
397 
398  if (!(tcpHeader.GetFlags () & TcpHeader::RST))
399  {
400  // build a RST packet and send
401  Ptr<Packet> rstPacket = Create<Packet> ();
402  TcpHeader header;
403  if (tcpHeader.GetFlags () & TcpHeader::ACK)
404  {
405  // ACK bit was set
406  header.SetFlags (TcpHeader::RST);
407  header.SetSequenceNumber (header.GetAckNumber ());
408  }
409  else
410  {
411  header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
412  header.SetSequenceNumber (SequenceNumber32 (0));
413  header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
414  }
415  header.SetSourcePort (tcpHeader.GetDestinationPort ());
416  header.SetDestinationPort (tcpHeader.GetSourcePort ());
417  SendPacket (rstPacket, header, ipHeader.GetDestination (), ipHeader.GetSource ());
419  }
420  else
421  {
423  }
424  }
425  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
426  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
427  (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort (),
428  incomingInterface);
429  return IpL4Protocol::RX_OK;
430 }
431 
434  Ipv6Header const &ipHeader,
435  Ptr<Ipv6Interface> interface)
436 {
437  NS_LOG_FUNCTION (this << packet << ipHeader.GetSourceAddress () << ipHeader.GetDestinationAddress ());
438 
439  TcpHeader tcpHeader;
440 
441  // If we are receving a v4-mapped packet, we will re-calculate the TCP checksum
442  // Is it worth checking every received "v6" packet to see if it is v4-mapped in
443  // order to avoid re-calculating TCP checksums for v4-mapped packets?
444 
445  if(Node::ChecksumEnabled ())
446  {
447  tcpHeader.EnableChecksums ();
448  tcpHeader.InitializeChecksum (ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress (), PROT_NUMBER);
449  }
450 
451  packet->PeekHeader (tcpHeader);
452 
453  NS_LOG_LOGIC ("TcpL4Protocol " << this
454  << " receiving seq " << tcpHeader.GetSequenceNumber ()
455  << " ack " << tcpHeader.GetAckNumber ()
456  << " flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
457  << " data size " << packet->GetSize ());
458 
459  if(!tcpHeader.IsChecksumOk ())
460  {
461  NS_LOG_INFO ("Bad checksum, dropping packet!");
463  }
464 
465  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
466  Ipv6EndPointDemux::EndPoints endPoints =
467  m_endPoints6->Lookup (ipHeader.GetDestinationAddress (), tcpHeader.GetDestinationPort (),
468  ipHeader.GetSourceAddress (), tcpHeader.GetSourcePort (),interface);
469  if (endPoints.empty ())
470  {
471  NS_LOG_LOGIC (" No IPv6 endpoints matched on TcpL4Protocol "<<this);
472  std::ostringstream oss;
473  oss<<" destination IP: ";
474  (ipHeader.GetDestinationAddress ()).Print (oss);
475  oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
476  (ipHeader.GetSourceAddress ()).Print (oss);
477  oss<<" source port: "<<tcpHeader.GetSourcePort ();
478  NS_LOG_LOGIC (oss.str ());
479 
480  if (!(tcpHeader.GetFlags () & TcpHeader::RST))
481  {
482  // build a RST packet and send
483  Ptr<Packet> rstPacket = Create<Packet> ();
484  TcpHeader header;
485  if (tcpHeader.GetFlags () & TcpHeader::ACK)
486  {
487  // ACK bit was set
488  header.SetFlags (TcpHeader::RST);
489  header.SetSequenceNumber (header.GetAckNumber ());
490  }
491  else
492  {
493  header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
494  header.SetSequenceNumber (SequenceNumber32 (0));
495  header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
496  }
497  header.SetSourcePort (tcpHeader.GetDestinationPort ());
498  header.SetDestinationPort (tcpHeader.GetSourcePort ());
499  SendPacket (rstPacket, header, ipHeader.GetDestinationAddress (), ipHeader.GetSourceAddress ());
501  }
502  else
503  {
505  }
506  }
507  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
508  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
509  (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort (), interface);
510  return IpL4Protocol::RX_OK;
511 }
512 
513 void
515  Ipv4Address saddr, Ipv4Address daddr,
516  uint16_t sport, uint16_t dport, Ptr<NetDevice> oif)
517 {
518  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << oif);
519 
520  TcpHeader tcpHeader;
521  tcpHeader.SetDestinationPort (dport);
522  tcpHeader.SetSourcePort (sport);
523  if(Node::ChecksumEnabled ())
524  {
525  tcpHeader.EnableChecksums ();
526  }
527  tcpHeader.InitializeChecksum (saddr,
528  daddr,
529  PROT_NUMBER);
530  tcpHeader.SetFlags (TcpHeader::ACK);
531  tcpHeader.SetAckNumber (SequenceNumber32 (0));
532 
533  packet->AddHeader (tcpHeader);
534 
535  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
536  if (ipv4 != 0)
537  {
538  Ipv4Header header;
539  header.SetDestination (daddr);
540  header.SetProtocol (PROT_NUMBER);
541  Socket::SocketErrno errno_;
542  Ptr<Ipv4Route> route;
543  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
544  if (ipv4->GetRoutingProtocol () != 0)
545  {
546  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
547  }
548  else
549  {
550  NS_LOG_ERROR ("No IPV4 Routing Protocol");
551  route = 0;
552  }
553  ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
554  }
555 }
556 
557 void
559  Ipv6Address saddr, Ipv6Address daddr,
560  uint16_t sport, uint16_t dport, Ptr<NetDevice> oif)
561 {
562  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << oif);
563 
564  TcpHeader tcpHeader;
565  tcpHeader.SetDestinationPort (dport);
566  tcpHeader.SetSourcePort (sport);
567  if(Node::ChecksumEnabled ())
568  {
569  tcpHeader.EnableChecksums ();
570  }
571  tcpHeader.InitializeChecksum (saddr,
572  daddr,
573  PROT_NUMBER);
574  tcpHeader.SetFlags (TcpHeader::ACK);
575  tcpHeader.SetAckNumber (SequenceNumber32 (0));
576 
577  packet->AddHeader (tcpHeader);
578 
580  if (ipv6 != 0)
581  {
582  Ipv6Header header;
583  header.SetDestinationAddress (daddr);
584  header.SetNextHeader (PROT_NUMBER);
585  Socket::SocketErrno errno_;
586  Ptr<Ipv6Route> route;
587  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
588  if (ipv6->GetRoutingProtocol () != 0)
589  {
590  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
591  }
592  else
593  {
594  NS_LOG_ERROR ("No IPV6 Routing Protocol");
595  route = 0;
596  }
597  ipv6->Send (packet, saddr, daddr, PROT_NUMBER, route);
598  }
599 }
600 
601 void
603  Ipv4Address saddr, Ipv4Address daddr, Ptr<NetDevice> oif)
604 {
605  NS_LOG_LOGIC ("TcpL4Protocol " << this
606  << " sending seq " << outgoing.GetSequenceNumber ()
607  << " ack " << outgoing.GetAckNumber ()
608  << " flags " << std::hex << (int)outgoing.GetFlags () << std::dec
609  << " data size " << packet->GetSize ());
610  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
611  // XXX outgoingHeader cannot be logged
612 
613  TcpHeader outgoingHeader = outgoing;
614  outgoingHeader.SetLength (5); //header length in units of 32bit words
616  /* outgoingHeader.SetUrgentPointer (0); */
617  if(Node::ChecksumEnabled ())
618  {
619  outgoingHeader.EnableChecksums ();
620  }
621  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
622 
623  packet->AddHeader (outgoingHeader);
624 
625  Ptr<Ipv4> ipv4 =
626  m_node->GetObject<Ipv4> ();
627  if (ipv4 != 0)
628  {
629  Ipv4Header header;
630  header.SetDestination (daddr);
631  header.SetProtocol (PROT_NUMBER);
632  Socket::SocketErrno errno_;
633  Ptr<Ipv4Route> route;
634  if (ipv4->GetRoutingProtocol () != 0)
635  {
636  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
637  }
638  else
639  {
640  NS_LOG_ERROR ("No IPV4 Routing Protocol");
641  route = 0;
642  }
643  m_downTarget (packet, saddr, daddr, PROT_NUMBER, route);
644  }
645  else
646  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv4 interface");
647 }
648 
649 void
651  Ipv6Address saddr, Ipv6Address daddr, Ptr<NetDevice> oif)
652 {
653  NS_LOG_LOGIC ("TcpL4Protocol " << this
654  << " sending seq " << outgoing.GetSequenceNumber ()
655  << " ack " << outgoing.GetAckNumber ()
656  << " flags " << std::hex << (int)outgoing.GetFlags () << std::dec
657  << " data size " << packet->GetSize ());
658  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
659  // XXX outgoingHeader cannot be logged
660 
661  if (daddr.IsIpv4MappedAddress ())
662  {
663  return (SendPacket (packet, outgoing, saddr.GetIpv4MappedAddress(), daddr.GetIpv4MappedAddress(), oif));
664  }
665  TcpHeader outgoingHeader = outgoing;
666  outgoingHeader.SetLength (5); //header length in units of 32bit words
668  /* outgoingHeader.SetUrgentPointer (0); */
669  if(Node::ChecksumEnabled ())
670  {
671  outgoingHeader.EnableChecksums ();
672  }
673  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
674 
675  packet->AddHeader (outgoingHeader);
676 
678  if (ipv6 != 0)
679  {
680  Ipv6Header header;
681  header.SetDestinationAddress (daddr);
682  header.SetSourceAddress (saddr);
683  header.SetNextHeader (PROT_NUMBER);
684  Socket::SocketErrno errno_;
685  Ptr<Ipv6Route> route;
686  if (ipv6->GetRoutingProtocol () != 0)
687  {
688  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
689  }
690  else
691  {
692  NS_LOG_ERROR ("No IPV6 Routing Protocol");
693  route = 0;
694  }
695  m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, route);
696  }
697  else
698  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv6 interface");
699 }
700 
701 void
703 {
704  m_downTarget = callback;
705 }
706 
709 {
710  return m_downTarget;
711 }
712 
713 void
715 {
716  m_downTarget6 = callback;
717 }
718 
721 {
722  return m_downTarget6;
723 }
724 
725 } // namespace ns3
726 
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberContainer)
Definition: object-vector.h:51
Ptr< Socket > CreateSocket(void)
Create a TCP socket.
TypeId m_socketTypeId
The socket TypeId.
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint16_t GetDestinationPort() const
Definition: tcp-header.cc:92
Ptr< Node > m_node
the node this stack is associated with
virtual void SetDownTarget6(IpL4Protocol::DownTargetCallback6 cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
SequenceNumber32 GetSequenceNumber() const
Definition: tcp-header.cc:96
virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
void InitializeChecksum(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
Initialize the TCP checksum.
Definition: tcp-header.cc:122
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
uint8_t GetFlags() const
Definition: tcp-header.cc:108
std::list< Ipv6EndPoint * > EndPoints
Container of the IPv6 endpoints.
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers...
IPv6 layer implementation.
EndPoints Lookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr< Ipv6Interface > incomingInterface)
lookup for a match with all the parameters.
SequenceNumber32 GetAckNumber() const
Definition: tcp-header.cc:100
static bool ChecksumEnabled(void)
Definition: node.cc:268
Ipv6EndPoint * Allocate6(void)
Allocate an IPv6 Endpoint.
void Send(Ptr< Packet > packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport, uint16_t dport, Ptr< NetDevice > oif=0)
Send a packet via TCP (IPv4)
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1018
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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])
Called from lower-level layers to send the ICMP packet up in the stack.
void SetTypeId(TypeId tid)
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:76
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
static TypeId GetTypeId(void)
Get the type ID.
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
void DeAllocate(Ipv4EndPoint *endPoint)
Remove an IPv4 Endpoint.
uint16_t port
Definition: dsdv-manet.cc:44
virtual void NotifyNewAggregate()
This method is invoked whenever two sets of objects are aggregated together.
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number
Demultiplexes packets to various transport layer endpoints.
Packet header for IPv4.
Definition: ipv4-header.h:31
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-newreno.cc:38
Ptr< Object > Create(void) const
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Called from lower-level layers to send the packet up in the stack.
Base class for all RTT Estimators.
Definition: rtt-estimator.h:69
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
Ipv6EndPoint * Allocate(void)
Allocate a Ipv6EndPoint.
hold objects of type ns3::TypeId
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
void Print(std::ostream &os) const
Print this address to the given output stream.
A base class for implementation of a stream socket using TCP.
void AggregateObject(Ptr< Object > other)
Definition: object.cc:242
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
std::vector< Ptr< TcpSocketBase > > m_sockets
list of sockets
void SetDestinationPort(uint16_t port)
Definition: tcp-header.cc:59
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
static const uint8_t PROT_NUMBER
protocol number (0x6)
void SetFlags(uint8_t flags)
Definition: tcp-header.cc:75
virtual void NotifyNewAggregate(void)
This method is invoked whenever two sets of objects are aggregated together.
Definition: object.cc:314
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
Ipv6EndPointDemux * m_endPoints6
A list of IPv6 end points.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:43
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Forward the ICMP packet to the upper level.
virtual int GetProtocolNumber(void) const
virtual void SetNode(Ptr< Node > node)
Set the associated node.
Ipv6EndPoint * SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
Simple lookup for a four-tuple match.
void SetSourcePort(uint16_t port)
Definition: tcp-header.cc:55
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
Ipv4EndPoint * SimpleLookup(Ipv4Address daddr, uint16_t dport, Ipv4Address saddr, uint16_t sport)
simple lookup for a match with all the parameters.
void SendPacket(Ptr< Packet >, const TcpHeader &, Ipv4Address, Ipv4Address, Ptr< NetDevice > oif=0)
L4 Protocol abstract base class.
Ipv4EndPoint * Allocate(void)
Allocate an IPv4 Endpoint.
EndPoints Lookup(Ipv4Address daddr, uint16_t dport, Ipv4Address saddr, uint16_t sport, Ptr< Ipv4Interface > incomingInterface)
lookup for a match with all the parameters.
Ipv4EndPointDemux * m_endPoints
A list of IPv4 end points.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:96
Describes an IPv6 address.
Definition: ipv6-address.h:46
instantiate subclasses of ns3::Object.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
std::list< Ipv4EndPoint * > EndPoints
Container of the IPv4 endpoints.
static TypeId GetTypeId(void)
Get the type ID.
void SetAckNumber(SequenceNumber32 ackNumber)
Definition: tcp-header.cc:67
Demultiplexor for end points.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
A representation of an internet IPv6 endpoint/connection.
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
TypeId m_rttTypeId
The RTT Estimator TypeId.
uint16_t GetSourcePort() const
Definition: tcp-header.cc:88
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1022
void ForwardIcmp(Ipv6Address src, uint8_t ttl, uint8_t type, uint8_t code, uint32_t info)
Forward the ICMP packet to the upper level.
RxStatus
Rx status codes.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
void SetLength(uint8_t length)
Definition: tcp-header.cc:71
tuple address
Definition: first.py:37
bool IsChecksumOk(void) const
Is the TCP checksum correct ?
Definition: tcp-header.cc:195
void EnableChecksums(void)
Enable checksum calculation for TCP.
Definition: tcp-header.cc:50
contain a set of ns3::Object pointers.
void DeAllocate(Ipv4EndPoint *endPoint)
Remove a end point.
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Ptr< T > GetObject(void) const
Definition: object.h:362
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
a unique identifier for an interface.
Definition: type-id.h:49
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
IpL4Protocol::DownTargetCallback6 m_downTarget6
Callback to send packets over IPv6.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
A representation of an internet endpoint/connection.
IpL4Protocol::DownTargetCallback m_downTarget
Callback to send packets over IPv4.
Ipv4EndPoint * Allocate(void)
Allocate a Ipv4EndPoint.