diff options
| author | Roy Marples <roy@marples.name> | 2017-03-05 21:05:24 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2017-03-05 21:05:24 +0000 |
| commit | bf66a5d998f78c0acbeb66e35d1aa63cc375e461 (patch) | |
| tree | d9cbb215bafb75b22bdb1cb61debb22fcfa1e56e /if-bsd.c | |
| parent | a1997a1d5268357a906aed94c16f14ed20e4d7ab (diff) | |
| download | dhcpcd-bf66a5d998f78c0acbeb66e35d1aa63cc375e461.tar.xz | |
bpf: ARP and BOOTP filter improvements
The ARP filter now checks hardware and protocol length matches
the interface, it's not from the interface itself and either the
source ip or target ip is one of our addresses of interest.
The BOOTP filter now checks for BOOTREPLY and matching xid.
If the interface hardware address fits inside chaddr then
that is checked as well.
Diffstat (limited to 'if-bsd.c')
| -rw-r--r-- | if-bsd.c | 33 |
1 files changed, 17 insertions, 16 deletions
@@ -86,8 +86,6 @@ #include "route.h" #include "sa.h" -#include "bpf-filter.h" - #ifndef RT_ROUNDUP #define RT_ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) @@ -621,7 +619,8 @@ if_closeraw(__unused struct interface *ifp, int fd) } int -if_openraw(struct interface *ifp, uint16_t protocol) +if_openraw(struct interface *ifp, __unused uint16_t protocol, + int (*filter)(struct interface *, int)) { struct ipv4_state *state; int fd = -1; @@ -629,7 +628,6 @@ if_openraw(struct interface *ifp, uint16_t protocol) int ibuf_len = 0; size_t buf_len; struct bpf_version pv; - struct bpf_program pf; #ifdef BIOCIMMEDIATE int flags; #endif @@ -677,6 +675,9 @@ if_openraw(struct interface *ifp, uint16_t protocol) goto eexit; } + if (filter(ifp, fd) != 0) + goto eexit; + memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, &ifr) == -1) @@ -701,18 +702,6 @@ if_openraw(struct interface *ifp, uint16_t protocol) goto eexit; #endif - /* Install the filter. */ - memset(&pf, 0, sizeof(pf)); - if (protocol == ETHERTYPE_ARP) { - pf.bf_insns = UNCONST(arp_bpf_filter); - pf.bf_len = arp_bpf_filter_len; - } else { - pf.bf_insns = UNCONST(bootp_bpf_filter); - pf.bf_len = bootp_bpf_filter_len; - } - if (ioctl(fd, BIOCSETF, &pf) == -1) - goto eexit; - return fd; eexit: @@ -786,6 +775,18 @@ next: } int +if_bpf_attach(int s, struct bpf_insn *filter, unsigned int filter_len) +{ + struct bpf_program pf; + + /* Install the filter. */ + memset(&pf, 0, sizeof(pf)); + pf.bf_insns = filter; + pf.bf_len = filter_len; + return ioctl(s, BIOCSETF, &pf); +} + +int if_address(unsigned char cmd, const struct ipv4_addr *ia) { int r; |
