On Sat, Sep 19, 2020 at 2:07 PM Denis Fondras <open...@ledeuns.net> wrote:
> On Wed, Sep 16, 2020 at 03:06:32PM -0400, Sven F. wrote: > > On Wed, Jun 3, 2020 at 2:13 PM sven falempin <sven.falem...@gmail.com> > > wrote: > > > > Can you send a proper diff please for review please ? > bpf.c is sort of ok, the rest need choices . The configuration of bpf should probably be updated if someone changes the lladdr after launching dhclient.
Index: bpf.c =================================================================== RCS file: /cvs/src/sbin/dhclient/bpf.c,v retrieving revision 1.75 diff -u -p -r1.75 bpf.c --- bpf.c 18 Mar 2019 00:00:59 -0000 1.75 +++ bpf.c 21 Sep 2020 19:18:52 -0000 @@ -102,6 +102,49 @@ get_udp_sock(int rdomain) return sock; } + +/* + * Packet MAC filter program. + * + * N.B.: Changes to the filter program may require changes to the + * constant offsets used in if_register_receive to patch the BPF program! + */ + +struct bpf_insn dhcp_bpf_mac_filter[] = { + /* 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), + + /* 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), + + /* 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, 8, 0), + + /* Get the IP header length. */ + BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), + + /* Make sure it's to the right port. */ + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */ + + /* check bootp.hw.addr 2 bytes */ + BPF_STMT(BPF_LD + BPF_H + BPF_IND, 50), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0000, 0, 3), /* patch */ + /* check bootp.hw.addr 4 bytes */ + BPF_STMT(BPF_LD + BPF_W + BPF_IND, 52), + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x00000000, 0, 1), /* patch */ + + /* If we passed all the tests, ask for the whole packet. */ + BPF_STMT(BPF_RET+BPF_K, (unsigned int)-1), + + /* Otherwise, drop it. */ + BPF_STMT(BPF_RET+BPF_K, 0), +}; +int dhcp_bpf_mac_filter_len = sizeof(dhcp_bpf_mac_filter) / sizeof(struct bpf_insn); + /* * Packet filter program. * @@ -177,13 +220,19 @@ struct bpf_insn dhcp_bpf_wfilter[] = { int dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn); + +extern int cmd_opts; + int -configure_bpf_sock(int bpffd) +configure_bpf_sock(struct interface_info *ifi) { struct bpf_version v; struct bpf_program p; int flag = 1, sz; int fildrop = BPF_FILDROP_CAPTURE; + uint32_t bits; + uint16_t bits16; + int bpffd = ifi->bpffd; /* Make sure the BPF version is in range. */ if (ioctl(bpffd, BIOCVERSION, &v) == -1) @@ -218,7 +267,18 @@ configure_bpf_sock(int bpffd) * N.B.: changes to filter program may require changes to the * insn number(s) used below! */ - dhcp_bpf_filter[8].k = LOCAL_PORT; + + if (cmd_opts & OPT_MAC_FITLER) { + p.bf_len = dhcp_bpf_mac_filter_len; + p.bf_insns = dhcp_bpf_mac_filter; + dhcp_bpf_mac_filter[8].k = LOCAL_PORT; + memcpy(&bits16, ifi->hw_address.ether_addr_octet, sizeof(bits16)); + dhcp_bpf_mac_filter[10].k = ntohs(bits16); + memcpy(&bits, ifi->hw_address.ether_addr_octet + 2, sizeof(bits)); + dhcp_bpf_mac_filter[12].k = ntohl(bits); + } else { + dhcp_bpf_filter[8].k = LOCAL_PORT; + } if (ioctl(bpffd, BIOCSETF, &p) == -1) fatal("BIOCSETF"); Index: dhclient.c =================================================================== RCS file: /cvs/src/sbin/dhclient/dhclient.c,v retrieving revision 1.678 diff -u -p -r1.678 dhclient.c --- dhclient.c 31 Jul 2020 12:12:11 -0000 1.678 +++ dhclient.c 21 Sep 2020 19:18:53 -0000 @@ -471,7 +471,7 @@ main(int argc, char *argv[]) log_setverbose(0); /* Don't show log_debug() messages. */ - while ((ch = getopt(argc, argv, "c:di:L:nrv")) != -1) + while ((ch = getopt(argc, argv, "c:di:L:nrvm")) != -1) switch (ch) { case 'c': if (optarg == NULL) @@ -494,6 +494,9 @@ main(int argc, char *argv[]) cmd_opts |= OPT_DBPATH; path_option_db = optarg; break; + case 'm': + cmd_opts |= OPT_MAC_FITLER; + break; case 'n': cmd_opts |= OPT_NOACTION; break; @@ -670,7 +673,7 @@ main(int argc, char *argv[]) /* Create the udp and bpf sockets, growing rbuf if needed. */ ifi->udpfd = get_udp_sock(ifi->rdomain); ifi->bpffd = get_bpf_sock(ifi->name); - newsize = configure_bpf_sock(ifi->bpffd); + newsize = configure_bpf_sock(ifi); if (newsize > ifi->rbuf_max) { if ((newp = realloc(ifi->rbuf, newsize)) == NULL) fatal("rbuf"); Index: dhcpd.h =================================================================== RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v retrieving revision 1.287 diff -u -p -r1.287 dhcpd.h --- dhcpd.h 21 May 2020 01:07:52 -0000 1.287 +++ dhcpd.h 21 Sep 2020 19:18:53 -0000 @@ -191,7 +191,7 @@ void parse_warn(char *); /* bpf.c */ int get_bpf_sock(char *); int get_udp_sock(int); -int configure_bpf_sock(int); +int configure_bpf_sock(struct interface_info *); ssize_t send_packet(struct interface_info *, struct in_addr, struct in_addr, const char *); ssize_t receive_packet(unsigned char *, unsigned char *, @@ -218,6 +218,7 @@ extern int cmd_opts; #define OPT_CONFPATH 0x10 #define OPT_DBPATH 0x20 #define OPT_IGNORELIST 0x40 +#define OPT_MAC_FITLER 0x80 void dhcpoffer(struct interface_info *, struct option_data *, const char *);