A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
tcp-header.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 <stdint.h>
22 #include <iostream>
23 #include "tcp-header.h"
24 #include "ns3/buffer.h"
25 #include "ns3/address-utils.h"
26 
27 namespace ns3 {
28 
29 NS_OBJECT_ENSURE_REGISTERED (TcpHeader);
30 
32  : m_sourcePort (0),
33  m_destinationPort (0),
34  m_sequenceNumber (0),
35  m_ackNumber (0),
36  m_length (5),
37  m_flags (0),
38  m_windowSize (0xffff),
39  m_urgentPointer (0),
40  m_calcChecksum (false),
41  m_goodChecksum (true)
42 {
43 }
44 
46 {
47 }
48 
49 void
51 {
52  m_calcChecksum = true;
53 }
54 
56 {
58 }
60 {
62 }
64 {
65  m_sequenceNumber = sequenceNumber;
66 }
68 {
69  m_ackNumber = ackNumber;
70 }
71 void TcpHeader::SetLength (uint8_t length)
72 {
73  m_length = length;
74 }
75 void TcpHeader::SetFlags (uint8_t flags)
76 {
77  m_flags = flags;
78 }
79 void TcpHeader::SetWindowSize (uint16_t windowSize)
80 {
81  m_windowSize = windowSize;
82 }
83 void TcpHeader::SetUrgentPointer (uint16_t urgentPointer)
84 {
85  m_urgentPointer = urgentPointer;
86 }
87 
88 uint16_t TcpHeader::GetSourcePort () const
89 {
90  return m_sourcePort;
91 }
93 {
94  return m_destinationPort;
95 }
97 {
98  return m_sequenceNumber;
99 }
101 {
102  return m_ackNumber;
103 }
104 uint8_t TcpHeader::GetLength () const
105 {
106  return m_length;
107 }
108 uint8_t TcpHeader::GetFlags () const
109 {
110  return m_flags;
111 }
112 uint16_t TcpHeader::GetWindowSize () const
113 {
114  return m_windowSize;
115 }
117 {
118  return m_urgentPointer;
119 }
120 
121 void
123  Ipv4Address destination,
124  uint8_t protocol)
125 {
126  m_source = source;
127  m_destination = destination;
128  m_protocol = protocol;
129 }
130 
131 void
133  Ipv6Address destination,
134  uint8_t protocol)
135 {
136  m_source = source;
137  m_destination = destination;
138  m_protocol = protocol;
139 }
140 
141 void
143  Address destination,
144  uint8_t protocol)
145 {
146  m_source = source;
147  m_destination = destination;
148  m_protocol = protocol;
149 }
150 
151 uint16_t
153 {
154  /* Buffer size must be at least as large as the largest IP pseudo-header */
155  /* [per RFC2460, but without consideration for IPv6 extension hdrs] */
156  /* Src address 16 bytes (more generally, Address::MAX_SIZE) */
157  /* Dst address 16 bytes (more generally, Address::MAX_SIZE) */
158  /* Upper layer pkt len 4 bytes */
159  /* Zero 3 bytes */
160  /* Next header 1 byte */
161 
162  uint32_t maxHdrSz = (2 * Address::MAX_SIZE) + 8;
163  Buffer buf = Buffer (maxHdrSz);
164  buf.AddAtStart (maxHdrSz);
165  Buffer::Iterator it = buf.Begin ();
166  uint32_t hdrSize = 0;
167 
168  WriteTo (it, m_source);
169  WriteTo (it, m_destination);
171  {
172  it.WriteU8 (0); /* protocol */
173  it.WriteU8 (m_protocol); /* protocol */
174  it.WriteU8 (size >> 8); /* length */
175  it.WriteU8 (size & 0xff); /* length */
176  hdrSize = 12;
177  }
178  else
179  {
180  it.WriteU16 (0);
181  it.WriteU8 (size >> 8); /* length */
182  it.WriteU8 (size & 0xff); /* length */
183  it.WriteU16 (0);
184  it.WriteU8 (0);
185  it.WriteU8 (m_protocol); /* protocol */
186  hdrSize = 40;
187  }
188 
189  it = buf.Begin ();
190  /* we don't CompleteChecksum ( ~ ) now */
191  return ~(it.CalculateIpChecksum (hdrSize));
192 }
193 
194 bool
196 {
197  return m_goodChecksum;
198 }
199 
200 TypeId
202 {
203  static TypeId tid = TypeId ("ns3::TcpHeader")
204  .SetParent<Header> ()
205  .AddConstructor<TcpHeader> ()
206  ;
207  return tid;
208 }
209 TypeId
211 {
212  return GetTypeId ();
213 }
214 void TcpHeader::Print (std::ostream &os) const
215 {
216  os << m_sourcePort << " > " << m_destinationPort;
217  if(m_flags!=0)
218  {
219  os<<" [";
220  if((m_flags & FIN) != 0)
221  {
222  os<<" FIN ";
223  }
224  if((m_flags & SYN) != 0)
225  {
226  os<<" SYN ";
227  }
228  if((m_flags & RST) != 0)
229  {
230  os<<" RST ";
231  }
232  if((m_flags & PSH) != 0)
233  {
234  os<<" PSH ";
235  }
236  if((m_flags & ACK) != 0)
237  {
238  os<<" ACK ";
239  }
240  if((m_flags & URG) != 0)
241  {
242  os<<" URG ";
243  }
244  if((m_flags & ECE) != 0)
245  {
246  os<<" ECE ";
247  }
248  if((m_flags & CWR) != 0)
249  {
250  os<<" CWR ";
251  }
252  os<<"]";
253  }
254  os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize;
255 }
256 uint32_t TcpHeader::GetSerializedSize (void) const
257 {
258  return 4*m_length;
259 }
261 {
267  i.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
269  i.WriteHtonU16 (0);
271 
272  if(m_calcChecksum)
273  {
274  uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ());
275  i = start;
276  uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum);
277 
278  i = start;
279  i.Next (16);
280  i.WriteU16 (checksum);
281  }
282 }
284 {
286  m_sourcePort = i.ReadNtohU16 ();
289  m_ackNumber = i.ReadNtohU32 ();
290  uint16_t field = i.ReadNtohU16 ();
291  m_flags = field & 0x3F;
292  m_length = field>>12;
293  m_windowSize = i.ReadNtohU16 ();
294  i.Next (2);
296 
297  if(m_calcChecksum)
298  {
299  uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ());
300  i = start;
301  uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum);
302  m_goodChecksum = (checksum == 0);
303  }
304 
305  return GetSerializedSize ();
306 }
307 
308 
309 } // namespace ns3