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-socket-impl.h" |
|
24 #include "tcp-header.h" |
|
25 #include "ns3/buffer.h" |
|
26 |
|
27 namespace ns3 { |
|
28 |
|
29 NS_OBJECT_ENSURE_REGISTERED (TcpHeader); |
|
30 |
|
31 bool TcpHeader::m_calcChecksum = false; |
|
32 |
|
33 TcpHeader::TcpHeader () |
|
34 : m_sourcePort (0), |
|
35 m_destinationPort (0), |
|
36 m_sequenceNumber (0), |
|
37 m_ackNumber (0), |
|
38 m_length (5), |
|
39 m_flags (0), |
|
40 m_windowSize (0xffff), |
|
41 m_checksum (0), |
|
42 m_urgentPointer (0) |
|
43 {} |
|
44 |
|
45 TcpHeader::~TcpHeader () |
|
46 {} |
|
47 |
|
48 void |
|
49 TcpHeader::EnableChecksums (void) |
|
50 { |
|
51 m_calcChecksum = true; |
|
52 } |
|
53 |
|
54 void TcpHeader::SetSourcePort (uint16_t port) |
|
55 { |
|
56 m_sourcePort = port; |
|
57 } |
|
58 void TcpHeader::SetDestinationPort (uint16_t port) |
|
59 { |
|
60 m_destinationPort = port; |
|
61 } |
|
62 void TcpHeader::SetSequenceNumber (SequenceNumber sequenceNumber) |
|
63 { |
|
64 m_sequenceNumber = sequenceNumber; |
|
65 } |
|
66 void TcpHeader::SetAckNumber (SequenceNumber ackNumber) |
|
67 { |
|
68 m_ackNumber = ackNumber; |
|
69 } |
|
70 void TcpHeader::SetLength (uint8_t length) |
|
71 { |
|
72 m_length = length; |
|
73 } |
|
74 void TcpHeader::SetFlags (uint8_t flags) |
|
75 { |
|
76 m_flags = flags; |
|
77 } |
|
78 void TcpHeader::SetWindowSize (uint16_t windowSize) |
|
79 { |
|
80 m_windowSize = windowSize; |
|
81 } |
|
82 void TcpHeader::SetChecksum (uint16_t checksum) |
|
83 { |
|
84 m_checksum = checksum; |
|
85 } |
|
86 void TcpHeader::SetUrgentPointer (uint16_t urgentPointer) |
|
87 { |
|
88 m_urgentPointer = urgentPointer; |
|
89 } |
|
90 |
|
91 uint16_t TcpHeader::GetSourcePort () const |
|
92 { |
|
93 return m_sourcePort; |
|
94 } |
|
95 uint16_t TcpHeader::GetDestinationPort () const |
|
96 { |
|
97 return m_destinationPort; |
|
98 } |
|
99 SequenceNumber TcpHeader::GetSequenceNumber () const |
|
100 { |
|
101 return m_sequenceNumber; |
|
102 } |
|
103 SequenceNumber TcpHeader::GetAckNumber () const |
|
104 { |
|
105 return m_ackNumber; |
|
106 } |
|
107 uint8_t TcpHeader::GetLength () const |
|
108 { |
|
109 return m_length; |
|
110 } |
|
111 uint8_t TcpHeader::GetFlags () const |
|
112 { |
|
113 return m_flags; |
|
114 } |
|
115 uint16_t TcpHeader::GetWindowSize () const |
|
116 { |
|
117 return m_windowSize; |
|
118 } |
|
119 uint16_t TcpHeader::GetChecksum () const |
|
120 { |
|
121 return m_checksum; |
|
122 } |
|
123 uint16_t TcpHeader::GetUrgentPointer () const |
|
124 { |
|
125 return m_urgentPointer; |
|
126 } |
|
127 |
|
128 void |
|
129 TcpHeader::InitializeChecksum (Ipv4Address source, |
|
130 Ipv4Address destination, |
|
131 uint8_t protocol) |
|
132 { |
|
133 m_checksum = 0; |
|
134 //XXX requires peeking into IP to get length of the TCP segment |
|
135 } |
|
136 |
|
137 TypeId |
|
138 TcpHeader::GetTypeId (void) |
|
139 { |
|
140 static TypeId tid = TypeId ("ns3::TcpHeader") |
|
141 .SetParent<Header> () |
|
142 .AddConstructor<TcpHeader> () |
|
143 ; |
|
144 return tid; |
|
145 } |
|
146 TypeId |
|
147 TcpHeader::GetInstanceTypeId (void) const |
|
148 { |
|
149 return GetTypeId (); |
|
150 } |
|
151 void TcpHeader::Print (std::ostream &os) const |
|
152 { |
|
153 os << m_sourcePort << " > " << m_destinationPort; |
|
154 if(m_flags!=0) |
|
155 { |
|
156 os<<" ["; |
|
157 if((m_flags & FIN) != 0) |
|
158 { |
|
159 os<<" FIN "; |
|
160 } |
|
161 if((m_flags & SYN) != 0) |
|
162 { |
|
163 os<<" SYN "; |
|
164 } |
|
165 if((m_flags & RST) != 0) |
|
166 { |
|
167 os<<" RST "; |
|
168 } |
|
169 if((m_flags & PSH) != 0) |
|
170 { |
|
171 os<<" PSH "; |
|
172 } |
|
173 if((m_flags & ACK) != 0) |
|
174 { |
|
175 os<<" ACK "; |
|
176 } |
|
177 if((m_flags & URG) != 0) |
|
178 { |
|
179 os<<" URG "; |
|
180 } |
|
181 os<<"]"; |
|
182 } |
|
183 os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize; |
|
184 } |
|
185 uint32_t TcpHeader::GetSerializedSize (void) const |
|
186 { |
|
187 return 4*m_length; |
|
188 } |
|
189 void TcpHeader::Serialize (Buffer::Iterator start) const |
|
190 { |
|
191 start.WriteHtonU16 (m_sourcePort); |
|
192 start.WriteHtonU16 (m_destinationPort); |
|
193 start.WriteHtonU32 (m_sequenceNumber); |
|
194 start.WriteHtonU32 (m_ackNumber); |
|
195 start.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero |
|
196 start.WriteHtonU16 (m_windowSize); |
|
197 //XXX calculate checksum here |
|
198 start.WriteHtonU16 (m_checksum); |
|
199 start.WriteHtonU16 (m_urgentPointer); |
|
200 } |
|
201 uint32_t TcpHeader::Deserialize (Buffer::Iterator start) |
|
202 { |
|
203 m_sourcePort = start.ReadNtohU16 (); |
|
204 m_destinationPort = start.ReadNtohU16 (); |
|
205 m_sequenceNumber = start.ReadNtohU32 (); |
|
206 m_ackNumber = start.ReadNtohU32 (); |
|
207 uint16_t field = start.ReadNtohU16 (); |
|
208 m_flags = field & 0x3F; |
|
209 m_length = field>>12; |
|
210 m_windowSize = start.ReadNtohU16 (); |
|
211 m_checksum = start.ReadNtohU16 (); |
|
212 m_urgentPointer = start.ReadNtohU16 (); |
|
213 return GetSerializedSize (); |
|
214 } |
|
215 |
|
216 |
|
217 }; // namespace ns3 |
|