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 
57 //TcpL4Protocol stuff----------------------------------------------------------
58 
59 #undef NS_LOG_APPEND_CONTEXT
60 #define NS_LOG_APPEND_CONTEXT \
61  if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
62 
63 /* see http://www.iana.org/assignments/protocol-numbers */
64 const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
65 
66 TypeId
68 {
69  static TypeId tid = TypeId ("ns3::TcpL4Protocol")
71  .AddConstructor<TcpL4Protocol> ()
72  .AddAttribute ("RttEstimatorType",
73  "Type of RttEstimator objects.",
75  MakeTypeIdAccessor (&TcpL4Protocol::m_rttTypeId),
76  MakeTypeIdChecker ())
77  .AddAttribute ("SocketType",
78  "Socket type of TCP objects.",
80  MakeTypeIdAccessor (&TcpL4Protocol::m_socketTypeId),
81  MakeTypeIdChecker ())
82  .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
85  MakeObjectVectorChecker<TcpSocketBase> ())
86  ;
87  return tid;
88 }
89 
91  : m_endPoints (new Ipv4EndPointDemux ()), m_endPoints6 (new Ipv6EndPointDemux ())
92 {
94  NS_LOG_LOGIC ("Made a TcpL4Protocol "<<this);
95 }
96 
98 {
100 }
101 
102 void
104 {
105  m_node = node;
106 }
107 
108 /*
109  * This method is called by AddAgregate and completes the aggregation
110  * by setting the node in the TCP stack, link it to the ipv4 stack and
111  * adding TCP socket factory to the node.
112  */
113 void
115 {
116  Ptr<Node> node = this->GetObject<Node> ();
117  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
119 
120  if (m_node == 0)
121  {
122  if ((node != 0) && (ipv4 != 0 || ipv6 != 0))
123  {
124  this->SetNode (node);
125  Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
126  tcpFactory->SetTcp (this);
127  node->AggregateObject (tcpFactory);
128  }
129  }
130 
131  // We set at least one of our 2 down targets to the IPv4/IPv6 send
132  // functions. Since these functions have different prototypes, we
133  // need to keep track of whether we are connected to an IPv4 or
134  // IPv6 lower layer and call the appropriate one.
135 
136  if (ipv4 != 0 && m_downTarget.IsNull ())
137  {
138  ipv4->Insert(this);
139  this->SetDownTarget(MakeCallback(&Ipv4::Send, ipv4));
140  }
141  if (ipv6 != 0 && m_downTarget6.IsNull ())
142  {
143  ipv6->Insert(this);
145  }
147 }
148 
149 int
151 {
152  return PROT_NUMBER;
153 }
154 
155 void
157 {
159  m_sockets.clear ();
160 
161  if (m_endPoints != 0)
162  {
163  delete m_endPoints;
164  m_endPoints = 0;
165  }
166 
167  if (m_endPoints6 != 0)
168  {
169  delete m_endPoints6;
170  m_endPoints6 = 0;
171  }
172 
173  m_node = 0;
177 }
178 
181 {
183  ObjectFactory rttFactory;
184  ObjectFactory socketFactory;
185  rttFactory.SetTypeId (m_rttTypeId);
186  socketFactory.SetTypeId (socketTypeId);
187  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();
188  Ptr<TcpSocketBase> socket = socketFactory.Create<TcpSocketBase> ();
189  socket->SetNode (m_node);
190  socket->SetTcp (this);
191  socket->SetRtt (rtt);
192  m_sockets.push_back (socket);
193  return socket;
194 }
195 
198 {
199  return CreateSocket (m_socketTypeId);
200 }
201 
202 Ipv4EndPoint *
204 {
206  return m_endPoints->Allocate ();
207 }
208 
209 Ipv4EndPoint *
211 {
212  NS_LOG_FUNCTION (this << address);
213  return m_endPoints->Allocate (address);
214 }
215 
216 Ipv4EndPoint *
218 {
219  NS_LOG_FUNCTION (this << port);
220  return m_endPoints->Allocate (port);
221 }
222 
223 Ipv4EndPoint *
225 {
226  NS_LOG_FUNCTION (this << address << port);
227  return m_endPoints->Allocate (address, port);
228 }
229 
230 Ipv4EndPoint *
231 TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
232  Ipv4Address peerAddress, uint16_t peerPort)
233 {
234  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
235  return m_endPoints->Allocate (localAddress, localPort,
236  peerAddress, peerPort);
237 }
238 
239 void
241 {
242  NS_LOG_FUNCTION (this << endPoint);
243  m_endPoints->DeAllocate (endPoint);
244 }
245 
246 Ipv6EndPoint *
248 {
250  return m_endPoints6->Allocate ();
251 }
252 
253 Ipv6EndPoint *
255 {
256  NS_LOG_FUNCTION (this << address);
257  return m_endPoints6->Allocate (address);
258 }
259 
260 Ipv6EndPoint *
262 {
263  NS_LOG_FUNCTION (this << port);
264  return m_endPoints6->Allocate (port);
265 }
266 
267 Ipv6EndPoint *
269 {
270  NS_LOG_FUNCTION (this << address << port);
271  return m_endPoints6->Allocate (address, port);
272 }
273 
274 Ipv6EndPoint *
275 TcpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
276  Ipv6Address peerAddress, uint16_t peerPort)
277 {
278  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
279  return m_endPoints6->Allocate (localAddress, localPort,
280  peerAddress, peerPort);
281 }
282 
283 void
285 {
286  NS_LOG_FUNCTION (this << endPoint);
287  m_endPoints6->DeAllocate (endPoint);
288 }
289 
290 void
291 TcpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
292  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
293  Ipv4Address payloadSource,Ipv4Address payloadDestination,
294  const uint8_t payload[8])
295 {
296  NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
297  << payloadSource << payloadDestination);
298  uint16_t src, dst;
299  src = payload[0] << 8;
300  src |= payload[1];
301  dst = payload[2] << 8;
302  dst |= payload[3];
303 
304  Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst);
305  if (endPoint != 0)
306  {
307  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
308  }
309  else
310  {
311  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
312  ", destination="<<payloadDestination<<
313  ", src=" << src << ", dst=" << dst);
314  }
315 }
316 
317 void
318 TcpL4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
319  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
320  Ipv6Address payloadSource,Ipv6Address payloadDestination,
321  const uint8_t payload[8])
322 {
323  NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
324  << payloadSource << payloadDestination);
325  uint16_t src, dst;
326  src = payload[0] << 8;
327  src |= payload[1];
328  dst = payload[2] << 8;
329  dst |= payload[3];
330 
331  Ipv6EndPoint *endPoint = m_endPoints6->SimpleLookup (payloadSource, src, payloadDestination, dst);
332  if (endPoint != 0)
333  {
334  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
335  }
336  else
337  {
338  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
339  ", destination="<<payloadDestination<<
340  ", src=" << src << ", dst=" << dst);
341  }
342 }
343 
346  Ipv4Header const &ipHeader,
347  Ptr<Ipv4Interface> incomingInterface)
348 {
349  NS_LOG_FUNCTION (this << packet << ipHeader << incomingInterface);
350 
351  TcpHeader tcpHeader;
352  if(Node::ChecksumEnabled ())
353  {
354  tcpHeader.EnableChecksums ();
355  tcpHeader.InitializeChecksum (ipHeader.GetSource (), ipHeader.GetDestination (), PROT_NUMBER);
356  }
357 
358  packet->PeekHeader (tcpHeader);
359 
360  NS_LOG_LOGIC ("TcpL4Protocol " << this
361  << " receiving seq " << tcpHeader.GetSequenceNumber ()
362  << " ack " << tcpHeader.GetAckNumber ()
363  << " flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
364  << " data size " << packet->GetSize ());
365 
366  if(!tcpHeader.IsChecksumOk ())
367  {
368  NS_LOG_INFO ("Bad checksum, dropping packet!");
370  }
371 
372  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
373  Ipv4EndPointDemux::EndPoints endPoints =
374  m_endPoints->Lookup (ipHeader.GetDestination (), tcpHeader.GetDestinationPort (),
375  ipHeader.GetSource (), tcpHeader.GetSourcePort (),incomingInterface);
376  if (endPoints.empty ())
377  {
378  if (this->GetObject<Ipv6L3Protocol> () != 0)
379  {
380  NS_LOG_LOGIC (" No Ipv4 endpoints matched on TcpL4Protocol, trying Ipv6 "<<this);
381  Ptr<Ipv6Interface> fakeInterface;
382  Ipv6Header ipv6Header;
385  ipv6Header.SetSourceAddress (src);
386  ipv6Header.SetDestinationAddress (dst);
387  return (this->Receive (packet, ipv6Header, fakeInterface));
388  }
389 
390  NS_LOG_LOGIC (" No endpoints matched on TcpL4Protocol "<<this);
391  std::ostringstream oss;
392  oss<<" destination IP: ";
393  ipHeader.GetDestination ().Print (oss);
394  oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
395  ipHeader.GetSource ().Print (oss);
396  oss<<" source port: "<<tcpHeader.GetSourcePort ();
397  NS_LOG_LOGIC (oss.str ());
398 
399  if (!(tcpHeader.GetFlags () & TcpHeader::RST))
400  {
401  // build a RST packet and send
402  Ptr<Packet> rstPacket = Create<Packet> ();
403  TcpHeader header;
404  if (tcpHeader.GetFlags () & TcpHeader::ACK)
405  {
406  // ACK bit was set
407  header.SetFlags (TcpHeader::RST);
408  header.SetSequenceNumber (header.GetAckNumber ());
409  }
410  else
411  {
412  header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
413  header.SetSequenceNumber (SequenceNumber32 (0));
414  header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
415  }
416  header.SetSourcePort (tcpHeader.GetDestinationPort ());
417  header.SetDestinationPort (tcpHeader.GetSourcePort ());
418  SendPacket (rstPacket, header, ipHeader.GetDestination (), ipHeader.GetSource ());
420  }
421  else
422  {
424  }
425  }
426  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
427  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
428  (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort (),
429  incomingInterface);
430  return IpL4Protocol::RX_OK;
431 }
432 
435  Ipv6Header const &ipHeader,
436  Ptr<Ipv6Interface> interface)
437 {
438  NS_LOG_FUNCTION (this << packet << ipHeader.GetSourceAddress () << ipHeader.GetDestinationAddress ());
439 
440  TcpHeader tcpHeader;
441 
442  // If we are receving a v4-mapped packet, we will re-calculate the TCP checksum
443  // Is it worth checking every received "v6" packet to see if it is v4-mapped in
444  // order to avoid re-calculating TCP checksums for v4-mapped packets?
445 
446  if(Node::ChecksumEnabled ())
447  {
448  tcpHeader.EnableChecksums ();
449  tcpHeader.InitializeChecksum (ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress (), PROT_NUMBER);
450  }
451 
452  packet->PeekHeader (tcpHeader);
453 
454  NS_LOG_LOGIC ("TcpL4Protocol " << this
455  << " receiving seq " << tcpHeader.GetSequenceNumber ()
456  << " ack " << tcpHeader.GetAckNumber ()
457  << " flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
458  << " data size " << packet->GetSize ());
459 
460  if(!tcpHeader.IsChecksumOk ())
461  {
462  NS_LOG_INFO ("Bad checksum, dropping packet!");
464  }
465 
466  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
467  Ipv6EndPointDemux::EndPoints endPoints =
468  m_endPoints6->Lookup (ipHeader.GetDestinationAddress (), tcpHeader.GetDestinationPort (),
469  ipHeader.GetSourceAddress (), tcpHeader.GetSourcePort (),interface);
470  if (endPoints.empty ())
471  {
472  NS_LOG_LOGIC (" No IPv6 endpoints matched on TcpL4Protocol "<<this);
473  std::ostringstream oss;
474  oss<<" destination IP: ";
475  (ipHeader.GetDestinationAddress ()).Print (oss);
476  oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
477  (ipHeader.GetSourceAddress ()).Print (oss);
478  oss<<" source port: "<<tcpHeader.GetSourcePort ();
479  NS_LOG_LOGIC (oss.str ());
480 
481  if (!(tcpHeader.GetFlags () & TcpHeader::RST))
482  {
483  // build a RST packet and send
484  Ptr<Packet> rstPacket = Create<Packet> ();
485  TcpHeader header;
486  if (tcpHeader.GetFlags () & TcpHeader::ACK)
487  {
488  // ACK bit was set
489  header.SetFlags (TcpHeader::RST);
490  header.SetSequenceNumber (header.GetAckNumber ());
491  }
492  else
493  {
494  header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
495  header.SetSequenceNumber (SequenceNumber32 (0));
496  header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
497  }
498  header.SetSourcePort (tcpHeader.GetDestinationPort ());
499  header.SetDestinationPort (tcpHeader.GetSourcePort ());
500  SendPacket (rstPacket, header, ipHeader.GetDestinationAddress (), ipHeader.GetSourceAddress ());
502  }
503  else
504  {
506  }
507  }
508  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
509  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
510  (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort (), interface);
511  return IpL4Protocol::RX_OK;
512 }
513 
514 void
516  Ipv4Address saddr, Ipv4Address daddr,
517  uint16_t sport, uint16_t dport, Ptr<NetDevice> oif)
518 {
519  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << oif);
520 
521  TcpHeader tcpHeader;
522  tcpHeader.SetDestinationPort (dport);
523  tcpHeader.SetSourcePort (sport);
524  if(Node::ChecksumEnabled ())
525  {
526  tcpHeader.EnableChecksums ();
527  }
528  tcpHeader.InitializeChecksum (saddr,
529  daddr,
530  PROT_NUMBER);
531  tcpHeader.SetFlags (TcpHeader::ACK);
532  tcpHeader.SetAckNumber (SequenceNumber32 (0));
533 
534  packet->AddHeader (tcpHeader);
535 
536  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
537  if (ipv4 != 0)
538  {
539  Ipv4Header header;
540  header.SetDestination (daddr);
541  header.SetProtocol (PROT_NUMBER);
542  Socket::SocketErrno errno_;
543  Ptr<Ipv4Route> route;
544  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
545  if (ipv4->GetRoutingProtocol () != 0)
546  {
547  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
548  }
549  else
550  {
551  NS_LOG_ERROR ("No IPV4 Routing Protocol");
552  route = 0;
553  }
554  ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
555  }
556 }
557 
558 void
560  Ipv6Address saddr, Ipv6Address daddr,
561  uint16_t sport, uint16_t dport, Ptr<NetDevice> oif)
562 {
563  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << oif);
564 
565  TcpHeader tcpHeader;
566  tcpHeader.SetDestinationPort (dport);
567  tcpHeader.SetSourcePort (sport);
568  if(Node::ChecksumEnabled ())
569  {
570  tcpHeader.EnableChecksums ();
571  }
572  tcpHeader.InitializeChecksum (saddr,
573  daddr,
574  PROT_NUMBER);
575  tcpHeader.SetFlags (TcpHeader::ACK);
576  tcpHeader.SetAckNumber (SequenceNumber32 (0));
577 
578  packet->AddHeader (tcpHeader);
579 
581  if (ipv6 != 0)
582  {
583  Ipv6Header header;
584  header.SetDestinationAddress (daddr);
585  header.SetNextHeader (PROT_NUMBER);
586  Socket::SocketErrno errno_;
587  Ptr<Ipv6Route> route;
588  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
589  if (ipv6->GetRoutingProtocol () != 0)
590  {
591  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
592  }
593  else
594  {
595  NS_LOG_ERROR ("No IPV6 Routing Protocol");
596  route = 0;
597  }
598  ipv6->Send (packet, saddr, daddr, PROT_NUMBER, route);
599  }
600 }
601 
602 void
604  Ipv4Address saddr, Ipv4Address daddr, Ptr<NetDevice> oif)
605 {
606  NS_LOG_LOGIC ("TcpL4Protocol " << this
607  << " sending seq " << outgoing.GetSequenceNumber ()
608  << " ack " << outgoing.GetAckNumber ()
609  << " flags " << std::hex << (int)outgoing.GetFlags () << std::dec
610  << " data size " << packet->GetSize ());
611  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
612  // XXX outgoingHeader cannot be logged
613 
614  TcpHeader outgoingHeader = outgoing;
615  outgoingHeader.SetLength (5); //header length in units of 32bit words
617  /* outgoingHeader.SetUrgentPointer (0); */
618  if(Node::ChecksumEnabled ())
619  {
620  outgoingHeader.EnableChecksums ();
621  }
622  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
623 
624  packet->AddHeader (outgoingHeader);
625 
626  Ptr<Ipv4> ipv4 =
627  m_node->GetObject<Ipv4> ();
628  if (ipv4 != 0)
629  {
630  Ipv4Header header;
631  header.SetDestination (daddr);
632  header.SetProtocol (PROT_NUMBER);
633  Socket::SocketErrno errno_;
634  Ptr<Ipv4Route> route;
635  if (ipv4->GetRoutingProtocol () != 0)
636  {
637  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
638  }
639  else
640  {
641  NS_LOG_ERROR ("No IPV4 Routing Protocol");
642  route = 0;
643  }
644  m_downTarget (packet, saddr, daddr, PROT_NUMBER, route);
645  }
646  else
647  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv4 interface");
648 }
649 
650 void
652  Ipv6Address saddr, Ipv6Address daddr, Ptr<NetDevice> oif)
653 {
654  NS_LOG_LOGIC ("TcpL4Protocol " << this
655  << " sending seq " << outgoing.GetSequenceNumber ()
656  << " ack " << outgoing.GetAckNumber ()
657  << " flags " << std::hex << (int)outgoing.GetFlags () << std::dec
658  << " data size " << packet->GetSize ());
659  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
660  // XXX outgoingHeader cannot be logged
661 
662  if (daddr.IsIpv4MappedAddress ())
663  {
664  return (SendPacket (packet, outgoing, saddr.GetIpv4MappedAddress(), daddr.GetIpv4MappedAddress(), oif));
665  }
666  TcpHeader outgoingHeader = outgoing;
667  outgoingHeader.SetLength (5); //header length in units of 32bit words
669  /* outgoingHeader.SetUrgentPointer (0); */
670  if(Node::ChecksumEnabled ())
671  {
672  outgoingHeader.EnableChecksums ();
673  }
674  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
675 
676  packet->AddHeader (outgoingHeader);
677 
679  if (ipv6 != 0)
680  {
681  Ipv6Header header;
682  header.SetDestinationAddress (daddr);
683  header.SetSourceAddress (saddr);
684  header.SetNextHeader (PROT_NUMBER);
685  Socket::SocketErrno errno_;
686  Ptr<Ipv6Route> route;
687  if (ipv6->GetRoutingProtocol () != 0)
688  {
689  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
690  }
691  else
692  {
693  NS_LOG_ERROR ("No IPV6 Routing Protocol");
694  route = 0;
695  }
696  m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, route);
697  }
698  else
699  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv6 interface");
700 }
701 
702 void
704 {
705  m_downTarget = callback;
706 }
707 
710 {
711  return m_downTarget;
712 }
713 
714 void
716 {
717  m_downTarget6 = callback;
718 }
719 
722 {
723  return m_downTarget6;
724 }
725 
726 } // namespace ns3
727 
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)
Definition: log.h:345
uint16_t GetDestinationPort() const
Definition: tcp-header.cc:93
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:97
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:123
uint8_t GetFlags() const
Definition: tcp-header.cc:109
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:101
static bool ChecksumEnabled(void)
Definition: node.cc:266
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:1014
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
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
Definition: packet.h:650
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:77
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
#define NS_LOG_INFO(msg)
Definition: log.h:298
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
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
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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
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:39
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:1238
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:243
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
std::vector< Ptr< TcpSocketBase > > m_sockets
list of sockets
void SetDestinationPort(uint16_t port)
Definition: tcp-header.cc:60
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:76
virtual void NotifyNewAggregate(void)
This method is invoked whenever two sets of objects are aggregated together.
Definition: object.cc:315
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
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:56
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)
Definition: assert.h:86
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:97
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:68
Demultiplexor for end points.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:102
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
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...
NS_LOG_COMPONENT_DEFINE("TcpL4Protocol")
TypeId m_rttTypeId
The RTT Estimator TypeId.
uint16_t GetSourcePort() const
Definition: tcp-header.cc:89
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1018
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)
Definition: log.h:271
void SetLength(uint8_t length)
Definition: tcp-header.cc:72
tuple address
Definition: first.py:37
bool IsChecksumOk(void) const
Is the TCP checksum correct ?
Definition: tcp-header.cc:196
void EnableChecksums(void)
Enable checksum calculation for TCP.
Definition: tcp-header.cc:51
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:361
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:107
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
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:112
A representation of an internet endpoint/connection.
IpL4Protocol::DownTargetCallback m_downTarget
Callback to send packets over IPv4.
Ipv4EndPoint * Allocate(void)
Allocate a Ipv4EndPoint.