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_MSG_SIZE 0x2a
|
||||||
#define ARP_RETRANS_DELAY 5000 // ms
|
#define ARP_RETRANS_DELAY 5000 // ms
|
||||||
|
#define ARP_MAX_TRIES 3
|
||||||
|
|
||||||
// From RFC5227
|
// From RFC5227
|
||||||
int arp_probe_wait = 1000; // initial random delay (ms)
|
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
|
else
|
||||||
log_line("%s: arp: Searching for dhcp server address...",
|
log_line("%s: arp: Searching for dhcp server address...",
|
||||||
client_config.interface);
|
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)
|
if (arp_ping(cs, cs->srcAddr) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (cs->routerAddr) {
|
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;
|
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...",
|
log_line("%s: arp: Still looking for DHCP agent hardware address...",
|
||||||
client_config.interface);
|
client_config.interface);
|
||||||
|
++cs->server_arp_sent;
|
||||||
if (arp_ping(cs, cs->srcAddr) < 0) {
|
if (arp_ping(cs, cs->srcAddr) < 0) {
|
||||||
log_warning("%s: arp: Failed to send ARP ping in retransmission.",
|
log_warning("%s: arp: Failed to send ARP ping in retransmission.",
|
||||||
client_config.interface);
|
client_config.interface);
|
||||||
@ -648,7 +657,7 @@ int arp_do_gw_query(struct client_state_t cs[static 1])
|
|||||||
cs->got_router_arp = true;
|
cs->got_router_arp = true;
|
||||||
if (cs->routerAddr == cs->srcAddr)
|
if (cs->routerAddr == cs->srcAddr)
|
||||||
goto server_is_router;
|
goto server_is_router;
|
||||||
if (cs->got_server_arp) {
|
if (cs->server_arp_state != ARP_QUERY) {
|
||||||
garp.wake_ts[AS_GW_QUERY] = -1;
|
garp.wake_ts[AS_GW_QUERY] = -1;
|
||||||
if (arp_open_fd(cs, true) < 0)
|
if (arp_open_fd(cs, true) < 0)
|
||||||
return ARPR_FAIL;
|
return ARPR_FAIL;
|
||||||
@ -663,7 +672,7 @@ server_is_router:
|
|||||||
client_config.interface, cs->serverArp[0], cs->serverArp[1],
|
client_config.interface, cs->serverArp[0], cs->serverArp[1],
|
||||||
cs->serverArp[2], cs->serverArp[3],
|
cs->serverArp[2], cs->serverArp[3],
|
||||||
cs->serverArp[4], cs->serverArp[5]);
|
cs->serverArp[4], cs->serverArp[5]);
|
||||||
cs->got_server_arp = true;
|
cs->server_arp_state = ARP_FOUND;
|
||||||
if (cs->got_router_arp) {
|
if (cs->got_router_arp) {
|
||||||
garp.wake_ts[AS_GW_QUERY] = -1;
|
garp.wake_ts[AS_GW_QUERY] = -1;
|
||||||
if (arp_open_fd(cs, true) < 0)
|
if (arp_open_fd(cs, true) < 0)
|
||||||
|
10
src/ndhc.h
10
src/ndhc.h
@ -34,18 +34,26 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include "nk/random.h"
|
#include "nk/random.h"
|
||||||
|
|
||||||
|
enum arp_state {
|
||||||
|
ARP_QUERY = 0,
|
||||||
|
ARP_FOUND,
|
||||||
|
ARP_FAILED,
|
||||||
|
};
|
||||||
|
|
||||||
struct client_state_t {
|
struct client_state_t {
|
||||||
struct nk_random_state rnd_state;
|
struct nk_random_state rnd_state;
|
||||||
long long leaseStartTime, renewTime, rebindTime;
|
long long leaseStartTime, renewTime, rebindTime;
|
||||||
long long dhcp_wake_ts;
|
long long dhcp_wake_ts;
|
||||||
int ifDeconfig; // Set if the interface has already been deconfigured.
|
int ifDeconfig; // Set if the interface has already been deconfigured.
|
||||||
int epollFd, signalFd, listenFd, arpFd, nlFd, rfkillFd;
|
int epollFd, signalFd, listenFd, arpFd, nlFd, rfkillFd;
|
||||||
|
int server_arp_sent;
|
||||||
uint32_t nlPortId;
|
uint32_t nlPortId;
|
||||||
unsigned int num_dhcp_requests;
|
unsigned int num_dhcp_requests;
|
||||||
uint32_t clientAddr, serverAddr, srcAddr, routerAddr;
|
uint32_t clientAddr, serverAddr, srcAddr, routerAddr;
|
||||||
uint32_t lease, xid;
|
uint32_t lease, xid;
|
||||||
uint8_t routerArp[6], serverArp[6];
|
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;
|
check_fingerprint, program_init;
|
||||||
bool sent_gw_query, sent_first_announce, sent_second_announce,
|
bool sent_gw_query, sent_first_announce, sent_second_announce,
|
||||||
init_fingerprint_inprogress;
|
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->clientAddr = 0;
|
||||||
cs->num_dhcp_requests = 0;
|
cs->num_dhcp_requests = 0;
|
||||||
|
cs->server_arp_sent = 0;
|
||||||
|
cs->server_arp_state = ARP_QUERY;
|
||||||
cs->got_router_arp = false;
|
cs->got_router_arp = false;
|
||||||
cs->got_server_arp = false;
|
|
||||||
cs->check_fingerprint = false;
|
cs->check_fingerprint = false;
|
||||||
cs->sent_gw_query = false;
|
cs->sent_gw_query = false;
|
||||||
cs->sent_first_announce = 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])
|
static int ifup_action(struct client_state_t cs[static 1])
|
||||||
{
|
{
|
||||||
if (cs->routerAddr && cs->serverAddr) {
|
if (cs->routerAddr && cs->serverAddr) {
|
||||||
|
if ((cs->routerAddr == cs->serverAddr) && cs->server_arp_state != ARP_FOUND)
|
||||||
|
goto no_fingerprint;
|
||||||
if (cs->init_fingerprint_inprogress) {
|
if (cs->init_fingerprint_inprogress) {
|
||||||
suicide("%s: Carrier lost during initial fingerprint. Forcing restart.",
|
suicide("%s: Carrier lost during initial fingerprint. Forcing restart.",
|
||||||
client_config.interface);
|
client_config.interface);
|
||||||
@ -431,6 +434,7 @@ static int ifup_action(struct client_state_t cs[static 1])
|
|||||||
return IFUP_FAIL;
|
return IFUP_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
no_fingerprint:
|
||||||
log_line("%s: Interface is back. Searching for new lease...",
|
log_line("%s: Interface is back. Searching for new lease...",
|
||||||
client_config.interface);
|
client_config.interface);
|
||||||
return IFUP_NEWLEASE;
|
return IFUP_NEWLEASE;
|
||||||
@ -622,7 +626,7 @@ skip_to_requesting:
|
|||||||
scrReturn(ret);
|
scrReturn(ret);
|
||||||
continue;
|
continue;
|
||||||
} else BAD_STATE();
|
} 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);
|
r = arp_do_gw_query(cs);
|
||||||
if (r == ARPR_OK) {
|
if (r == ARPR_OK) {
|
||||||
} else if (r == ARPR_FREE) {
|
} else if (r == ARPR_FREE) {
|
||||||
@ -657,7 +661,7 @@ skip_to_requesting:
|
|||||||
arp_announce_timeout(cs, nowts);
|
arp_announce_timeout(cs, nowts);
|
||||||
if (!cs->sent_gw_query)
|
if (!cs->sent_gw_query)
|
||||||
arp_query_gateway_timeout(cs, nowts);
|
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);
|
int r = arp_gw_query_timeout(cs, nowts);
|
||||||
if (r == ARPR_OK) {
|
if (r == ARPR_OK) {
|
||||||
} else if (r == ARPR_FAIL) {
|
} else if (r == ARPR_FAIL) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user