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:
Nicholas J. Kain 2011-07-01 03:01:29 -04:00
parent 0e55bfd4fd
commit 7a2585d2bf

View File

@ -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)); */
// 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->h_dest, client_config.arp, 6)) {
/* log_warning("arp: Ethernet destination does not equal our MAC"); */
return 0; return 0;
} if (memcmp(am->h_dest, client_config.arp, 6))
if (memcmp(am->dmac, client_config.arp, 6)) { return 0;
/* log_warning("arp: ARP destination does not equal our MAC"); */ if (memcmp(am->dmac, client_config.arp, 6))
return 0; return 0;
}
return 1; return 1;
} }