Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/external/bsd/dhcpcd/dist/src/bpf.c,v rcsdiff: /ftp/cvs/cvsroot/src/external/bsd/dhcpcd/dist/src/bpf.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.11 retrieving revision 1.11.2.3 diff -u -p -r1.11 -r1.11.2.3 --- src/external/bsd/dhcpcd/dist/src/bpf.c 2019/07/30 10:25:03 1.11 +++ src/external/bsd/dhcpcd/dist/src/bpf.c 2020/04/12 08:29:40 1.11.2.3 @@ -93,6 +93,38 @@ bpf_frame_header_len(const struct interf } } +void * +bpf_frame_header_src(const struct interface *ifp, void *fh, size_t *len) +{ + uint8_t *f = fh; + + switch (ifp->family) { + case ARPHRD_ETHER: + *len = sizeof(((struct ether_header *)0)->ether_shost); + return f + offsetof(struct ether_header, ether_shost); + default: + *len = 0; + errno = ENOTSUP; + return NULL; + } +} + +void * +bpf_frame_header_dst(const struct interface *ifp, void *fh, size_t *len) +{ + uint8_t *f = fh; + + switch (ifp->family) { + case ARPHRD_ETHER: + *len = sizeof(((struct ether_header *)0)->ether_dhost); + return f + offsetof(struct ether_header, ether_dhost); + default: + *len = 0; + errno = ENOTSUP; + return NULL; + } +} + static const uint8_t etherbcastaddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -215,7 +247,6 @@ ssize_t bpf_read(struct interface *ifp, int fd, void *data, size_t len, unsigned int *flags) { - ssize_t fl = (ssize_t)bpf_frame_header_len(ifp); ssize_t bytes; struct ipv4_state *state = IPV4_STATE(ifp); @@ -250,10 +281,10 @@ bpf_read(struct interface *ifp, int fd, *flags |= BPF_BCAST; else *flags &= ~BPF_BCAST; - payload += fl; - bytes = (ssize_t)packet.bh_caplen - fl; - if ((size_t)bytes > len) + if (packet.bh_caplen > len) bytes = (ssize_t)len; + else + bytes = (ssize_t)packet.bh_caplen; memcpy(data, payload, (size_t)bytes); next: state->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen + @@ -410,13 +441,7 @@ bpf_cmp_hwaddr(struct bpf_insn *bpf, siz #endif #ifdef ARP - static const struct bpf_insn bpf_arp_ether [] = { - /* Ensure packet is at least correct size. */ - BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), - BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0), - BPF_STMT(BPF_RET + BPF_K, 0), - /* Check this is an ARP packet. */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_header, ether_type)), @@ -552,11 +577,11 @@ bpf_arp(struct interface *ifp, int fd) } #endif -#define BPF_M_FHLEN 0 -#define BPF_M_IPHLEN 1 -#define BPF_M_IPLEN 2 -#define BPF_M_UDP 3 -#define BPF_M_UDPLEN 4 +#ifdef ARPHRD_NONE +static const struct bpf_insn bpf_bootp_none[] = { +}; +#define BPF_BOOTP_NONE_LEN __arraycount(bpf_bootp_none) +#endif static const struct bpf_insn bpf_bootp_ether[] = { /* Make sure this is an IP packet. */ @@ -565,13 +590,14 @@ static const struct bpf_insn bpf_bootp_e BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0), BPF_STMT(BPF_RET + BPF_K, 0), - /* Load frame header length into X. */ - BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, sizeof(struct ether_header)), - /* Copy frame header length to memory */ - BPF_STMT(BPF_STX, BPF_M_FHLEN), + /* Advance to the IP header. */ + BPF_STMT(BPF_LDX + BPF_K, sizeof(struct ether_header)), }; #define BPF_BOOTP_ETHER_LEN __arraycount(bpf_bootp_ether) +#define BOOTP_MIN_SIZE sizeof(struct ip) + sizeof(struct udphdr) + \ + sizeof(struct bootp) + static const struct bpf_insn bpf_bootp_filter[] = { /* Make sure it's an IPv4 packet. */ BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0), @@ -579,15 +605,6 @@ static const struct bpf_insn bpf_bootp_f BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x40, 1, 0), BPF_STMT(BPF_RET + BPF_K, 0), - /* Ensure IP header length is big enough and - * store the IP header length in memory. */ - BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0), - BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x0f), - BPF_STMT(BPF_ALU + BPF_MUL + BPF_K, 4), - BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ip), 1, 0), - BPF_STMT(BPF_RET + BPF_K, 0), - BPF_STMT(BPF_ST, BPF_M_IPHLEN), - /* Make sure it's a UDP packet. */ BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct ip, ip_p)), BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), @@ -598,49 +615,17 @@ static const struct bpf_insn bpf_bootp_f BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 0, 1), BPF_STMT(BPF_RET + BPF_K, 0), - /* Store IP length. */ - BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct ip, ip_len)), - BPF_STMT(BPF_ST, BPF_M_IPLEN), - /* Advance to the UDP header. */ - BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPHLEN), + BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0), + BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x0f), + BPF_STMT(BPF_ALU + BPF_MUL + BPF_K, 4), BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0), BPF_STMT(BPF_MISC + BPF_TAX, 0), - /* Store UDP location */ - BPF_STMT(BPF_STX, BPF_M_UDP), - /* Make sure it's from and to the right port. */ BPF_STMT(BPF_LD + BPF_W + BPF_IND, 0), BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (BOOTPS << 16) + BOOTPC, 1, 0), BPF_STMT(BPF_RET + BPF_K, 0), - - /* Store UDP length. */ - BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct udphdr, uh_ulen)), - BPF_STMT(BPF_ST, BPF_M_UDPLEN), - - /* Ensure that UDP length + IP header length == IP length */ - /* Copy IP header length to X. */ - BPF_STMT(BPF_LDX + BPF_MEM, BPF_M_IPHLEN), - /* Add UDP length (A) to IP header length (X). */ - BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0), - /* Store result in X. */ - BPF_STMT(BPF_MISC + BPF_TAX, 0), - /* Copy IP length to A. */ - BPF_STMT(BPF_LD + BPF_MEM, BPF_M_IPLEN), - /* Ensure X == A. */ - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0), - BPF_STMT(BPF_RET + BPF_K, 0), - - /* Advance to the BOOTP packet. */ - BPF_STMT(BPF_LD + BPF_MEM, BPF_M_UDP), - BPF_STMT(BPF_ALU + BPF_ADD + BPF_K, sizeof(struct udphdr)), - BPF_STMT(BPF_MISC + BPF_TAX, 0), - - /* Make sure it's BOOTREPLY. */ - BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct bootp, op)), - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), - BPF_STMT(BPF_RET + BPF_K, 0), }; #define BPF_BOOTP_FILTER_LEN __arraycount(bpf_bootp_filter) @@ -665,6 +650,12 @@ bpf_bootp(struct interface *ifp, int fd) bp = bpf; /* Check frame header. */ switch(ifp->family) { +#ifdef ARPHRD_NONE + case ARPHRD_NONE: + memcpy(bp, bpf_bootp_none, sizeof(bpf_bootp_none)); + bp += BPF_BOOTP_NONE_LEN; + break; +#endif case ARPHRD_ETHER: memcpy(bp, bpf_bootp_ether, sizeof(bpf_bootp_ether)); bp += BPF_BOOTP_ETHER_LEN; @@ -714,14 +705,8 @@ bpf_bootp(struct interface *ifp, int fd) } #endif - /* All passed, return the packet - frame length + ip length */ - BPF_SET_STMT(bp, BPF_LD + BPF_MEM, BPF_M_FHLEN); - bp++; - BPF_SET_STMT(bp, BPF_LDX + BPF_MEM, BPF_M_IPLEN); - bp++; - BPF_SET_STMT(bp, BPF_ALU + BPF_ADD + BPF_X, 0); - bp++; - BPF_SET_STMT(bp, BPF_RET + BPF_A, 0); + /* All passed, return the packet. */ + BPF_SET_STMT(bp, BPF_RET + BPF_K, BPF_WHOLEPACKET); bp++; return bpf_attach(fd, bpf, (unsigned int)(bp - bpf));