A Discrete-Event Network Simulator
API
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
27namespace ns3 {
28
29NS_LOG_COMPONENT_DEFINE ("Ipv4Header");
30
32
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
48void
50{
51 NS_LOG_FUNCTION (this);
52 m_calcChecksum = true;
53}
54
55void
57{
58 NS_LOG_FUNCTION (this << size);
59 m_payloadSize = size;
60}
61uint16_t
63{
64 NS_LOG_FUNCTION (this);
65 return m_payloadSize;
66}
67
68uint16_t
70{
71 NS_LOG_FUNCTION (this);
72 return m_identification;
73}
74void
75Ipv4Header::SetIdentification (uint16_t identification)
76{
77 NS_LOG_FUNCTION (this << identification);
78 m_identification = identification;
79}
80
81void
82Ipv4Header::SetTos (uint8_t tos)
83{
84 NS_LOG_FUNCTION (this << static_cast<uint32_t> (tos));
85 m_tos = tos;
86}
87
88void
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 << 2);
94}
95
96void
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
106{
107 NS_LOG_FUNCTION (this);
108 // Extract only first 6 bits of TOS byte, i.e 0xFC
109 return DscpType ((m_tos & 0xFC) >> 2);
110}
111
112std::string
114{
115 NS_LOG_FUNCTION (this << dscp);
116 switch (dscp)
117 {
118 case DscpDefault:
119 return "Default";
120 case DSCP_CS1:
121 return "CS1";
122 case DSCP_AF11:
123 return "AF11";
124 case DSCP_AF12:
125 return "AF12";
126 case DSCP_AF13:
127 return "AF13";
128 case DSCP_CS2:
129 return "CS2";
130 case DSCP_AF21:
131 return "AF21";
132 case DSCP_AF22:
133 return "AF22";
134 case DSCP_AF23:
135 return "AF23";
136 case DSCP_CS3:
137 return "CS3";
138 case DSCP_AF31:
139 return "AF31";
140 case DSCP_AF32:
141 return "AF32";
142 case DSCP_AF33:
143 return "AF33";
144 case DSCP_CS4:
145 return "CS4";
146 case DSCP_AF41:
147 return "AF41";
148 case DSCP_AF42:
149 return "AF42";
150 case DSCP_AF43:
151 return "AF43";
152 case DSCP_CS5:
153 return "CS5";
154 case DSCP_EF:
155 return "EF";
156 case DSCP_CS6:
157 return "CS6";
158 case DSCP_CS7:
159 return "CS7";
160 default:
161 return "Unrecognized DSCP";
162 };
163}
164
165
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
174std::string
176{
177 NS_LOG_FUNCTION (this << ecn);
178 switch (ecn)
179 {
180 case ECN_NotECT:
181 return "Not-ECT";
182 case ECN_ECT1:
183 return "ECT (1)";
184 case ECN_ECT0:
185 return "ECT (0)";
186 case ECN_CE:
187 return "CE";
188 default:
189 return "Unknown ECN";
190 };
191}
192
193uint8_t
195{
196 NS_LOG_FUNCTION (this);
197 return m_tos;
198}
199void
201{
202 NS_LOG_FUNCTION (this);
204}
205void
207{
208 NS_LOG_FUNCTION (this);
209 m_flags &= ~MORE_FRAGMENTS;
210}
211bool
213{
214 NS_LOG_FUNCTION (this);
215 return !(m_flags & MORE_FRAGMENTS);
216}
217
218void
220{
221 NS_LOG_FUNCTION (this);
223}
224void
226{
227 NS_LOG_FUNCTION (this);
228 m_flags &= ~DONT_FRAGMENT;
229}
230bool
232{
233 NS_LOG_FUNCTION (this);
234 return (m_flags & DONT_FRAGMENT);
235}
236
237void
238Ipv4Header::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}
245uint16_t
247{
248 NS_LOG_FUNCTION (this);
249 // -fstrict-overflow sensitive, see bug 1868
250 if ( m_fragmentOffset + m_payloadSize > 65535 - 5*4 )
251 {
252 NS_LOG_WARN("Fragment will exceed the maximum packet size once reassembled");
253 }
254
255 return m_fragmentOffset;
256}
257
258void
260{
261 NS_LOG_FUNCTION (this << static_cast<uint32_t> (ttl));
262 m_ttl = ttl;
263}
264uint8_t
266{
267 NS_LOG_FUNCTION (this);
268 return m_ttl;
269}
270
271uint8_t
273{
274 NS_LOG_FUNCTION (this);
275 return m_protocol;
276}
277void
278Ipv4Header::SetProtocol (uint8_t protocol)
279{
280 NS_LOG_FUNCTION (this << static_cast<uint32_t> (protocol));
281 m_protocol = protocol;
282}
283
284void
286{
287 NS_LOG_FUNCTION (this << source);
288 m_source = source;
289}
292{
293 NS_LOG_FUNCTION (this);
294 return m_source;
295}
296
297void
299{
300 NS_LOG_FUNCTION (this << dst);
301 m_destination = dst;
302}
305{
306 NS_LOG_FUNCTION (this);
307 return m_destination;
308}
309
310
311bool
313{
314 NS_LOG_FUNCTION (this);
315 return m_goodChecksum;
316}
317
318TypeId
320{
321 static TypeId tid = TypeId ("ns3::Ipv4Header")
322 .SetParent<Header> ()
323 .SetGroupName ("Internet")
324 .AddConstructor<Ipv4Header> ()
325 ;
326 return tid;
327}
328TypeId
330{
331 NS_LOG_FUNCTION (this);
332 return GetTypeId ();
333}
334void
335Ipv4Header::Print (std::ostream &os) const
336{
337 NS_LOG_FUNCTION (this << &os);
338 // ipv4, right ?
339 std::string flags;
340 if (m_flags == 0)
341 {
342 flags = "none";
343 }
344 else if ((m_flags & MORE_FRAGMENTS) &&
346 {
347 flags = "MF|DF";
348 }
349 else if (m_flags & DONT_FRAGMENT)
350 {
351 flags = "DF";
352 }
353 else if (m_flags & MORE_FRAGMENTS)
354 {
355 flags = "MF";
356 }
357 else
358 {
359 flags = "XX";
360 }
361 os << "tos 0x" << std::hex << m_tos << std::dec << " "
362 << "DSCP " << DscpTypeToString (GetDscp ()) << " "
363 << "ECN " << EcnTypeToString (GetEcn ()) << " "
364 << "ttl " << m_ttl << " "
365 << "id " << m_identification << " "
366 << "protocol " << m_protocol << " "
367 << "offset (bytes) " << m_fragmentOffset << " "
368 << "flags [" << flags << "] "
369 << "length: " << (m_payloadSize + 5 * 4)
370 << " "
371 << m_source << " > " << m_destination
372 ;
373}
376{
377 NS_LOG_FUNCTION (this);
378 //return 5 * 4;
379 return m_headerSize;
380}
381
382void
384{
385 NS_LOG_FUNCTION (this << &start);
387
388 uint8_t verIhl = (4 << 4) | (5);
389 i.WriteU8 (verIhl);
390 i.WriteU8 (m_tos);
391 i.WriteHtonU16 (m_payloadSize + 5*4);
393 uint32_t fragmentOffset = m_fragmentOffset / 8;
394 uint8_t flagsFrag = (fragmentOffset >> 8) & 0x1f;
395 if (m_flags & DONT_FRAGMENT)
396 {
397 flagsFrag |= (1<<6);
398 }
399 if (m_flags & MORE_FRAGMENTS)
400 {
401 flagsFrag |= (1<<5);
402 }
403 i.WriteU8 (flagsFrag);
404 uint8_t frag = fragmentOffset & 0xff;
405 i.WriteU8 (frag);
406 i.WriteU8 (m_ttl);
408 i.WriteHtonU16 (0);
411
412 if (m_calcChecksum)
413 {
414 i = start;
415 uint16_t checksum = i.CalculateIpChecksum (20);
416 NS_LOG_LOGIC ("checksum=" <<checksum);
417 i = start;
418 i.Next (10);
419 i.WriteU16 (checksum);
420 }
421}
424{
425 NS_LOG_FUNCTION (this << &start);
427
428 uint8_t verIhl = i.ReadU8 ();
429 uint8_t ihl = verIhl & 0x0f;
430 uint16_t headerSize = ihl * 4;
431
432 if ((verIhl >> 4) != 4)
433 {
434 NS_LOG_WARN ("Trying to decode a non-IPv4 header, refusing to do it.");
435 return 0;
436 }
437
438 m_tos = i.ReadU8 ();
439 uint16_t size = i.ReadNtohU16 ();
440 m_payloadSize = size - headerSize;
442 uint8_t flags = i.ReadU8 ();
443 m_flags = 0;
444 if (flags & (1<<6))
445 {
447 }
448 if (flags & (1<<5))
449 {
451 }
452 i.Prev ();
453 m_fragmentOffset = i.ReadU8 () & 0x1f;
454 m_fragmentOffset <<= 8;
455 m_fragmentOffset |= i.ReadU8 ();
456 m_fragmentOffset <<= 3;
457 m_ttl = i.ReadU8 ();
458 m_protocol = i.ReadU8 ();
459 m_checksum = i.ReadU16 ();
460 /* i.Next (2); // checksum */
461 m_source.Set (i.ReadNtohU32 ());
463 m_headerSize = headerSize;
464
465 if (m_calcChecksum)
466 {
467 i = start;
468 uint16_t checksum = i.CalculateIpChecksum (headerSize);
469 NS_LOG_LOGIC ("checksum=" <<checksum);
470
471 m_goodChecksum = (checksum == 0);
472 }
473 return GetSerializedSize ();
474}
475
476} // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:99
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1134
void WriteU8(uint8_t data)
Definition: buffer.h:869
void Next(void)
go forward by one byte
Definition: buffer.h:845
void WriteU16(uint16_t data)
Definition: buffer.cc:871
uint16_t ReadU16(void)
Definition: buffer.h:1029
uint8_t ReadU8(void)
Definition: buffer.h:1021
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
void Prev(void)
go backward by one byte
Definition: buffer.h:851
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
Protocol header serialization and deserialization.
Definition: header.h:43
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
uint32_t Get(void) const
Get the host-order 32-bit IP address.
void Set(uint32_t address)
input address is in host order.
Packet header for IPv4.
Definition: ipv4-header.h:34
DscpType GetDscp(void) const
Definition: ipv4-header.cc:105
void SetMoreFragments(void)
This packet is not the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:200
Ipv4Address m_source
source address
Definition: ipv4-header.h:258
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
static TypeId GetTypeId(void)
Get the type ID.
Definition: ipv4-header.cc:319
uint16_t m_fragmentOffset
Fragment offset.
Definition: ipv4-header.h:257
std::string EcnTypeToString(EcnType ecn) const
Definition: ipv4-header.cc:175
void SetLastFragment(void)
This packet is the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:206
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:375
uint32_t m_ttl
TTL.
Definition: ipv4-header.h:254
uint32_t m_protocol
Protocol.
Definition: ipv4-header.h:255
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
virtual void Print(std::ostream &os) const
Definition: ipv4-header.cc:335
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: ipv4-header.cc:423
uint16_t m_identification
identification
Definition: ipv4-header.h:252
uint16_t GetIdentification(void) const
Definition: ipv4-header.cc:69
uint16_t GetFragmentOffset(void) const
Definition: ipv4-header.cc:246
uint8_t GetTos(void) const
Definition: ipv4-header.cc:194
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
uint16_t m_payloadSize
payload size
Definition: ipv4-header.h:251
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:259
bool IsDontFragment(void) const
Definition: ipv4-header.cc:231
uint32_t m_tos
TOS, also used as DSCP + ECN value.
Definition: ipv4-header.h:253
bool m_goodChecksum
true if checksum is correct
Definition: ipv4-header.h:261
void SetMayFragment(void)
If you need to fragment this packet, you can do it.
Definition: ipv4-header.cc:225
void SetDscp(DscpType dscp)
Set DSCP Field.
Definition: ipv4-header.cc:89
void SetDontFragment(void)
Don't fragment this packet: if you need to anyway, drop it.
Definition: ipv4-header.cc:219
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
Ipv4Address m_destination
destination address
Definition: ipv4-header.h:259
EcnType GetEcn(void) const
Definition: ipv4-header.cc:167
void EnableChecksum(void)
Enable checksum calculation for this header.
Definition: ipv4-header.cc:49
EcnType
ECN Type defined in RFC 3168
Definition: ipv4-header.h:113
uint16_t m_checksum
checksum
Definition: ipv4-header.h:260
uint16_t m_headerSize
IP header size.
Definition: ipv4-header.h:262
void SetEcn(EcnType ecn)
Set ECN Field.
Definition: ipv4-header.cc:97
DscpType
DiffServ codepoints.
Definition: ipv4-header.h:71
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
std::string DscpTypeToString(DscpType dscp) const
Definition: ipv4-header.cc:113
uint32_t m_flags
flags
Definition: ipv4-header.h:256
uint16_t GetPayloadSize(void) const
Definition: ipv4-header.cc:62
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetFragmentOffset(uint16_t offsetBytes)
The offset is measured in bytes for the packet start.
Definition: ipv4-header.cc:238
void SetIdentification(uint16_t identification)
Definition: ipv4-header.cc:75
bool IsChecksumOk(void) const
Definition: ipv4-header.cc:312
bool IsLastFragment(void) const
Definition: ipv4-header.cc:212
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: ipv4-header.cc:329
virtual void Serialize(Buffer::Iterator start) const
Definition: ipv4-header.cc:383
void SetTos(uint8_t tos)
Definition: ipv4-header.cc:82
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
Ipv4Header()
Construct a null IPv4 header.
Definition: ipv4-header.cc:33
bool m_calcChecksum
true if the checksum must be calculated
Definition: ipv4-header.h:249
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
def start()
Definition: core.py:1853