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:
Nicholas J. Kain 2015-02-18 11:02:13 -05:00
parent a627e9dc9c
commit b3bd13d45f
7 changed files with 25 additions and 30 deletions

View File

@ -674,14 +674,14 @@ server_is_router:
return ARPR_OK; 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; ssize_t r = 0;
if (garp.reply_offset < sizeof garp.reply) { if (garp.reply_offset < sizeof garp.reply) {
r = safe_read(cs->arpFd, (char *)&garp.reply + garp.reply_offset, r = safe_read(cs->arpFd, (char *)&garp.reply + garp.reply_offset,
sizeof garp.reply - garp.reply_offset); sizeof garp.reply - garp.reply_offset);
if (r == 0) if (r == 0)
return ARPP_NONE; return false;
if (r < 0) { if (r < 0) {
log_error("%s: (%s) ARP response read failed: %s", log_error("%s: (%s) ARP response read failed: %s",
client_config.interface, __func__, strerror(errno)); 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) if (arp_open_fd(cs, cs->arp_is_defense) < 0)
suicide("%s: (%s) Failed to reopen ARP fd: %s", suicide("%s: (%s) Failed to reopen ARP fd: %s",
client_config.interface, __func__, strerror(errno)); client_config.interface, __func__, strerror(errno));
return ARPP_NONE; return false;
} }
garp.reply_offset += (size_t)r; garp.reply_offset += (size_t)r;
} }
if (garp.reply_offset < ARP_MSG_SIZE) if (garp.reply_offset < ARP_MSG_SIZE)
return ARPP_NONE; return false;
// Emulate the BPF filters if they are not in use. // Emulate the BPF filters if they are not in use.
if (!garp.using_bpf && if (!garp.using_bpf &&
@ -704,9 +704,9 @@ int arp_packet_get(struct client_state_t cs[static 1])
(cs->arp_is_defense && (cs->arp_is_defense &&
!arp_validate_bpf_defense(cs, &garp.reply)))) { !arp_validate_bpf_defense(cs, &garp.reply)))) {
arp_reply_clear(); arp_reply_clear();
return ARPP_NONE; return false;
} }
return ARPP_HAVE; return true;
} }
// XXX: Move into client_state // XXX: Move into client_state

View File

@ -104,7 +104,7 @@ struct arp_data {
void arp_reply_clear(void); 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 set_arp_relentless_def(bool v);
void arp_reset_send_stats(void); 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 #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); long long arp_get_wake_ts(void);
#endif /* ARP_H_ */ #endif /* ARP_H_ */

View File

@ -380,13 +380,13 @@ static int validate_dhcp_packet(struct client_state_t cs[static 1],
return 1; return 1;
} }
int dhcp_packet_get(struct client_state_t cs[static 1], bool dhcp_packet_get(struct client_state_t cs[static 1],
struct dhcpmsg packet[static 1], struct dhcpmsg packet[static 1],
uint8_t msgtype[static 1], uint8_t msgtype[static 1],
uint32_t srcaddr[static 1]) uint32_t srcaddr[static 1])
{ {
if (cs->listenFd < 0) if (cs->listenFd < 0)
return -1; return false;
ssize_t r = get_raw_packet(cs, packet, srcaddr); ssize_t r = get_raw_packet(cs, packet, srcaddr);
if (r < 0) { if (r < 0) {
// Not a transient issue handled by packet collection functions. // 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); stop_dhcp_listen(cs);
start_dhcp_listen(cs); start_dhcp_listen(cs);
} }
return -1; return false;
} }
if (!validate_dhcp_packet(cs, (size_t)r, packet, msgtype)) if (!validate_dhcp_packet(cs, (size_t)r, packet, msgtype))
return -1; return false;
return 0; return true;
} }
// Initialize a DHCP client packet that will be sent to a server // Initialize a DHCP client packet that will be sent to a server

View File

@ -83,7 +83,7 @@ struct udp_dhcp_packet {
void start_dhcp_listen(struct client_state_t cs[static 1]); void start_dhcp_listen(struct client_state_t cs[static 1]);
void stop_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], bool dhcp_packet_get(struct client_state_t cs[static 1],
struct dhcpmsg packet[static 1], struct dhcpmsg packet[static 1],
uint8_t msgtype[static 1], uint8_t msgtype[static 1],
uint32_t srcaddr[static 1]); uint32_t srcaddr[static 1]);

View File

@ -292,10 +292,10 @@ static void do_ndhc_work(void)
else else
suicide("epoll_wait failed"); suicide("epoll_wait failed");
} }
int sev_dhcp = -1; bool sev_dhcp = false;
uint32_t dhcp_srcaddr; uint32_t dhcp_srcaddr;
uint8_t dhcp_msgtype; uint8_t dhcp_msgtype;
int sev_arp = ARPP_NONE; bool sev_arp = false;
int sev_nl = IFS_NONE; int sev_nl = IFS_NONE;
int sev_rfk = RFK_NONE; int sev_rfk = RFK_NONE;
int sev_signal = SIGNAL_NONE; int sev_signal = SIGNAL_NONE;

View File

@ -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. // 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 dhcp_handle(struct client_state_t cs[static 1], long long nowts,
int sev_dhcp, struct dhcpmsg dhcp_packet[static 1], bool sev_dhcp, struct dhcpmsg dhcp_packet[static 1],
uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, int sev_arp, uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, bool sev_arp,
bool force_fingerprint, bool dhcp_timeout, bool arp_timeout, bool force_fingerprint, bool dhcp_timeout, bool arp_timeout,
int sev_signal) int sev_signal)
{ {

View File

@ -41,8 +41,8 @@ enum {
}; };
int dhcp_handle(struct client_state_t cs[static 1], long long nowts, int dhcp_handle(struct client_state_t cs[static 1], long long nowts,
int sev_dhcp, struct dhcpmsg dhcp_packet[static 1], bool sev_dhcp, struct dhcpmsg dhcp_packet[static 1],
uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, int sev_arp, uint8_t dhcp_msgtype, uint32_t dhcp_srcaddr, bool sev_arp,
bool force_fingerprint, bool dhcp_timeout, bool arp_timeout, bool force_fingerprint, bool dhcp_timeout, bool arp_timeout,
int sev_signal); int sev_signal);