Skip to content

Commit f11f861

Browse files
committed
DHCP server: Debug info added and updated clear_offered_ips method
1 parent 3b903c7 commit f11f861

2 files changed

Lines changed: 131 additions & 7 deletions

File tree

api/net/dhcp/dhcpd.hpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,56 @@ namespace dhcp {
155155

156156
void clear_offered_ip(IP4::addr ip);
157157
void clear_offered_ips();
158+
159+
void print(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
160+
debug("Printing:\n");
161+
162+
debug("OP: %u\n", msg->op);
163+
debug("HTYPE: %u\n", msg->htype);
164+
debug("HLEN: %u\n", msg->hlen);
165+
debug("HOPS: %u\n", msg->hops);
166+
debug("XID: %u\n", msg->xid);
167+
debug("SECS: %u\n", msg->secs);
168+
debug("FLAGS: %u\n", msg->flags);
169+
debug("CIADDR (IP4::addr): %s\n", msg->ciaddr.to_string().c_str());
170+
debug("YIADDR (IP4::addr): %s\n", msg->yiaddr.to_string().c_str());
171+
debug("SIADDR (IP4::addr): %s\n", msg->siaddr.to_string().c_str());
172+
debug("GIADDR (IP4::addr): %s\n", msg->giaddr.to_string().c_str());
173+
174+
debug("\nCHADDR:\n");
175+
for (int i = 0; i < dhcp_packet_t::CHADDR_LEN; i++)
176+
debug("%u ", msg->chaddr[i]);
177+
debug("\n");
178+
179+
debug("\nSNAME:\n");
180+
for (int i = 0; i < dhcp_packet_t::SNAME_LEN; i++)
181+
debug("%u ", msg->sname[i]);
182+
debug("\n");
183+
184+
debug("\nFILE:\n");
185+
for (int i = 0; i < dhcp_packet_t::FILE_LEN; i++)
186+
debug("%u ", msg->file[i]);
187+
debug("\n");
188+
189+
debug("\nMAGIC:\n");
190+
for (int i = 0; i < 4; i++)
191+
debug("%u ", msg->magic[i]);
192+
debug("\n");
193+
194+
// Opts
195+
196+
while(opts->code != DHO_END) {
197+
debug("\nOptions->code: %d\n", opts->code);
198+
debug("\nOptions->length: %d\n", opts->length);
199+
200+
debug("\nOptions->val: ");
201+
for (size_t i = 0; i < opts->length; i++)
202+
debug("%d ", opts->val[i]);
203+
debug("\n");
204+
205+
opts = (const dhcp_option_t*) (((const uint8_t*) opts) + 2 + opts->length);
206+
}
207+
}
158208
};
159209

160210
} // < namespace dhcp

src/net/dhcp/dhcpd.cpp

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,35 +112,59 @@ void DHCPD::listen() {
112112
}
113113

114114
void DHCPD::resolve(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
115-
if (msg->op not_eq BOOTREQUEST or msg->hops not_eq 0)
115+
if (msg->op not_eq BOOTREQUEST or msg->hops not_eq 0) {
116+
debug("Invalid op\n");
116117
return;
118+
}
117119

118-
if (msg->htype == 0 or msg->htype > HTYPE_HFI) // http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
120+
if (msg->htype == 0 or msg->htype > HTYPE_HFI) { // http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
121+
debug("Invalid htype\n");
119122
return;
123+
}
120124

121-
if (msg->yiaddr not_eq IP4::addr{0} or msg->siaddr not_eq IP4::addr{0} or msg->giaddr not_eq IP4::addr{0})
125+
if (msg->yiaddr not_eq IP4::addr{0} or msg->siaddr not_eq IP4::addr{0} or msg->giaddr not_eq IP4::addr{0}) {
126+
debug("Invalid yiaddr, siaddr or giaddr\n");
122127
return;
128+
}
123129

124-
if (not valid_options(opts))
130+
if (not valid_options(opts)) {
131+
debug("Invalid options\n");
125132
return;
133+
}
126134

127135
const auto cid = get_client_id(msg->chaddr, opts);
128-
if (cid.empty() or std::all_of(cid.begin(), cid.end(), [] (int i) { return i == 0; }))
136+
if (cid.empty() or std::all_of(cid.begin(), cid.end(), [] (int i) { return i == 0; })) {
137+
debug("Invalid client id\n");
129138
return;
139+
}
130140

131-
if (msg->magic[0] not_eq 99 or msg->magic[1] not_eq 130 or msg->magic[2] not_eq 83 or msg->magic[3] not_eq 99)
141+
if (msg->magic[0] not_eq 99 or msg->magic[1] not_eq 130 or msg->magic[2] not_eq 83 or msg->magic[3] not_eq 99) {
142+
debug("Invalid magic\n");
132143
return;
144+
}
133145

134146
int ridx;
135147

136148
switch (opts->val[0]) {
137149
case DHCPDISCOVER:
150+
151+
debug("------------Discover------------\n");
152+
print(msg, opts);
153+
138154
offer(msg, opts);
139155
break;
140156
case DHCPREQUEST:
157+
158+
debug("-------------Request--------------\n");
159+
print(msg, opts);
160+
141161
handle_request(msg, opts);
142162
break;
143163
case DHCPDECLINE:
164+
165+
debug("-------------Decline--------------\n");
166+
print(msg, opts);
167+
144168
// A client has discovered that the suggested network address is already in use.
145169
// The server must mark the network address as not available and should notify the network admin
146170
// of a possible configuration problem - TODO
@@ -151,6 +175,10 @@ void DHCPD::resolve(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
151175
update_pool(get_requested_ip_in_opts(opts), Status::IN_USE); // In use - possible config problem
152176
break;
153177
case DHCPRELEASE:
178+
179+
debug("--------------Release--------------\n");
180+
print(msg, opts);
181+
154182
// Mark the network address as not allocated anymore
155183
// Should retain a record of the client's initialization parameters for possible reuse
156184
// in response to subsequent requests from the client
@@ -168,6 +196,10 @@ void DHCPD::resolve(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
168196
// update_pool(msg->ciaddr, Status::RELEASED);
169197

170198
case DHCPINFORM:
199+
200+
debug("---------------Inform---------------\n");
201+
print(msg, opts);
202+
171203
inform_ack(msg);
172204
break;
173205
}
@@ -186,8 +218,14 @@ void DHCPD::handle_request(const dhcp_packet_t* msg, const dhcp_option_t* opts)
186218
IP4::addr sid{opt->val[0], opt->val[1], opt->val[2], opt->val[3]};
187219

188220
if (sid not_eq server_id()) { // The client has not chosen this server
221+
222+
debug("Client hasn't chosen this server - returning\n");
223+
189224
int ridx = get_record_idx(get_client_id(msg->chaddr, opts));
190225
if (ridx != -1) {
226+
227+
debug("Freeing up record\n");
228+
191229
// Free up the IP address - the client has declined our offer
192230
update_pool(records_.at(ridx).ip(), Status::AVAILABLE);
193231
records_.erase(records_.begin() + ridx);
@@ -197,6 +235,8 @@ void DHCPD::handle_request(const dhcp_packet_t* msg, const dhcp_option_t* opts)
197235

198236
// Server identifier == this server's ID
199237

238+
debug("Client has chosen this server\n");
239+
200240
int ridx = get_record_idx(get_client_id(msg->chaddr, opts));
201241

202242
if (ridx not_eq -1) { // A record for this client already exists
@@ -214,18 +254,24 @@ void DHCPD::handle_request(const dhcp_packet_t* msg, const dhcp_option_t* opts)
214254
return;
215255
}
216256

257+
debug("ciaddr not zero or not correct requested ip - sending nak\n");
258+
217259
// Else ciaddr is not zero or record's ip is not the same as the requested ip in the request
218260
// TODO: nak() or silent return?
219261
nak(msg);
220262
return;
221263
}
222264

265+
debug("No record of this client exists - sending nak\n");
266+
223267
// Else a record with this client id doesn't exist
224268
// TODO: nak() or silent return?
225269
nak(msg);
226270
return;
227271
}
228272

273+
debug("Verifying or extending lease\n");
274+
229275
// Else server identifier is not filled in and this is not a response to a DHCPOFFER message, but
230276
// a request to verify or extend an existing lease
231277
verify_or_extend_lease(msg, opts);
@@ -244,13 +290,18 @@ void DHCPD::verify_or_extend_lease(const dhcp_packet_t* msg, const dhcp_option_t
244290
// Then the client is seeking to verify a previously allocated, cached configuration
245291
// Client state: INIT-REBOOT
246292

293+
debug("Init-reboot\n");
294+
247295
// 1. (Before or in the if statement) Check if on correct network
248296
// Server should send a DHCPNAK if the client is on the wrong network
249297
// If the server detects that the client is on the wrong net (i.e., the result of applying the local
250298
// subnet mask or remote subnet mask (if giaddr is not zero) to requested IP address value doesn't
251299
// match reality), then the server should send a DHCPNAK message to the client.
252300
// 2. (After or in the if statement) If client is on correct network: Check if the client's notion of IP is correct
253301
if ((not on_correct_network(msg->giaddr, opts)) or (get_requested_ip_in_opts(opts) not_eq records_.at(ridx).ip())) {
302+
303+
debug("Client not on correct network\n");
304+
254305
// Updating pool and erasing record
255306
update_pool(records_.at(ridx).ip(), Status::AVAILABLE);
256307
records_.erase(records_.begin() + ridx);
@@ -288,6 +339,8 @@ void DHCPD::verify_or_extend_lease(const dhcp_packet_t* msg, const dhcp_option_t
288339

289340
// Table 4 page 33 in RFC 2131 - Fields in client message from client in different state
290341

342+
debug("Renewing or rebinding state\n");
343+
291344
// Extend the lease or not - should send a DHCPACK regardless
292345
// Update record and pool
293346
auto& record = records_.at(ridx);
@@ -329,6 +382,9 @@ void DHCPD::offer(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
329382
bool ok = false;
330383
for (auto& entry : pool_) {
331384
if (entry.second == Status::AVAILABLE) {
385+
386+
debug("Found available IP: %s\n", entry.first.to_string().c_str());
387+
332388
entry.second = Status::OFFERED;
333389
offer->yiaddr = entry.first;
334390
ok = true;
@@ -348,6 +404,9 @@ void DHCPD::offer(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
348404
}
349405
}
350406
if (not ok) { // Then no IP is available - sending DHCPNAK
407+
408+
debug("No more available IPs - clearing offered ips and sending nak\n");
409+
351410
// Clear offered ips that have not been confirmed - Maybe use pending value instead
352411
clear_offered_ips();
353412
nak(msg); // Record has not been added to the records_ vector so OK
@@ -461,6 +520,8 @@ void DHCPD::offer(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
461520
// RECORD
462521
add_record(record);
463522

523+
debug("Sending offer\n");
524+
464525
// If the giaddr field in a DHCP message from a client is non-zero, the server sends any return
465526
// messages to the DHCP server port on the BOOTP relay agent whose address appears in giaddr
466527
if (msg->giaddr != IP4::addr{0}) {
@@ -533,6 +594,8 @@ void DHCPD::inform_ack(const dhcp_packet_t* msg) {
533594
ack_opts->length = 1;
534595
ack_opts->val[0] = DHCPACK;
535596

597+
debug("Sending inform ack\n");
598+
536599
// TODO Add options requested by the client
537600

538601
// Send the DHCPACK - Unicast to DHCPINFORM message's ciaddr field
@@ -609,6 +672,8 @@ void DHCPD::request_ack(const dhcp_packet_t* msg, const dhcp_option_t* opts) {
609672
ack_opts->code = DHO_END;
610673
ack_opts->length = 0;
611674

675+
debug("Sending request ack\n");
676+
612677
// If the giaddr field in a DHCP message from a client is non-zero, the server sends any return
613678
// messages to the DHCP server port on the BOOTP relay agent whose address appears in giaddr
614679
if (msg->giaddr != IP4::addr{0}) {
@@ -681,6 +746,8 @@ void DHCPD::nak(const dhcp_packet_t* msg) {
681746
nak_opts->code = DHO_END;
682747
nak_opts->length = 0;
683748

749+
debug("Sending NAK\n");
750+
684751
// Send the DHCPNAK - Broadcast
685752
socket_.bcast(server_id_, DHCP_CLIENT_PORT, packet, PACKET_SIZE);
686753
}
@@ -769,10 +836,17 @@ void DHCPD::clear_offered_ip(IP4::addr ip) {
769836
}
770837

771838
void DHCPD::clear_offered_ips() {
839+
// looping through pool
840+
for (auto& entry : pool_) {
841+
if (entry.second == Status::OFFERED)
842+
entry.second = Status::AVAILABLE;
843+
}
844+
845+
// and records
772846
for (size_t i = 0; i < records_.size(); i++) {
773847
if (records_.at(i).status() == Status::OFFERED) {
774848
// Update pool
775-
update_pool(records_.at(i).ip(), Status::AVAILABLE);
849+
// update_pool(records_.at(i).ip(), Status::AVAILABLE);
776850
// And erase record
777851
records_.erase(records_.begin() + i);
778852
}

0 commit comments

Comments
 (0)