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