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  ;
33 
35  : m_calcChecksum (false),
36  m_payloadSize (0),
37  m_identification (0),
38  m_tos (0),
39  m_ttl (0),
40  m_protocol (0),
41  m_flags (0),
42  m_fragmentOffset (0),
43  m_checksum (0),
44  m_goodChecksum (true),
45  m_headerSize(5*4)
46 {
47 }
48 
49 void
51 {
52  NS_LOG_FUNCTION (this);
53  m_calcChecksum = true;
54 }
55 
56 void
58 {
59  NS_LOG_FUNCTION (this << size);
60  m_payloadSize = size;
61 }
62 uint16_t
64 {
65  NS_LOG_FUNCTION (this);
66  return m_payloadSize;
67 }
68 
69 uint16_t
71 {
72  NS_LOG_FUNCTION (this);
73  return m_identification;
74 }
75 void
76 Ipv4Header::SetIdentification (uint16_t identification)
77 {
78  NS_LOG_FUNCTION (this << identification);
79  m_identification = identification;
80 }
81 
82 void
83 Ipv4Header::SetTos (uint8_t tos)
84 {
85  NS_LOG_FUNCTION (this << static_cast<uint32_t> (tos));
86  m_tos = tos;
87 }
88 
89 void
91 {
92  NS_LOG_FUNCTION (this << dscp);
93  m_tos &= 0x3; // Clear out the DSCP part, retain 2 bits of ECN
94  m_tos |= dscp;
95 }
96 
97 void
99 {
100  NS_LOG_FUNCTION (this << ecn);
101  m_tos &= 0xFC; // Clear out the ECN part, retain 6 bits of DSCP
102  m_tos |= ecn;
103 }
104 
107 {
108  NS_LOG_FUNCTION (this);
109  // Extract only first 6 bits of TOS byte, i.e 0xFC
110  return DscpType (m_tos & 0xFC);
111 }
112 
113 std::string
115 {
116  NS_LOG_FUNCTION (this << dscp);
117  switch (dscp)
118  {
119  case DscpDefault:
120  return "Default";
121  case DSCP_CS1:
122  return "CS1";
123  case DSCP_AF11:
124  return "AF11";
125  case DSCP_AF12:
126  return "AF12";
127  case DSCP_AF13:
128  return "AF13";
129  case DSCP_CS2:
130  return "CS2";
131  case DSCP_AF21:
132  return "AF21";
133  case DSCP_AF22:
134  return "AF22";
135  case DSCP_AF23:
136  return "AF23";
137  case DSCP_CS3:
138  return "CS3";
139  case DSCP_AF31:
140  return "AF31";
141  case DSCP_AF32:
142  return "AF32";
143  case DSCP_AF33:
144  return "AF33";
145  case DSCP_CS4:
146  return "CS4";
147  case DSCP_AF41:
148  return "AF41";
149  case DSCP_AF42:
150  return "AF42";
151  case DSCP_AF43:
152  return "AF43";
153  case DSCP_CS5:
154  return "CS5";
155  case DSCP_EF:
156  return "EF";
157  case DSCP_CS6:
158  return "CS6";
159  case DSCP_CS7:
160  return "CS7";
161  default:
162  return "Unrecognized DSCP";
163  };
164 }
165 
166 
168 Ipv4Header::GetEcn (void) const
169 {
170  NS_LOG_FUNCTION (this);
171  // Extract only last 2 bits of TOS byte, i.e 0x3
172  return EcnType (m_tos & 0x3);
173 }
174 
175 std::string
177 {
178  NS_LOG_FUNCTION (this << ecn);
179  switch (ecn)
180  {
181  case ECN_NotECT:
182  return "Not-ECT";
183  case ECN_ECT1:
184  return "ECT (1)";
185  case ECN_ECT0:
186  return "ECT (0)";
187  case ECN_CE:
188  return "CE";
189  default:
190  return "Unknown ECN";
191  };
192 }
193 
194 uint8_t
195 Ipv4Header::GetTos (void) const
196 {
197  NS_LOG_FUNCTION (this);
198  return m_tos;
199 }
200 void
202 {
203  NS_LOG_FUNCTION (this);
205 }
206 void
208 {
209  NS_LOG_FUNCTION (this);
211 }
212 bool
214 {
215  NS_LOG_FUNCTION (this);
216  return !(m_flags & MORE_FRAGMENTS);
217 }
218 
219 void
221 {
222  NS_LOG_FUNCTION (this);
224 }
225 void
227 {
228  NS_LOG_FUNCTION (this);
230 }
231 bool
233 {
234  NS_LOG_FUNCTION (this);
235  return (m_flags & DONT_FRAGMENT);
236 }
237 
238 void
239 Ipv4Header::SetFragmentOffset (uint16_t offsetBytes)
240 {
241  NS_LOG_FUNCTION (this << offsetBytes);
242  // check if the user is trying to set an invalid offset
243  NS_ABORT_MSG_IF ((offsetBytes & 0x7), "offsetBytes must be multiple of 8 bytes");
244  m_fragmentOffset = offsetBytes;
245 }
246 uint16_t
248 {
249  NS_LOG_FUNCTION (this);
250  if ((m_fragmentOffset+m_payloadSize+5*4) > 65535)
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:845
Protocol header serialization and deserialization.
Definition: header.h:42
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1158
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:57
uint16_t GetPayloadSize(void) const
Definition: ipv4-header.cc:63
uint32_t m_ttl
TTL.
Definition: ipv4-header.h:248
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
uint32_t m_flags
flags
Definition: ipv4-header.h:250
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)
Definition: assert.h:64
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
uint16_t GetIdentification(void) const
Definition: ipv4-header.cc:70
uint16_t m_headerSize
IP header size.
Definition: ipv4-header.h:256
bool IsDontFragment(void) const
Definition: ipv4-header.cc:232
void SetFragmentOffset(uint16_t offsetBytes)
The offset is measured in bytes for the packet start.
Definition: ipv4-header.cc:239
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:114
void SetDontFragment(void)
Don't fragment this packet: if you need to anyway, drop it.
Definition: ipv4-header.cc:220
uint32_t ReadNtohU32(void)
Definition: buffer.h:791
NS_LOG_COMPONENT_DEFINE("Ipv4Header")
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:207
bool m_goodChecksum
true if checksum is correct
Definition: ipv4-header.h:255
void Prev(void)
go backward by one byte
Definition: buffer.h:672
uint32_t Get(void) const
Get the host-order 32-bit IP address.
DscpType GetDscp(void) const
Definition: ipv4-header.cc:106
Ipv4Header()
Construct a null IPv4 header.
Definition: ipv4-header.cc:34
void WriteU16(uint16_t data)
Definition: buffer.cc:895
void EnableChecksum(void)
Enable checksum calculation for this header.
Definition: ipv4-header.cc:50
void SetDscp(DscpType dscp)
Set DSCP Field.
Definition: ipv4-header.cc:90
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
void Next(void)
go forward by one byte
Definition: buffer.h:666
void SetIdentification(uint16_t identification)
Definition: ipv4-header.cc:76
void SetMayFragment(void)
If you need to fragment this packet, you can do it.
Definition: ipv4-header.cc:226
uint16_t m_fragmentOffset
Fragment offset.
Definition: ipv4-header.h:251
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
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:201
bool IsLastFragment(void) const
Definition: ipv4-header.cc:213
void SetTos(uint8_t tos)
Definition: ipv4-header.cc:83
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:745
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:690
uint16_t GetFragmentOffset(void) const
Definition: ipv4-header.cc:247
#define NS_LOG_WARN(msg)
Definition: log.h:280
uint32_t m_protocol
Protocol.
Definition: ipv4-header.h:249
void SetEcn(EcnType ecn)
Set ECN Field.
Definition: ipv4-header.cc:98
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:259
uint8_t ReadU8(void)
Definition: buffer.h:819
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:195
uint16_t m_payloadSize
payload size
Definition: ipv4-header.h:245
std::string EcnTypeToString(EcnType ecn) const
Definition: ipv4-header.cc:176
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
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:611
EcnType GetEcn(void) const
Definition: ipv4-header.cc:168
EcnType
ECN Type defined in RFC 3168
Definition: ipv4-header.h:106
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: ipv4-header.cc:422