A Discrete-Event Network Simulator
API
 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 
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
50 {
51  NS_LOG_FUNCTION (this);
52  m_calcChecksum = true;
53 }
54 
55 void
57 {
58  NS_LOG_FUNCTION (this << size);
59  m_payloadSize = size;
60 }
61 uint16_t
63 {
64  NS_LOG_FUNCTION (this);
65  return m_payloadSize;
66 }
67 
68 uint16_t
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
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
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);
110 }
111 
112 std::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 
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
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 
193 uint8_t
194 Ipv4Header::GetTos (void) const
195 {
196  NS_LOG_FUNCTION (this);
197  return m_tos;
198 }
199 void
201 {
202  NS_LOG_FUNCTION (this);
204 }
205 void
207 {
208  NS_LOG_FUNCTION (this);
210 }
211 bool
213 {
214  NS_LOG_FUNCTION (this);
215  return !(m_flags & MORE_FRAGMENTS);
216 }
217 
218 void
220 {
221  NS_LOG_FUNCTION (this);
223 }
224 void
226 {
227  NS_LOG_FUNCTION (this);
229 }
230 bool
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
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 
258 void
259 Ipv4Header::SetTtl (uint8_t ttl)
260 {
261  NS_LOG_FUNCTION (this << static_cast<uint32_t> (ttl));
262  m_ttl = ttl;
263 }
264 uint8_t
265 Ipv4Header::GetTtl (void) const
266 {
267  NS_LOG_FUNCTION (this);
268  return m_ttl;
269 }
270 
271 uint8_t
273 {
274  NS_LOG_FUNCTION (this);
275  return m_protocol;
276 }
277 void
278 Ipv4Header::SetProtocol (uint8_t protocol)
279 {
280  NS_LOG_FUNCTION (this << static_cast<uint32_t> (protocol));
281  m_protocol = protocol;
282 }
283 
284 void
286 {
287  NS_LOG_FUNCTION (this << source);
288  m_source = source;
289 }
292 {
293  NS_LOG_FUNCTION (this);
294  return m_source;
295 }
296 
297 void
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 
311 bool
313 {
314  NS_LOG_FUNCTION (this);
315  return m_goodChecksum;
316 }
317 
318 TypeId
320 {
321  static TypeId tid = TypeId ("ns3::Ipv4Header")
322  .SetParent<Header> ()
323  .AddConstructor<Ipv4Header> ()
324  ;
325  return tid;
326 }
327 TypeId
329 {
330  NS_LOG_FUNCTION (this);
331  return GetTypeId ();
332 }
333 void
334 Ipv4Header::Print (std::ostream &os) const
335 {
336  NS_LOG_FUNCTION (this << &os);
337  // ipv4, right ?
338  std::string flags;
339  if (m_flags == 0)
340  {
341  flags = "none";
342  }
343  else if (m_flags & MORE_FRAGMENTS &&
345  {
346  flags = "MF|DF";
347  }
348  else if (m_flags & DONT_FRAGMENT)
349  {
350  flags = "DF";
351  }
352  else if (m_flags & MORE_FRAGMENTS)
353  {
354  flags = "MF";
355  }
356  else
357  {
358  flags = "XX";
359  }
360  os << "tos 0x" << std::hex << m_tos << std::dec << " "
361  << "DSCP " << DscpTypeToString (GetDscp ()) << " "
362  << "ECN " << EcnTypeToString (GetEcn ()) << " "
363  << "ttl " << m_ttl << " "
364  << "id " << m_identification << " "
365  << "protocol " << m_protocol << " "
366  << "offset (bytes) " << m_fragmentOffset << " "
367  << "flags [" << flags << "] "
368  << "length: " << (m_payloadSize + 5 * 4)
369  << " "
370  << m_source << " > " << m_destination
371  ;
372 }
373 uint32_t
375 {
376  NS_LOG_FUNCTION (this);
377  //return 5 * 4;
378  return m_headerSize;
379 }
380 
381 void
383 {
384  NS_LOG_FUNCTION (this << &start);
386 
387  uint8_t verIhl = (4 << 4) | (5);
388  i.WriteU8 (verIhl);
389  i.WriteU8 (m_tos);
390  i.WriteHtonU16 (m_payloadSize + 5*4);
392  uint32_t fragmentOffset = m_fragmentOffset / 8;
393  uint8_t flagsFrag = (fragmentOffset >> 8) & 0x1f;
394  if (m_flags & DONT_FRAGMENT)
395  {
396  flagsFrag |= (1<<6);
397  }
398  if (m_flags & MORE_FRAGMENTS)
399  {
400  flagsFrag |= (1<<5);
401  }
402  i.WriteU8 (flagsFrag);
403  uint8_t frag = fragmentOffset & 0xff;
404  i.WriteU8 (frag);
405  i.WriteU8 (m_ttl);
406  i.WriteU8 (m_protocol);
407  i.WriteHtonU16 (0);
408  i.WriteHtonU32 (m_source.Get ());
410 
411  if (m_calcChecksum)
412  {
413  i = start;
414  uint16_t checksum = i.CalculateIpChecksum (20);
415  NS_LOG_LOGIC ("checksum=" <<checksum);
416  i = start;
417  i.Next (10);
418  i.WriteU16 (checksum);
419  }
420 }
421 uint32_t
423 {
424  NS_LOG_FUNCTION (this << &start);
426  uint8_t verIhl = i.ReadU8 ();
427  uint8_t ihl = verIhl & 0x0f;
428  uint16_t headerSize = ihl * 4;
429  NS_ASSERT ((verIhl >> 4) == 4);
430  m_tos = i.ReadU8 ();
431  uint16_t size = i.ReadNtohU16 ();
432  m_payloadSize = size - headerSize;
434  uint8_t flags = i.ReadU8 ();
435  m_flags = 0;
436  if (flags & (1<<6))
437  {
439  }
440  if (flags & (1<<5))
441  {
443  }
444  i.Prev ();
445  m_fragmentOffset = i.ReadU8 () & 0x1f;
446  m_fragmentOffset <<= 8;
447  m_fragmentOffset |= i.ReadU8 ();
448  m_fragmentOffset <<= 3;
449  m_ttl = i.ReadU8 ();
450  m_protocol = i.ReadU8 ();
451  m_checksum = i.ReadU16 ();
452  /* i.Next (2); // checksum */
453  m_source.Set (i.ReadNtohU32 ());
455  m_headerSize = headerSize;
456 
457  if (m_calcChecksum)
458  {
459  i = start;
460  uint16_t checksum = i.CalculateIpChecksum (headerSize);
461  NS_LOG_LOGIC ("checksum=" <<checksum);
462 
463  m_goodChecksum = (checksum == 0);
464  }
465  return GetSerializedSize ();
466 }
467 
468 } // namespace ns3
uint16_t ReadU16(void)
Definition: buffer.h:1036
Protocol header serialization and deserialization.
Definition: header.h:42
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1162
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
uint16_t GetPayloadSize(void) const
Definition: ipv4-header.cc:62
uint32_t m_ttl
TTL.
Definition: ipv4-header.h:248
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint32_t m_flags
flags
Definition: ipv4-header.h:250
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
uint16_t m_identification
identification
Definition: ipv4-header.h:246
DscpType
DiffServ Code Points Code Points defined in Assured Forwarding (AF) RFC 2597 Expedited Forwarding (EF...
Definition: ipv4-header.h:64
Ipv4Address m_destination
destination address
Definition: ipv4-header.h:253
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
uint16_t GetIdentification(void) const
Definition: ipv4-header.cc:69
uint16_t m_headerSize
IP header size.
Definition: ipv4-header.h:256
bool IsDontFragment(void) const
Definition: ipv4-header.cc:231
void SetFragmentOffset(uint16_t offsetBytes)
The offset is measured in bytes for the packet start.
Definition: ipv4-header.cc:238
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
uint32_t m_tos
TOS, also used as DSCP + ECN value.
Definition: ipv4-header.h:247
std::string DscpTypeToString(DscpType dscp) const
Definition: ipv4-header.cc:113
void SetDontFragment(void)
Don't fragment this packet: if you need to anyway, drop it.
Definition: ipv4-header.cc:219
uint32_t ReadNtohU32(void)
Definition: buffer.h:977
iterator in a Buffer instance
Definition: buffer.h:98
static TypeId GetTypeId(void)
Get the type ID.
Definition: ipv4-header.cc:319
void SetLastFragment(void)
This packet is the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:206
bool m_goodChecksum
true if checksum is correct
Definition: ipv4-header.h:255
void Prev(void)
go backward by one byte
Definition: buffer.h:858
uint32_t Get(void) const
Get the host-order 32-bit IP address.
DscpType GetDscp(void) const
Definition: ipv4-header.cc:105
Ipv4Header()
Construct a null IPv4 header.
Definition: ipv4-header.cc:33
void WriteU16(uint16_t data)
Definition: buffer.cc:899
void EnableChecksum(void)
Enable checksum calculation for this header.
Definition: ipv4-header.cc:49
void SetDscp(DscpType dscp)
Set DSCP Field.
Definition: ipv4-header.cc:89
void WriteHtonU16(uint16_t data)
Definition: buffer.h:912
void Next(void)
go forward by one byte
Definition: buffer.h:852
void SetIdentification(uint16_t identification)
Definition: ipv4-header.cc:75
void SetMayFragment(void)
If you need to fragment this packet, you can do it.
Definition: ipv4-header.cc:225
uint16_t m_fragmentOffset
Fragment offset.
Definition: ipv4-header.h:251
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
uint16_t m_checksum
checksum
Definition: ipv4-header.h:254
void SetMoreFragments(void)
This packet is not the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:200
bool IsLastFragment(void) const
Definition: ipv4-header.cc:212
void SetTos(uint8_t tos)
Definition: ipv4-header.cc:82
virtual void Print(std::ostream &os) const
Definition: ipv4-header.cc:334
Ipv4Address m_source
source address
Definition: ipv4-header.h:252
void WriteHtonU32(uint32_t data)
Definition: buffer.h:931
virtual TypeId GetInstanceTypeId(void) const
Definition: ipv4-header.cc:328
void Set(uint32_t address)
input address is in host order.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
void WriteU8(uint8_t data)
Definition: buffer.h:876
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:101
uint16_t GetFragmentOffset(void) const
Definition: ipv4-header.cc:246
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
uint32_t m_protocol
Protocol.
Definition: ipv4-header.h:249
void SetEcn(EcnType ecn)
Set ECN Field.
Definition: ipv4-header.cc:97
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:259
uint8_t ReadU8(void)
Definition: buffer.h:1028
virtual void Serialize(Buffer::Iterator start) const
Definition: ipv4-header.cc:382
bool IsChecksumOk(void) const
Definition: ipv4-header.cc:312
bool m_calcChecksum
true if the checksum must be calculated
Definition: ipv4-header.h:243
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
uint8_t GetTos(void) const
Definition: ipv4-header.cc:194
uint16_t m_payloadSize
payload size
Definition: ipv4-header.h:245
std::string EcnTypeToString(EcnType ecn) const
Definition: ipv4-header.cc:175
uint16_t ReadNtohU16(void)
Definition: buffer.h:953
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:374
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
EcnType GetEcn(void) const
Definition: ipv4-header.cc:167
EcnType
ECN Type defined in RFC 3168
Definition: ipv4-header.h:106
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: ipv4-header.cc:422