summaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2017-03-05 21:05:24 +0000
committerRoy Marples <roy@marples.name>2017-03-05 21:05:24 +0000
commitbf66a5d998f78c0acbeb66e35d1aa63cc375e461 (patch)
treed9cbb215bafb75b22bdb1cb61debb22fcfa1e56e /if-bsd.c
parenta1997a1d5268357a906aed94c16f14ed20e4d7ab (diff)
downloaddhcpcd-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.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/if-bsd.c b/if-bsd.c
index 44e09d9e..b3dec083 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -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;