Fix the return values of dhcp_packet_get and arp_packet_get.
This corrects a bug where stale dhcp packets would get reprocessed, causing very bad behavior; an issue that was introduced in the coroutine conversion.
This commit is contained in:
		
							
								
								
									
										12
									
								
								src/arp.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/arp.c
									
									
									
									
									
								
							| @@ -674,14 +674,14 @@ server_is_router: | ||||
|     return ARPR_OK; | ||||
| } | ||||
|  | ||||
| int arp_packet_get(struct client_state_t cs[static 1]) | ||||
| bool arp_packet_get(struct client_state_t cs[static 1]) | ||||
| { | ||||
|     ssize_t r = 0; | ||||
|     if (garp.reply_offset < sizeof garp.reply) { | ||||
|         r = safe_read(cs->arpFd, (char *)&garp.reply + garp.reply_offset, | ||||
|                       sizeof garp.reply - garp.reply_offset); | ||||
|         if (r == 0) | ||||
|             return ARPP_NONE; | ||||
|             return false; | ||||
|         if (r < 0) { | ||||
|             log_error("%s: (%s) ARP response read failed: %s", | ||||
|                       client_config.interface, __func__, strerror(errno)); | ||||
| @@ -690,13 +690,13 @@ int arp_packet_get(struct client_state_t cs[static 1]) | ||||
|             if (arp_open_fd(cs, cs->arp_is_defense) < 0) | ||||
|                 suicide("%s: (%s) Failed to reopen ARP fd: %s", | ||||
|                         client_config.interface, __func__, strerror(errno)); | ||||
|             return ARPP_NONE; | ||||
|             return false; | ||||
|         } | ||||
|         garp.reply_offset += (size_t)r; | ||||
|     } | ||||
|  | ||||
|     if (garp.reply_offset < ARP_MSG_SIZE) | ||||
|         return ARPP_NONE; | ||||
|         return false; | ||||
|  | ||||
|     // Emulate the BPF filters if they are not in use. | ||||
|     if (!garp.using_bpf && | ||||
| @@ -704,9 +704,9 @@ int arp_packet_get(struct client_state_t cs[static 1]) | ||||
|          (cs->arp_is_defense && | ||||
|           !arp_validate_bpf_defense(cs, &garp.reply)))) { | ||||
|         arp_reply_clear(); | ||||
|         return ARPP_NONE; | ||||
|         return false; | ||||
|     } | ||||
|     return ARPP_HAVE; | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| // XXX: Move into client_state | ||||
|   | ||||
| @@ -104,7 +104,7 @@ struct arp_data { | ||||
|  | ||||
| void arp_reply_clear(void); | ||||
|  | ||||
| int arp_packet_get(struct client_state_t cs[static 1]); | ||||
| bool arp_packet_get(struct client_state_t cs[static 1]); | ||||
|  | ||||
| void set_arp_relentless_def(bool v); | ||||
| void arp_reset_send_stats(void); | ||||
| @@ -134,11 +134,6 @@ int arp_gw_check_timeout(struct client_state_t cs[static 1], long long nowts); | ||||
| #define ARPR_FAIL -2 | ||||
|  | ||||
|  | ||||
| // There is no new packet. | ||||
| #define ARPP_NONE 0 | ||||
| // We have a pending packet. | ||||
| #define ARPP_HAVE 1 | ||||
|  | ||||
| long long arp_get_wake_ts(void); | ||||
|  | ||||
| #endif /* ARP_H_ */ | ||||
|   | ||||
							
								
								
									
										16
									
								
								src/dhcp.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/dhcp.c
									
									
									
									
									
								
							| @@ -380,13 +380,13 @@ static int validate_dhcp_packet(struct client_state_t cs[static 1], | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| int dhcp_packet_get(struct client_state_t cs[static 1], | ||||
|                     struct dhcpmsg packet[static 1], | ||||
|                     uint8_t msgtype[static 1], | ||||
|                     uint32_t srcaddr[static 1]) | ||||
| bool dhcp_packet_get(struct client_state_t cs[static 1], | ||||
|                      struct dhcpmsg packet[static 1], | ||||
|                      uint8_t msgtype[static 1], | ||||
|                      uint32_t srcaddr[static 1]) | ||||
| { | ||||
|     if (cs->listenFd < 0) | ||||
|         return -1; | ||||
|         return false; | ||||
|     ssize_t r = get_raw_packet(cs, packet, srcaddr); | ||||
|     if (r < 0) { | ||||
|         // Not a transient issue handled by packet collection functions. | ||||
| @@ -396,11 +396,11 @@ int dhcp_packet_get(struct client_state_t cs[static 1], | ||||
|             stop_dhcp_listen(cs); | ||||
|             start_dhcp_listen(cs); | ||||
|         } | ||||
|         return -1; | ||||
|         return false; | ||||
|     } | ||||
|     if (!validate_dhcp_packet(cs, (size_t)r, packet, msgtype)) | ||||
|         return -1; | ||||
|     return 0; | ||||
|         return false; | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| // Initialize a DHCP client packet that will be sent to a server | ||||
|   | ||||
| @@ -83,10 +83,10 @@ struct udp_dhcp_packet { | ||||
|  | ||||
| void start_dhcp_listen(struct client_state_t cs[static 1]); | ||||
| void stop_dhcp_listen(struct client_state_t cs[static 1]); | ||||
| int dhcp_packet_get(struct client_state_t cs[static 1], | ||||
|                     struct dhcpmsg packet[static 1], | ||||
|                     uint8_t msgtype[static 1], | ||||
|                     uint32_t srcaddr[static 1]); | ||||
| bool dhcp_packet_get(struct client_state_t cs[static 1], | ||||
|                      struct dhcpmsg packet[static 1], | ||||
|                      uint8_t msgtype[static 1], | ||||
|                      uint32_t srcaddr[static 1]); | ||||
| ssize_t send_discover(struct client_state_t cs[static 1]); | ||||
| ssize_t send_selecting(struct client_state_t cs[static 1]); | ||||
| ssize_t send_renew(struct client_state_t cs[static 1]); | ||||
|   | ||||
| @@ -292,10 +292,10 @@ static void do_ndhc_work(void) | ||||
|             else | ||||
|                 suicide("epoll_wait failed"); | ||||
|         } | ||||
|         int sev_dhcp = -1; | ||||
|         bool sev_dhcp = false; | ||||
|         uint32_t dhcp_srcaddr; | ||||
|         uint8_t dhcp_msgtype; | ||||
|         int sev_arp = ARPP_NONE; | ||||
|         bool sev_arp = false; | ||||
|         int sev_nl = IFS_NONE; | ||||
|         int sev_rfk = RFK_NONE; | ||||
|         int sev_signal = SIGNAL_NONE; | ||||
|   | ||||
| @@ -437,8 +437,8 @@ static int ifup_action(struct client_state_t cs[static 1]) | ||||
|  | ||||
| // XXX: Should be re-entrant so as to handle multiple servers. | ||||
| int dhcp_handle(struct client_state_t cs[static 1], long long nowts, | ||||
|                 int sev_dhcp, struct dhcpmsg dhcp_packet[static 1], | ||||
|                 uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, int sev_arp, | ||||
|                 bool sev_dhcp, struct dhcpmsg dhcp_packet[static 1], | ||||
|                 uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, bool sev_arp, | ||||
|                 bool force_fingerprint, bool dhcp_timeout, bool arp_timeout, | ||||
|                 int sev_signal) | ||||
| { | ||||
|   | ||||
| @@ -41,8 +41,8 @@ enum { | ||||
| }; | ||||
|  | ||||
| int dhcp_handle(struct client_state_t cs[static 1], long long nowts, | ||||
|                 int sev_dhcp, struct dhcpmsg dhcp_packet[static 1], | ||||
|                 uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, int sev_arp, | ||||
|                 bool sev_dhcp, struct dhcpmsg dhcp_packet[static 1], | ||||
|                 uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, bool sev_arp, | ||||
|                 bool force_fingerprint, bool dhcp_timeout, bool arp_timeout, | ||||
|                 int sev_signal); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user