Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2007 Georgia Tech Research Corporation | 3 * Copyright (c) 2007 Georgia Tech Research Corporation |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 TcpHeader::~TcpHeader () | 45 TcpHeader::~TcpHeader () |
46 { | 46 { |
47 } | 47 } |
48 | 48 |
49 void | 49 void |
50 TcpHeader::EnableChecksums (void) | 50 TcpHeader::EnableChecksums (void) |
51 { | 51 { |
52 m_calcChecksum = true; | 52 m_calcChecksum = true; |
53 } | 53 } |
54 | 54 |
55 void TcpHeader::SetSourcePort (uint16_t port) | 55 void |
56 TcpHeader::SetSourcePort (uint16_t port) | |
56 { | 57 { |
57 m_sourcePort = port; | 58 m_sourcePort = port; |
58 } | 59 } |
59 void TcpHeader::SetDestinationPort (uint16_t port) | 60 |
61 void | |
62 TcpHeader::SetDestinationPort (uint16_t port) | |
60 { | 63 { |
61 m_destinationPort = port; | 64 m_destinationPort = port; |
62 } | 65 } |
63 void TcpHeader::SetSequenceNumber (SequenceNumber32 sequenceNumber) | 66 |
67 void | |
68 TcpHeader::SetSequenceNumber (SequenceNumber32 sequenceNumber) | |
64 { | 69 { |
65 m_sequenceNumber = sequenceNumber; | 70 m_sequenceNumber = sequenceNumber; |
66 } | 71 } |
67 void TcpHeader::SetAckNumber (SequenceNumber32 ackNumber) | 72 |
73 void | |
74 TcpHeader::SetAckNumber (SequenceNumber32 ackNumber) | |
68 { | 75 { |
69 m_ackNumber = ackNumber; | 76 m_ackNumber = ackNumber; |
70 } | 77 } |
71 void TcpHeader::SetLength (uint8_t length) | 78 |
79 void | |
80 TcpHeader::SetLength (uint8_t length) | |
Tommaso Pecorella
2014/08/17 10:38:12
1) Declare it obsolete.
2) Make it a no-op
3) Thro
Tom Henderson
2014/08/26 16:52:29
I agree to remove this.
| |
72 { | 81 { |
73 m_length = length; | 82 m_length = length; |
74 } | 83 } |
75 void TcpHeader::SetFlags (uint8_t flags) | 84 |
85 void | |
86 TcpHeader::SetFlags (uint8_t flags) | |
76 { | 87 { |
77 m_flags = flags; | 88 m_flags = flags; |
78 } | 89 } |
79 void TcpHeader::SetWindowSize (uint16_t windowSize) | 90 |
91 void | |
92 TcpHeader::SetWindowSize (uint16_t windowSize) | |
80 { | 93 { |
81 m_windowSize = windowSize; | 94 m_windowSize = windowSize; |
82 } | 95 } |
83 void TcpHeader::SetUrgentPointer (uint16_t urgentPointer) | 96 |
97 void | |
98 TcpHeader::SetUrgentPointer (uint16_t urgentPointer) | |
84 { | 99 { |
85 m_urgentPointer = urgentPointer; | 100 m_urgentPointer = urgentPointer; |
86 } | 101 } |
87 | 102 |
88 uint16_t TcpHeader::GetSourcePort () const | 103 uint16_t |
104 TcpHeader::GetSourcePort () const | |
89 { | 105 { |
90 return m_sourcePort; | 106 return m_sourcePort; |
91 } | 107 } |
92 uint16_t TcpHeader::GetDestinationPort () const | 108 |
109 uint16_t | |
110 TcpHeader::GetDestinationPort () const | |
93 { | 111 { |
94 return m_destinationPort; | 112 return m_destinationPort; |
95 } | 113 } |
96 SequenceNumber32 TcpHeader::GetSequenceNumber () const | 114 |
115 SequenceNumber32 | |
116 TcpHeader::GetSequenceNumber () const | |
97 { | 117 { |
98 return m_sequenceNumber; | 118 return m_sequenceNumber; |
99 } | 119 } |
100 SequenceNumber32 TcpHeader::GetAckNumber () const | 120 |
121 SequenceNumber32 | |
122 TcpHeader::GetAckNumber () const | |
101 { | 123 { |
102 return m_ackNumber; | 124 return m_ackNumber; |
103 } | 125 } |
104 uint8_t TcpHeader::GetLength () const | 126 |
127 uint8_t | |
128 TcpHeader::GetLength () const | |
105 { | 129 { |
106 return m_length; | 130 return m_length; |
107 } | 131 } |
108 uint8_t TcpHeader::GetFlags () const | 132 |
133 uint8_t | |
134 TcpHeader::GetFlags () const | |
109 { | 135 { |
110 return m_flags; | 136 return m_flags; |
111 } | 137 } |
112 uint16_t TcpHeader::GetWindowSize () const | 138 |
139 uint16_t | |
140 TcpHeader::GetWindowSize () const | |
113 { | 141 { |
114 return m_windowSize; | 142 return m_windowSize; |
115 } | 143 } |
116 uint16_t TcpHeader::GetUrgentPointer () const | 144 |
145 uint16_t | |
146 TcpHeader::GetUrgentPointer () const | |
117 { | 147 { |
118 return m_urgentPointer; | 148 return m_urgentPointer; |
119 } | 149 } |
120 | 150 |
121 void· | 151 void· |
122 TcpHeader::InitializeChecksum (Ipv4Address source,· | 152 TcpHeader::InitializeChecksum (Ipv4Address source,· |
123 Ipv4Address destination, | 153 Ipv4Address destination, |
124 uint8_t protocol) | 154 uint8_t protocol) |
125 { | 155 { |
126 m_source = source; | 156 m_source = source; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 | 229 |
200 TypeId· | 230 TypeId· |
201 TcpHeader::GetTypeId (void) | 231 TcpHeader::GetTypeId (void) |
202 { | 232 { |
203 static TypeId tid = TypeId ("ns3::TcpHeader") | 233 static TypeId tid = TypeId ("ns3::TcpHeader") |
204 .SetParent<Header> () | 234 .SetParent<Header> () |
205 .AddConstructor<TcpHeader> () | 235 .AddConstructor<TcpHeader> () |
206 ; | 236 ; |
207 return tid; | 237 return tid; |
208 } | 238 } |
239 | |
209 TypeId· | 240 TypeId· |
210 TcpHeader::GetInstanceTypeId (void) const | 241 TcpHeader::GetInstanceTypeId (void) const |
211 { | 242 { |
212 return GetTypeId (); | 243 return GetTypeId (); |
213 } | 244 } |
214 void TcpHeader::Print (std::ostream &os) const | 245 |
246 void | |
247 TcpHeader::Print (std::ostream &os) const | |
215 { | 248 { |
216 os << m_sourcePort << " > " << m_destinationPort; | 249 os << m_sourcePort << " > " << m_destinationPort; |
217 if(m_flags!=0) | 250 |
251 if (m_flags != 0) | |
218 { | 252 { |
219 os<<" ["; | 253 os<<" ["; |
220 if((m_flags & FIN) != 0) | 254 if ((m_flags & FIN) != 0) |
221 { | 255 { |
222 os<<" FIN "; | 256 os<<" FIN "; |
223 } | 257 } |
224 if((m_flags & SYN) != 0) | 258 if ((m_flags & SYN) != 0) |
225 { | 259 { |
226 os<<" SYN "; | 260 os<<" SYN "; |
227 } | 261 } |
228 if((m_flags & RST) != 0) | 262 if ((m_flags & RST) != 0) |
229 { | 263 { |
230 os<<" RST "; | 264 os<<" RST "; |
231 } | 265 } |
232 if((m_flags & PSH) != 0) | 266 if ((m_flags & PSH) != 0) |
233 { | 267 { |
234 os<<" PSH "; | 268 os<<" PSH "; |
235 } | 269 } |
236 if((m_flags & ACK) != 0) | 270 if ((m_flags & ACK) != 0) |
237 { | 271 { |
238 os<<" ACK "; | 272 os<<" ACK "; |
239 } | 273 } |
240 if((m_flags & URG) != 0) | 274 if ((m_flags & URG) != 0) |
241 { | 275 { |
242 os<<" URG "; | 276 os<<" URG "; |
243 } | 277 } |
244 if((m_flags & ECE) != 0) | 278 if ((m_flags & ECE) != 0) |
245 { | 279 { |
246 os<<" ECE "; | 280 os<<" ECE "; |
247 } | 281 } |
248 if((m_flags & CWR) != 0) | 282 if ((m_flags & CWR) != 0) |
Tom Henderson
2014/08/26 16:52:29
whitespace changes should be outside of the option
| |
249 { | 283 { |
250 os<<" CWR "; | 284 os<<" CWR "; |
251 } | 285 } |
286 | |
252 os<<"]"; | 287 os<<"]"; |
253 } | 288 } |
289 | |
254 os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize; | 290 os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize; |
291 | |
292 TcpOptionList::const_iterator op; | |
293 | |
294 for (op = m_options.begin (); op != m_options.end (); ++op) | |
295 { | |
296 os << " " << (*op)->GetInstanceTypeId ().GetName () << "("; | |
297 (*op)->Print (os); | |
298 os << ")"; | |
299 } | |
255 } | 300 } |
256 uint32_t TcpHeader::GetSerializedSize (void) const | 301 |
302 uint32_t | |
303 TcpHeader::GetSerializedSize (void) const | |
257 { | 304 { |
258 return 4*m_length; | 305 return 4*GetLength (); |
259 } | 306 } |
260 void TcpHeader::Serialize (Buffer::Iterator start) const | 307 |
308 void | |
309 TcpHeader::Serialize (Buffer::Iterator start) const | |
261 { | 310 { |
262 Buffer::Iterator i = start; | 311 Buffer::Iterator i = start; |
263 i.WriteHtonU16 (m_sourcePort); | 312 i.WriteHtonU16 (m_sourcePort); |
264 i.WriteHtonU16 (m_destinationPort); | 313 i.WriteHtonU16 (m_destinationPort); |
265 i.WriteHtonU32 (m_sequenceNumber.GetValue ()); | 314 i.WriteHtonU32 (m_sequenceNumber.GetValue ()); |
266 i.WriteHtonU32 (m_ackNumber.GetValue ()); | 315 i.WriteHtonU32 (m_ackNumber.GetValue ()); |
267 i.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero | 316 i.WriteHtonU16 (GetLength () << 12 | m_flags); //reserved bits are all zero |
268 i.WriteHtonU16 (m_windowSize); | 317 i.WriteHtonU16 (m_windowSize); |
269 i.WriteHtonU16 (0); | 318 i.WriteHtonU16 (0); |
270 i.WriteHtonU16 (m_urgentPointer); | 319 i.WriteHtonU16 (m_urgentPointer); |
271 | 320 |
321 // Serialize options if they exists | |
322 unsigned optionLen = 0; | |
323 TcpOptionList::const_iterator op; | |
324 for (op = m_options.begin (); op != m_options.end (); ++op) | |
325 { | |
326 optionLen += (*op)->GetSerializedSize (); | |
327 (*op)->Serialize(i); | |
328 i.Next ((*op)->GetSerializedSize ()); | |
329 } | |
330 | |
trucanh524
2014/08/07 10:35:14
A think a 1-line comment here (for example, // Pad
Tom Henderson
2014/08/26 16:52:29
Some implementations pad options to word boundarie
| |
331 while (optionLen % 4) | |
332 { | |
333 ++optionLen; | |
334 i.WriteU8 (0); | |
335 } | |
336 | |
337 // Make checksum | |
272 if(m_calcChecksum) | 338 if(m_calcChecksum) |
273 { | 339 { |
274 uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); | 340 uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); |
275 i = start; | 341 i = start; |
276 uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksu m); | 342 uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksu m); |
277 | 343 |
278 i = start; | 344 i = start; |
279 i.Next (16); | 345 i.Next (16); |
280 i.WriteU16 (checksum); | 346 i.WriteU16 (checksum); |
281 } | 347 } |
282 } | 348 } |
283 uint32_t TcpHeader::Deserialize (Buffer::Iterator start) | 349 |
350 uint32_t | |
351 TcpHeader::Deserialize (Buffer::Iterator start) | |
284 { | 352 { |
285 Buffer::Iterator i = start; | 353 Buffer::Iterator i = start; |
286 m_sourcePort = i.ReadNtohU16 (); | 354 m_sourcePort = i.ReadNtohU16 (); |
287 m_destinationPort = i.ReadNtohU16 (); | 355 m_destinationPort = i.ReadNtohU16 (); |
288 m_sequenceNumber = i.ReadNtohU32 (); | 356 m_sequenceNumber = i.ReadNtohU32 (); |
289 m_ackNumber = i.ReadNtohU32 (); | 357 m_ackNumber = i.ReadNtohU32 (); |
290 uint16_t field = i.ReadNtohU16 (); | 358 uint16_t field = i.ReadNtohU16 (); |
291 m_flags = field & 0x3F; | 359 m_flags = field & 0x3F; |
292 m_length = field>>12; | 360 m_length = field>>12; |
293 m_windowSize = i.ReadNtohU16 (); | 361 m_windowSize = i.ReadNtohU16 (); |
294 i.Next (2); | 362 i.Next (2); |
295 m_urgentPointer = i.ReadNtohU16 (); | 363 m_urgentPointer = i.ReadNtohU16 (); |
296 | 364 |
365 // Deserialize options if they exist | |
366 m_options.clear (); | |
367 unsigned optionLen = (m_length - 5) * 4; | |
Tommaso Pecorella
2014/08/17 10:38:12
unsigned ?!?!?!
| |
368 while (optionLen) | |
369 { | |
370 uint8_t kind = i.ReadU8 (); | |
371 Ptr<TcpOption> op = TcpOption::CreateOption (kind); | |
Tommaso Pecorella
2014/08/17 10:38:12
This could return null, a check is mandatory.
Alt
n.p
2014/08/23 10:30:36
All things done in Deserialize are assumed to be "
Tommaso Pecorella
2014/08/25 14:40:15
Thanks to the TCP Options structure (i.e., 2 optio
Tom Henderson
2014/08/26 16:52:29
If kind is unknown, need to peek the length and de
| |
372 | |
373 optionLen -= op->Deserialize (i); | |
374 i.Next (op->GetSerializedSize () - 1); | |
375 | |
376 if (op->GetKind () != 0) | |
377 { | |
378 m_options.push_back (op); | |
379 } | |
380 else | |
381 { | |
382 while(optionLen) | |
383 { | |
384 i.Next (1); | |
385 --optionLen; | |
386 } | |
Tommaso Pecorella
2014/08/17 10:38:12
I think we're going to far ahead with the buffer,
n.p
2014/08/23 10:30:36
Where?
Tommaso Pecorella
2014/08/25 14:40:15
Maybe not, but I feel the code counterintuitive.
| |
387 } | |
388 } | |
389 | |
390 // Do checksum | |
297 if(m_calcChecksum) | 391 if(m_calcChecksum) |
298 { | 392 { |
299 uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); | 393 uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ()); |
300 i = start; | 394 i = start; |
301 uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksu m); | 395 uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksu m); |
302 m_goodChecksum = (checksum == 0); | 396 m_goodChecksum = (checksum == 0); |
303 } | 397 } |
304 | 398 |
305 return GetSerializedSize (); | 399 return GetSerializedSize (); |
306 } | 400 } |
307 | 401 |
402 void | |
403 TcpHeader::AppendOption (Ptr<TcpOption> option) | |
404 { | |
405 if (option->GetKind () != 0) | |
406 { | |
407 m_options.push_back (option); | |
408 } | |
409 | |
410 // Update length | |
411 unsigned totalLen = 20; | |
412 for (TcpOptionList::iterator i = m_options.begin (); i != m_options.end (); ++ i) | |
413 { | |
414 totalLen += (*i)->GetSerializedSize (); | |
415 } | |
416 | |
trucanh524
2014/08/07 10:35:14
I remember the maximum option length allowed for e
Tommaso Pecorella
2014/08/17 10:38:12
Indeed, we must.
On 2014/08/07 10:35:14, trucanh5
| |
417 if (totalLen > 20) | |
418 { | |
419 totalLen += 3; | |
420 } | |
421 | |
422 m_length = totalLen >> 2; | |
423 } | |
424 | |
425 Ptr<TcpOption> | |
426 TcpHeader::GetOption (uint8_t kind) const | |
427 { | |
428 TcpOptionList::const_iterator i; | |
429 | |
430 for (i = m_options.begin (); i != m_options.end () ; ++i) | |
431 { | |
432 if ((*i)->GetKind () == kind) | |
433 { | |
434 return (*i); | |
435 } | |
436 } | |
437 | |
438 return 0; | |
439 } | |
440 | |
441 bool | |
442 TcpHeader::HasOption (uint8_t kind) const | |
443 { | |
444 TcpOptionList::const_iterator i; | |
445 | |
446 for (i = m_options.begin (); i != m_options.end () ; ++i) | |
447 { | |
448 if ((*i)->GetKind () == kind) | |
449 { | |
450 return true; | |
451 } | |
452 } | |
453 | |
454 return false; | |
455 } | |
308 | 456 |
309 } // namespace ns3 | 457 } // namespace ns3 |
OLD | NEW |