Give up on fingerprinting relay agent/server if it doesn't reply.
Try to send/wait three times; then if there's no response, then assume that the relay agent is ignoring or firewalled from receiving ARP requests.
This commit is contained in:
parent
ba046c02c7
commit
7bd551d564
17
src/arp.c
17
src/arp.c
@ -49,6 +49,7 @@
|
||||
|
||||
#define ARP_MSG_SIZE 0x2a
|
||||
#define ARP_RETRANS_DELAY 5000 // ms
|
||||
#define ARP_MAX_TRIES 3
|
||||
|
||||
// From RFC5227
|
||||
int arp_probe_wait = 1000; // initial random delay (ms)
|
||||
@ -307,7 +308,8 @@ static int arp_get_gw_hwaddr(struct client_state_t cs[static 1])
|
||||
else
|
||||
log_line("%s: arp: Searching for dhcp server address...",
|
||||
client_config.interface);
|
||||
cs->got_server_arp = false;
|
||||
cs->server_arp_state = ARP_QUERY;
|
||||
++cs->server_arp_sent;
|
||||
if (arp_ping(cs, cs->srcAddr) < 0)
|
||||
return -1;
|
||||
if (cs->routerAddr) {
|
||||
@ -472,9 +474,16 @@ int arp_gw_query_timeout(struct client_state_t cs[static 1], long long nowts)
|
||||
return ARPR_FAIL;
|
||||
}
|
||||
}
|
||||
if (!cs->got_server_arp) {
|
||||
if (cs->server_arp_state == ARP_QUERY) {
|
||||
if (cs->server_arp_sent >= ARP_MAX_TRIES) {
|
||||
log_line("%s: arp: DHCP agent is ignoring ARPs.",
|
||||
client_config.interface);
|
||||
cs->server_arp_state = ARP_FAILED;
|
||||
return ARPR_OK;
|
||||
}
|
||||
log_line("%s: arp: Still looking for DHCP agent hardware address...",
|
||||
client_config.interface);
|
||||
++cs->server_arp_sent;
|
||||
if (arp_ping(cs, cs->srcAddr) < 0) {
|
||||
log_warning("%s: arp: Failed to send ARP ping in retransmission.",
|
||||
client_config.interface);
|
||||
@ -648,7 +657,7 @@ int arp_do_gw_query(struct client_state_t cs[static 1])
|
||||
cs->got_router_arp = true;
|
||||
if (cs->routerAddr == cs->srcAddr)
|
||||
goto server_is_router;
|
||||
if (cs->got_server_arp) {
|
||||
if (cs->server_arp_state != ARP_QUERY) {
|
||||
garp.wake_ts[AS_GW_QUERY] = -1;
|
||||
if (arp_open_fd(cs, true) < 0)
|
||||
return ARPR_FAIL;
|
||||
@ -663,7 +672,7 @@ server_is_router:
|
||||
client_config.interface, cs->serverArp[0], cs->serverArp[1],
|
||||
cs->serverArp[2], cs->serverArp[3],
|
||||
cs->serverArp[4], cs->serverArp[5]);
|
||||
cs->got_server_arp = true;
|
||||
cs->server_arp_state = ARP_FOUND;
|
||||
if (cs->got_router_arp) {
|
||||
garp.wake_ts[AS_GW_QUERY] = -1;
|
||||
if (arp_open_fd(cs, true) < 0)
|
||||
|
10
src/ndhc.h
10
src/ndhc.h
@ -34,18 +34,26 @@
|
||||
#include <net/if.h>
|
||||
#include "nk/random.h"
|
||||
|
||||
enum arp_state {
|
||||
ARP_QUERY = 0,
|
||||
ARP_FOUND,
|
||||
ARP_FAILED,
|
||||
};
|
||||
|
||||
struct client_state_t {
|
||||
struct nk_random_state rnd_state;
|
||||
long long leaseStartTime, renewTime, rebindTime;
|
||||
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;
|
||||
uint32_t nlPortId;
|
||||
unsigned int num_dhcp_requests;
|
||||
uint32_t clientAddr, serverAddr, srcAddr, routerAddr;
|
||||
uint32_t lease, xid;
|
||||
uint8_t routerArp[6], serverArp[6];
|
||||
bool using_dhcp_bpf, got_router_arp, got_server_arp, arp_is_defense,
|
||||
enum arp_state server_arp_state;
|
||||
bool using_dhcp_bpf, got_router_arp, arp_is_defense,
|
||||
check_fingerprint, program_init;
|
||||
bool sent_gw_query, sent_first_announce, sent_second_announce,
|
||||
init_fingerprint_inprogress;
|
||||
|
10
src/state.c
10
src/state.c
@ -77,8 +77,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->server_arp_state = ARP_QUERY;
|
||||
cs->got_router_arp = false;
|
||||
cs->got_server_arp = false;
|
||||
cs->check_fingerprint = false;
|
||||
cs->sent_gw_query = false;
|
||||
cs->sent_first_announce = false;
|
||||
@ -417,6 +418,8 @@ 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)
|
||||
goto no_fingerprint;
|
||||
if (cs->init_fingerprint_inprogress) {
|
||||
suicide("%s: Carrier lost during initial fingerprint. Forcing restart.",
|
||||
client_config.interface);
|
||||
@ -431,6 +434,7 @@ static int ifup_action(struct client_state_t cs[static 1])
|
||||
return IFUP_FAIL;
|
||||
}
|
||||
}
|
||||
no_fingerprint:
|
||||
log_line("%s: Interface is back. Searching for new lease...",
|
||||
client_config.interface);
|
||||
return IFUP_NEWLEASE;
|
||||
@ -622,7 +626,7 @@ skip_to_requesting:
|
||||
scrReturn(ret);
|
||||
continue;
|
||||
} else BAD_STATE();
|
||||
if (!cs->got_router_arp || !cs->got_server_arp) {
|
||||
if (!cs->got_router_arp || cs->server_arp_state == ARP_QUERY) {
|
||||
r = arp_do_gw_query(cs);
|
||||
if (r == ARPR_OK) {
|
||||
} else if (r == ARPR_FREE) {
|
||||
@ -657,7 +661,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->got_server_arp) {
|
||||
else if (!cs->got_router_arp || cs->server_arp_state == ARP_QUERY) {
|
||||
int r = arp_gw_query_timeout(cs, nowts);
|
||||
if (r == ARPR_OK) {
|
||||
} else if (r == ARPR_FAIL) {
|
||||
|
Loading…
Reference in New Issue
Block a user