A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
ipv4-header.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2005 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
*/
20
21
#include "ns3/assert.h"
22
#include "ns3/abort.h"
23
#include "ns3/log.h"
24
#include "ns3/header.h"
25
#include "
ipv4-header.h
"
26
27
NS_LOG_COMPONENT_DEFINE
(
"Ipv4Header"
);
28
29
namespace
ns3 {
30
31
NS_OBJECT_ENSURE_REGISTERED
(Ipv4Header);
32
33
Ipv4Header::Ipv4Header
()
34
: m_calcChecksum (false),
35
m_payloadSize (0),
36
m_identification (0),
37
m_tos (0),
38
m_ttl (0),
39
m_protocol (0),
40
m_flags (0),
41
m_fragmentOffset (0),
42
m_checksum (0),
43
m_goodChecksum (true),
44
m_headerSize(5*4)
45
{
46
}
47
48
void
49
Ipv4Header::EnableChecksum
(
void
)
50
{
51
NS_LOG_FUNCTION
(
this
);
52
m_calcChecksum
=
true
;
53
}
54
55
void
56
Ipv4Header::SetPayloadSize
(uint16_t size)
57
{
58
NS_LOG_FUNCTION
(
this
<< size);
59
m_payloadSize
= size;
60
}
61
uint16_t
62
Ipv4Header::GetPayloadSize
(
void
)
const
63
{
64
NS_LOG_FUNCTION
(
this
);
65
return
m_payloadSize
;
66
}
67
68
uint16_t
69
Ipv4Header::GetIdentification
(
void
)
const
70
{
71
NS_LOG_FUNCTION
(
this
);
72
return
m_identification
;
73
}
74
void
75
Ipv4Header::SetIdentification
(uint16_t identification)
76
{
77
NS_LOG_FUNCTION
(
this
<< identification);
78
m_identification
= identification;
79
}
80
81
void
82
Ipv4Header::SetTos
(uint8_t tos)
83
{
84
NS_LOG_FUNCTION
(
this
<< static_cast<uint32_t> (tos));
85
m_tos
= tos;
86
}
87
88
void
89
Ipv4Header::SetDscp
(
DscpType
dscp)
90
{
91
NS_LOG_FUNCTION
(
this
<< dscp);
92
m_tos
&= 0x3;
// Clear out the DSCP part, retain 2 bits of ECN
93
m_tos
|= dscp;
94
}
95
96
void
97
Ipv4Header::SetEcn
(
EcnType
ecn)
98
{
99
NS_LOG_FUNCTION
(
this
<< ecn);
100
m_tos
&= 0xFC;
// Clear out the ECN part, retain 6 bits of DSCP
101
m_tos
|= ecn;
102
}
103
104
Ipv4Header::DscpType
105
Ipv4Header::GetDscp
(
void
)
const
106
{
107
NS_LOG_FUNCTION
(
this
);
108
// Extract only first 6 bits of TOS byte, i.e 0xFC
109
return
DscpType
(
m_tos
& 0xFC);
110
}
111
112
std::string
113
Ipv4Header::DscpTypeToString
(
DscpType
dscp)
const
114
{
115
NS_LOG_FUNCTION
(
this
<< dscp);
116
switch
(dscp)
117
{
118
case
DscpDefault
:
119
return
"Default"
;
120
case
CS1
:
121
return
"CS1"
;
122
case
AF11
:
123
return
"AF11"
;
124
case
AF12
:
125
return
"AF12"
;
126
case
AF13
:
127
return
"AF13"
;
128
case
CS2
:
129
return
"CS2"
;
130
case
AF21
:
131
return
"AF21"
;
132
case
AF22
:
133
return
"AF22"
;
134
case
AF23
:
135
return
"AF23"
;
136
case
CS3
:
137
return
"CS3"
;
138
case
AF31
:
139
return
"AF31"
;
140
case
AF32
:
141
return
"AF32"
;
142
case
AF33
:
143
return
"AF33"
;
144
case
CS4
:
145
return
"CS4"
;
146
case
AF41
:
147
return
"AF41"
;
148
case
AF42
:
149
return
"AF42"
;
150
case
AF43
:
151
return
"AF43"
;
152
case
CS5
:
153
return
"CS5"
;
154
case
EF
:
155
return
"EF"
;
156
case
CS6
:
157
return
"CS6"
;
158
case
CS7
:
159
return
"CS7"
;
160
default
:
161
return
"Unrecognized DSCP"
;
162
};
163
}
164
165
166
Ipv4Header::EcnType
167
Ipv4Header::GetEcn
(
void
)
const
168
{
169
NS_LOG_FUNCTION
(
this
);
170
// Extract only last 2 bits of TOS byte, i.e 0x3
171
return
EcnType
(
m_tos
& 0x3);
172
}
173
174
std::string
175
Ipv4Header::EcnTypeToString
(
EcnType
ecn)
const
176
{
177
NS_LOG_FUNCTION
(
this
<< ecn);
178
switch
(ecn)
179
{
180
case
NotECT
:
181
return
"Not-ECT"
;
182
case
ECT1
:
183
return
"ECT (1)"
;
184
case
ECT0
:
185
return
"ECT (0)"
;
186
case
CE
:
187
return
"CE"
;
188
default
:
189
return
"Unknown ECN"
;
190
};
191
}
192
193
uint8_t
194
Ipv4Header::GetTos
(
void
)
const
195
{
196
NS_LOG_FUNCTION
(
this
);
197
return
m_tos
;
198
}
199
void
200
Ipv4Header::SetMoreFragments
(
void
)
201
{
202
NS_LOG_FUNCTION
(
this
);
203
m_flags
|=
MORE_FRAGMENTS
;
204
}
205
void
206
Ipv4Header::SetLastFragment
(
void
)
207
{
208
NS_LOG_FUNCTION
(
this
);
209
m_flags
&= ~
MORE_FRAGMENTS
;
210
}
211
bool
212
Ipv4Header::IsLastFragment
(
void
)
const
213
{
214
NS_LOG_FUNCTION
(
this
);
215
return
!(
m_flags
&
MORE_FRAGMENTS
);
216
}
217
218
void
219
Ipv4Header::SetDontFragment
(
void
)
220
{
221
NS_LOG_FUNCTION
(
this
);
222
m_flags
|=
DONT_FRAGMENT
;
223
}
224
void
225
Ipv4Header::SetMayFragment
(
void
)
226
{
227
NS_LOG_FUNCTION
(
this
);
228
m_flags
&= ~
DONT_FRAGMENT
;
229
}
230
bool
231
Ipv4Header::IsDontFragment
(
void
)
const
232
{
233
NS_LOG_FUNCTION
(
this
);
234
return
(
m_flags
&
DONT_FRAGMENT
);
235
}
236
237
void
238
Ipv4Header::SetFragmentOffset
(uint16_t offsetBytes)
239
{
240
NS_LOG_FUNCTION
(
this
<< offsetBytes);
241
// check if the user is trying to set an invalid offset
242
NS_ABORT_MSG_IF
((offsetBytes & 0x7),
"offsetBytes must be multiple of 8 bytes"
);
243
m_fragmentOffset
= offsetBytes;
244
}
245
uint16_t
246
Ipv4Header::GetFragmentOffset
(
void
)
const
247
{
248
NS_LOG_FUNCTION
(
this
);
249
if
((
m_fragmentOffset
+
m_payloadSize
+5*4) > 65535)
250
{
251
NS_LOG_WARN
(
"Fragment will exceed the maximum packet size once reassembled"
);
252
}
253
254
return
m_fragmentOffset
;
255
}
256
257
void
258
Ipv4Header::SetTtl
(uint8_t ttl)
259
{
260
NS_LOG_FUNCTION
(
this
<< static_cast<uint32_t> (ttl));
261
m_ttl
= ttl;
262
}
263
uint8_t
264
Ipv4Header::GetTtl
(
void
)
const
265
{
266
NS_LOG_FUNCTION
(
this
);
267
return
m_ttl
;
268
}
269
270
uint8_t
271
Ipv4Header::GetProtocol
(
void
)
const
272
{
273
NS_LOG_FUNCTION
(
this
);
274
return
m_protocol
;
275
}
276
void
277
Ipv4Header::SetProtocol
(uint8_t protocol)
278
{
279
NS_LOG_FUNCTION
(
this
<< static_cast<uint32_t> (protocol));
280
m_protocol
= protocol;
281
}
282
283
void
284
Ipv4Header::SetSource
(
Ipv4Address
source)
285
{
286
NS_LOG_FUNCTION
(
this
<< source);
287
m_source
= source;
288
}
289
Ipv4Address
290
Ipv4Header::GetSource
(
void
)
const
291
{
292
NS_LOG_FUNCTION
(
this
);
293
return
m_source
;
294
}
295
296
void
297
Ipv4Header::SetDestination
(
Ipv4Address
dst)
298
{
299
NS_LOG_FUNCTION
(
this
<< dst);
300
m_destination
= dst;
301
}
302
Ipv4Address
303
Ipv4Header::GetDestination
(
void
)
const
304
{
305
NS_LOG_FUNCTION
(
this
);
306
return
m_destination
;
307
}
308
309
310
bool
311
Ipv4Header::IsChecksumOk
(
void
)
const
312
{
313
NS_LOG_FUNCTION
(
this
);
314
return
m_goodChecksum
;
315
}
316
317
TypeId
318
Ipv4Header::GetTypeId
(
void
)
319
{
320
static
TypeId
tid =
TypeId
(
"ns3::Ipv4Header"
)
321
.
SetParent
<
Header
> ()
322
.AddConstructor<Ipv4Header> ()
323
;
324
return
tid;
325
}
326
TypeId
327
Ipv4Header::GetInstanceTypeId
(
void
)
const
328
{
329
NS_LOG_FUNCTION
(
this
);
330
return
GetTypeId
();
331
}
332
void
333
Ipv4Header::Print
(std::ostream &os)
const
334
{
335
NS_LOG_FUNCTION
(
this
<< &os);
336
// ipv4, right ?
337
std::string flags;
338
if
(
m_flags
== 0)
339
{
340
flags =
"none"
;
341
}
342
else
if
(
m_flags
&
MORE_FRAGMENTS
&&
343
m_flags
&
DONT_FRAGMENT
)
344
{
345
flags =
"MF|DF"
;
346
}
347
else
if
(
m_flags
& DONT_FRAGMENT)
348
{
349
flags =
"DF"
;
350
}
351
else
if
(
m_flags
&
MORE_FRAGMENTS
)
352
{
353
flags =
"MF"
;
354
}
355
else
356
{
357
flags =
"XX"
;
358
}
359
os <<
"tos 0x"
<< std::hex <<
m_tos
<< std::dec <<
" "
360
<<
"DSCP "
<<
DscpTypeToString
(
GetDscp
()) <<
" "
361
<<
"ECN "
<<
EcnTypeToString
(
GetEcn
()) <<
" "
362
<<
"ttl "
<<
m_ttl
<<
" "
363
<<
"id "
<<
m_identification
<<
" "
364
<<
"protocol "
<<
m_protocol
<<
" "
365
<<
"offset (bytes) "
<<
m_fragmentOffset
<<
" "
366
<<
"flags ["
<< flags <<
"] "
367
<<
"length: "
<< (
m_payloadSize
+ 5 * 4)
368
<<
" "
369
<<
m_source
<<
" > "
<<
m_destination
370
;
371
}
372
uint32_t
373
Ipv4Header::GetSerializedSize
(
void
)
const
374
{
375
NS_LOG_FUNCTION
(
this
);
376
//return 5 * 4;
377
return
m_headerSize
;
378
}
379
380
void
381
Ipv4Header::Serialize
(
Buffer::Iterator
start
)
const
382
{
383
NS_LOG_FUNCTION
(
this
<< &start);
384
Buffer::Iterator
i =
start
;
385
386
uint8_t verIhl = (4 << 4) | (5);
387
i.
WriteU8
(verIhl);
388
i.
WriteU8
(
m_tos
);
389
i.
WriteHtonU16
(
m_payloadSize
+ 5*4);
390
i.
WriteHtonU16
(
m_identification
);
391
uint32_t fragmentOffset =
m_fragmentOffset
/ 8;
392
uint8_t flagsFrag = (fragmentOffset >> 8) & 0x1f;
393
if
(
m_flags
&
DONT_FRAGMENT
)
394
{
395
flagsFrag |= (1<<6);
396
}
397
if
(
m_flags
&
MORE_FRAGMENTS
)
398
{
399
flagsFrag |= (1<<5);
400
}
401
i.
WriteU8
(flagsFrag);
402
uint8_t frag = fragmentOffset & 0xff;
403
i.
WriteU8
(frag);
404
i.
WriteU8
(
m_ttl
);
405
i.
WriteU8
(
m_protocol
);
406
i.
WriteHtonU16
(0);
407
i.
WriteHtonU32
(
m_source
.
Get
());
408
i.
WriteHtonU32
(
m_destination
.
Get
());
409
410
if
(
m_calcChecksum
)
411
{
412
i =
start
;
413
uint16_t checksum = i.
CalculateIpChecksum
(20);
414
NS_LOG_LOGIC
(
"checksum="
<<checksum);
415
i =
start
;
416
i.
Next
(10);
417
i.
WriteU16
(checksum);
418
}
419
}
420
uint32_t
421
Ipv4Header::Deserialize
(
Buffer::Iterator
start
)
422
{
423
NS_LOG_FUNCTION
(
this
<< &start);
424
Buffer::Iterator
i =
start
;
425
uint8_t verIhl = i.
ReadU8
();
426
uint8_t ihl = verIhl & 0x0f;
427
uint16_t headerSize = ihl * 4;
428
NS_ASSERT
((verIhl >> 4) == 4);
429
m_tos
= i.
ReadU8
();
430
uint16_t size = i.
ReadNtohU16
();
431
m_payloadSize
= size - headerSize;
432
m_identification
= i.
ReadNtohU16
();
433
uint8_t flags = i.
ReadU8
();
434
m_flags
= 0;
435
if
(flags & (1<<6))
436
{
437
m_flags
|=
DONT_FRAGMENT
;
438
}
439
if
(flags & (1<<5))
440
{
441
m_flags
|=
MORE_FRAGMENTS
;
442
}
443
i.
Prev
();
444
m_fragmentOffset
= i.
ReadU8
() & 0x1f;
445
m_fragmentOffset
<<= 8;
446
m_fragmentOffset
|= i.
ReadU8
();
447
m_fragmentOffset
<<= 3;
448
m_ttl
= i.
ReadU8
();
449
m_protocol
= i.
ReadU8
();
450
m_checksum
= i.
ReadU16
();
451
/* i.Next (2); // checksum */
452
m_source
.
Set
(i.
ReadNtohU32
());
453
m_destination
.
Set
(i.
ReadNtohU32
());
454
m_headerSize
= headerSize;
455
456
if
(
m_calcChecksum
)
457
{
458
i =
start
;
459
uint16_t checksum = i.
CalculateIpChecksum
(headerSize);
460
NS_LOG_LOGIC
(
"checksum="
<<checksum);
461
462
m_goodChecksum
= (checksum == 0);
463
}
464
return
GetSerializedSize
();
465
}
466
467
}
// namespace ns3
src
internet
model
ipv4-header.cc
Generated on Tue May 14 2013 11:08:22 for ns-3 by
1.8.1.2