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