diff --git a/sbin/dhclient/bpf.c b/sbin/dhclient/bpf.c index b2f8fb9da9cb..23561104ced8 100644 --- a/sbin/dhclient/bpf.c +++ b/sbin/dhclient/bpf.c @@ -5,7 +5,7 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * - * Copyright (c) 2018 Franco Fichtner + * Copyright (c) 2018-2021 Franco Fichtner * Copyright (c) 1995, 1996, 1998, 1999 * The Internet Software Consortium. All rights reserved. * @@ -203,20 +203,41 @@ if_register_send(struct interface_info *info) * constant offsets used in if_register_send to patch the BPF program! */ static struct bpf_insn dhcp_bpf_filter[] = { + /* Set packet index for IP packet... */ + BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, 0), + + /* Test whether this is a VLAN packet... */ + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 12), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_VLAN, 0, 4), + + /* Test whether it has a VID of 0 */ + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 14), + BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0xfff), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1), + + /* Correct the packet index for VLAN... */ + BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, 4), + /* Make sure this is an IP packet... */ - BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8), + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 12), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 14), /* Make sure it's a UDP packet... */ - BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), + BPF_STMT(BPF_LD + BPF_B + BPF_IND, 23), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 12), /* Make sure this isn't a fragment... */ - BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), - BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 20), + BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 10, 0), /* Get the IP header length... */ + BPF_STMT(BPF_MISC + BPF_TXA, 0), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 2), BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), + BPF_JUMP(BPF_JMP + BPF_JA, 1, 0, 0), + BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 18), + BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0), + BPF_STMT(BPF_MISC + BPF_TAX, 0), /* Make sure it's to the right port... */ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), @@ -279,7 +300,7 @@ if_register_receive(struct interface_info *info) * XXX: changes to filter program may require changes to the * insn number(s) used below! */ - dhcp_bpf_filter[8].k = LOCAL_PORT; + dhcp_bpf_filter[21].k = LOCAL_PORT; if (ioctl(info->rfdesc, BIOCSETF, &p) < 0) error("Can't install packet filter program: %m"); diff --git a/sbin/dhclient/packet.c b/sbin/dhclient/packet.c index e482398f3ecb..ef86cfbffe07 100644 --- a/sbin/dhclient/packet.c +++ b/sbin/dhclient/packet.c @@ -167,7 +167,8 @@ decode_hw_header(unsigned char *buf, int bufix, struct hardware *from) from->htype = ARPHRD_ETHER; from->hlen = sizeof(eh.ether_shost); - return (sizeof(eh)); + return (sizeof(eh) + (ntohs(eh.ether_type) == ETHERTYPE_VLAN ? + ETHER_VLAN_ENCAP_LEN : 0)); } ssize_t