A Discrete-Event Network Simulator
API
dhcp-header.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 UPB
4  * Copyright (c) 2017 NITK Surathkal
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Radu Lupu <rlupu@elcom.pub.ro>
20  * Ankit Deepak <adadeepak8@gmail.com>
21  * Deepti Rajagopal <deeptir96@gmail.com>
22  *
23  */
24 
25 #include "ns3/assert.h"
26 #include "ns3/log.h"
27 #include "ns3/simulator.h"
28 #include "ns3/address-utils.h"
29 #include "dhcp-header.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("DhcpHeader");
34 NS_OBJECT_ENSURE_REGISTERED (DhcpHeader);
35 
37 {
38  m_hType = 1;
39  m_hLen = 6;
40  m_xid = 0;
41  m_secs = 0;
42  m_hops = 0;
43  m_flags = 0;
44  Ipv4Address addr = Ipv4Address ("0.0.0.0");
45  m_yiAddr = addr;
46  m_ciAddr = addr;
47  m_siAddr = addr;
48  m_giAddr = addr;
49  m_dhcps = addr;
50  m_req = addr;
51  m_route = addr;
52  m_len = 240;
53 
54  uint32_t i;
55 
56  for (i = 0; i < 64; i++)
57  {
58  m_sname[i] = 0;
59  }
60  for (i = 0; i < 128; i++)
61  {
62  m_file[i] = 0;
63  }
64  m_magic_cookie[0] = 99;
65  m_magic_cookie[1] = 130;
66  m_magic_cookie[2] = 83;
67  m_magic_cookie[3] = 99;
68 }
69 
71 {
72 }
73 
74 void DhcpHeader::SetType (uint8_t type)
75 {
76  if (m_opt[OP_MSGTYPE] == false)
77  {
78  m_len += 3;
79  m_opt[OP_MSGTYPE] = true;
80  }
81  m_op = type;
82  m_bootp = (m_op == 0||m_op == 2) ? 1 : 2;
83 }
84 
85 uint8_t DhcpHeader::GetType (void) const
86 {
87  return m_op;
88 }
89 
90 void DhcpHeader::SetHWType (uint8_t htype, uint8_t hlen)
91 {
92  m_hType = htype;
93  m_hLen = hlen;
94 }
95 
96 void DhcpHeader::SetTran (uint32_t tran)
97 {
98  m_xid = tran;
99 }
100 
101 uint32_t DhcpHeader::GetTran (void) const
102 {
103  return m_xid;
104 }
105 
107 {
108  m_secs = (uint16_t) Simulator::Now ().GetSeconds ();
109 }
110 
112 {
113  std::memset (m_chaddr, 0, 16);
114  NS_ASSERT_MSG (addr.GetLength () <= 16, "Address length too big");
115  addr.CopyTo (m_chaddr);
116 }
117 
118 void DhcpHeader::SetChaddr (uint8_t* addr, uint8_t len)
119 {
120  std::memset (m_chaddr, 0, 16);
121  NS_ASSERT_MSG (len <= 16, "Address length too big");
122  std::memcpy (m_chaddr, addr, len);
123 }
124 
126 {
127  Address addr;
128  addr.CopyFrom (m_chaddr, 16);
129  return addr;
130 }
131 
133 {
134  m_yiAddr = addr;
135 }
136 
138 {
139  return m_yiAddr;
140 }
141 
143 {
144  if (m_opt[OP_SERVID] == false)
145  {
146  m_len += 6;
147  m_opt[OP_SERVID] = true;
148  }
149  m_dhcps = addr;
150 }
151 
153 {
154  return m_dhcps;
155 }
156 
158 {
159  if (m_opt[OP_ADDREQ] == false)
160  {
161  m_len += 6;
162  m_opt[OP_ADDREQ] = true;
163  }
164  m_req = addr;
165 }
166 
168 {
169  return m_req;
170 }
171 
172 void DhcpHeader::SetMask (uint32_t addr)
173 {
174  if (m_opt[OP_MASK] == false)
175  {
176  m_len += 6;
177  m_opt[OP_MASK] = true;
178  }
179  m_mask = addr;
180 }
181 
182 uint32_t DhcpHeader::GetMask (void) const
183 {
184  return m_mask;
185 }
186 
188 {
189  if (m_opt[OP_ROUTE] == false)
190  {
191  m_len += 6;
192  m_opt[OP_ROUTE] = true;
193  }
194  m_route = addr;
195 }
196 
198 {
199  return m_route;
200 }
201 
202 void DhcpHeader::SetLease (uint32_t time)
203 {
204  if (m_opt[OP_LEASE] == false)
205  {
206  m_len += 6;
207  m_opt[OP_LEASE] = true;
208  }
209  m_lease = time;
210 }
211 
212 uint32_t DhcpHeader::GetLease (void) const
213 {
214  return m_lease;
215 }
216 
217 void DhcpHeader::SetRenew (uint32_t time)
218 {
219  if (m_opt[OP_RENEW] == false)
220  {
221  m_len += 6;
222  m_opt[OP_RENEW] = true;
223  }
224  m_renew = time;
225 }
226 
227 uint32_t DhcpHeader::GetRenew (void) const
228 {
229  return m_renew;
230 }
231 
232 void DhcpHeader::SetRebind (uint32_t time)
233 {
234  if (m_opt[OP_REBIND] == false)
235  {
236  m_len += 6;
237  m_opt[OP_REBIND] = true;
238  }
239  m_rebind = time;
240 }
241 
242 uint32_t DhcpHeader::GetRebind (void) const
243 {
244  return m_rebind;
245 }
246 
248 {
249  m_len = 241;
250  int i;
251  for (i = 0; i < OP_END; i++)
252  {
253  m_opt[i] = false;
254  }
255 }
256 
257 uint32_t DhcpHeader::GetSerializedSize (void) const
258 {
259  return m_len;
260 }
261 
263 {
264  static TypeId tid = TypeId ("ns3::DhcpHeader")
265  .SetParent<Header> ()
266  .SetGroupName ("Internet-Apps")
267  .AddConstructor<DhcpHeader> ()
268  ;
269  return tid;
270 }
271 
273 {
274  return GetTypeId ();
275 }
276 
277 void DhcpHeader::Print (std::ostream &os) const
278 {
279  os << "(type=" << m_op << ")";
280 }
281 
282 void
284 {
286  i.WriteU8 (m_bootp);
287  i.WriteU8 (m_hType);
288  i.WriteU8 (m_hLen);
289  i.WriteU8 (m_hops);
290  i.WriteU32 (m_xid);
291  i.WriteHtonU16 (m_secs);
292  i.WriteU16 ( m_flags);
293  WriteTo (i, m_ciAddr);
294  WriteTo (i, m_yiAddr);
295  WriteTo (i, m_siAddr);
296  WriteTo (i, m_giAddr);
297  i.Write (m_chaddr, 16);
298  i.Write (m_sname,64);
299  i.Write (m_file,128);
300  i.Write (m_magic_cookie,4);
301  if (m_opt[OP_MASK])
302  {
303  i.WriteU8 (OP_MASK);
304  i.WriteU8 (4);
305  i.WriteHtonU32 (m_mask);
306  }
307  if (m_opt[OP_MSGTYPE])
308  {
309  i.WriteU8 (OP_MSGTYPE);
310  i.WriteU8 (1);
311  i.WriteU8 ((m_op + 1));
312  }
313  if (m_opt[OP_ADDREQ])
314  {
315  i.WriteU8 (OP_ADDREQ);
316  i.WriteU8 (4);
317  WriteTo (i, m_req);
318  }
319  if (m_opt[OP_SERVID])
320  {
321  i.WriteU8 (OP_SERVID);
322  i.WriteU8 (4);
323  WriteTo (i, m_dhcps);
324  }
325  if (m_opt[OP_ROUTE])
326  {
327  i.WriteU8 (OP_ROUTE);
328  i.WriteU8 (4);
329  WriteTo (i, m_route);
330  }
331  if (m_opt[OP_LEASE])
332  {
333  i.WriteU8 (OP_LEASE);
334  i.WriteU8 (4);
335  i.WriteHtonU32 (m_lease);
336  }
337  if (m_opt[OP_RENEW])
338  {
339  i.WriteU8 (OP_RENEW);
340  i.WriteU8 (4);
341  i.WriteHtonU32 (m_renew);
342  }
343  if (m_opt[OP_REBIND])
344  {
345  i.WriteU8 (OP_REBIND);
346  i.WriteU8 (4);
348  }
349  i.WriteU8 (OP_END);
350 }
351 
353 {
354  uint32_t len, clen = start.GetSize ();
355  if (clen < 240)
356  {
357  NS_LOG_WARN ("Malformed Packet");
358  return 0;
359  }
361  m_bootp = i.ReadU8 ();
362  m_hType = i.ReadU8 ();
363  m_hLen = i.ReadU8 ();
364  m_hops = i.ReadU8 ();
365  m_xid = i.ReadU32 ();
366  m_secs = i.ReadNtohU16 ();
367  m_flags = i.ReadU16 ();
368  ReadFrom (i, m_ciAddr);
369  ReadFrom (i, m_yiAddr);
370  ReadFrom (i, m_siAddr);
371  ReadFrom (i, m_giAddr);
372  i.Read (m_chaddr, 16);
373  i.Read (m_sname, 64);
374  i.Read (m_file, 128);
375  i.Read (m_magic_cookie, 4);
376  if ( m_magic_cookie[0] != 99 || m_magic_cookie[1] != 130 || m_magic_cookie[2] != 83 || m_magic_cookie[3] != 99)
377  {
378  NS_LOG_WARN ("Malformed Packet");
379  return 0;
380  }
381  len = 240;
382  uint8_t option;
383  bool loop = true;
384  do
385  {
386  if (len + 1 <= clen)
387  {
388  option = i.ReadU8 ();
389  len += 1;
390  }
391  else
392  {
393  NS_LOG_WARN ("Malformed Packet");
394  return 0;
395  }
396  switch (option)
397  {
398  case OP_MASK:
399  if (len + 5 < clen)
400  {
401  i.ReadU8 ();
402  m_mask = i.ReadNtohU32 ();
403  len += 5;
404  }
405  else
406  {
407  NS_LOG_WARN ("Malformed Packet");
408  return 0;
409  }
410  break;
411  case OP_ROUTE:
412  if (len + 5 < clen)
413  {
414  i.ReadU8 ();
415  ReadFrom (i, m_route);
416  len += 5;
417  }
418  else
419  {
420  NS_LOG_WARN ("Malformed Packet");
421  return 0;
422  }
423  break;
424  case OP_MSGTYPE:
425  if (len + 2 < clen)
426  {
427  i.ReadU8 ();
428  m_op = (i.ReadU8 () - 1);
429  len += 2;
430  }
431  else
432  {
433  NS_LOG_WARN ("Malformed Packet");
434  return 0;
435  }
436  break;
437  case OP_SERVID:
438  if (len + 5 < clen)
439  {
440  i.ReadU8 ();
441  ReadFrom (i, m_dhcps);
442  len += 5;
443  }
444  else
445  {
446  NS_LOG_WARN ("Malformed Packet");
447  return 0;
448  }
449  break;
450  case OP_ADDREQ:
451  if (len + 5 < clen)
452  {
453  i.ReadU8 ();
454  ReadFrom (i, m_req);
455  len += 5;
456  }
457  else
458  {
459  NS_LOG_WARN ("Malformed Packet");
460  return 0;
461  }
462  break;
463  case OP_LEASE:
464  if (len + 5 < clen)
465  {
466  i.ReadU8 ();
467  m_lease = i.ReadNtohU32 ();
468  len += 5;
469  }
470  else
471  {
472  NS_LOG_WARN ("Malformed Packet");
473  return 0;
474  }
475  break;
476  case OP_RENEW:
477  if (len + 5 < clen)
478  {
479  i.ReadU8 ();
480  m_renew = i.ReadNtohU32 ();
481  len += 5;
482  }
483  else
484  {
485  NS_LOG_WARN ("Malformed Packet");
486  return 0;
487  }
488  break;
489  case OP_REBIND:
490  if (len + 5 < clen)
491  {
492  i.ReadU8 ();
493  m_rebind = i.ReadNtohU32 ();
494  len += 5;
495  }
496  else
497  {
498  NS_LOG_WARN ("Malformed Packet");
499  return 0;
500  }
501  break;
502  case OP_END:
503  loop = false;
504  break;
505  default:
506  NS_LOG_WARN ("Malformed Packet");
507  return 0;
508  }
509  }
510  while (loop);
511 
512  m_len = len;
513  return m_len;
514 }
515 
516 } // namespace ns3
a polymophic address class
Definition: address.h:91
uint8_t GetLength(void) const
Get the length of the underlying address.
Definition: address.cc:75
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:101
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:82
iterator in a Buffer instance
Definition: buffer.h:99
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:954
void WriteU32(uint32_t data)
Definition: buffer.cc:879
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
void WriteU8(uint8_t data)
Definition: buffer.h:869
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 Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1124
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
uint32_t ReadU32(void)
Definition: buffer.cc:973
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
BOOTP header with DHCP messages supports the following options: Subnet Mask (1), Address Request (50)...
Definition: dhcp-header.h:82
void SetTime()
Set the time when message is sent.
Definition: dhcp-header.cc:106
Ipv4Address m_ciAddr
The IP address of the client.
Definition: dhcp-header.h:305
uint32_t m_rebind
The rebinding time for the client.
Definition: dhcp-header.h:316
uint8_t m_chaddr[16]
The address identifier.
Definition: dhcp-header.h:303
Ipv4Address GetDhcps(void) const
Get the information about the DHCP server.
Definition: dhcp-header.cc:152
Ipv4Address m_giAddr
Relay Agent IP address.
Definition: dhcp-header.h:307
void ResetOpt()
Reset the BOOTP options.
Definition: dhcp-header.cc:247
uint8_t m_hops
The number of hops covered by the message.
Definition: dhcp-header.h:297
uint32_t GetRebind(void) const
Return the Rebind time of the address.
Definition: dhcp-header.cc:242
uint8_t m_bootp
The BOOTP Message type.
Definition: dhcp-header.h:294
uint32_t m_lease
The lease time of the address.
Definition: dhcp-header.h:314
void SetType(uint8_t type)
Set the type of BOOTP and DHCP messages.
Definition: dhcp-header.cc:74
~DhcpHeader()
Destructor.
Definition: dhcp-header.cc:70
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: dhcp-header.cc:272
void SetTran(uint32_t tran)
Set the transaction ID.
Definition: dhcp-header.cc:96
virtual void Serialize(Buffer::Iterator start) const
Definition: dhcp-header.cc:283
uint8_t m_sname[64]
Server name (Padded for now)
Definition: dhcp-header.h:311
Ipv4Address m_yiAddr
Your (client) IP address.
Definition: dhcp-header.h:304
uint32_t GetMask(void) const
Return the mask of the network.
Definition: dhcp-header.cc:182
void SetYiaddr(Ipv4Address addr)
Set the IPv4Address of the client.
Definition: dhcp-header.cc:132
uint32_t m_len
The length of the header.
Definition: dhcp-header.h:300
void SetDhcps(Ipv4Address addr)
Set the DHCP server information.
Definition: dhcp-header.cc:142
uint16_t m_secs
Seconds elapsed.
Definition: dhcp-header.h:301
uint32_t m_mask
The mask of the network.
Definition: dhcp-header.h:299
Ipv4Address m_dhcps
DHCP server IP address.
Definition: dhcp-header.h:308
Ipv4Address m_siAddr
Next Server IP address.
Definition: dhcp-header.h:306
void SetRenew(uint32_t time)
Set the Renewal time of the IPv4Address.
Definition: dhcp-header.cc:217
bool m_opt[255]
BOOTP option list.
Definition: dhcp-header.h:317
Ipv4Address GetReq(void) const
Get the IPv4Address requested by the client.
Definition: dhcp-header.cc:167
uint8_t m_magic_cookie[4]
DHCP Magic Cookie.
Definition: dhcp-header.h:313
void SetLease(uint32_t time)
Set the lease time of the IPv4Address.
Definition: dhcp-header.cc:202
@ OP_SERVID
BOOTP Option 54: Server Identifier.
Definition: dhcp-header.h:108
@ OP_MASK
BOOTP Option 1: Address Mask.
Definition: dhcp-header.h:103
@ OP_REBIND
BOOTP Option 59: Address Rebind Time.
Definition: dhcp-header.h:110
@ OP_MSGTYPE
BOOTP Option 53: DHCP Message Type.
Definition: dhcp-header.h:107
@ OP_RENEW
BOOTP Option 58: Address Renewal Time.
Definition: dhcp-header.h:109
@ OP_ADDREQ
BOOTP Option 50: Requested Address.
Definition: dhcp-header.h:105
@ OP_ROUTE
BOOTP Option 3: Router Option.
Definition: dhcp-header.h:104
@ OP_END
BOOTP Option 255: END.
Definition: dhcp-header.h:111
@ OP_LEASE
BOOTP Option 51: Address Lease Time.
Definition: dhcp-header.h:106
uint8_t m_hLen
The hardware length.
Definition: dhcp-header.h:296
DhcpHeader()
Constructor.
Definition: dhcp-header.cc:36
void SetRouter(Ipv4Address addr)
Set the Ipv4Address of gateway to be used.
Definition: dhcp-header.cc:187
void SetMask(uint32_t addr)
Set the mask of the IPv4Address.
Definition: dhcp-header.cc:172
uint32_t GetTran(void) const
Get the transaction id.
Definition: dhcp-header.cc:101
uint32_t m_renew
The renewal time for the client.
Definition: dhcp-header.h:315
uint8_t m_hType
The hardware type.
Definition: dhcp-header.h:295
uint8_t GetType(void) const
Return the type of DHCP message.
Definition: dhcp-header.cc:85
uint32_t GetLease(void) const
Return the lease time of the IPv4Address.
Definition: dhcp-header.cc:212
Ipv4Address GetRouter(void) const
Return the Ipv4Address of gateway to be used.
Definition: dhcp-header.cc:197
void SetReq(Ipv4Address addr)
Set the Ipv4Address requested by the client.
Definition: dhcp-header.cc:157
static TypeId GetTypeId(void)
Get the type ID.
Definition: dhcp-header.cc:262
uint16_t m_flags
BOOTP flags.
Definition: dhcp-header.h:302
Ipv4Address GetYiaddr(void) const
Get the IPv4Address of the client.
Definition: dhcp-header.cc:137
virtual void Print(std::ostream &os) const
Definition: dhcp-header.cc:277
virtual uint32_t GetSerializedSize(void) const
Definition: dhcp-header.cc:257
void SetRebind(uint32_t time)
Set the Rebind time of the IPv4Address.
Definition: dhcp-header.cc:232
Ipv4Address m_route
Router Option Address.
Definition: dhcp-header.h:310
uint8_t m_op
The DHCP Message type.
Definition: dhcp-header.h:293
uint32_t m_xid
The transaction number.
Definition: dhcp-header.h:298
Ipv4Address m_req
Requested Address.
Definition: dhcp-header.h:309
Address GetChaddr(void)
Get the Address of the client.
Definition: dhcp-header.cc:125
void SetChaddr(Address addr)
Set the Address of the device.
Definition: dhcp-header.cc:111
uint32_t GetRenew(void) const
Return the Renewal time of the address.
Definition: dhcp-header.cc:227
uint8_t m_file[128]
File name (Padded for now)
Definition: dhcp-header.h:312
void SetHWType(uint8_t htype, uint8_t hlen)
Set the hardware information.
Definition: dhcp-header.cc:90
Protocol header serialization and deserialization.
Definition: header.h:43
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
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_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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.
void WriteTo(Buffer::Iterator &i, Ipv4Address ad)
Write an Ipv4Address to a Buffer.
void ReadFrom(Buffer::Iterator &i, Ipv4Address &ad)
Read an Ipv4Address from a Buffer.
def start()
Definition: core.py:1853