A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
tcp-header.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 <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 
31 TcpHeader::TcpHeader ()
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 
45 TcpHeader::~TcpHeader ()
46 {
47 }
48 
49 void
50 TcpHeader::EnableChecksums (void)
51 {
52  m_calcChecksum = true;
53 }
54 
55 void TcpHeader::SetSourcePort (uint16_t port)
56 {
57  m_sourcePort = port;
58 }
59 void TcpHeader::SetDestinationPort (uint16_t port)
60 {
61  m_destinationPort = port;
62 }
63 void TcpHeader::SetSequenceNumber (SequenceNumber32 sequenceNumber)
64 {
65  m_sequenceNumber = sequenceNumber;
66 }
67 void TcpHeader::SetAckNumber (SequenceNumber32 ackNumber)
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 }
92 uint16_t TcpHeader::GetDestinationPort () const
93 {
94  return m_destinationPort;
95 }
96 SequenceNumber32 TcpHeader::GetSequenceNumber () const
97 {
98  return m_sequenceNumber;
99 }
100 SequenceNumber32 TcpHeader::GetAckNumber () const
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 }
116 uint16_t TcpHeader::GetUrgentPointer () const
117 {
118  return m_urgentPointer;
119 }
120 
121 void
122 TcpHeader::InitializeChecksum (Ipv4Address source,
123  Ipv4Address destination,
124  uint8_t protocol)
125 {
126  m_source = source;
127  m_destination = destination;
128  m_protocol = protocol;
129 }
130 
131 void
132 TcpHeader::InitializeChecksum (Ipv6Address source,
133  Ipv6Address destination,
134  uint8_t protocol)
135 {
136  m_source = source;
137  m_destination = destination;
138  m_protocol = protocol;
139 }
140 
141 void
142 TcpHeader::InitializeChecksum (Address source,
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
152 TcpHeader::CalculateHeaderChecksum (uint16_t size) const
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);
170  if (Ipv4Address::IsMatchingType(m_source))
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
195 TcpHeader::IsChecksumOk (void) const
196 {
197  return m_goodChecksum;
198 }
199 
200 TypeId
201 TcpHeader::GetTypeId (void)
202 {
203  static TypeId tid = TypeId ("ns3::TcpHeader")
204  .SetParent<Header> ()
205  .AddConstructor<TcpHeader> ()
206  ;
207  return tid;
208 }
209 TypeId
210 TcpHeader::GetInstanceTypeId (void) const
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 }
260 void TcpHeader::Serialize (Buffer::Iterator start) const
261 {
262  Buffer::Iterator i = start;
263  i.WriteHtonU16 (m_sourcePort);
264  i.WriteHtonU16 (m_destinationPort);
265  i.WriteHtonU32 (m_sequenceNumber.GetValue ());
266  i.WriteHtonU32 (m_ackNumber.GetValue ());
267  i.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
268  i.WriteHtonU16 (m_windowSize);
269  i.WriteHtonU16 (0);
270  i.WriteHtonU16 (m_urgentPointer);
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 }
283 uint32_t TcpHeader::Deserialize (Buffer::Iterator start)
284 {
285  Buffer::Iterator i = start;
286  m_sourcePort = i.ReadNtohU16 ();
287  m_destinationPort = i.ReadNtohU16 ();
288  m_sequenceNumber = i.ReadNtohU32 ();
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);
295  m_urgentPointer = i.ReadNtohU16 ();
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
Protocol header serialization and deserialization.
Definition: header.h:42
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1158
uint32_t ReadNtohU32(void)
Definition: buffer.h:791
iterator in a Buffer instance
Definition: buffer.h:98
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
void Next(void)
Definition: buffer.h:666
void WriteHtonU32(uint32_t data)
Definition: buffer.h:745
Describes an IPv6 address.
Definition: ipv6-address.h:44
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
uint32_t GetSize(void) const
Definition: buffer.cc:1183
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471