Give up on fingerprinting router/gateway if it doesn't reply.

This commit is contained in:
Nicholas J. Kain 2020-10-19 04:25:15 -04:00
parent 87ac82fa45
commit 9b8c63d998
3 changed files with 23 additions and 14 deletions

View File

@ -313,11 +313,11 @@ static int arp_get_gw_hwaddr(struct client_state_t cs[static 1])
if (arp_ping(cs, cs->srcAddr) < 0)
return -1;
if (cs->routerAddr) {
cs->got_router_arp = false;
cs->router_arp_state = ARP_QUERY;
++cs->router_arp_sent;
if (arp_ping(cs, cs->routerAddr) < 0)
return -1;
} else
cs->got_router_arp = true;
} else cs->router_arp_state = ARP_FAILED;
garp.wake_ts[AS_GW_QUERY] =
garp.send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY + 250;
return 0;
@ -465,9 +465,16 @@ int arp_gw_query_timeout(struct client_state_t cs[static 1], long long nowts)
garp.wake_ts[AS_GW_QUERY] = rtts;
return ARPR_OK;
}
if (!cs->got_router_arp) {
if (cs->router_arp_state == ARP_QUERY) {
if (cs->router_arp_sent >= ARP_MAX_TRIES) {
log_line("%s: arp: Gateway is ignoring ARPs.",
client_config.interface);
cs->router_arp_state = ARP_FAILED;
return ARPR_OK;
}
log_line("%s: arp: Still looking for gateway hardware address...",
client_config.interface);
++cs->router_arp_sent;
if (arp_ping(cs, cs->routerAddr) < 0) {
log_warning("%s: arp: Failed to send ARP ping in retransmission.",
client_config.interface);
@ -654,7 +661,7 @@ int arp_do_gw_query(struct client_state_t cs[static 1])
client_config.interface, cs->routerArp[0], cs->routerArp[1],
cs->routerArp[2], cs->routerArp[3],
cs->routerArp[4], cs->routerArp[5]);
cs->got_router_arp = true;
cs->router_arp_state = ARP_FOUND;
if (cs->routerAddr == cs->srcAddr)
goto server_is_router;
if (cs->server_arp_state != ARP_QUERY) {
@ -673,7 +680,7 @@ server_is_router:
cs->serverArp[2], cs->serverArp[3],
cs->serverArp[4], cs->serverArp[5]);
cs->server_arp_state = ARP_FOUND;
if (cs->got_router_arp) {
if (cs->router_arp_state != ARP_QUERY) {
garp.wake_ts[AS_GW_QUERY] = -1;
if (arp_open_fd(cs, true) < 0)
return ARPR_FAIL;

View File

@ -46,15 +46,14 @@ struct client_state_t {
long long dhcp_wake_ts;
int ifDeconfig; // Set if the interface has already been deconfigured.
int epollFd, signalFd, listenFd, arpFd, nlFd, rfkillFd;
int server_arp_sent;
int server_arp_sent, router_arp_sent;
uint32_t nlPortId;
unsigned int num_dhcp_requests;
uint32_t clientAddr, serverAddr, srcAddr, routerAddr;
uint32_t lease, xid;
uint8_t routerArp[6], serverArp[6];
enum arp_state server_arp_state;
bool using_dhcp_bpf, got_router_arp, arp_is_defense,
check_fingerprint, program_init;
enum arp_state server_arp_state, router_arp_state;
bool using_dhcp_bpf, arp_is_defense, check_fingerprint, program_init;
bool sent_gw_query, sent_first_announce, sent_second_announce,
init_fingerprint_inprogress;
};

View File

@ -78,8 +78,9 @@ static void reinit_shared_deconfig(struct client_state_t cs[static 1])
cs->clientAddr = 0;
cs->num_dhcp_requests = 0;
cs->server_arp_sent = 0;
cs->router_arp_sent = 0;
cs->server_arp_state = ARP_QUERY;
cs->got_router_arp = false;
cs->router_arp_state = ARP_QUERY;
cs->check_fingerprint = false;
cs->sent_gw_query = false;
cs->sent_first_announce = false;
@ -414,7 +415,9 @@ static int frenew(struct client_state_t cs[static 1], bool is_bound)
static int ifup_action(struct client_state_t cs[static 1])
{
if (cs->routerAddr && cs->serverAddr) {
if ((cs->routerAddr == cs->serverAddr) && cs->server_arp_state != ARP_FOUND)
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)
goto no_fingerprint;
if (cs->init_fingerprint_inprogress) {
suicide("%s: Carrier lost during initial fingerprint. Forcing restart.",
@ -622,7 +625,7 @@ skip_to_requesting:
scrReturn(ret);
continue;
} else BAD_STATE();
if (!cs->got_router_arp || cs->server_arp_state == ARP_QUERY) {
if (cs->router_arp_state == ARP_QUERY || cs->server_arp_state == ARP_QUERY) {
r = arp_do_gw_query(cs);
if (r == ARPR_OK) {
} else if (r == ARPR_FREE) {
@ -657,7 +660,7 @@ skip_to_requesting:
arp_announce_timeout(cs, nowts);
if (!cs->sent_gw_query)
arp_query_gateway_timeout(cs, nowts);
else if (!cs->got_router_arp || cs->server_arp_state == ARP_QUERY) {
else if (cs->router_arp_state == ARP_QUERY || cs->server_arp_state == ARP_QUERY) {
int r = arp_gw_query_timeout(cs, nowts);
if (r == ARPR_OK) {
} else if (r == ARPR_FAIL) {