A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
tcp-l4-protocol.cc
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"
42 #include "tcp-socket-factory-impl.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
66 TcpL4Protocol::GetTypeId (void)
67 {
68  static TypeId tid = TypeId ("ns3::TcpL4Protocol")
69  .SetParent<IpL4Protocol> ()
70  .AddConstructor<TcpL4Protocol> ()
71  .AddAttribute ("RttEstimatorType",
72  "Type of RttEstimator objects.",
73  TypeIdValue (RttMeanDeviation::GetTypeId ()),
74  MakeTypeIdAccessor (&TcpL4Protocol::m_rttTypeId),
75  MakeTypeIdChecker ())
76  .AddAttribute ("SocketType",
77  "Socket type of TCP objects.",
78  TypeIdValue (TcpNewReno::GetTypeId ()),
79  MakeTypeIdAccessor (&TcpL4Protocol::m_socketTypeId),
80  MakeTypeIdChecker ())
81  .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
82  ObjectVectorValue (),
83  MakeObjectVectorAccessor (&TcpL4Protocol::m_sockets),
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 
96 TcpL4Protocol::~TcpL4Protocol ()
97 {
99 }
100 
101 void
102 TcpL4Protocol::SetNode (Ptr<Node> node)
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);
143  this->SetDownTarget6(MakeCallback(&Ipv6L3Protocol::Send, ipv6));
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;
173  m_downTarget.Nullify ();
174  m_downTarget6.Nullify ();
176 }
177 
179 TcpL4Protocol::CreateSocket (TypeId socketTypeId)
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  return socket;
192 }
193 
194 Ptr<Socket>
196 {
197  return CreateSocket (m_socketTypeId);
198 }
199 
200 Ipv4EndPoint *
201 TcpL4Protocol::Allocate (void)
202 {
204  return m_endPoints->Allocate ();
205 }
206 
207 Ipv4EndPoint *
208 TcpL4Protocol::Allocate (Ipv4Address address)
209 {
210  NS_LOG_FUNCTION (this << address);
211  return m_endPoints->Allocate (address);
212 }
213 
214 Ipv4EndPoint *
215 TcpL4Protocol::Allocate (uint16_t port)
216 {
217  NS_LOG_FUNCTION (this << port);
218  return m_endPoints->Allocate (port);
219 }
220 
221 Ipv4EndPoint *
222 TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
223 {
224  NS_LOG_FUNCTION (this << address << port);
225  return m_endPoints->Allocate (address, port);
226 }
227 
228 Ipv4EndPoint *
229 TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
230  Ipv4Address peerAddress, uint16_t peerPort)
231 {
232  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
233  return m_endPoints->Allocate (localAddress, localPort,
234  peerAddress, peerPort);
235 }
236 
237 void
238 TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
239 {
240  NS_LOG_FUNCTION (this << endPoint);
241  m_endPoints->DeAllocate (endPoint);
242 }
243 
244 Ipv6EndPoint *
245 TcpL4Protocol::Allocate6 (void)
246 {
248  return m_endPoints6->Allocate ();
249 }
250 
251 Ipv6EndPoint *
252 TcpL4Protocol::Allocate6 (Ipv6Address address)
253 {
254  NS_LOG_FUNCTION (this << address);
255  return m_endPoints6->Allocate (address);
256 }
257 
258 Ipv6EndPoint *
259 TcpL4Protocol::Allocate6 (uint16_t port)
260 {
261  NS_LOG_FUNCTION (this << port);
262  return m_endPoints6->Allocate (port);
263 }
264 
265 Ipv6EndPoint *
266 TcpL4Protocol::Allocate6 (Ipv6Address address, uint16_t port)
267 {
268  NS_LOG_FUNCTION (this << address << port);
269  return m_endPoints6->Allocate (address, port);
270 }
271 
272 Ipv6EndPoint *
273 TcpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
274  Ipv6Address peerAddress, uint16_t peerPort)
275 {
276  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
277  return m_endPoints6->Allocate (localAddress, localPort,
278  peerAddress, peerPort);
279 }
280 
281 void
282 TcpL4Protocol::DeAllocate (Ipv6EndPoint *endPoint)
283 {
284  NS_LOG_FUNCTION (this << endPoint);
285  m_endPoints6->DeAllocate (endPoint);
286 }
287 
288 void
289 TcpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
290  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
291  Ipv4Address payloadSource,Ipv4Address payloadDestination,
292  const uint8_t payload[8])
293 {
294  NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
295  << payloadSource << payloadDestination);
296  uint16_t src, dst;
297  src = payload[0] << 8;
298  src |= payload[1];
299  dst = payload[2] << 8;
300  dst |= payload[3];
301 
302  Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst);
303  if (endPoint != 0)
304  {
305  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
306  }
307  else
308  {
309  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
310  ", destination="<<payloadDestination<<
311  ", src=" << src << ", dst=" << dst);
312  }
313 }
314 
315 void
316 TcpL4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
317  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
318  Ipv6Address payloadSource,Ipv6Address payloadDestination,
319  const uint8_t payload[8])
320 {
321  NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
322  << payloadSource << payloadDestination);
323  uint16_t src, dst;
324  src = payload[0] << 8;
325  src |= payload[1];
326  dst = payload[2] << 8;
327  dst |= payload[3];
328 
329  Ipv6EndPoint *endPoint = m_endPoints6->SimpleLookup (payloadSource, src, payloadDestination, dst);
330  if (endPoint != 0)
331  {
332  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
333  }
334  else
335  {
336  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
337  ", destination="<<payloadDestination<<
338  ", src=" << src << ", dst=" << dst);
339  }
340 }
341 
342 enum IpL4Protocol::RxStatus
344  Ipv4Header const &ipHeader,
345  Ptr<Ipv4Interface> incomingInterface)
346 {
347  NS_LOG_FUNCTION (this << packet << ipHeader << incomingInterface);
348 
349  TcpHeader tcpHeader;
350  if(Node::ChecksumEnabled ())
351  {
352  tcpHeader.EnableChecksums ();
353  tcpHeader.InitializeChecksum (ipHeader.GetSource (), ipHeader.GetDestination (), PROT_NUMBER);
354  }
355 
356  packet->PeekHeader (tcpHeader);
357 
358  NS_LOG_LOGIC ("TcpL4Protocol " << this
359  << " receiving seq " << tcpHeader.GetSequenceNumber ()
360  << " ack " << tcpHeader.GetAckNumber ()
361  << " flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
362  << " data size " << packet->GetSize ());
363 
364  if(!tcpHeader.IsChecksumOk ())
365  {
366  NS_LOG_INFO ("Bad checksum, dropping packet!");
367  return IpL4Protocol::RX_CSUM_FAILED;
368  }
369 
370  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
371  Ipv4EndPointDemux::EndPoints endPoints =
372  m_endPoints->Lookup (ipHeader.GetDestination (), tcpHeader.GetDestinationPort (),
373  ipHeader.GetSource (), tcpHeader.GetSourcePort (),incomingInterface);
374  if (endPoints.empty ())
375  {
376  if (this->GetObject<Ipv6L3Protocol> () != 0)
377  {
378  NS_LOG_LOGIC (" No Ipv4 endpoints matched on TcpL4Protocol, trying Ipv6 "<<this);
379  Ptr<Ipv6Interface> fakeInterface;
380  Ipv6Header ipv6Header;
383  ipv6Header.SetSourceAddress (src);
384  ipv6Header.SetDestinationAddress (dst);
385  return (this->Receive (packet, ipv6Header, fakeInterface));
386  }
387 
388  NS_LOG_LOGIC (" No endpoints matched on TcpL4Protocol "<<this);
389  std::ostringstream oss;
390  oss<<" destination IP: ";
391  ipHeader.GetDestination ().Print (oss);
392  oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
393  ipHeader.GetSource ().Print (oss);
394  oss<<" source port: "<<tcpHeader.GetSourcePort ();
395  NS_LOG_LOGIC (oss.str ());
396 
397  if (!(tcpHeader.GetFlags () & TcpHeader::RST))
398  {
399  // build a RST packet and send
400  Ptr<Packet> rstPacket = Create<Packet> ();
401  TcpHeader header;
402  if (tcpHeader.GetFlags () & TcpHeader::ACK)
403  {
404  // ACK bit was set
405  header.SetFlags (TcpHeader::RST);
406  header.SetSequenceNumber (header.GetAckNumber ());
407  }
408  else
409  {
410  header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
411  header.SetSequenceNumber (SequenceNumber32 (0));
412  header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
413  }
414  header.SetSourcePort (tcpHeader.GetDestinationPort ());
415  header.SetDestinationPort (tcpHeader.GetSourcePort ());
416  SendPacket (rstPacket, header, ipHeader.GetDestination (), ipHeader.GetSource ());
417  return IpL4Protocol::RX_ENDPOINT_CLOSED;
418  }
419  else
420  {
421  return IpL4Protocol::RX_ENDPOINT_CLOSED;
422  }
423  }
424  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
425  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
426  (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort (),
427  incomingInterface);
428  return IpL4Protocol::RX_OK;
429 }
430 
431 enum IpL4Protocol::RxStatus
433  Ipv6Header const &ipHeader,
434  Ptr<Ipv6Interface> interface)
435 {
436  NS_LOG_FUNCTION (this << packet << ipHeader.GetSourceAddress () << ipHeader.GetDestinationAddress ());
437 
438  TcpHeader tcpHeader;
439 
440  // If we are receving a v4-mapped packet, we will re-calculate the TCP checksum
441  // Is it worth checking every received "v6" packet to see if it is v4-mapped in
442  // order to avoid re-calculating TCP checksums for v4-mapped packets?
443 
444  if(Node::ChecksumEnabled ())
445  {
446  tcpHeader.EnableChecksums ();
447  tcpHeader.InitializeChecksum (ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress (), PROT_NUMBER);
448  }
449 
450  packet->PeekHeader (tcpHeader);
451 
452  NS_LOG_LOGIC ("TcpL4Protocol " << this
453  << " receiving seq " << tcpHeader.GetSequenceNumber ()
454  << " ack " << tcpHeader.GetAckNumber ()
455  << " flags "<< std::hex << (int)tcpHeader.GetFlags () << std::dec
456  << " data size " << packet->GetSize ());
457 
458  if(!tcpHeader.IsChecksumOk ())
459  {
460  NS_LOG_INFO ("Bad checksum, dropping packet!");
461  return IpL4Protocol::RX_CSUM_FAILED;
462  }
463 
464  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
465  Ipv6EndPointDemux::EndPoints endPoints =
466  m_endPoints6->Lookup (ipHeader.GetDestinationAddress (), tcpHeader.GetDestinationPort (),
467  ipHeader.GetSourceAddress (), tcpHeader.GetSourcePort (),interface);
468  if (endPoints.empty ())
469  {
470  NS_LOG_LOGIC (" No IPv6 endpoints matched on TcpL4Protocol "<<this);
471  std::ostringstream oss;
472  oss<<" destination IP: ";
473  (ipHeader.GetDestinationAddress ()).Print (oss);
474  oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
475  (ipHeader.GetSourceAddress ()).Print (oss);
476  oss<<" source port: "<<tcpHeader.GetSourcePort ();
477  NS_LOG_LOGIC (oss.str ());
478 
479  if (!(tcpHeader.GetFlags () & TcpHeader::RST))
480  {
481  // build a RST packet and send
482  Ptr<Packet> rstPacket = Create<Packet> ();
483  TcpHeader header;
484  if (tcpHeader.GetFlags () & TcpHeader::ACK)
485  {
486  // ACK bit was set
487  header.SetFlags (TcpHeader::RST);
488  header.SetSequenceNumber (header.GetAckNumber ());
489  }
490  else
491  {
492  header.SetFlags (TcpHeader::RST | TcpHeader::ACK);
493  header.SetSequenceNumber (SequenceNumber32 (0));
494  header.SetAckNumber (header.GetSequenceNumber () + SequenceNumber32 (1));
495  }
496  header.SetSourcePort (tcpHeader.GetDestinationPort ());
497  header.SetDestinationPort (tcpHeader.GetSourcePort ());
498  SendPacket (rstPacket, header, ipHeader.GetDestinationAddress (), ipHeader.GetSourceAddress ());
499  return IpL4Protocol::RX_ENDPOINT_CLOSED;
500  }
501  else
502  {
503  return IpL4Protocol::RX_ENDPOINT_CLOSED;
504  }
505  }
506  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
507  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
508  (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort ());
509  return IpL4Protocol::RX_OK;
510 }
511 
512 void
514  Ipv4Address saddr, Ipv4Address daddr,
515  uint16_t sport, uint16_t dport, Ptr<NetDevice> oif)
516 {
517  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << oif);
518 
519  TcpHeader tcpHeader;
520  tcpHeader.SetDestinationPort (dport);
521  tcpHeader.SetSourcePort (sport);
522  if(Node::ChecksumEnabled ())
523  {
524  tcpHeader.EnableChecksums ();
525  }
526  tcpHeader.InitializeChecksum (saddr,
527  daddr,
528  PROT_NUMBER);
529  tcpHeader.SetFlags (TcpHeader::ACK);
530  tcpHeader.SetAckNumber (SequenceNumber32 (0));
531 
532  packet->AddHeader (tcpHeader);
533 
534  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
535  if (ipv4 != 0)
536  {
537  Ipv4Header header;
538  header.SetDestination (daddr);
539  header.SetProtocol (PROT_NUMBER);
540  Socket::SocketErrno errno_;
541  Ptr<Ipv4Route> route;
542  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
543  if (ipv4->GetRoutingProtocol () != 0)
544  {
545  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
546  }
547  else
548  {
549  NS_LOG_ERROR ("No IPV4 Routing Protocol");
550  route = 0;
551  }
552  ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
553  }
554 }
555 
556 void
558  Ipv6Address saddr, Ipv6Address daddr,
559  uint16_t sport, uint16_t dport, Ptr<NetDevice> oif)
560 {
561  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport << oif);
562 
563  TcpHeader tcpHeader;
564  tcpHeader.SetDestinationPort (dport);
565  tcpHeader.SetSourcePort (sport);
566  if(Node::ChecksumEnabled ())
567  {
568  tcpHeader.EnableChecksums ();
569  }
570  tcpHeader.InitializeChecksum (saddr,
571  daddr,
572  PROT_NUMBER);
573  tcpHeader.SetFlags (TcpHeader::ACK);
574  tcpHeader.SetAckNumber (SequenceNumber32 (0));
575 
576  packet->AddHeader (tcpHeader);
577 
578  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
579  if (ipv6 != 0)
580  {
581  Ipv6Header header;
582  header.SetDestinationAddress (daddr);
583  header.SetNextHeader (PROT_NUMBER);
584  Socket::SocketErrno errno_;
585  Ptr<Ipv6Route> route;
586  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
587  if (ipv6->GetRoutingProtocol () != 0)
588  {
589  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
590  }
591  else
592  {
593  NS_LOG_ERROR ("No IPV6 Routing Protocol");
594  route = 0;
595  }
596  ipv6->Send (packet, saddr, daddr, PROT_NUMBER, route);
597  }
598 }
599 
600 void
601 TcpL4Protocol::SendPacket (Ptr<Packet> packet, const TcpHeader &outgoing,
602  Ipv4Address saddr, Ipv4Address daddr, Ptr<NetDevice> oif)
603 {
604  NS_LOG_LOGIC ("TcpL4Protocol " << this
605  << " sending seq " << outgoing.GetSequenceNumber ()
606  << " ack " << outgoing.GetAckNumber ()
607  << " flags " << std::hex << (int)outgoing.GetFlags () << std::dec
608  << " data size " << packet->GetSize ());
609  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
610  // XXX outgoingHeader cannot be logged
611 
612  TcpHeader outgoingHeader = outgoing;
613  outgoingHeader.SetLength (5); //header length in units of 32bit words
614  /* outgoingHeader.SetUrgentPointer (0); //XXX */
615  if(Node::ChecksumEnabled ())
616  {
617  outgoingHeader.EnableChecksums ();
618  }
619  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
620 
621  packet->AddHeader (outgoingHeader);
622 
623  Ptr<Ipv4> ipv4 =
624  m_node->GetObject<Ipv4> ();
625  if (ipv4 != 0)
626  {
627  Ipv4Header header;
628  header.SetDestination (daddr);
629  header.SetProtocol (PROT_NUMBER);
630  Socket::SocketErrno errno_;
631  Ptr<Ipv4Route> route;
632  if (ipv4->GetRoutingProtocol () != 0)
633  {
634  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
635  }
636  else
637  {
638  NS_LOG_ERROR ("No IPV4 Routing Protocol");
639  route = 0;
640  }
641  m_downTarget (packet, saddr, daddr, PROT_NUMBER, route);
642  }
643  else
644  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv4 interface");
645 }
646 
647 void
648 TcpL4Protocol::SendPacket (Ptr<Packet> packet, const TcpHeader &outgoing,
649  Ipv6Address saddr, Ipv6Address daddr, Ptr<NetDevice> oif)
650 {
651  NS_LOG_LOGIC ("TcpL4Protocol " << this
652  << " sending seq " << outgoing.GetSequenceNumber ()
653  << " ack " << outgoing.GetAckNumber ()
654  << " flags " << std::hex << (int)outgoing.GetFlags () << std::dec
655  << " data size " << packet->GetSize ());
656  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
657  // XXX outgoingHeader cannot be logged
658 
659  if (daddr.IsIpv4MappedAddress ())
660  {
661  return (SendPacket (packet, outgoing, saddr.GetIpv4MappedAddress(), daddr.GetIpv4MappedAddress(), oif));
662  }
663  TcpHeader outgoingHeader = outgoing;
664  outgoingHeader.SetLength (5); //header length in units of 32bit words
665  /* outgoingHeader.SetUrgentPointer (0); //XXX */
666  if(Node::ChecksumEnabled ())
667  {
668  outgoingHeader.EnableChecksums ();
669  }
670  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
671 
672  packet->AddHeader (outgoingHeader);
673 
674  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
675  if (ipv6 != 0)
676  {
677  Ipv6Header header;
678  header.SetDestinationAddress (daddr);
679  header.SetSourceAddress (saddr);
680  header.SetNextHeader (PROT_NUMBER);
681  Socket::SocketErrno errno_;
682  Ptr<Ipv6Route> route;
683  if (ipv6->GetRoutingProtocol () != 0)
684  {
685  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
686  }
687  else
688  {
689  NS_LOG_ERROR ("No IPV6 Routing Protocol");
690  route = 0;
691  }
692  m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, route);
693  }
694  else
695  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv6 interface");
696 }
697 
698 void
700 {
701  m_downTarget = callback;
702 }
703 
706 {
707  return m_downTarget;
708 }
709 
710 void
711 TcpL4Protocol::SetDownTarget6 (IpL4Protocol::DownTargetCallback6 callback)
712 {
713  m_downTarget6 = callback;
714 }
715 
716 IpL4Protocol::DownTargetCallback6
717 TcpL4Protocol::GetDownTarget6 (void) const
718 {
719  return m_downTarget6;
720 }
721 
722 } // namespace ns3
723 
Ptr< Socket > CreateSocket(void)
Packet header for IPv6.
Definition: ipv6-header.h:33
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:297
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
uint16_t GetDestinationPort() const
Definition: tcp-header.cc:92
SequenceNumber32 GetSequenceNumber() const
Definition: tcp-header.cc:96
void InitializeChecksum(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
Definition: tcp-header.cc:122
uint8_t GetFlags() const
Definition: tcp-header.cc:108
virtual void DoDispose(void)
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:267
void Send(Ptr< Packet > packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport, uint16_t dport, Ptr< NetDevice > oif=0)
Send a packet via TCP.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
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])
Receive an ICMP packet.
void SetTypeId(TypeId tid)
uint32_t GetSize(void) const
Definition: packet.h:620
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Definition: log.h:264
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:277
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
virtual void NotifyNewAggregate()
Demultiplexes packets to various transport layer endpoints.
Packet header for IPv4.
Definition: ipv4-header.h:31
Ptr< Object > Create(void) const
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Receive a packet up the protocol stack.
TcpL4Protocol()
Constructor.
Base class for all RTT Estimators.
Definition: rtt-estimator.h:58
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const
Ipv6EndPoint * Allocate(void)
Allocate a Ipv6EndPoint.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
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)
Definition: log.h:334
void SetDestinationPort(uint16_t port)
Definition: tcp-header.cc:59
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
void SetFlags(uint8_t flags)
Definition: tcp-header.cc:75
virtual void NotifyNewAggregate(void)
Definition: object.cc:314
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
uint32_t PeekHeader(Header &header) const
Definition: packet.cc:294
Header for the Transmission Control Protocol.
Definition: tcp-header.h:43
virtual int GetProtocolNumber(void) const
virtual void SetNode(Ptr< Node > 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
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:96
Describes an IPv6 address.
Definition: ipv6-address.h:44
instantiate subclasses of ns3::Object.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
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)
Definition: log.h:255
An IPv6 end point, four tuples identification.
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)
uint16_t GetSourcePort() const
Definition: tcp-header.cc:88
void ForwardIcmp(Ipv6Address src, uint8_t ttl, uint8_t type, uint8_t code, uint32_t info)
Function called from an L4Protocol implementation to notify an endpoint of an icmp message reception...
#define NS_LOG_ERROR(msg)
Definition: log.h:237
bool IsChecksumOk(void) const
Is the TCP checksum correct ?
Definition: tcp-header.cc:195
void EnableChecksums(void)
Enable checksum calculation for TCP (XXX currently has no effect)
Definition: tcp-header.cc:50
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Ptr< T > GetObject(void) const
Definition: object.h:332
a unique identifier for an interface.
Definition: type-id.h:44
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
void AddHeader(const Header &header)
Definition: packet.cc:270
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
A representation of an internet endpoint/connection.