* Robert Olsson <robert@robur.slu.se> and Paul Mackerras.
*/
-/* $Id: if_ppp.c,v 1.4 1994/12/08 00:32:59 paulus Exp $ */
+/* $Id: if_ppp.c,v 1.12 1996/09/26 06:18:37 paulus Exp $ */
/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
+/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
#include "ppp.h"
#if NPPP > 0
#include "../h/socket.h"
#include "../h/ioctl.h"
#include "../h/systm.h"
+#include "../h/time.h"
#include "../net/net/if.h"
#include "../net/net/netisr.h"
#include "../machine/mtpr.h"
#endif
-#include "ppp_defs.h"
-#include "if_ppp.h"
-
#ifdef VJC
#include "slcompress.h"
#endif
+#include "ppp_defs.h"
+#include "if_ppp.h"
#include "if_pppvar.h"
#ifdef PPP_COMPRESS
#include "ppp-comp.h"
#endif
-void pppattach __P((void));
-int pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag,
- struct proc *));
-int pppoutput __P((struct ifnet *ifp, struct mbuf *m0,
- struct sockaddr *dst));
-int pppsioctl __P((struct ifnet *ifp, int cmd, caddr_t data));
-void pppintr __P((void));
-
static void ppp_requeue __P((struct ppp_softc *));
static void ppp_outpkt __P((struct ppp_softc *));
-static int ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd));
+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 *));
static void pppdumpm __P((struct mbuf *m0));
*/
extern struct compressor ppp_bsd_compress;
+extern struct compressor ppp_deflate;
struct compressor *ppp_compressors[] = {
+#if DO_BSD_COMPRESS
&ppp_bsd_compress,
+#endif
+#if DO_DEFLATE
+ &ppp_deflate,
+#endif
NULL
};
#endif /* PPP_COMPRESS */
+
/*
* Called from boot code to establish ppp interfaces.
*/
sc->sc_flags = 0;
sc->sc_mru = PPP_MRU;
sc->sc_relinq = NULL;
+ bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats));
#ifdef VJC
- sl_compress_init(&sc->sc_comp);
+ KM_ALLOC(sc->sc_comp, struct slcompress *, sizeof(struct slcompress),
+ KM_DEVBUF, KM_NOARG);
+ if (sc->sc_comp)
+ sl_compress_init(sc->sc_comp);
#endif
#ifdef PPP_COMPRESS
sc->sc_xc_state = NULL;
sc->sc_npmode[i] = NPMODE_ERROR;
sc->sc_npqueue = NULL;
sc->sc_npqtail = &sc->sc_npqueue;
+ sc->sc_last_sent = sc->sc_last_recv = time.tv_sec;
return sc;
}
m_freem(m);
}
while ((m = sc->sc_npqueue) != NULL) {
- sc->sc_npqueue = m->m_nextpkt;
+ sc->sc_npqueue = m->m_act;
m_freem(m);
}
if (sc->sc_togo != NULL) {
sc->sc_xc_state = NULL;
sc->sc_rc_state = NULL;
#endif /* PPP_COMPRESS */
+#ifdef VJC
+ if (sc->sc_comp != 0) {
+ KM_FREE(sc->sc_comp, KM_DEVBUF);
+ sc->sc_comp = 0;
+ }
+#endif
}
/*
int cmd, flag;
{
struct proc *p = u.u_procp;
- int s, error, flags, mru, nb, npx;
+ int s, error, flags, mru, mtu, nb, npx;
struct ppp_option_data *odp;
struct compressor **cp;
struct npioctl *npi;
+ time_t t;
+#ifdef PPP_COMPRESS
u_char ccp_option[CCP_MAX_OPTION_LENGTH];
+#endif
switch (cmd) {
case FIONREAD:
return EPERM;
flags = *(int *)data & SC_MASK;
s = splnet();
+#ifdef PPP_COMPRESS
if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN))
ppp_ccp_closed(sc);
+#endif
splimp();
sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags;
splx(s);
*(int *)data = sc->sc_mru;
break;
+ /*
+ * PPPIOC[GS]MTU are implemented here, instead of supporting
+ * SIOC[GS]IFMTU in pppsioctl, because under Ultrix, we can't get an
+ * interface ioctl through to the interface until it has an IP
+ * address set.
+ */
+ case PPPIOCSMTU:
+ if (!suser())
+ return EPERM;
+ mtu = *(int *) data;
+ if (mtu <= 0 || mtu > PPP_MAXMRU)
+ return EINVAL;
+ s = splimp();
+ sc->sc_if.if_mtu = mtu;
+ splx(s);
+ break;
+
+ case PPPIOCGMTU:
+ *(int *) data = sc->sc_if.if_mtu;
+ break;
+
#ifdef VJC
case PPPIOCSMAXCID:
if (!suser())
return EPERM;
- s = splnet();
- sl_compress_setup(&sc->sc_comp, *(int *)data);
- splx(s);
+ if (sc->sc_comp) {
+ s = splnet();
+ sl_compress_setup(sc->sc_comp, *(int *)data);
+ splx(s);
+ }
break;
#endif
nb = odp->length;
if (nb > sizeof(ccp_option))
nb = sizeof(ccp_option);
- if (error = copyin(odp->ptr, ccp_option, nb))
+ if ((error = copyin(odp->ptr, ccp_option, nb)) != 0)
return (error);
if (ccp_option[1] < 2) /* preliminary check on the length byte */
return (EINVAL);
* a compressor or decompressor.
*/
error = 0;
- s = splnet();
if (odp->transmit) {
+ s = splnet();
if (sc->sc_xc_state != NULL)
(*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
sc->sc_xcomp = *cp;
}
splimp();
sc->sc_flags &= ~SC_COMP_RUN;
+ splx(s);
} else {
+ s = splnet();
if (sc->sc_rc_state != NULL)
(*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
sc->sc_rcomp = *cp;
}
splimp();
sc->sc_flags &= ~SC_DECOMP_RUN;
+ splx(s);
}
- splx(s);
return (error);
}
if (sc->sc_flags & SC_DEBUG)
if (!suser())
return EPERM;
if (npi->mode != sc->sc_npmode[npx]) {
- s = splimp();
+ s = splnet();
sc->sc_npmode[npx] = npi->mode;
if (npi->mode != NPMODE_QUEUE) {
ppp_requeue(sc);
}
break;
+ case PPPIOCGIDLE:
+ s = splnet();
+ t = time.tv_sec;
+ ((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
+ ((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
+ splx(s);
+ break;
+
default:
return (-1);
}
register struct ifaddr *ifa = (struct ifaddr *)data;
register struct ifreq *ifr = (struct ifreq *)data;
struct ppp_stats *psp;
+#ifdef PPP_COMPRESS
struct ppp_comp_stats *pcp;
+#endif
int s = splimp(), error = 0;
switch (cmd) {
error = EAFNOSUPPORT;
break;
+/*
+ * Ioctls other than the above don't get through until the
+ * interface has its IP addresses set :-(
+ */
+
+#if 0
case SIOCSIFMTU:
if (!suser())
return EPERM;
case SIOCGIFMTU:
ifr->ifr_mtu = sc->sc_if.if_mtu;
break;
+#endif
case SIOCGPPPSTATS:
psp = &((struct ifpppstatsreq *) data)->stats;
bzero(psp, sizeof(*psp));
- psp->p.ppp_ibytes = sc->sc_bytesrcvd;
- psp->p.ppp_ipackets = ifp->if_ipackets;
- psp->p.ppp_ierrors = ifp->if_ierrors;
- psp->p.ppp_obytes = sc->sc_bytessent;
- psp->p.ppp_opackets = ifp->if_opackets;
- psp->p.ppp_oerrors = ifp->if_oerrors;
-#ifdef VJC
- psp->vj.vjs_packets = sc->sc_comp.sls_packets;
- psp->vj.vjs_compressed = sc->sc_comp.sls_compressed;
- psp->vj.vjs_searches = sc->sc_comp.sls_searches;
- psp->vj.vjs_misses = sc->sc_comp.sls_misses;
- psp->vj.vjs_uncompressedin = sc->sc_comp.sls_uncompressedin;
- psp->vj.vjs_compressedin = sc->sc_comp.sls_compressedin;
- psp->vj.vjs_errorin = sc->sc_comp.sls_errorin;
- psp->vj.vjs_tossed = sc->sc_comp.sls_tossed;
+ psp->p = sc->sc_stats;
+#if defined(VJC) && !defined(SL_NO_STATS)
+ if (sc->sc_comp) {
+ psp->vj.vjs_packets = sc->sc_comp->sls_packets;
+ psp->vj.vjs_compressed = sc->sc_comp->sls_compressed;
+ psp->vj.vjs_searches = sc->sc_comp->sls_searches;
+ psp->vj.vjs_misses = sc->sc_comp->sls_misses;
+ psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin;
+ psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin;
+ psp->vj.vjs_errorin = sc->sc_comp->sls_errorin;
+ psp->vj.vjs_tossed = sc->sc_comp->sls_tossed;
+ }
#endif /* VJC */
break;
struct sockaddr *dst;
{
register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
- struct ppp_header *ph;
int protocol, address, control;
u_char *cp;
int s, error;
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) {
+ || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) {
error = ENETDOWN; /* sort of */
goto bad;
}
control = PPP_UI;
protocol = PPP_IP;
mode = sc->sc_npmode[NP_IP];
-
+
/*
* If this is a TCP packet to or from an "interactive" port,
* put the packet on the fastq instead.
*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) {
+ /*
+ * Update the time we sent the most recent data packet.
+ */
+ sc->sc_last_sent = time.tv_sec;
+ }
+
#if NBPFILTER > 0
/*
* See if bpf wants to look at the packet.
/*
* Put the packet on the appropriate queue.
*/
- s = splimp(); /* splnet should be OK now */
+ s = splnet();
if (mode == NPMODE_QUEUE) {
/* XXX we should limit the number of packets on this queue */
*sc->sc_npqtail = m0;
- m0->m_nextpkt = NULL;
- sc->sc_npqtail = &m0->m_nextpkt;
+ m0->m_act = NULL;
+ sc->sc_npqtail = &m0->m_act;
} else {
ifq = m0->m_context? &sc->sc_fastq: &ifp->if_snd;
- if (IF_QFULL(ifq)) {
+ if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) {
IF_DROP(ifq);
splx(s);
sc->sc_if.if_oerrors++;
+ sc->sc_stats.ppp_oerrors++;
error = ENOBUFS;
goto bad;
}
IF_ENQUEUE(ifq, m0);
(*sc->sc_start)(sc);
}
+ ifp->if_opackets++;
splx(s);
return (0);
/*
* After a change in the NPmode for some NP, move packets from the
* npqueue to the send queue or the fast queue as appropriate.
- * Should be called at splimp (actually splnet would probably suffice).
+ * Should be called at splnet.
*/
static void
ppp_requeue(sc)
/*
* This packet can now go on one of the queues to be sent.
*/
- *mpp = m->m_nextpkt;
- m->m_nextpkt = NULL;
- ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd;
+ *mpp = m->m_act;
+ m->m_act = NULL;
+ ifq = m->m_context? &sc->sc_fastq: &sc->sc_if.if_snd;
if (IF_QFULL(ifq)) {
IF_DROP(ifq);
sc->sc_if.if_oerrors++;
+ sc->sc_stats.ppp_oerrors++;
} else
IF_ENQUEUE(ifq, m);
break;
case NPMODE_DROP:
case NPMODE_ERROR:
- *mpp = m->m_nextpkt;
+ *mpp = m->m_act;
m_freem(m);
break;
case NPMODE_QUEUE:
- mpp = &m->m_nextpkt;
+ mpp = &m->m_act;
break;
}
}
}
/*
- * Get a packet to send. This procedure is intended to be called
- * at spltty()/splimp(), so it takes little time. If there isn't
- * a packet waiting to go out, it schedules a software interrupt
- * to prepare a new packet; the device start routine gets called
- * again when a packet is ready.
+ * Transmitter has finished outputting some stuff;
+ * remember to call sc->sc_start later at splnet.
*/
-struct mbuf *
-ppp_dequeue(sc)
+void
+ppp_restart(sc)
struct ppp_softc *sc;
{
- struct mbuf *m;
int s = splimp();
- m = sc->sc_togo;
- if (m) {
- /*
- * Had a packet waiting - send it.
- */
- sc->sc_togo = NULL;
- sc->sc_flags |= SC_TBUSY;
- splx(s);
- return m;
- }
- /*
- * Remember we wanted a packet and schedule a software interrupt.
- */
sc->sc_flags &= ~SC_TBUSY;
schednetisr(NETISR_PPP);
splx(s);
- return NULL;
-}
-
-/*
- * Software interrupt routine, called at splnet().
- */
-void
-pppintr()
-{
- struct ppp_softc *sc;
- int i, s;
- struct mbuf *m;
-
- s = splnet();
- sc = ppp_softc;
- for (i = 0; i < NPPP; ++i, ++sc) {
- if (!(sc->sc_flags & SC_TBUSY) && sc->sc_togo == NULL
- && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head))
- ppp_outpkt(sc);
- for (;;) {
- IF_DEQUEUE(&sc->sc_rawq, m);
- if (m == NULL)
- break;
- ppp_inproc(sc, m);
- }
- }
- splx(s);
}
/*
- * Grab another packet off a queue and apply VJ compression,
- * packet compression, address/control and/or protocol compression
- * if enabled. Should be called at splnet.
+ * Get a packet to send. This procedure is intended to be called at
+ * splnet, since it may involve time-consuming operations such as
+ * applying VJ compression, packet compression, address/control and/or
+ * protocol field compression to the packet.
*/
-static void
-ppp_outpkt(sc)
+struct mbuf *
+ppp_dequeue(sc)
struct ppp_softc *sc;
{
- int s;
struct mbuf *m, *mp;
u_char *cp;
int address, control, protocol;
- enum NPmode mode;
+ int s;
/*
* Grab a packet to send: first try the fast queue, then the
if (m == NULL)
IF_DEQUEUE(&sc->sc_if.if_snd, m);
if (m == NULL)
- return;
+ return NULL;
+
+ ++sc->sc_stats.ppp_opackets;
/*
* Extract the ppp header of the new packet.
protocol = PPP_PROTOCOL(cp);
switch (protocol) {
-#ifdef VJC
case PPP_IP:
+#ifdef VJC
/*
* If the packet is a TCP/IP packet, see if we can compress it.
*/
- if (sc->sc_flags & SC_COMP_TCP) {
+ if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) {
struct ip *ip;
int type;
}
/* this code assumes the IP/TCP header is in one non-shared mbuf */
if (ip->ip_p == IPPROTO_TCP) {
- type = sl_compress_tcp(mp, ip, &sc->sc_comp,
+ type = sl_compress_tcp(mp, ip, sc->sc_comp,
!(sc->sc_flags & SC_NO_TCP_CCID));
switch (type) {
case TYPE_UNCOMPRESSED_TCP:
cp[3] = protocol; /* update protocol in PPP header */
}
}
- break;
#endif /* VJC */
+ break;
#ifdef PPP_COMPRESS
case PPP_CCP:
#ifdef PPP_COMPRESS
if (protocol != PPP_LCP && protocol != PPP_CCP
&& sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
- struct mbuf *mcomp;
+ struct mbuf *mcomp = NULL;
int slen, clen;
slen = 0;
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_len;
}
- s = splimp();
- sc->sc_togo = m;
- (*sc->sc_start)(sc);
+ return m;
+}
+
+/*
+ * Software interrupt routine, called at splnet.
+ */
+void
+pppintr()
+{
+ struct ppp_softc *sc;
+ int i, s, s2;
+ struct mbuf *m;
+
+ sc = ppp_softc;
+ s = splnet();
+ for (i = 0; i < NPPP; ++i, ++sc) {
+ if (!(sc->sc_flags & SC_TBUSY)
+ && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) {
+ s2 = splimp();
+ sc->sc_flags |= SC_TBUSY;
+ splx(s2);
+ (*sc->sc_start)(sc);
+ }
+ for (;;) {
+ s2 = splimp();
+ IF_DEQUEUE(&sc->sc_rawq, m);
+ splx(s2);
+ if (m == NULL)
+ break;
+ ppp_inproc(sc, m);
+ }
+ }
splx(s);
}
* Handle a CCP packet. `rcvd' is 1 if the packet was received,
* 0 if it is about to be transmitted.
*/
-static int
+static void
ppp_ccp(sc, m, rcvd)
struct ppp_softc *sc;
struct mbuf *m;
u_char *dp, *ep;
struct mbuf *mp;
int slen, s;
- struct bsd_db *db;
/*
* Get a pointer to the data after the PPP header.
if (sc->sc_xc_state != NULL
&& (*sc->sc_xcomp->comp_init)
(sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
- sc->sc_if.if_unit, sc->sc_flags & SC_DEBUG)) {
+ sc->sc_if.if_unit, 0, sc->sc_flags & SC_DEBUG)) {
s = splimp();
sc->sc_flags |= SC_COMP_RUN;
splx(s);
/*
* Process a received PPP packet, doing decompression as necessary.
+ * Should be called at splnet.
*/
#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
TYPE_UNCOMPRESSED_TCP)
struct ppp_softc *sc;
struct mbuf *m;
{
- struct ifqueue *inq;
+ struct ifnet *ifp = &sc->sc_if;
+ struct ifqueue *inq, *lock;
int s, ilen, xlen, proto, rv;
u_char *cp, adrs, ctrl;
- struct mbuf *mp, *dmp, *pc;
+ struct mbuf *mp, *dmp = NULL, *pc;
u_char *iphdr;
u_int hlen;
- sc->sc_if.if_ipackets++;
+ sc->sc_stats.ppp_ipackets++;
if (sc->sc_flags & SC_LOG_INPKT) {
- printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen);
+ ilen = 0;
+ for (mp = m; mp != NULL; mp = mp->m_next)
+ ilen += mp->m_len;
+ printf("ppp%d: got %d bytes\n", ifp->if_unit, ilen);
pppdumpm(m);
}
&& !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) {
/* decompress this packet */
rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp);
- if (dmp != NULL) {
+ if (rv == DECOMP_OK) {
m_freem(m);
+ if (dmp == NULL) {
+ /* no error, but no decompressed packet produced */
+ return;
+ }
m = dmp;
cp = mtod(m, u_char *);
proto = PPP_PROTOCOL(cp);
} else {
- /* pass the compressed packet up to pppd, which may take
- CCP down or issue a Reset-Req. */
+ /*
+ * An error has occurred in decompression.
+ * Pass the compressed packet up to pppd, which may take
+ * CCP down or issue a Reset-Req.
+ */
if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: decompress failed %d\n", sc->sc_if.if_unit, rv);
+ printf("ppp%d: decompress failed %d\n", ifp->if_unit, rv);
s = splimp();
sc->sc_flags |= SC_VJ_RESET;
- switch (rv) {
- case DECOMP_OK:
- /* no error, but no decompressed packet produced */
- splx(s);
- m_freem(m);
- return;
- case DECOMP_ERROR:
+ if (rv == DECOMP_ERROR)
sc->sc_flags |= SC_DC_ERROR;
- break;
- case DECOMP_FATALERROR:
+ else
sc->sc_flags |= SC_DC_FERROR;
- break;
- }
splx(s);
}
* If we've missed a packet, we must toss subsequent compressed
* packets which don't have an explicit connection ID.
*/
- sl_uncompress_tcp(NULL, 0, TYPE_ERROR, &sc->sc_comp);
+ if (sc->sc_comp)
+ sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp);
s = splimp();
sc->sc_flags &= ~SC_VJ_RESET;
splx(s);
* See if we have a VJ-compressed packet to uncompress.
*/
if (proto == PPP_VJC_COMP) {
- if (sc->sc_flags & SC_REJ_COMP_TCP)
+ if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
goto bad;
xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP,
- &sc->sc_comp, &iphdr, &hlen);
+ sc->sc_comp, &iphdr, &hlen);
if (xlen <= 0) {
if (sc->sc_flags & SC_DEBUG)
printf("ppp%d: VJ uncompress failed on type comp\n",
- sc->sc_if.if_unit);
+ ifp->if_unit);
goto bad;
}
ilen += hlen - xlen;
} else if (proto == PPP_VJC_UNCOMP) {
- if (sc->sc_flags & SC_REJ_COMP_TCP)
+ if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
goto bad;
xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP,
- &sc->sc_comp, &iphdr, &hlen);
+ sc->sc_comp, &iphdr, &hlen);
if (xlen < 0) {
if (sc->sc_flags & SC_DEBUG)
printf("ppp%d: VJ uncompress failed on type uncomp\n",
- sc->sc_if.if_unit);
+ ifp->if_unit);
goto bad;
}
}
}
+ /*
+ * Record the time that we received this packet.
+ */
+ if ((proto & 0x8000) == 0) {
+ sc->sc_last_recv = time.tv_sec;
+ }
+
#if NBPFILTER > 0
/* See if bpf wants to look at the packet. */
if (sc->sc_bpf)
/*
* IP packet - take off the ppp header and pass it up to IP.
*/
- if ((sc->sc_if.if_flags & IFF_UP) == 0
+ if ((ifp->if_flags & IFF_UP) == 0
|| sc->sc_npmode[NP_IP] != NPMODE_PASS) {
/* interface is down - drop the packet. */
m_freem(m);
smp_lock(&lock->lk_ifqueue, LK_RETRY);
if (IF_QFULL(inq)) {
IF_DROP(inq);
- /* XXX should we unlock here? */
+ smp_unlock(&lock->lk_ifqueue);
splx(s);
if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: input queue full\n", sc->sc_if.if_unit);
+ printf("ppp%d: input queue full\n", ifp->if_unit);
goto bad;
}
IF_ENQUEUEIF(inq, m, &sc->sc_if);
smp_unlock(&lock->lk_ifqueue);
splx(s);
+ ifp->if_ipackets++;
if (rv)
(*sc->sc_ctlp)(sc);
bad:
m_freem(m);
sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
}
#define MAX_DUMP_BYTES 128