From 918555219b69220cb61924fe5e7d4e6bff0ba38f Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Tue, 27 Oct 2020 14:14:18 -0400 Subject: [PATCH] Make fingerprinting more robust with rapid carrier state changes. The existing code tracked the fingerprinting completion state with a bool, which is insufficient; what is required is a tristate (none|inprogress|done) where the inprogress state reverts to none on carrier down, but done state stays done on carrier down. --- src/arp.c | 3 ++- src/ndhc.h | 10 ++++++++-- src/state.c | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/arp.c b/src/arp.c index 9a96c0b..d2496eb 100644 --- a/src/arp.c +++ b/src/arp.c @@ -553,7 +553,8 @@ int arp_query_gateway(struct client_state_t cs[static 1]) return ARPR_FAIL; } cs->sent_gw_query = true; - cs->init_fingerprint_inprogress = true; + if (cs->fp_state == FPRINT_NONE) + cs->fp_state = FPRINT_INPROGRESS; garp.wake_ts[AS_QUERY_GW_SEND] = -1; return ARPR_OK; } diff --git a/src/ndhc.h b/src/ndhc.h index f47341a..f0e968e 100644 --- a/src/ndhc.h +++ b/src/ndhc.h @@ -40,6 +40,12 @@ enum arp_state { ARP_FAILED, }; +enum fprint_state { + FPRINT_NONE = 0, + FPRINT_INPROGRESS, + FPRINT_DONE, +}; + struct client_state_t { struct nk_random_state rnd_state; long long leaseStartTime, renewTime, rebindTime; @@ -53,10 +59,10 @@ struct client_state_t { uint32_t lease, xid; uint8_t routerArp[6], serverArp[6]; enum arp_state server_arp_state, router_arp_state; + enum fprint_state fp_state; bool using_dhcp_bpf, arp_is_defense, check_fingerprint, program_init, sent_renew_or_rebind; - bool sent_gw_query, sent_first_announce, sent_second_announce, - init_fingerprint_inprogress; + bool sent_gw_query, sent_first_announce, sent_second_announce; }; struct client_config_t { diff --git a/src/state.c b/src/state.c index eb6bfa6..4a8916a 100644 --- a/src/state.c +++ b/src/state.c @@ -85,12 +85,12 @@ static void reinit_shared_deconfig(struct client_state_t cs[static 1]) cs->router_arp_sent = 0; cs->server_arp_state = ARP_QUERY; cs->router_arp_state = ARP_QUERY; + cs->fp_state = FPRINT_NONE; cs->check_fingerprint = false; cs->sent_renew_or_rebind = false; cs->sent_gw_query = false; cs->sent_first_announce = false; cs->sent_second_announce = false; - cs->init_fingerprint_inprogress = false; memset(&cs->routerArp, 0, sizeof cs->routerArp); memset(&cs->serverArp, 0, sizeof cs->serverArp); arp_reset_state(cs); @@ -394,9 +394,9 @@ static int ifup_action(struct client_state_t cs[static 1]) if (cs->routerAddr && cs->serverAddr) { const bool fp_server = cs->server_arp_state == ARP_FOUND; const bool fp_router = (cs->routerAddr != cs->serverAddr) ? (cs->router_arp_state == ARP_FOUND) : fp_server; - if (!fp_server && !fp_router) + if ((!fp_server && !fp_router) || cs->fp_state == FPRINT_NONE) goto no_fingerprint; - if (cs->init_fingerprint_inprogress) { + if (cs->fp_state == FPRINT_INPROGRESS) { suicide("%s: Carrier lost during initial fingerprint. Forcing restart.", client_config.interface); } @@ -636,7 +636,7 @@ skip_to_requesting: if (r == ARPR_OK) { } else if (r == ARPR_FREE) { log_line("%s: Network fingerprinting complete.", client_config.interface); - cs->init_fingerprint_inprogress = false; + cs->fp_state = FPRINT_DONE; } else if (r == ARPR_FAIL) { ret = COR_ERROR; scrReturn(ret);