Keep track of whether the ARP BPF has been successfully installed. If it has,
then don't perform redundant checks in ARP validation.
This commit is contained in:
parent
0e55bfd4fd
commit
7a2585d2bf
39
ndhc/arp.c
39
ndhc/arp.c
@ -46,6 +46,7 @@ static struct arpMsg arpreply;
|
|||||||
static int arpreply_offset;
|
static int arpreply_offset;
|
||||||
static struct dhcpmsg arp_dhcp_packet;
|
static struct dhcpmsg arp_dhcp_packet;
|
||||||
static int arp_packet_num;
|
static int arp_packet_num;
|
||||||
|
static int using_arp_bpf;
|
||||||
|
|
||||||
static int arp_open_fd(struct client_state_t *cs)
|
static int arp_open_fd(struct client_state_t *cs)
|
||||||
{
|
{
|
||||||
@ -79,9 +80,9 @@ static int arp_open_fd(struct client_state_t *cs)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignoring error since kernel may lack support for BPF.
|
using_arp_bpf = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &sfp_arp,
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &sfp_arp,
|
sizeof sfp_arp) != -1;
|
||||||
sizeof sfp_arp) >= 0)
|
if (using_arp_bpf)
|
||||||
log_line("Attached filter to raw ARP socket fd %d", fd);
|
log_line("Attached filter to raw ARP socket fd %d", fd);
|
||||||
|
|
||||||
int opt = 1;
|
int opt = 1;
|
||||||
@ -262,13 +263,10 @@ static void arp_gw_success(struct client_state_t *cs)
|
|||||||
cs->dhcpState = cs->arpPrevState;
|
cs->dhcpState = cs->arpPrevState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this function will see all ARP traffic on the interface.
|
// ARP validation functions that will be performed by the BPF if it is
|
||||||
// Therefore the validation shouldn't be noisy, and should silently
|
// installed.
|
||||||
// reject non-malformed ARP packets that are irrelevant.
|
static int arp_validate_bpf(struct arpMsg *am)
|
||||||
static int arp_validate(struct arpMsg *am)
|
|
||||||
{
|
{
|
||||||
if (!am)
|
|
||||||
return 0;
|
|
||||||
if (am->h_proto != htons(ETH_P_ARP)) {
|
if (am->h_proto != htons(ETH_P_ARP)) {
|
||||||
log_warning("arp: IP header does not indicate ARP protocol");
|
log_warning("arp: IP header does not indicate ARP protocol");
|
||||||
return 0;
|
return 0;
|
||||||
@ -289,19 +287,22 @@ static int arp_validate(struct arpMsg *am)
|
|||||||
log_warning("arp: ARP protocol address length invalid");
|
log_warning("arp: ARP protocol address length invalid");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (am->operation != htons(ARPOP_REPLY)) {
|
return 1;
|
||||||
/* log_warning("arp: ARP operation type is not 'reply': %x", */
|
|
||||||
/* ntohs(am->operation)); */
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (memcmp(am->h_dest, client_config.arp, 6)) {
|
|
||||||
/* log_warning("arp: Ethernet destination does not equal our MAC"); */
|
// Note that this function will see all ARP traffic on the interface.
|
||||||
|
// Therefore the validation shouldn't be noisy, and should silently
|
||||||
|
// reject non-malformed ARP packets that are irrelevant.
|
||||||
|
static int arp_validate(struct arpMsg *am)
|
||||||
|
{
|
||||||
|
if (!using_arp_bpf && !arp_validate_bpf(am))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
if (am->operation != htons(ARPOP_REPLY))
|
||||||
if (memcmp(am->dmac, client_config.arp, 6)) {
|
return 0;
|
||||||
/* log_warning("arp: ARP destination does not equal our MAC"); */
|
if (memcmp(am->h_dest, client_config.arp, 6))
|
||||||
|
return 0;
|
||||||
|
if (memcmp(am->dmac, client_config.arp, 6))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user