@@ -112,35 +112,59 @@ void DHCPD::listen() {
112112}
113113
114114void 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
771838void 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