]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
bpf: match ip_dst to to lease address when bound
authorRoy Marples <roy@marples.name>
Sun, 5 Mar 2017 21:33:45 +0000 (21:33 +0000)
committerRoy Marples <roy@marples.name>
Sun, 5 Mar 2017 21:36:12 +0000 (21:36 +0000)
Because we can't filter on xid as the only message we expect
is FORCERENEW.
Fixes T101.

bpf.c

diff --git a/bpf.c b/bpf.c
index 6f898fc296843afc67e0907e8b410d39540b761b..4ab7c9648564362b0c27721b54c462453ee88b2b 100644 (file)
--- a/bpf.c
+++ b/bpf.c
@@ -332,8 +332,22 @@ bpf_bootp(struct interface *ifp, int fd)
            ifp->hwlen <= sizeof(((struct bootp *)0)->chaddr))
                bp--;
 
-       if (state->state != DHS_BOUND) {
-               /* Make sure the BOOTP packet is for us. */
+       /* Make sure the BOOTP packet is for us. */
+       if (state->state == DHS_BOUND) {
+               /* If bound, we only expect FORCERENEW messages
+                * and they need to be unicast to us. */
+               BPF_SET_STMT(bp, BPF_LD + BPF_W + BPF_ABS,
+                            BPF_L2L + offsetof(struct bootp_pkt, ip.ip_dst));
+               bp++;
+               BPF_SET_JUMP(bp, BPF_JMP + BPF_JEQ + BPF_K,
+                            htonl(state->lease.addr.s_addr), 1, 0);
+               bp++;
+               BPF_SET_STMT(bp, BPF_RET + BPF_K, 0);
+               bp++;
+               bpf_len -= 3;
+       } else {
+               /* As we're not bound, we need to check xid to ensure
+                * it's a reply to our transaction. */
                BPF_SET_STMT(bp, BPF_LD + BPF_W + BPF_ABS,
                             BPF_L2L + offsetof(struct bootp_pkt, bootp.xid));
                bp++;