-/* $Id: if_ppp.c,v 1.3 1996/07/01 01:03:38 paulus Exp $ */
+/* $Id: if_ppp.c,v 1.8 1998/03/25 04:04:37 paulus Exp $ */
/*
* if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver.
#include <sys/time.h>
#include <sys/malloc.h>
+#if NetBSD1_0 && defined(i386)
+#include <machine/psl.h>
+#endif
+
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
+#ifdef PPP_FILTER
+#include <net/bpf.h>
+#endif
#if INET
#include <netinet/in.h>
#include "bpfilter.h"
#if NBPFILTER > 0
+#include <sys/time.h>
#include <net/bpf.h>
#endif
#include <net/if_pppvar.h>
#include <machine/cpu.h>
+#if NetBSD1_0
+#define splsoftnet splnet
+#endif
+
#ifdef PPP_COMPRESS
#define PACKETPTR struct mbuf *
#include <net/ppp-comp.h>
#endif
+static int pppsioctl __P((struct ifnet *, u_long, caddr_t));
static void ppp_requeue __P((struct ppp_softc *));
-static void ppp_outpkt __P((struct ppp_softc *));
static void ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd));
static void ppp_ccp_closed __P((struct ppp_softc *));
static void ppp_inproc __P((struct ppp_softc *, struct mbuf *));
*/
extern struct compressor ppp_bsd_compress;
-extern struct compressor ppp_deflate;
+extern struct compressor ppp_deflate, ppp_deflate_draft;
struct compressor *ppp_compressors[8] = {
#if DO_BSD_COMPRESS
#endif
#if DO_DEFLATE
&ppp_deflate,
+ &ppp_deflate_draft,
#endif
NULL
};
bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
#endif
}
+
+#if NetBSD1_0 && defined(i386)
+ /*
+ * XXX kludge to fix the bug in the i386 interrupt handling code,
+ * where software interrupts could be taken while hardware
+ * interrupts were blocked.
+ */
+ if ((imask[IPL_TTY] & (1 << SIR_NET)) == 0) {
+ imask[IPL_TTY] |= (1 << SIR_NET);
+ intr_calculatemasks();
+ }
+#endif
}
/*
sc->sc_xc_state = NULL;
sc->sc_rc_state = NULL;
#endif /* PPP_COMPRESS */
+#ifdef PPP_FILTER
+ if (sc->sc_pass_filt.bf_insns != 0) {
+ FREE(sc->sc_pass_filt.bf_insns, M_DEVBUF);
+ sc->sc_pass_filt.bf_insns = 0;
+ sc->sc_pass_filt.bf_len = 0;
+ }
+ if (sc->sc_active_filt.bf_insns != 0) {
+ FREE(sc->sc_active_filt.bf_insns, M_DEVBUF);
+ sc->sc_active_filt.bf_insns = 0;
+ sc->sc_active_filt.bf_len = 0;
+ }
+#endif /* PPP_FILTER */
#ifdef VJC
if (sc->sc_comp != 0) {
FREE(sc->sc_comp, M_DEVBUF);
struct compressor **cp;
struct npioctl *npi;
time_t t;
+#ifdef PPP_FILTER
+ struct bpf_program *bp, *nbp;
+ struct bpf_insn *newcode, *oldcode;
+ int newcodelen;
+#endif /* PPP_FILTER */
#ifdef PPP_COMPRESS
u_char ccp_option[CCP_MAX_OPTION_LENGTH];
#endif
splx(s);
break;
-#if 0
+#ifdef PPP_FILTER
case PPPIOCSPASS:
case PPPIOCSACTIVE:
nbp = (struct bpf_program *) data;
/*
* Process an ioctl request to the ppp network interface.
*/
-int
+static int
pppsioctl(ifp, cmd, data)
register struct ifnet *ifp;
u_long cmd;
struct ip *ip;
struct ifqueue *ifq;
enum NPmode mode;
+ int len;
+ struct mbuf *m;
if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0
|| ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) {
*cp++ = protocol & 0xff;
m0->m_len += PPP_HDRLEN;
+ len = 0;
+ for (m = m0; m != 0; m = m->m_next)
+ len += m->m_len;
+
if (sc->sc_flags & SC_LOG_OUTPKT) {
printf("ppp%d output: ", ifp->if_unit);
pppdumpm(m0);
}
if ((protocol & 0x8000) == 0) {
+#ifdef PPP_FILTER
+ /*
+ * Apply the pass and active filters to the packet,
+ * but only if it is a data packet.
+ */
+ *mtod(m0, u_char *) = 1; /* indicates outbound */
+ if (sc->sc_pass_filt.bf_insns != 0
+ && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m0,
+ len, 0) == 0) {
+ error = 0; /* drop this packet */
+ goto bad;
+ }
+
+ /*
+ * Update the time we sent the most recent packet.
+ */
+ if (sc->sc_active_filt.bf_insns == 0
+ || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m0, len, 0))
+ sc->sc_last_sent = time.tv_sec;
+
+ *mtod(m0, u_char *) = address;
+#else
/*
* Update the time we sent the most recent data packet.
*/
sc->sc_last_sent = time.tv_sec;
+#endif /* PPP_FILTER */
}
#if NBPFILTER > 0
struct mbuf *m, *mp;
u_char *cp;
int address, control, protocol;
- int s;
/*
* Grab a packet to send: first try the fast queue, then the
for (mp = m; mp != NULL; mp = mp->m_next)
slen += mp->m_len;
clen = (*sc->sc_xcomp->compress)
- (sc->sc_xc_state, &mcomp, m, slen,
- (sc->sc_flags & SC_CCP_UP? sc->sc_if.if_mtu: 0));
+ (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN);
if (mcomp != NULL) {
- m_freem(m);
- m = mcomp;
- cp = mtod(m, u_char *);
- protocol = cp[3];
+ if (sc->sc_flags & SC_CCP_UP) {
+ /* Send the compressed packet instead of the original. */
+ m_freem(m);
+ m = mcomp;
+ cp = mtod(m, u_char *);
+ protocol = cp[3];
+ } else {
+ /* Can't transmit compressed packets until CCP is up. */
+ m_freem(mcomp);
+ }
}
}
#endif /* PPP_COMPRESS */
m->m_pkthdr.len = ilen;
m->m_pkthdr.rcvif = ifp;
- /*
- * Record the time that we received this packet.
- */
if ((proto & 0x8000) == 0) {
+#ifdef PPP_FILTER
+ /*
+ * See whether we want to pass this packet, and
+ * if it counts as link activity.
+ */
+ adrs = *mtod(m, u_char *); /* save address field */
+ *mtod(m, u_char *) = 0; /* indicate inbound */
+ if (sc->sc_pass_filt.bf_insns != 0
+ && bpf_filter(sc->sc_pass_filt.bf_insns, (u_char *) m,
+ ilen, 0) == 0) {
+ /* drop this packet */
+ m_freem(m);
+ return;
+ }
+ if (sc->sc_active_filt.bf_insns == 0
+ || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m, ilen, 0))
+ sc->sc_last_recv = time.tv_sec;
+
+ *mtod(m, u_char *) = adrs;
+#else
+ /*
+ * Record the time that we received this packet.
+ */
sc->sc_last_recv = time.tv_sec;
+#endif /* PPP_FILTER */
}
#if NBPFILTER > 0