]> git.ozlabs.org Git - ppp.git/blobdiff - svr4/ppp.c
use cc; sources from modules dir
[ppp.git] / svr4 / ppp.c
diff --git a/svr4/ppp.c b/svr4/ppp.c
deleted file mode 100644 (file)
index 43afb95..0000000
+++ /dev/null
@@ -1,1578 +0,0 @@
-/*
- * ppp.c - STREAMS multiplexing pseudo-device driver for PPP.
- *
- * Copyright (c) 1994 The Australian National University.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation is hereby granted, provided that the above copyright
- * notice appears in all copies.  This software is provided without any
- * warranty, express or implied. The Australian National University
- * makes no representations about the suitability of this software for
- * any purpose.
- *
- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
- * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
- * OR MODIFICATIONS.
- *
- * $Id: ppp.c,v 1.7 1995/10/27 03:55:56 paulus Exp $
- */
-
-/*
- * This file is used under Solaris 2.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/conf.h>
-#include <sys/dlpi.h>
-#include <sys/ioccom.h>
-#include <sys/kmem.h>
-#include <sys/ddi.h>
-#ifdef sun
-#include <sys/modctl.h>
-#include <sys/kstat.h>
-#include <sys/sunddi.h>
-#else
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#endif
-#include <net/ppp_defs.h>
-#include <net/pppio.h>
-
-#ifdef __STDC__
-#define __P(x) x
-#else
-#define __P(x) ()
-#endif
-
-/*
- * The IP module uses this SAP value for IP packets.
- */
-#ifndef ETHERTYPE_IP
-#define ETHERTYPE_IP   0x800
-#endif
-
-#ifndef PPP_MAXMTU
-#define PPP_MAXMTU     65535
-#endif
-
-/*
- * Private information; one per upper stream.
- */
-typedef struct upperstr {
-    minor_t mn;                        /* minor device number */
-    struct upperstr *nextmn;   /* next minor device */
-    queue_t *q;                        /* read q associated with this upper stream */
-    int flags;                 /* flag bits, see below */
-    int state;                 /* current DLPI state */
-    int sap;                   /* service access point */
-    int req_sap;               /* which SAP the DLPI client requested */
-    struct upperstr *ppa;      /* control stream for our ppa */
-    struct upperstr *next;     /* next stream for this ppa */
-    uint ioc_id;               /* last ioctl ID for this stream */
-    /*
-     * There is exactly one control stream for each PPA.
-     * The following fields are only used for control streams.
-     */
-    int ppa_id;
-    queue_t *lowerq;           /* write queue attached below this PPA */
-    struct upperstr *nextppa;  /* next control stream */
-    int mru;
-    int mtu;
-    struct pppstat stats;      /* statistics */
-#ifdef sun
-    kstat_t *kstats;           /* stats for netstat */
-#else
-    int ifflags;
-    char ifname[IFNAMSIZ];
-    struct ifstats ifstats;
-#endif
-} upperstr_t;
-
-/* Values for flags */
-#define US_PRIV                1       /* stream was opened by superuser */
-#define US_CONTROL     2       /* stream is a control stream */
-#define US_BLOCKED     4       /* flow ctrl has blocked lower write stream */
-#define US_LASTMOD     8       /* no PPP modules below us */
-#define US_DBGLOG      0x10    /* log various occurrences */
-
-static upperstr_t *minor_devs = NULL;
-static upperstr_t *ppas = NULL;
-
-#ifdef sun
-static int ppp_identify __P((dev_info_t *));
-static int ppp_attach __P((dev_info_t *, ddi_attach_cmd_t));
-static int ppp_detach __P((dev_info_t *, ddi_detach_cmd_t));
-static int ppp_devinfo __P((dev_info_t *, ddi_info_cmd_t, void *, void **));
-#endif
-static int pppopen __P((queue_t *, dev_t *, int, int, cred_t *));
-static int pppclose __P((queue_t *, int, cred_t *));
-static int pppuwput __P((queue_t *, mblk_t *));
-static int pppursrv __P((queue_t *));
-static int pppuwsrv __P((queue_t *));
-static int ppplrput __P((queue_t *, mblk_t *));
-static int ppplwput __P((queue_t *, mblk_t *));
-static int ppplrsrv __P((queue_t *));
-static int ppplwsrv __P((queue_t *));
-static void dlpi_request __P((queue_t *, mblk_t *, upperstr_t *));
-static void dlpi_error __P((queue_t *, int, int, int));
-static void dlpi_ok __P((queue_t *, int));
-static int send_data __P((mblk_t *, upperstr_t *));
-static void new_ppa __P((queue_t *, mblk_t *));
-static void attach_ppa __P((queue_t *, mblk_t *));
-static void detach_ppa __P((queue_t *, mblk_t *));
-static void debug_dump __P((queue_t *, mblk_t *));
-static upperstr_t *find_dest __P((upperstr_t *, int));
-static int putctl2 __P((queue_t *, int, int, int));
-static int putctl4 __P((queue_t *, int, int, int));
-
-static struct module_info ppp_info = {
-    0xb1a6, "ppp", 0, 512, 512, 128
-};
-
-static struct qinit pppurint = {
-    NULL, pppursrv, pppopen, pppclose, NULL, &ppp_info, NULL
-};
-
-static struct qinit pppuwint = {
-    pppuwput, pppuwsrv, NULL, NULL, NULL, &ppp_info, NULL
-};
-
-static struct qinit ppplrint = {
-    ppplrput, ppplrsrv, NULL, NULL, NULL, &ppp_info, NULL
-};
-
-static struct qinit ppplwint = {
-    ppplwput, ppplwsrv, NULL, NULL, NULL, &ppp_info, NULL
-};
-
-#ifndef sun
-extern struct ifstats *ifstats;
-int pppdevflag = 0;
-#else
-static
-#endif
-struct streamtab pppinfo = {
-    &pppurint, &pppuwint,
-    &ppplrint, &ppplwint
-};
-
-#ifdef sun
-static dev_info_t *ppp_dip;
-
-static struct cb_ops cb_ppp_ops = {
-    nulldev, nulldev, nodev, nodev,    /* cb_open, ... */
-    nodev, nodev, nodev, nodev,                /* cb_dump, ... */
-    nodev, nodev, nodev, nochpoll,     /* cb_devmap, ... */
-    ddi_prop_op,                       /* cb_prop_op */
-    &pppinfo,                          /* cb_stream */
-    D_NEW|D_MP|D_MTQPAIR|D_MTOUTPERIM|D_MTOCEXCL       /* cb_flag */
-};
-
-static struct dev_ops ppp_ops = {
-    DEVO_REV,                          /* devo_rev */
-    0,                                 /* devo_refcnt */
-    ppp_devinfo,                       /* devo_getinfo */
-    ppp_identify,                      /* devo_identify */
-    nulldev,                           /* devo_probe */
-    ppp_attach,                                /* devo_attach */
-    ppp_detach,                                /* devo_detach */
-    nodev,                             /* devo_reset */
-    &cb_ppp_ops,                       /* devo_cb_ops */
-    NULL                               /* devo_bus_ops */
-};
-
-/*
- * Module linkage information
- */
-
-static struct modldrv modldrv = {
-    &mod_driverops,                    /* says this is a pseudo driver */
-    "PPP-2.2 multiplexing driver",
-    &ppp_ops                           /* driver ops */
-};
-
-static struct modlinkage modlinkage = {
-    MODREV_1,
-    (void *) &modldrv,
-    NULL
-};
-
-int
-_init(void)
-{
-    return mod_install(&modlinkage);
-}
-
-int
-_fini(void)
-{
-    return mod_remove(&modlinkage);
-}
-
-int
-_info(mip)
-    struct modinfo *mip;
-{
-    return mod_info(&modlinkage, mip);
-}
-
-static int
-ppp_identify(dip)
-    dev_info_t *dip;
-{
-    return strcmp(ddi_get_name(dip), "ppp") == 0? DDI_IDENTIFIED:
-       DDI_NOT_IDENTIFIED;
-}
-
-static int
-ppp_attach(dip, cmd)
-    dev_info_t *dip;
-    ddi_attach_cmd_t cmd;
-{
-
-    if (cmd != DDI_ATTACH)
-       return DDI_FAILURE;
-    if (ddi_create_minor_node(dip, "ppp", S_IFCHR, 0, DDI_PSEUDO, CLONE_DEV)
-       == DDI_FAILURE) {
-       ddi_remove_minor_node(dip, NULL);
-       return DDI_FAILURE;
-    }
-    return DDI_SUCCESS;
-}
-
-static int
-ppp_detach(dip, cmd)
-    dev_info_t *dip;
-    ddi_detach_cmd_t cmd;
-{
-    ddi_remove_minor_node(dip, NULL);
-    return DDI_SUCCESS;
-}
-
-static int
-ppp_devinfo(dip, cmd, arg, result)
-    dev_info_t *dip;
-    ddi_info_cmd_t cmd;
-    void *arg;
-    void **result;
-{
-    int error;
-
-    error = DDI_SUCCESS;
-    switch (cmd) {
-    case DDI_INFO_DEVT2DEVINFO:
-       if (ppp_dip == NULL)
-           error = DDI_FAILURE;
-       else
-           *result = (void *) ppp_dip;
-       break;
-    case DDI_INFO_DEVT2INSTANCE:
-       *result = NULL;
-       break;
-    default:
-       error = DDI_FAILURE;
-    }
-    return error;
-}
-#endif /* sun */
-
-#ifndef sun
-#define put(q, mp)     ((*(q)->q_qinfo->qi_putp)((q), (mp)))
-# define qprocson(q)
-# define qprocsoff(q)
-# define canputnext(q) canput((q)->q_next)
-# define qwriter(q, mp, func, scope)   (func)((q), (mp))
-#endif
-
-static int
-pppopen(q, devp, oflag, sflag, credp)
-    queue_t *q;
-    dev_t *devp;
-    int oflag, sflag;
-    cred_t *credp;
-{
-    upperstr_t *up;
-    upperstr_t **prevp;
-    minor_t mn;
-
-    if (q->q_ptr)
-       return 0;               /* device is already open */
-
-    if (sflag == CLONEOPEN) {
-       mn = 0;
-       for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) {
-           if (up->mn != mn)
-               break;
-           ++mn;
-       }
-    } else {
-       mn = getminor(*devp);
-       for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) {
-           if (up->mn >= mn)
-               break;
-       }
-       if (up->mn == mn) {
-           /* this can't happen */
-           q->q_ptr = WR(q)->q_ptr = up;
-           return 0;
-       }
-    }
-
-    /*
-     * Construct a new minor node.
-     */
-    up = (upperstr_t *) kmem_zalloc(sizeof(upperstr_t), KM_SLEEP);
-    if (up == 0) {
-       cmn_err(CE_CONT, "pppopen: out of kernel memory\n");
-       return ENXIO;
-    }
-    up->nextmn = *prevp;
-    *prevp = up;
-    up->mn = mn;
-    *devp = makedevice(getmajor(*devp), mn);
-    up->q = q;
-    if (drv_priv(credp) == 0)
-       up->flags |= US_PRIV;
-    up->state = DL_UNATTACHED;
-#ifndef sun
-    up->ifflags = IFF_UP | IFF_POINTOPOINT;
-#endif
-    up->sap = -1;
-    q->q_ptr = up;
-    WR(q)->q_ptr = up;
-    noenable(WR(q));
-
-    qprocson(q);
-    return 0;
-}
-
-static int
-pppclose(q, flag, credp)
-    queue_t *q;
-    int flag;
-    cred_t *credp;
-{
-    upperstr_t *up, **upp;
-    upperstr_t *as, *asnext;
-    upperstr_t **prevp;
-
-    qprocsoff(q);
-
-    up = (upperstr_t *) q->q_ptr;
-    if (up->flags & US_DBGLOG)
-       cmn_err(CE_CONT, "ppp/%d: close, flags=%x\n", up->mn, up->flags);
-    if (up == 0)
-       return 0;
-    if (up->flags & US_CONTROL) {
-#ifndef sun
-       struct ifstats *ifp, *pifp;
-#endif
-       /*
-        * This stream represents a PPA:
-        * For all streams attached to the PPA, clear their
-        * references to this PPA.
-        * Then remove this PPA from the list of PPAs.
-        */
-       for (as = up->next; as != 0; as = asnext) {
-           asnext = as->next;
-           as->next = 0;
-           as->ppa = 0;
-           if (as->flags & US_BLOCKED) {
-               as->flags &= ~US_BLOCKED;
-               flushq(WR(as->q), FLUSHDATA);
-           }
-       }
-       for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa)
-           if (*upp == up) {
-               *upp = up->nextppa;
-               break;
-           }
-#ifndef sun
-       /* Remove the statistics from the active list.  */
-       for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) {
-           if (ifp == &up->ifstats) {
-               if (pifp)
-                   pifp->ifs_next = ifp->ifs_next;
-               else
-                   ifstats = ifp->ifs_next;
-               break;
-           }
-           pifp = ifp;
-       }
-#endif
-    } else {
-       /*
-        * If this stream is attached to a PPA,
-        * remove it from the PPA's list.
-        */
-       if ((as = up->ppa) != 0) {
-           for (; as->next != 0; as = as->next)
-               if (as->next == up) {
-                   as->next = up->next;
-                   break;
-               }
-       }
-    }
-
-#ifdef sun
-    if (up->kstats)
-       kstat_delete(up->kstats);
-#endif
-
-    q->q_ptr = NULL;
-    WR(q)->q_ptr = NULL;
-
-    for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) {
-       if (*prevp == up) {
-           *prevp = up->nextmn;
-           break;
-       }
-    }
-    kmem_free(up, sizeof(upperstr_t));
-
-    return 0;
-}
-
-/*
- * A message from on high.  We do one of three things:
- *     - qreply()
- *     - put the message on the lower write stream
- *     - queue it for our service routine
- */
-static int
-pppuwput(q, mp)
-    queue_t *q;
-    mblk_t *mp;
-{
-    upperstr_t *us, *usnext, *ppa;
-    struct iocblk *iop;
-    struct linkblk *lb;
-#ifndef sun
-    struct ifreq *ifr;
-    int i;
-#endif
-    queue_t *lq;
-    int error, n;
-    mblk_t *mq;
-
-    us = (upperstr_t *) q->q_ptr;
-    switch (mp->b_datap->db_type) {
-    case M_PCPROTO:
-    case M_PROTO:
-       dlpi_request(q, mp, us);
-       break;
-
-    case M_DATA:
-       if (us->flags & US_DBGLOG)
-           cmn_err(CE_CONT, "ppp/%d: uwput M_DATA len=%d flags=%x\n",
-                   us->mn, msgdsize(mp), us->flags);
-       if ((us->flags & US_CONTROL) == 0
-           || msgdsize(mp) > us->mtu + PPP_HDRLEN) {
-#if DEBUG
-           cmn_err(CE_CONT, "pppuwput: junk data len=%d\n", msgdsize(mp));
-#endif
-           freemsg(mp);
-           break;
-       }
-       if (!send_data(mp, us))
-           putq(q, mp);
-       break;
-
-    case M_IOCTL:
-       iop = (struct iocblk *) mp->b_rptr;
-       error = EINVAL;
-       if (us->flags & US_DBGLOG)
-           cmn_err(CE_CONT, "ppp/%d: ioctl %x count=%d\n",
-                   us->mn, iop->ioc_cmd, iop->ioc_count);
-       switch (iop->ioc_cmd) {
-       case I_LINK:
-           if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0)
-               break;
-           lb = (struct linkblk *) mp->b_cont->b_rptr;
-           us->lowerq = lq = lb->l_qbot;
-           lq->q_ptr = us;
-           RD(lq)->q_ptr = us;
-           noenable(RD(lq));
-           iop->ioc_count = 0;
-           error = 0;
-           us->flags &= ~US_LASTMOD;
-           /* Unblock upper streams which now feed this lower stream. */
-           qenable(lq);
-           /* Send useful information down to the modules which
-              are now linked below us. */
-           putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id);
-           putctl4(lq, M_CTL, PPPCTL_MRU, us->mru);
-           putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu);
-           break;
-
-       case I_UNLINK:
-           lb = (struct linkblk *) mp->b_cont->b_rptr;
-#if DEBUG
-           if (us->lowerq != lb->l_qbot)
-               cmn_err(CE_CONT, "ppp unlink: lowerq=%x qbot=%x\n",
-                       us->lowerq, lb->l_qbot);
-#endif
-           us->lowerq = 0;
-           iop->ioc_count = 0;
-           error = 0;
-           /* Unblock streams which now feed back up the control stream. */
-           qenable(us->q);
-           break;
-
-       case PPPIO_NEWPPA:
-           if (us->flags & US_CONTROL)
-               break;
-           if ((us->flags & US_PRIV) == 0) {
-               error = EPERM;
-               break;
-           }
-           /* Arrange to return an int */
-           if ((mq = mp->b_cont) == 0
-               || mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) {
-               mq = allocb(sizeof(int), BPRI_HI);
-               if (mq == 0) {
-                   error = ENOSR;
-                   break;
-               }
-               if (mp->b_cont != 0)
-                   freemsg(mp->b_cont);
-               mp->b_cont = mq;
-               mq->b_cont = 0;
-           }
-           iop->ioc_count = sizeof(int);
-           mq->b_wptr = mq->b_rptr + sizeof(int);
-           qwriter(q, mp, new_ppa, PERIM_OUTER);
-           error = -1;
-           break;
-
-       case PPPIO_ATTACH:
-           /* like dlpi_attach, for programs which can't write to
-              the stream (like pppstats) */
-           if (iop->ioc_count != sizeof(int) || us->ppa != 0)
-               break;
-           n = *(int *)mp->b_cont->b_rptr;
-           for (ppa = ppas; ppa != 0; ppa = ppa->nextppa)
-               if (ppa->ppa_id == n)
-                   break;
-           if (ppa == 0)
-               break;
-           us->ppa = ppa;
-           iop->ioc_count = 0;
-           qwriter(q, mp, attach_ppa, PERIM_OUTER);
-           error = -1;
-           break;
-
-       case PPPIO_MRU:
-           if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0)
-               break;
-           n = *(int *)mp->b_cont->b_rptr;
-           if (n <= 0 || n > PPP_MAXMTU)
-               break;
-           if (n < PPP_MRU)
-               n = PPP_MRU;
-           us->mru = n;
-           if (us->lowerq)
-               putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n);
-           error = 0;
-           iop->ioc_count = 0;
-           break;
-
-       case PPPIO_MTU:
-           if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0)
-               break;
-           n = *(int *)mp->b_cont->b_rptr;
-           if (n <= 0 || n > PPP_MAXMTU)
-               break;
-           if (n < PPP_MRU)
-               n = PPP_MRU;
-           us->mtu = n;
-#ifndef sun
-           us->ifstats.ifs_mtu = n;
-#endif
-           if (us->lowerq)
-               putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n);
-           error = 0;
-           iop->ioc_count = 0;
-           break;
-
-       case PPPIO_LASTMOD:
-           us->flags |= US_LASTMOD;
-           error = 0;
-           break;
-
-       case PPPIO_DEBUG:
-           if (iop->ioc_count != sizeof(int))
-               break;
-           n = *(int *)mp->b_cont->b_rptr;
-           if (n == PPPDBG_DUMP + PPPDBG_DRIVER) {
-               qwriter(q, NULL, debug_dump, PERIM_OUTER);
-               iop->ioc_count = 0;
-               error = 0;
-           } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) {
-               cmn_err(CE_CONT, "ppp/%d: debug log enabled\n", us->mn);
-               us->flags |= US_DBGLOG;
-               iop->ioc_count = 0;
-               error = 0;
-           } else {
-               if (us->ppa == 0 || us->ppa->lowerq == 0)
-                   break;
-               putnext(us->ppa->lowerq, mp);
-               error = -1;
-           }
-           break;
-
-#ifndef sun
-       case SIOCSIFNAME:
-           printf("SIOCSIFNAME\n");
-           /* Sent from IP down to us.  Attach the ifstats structure.  */
-           if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0)
-               break;
-           ifr = (struct ifreq *)mp->b_cont->b_rptr;
-           /* Find the unit number in the interface name.  */
-           for (i = 0; i < IFNAMSIZ; i++) {
-               if (ifr->ifr_name[i] == 0 ||
-                   (ifr->ifr_name[i] >= '0' &&
-                    ifr->ifr_name[i] <= '9'))
-                   break;
-               else
-                   us->ifname[i] = ifr->ifr_name[i];
-           }
-           us->ifname[i] = 0;
-
-           /* Convert the unit number to binary.  */
-           for (n = 0; i < IFNAMSIZ; i++) {
-               if (ifr->ifr_name[i] == 0) {
-                   break;
-               }
-               else {
-                   n = n * 10 + ifr->ifr_name[i] - '0';
-               }
-           }
-
-           /* Verify the ppa.  */
-           if (us->ppa->ppa_id != n)
-               break;
-           ppa = us->ppa;
-
-           /* Set up the netstat block.  */
-           strncpy (ppa->ifname, us->ifname, IFNAMSIZ);
-
-           ppa->ifstats.ifs_name = ppa->ifname;
-           ppa->ifstats.ifs_unit = n;
-           ppa->ifstats.ifs_active = us->state != DL_UNBOUND;
-           ppa->ifstats.ifs_mtu = ppa->mtu;
-
-           /* Link in statistics used by netstat.  */
-           ppa->ifstats.ifs_next = ifstats;
-           ifstats = &ppa->ifstats;
-
-           iop->ioc_count = 0;
-           error = 0;
-           break;
-
-       case SIOCGIFFLAGS:
-           printf("SIOCGIFFLAGS\n");
-           if (!(us->flags & US_CONTROL)) {
-               if (us->ppa)
-                   us = us->ppa;
-               else
-                   break;
-           }
-           ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags;
-           error = 0;
-           break;
-
-       case SIOCSIFFLAGS:
-           printf("SIOCSIFFLAGS\n");
-           if (!(us->flags & US_CONTROL)) {
-               if (us->ppa)
-                   us = us->ppa;
-               else
-                   break;
-           }
-           us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags;
-           error = 0;
-           break;
-
-       case SIOCSIFADDR:
-           printf("SIOCSIFADDR\n");
-           if (!(us->flags & US_CONTROL)) {
-               if (us->ppa)
-                   us = us->ppa;
-               else
-                   break;
-           }
-           us->ifflags |= IFF_RUNNING;
-           ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING;
-           error = 0;
-           break;
-
-       case SIOCGIFNETMASK:
-       case SIOCSIFNETMASK:
-       case SIOCGIFADDR:
-       case SIOCGIFDSTADDR:
-       case SIOCSIFDSTADDR:
-       case SIOCGIFMETRIC:
-           error = 0;
-           break;
-#endif
-
-       default:
-           if (us->ppa == 0 || us->ppa->lowerq == 0)
-               break;
-           us->ioc_id = iop->ioc_id;
-           error = -1;
-           switch (iop->ioc_cmd) {
-           case PPPIO_GETSTAT:
-           case PPPIO_GETCSTAT:
-               if (us->flags & US_LASTMOD) {
-                   error = EINVAL;
-                   break;
-               }
-               putnext(us->ppa->lowerq, mp);
-               break;
-           default:
-               if (us->flags & US_PRIV)
-                   putnext(us->ppa->lowerq, mp);
-               else {
-#if DEBUG
-                   cmn_err(CE_CONT, "ppp ioctl %x rejected\n", iop->ioc_cmd);
-#endif
-                   error = EPERM;
-               }
-               break;
-           }
-           break;
-       }
-
-       if (error > 0) {
-           iop->ioc_error = error;
-           mp->b_datap->db_type = M_IOCNAK;
-           qreply(q, mp);
-       } else if (error == 0) {
-           mp->b_datap->db_type = M_IOCACK;
-           qreply(q, mp);
-       }
-       break;
-
-    case M_FLUSH:
-       if (us->flags & US_DBGLOG)
-           cmn_err(CE_CONT, "ppp/%d: flush %x\n", us->mn, *mp->b_rptr);
-       if (*mp->b_rptr & FLUSHW)
-           flushq(q, FLUSHDATA);
-       if (*mp->b_rptr & FLUSHR) {
-           *mp->b_rptr &= ~FLUSHW;
-           qreply(q, mp);
-       } else
-           freemsg(mp);
-       break;
-
-    default:
-       freemsg(mp);
-       break;
-    }
-    return 0;
-}
-
-static void
-dlpi_request(q, mp, us)
-    queue_t *q;
-    mblk_t *mp;
-    upperstr_t *us;
-{
-    union DL_primitives *d = (union DL_primitives *) mp->b_rptr;
-    int size = mp->b_wptr - mp->b_rptr;
-    mblk_t *reply, *np;
-    upperstr_t *ppa, *os;
-    int sap, *ip, len;
-    dl_info_ack_t *info;
-    dl_bind_ack_t *ackp;
-
-    if (us->flags & US_DBGLOG)
-       cmn_err(CE_CONT, "ppp/%d: dlpi prim %x len=%d\n", us->mn,
-               d->dl_primitive, size);
-    switch (d->dl_primitive) {
-    case DL_INFO_REQ:
-       if (size < sizeof(dl_info_req_t))
-           goto badprim;
-       if ((reply = allocb(sizeof(dl_info_ack_t), BPRI_HI)) == 0)
-           break;              /* should do bufcall */
-       reply->b_datap->db_type = M_PCPROTO;
-       info = (dl_info_ack_t *) reply->b_wptr;
-       reply->b_wptr += sizeof(dl_info_ack_t);
-       bzero((caddr_t) info, sizeof(dl_info_ack_t));
-       info->dl_primitive = DL_INFO_ACK;
-       info->dl_max_sdu = PPP_MAXMTU;
-       info->dl_min_sdu = 1;
-       info->dl_addr_length = sizeof(ulong);
-#ifdef DL_OTHER
-       info->dl_mac_type = DL_OTHER;
-#else
-       info->dl_mac_type = DL_HDLC;    /* a lie */
-#endif
-       info->dl_current_state = us->state;
-       info->dl_service_mode = DL_CLDLS;
-       info->dl_provider_style = DL_STYLE2;
-#if DL_CURRENT_VERSION >= 2
-       info->dl_sap_length = sizeof(ulong);
-       info->dl_version = DL_CURRENT_VERSION;
-#endif
-       qreply(q, reply);
-       break;
-
-    case DL_ATTACH_REQ:
-       if (size < sizeof(dl_attach_req_t))
-           goto badprim;
-       if (us->state != DL_UNATTACHED || us->ppa != 0) {
-           dlpi_error(q, DL_ATTACH_REQ, DL_OUTSTATE, 0);
-           break;
-       }
-       for (ppa = ppas; ppa != 0; ppa = ppa->nextppa)
-           if (ppa->ppa_id == d->attach_req.dl_ppa)
-               break;
-       if (ppa == 0) {
-           dlpi_error(q, DL_ATTACH_REQ, DL_BADPPA, 0);
-           break;
-       }
-       us->ppa = ppa;
-       qwriter(q, mp, attach_ppa, PERIM_OUTER);
-       break;
-
-    case DL_DETACH_REQ:
-       if (size < sizeof(dl_detach_req_t))
-           goto badprim;
-       if (us->state != DL_UNBOUND || us->ppa == 0) {
-           dlpi_error(q, DL_DETACH_REQ, DL_OUTSTATE, 0);
-           break;
-       }
-       qwriter(q, mp, detach_ppa, PERIM_OUTER);
-       break;
-
-    case DL_BIND_REQ:
-       if (size < sizeof(dl_bind_req_t))
-           goto badprim;
-       if (us->state != DL_UNBOUND || us->ppa == 0) {
-           dlpi_error(q, DL_BIND_REQ, DL_OUTSTATE, 0);
-           break;
-       }
-       if (d->bind_req.dl_service_mode != DL_CLDLS) {
-           dlpi_error(q, DL_BIND_REQ, DL_UNSUPPORTED, 0);
-           break;
-       }
-
-       /* saps must be valid PPP network protocol numbers,
-          except that we accept ETHERTYPE_IP in place of PPP_IP. */
-       sap = d->bind_req.dl_sap;
-       us->req_sap = sap;
-#if DEBUG
-       cmn_err(CE_CONT, "ppp bind %x\n", sap);
-#endif
-       if (sap == ETHERTYPE_IP)
-           sap = PPP_IP;
-       if (sap < 0x21 || sap > 0x3fff || (sap & 0x101) != 1) {
-           dlpi_error(q, DL_BIND_REQ, DL_BADADDR, 0);
-           break;
-       }
-
-       /* check that no other stream is bound to this sap already. */
-       for (os = us->ppa; os != 0; os = os->next)
-           if (os->sap == sap)
-               break;
-       if (os != 0) {
-           dlpi_error(q, DL_BIND_REQ, DL_NOADDR, 0);
-           break;
-       }
-
-       us->sap = sap;
-       us->state = DL_IDLE;
-
-       if ((reply = allocb(sizeof(dl_bind_ack_t) + sizeof(ulong),
-                           BPRI_HI)) == 0)
-           break;              /* should do bufcall */
-       ackp = (dl_bind_ack_t *) reply->b_wptr;
-       reply->b_wptr += sizeof(dl_bind_ack_t) + sizeof(ulong);
-       reply->b_datap->db_type = M_PCPROTO;
-       bzero((caddr_t) ackp, sizeof(dl_bind_ack_t));
-       ackp->dl_primitive = DL_BIND_ACK;
-       ackp->dl_sap = sap;
-       ackp->dl_addr_length = sizeof(ulong);
-       ackp->dl_addr_offset = sizeof(dl_bind_ack_t);
-       *(ulong *)(ackp+1) = sap;
-       qreply(q, reply);
-       break;
-
-    case DL_UNBIND_REQ:
-       if (size < sizeof(dl_unbind_req_t))
-           goto badprim;
-       if (us->state != DL_IDLE) {
-           dlpi_error(q, DL_UNBIND_REQ, DL_OUTSTATE, 0);
-           break;
-       }
-       us->sap = -1;
-       us->state = DL_UNBOUND;
-#ifndef sun
-       us->ppa->ifstats.ifs_active = 0;
-#endif
-       dlpi_ok(q, DL_UNBIND_REQ);
-       break;
-
-    case DL_UNITDATA_REQ:
-       if (size < sizeof(dl_unitdata_req_t))
-           goto badprim;
-       if (us->state != DL_IDLE) {
-           dlpi_error(q, DL_UNITDATA_REQ, DL_OUTSTATE, 0);
-           break;
-       }
-       if (us->ppa == 0) {
-           cmn_err(CE_CONT, "ppp: in state dl_idle but ppa == 0?\n");
-           break;
-       }
-       len = mp->b_cont == 0? 0: msgdsize(mp->b_cont);
-       if (len > us->ppa->mtu) {
-#if DEBUG
-           cmn_err(CE_CONT, "dlpi data too large (%d > %d)\n", len, us->mtu);
-#endif
-           break;
-       }
-       /* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */
-       if (mp->b_datap->db_ref > 1) {
-           np = allocb(PPP_HDRLEN, BPRI_HI);
-           if (np == 0)
-               break;          /* gak! */
-           np->b_cont = mp->b_cont;
-           mp->b_cont = 0;
-           freeb(mp);
-           mp = np;
-       } else
-           mp->b_datap->db_type = M_DATA;
-       /* XXX should use dl_dest_addr_offset/length here,
-          but we would have to translate ETHERTYPE_IP -> PPP_IP */
-       mp->b_wptr = mp->b_rptr + PPP_HDRLEN;
-       mp->b_rptr[0] = PPP_ALLSTATIONS;
-       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);
-       return;
-
-#if DL_CURRENT_VERSION >= 2
-    case DL_SUBS_BIND_REQ:
-    case DL_SUBS_UNBIND_REQ:
-    case DL_ENABMULTI_REQ:
-    case DL_DISABMULTI_REQ:
-    case DL_PROMISCON_REQ:
-    case DL_PROMISCOFF_REQ:
-    case DL_PHYS_ADDR_REQ:
-    case DL_SET_PHYS_ADDR_REQ:
-    case DL_XID_REQ:
-    case DL_TEST_REQ:
-    case DL_REPLY_UPDATE_REQ:
-    case DL_REPLY_REQ:
-    case DL_DATA_ACK_REQ:
-#endif
-    case DL_CONNECT_REQ:
-    case DL_TOKEN_REQ:
-       dlpi_error(q, d->dl_primitive, DL_NOTSUPPORTED, 0);
-       break;
-
-    case DL_CONNECT_RES:
-    case DL_DISCONNECT_REQ:
-    case DL_RESET_REQ:
-    case DL_RESET_RES:
-       dlpi_error(q, d->dl_primitive, DL_OUTSTATE, 0);
-       break;
-
-    case DL_UDQOS_REQ:
-       dlpi_error(q, d->dl_primitive, DL_BADQOSTYPE, 0);
-       break;
-
-#if DL_CURRENT_VERSION >= 2
-    case DL_TEST_RES:
-    case DL_XID_RES:
-       break;
-#endif
-
-    default:
-       cmn_err(CE_CONT, "ppp: unknown dlpi prim 0x%x\n", d->dl_primitive);
-       /* fall through */
-    badprim:
-       dlpi_error(q, d->dl_primitive, DL_BADPRIM, 0);
-       break;
-    }
-    freemsg(mp);
-}
-
-static void
-dlpi_error(q, prim, err, uerr)
-    queue_t *q;
-    int prim, err, uerr;
-{
-    mblk_t *reply;
-    dl_error_ack_t *errp;
-
-    reply = allocb(sizeof(dl_error_ack_t), BPRI_HI);
-    if (reply == 0)
-       return;                 /* XXX should do bufcall */
-    reply->b_datap->db_type = M_PCPROTO;
-    errp = (dl_error_ack_t *) reply->b_wptr;
-    reply->b_wptr += sizeof(dl_error_ack_t);
-    errp->dl_primitive = DL_ERROR_ACK;
-    errp->dl_error_primitive = prim;
-    errp->dl_errno = err;
-    errp->dl_unix_errno = uerr;
-    qreply(q, reply);
-}
-
-static void
-dlpi_ok(q, prim)
-    queue_t *q;
-    int prim;
-{
-    mblk_t *reply;
-    dl_ok_ack_t *okp;
-
-    reply = allocb(sizeof(dl_ok_ack_t), BPRI_HI);
-    if (reply == 0)
-       return;                 /* XXX should do bufcall */
-    reply->b_datap->db_type = M_PCPROTO;
-    okp = (dl_ok_ack_t *) reply->b_wptr;
-    reply->b_wptr += sizeof(dl_ok_ack_t);
-    okp->dl_primitive = DL_OK_ACK;
-    okp->dl_correct_primitive = prim;
-    qreply(q, reply);
-}
-
-static int
-send_data(mp, us)
-    mblk_t *mp;
-    upperstr_t *us;
-{
-    queue_t *q;
-    upperstr_t *ppa;
-
-    if (us->flags & US_BLOCKED)
-       return 0;
-    ppa = us->ppa;
-    if (ppa == 0) {
-       freemsg(mp);
-       return 1;
-    }
-    if ((q = ppa->lowerq) == 0) {
-       /* try to send it up the control stream */
-       if (canputnext(ppa->q)) {
-           putnext(ppa->q, mp);
-           return 1;
-       }
-    } else {
-       if (canputnext(ppa->lowerq)) {
-           /*
-            * The lower write queue's put procedure just updates counters
-            * and does a putnext.  We call it in order to enter the lower
-            * queues' perimeter so that the counter updates are serialized.
-            */
-           put(ppa->lowerq, mp);
-           return 1;
-       }
-    }
-    us->flags |= US_BLOCKED;
-    return 0;
-}
-
-/*
- * Allocate a new PPA id and link this stream into the list of PPAs.
- * This procedure is called with an exclusive lock on all queues in
- * this driver.
- */
-static void
-new_ppa(q, mp)
-    queue_t *q;
-    mblk_t *mp;
-{
-    upperstr_t *us, **usp;
-    int ppa_id;
-
-    usp = &ppas;
-    ppa_id = 0;
-    while ((us = *usp) != 0 && ppa_id == us->ppa_id) {
-       ++ppa_id;
-       usp = &us->nextppa;
-    }
-    us = (upperstr_t *) q->q_ptr;
-    us->ppa_id = ppa_id;
-    us->ppa = us;
-    us->next = 0;
-    us->nextppa = *usp;
-    *usp = us;
-    us->flags |= US_CONTROL;
-
-    us->mtu = PPP_MRU;
-    us->mru = PPP_MRU;
-
-#ifdef sun
-    if (us->kstats == 0) {
-       char unit[32];
-
-       sprintf(unit, "ppp%d", us->ppa->ppa_id);
-       us->kstats = kstat_create("ppp", us->ppa->ppa_id, unit,
-                                 "net", KSTAT_TYPE_NAMED, 4, 0);
-       if (us->kstats != 0) {
-           kstat_named_t *kn = KSTAT_NAMED_PTR(us->kstats);
-
-           strcpy(kn[0].name, "ipackets");
-           kn[0].data_type = KSTAT_DATA_ULONG;
-           strcpy(kn[1].name, "ierrors");
-           kn[1].data_type = KSTAT_DATA_ULONG;
-           strcpy(kn[2].name, "opackets");
-           kn[2].data_type = KSTAT_DATA_ULONG;
-           strcpy(kn[3].name, "oerrors");
-           kn[3].data_type = KSTAT_DATA_ULONG;
-           kstat_install(us->kstats);
-       }
-    }
-#endif
-
-    *(int *)mp->b_cont->b_rptr = ppa_id;
-    mp->b_datap->db_type = M_IOCACK;
-    qreply(q, mp);
-}
-
-static void
-attach_ppa(q, mp)
-    queue_t *q;
-    mblk_t *mp;
-{
-    upperstr_t *us, *t;
-
-    us = (upperstr_t *) q->q_ptr;
-    us->state = DL_UNBOUND;
-    for (t = us->ppa; t->next != 0; t = t->next)
-       ;
-    t->next = us;
-    us->next = 0;
-    if (mp->b_datap->db_type == M_IOCTL) {
-       mp->b_datap->db_type = M_IOCACK;
-       qreply(q, mp);
-    } else {
-       dlpi_ok(q, DL_ATTACH_REQ);
-    }
-}
-
-static void
-detach_ppa(q, mp)
-    queue_t *q;
-    mblk_t *mp;
-{
-    upperstr_t *us, *t;
-
-    us = (upperstr_t *) q->q_ptr;
-    for (t = us->ppa; t->next != 0; t = t->next)
-       if (t->next == us) {
-           t->next = us->next;
-           break;
-       }
-    us->next = 0;
-    us->ppa = 0;
-    us->state = DL_UNATTACHED;
-    dlpi_ok(q, DL_DETACH_REQ);
-}
-
-static int
-pppuwsrv(q)
-    queue_t *q;
-{
-    upperstr_t *us;
-    struct lowerstr *ls;
-    queue_t *lwq;
-    mblk_t *mp;
-
-    us = (upperstr_t *) q->q_ptr;
-    us->flags &= ~US_BLOCKED;
-    while ((mp = getq(q)) != 0) {
-       if (!send_data(mp, us)) {
-           putbq(q, mp);
-           break;
-       }
-    }
-    return 0;
-}
-
-static int
-ppplwput(q, mp)
-    queue_t *q;
-    mblk_t *mp;
-{
-    upperstr_t *ppa;
-
-    ppa = q->q_ptr;
-    if (ppa != 0) {            /* why wouldn't it? */
-       ppa->stats.ppp_opackets++;
-       ppa->stats.ppp_obytes += msgdsize(mp);
-#ifdef sun
-       if (ppa->kstats != 0)
-           KSTAT_NAMED_PTR(ppa->kstats)[2].value.ul++;
-#else
-       ppa->ifstats.ifs_opackets++;
-#endif
-    }
-    putnext(q, mp);
-    return 0;
-}
-
-static int
-ppplwsrv(q)
-    queue_t *q;
-{
-    upperstr_t *us;
-
-    /*
-     * Flow control has back-enabled this stream:
-     * enable the write service procedures of all upper
-     * streams feeding this lower stream.
-     */
-    for (us = (upperstr_t *) q->q_ptr; us != NULL; us = us->next)
-       if (us->flags & US_BLOCKED)
-           qenable(WR(us->q));
-    return 0;
-}
-
-static int
-pppursrv(q)
-    queue_t *q;
-{
-    upperstr_t *us, *as;
-    mblk_t *mp, *hdr;
-    dl_unitdata_ind_t *ud;
-    int proto;
-
-    us = (upperstr_t *) q->q_ptr;
-    if (us->flags & US_CONTROL) {
-       /*
-        * A control stream.
-        * If there is no lower queue attached, run the write service
-        * routines of other upper streams attached to this PPA.
-        */
-       if (us->lowerq == 0) {
-           as = us;
-           do {
-               if (as->flags & US_BLOCKED)
-                   qenable(WR(as->q));
-               as = as->next;
-           } while (as != 0);
-       }
-    } else {
-       /*
-        * A network protocol stream.  Put a DLPI header on each
-        * packet and send it on.
-        * (Actually, it seems that the IP module will happily
-        * accept M_DATA messages without the DL_UNITDATA_IND header.)
-        */
-       while ((mp = getq(q)) != 0) {
-           if (!canputnext(q)) {
-               putbq(q, mp);
-               break;
-           }
-           proto = PPP_PROTOCOL(mp->b_rptr);
-           mp->b_rptr += PPP_HDRLEN;
-           hdr = allocb(sizeof(dl_unitdata_ind_t) + 2 * sizeof(ulong),
-                        BPRI_MED);
-           if (hdr == 0) {
-               /* XXX should put it back and use bufcall */
-               freemsg(mp);
-               continue;
-           }
-           hdr->b_datap->db_type = M_PROTO;
-           ud = (dl_unitdata_ind_t *) hdr->b_wptr;
-           hdr->b_wptr += sizeof(dl_unitdata_ind_t) + 2 * sizeof(ulong);
-           hdr->b_cont = mp;
-           ud->dl_primitive = DL_UNITDATA_IND;
-           ud->dl_dest_addr_length = sizeof(ulong);
-           ud->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t);
-           ud->dl_src_addr_length = sizeof(ulong);
-           ud->dl_src_addr_offset = ud->dl_dest_addr_offset + sizeof(ulong);
-#if DL_CURRENT_VERSION >= 2
-           ud->dl_group_address = 0;
-#endif
-           /* Send the DLPI client the data with the SAP they requested,
-              (e.g. ETHERTYPE_IP) rather than the PPP protocol number
-              (e.g. PPP_IP) */
-           ((ulong *)(ud + 1))[0] = us->req_sap;       /* dest SAP */
-           ((ulong *)(ud + 1))[1] = us->req_sap;       /* src SAP */
-           putnext(q, hdr);
-       }
-    }
-
-    /*
-     * If this stream is attached to a PPA with a lower queue pair,
-     * enable the read queue's service routine if it has data queued.
-     * XXX there is a possibility that packets could get out of order
-     * if ppplrput now runs before ppplrsrv.
-     */
-    if (us->ppa != 0 && us->ppa->lowerq != 0)
-       qenable(RD(us->ppa->lowerq));
-
-    return 0;
-}
-
-static upperstr_t *
-find_dest(ppa, proto)
-    upperstr_t *ppa;
-    int proto;
-{
-    upperstr_t *us;
-
-    for (us = ppa->next; us != 0; us = us->next)
-       if (proto == us->sap)
-           break;
-    return us;
-}
-
-static int
-ppplrput(q, mp)
-    queue_t *q;
-    mblk_t *mp;
-{
-    upperstr_t *ppa, *us;
-    queue_t *uq;
-    int proto, len;
-    mblk_t *np;
-    struct iocblk *iop;
-
-    ppa = (upperstr_t *) q->q_ptr;
-    if (ppa == 0) {
-#if DEBUG
-       cmn_err(CE_CONT, "ppplrput: q = %x, ppa = 0??\n", q);
-#endif
-       freemsg(mp);
-       return 0;
-    }
-    switch (mp->b_datap->db_type) {
-    case M_FLUSH:
-       if (*mp->b_rptr & FLUSHW) {
-           *mp->b_rptr &= ~FLUSHR;
-           qreply(q, mp);
-       } else
-           freemsg(mp);
-       break;
-
-    case M_CTL:
-       switch (*mp->b_rptr) {
-       case PPPCTL_IERROR:
-#ifdef sun
-           if (ppa->kstats != 0) {
-               KSTAT_NAMED_PTR(ppa->kstats)[1].value.ul++;
-           }
-#else
-           ppa->ifstats.ifs_ierrors++;
-#endif
-           ppa->stats.ppp_ierrors++;
-           break;
-       case PPPCTL_OERROR:
-#ifdef sun
-           if (ppa->kstats != 0) {
-               KSTAT_NAMED_PTR(ppa->kstats)[3].value.ul++;
-           }
-#else
-           ppa->ifstats.ifs_oerrors++;
-#endif
-           ppa->stats.ppp_oerrors++;
-           break;
-       }
-       freemsg(mp);
-       break;
-
-    case M_IOCACK:
-    case M_IOCNAK:
-       /*
-        * Attempt to match up the response with the stream
-        * that the request came from.
-        */
-       iop = (struct iocblk *) mp->b_rptr;
-       for (us = ppa; us != 0; us = us->next)
-           if (us->ioc_id == iop->ioc_id)
-               break;
-       if (us == 0)
-           freemsg(mp);
-       else
-           putnext(us->q, mp);
-       break;
-
-    default:
-       if (mp->b_datap->db_type == M_DATA) {
-           len = msgdsize(mp);
-           if (mp->b_wptr - mp->b_rptr < PPP_HDRLEN) {
-#ifdef USE_MSGPULLUP
-               np = msgpullup(mp, PPP_HDRLEN);
-               freemsg(mp);
-               if (np == 0) {
-#if DEBUG
-                   cmn_err(CE_CONT, "ppp_lrput: msgpullup failed (len=%d)\n",
-                           len);
-#endif
-                   break;
-               }
-               mp = np;
-#else
-               if (!pullupmsg (mp, PPP_HDRLEN)) {
-#if DEBUG
-                   cmn_err(CE_CONT, "ppp_lrput: pullupmsg failed (len=%d)\n",
-                           len);
-#endif
-                   break;
-               }
-#endif
-           }
-           ppa->stats.ppp_ipackets++;
-           ppa->stats.ppp_ibytes += len;
-#ifdef sun
-           if (ppa->kstats != 0) {
-               KSTAT_NAMED_PTR(ppa->kstats)[0].value.ul++;
-           }
-#else
-           ppa->ifstats.ifs_ipackets++;
-#endif
-           proto = PPP_PROTOCOL(mp->b_rptr);
-           if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) {
-               /*
-                * A data packet for some network protocol.
-                * Queue it on the upper stream for that protocol.
-                */
-               if (canput(us->q))
-                   putq(us->q, mp);
-               else
-                   putq(q, mp);
-               break;
-           }
-       }
-       /*
-        * A control frame, a frame for an unknown protocol,
-        * or some other message type.
-        * Send it up to pppd via the control stream.
-        */
-       if (queclass(mp) == QPCTL || canputnext(ppa->q))
-           putnext(ppa->q, mp);
-       else
-           putq(q, mp);
-       break;
-    }
-
-    return 0;
-}
-
-static int
-ppplrsrv(q)
-    queue_t *q;
-{
-    mblk_t *mp;
-    upperstr_t *ppa, *us;
-    int proto;
-
-    /*
-     * Packets only get queued here for flow control reasons.
-     */
-    ppa = (upperstr_t *) q->q_ptr;
-    while ((mp = getq(q)) != 0) {
-       if (mp->b_datap->db_type == M_DATA
-           && (proto = PPP_PROTOCOL(mp->b_rptr)) < 0x8000
-           && (us = find_dest(ppa, proto)) != 0) {
-           if (canput(us->q))
-               putq(us->q, mp);
-           else {
-               putbq(q, mp);
-               break;
-           }
-       } else {
-           if (canputnext(ppa->q))
-               putnext(ppa->q, mp);
-           else {
-               putbq(q, mp);
-               break;
-           }
-       }
-    }
-    return 0;
-}
-
-static int
-putctl2(q, type, code, val)
-    queue_t *q;
-    int type, code, val;
-{
-    mblk_t *mp;
-
-    mp = allocb(2, BPRI_HI);
-    if (mp == 0)
-       return 0;
-    mp->b_datap->db_type = type;
-    mp->b_wptr[0] = code;
-    mp->b_wptr[1] = val;
-    mp->b_wptr += 2;
-    putnext(q, mp);
-    return 1;
-}
-
-static int
-putctl4(q, type, code, val)
-    queue_t *q;
-    int type, code, val;
-{
-    mblk_t *mp;
-
-    mp = allocb(4, BPRI_HI);
-    if (mp == 0)
-       return 0;
-    mp->b_datap->db_type = type;
-    mp->b_wptr[0] = code;
-    ((short *)mp->b_wptr)[1] = val;
-    mp->b_wptr += 4;
-    putnext(q, mp);
-    return 1;
-}
-
-static void
-debug_dump(q, mp)
-    queue_t *q;                        /* not used */
-    mblk_t *mp;                        /* not used either */
-{
-    upperstr_t *us;
-    queue_t *uq, *lq;
-
-    cmn_err(CE_CONT, "ppp upper streams:\n");
-    for (us = minor_devs; us != 0; us = us->nextmn) {
-       uq = us->q;
-       cmn_err(CE_CONT, " %d: q=%x rlev=%d wlev=%d flags=0x%b",
-               us->mn, uq, (uq? qsize(uq): 0), (uq? qsize(WR(uq)): 0),
-               us->flags, "\020\1priv\2control\3blocked\4last");
-       cmn_err(CE_CONT, " state=%x sap=%x req_sap=%x", us->state, us->sap,
-               us->req_sap);
-       if (us->ppa == 0)
-           cmn_err(CE_CONT, " ppa=?\n");
-       else
-           cmn_err(CE_CONT, " ppa=%d\n", us->ppa->ppa_id);
-       if (us->flags & US_CONTROL) {
-           lq = us->lowerq;
-           cmn_err(CE_CONT, "    control for %d lq=%x rlev=%d wlev=%d",
-                   us->ppa_id, lq, (lq? qsize(RD(lq)): 0),
-                   (lq? qsize(lq): 0));
-           cmn_err(CE_CONT, " mru=%d mtu=%d\n", us->mru, us->mtu);
-       }
-    }
-}