From e2ee7289824cb13f30af29598d16fe7335327b08 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Sun, 6 Apr 2014 22:12:31 -0400 Subject: [PATCH] Consolidate all of the global static variables in arp.c into a single struct, and use booleans where appropriate. --- src/arp.c | 300 ++++++++++++++++++++++++++++------------------------- src/arp.h | 2 +- src/ndhc.c | 2 +- 3 files changed, 160 insertions(+), 144 deletions(-) diff --git a/src/arp.c b/src/arp.c index 8e65ce8..c2168cc 100644 --- a/src/arp.c +++ b/src/arp.c @@ -61,7 +61,6 @@ int arp_probe_max = 2000; // maximum delay until repeated probe (ms) #define RATE_LIMIT_INTERVAL 60000 // delay between successive attempts #define DEFEND_INTERVAL 10000 // minimum interval between defensive ARPs - typedef enum { AS_NONE = 0, // Nothing to react to wrt ARP AS_COLLISION_CHECK, // Checking to see if another host has our IP before @@ -73,8 +72,6 @@ typedef enum { AS_MAX, } arp_state_t; -static long long arp_wake_ts[AS_MAX] = { -1, -1, -1, -1, -1 }; - typedef enum { ASEND_COLLISION_CHECK, ASEND_GW_PING, @@ -82,45 +79,62 @@ typedef enum { ASEND_MAX, } arp_send_t; -static arp_state_t arpState; struct arp_stats { long long ts; int count; }; -static struct arp_stats arp_send_stats[ASEND_MAX]; -static int using_arp_bpf; // Is a BPF installed on the ARP socket? -int arp_relentless_def; // Don't give up defense no matter what. -static long long last_conflict_ts; // TS of the last conflicting ARP seen. +struct arp_data { + struct dhcpmsg dhcp_packet; // Used only for AS_COLLISION_CHECK + struct arpMsg reply; + struct arp_stats send_stats[ASEND_MAX]; + long long wake_ts[AS_MAX]; + long long last_conflict_ts; // TS of the last conflicting ARP seen. + long long arp_check_start_ts; // TS of when we started the + // AS_COLLISION_CHECK state. + size_t reply_offset; + arp_state_t state; + unsigned int total_conflicts; // Total number of address conflicts on + // the interface. Never decreases. + int gw_check_initpings; // Initial count of ASEND_GW_PING when + // AS_GW_CHECK was entered. + uint16_t probe_wait_time; // Time to wait for a COLLISION_CHECK reply + // (in ms?). + bool using_bpf:1; // Is a BPF installed on the ARP socket? + bool relentless_def:1; // Don't give up defense no matter what. + bool router_replied:1; + bool server_replied:1; +}; -static int gw_check_init_pingcount; // Initial count of ASEND_GW_PING when - // AS_GW_CHECK was entered. +static struct arp_data garp = { + .state = AS_NONE, + .wake_ts = { -1, -1, -1, -1, -1 }, + .send_stats = {{0},{0},{0}}, + .last_conflict_ts = 0, + .gw_check_initpings = 0, + .arp_check_start_ts = 0, + .total_conflicts = 0, + .probe_wait_time = 0, + .reply_offset = 0, + .using_bpf = false, + .relentless_def = false, + .router_replied = false, + .server_replied = false, +}; -static uint16_t probe_wait_time; // Time to wait for a COLLISION_CHECK reply. -static long long arp_check_start_ts; // TS of when we started the - // AS_COLLISION_CHECK state. +void set_arp_relentless_def(void) { garp.relentless_def = true; } -static unsigned int total_conflicts; // Total number of address conflicts on - // the interface. Never decreases. - -static struct dhcpmsg arp_dhcp_packet; // Used only for AS_COLLISION_CHECK - -static char arp_router_has_replied; -static char arp_server_has_replied; - -static struct arpMsg arpreply; -static size_t arpreply_offset; -static void arpreply_clear(void) +static void arp_reply_clear(void) { - memset(&arpreply, 0, sizeof arpreply); - arpreply_offset = 0; + memset(&garp.reply, 0, sizeof garp.reply); + garp.reply_offset = 0; } void arp_reset_send_stats(void) { for (int i = 0; i < ASEND_MAX; ++i) { - arp_send_stats[i].ts = 0; - arp_send_stats[i].count = 0; + garp.send_stats[i].ts = 0; + garp.send_stats[i].count = 0; } } @@ -129,8 +143,8 @@ static int get_arp_basic_socket(void) char resp; int fd = request_sockd_fd("a", 1, &resp); switch (resp) { - case 'A': using_arp_bpf = 1; break; - case 'a': using_arp_bpf = 0; break; + case 'A': garp.using_bpf = true; break; + case 'a': garp.using_bpf = false; break; default: suicide("%s: (%s) expected a or A sockd reply but got %c", client_config.interface, __func__, resp); } @@ -150,8 +164,8 @@ static int get_arp_defense_socket(struct client_state_t *cs) char resp; int fd = request_sockd_fd(buf, buflen, &resp); switch (resp) { - case 'D': using_arp_bpf = 1; break; - case 'd': using_arp_bpf = 0; break; + case 'D': garp.using_bpf = true; break; + case 'd': garp.using_bpf = false; break; default: suicide("%s: (%s) expected d or D sockd reply but got %c", client_config.interface, __func__, resp); } @@ -180,7 +194,7 @@ static int arp_open_fd(struct client_state_t *cs, arp_state_t state) return -1; } epoll_add(cs->epollFd, cs->arpFd); - arpreply_clear(); + arp_reply_clear(); return 0; } @@ -191,38 +205,38 @@ static void arp_min_close_fd(struct client_state_t *cs) epoll_del(cs->epollFd, cs->arpFd); close(cs->arpFd); cs->arpFd = -1; - arpState = AS_NONE; + garp.state = AS_NONE; } static void arp_switch_state(struct client_state_t *cs, arp_state_t state) { - if (arpState == state || arpState >= AS_MAX) + if (garp.state == state || garp.state >= AS_MAX) return; if (state == AS_NONE) { arp_close_fd(cs); return; } - bool force_reopen = state == AS_DEFENSE || arpState == AS_DEFENSE; + bool force_reopen = state == AS_DEFENSE || garp.state == AS_DEFENSE; if (force_reopen) arp_min_close_fd(cs); if (cs->arpFd < 0 || force_reopen) { if (arp_open_fd(cs, state) < 0) suicide("arp: Failed to open arpFd when changing state %u -> %u", - arpState, state); + garp.state, state); } - arpState = state; + garp.state = state; } void arp_close_fd(struct client_state_t *cs) { arp_min_close_fd(cs); for (int i = 0; i < AS_MAX; ++i) - arp_wake_ts[i] = -1; + garp.wake_ts[i] = -1; } static void arp_reopen_fd(struct client_state_t *cs) { - arp_state_t prev_state = arpState; + arp_state_t prev_state = garp.state; arp_min_close_fd(cs); arp_switch_state(cs, prev_state); } @@ -270,8 +284,8 @@ static int arp_ping(struct client_state_t *cs, uint32_t test_ip) memcpy(arp.dip4, &test_ip, sizeof test_ip); if (arp_send(cs, &arp) < 0) return -1; - arp_send_stats[ASEND_GW_PING].count++; - arp_send_stats[ASEND_GW_PING].ts = curms(); + garp.send_stats[ASEND_GW_PING].count++; + garp.send_stats[ASEND_GW_PING].ts = curms(); return 0; } @@ -283,8 +297,8 @@ static int arp_ip_anon_ping(struct client_state_t *cs, uint32_t test_ip) log_line("arp: Probing for hosts that may conflict with our lease..."); if (arp_send(cs, &arp) < 0) return -1; - arp_send_stats[ASEND_COLLISION_CHECK].count++; - arp_send_stats[ASEND_COLLISION_CHECK].ts = curms(); + garp.send_stats[ASEND_COLLISION_CHECK].count++; + garp.send_stats[ASEND_COLLISION_CHECK].ts = curms(); return 0; } @@ -295,8 +309,8 @@ static int arp_announcement(struct client_state_t *cs) memcpy(arp.dip4, &cs->clientAddr, 4); if (arp_send(cs, &arp) < 0) return -1; - arp_send_stats[ASEND_ANNOUNCE].count++; - arp_send_stats[ASEND_ANNOUNCE].ts = curms(); + garp.send_stats[ASEND_ANNOUNCE].count++; + garp.send_stats[ASEND_ANNOUNCE].ts = curms(); return 0; } #undef BASE_ARPMSG @@ -304,38 +318,39 @@ static int arp_announcement(struct client_state_t *cs) // Callable from DS_REQUESTING, DS_RENEWING, or DS_REBINDING via an_packet() int arp_check(struct client_state_t *cs, struct dhcpmsg *packet) { - memcpy(&arp_dhcp_packet, packet, sizeof (struct dhcpmsg)); + memcpy(&garp.dhcp_packet, packet, sizeof (struct dhcpmsg)); arp_switch_state(cs, AS_COLLISION_CHECK); - if (arp_ip_anon_ping(cs, arp_dhcp_packet.yiaddr) < 0) + if (arp_ip_anon_ping(cs, garp.dhcp_packet.yiaddr) < 0) return -1; cs->arpPrevState = cs->dhcpState; cs->dhcpState = DS_COLLISION_CHECK; - arp_check_start_ts = arp_send_stats[ASEND_COLLISION_CHECK].ts; - probe_wait_time = arp_probe_wait; - arp_wake_ts[AS_COLLISION_CHECK] = arp_check_start_ts + probe_wait_time; + garp.arp_check_start_ts = garp.send_stats[ASEND_COLLISION_CHECK].ts; + garp.probe_wait_time = arp_probe_wait; + garp.wake_ts[AS_COLLISION_CHECK] = garp.arp_check_start_ts + + garp.probe_wait_time; return 0; } // Callable only from DS_BOUND via state.c:ifup_action(). int arp_gw_check(struct client_state_t *cs) { - if (arpState == AS_GW_CHECK) // Guard against state bounce. + if (garp.state == AS_GW_CHECK) // Guard against state bounce. return 0; - gw_check_init_pingcount = arp_send_stats[ASEND_GW_PING].count; - arp_server_has_replied = 0; + garp.gw_check_initpings = garp.send_stats[ASEND_GW_PING].count; + garp.server_replied = false; if (arp_ping(cs, cs->serverAddr) < 0) return -1; if (cs->routerAddr) { - arp_router_has_replied = 0; + garp.router_replied = false; if (arp_ping(cs, cs->routerAddr) < 0) return -1; } else - arp_router_has_replied = 1; + garp.router_replied = true; arp_switch_state(cs, AS_GW_CHECK); cs->arpPrevState = cs->dhcpState; cs->dhcpState = DS_BOUND_GW_CHECK; - arp_wake_ts[AS_GW_CHECK] = - arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY + 250; + garp.wake_ts[AS_GW_CHECK] = + garp.send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY + 250; return 0; } @@ -358,32 +373,32 @@ static int arp_get_gw_hwaddr(struct client_state_t *cs) return -1; } else cs->got_router_arp = 1; - arp_wake_ts[AS_GW_QUERY] = - arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY + 250; + garp.wake_ts[AS_GW_QUERY] = + garp.send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY + 250; return 0; } static void arp_failed(struct client_state_t *cs) { log_line("arp: Offered address is in use. Declining."); - send_decline(cs, arp_dhcp_packet.yiaddr); - arp_wake_ts[AS_COLLISION_CHECK] = -1; - reinit_selecting(cs, total_conflicts < MAX_CONFLICTS ? + send_decline(cs, garp.dhcp_packet.yiaddr); + garp.wake_ts[AS_COLLISION_CHECK] = -1; + reinit_selecting(cs, garp.total_conflicts < MAX_CONFLICTS ? 0 : RATE_LIMIT_INTERVAL); } static void arp_gw_failed(struct client_state_t *cs) { - arp_wake_ts[AS_GW_CHECK] = -1; + garp.wake_ts[AS_GW_CHECK] = -1; reinit_selecting(cs, 0); } static int act_if_arp_gw_failed(struct client_state_t *cs) { - if (arp_send_stats[ASEND_GW_PING].count >= gw_check_init_pingcount + 6) { - if (arp_router_has_replied && !arp_server_has_replied) + if (garp.send_stats[ASEND_GW_PING].count >= garp.gw_check_initpings + 6) { + if (garp.router_replied && !garp.server_replied) log_line("arp: DHCP server didn't reply. Getting new lease."); - else if (!arp_router_has_replied && arp_server_has_replied) + else if (!garp.router_replied && garp.server_replied) log_line("arp: Gateway didn't reply. Getting new lease."); else log_line("arp: DHCP server and gateway didn't reply. Getting new lease."); @@ -401,20 +416,20 @@ void arp_set_defense_mode(struct client_state_t *cs) void arp_success(struct client_state_t *cs) { char clibuf[INET_ADDRSTRLEN]; - struct in_addr temp_addr = {.s_addr = arp_dhcp_packet.yiaddr}; + struct in_addr temp_addr = {.s_addr = garp.dhcp_packet.yiaddr}; inet_ntop(AF_INET, &temp_addr, clibuf, sizeof clibuf); log_line("Lease of %s obtained. Lease time is %ld seconds.", clibuf, cs->lease); - cs->clientAddr = arp_dhcp_packet.yiaddr; + cs->clientAddr = garp.dhcp_packet.yiaddr; cs->dhcpState = DS_BOUND; cs->init = 0; - last_conflict_ts = 0; - arp_wake_ts[AS_COLLISION_CHECK] = -1; - ifchange_bind(cs, &arp_dhcp_packet); + garp.last_conflict_ts = 0; + garp.wake_ts[AS_COLLISION_CHECK] = -1; + ifchange_bind(cs, &garp.dhcp_packet); if (cs->arpPrevState == DS_RENEWING || cs->arpPrevState == DS_REBINDING) { arp_switch_state(cs, AS_DEFENSE); } else { - cs->routerAddr = get_option_router(&arp_dhcp_packet); + cs->routerAddr = get_option_router(&garp.dhcp_packet); arp_get_gw_hwaddr(cs); } set_listen_none(cs); @@ -432,7 +447,7 @@ static void arp_gw_success(struct client_state_t *cs) arp_switch_state(cs, AS_DEFENSE); arp_announcement(cs); - arp_wake_ts[AS_GW_CHECK] = -1; + garp.wake_ts[AS_GW_CHECK] = -1; cs->dhcpState = cs->arpPrevState; } @@ -496,10 +511,10 @@ static int arp_gen_probe_wait(struct client_state_t *cs) static void arp_defense_timeout(struct client_state_t *cs, long long nowts) { (void)nowts; // Suppress warning; parameter necessary but unused. - if (arp_wake_ts[AS_DEFENSE] != -1) { + if (garp.wake_ts[AS_DEFENSE] != -1) { log_line("arp: Defending our lease IP."); arp_announcement(cs); - arp_wake_ts[AS_DEFENSE] = -1; + garp.wake_ts[AS_DEFENSE] = -1; } } @@ -509,32 +524,32 @@ static void arp_gw_check_timeout(struct client_state_t *cs, long long nowts) if (act_if_arp_gw_failed(cs)) return; - long long rtts = arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; + long long rtts = garp.send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; if (nowts < rtts) { - arp_wake_ts[AS_GW_CHECK] = rtts; + garp.wake_ts[AS_GW_CHECK] = rtts; return; } - if (!arp_router_has_replied) { + if (!garp.router_replied) { log_line("arp: Still waiting for gateway to reply to arp ping..."); if (arp_ping(cs, cs->routerAddr) < 0) log_warning("arp: Failed to send ARP ping in retransmission."); } - if (!arp_server_has_replied) { + if (!garp.server_replied) { log_line("arp: Still waiting for DHCP server to reply to arp ping..."); if (arp_ping(cs, cs->serverAddr) < 0) log_warning("arp: Failed to send ARP ping in retransmission."); } - arp_wake_ts[AS_GW_CHECK] = - arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; + garp.wake_ts[AS_GW_CHECK] = + garp.send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; } static void arp_gw_query_timeout(struct client_state_t *cs, long long nowts) { arp_defense_timeout(cs, nowts); - long long rtts = arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; + long long rtts = garp.send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; if (nowts < rtts) { - arp_wake_ts[AS_GW_QUERY] = rtts; + garp.wake_ts[AS_GW_QUERY] = rtts; return; } if (!cs->got_router_arp) { @@ -547,30 +562,30 @@ static void arp_gw_query_timeout(struct client_state_t *cs, long long nowts) if (arp_ping(cs, cs->serverAddr) < 0) log_warning("arp: Failed to send ARP ping in retransmission."); } - arp_wake_ts[AS_GW_QUERY] = - arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; + garp.wake_ts[AS_GW_QUERY] = + garp.send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; } static void arp_collision_timeout(struct client_state_t *cs, long long nowts) { arp_defense_timeout(cs, nowts); - if (nowts >= arp_check_start_ts + ANNOUNCE_WAIT || - arp_send_stats[ASEND_COLLISION_CHECK].count >= arp_probe_num) { + if (nowts >= garp.arp_check_start_ts + ANNOUNCE_WAIT || + garp.send_stats[ASEND_COLLISION_CHECK].count >= arp_probe_num) { arp_success(cs); return; } - long long rtts = arp_send_stats[ASEND_COLLISION_CHECK].ts + - probe_wait_time; + long long rtts = garp.send_stats[ASEND_COLLISION_CHECK].ts + + garp.probe_wait_time; if (nowts < rtts) { - arp_wake_ts[AS_COLLISION_CHECK] = rtts; + garp.wake_ts[AS_COLLISION_CHECK] = rtts; return; } - if (arp_ip_anon_ping(cs, arp_dhcp_packet.yiaddr) < 0) + if (arp_ip_anon_ping(cs, garp.dhcp_packet.yiaddr) < 0) log_warning("arp: Failed to send ARP ping in retransmission."); - probe_wait_time = arp_gen_probe_wait(cs); - arp_wake_ts[AS_COLLISION_CHECK] = - arp_send_stats[ASEND_COLLISION_CHECK].ts + probe_wait_time; + garp.probe_wait_time = arp_gen_probe_wait(cs); + garp.wake_ts[AS_COLLISION_CHECK] = + garp.send_stats[ASEND_COLLISION_CHECK].ts + garp.probe_wait_time; } static void arp_do_defense(struct client_state_t *cs) @@ -578,43 +593,43 @@ static void arp_do_defense(struct client_state_t *cs) // Even though the BPF will usually catch this case, sometimes there are // packets still in the socket buffer that arrived before the defense // BPF was installed, so it's necessary to check here. - if (!arp_validate_bpf_defense(cs, &arpreply)) + if (!arp_validate_bpf_defense(cs, &garp.reply)) return; log_line("arp: Detected a peer attempting to use our IP!"); long long nowts = curms(); - arp_wake_ts[AS_DEFENSE] = -1; - if (!last_conflict_ts || - nowts - last_conflict_ts < DEFEND_INTERVAL) { + garp.wake_ts[AS_DEFENSE] = -1; + if (!garp.last_conflict_ts || + nowts - garp.last_conflict_ts < DEFEND_INTERVAL) { log_line("arp: Defending our lease IP."); arp_announcement(cs); - } else if (!arp_relentless_def) { + } else if (!garp.relentless_def) { log_line("arp: Conflicting peer is persistent. Requesting new lease."); send_release(cs); reinit_selecting(cs, 0); } else { - arp_wake_ts[AS_DEFENSE] = - arp_send_stats[ASEND_ANNOUNCE].ts + DEFEND_INTERVAL; + garp.wake_ts[AS_DEFENSE] = + garp.send_stats[ASEND_ANNOUNCE].ts + DEFEND_INTERVAL; } - total_conflicts++; - last_conflict_ts = nowts; + garp.total_conflicts++; + garp.last_conflict_ts = nowts; } static void arp_do_gw_query_done(struct client_state_t *cs) { - arp_wake_ts[AS_GW_QUERY] = -1; + garp.wake_ts[AS_GW_QUERY] = -1; arp_switch_state(cs, AS_DEFENSE); arp_announcement(cs); // Do a second announcement. } static void arp_do_gw_query(struct client_state_t *cs) { - if (!arp_is_query_reply(&arpreply)) { + if (!arp_is_query_reply(&garp.reply)) { arp_do_defense(cs); return; } - if (!memcmp(arpreply.sip4, &cs->routerAddr, 4)) { - memcpy(cs->routerArp, arpreply.smac, 6); + if (!memcmp(garp.reply.sip4, &cs->routerAddr, 4)) { + memcpy(cs->routerArp, garp.reply.smac, 6); log_line("arp: Gateway hardware address %02x:%02x:%02x:%02x:%02x:%02x", cs->routerArp[0], cs->routerArp[1], cs->routerArp[2], cs->routerArp[3], @@ -626,9 +641,9 @@ static void arp_do_gw_query(struct client_state_t *cs) arp_do_gw_query_done(cs); return; } - if (!memcmp(arpreply.sip4, &cs->serverAddr, 4)) { + if (!memcmp(garp.reply.sip4, &cs->serverAddr, 4)) { server_is_router: - memcpy(cs->serverArp, arpreply.smac, 6); + memcpy(cs->serverArp, garp.reply.smac, 6); log_line("arp: DHCP Server hardware address %02x:%02x:%02x:%02x:%02x:%02x", cs->serverArp[0], cs->serverArp[1], cs->serverArp[2], cs->serverArp[3], @@ -643,29 +658,29 @@ server_is_router: static void arp_do_collision_check(struct client_state_t *cs) { - if (!arp_is_query_reply(&arpreply)) + if (!arp_is_query_reply(&garp.reply)) return; // If this packet was sent from our lease IP, and does not have a // MAC address matching our own (the latter check guards against stupid // hubs or repeaters), then it's a conflict and thus a failure. - if (!memcmp(arpreply.sip4, &arp_dhcp_packet.yiaddr, 4) && - !memcmp(client_config.arp, arpreply.smac, 6)) { - total_conflicts++; + if (!memcmp(garp.reply.sip4, &garp.dhcp_packet.yiaddr, 4) && + !memcmp(client_config.arp, garp.reply.smac, 6)) { + garp.total_conflicts++; arp_failed(cs); } } static void arp_do_gw_check(struct client_state_t *cs) { - if (!arp_is_query_reply(&arpreply)) + if (!arp_is_query_reply(&garp.reply)) return; - if (!memcmp(arpreply.sip4, &cs->routerAddr, 4)) { + if (!memcmp(garp.reply.sip4, &cs->routerAddr, 4)) { // Success only if the router/gw MAC matches stored value - if (!memcmp(cs->routerArp, arpreply.smac, 6)) { - arp_router_has_replied = 1; + if (!memcmp(cs->routerArp, garp.reply.smac, 6)) { + garp.router_replied = true; if (cs->routerAddr == cs->serverAddr) goto server_is_router; - if (arp_server_has_replied) + if (garp.server_replied) arp_gw_success(cs); } else { log_line("arp: Gateway is different. Getting a new lease."); @@ -673,12 +688,12 @@ static void arp_do_gw_check(struct client_state_t *cs) } return; } - if (!memcmp(arpreply.sip4, &cs->serverAddr, 4)) { + if (!memcmp(garp.reply.sip4, &cs->serverAddr, 4)) { server_is_router: // Success only if the server MAC matches stored value - if (!memcmp(cs->serverArp, arpreply.smac, 6)) { - arp_server_has_replied = 1; - if (arp_router_has_replied) + if (!memcmp(cs->serverArp, garp.reply.smac, 6)) { + garp.server_replied = true; + if (garp.router_replied) arp_gw_success(cs); } else { log_line("arp: DHCP server is different. Getting a new lease."); @@ -689,7 +704,7 @@ server_is_router: static void arp_do_invalid(struct client_state_t *cs) { - log_error("handle_arp_response: called in invalid state %u", arpState); + log_error("handle_arp_response: called in invalid state %u", garp.state); arp_close_fd(cs); } @@ -710,18 +725,18 @@ static const arp_state_fn_t arp_states[] = { void handle_arp_response(struct client_state_t *cs) { ssize_t r = 0; - if (arpreply_offset < sizeof arpreply) { - r = safe_read(cs->arpFd, (char *)&arpreply + arpreply_offset, - sizeof arpreply - arpreply_offset); + 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) { log_error("arp: ARP response read failed: %s", strerror(errno)); - switch (arpState) { + switch (garp.state) { case AS_COLLISION_CHECK: arp_failed(cs); break; case AS_GW_CHECK: arp_gw_failed(cs); break; default: arp_reopen_fd(cs); break; } } else - arpreply_offset += (size_t)r; + garp.reply_offset += (size_t)r; } if (r <= 0) { @@ -729,37 +744,38 @@ void handle_arp_response(struct client_state_t *cs) return; } - if (arpreply_offset < ARP_MSG_SIZE) + if (garp.reply_offset < ARP_MSG_SIZE) return; // Emulate the BPF filters if they are not in use. - if (!using_arp_bpf && (!arp_validate_bpf(&arpreply) || - (arpState == AS_DEFENSE && - !arp_validate_bpf_defense(cs, &arpreply)))) { - arpreply_clear(); + if (!garp.using_bpf && + (!arp_validate_bpf(&garp.reply) || + (garp.state == AS_DEFENSE && + !arp_validate_bpf_defense(cs, &garp.reply)))) { + arp_reply_clear(); return; } - if (arp_states[arpState].packet_fn) - arp_states[arpState].packet_fn(cs); - arpreply_clear(); + if (arp_states[garp.state].packet_fn) + arp_states[garp.state].packet_fn(cs); + arp_reply_clear(); } // Perform retransmission if necessary. void handle_arp_timeout(struct client_state_t *cs, long long nowts) { - if (arp_states[arpState].timeout_fn) - arp_states[arpState].timeout_fn(cs, nowts); + if (arp_states[garp.state].timeout_fn) + arp_states[garp.state].timeout_fn(cs, nowts); } long long arp_get_wake_ts(void) { long long mt = -1; for (int i = 0; i < AS_MAX; ++i) { - if (arp_wake_ts[i] < 0) + if (garp.wake_ts[i] < 0) continue; - if (mt < 0 || mt > arp_wake_ts[i]) - mt = arp_wake_ts[i]; + if (mt < 0 || mt > garp.wake_ts[i]) + mt = garp.wake_ts[i]; } return mt; } diff --git a/src/arp.h b/src/arp.h index 7ff5eb7..34f09c5 100644 --- a/src/arp.h +++ b/src/arp.h @@ -56,8 +56,8 @@ extern int arp_probe_wait; extern int arp_probe_num; extern int arp_probe_min; extern int arp_probe_max; -extern int arp_relentless_def; +void set_arp_relentless_def(void); void arp_reset_send_stats(void); void arp_close_fd(struct client_state_t *cs); int arp_check(struct client_state_t *cs, struct dhcpmsg *packet); diff --git a/src/ndhc.c b/src/ndhc.c index 0f32334..3f4cf46 100644 --- a/src/ndhc.c +++ b/src/ndhc.c @@ -538,7 +538,7 @@ static void parse_program_options(int argc, char *argv[]) seccomp_enforce = true; break; case 'd': - arp_relentless_def = 1; + set_arp_relentless_def(); break; case 'w': case 'W': {