From: Paul Mackerras Date: Thu, 4 Apr 1996 02:46:59 +0000 (+0000) Subject: Add support for packet filtering X-Git-Tag: RELEASE_2_3_6~514 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=ce773fec27f115f665ac7d9630eeb5f5484d5eb7 Add support for packet filtering --- diff --git a/include/net/bpf.h b/include/net/bpf.h new file mode 100644 index 0000000..c5f7c1f --- /dev/null +++ b/include/net/bpf.h @@ -0,0 +1,147 @@ +/* From: NetBSD: bpf.h,v 1.12 1995/09/27 18:30:40 thorpej Exp */ + +/* + * Copyright (c) 1990, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 8.1 (Berkeley) 6/10/93 + */ + +#ifndef _NET_BPF_H_ +#define _NET_BPF_H_ + +/* + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. + */ +#define BPF_ALIGNMENT sizeof(long) +#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + +#define BPF_MAXINSNS 512 +#define BPF_MAXBUFSIZE 0x8000 +#define BPF_MINBUFSIZE 32 + +/* + * Structure for BIOCSETF. + */ +struct bpf_program { + unsigned int bf_len; + struct bpf_insn *bf_insns; +}; + +/* + * The instruction encondings. + */ +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +/* + * The instruction data structure. + */ +struct bpf_insn { + unsigned short code; + unsigned char jt; + unsigned char jf; + int k; +}; + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k } + +#ifdef _KERNEL +int bpf_validate __P((struct bpf_insn *, int)); +u_int bpf_filter __P((struct bpf_insn *, u_char *, u_int, u_int)); +#endif + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#endif /* _NET_BPF_H_ */ diff --git a/include/net/pppio.h b/include/net/pppio.h index 547b798..d364aea 100644 --- a/include/net/pppio.h +++ b/include/net/pppio.h @@ -24,7 +24,7 @@ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. * - * $Id: pppio.h,v 1.6 1995/10/27 03:36:58 paulus Exp $ + * $Id: pppio.h,v 1.7 1996/04/04 02:46:59 paulus Exp $ */ #define _PPPIO(n) (('p' << 8) + (n)) @@ -47,6 +47,8 @@ #define PPPIO_BIND _PPPIO(145) /* bind to SAP */ #define PPPIO_NPMODE _PPPIO(146) /* set mode for handling data pkts */ #define PPPIO_GIDLE _PPPIO(147) /* get time since last data pkt */ +#define PPPIO_PASSFILT _PPPIO(148) /* set filter for packets to pass */ +#define PPPIO_ACTIVEFILT _PPPIO(149) /* set filter for "link active" pkts */ /* * Values for PPPIO_CFLAGS diff --git a/modules/bpf_filter.c b/modules/bpf_filter.c new file mode 100644 index 0000000..f47ed2c --- /dev/null +++ b/modules/bpf_filter.c @@ -0,0 +1,542 @@ +/* From NetBSD: bpf_filter.c,v 1.12 1996/02/13 22:00:00 christos Exp */ + +/* + * Copyright (c) 1990, 1991, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: @(#)bpf_filter.c 8.1 (Berkeley) 6/10/93 + * $Id: bpf_filter.c,v 1.1 1996/04/04 02:45:45 paulus Exp $ + */ + +#include +#include +#include +#include +#include "ppp_mod.h" + +#ifdef SVR4 +#ifndef __GNUC__ +#include /* for ntohl, etc. */ +#else +/* make sure we don't get the gnu "fixed" one! */ +#include "/usr/include/sys/byteorder.h" +#endif +#endif + +#ifdef OSF1 +#include +#endif +#include + +#ifdef AIX4 +#define _NETINET_IN_SYSTM_H_ +typedef u_long n_long; +#else +#include +#endif + +#if !(defined(__i386__) || defined(__m68k__)) /* any others? */ +#define BPF_ALIGN +#endif + +#ifndef BPF_ALIGN +#define EXTRACT_SHORT(p) ((ushort)ntohs(*(ushort *)p)) +#define EXTRACT_LONG(p) (ntohl(*(uint *)p)) +#else +#define EXTRACT_SHORT(p)\ + ((ushort)\ + ((ushort)*((u_char *)p+0)<<8|\ + (ushort)*((u_char *)p+1)<<0)) +#define EXTRACT_LONG(p)\ + ((uint)*((u_char *)p+0)<<24|\ + (uint)*((u_char *)p+1)<<16|\ + (uint)*((u_char *)p+2)<<8|\ + (uint)*((u_char *)p+3)<<0) +#endif + +#ifdef _KERNEL +#define MINDEX(len, m, k) \ +{ \ + len = m->b_wptr - m->b_rptr; \ + while (k >= len) { \ + k -= len; \ + m = m->b_cont; \ + if (m == 0) \ + return 0; \ + len = m->b_wptr - m->b_rptr; \ + } \ +} + +static int m_xword __P((mblk_t *, int, int *)); +static int m_xhalf __P((mblk_t *, int, int *)); + +static int +m_xword(m, k, err) + register mblk_t *m; + register int k, *err; +{ + register int len; + register uchar_t *cp, *np; + register mblk_t *m0; + + MINDEX(len, m, k); + cp = m->b_rptr + k; + if (len - k >= 4) { + *err = 0; + return EXTRACT_LONG(cp); + } + m0 = m->b_cont; + if (m0 == 0 || m0->b_wptr - m0->b_rptr + len - k < 4) + goto bad; + *err = 0; + np = m0->b_rptr; + switch (len - k) { + + case 1: + return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2]; + + case 2: + return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1]; + + default: + return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0]; + } + bad: + *err = 1; + return 0; +} + +static int +m_xhalf(m, k, err) + register mblk_t *m; + register int k, *err; +{ + register int len; + register uchar_t *cp; + register mblk_t *m0; + + MINDEX(len, m, k); + cp = m->b_rptr + k; + if (len - k >= 2) { + *err = 0; + return EXTRACT_SHORT(cp); + } + m0 = m->b_cont; + if (m0 == 0) + goto bad; + *err = 0; + return (cp[0] << 8) | m0->b_rptr[0]; + bad: + *err = 1; + return 0; +} +#endif + +#include + +/* + * Execute the filter program starting at pc on the packet p + * wirelen is the length of the original packet + * buflen is the amount of data present + */ +uint +bpf_filter(pc, p, wirelen, buflen) + register struct bpf_insn *pc; + register uchar_t *p; + uint wirelen; + register uint buflen; +{ + register uint A = 0, X = 0; + register int k; + int mem[BPF_MEMWORDS]; + + if (pc == 0) + /* + * No filter means accept all. + */ + return (uint)-1; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: +#ifdef _KERNEL + return 0; +#else + abort(); +#endif + case BPF_RET|BPF_K: + return (uint)pc->k; + + case BPF_RET|BPF_A: + return (uint)A; + + case BPF_LD|BPF_W|BPF_ABS: + k = pc->k; + if (k + sizeof(int) > buflen) { +#ifdef _KERNEL + int merr; + + if (buflen != 0) + return 0; + A = m_xword((mblk_t *)p, k, &merr); + if (merr != 0) + return 0; + continue; +#else + return 0; +#endif + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_ABS: + k = pc->k; + if (k + sizeof(short int) > buflen) { +#ifdef _KERNEL + int merr; + + if (buflen != 0) + return 0; + A = m_xhalf((mblk_t *)p, k, &merr); + continue; +#else + return 0; +#endif + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_ABS: + k = pc->k; + if (k >= buflen) { +#ifdef _KERNEL + register mblk_t *m; + register int len; + + if (buflen != 0) + return 0; + m = (mblk_t *)p; + MINDEX(len, m, k); + A = m->b_rptr[k]; + continue; +#else + return 0; +#endif + } + A = p[k]; + continue; + + case BPF_LD|BPF_W|BPF_LEN: + A = wirelen; + continue; + + case BPF_LDX|BPF_W|BPF_LEN: + X = wirelen; + continue; + + case BPF_LD|BPF_W|BPF_IND: + k = X + pc->k; + if (k + sizeof(int) > buflen) { +#ifdef _KERNEL + int merr; + + if (buflen != 0) + return 0; + A = m_xword((mblk_t *)p, k, &merr); + if (merr != 0) + return 0; + continue; +#else + return 0; +#endif + } + A = EXTRACT_LONG(&p[k]); + continue; + + case BPF_LD|BPF_H|BPF_IND: + k = X + pc->k; + if (k + sizeof(short int) > buflen) { +#ifdef _KERNEL + int merr; + + if (buflen != 0) + return 0; + A = m_xhalf((mblk_t *)p, k, &merr); + if (merr != 0) + return 0; + continue; +#else + return 0; +#endif + } + A = EXTRACT_SHORT(&p[k]); + continue; + + case BPF_LD|BPF_B|BPF_IND: + k = X + pc->k; + if (k >= buflen) { +#ifdef _KERNEL + register mblk_t *m; + register int len; + + if (buflen != 0) + return 0; + m = (mblk_t *)p; + MINDEX(len, m, k); + A = m->b_rptr[k]; + continue; +#else + return 0; +#endif + } + A = p[k]; + continue; + + case BPF_LDX|BPF_MSH|BPF_B: + k = pc->k; + if (k >= buflen) { +#ifdef _KERNEL + register mblk_t *m; + register int len; + + if (buflen != 0) + return 0; + m = (mblk_t *)p; + MINDEX(len, m, k); + X = (m->b_rptr[k] & 0xf) << 2; + continue; +#else + return 0; +#endif + } + X = (p[pc->k] & 0xf) << 2; + continue; + + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += (A > pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += (A >= pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += (A == pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; + + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + A = -A; + continue; + + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; + } + } +} + +#ifdef _KERNEL +/* + * Return true if the 'fcode' is a valid filter program. + * The constraints are that each jump be forward and to a valid + * code. The code must terminate with either an accept or reject. + * 'valid' is an array for use by the routine (it must be at least + * 'len' bytes long). + * + * The kernel needs to be able to verify an application's filter code. + * Otherwise, a bogus program could easily crash the system. + */ +int +bpf_validate(f, len) + struct bpf_insn *f; + int len; +{ + register int i; + register struct bpf_insn *p; + + for (i = 0; i < len; ++i) { + /* + * Check that that jumps are forward, and within + * the code block. + */ + p = &f[i]; + if (BPF_CLASS(p->code) == BPF_JMP) { + register int from = i + 1; + + if (BPF_OP(p->code) == BPF_JA) { + if (from + p->k >= len) + return 0; + } + else if (from + p->jt >= len || from + p->jf >= len) + return 0; + } + /* + * Check that memory operations use valid addresses. + */ + if ((BPF_CLASS(p->code) == BPF_ST || + (BPF_CLASS(p->code) == BPF_LD && + (p->code & 0xe0) == BPF_MEM)) && + (p->k >= BPF_MEMWORDS || p->k < 0)) + return 0; + /* + * Check for constant division by 0. + */ + if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) + return 0; + } + return BPF_CLASS(f[len - 1].code) == BPF_RET; +} +#endif diff --git a/modules/ppp.c b/modules/ppp.c index 0000cb1..97c40dd 100644 --- a/modules/ppp.c +++ b/modules/ppp.c @@ -24,7 +24,7 @@ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. * - * $Id: ppp.c,v 1.3 1996/01/01 22:48:39 paulus Exp $ + * $Id: ppp.c,v 1.4 1996/04/04 02:45:29 paulus Exp $ */ /* @@ -58,6 +58,7 @@ #endif /* SVR4 */ #include #include +#include #include "ppp_mod.h" #ifdef __STDC__ @@ -106,6 +107,8 @@ typedef struct upperstr { struct pppstat stats; /* statistics */ time_t last_sent; /* time last NP packet sent */ time_t last_recv; /* time last NP packet rcvd */ + struct bpf_program active_f;/* filter for active packets */ + struct bpf_program pass_f; /* filter for packets to pass */ #ifdef SOL2 kstat_t *kstats; /* stats for netstat */ #endif /* SOL2 */ @@ -378,6 +381,15 @@ pppclose(q, flag) kstat_delete(up->kstats); #endif + if (up->active_f.bf_insns) { + kmem_free(up->active_f.bf_insns, up->active_f.bf_len); + up->active_f.bf_insns = 0; + } + if (up->pass_f.bf_insns) { + kmem_free(up->pass_f.bf_insns, up->pass_f.bf_len); + up->pass_f.bf_insns = 0; + } + q->q_ptr = NULL; WR(q)->q_ptr = NULL; @@ -415,6 +427,9 @@ pppuwput(q, mp) int error, n, sap; mblk_t *mq; struct ppp_idle *pip; + int len; + struct bpf_insn *ip; + struct bpf_program *dest; us = (upperstr_t *) q->q_ptr; switch (mp->b_datap->db_type) { @@ -439,8 +454,10 @@ pppuwput(q, mp) break; } #ifdef NO_DLPI - if ((us->flags & US_CONTROL) == 0) - us->ppa->last_sent = time; + if (!pass_packet(us->ppa, mp, 1)) { + freemsg(mp); + break; + } #endif if (!send_data(mp, us)) putq(q, mp); @@ -652,6 +669,34 @@ pppuwput(q, mp) error = 0; break; + case PPPIO_PASSFILT: + case PPPIO_ACTIVEFILT: + if ((us->flags & US_CONTROL) == 0) + break; + len = iop->ioc_count; + if (len > BPF_MAXINSNS * sizeof(struct bpf_insn) + || len % sizeof(struct bpf_insn) != 0) + break; + if (len > 0) { + if (!bpf_validate((struct bpf_insn *) mp->b_cont->b_rptr, + len / sizeof(struct bpf_insn))) + break; + ip = (struct bpf_insn *) ALLOC_NOSLEEP(len); + if (ip == 0) { + error = ENOSR; + break; + } + bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)ip, len); + } else + ip = 0; + dest = iop->ioc_cmd == PPPIO_ACTIVEFILT? + &us->active_f: &us->pass_f; + if (dest->bf_insns != 0) + kmem_free((caddr_t) dest->bf_insns, dest->bf_len); + dest->bf_len = len; + dest->bf_insns = ip; + break; + #ifdef LACHTCP case SIOCSIFNAME: printf("SIOCSIFNAME\n"); @@ -960,7 +1005,6 @@ dlpi_request(q, mp, us) DPRINT2("dlpi data too large (%d > %d)\n", len, ppa->mtu); break; } - ppa->last_sent = time; /* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */ if (mp->b_datap->db_ref > 1) { np = allocb(PPP_HDRLEN, BPRI_HI); @@ -979,8 +1023,12 @@ dlpi_request(q, mp, us) mp->b_rptr[1] = PPP_UI; mp->b_rptr[2] = us->sap >> 8; mp->b_rptr[3] = us->sap; - if (!send_data(mp, us)) - putq(q, mp); + if (!pass_packet(ppa, mp, 1)) + freemsg(mp); + else { + if (!send_data(mp, us)) + putq(q, mp); + } return; #if DL_CURRENT_VERSION >= 2 @@ -1071,6 +1119,33 @@ dlpi_ok(q, prim) } #endif /* NO_DLPI */ +static int +pass_packet(ppa, mp, outbound) + upperstr_t *ppa; + mblk_t *mp; + int outbound; +{ + int len, adr, pass; + + if (PPP_PROTOCOL(mp->b_rptr) >= 0x8000 + || (ppa->pass_f.bf_insns == 0 && ppa->active_f.bf_insns == 0)) + return 1; + len = msgdsize(mp); + adr = *mp->b_rptr; + *mp->b_rptr = outbound; + pass = ppa->pass_f.bf_insns == 0 + || bpf_filter(ppa->pass_f.bf_insns, mp, len, 0); + if (pass && (ppa->active_f.bf_insns == 0 + || bpf_filter(ppa->active_f.bf_insns, mp, len, 0))) { + if (outbound) + ppa->last_sent = time; + else + ppa->last_recv = time; + } + *mp->b_rptr = adr; + return pass; +} + static int send_data(mp, us) mblk_t *mp; @@ -1444,6 +1519,10 @@ ppplrput(q, mp) #ifdef INCR_IPACKETS INCR_IPACKETS(ppa); #endif + if (!pass_packet(ppa, mp, 0)) { + freemsg(mp); + break; + } proto = PPP_PROTOCOL(mp->b_rptr); if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) { /* @@ -1454,7 +1533,6 @@ ppplrput(q, mp) putq(us->q, mp); else putq(q, mp); - ppa->last_recv = time; break; } }