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