From: Paul Mackerras Date: Mon, 11 Dec 1995 05:19:29 +0000 (+0000) Subject: use cc; sources from modules dir X-Git-Tag: RELEASE_2_3_6~577 X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=c3183b45104c236f662e083876812680a7a6e92c use cc; sources from modules dir --- diff --git a/svr4/Makefile.sol2 b/svr4/Makefile.sol2 index 060c7bc..0ea1175 100644 --- a/svr4/Makefile.sol2 +++ b/svr4/Makefile.sol2 @@ -1,27 +1,30 @@ # # Makefile for STREAMS modules for Solaris 2. # -# $Id: Makefile.sol2,v 1.1 1995/10/27 03:58:30 paulus Exp $ +# $Id: Makefile.sol2,v 1.2 1995/12/11 05:19:29 paulus Exp $ # -# Note: Sun cc doesn't predefine svr4 or __svr4__, but gcc does - -CFLAGS= -D_KERNEL -Dsvr4 -I.. -O -#CC= gcc +CFLAGS= -D_KERNEL -DSVR4 -DSOL2 -I.. -O -Xa all: ppp ppp_ahdl ppp_comp -ppp: ppp.o - ld -r -o $@ ppp.o +ppp: ppp.o ppp_mod.o + ld -r -o $@ ppp.o ppp_mod.o -ppp_ahdl: ppp_ahdlc.o - ld -r -o $@ ppp_ahdlc.o +ppp_ahdl: ppp_ahdlc.o ppp_ahdlc_mod.o + ld -r -o $@ ppp_ahdlc.o ppp_ahdlc_mod.o -ppp_comp: ppp_comp.o bsd-comp.o vjcompress.o - ld -r -o $@ ppp_comp.o bsd-comp.o vjcompress.o +ppp_comp: ppp_comp.o bsd-comp.o vjcompress.o ppp_comp_mod.o + ld -r -o $@ ppp_comp.o bsd-comp.o vjcompress.o ppp_comp_mod.o bsd-comp.o: ../modules/bsd-comp.c $(CC) $(CFLAGS) -c $? +ppp.o: ../modules/ppp.c + $(CC) $(CFLAGS) -c $? +ppp_ahdlc.o: ../modules/ppp_ahdlc.c + $(CC) $(CFLAGS) -c $? +ppp_comp.o: ../modules/ppp_comp.c + $(CC) $(CFLAGS) -c $? vjcompress.o: ../modules/vjcompress.c $(CC) $(CFLAGS) -c $? diff --git a/svr4/ppp.c b/svr4/ppp.c deleted file mode 100644 index 43afb95..0000000 --- a/svr4/ppp.c +++ /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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef sun -#include -#include -#include -#else -#include -#include -#include -#include -#endif -#include -#include - -#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); - } - } -} diff --git a/svr4/ppp_ahdlc.c b/svr4/ppp_ahdlc.c deleted file mode 100644 index ffbe120..0000000 --- a/svr4/ppp_ahdlc.c +++ /dev/null @@ -1,775 +0,0 @@ -/* - * ppp_ahdlc.c - STREAMS module for doing PPP asynchronous HDLC. - * - * 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_ahdlc.c,v 1.5 1995/10/27 03:57:10 paulus Exp $ - */ - -/* - * This file is used under Solaris 2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef sun -#include -#include -#endif -#include -#include - -#define IFRAME_BSIZE 512 /* Block size to allocate for input */ -#define OFRAME_BSIZE 4096 /* Don't allocb more than this for output */ - -static int ahdlc_open __P((queue_t *, dev_t *, int, int, cred_t *)); -static int ahdlc_close __P((queue_t *, int, cred_t *)); -static int ahdlc_wput __P((queue_t *, mblk_t *)); -static int ahdlc_rput __P((queue_t *, mblk_t *)); -static void stuff_frame __P((queue_t *, mblk_t *)); -static void unstuff_chars __P((queue_t *, mblk_t *)); -static int msg_copy __P((uchar_t *, mblk_t *, int)); - -static struct module_info minfo = { - 0x7d23, "ppp_ahdl", 0, INFPSZ, 4096, 128 -}; - -static struct qinit rinit = { - ahdlc_rput, NULL, ahdlc_open, ahdlc_close, NULL, &minfo, NULL -}; - -static struct qinit winit = { - ahdlc_wput, NULL, NULL, NULL, NULL, &minfo, NULL -}; - -static struct streamtab ahdlc_info = { - &rinit, &winit, NULL, NULL -}; - -#ifdef sun -static struct fmodsw fsw = { - "ppp_ahdl", - &ahdlc_info, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP async HDLC module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; -#endif /* sun */ - -typedef struct ahdlc_state { - int flags; - mblk_t *cur_frame; - mblk_t *cur_blk; - int inlen; - ushort infcs; - u_int32_t xaccm[8]; - u_int32_t raccm; - int mtu; - int mru; - int unit; - struct pppstat stats; -} ahdlc_state_t; - -/* Values for flags */ -#define ESCAPED 0x100 /* last saw escape char on input */ -#define IFLUSH 0x200 /* flushing input due to error */ - -/* RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also. */ -#define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP) - -#ifndef sun -# define qprocson(q) -# define qprocsoff(q) -#endif - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -#ifdef sun -/* - * Entry points for modloading. - */ -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); -} -#endif - -/* - * STREAMS module entry points. - */ -static int -ahdlc_open(q, devp, flag, sflag, credp) - queue_t *q; - dev_t *devp; - int flag, sflag; - cred_t *credp; -{ - ahdlc_state_t *sp; - - if (q->q_ptr == 0) { - sp = (ahdlc_state_t *) kmem_zalloc(sizeof(ahdlc_state_t), KM_SLEEP); - if (sp == 0) - return ENOSR; - q->q_ptr = sp; - WR(q)->q_ptr = sp; - sp->xaccm[0] = ~0; - sp->xaccm[3] = 0x60000000; - sp->mru = 1500; - qprocson(q); - } - return 0; -} - -static int -ahdlc_close(q, flag, credp) - queue_t *q; - int flag; - cred_t *credp; -{ - ahdlc_state_t *state; - - qprocsoff(q); - if (q->q_ptr != 0) { - state = (ahdlc_state_t *) q->q_ptr; - if (state->cur_frame != 0) { - freemsg(state->cur_frame); - state->cur_frame = 0; - } - kmem_free(q->q_ptr, sizeof(ahdlc_state_t)); - } - return 0; -} - -static int -ahdlc_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - struct iocblk *iop; - int error; - mblk_t *np; - struct ppp_stats *psp; - - state = (ahdlc_state_t *) q->q_ptr; - switch (mp->b_datap->db_type) { - case M_DATA: - /* - * A data packet - do character-stuffing and FCS, and - * send it onwards. - */ - stuff_frame(q, mp); - freemsg(mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - case PPPIO_XACCM: - if (iop->ioc_count < sizeof(u_int32_t) - || iop->ioc_count > sizeof(ext_accm)) - break; - bcopy(mp->b_cont->b_rptr, (caddr_t)state->xaccm, iop->ioc_count); - state->xaccm[2] &= 0x40000000; /* don't escape 0x5e */ - state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */ - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_RACCM: - if (iop->ioc_count != sizeof(u_int32_t)) - break; - bcopy(mp->b_cont->b_rptr, (caddr_t)&state->raccm, - sizeof(u_int32_t)); - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_GCLEAN: - np = allocb(sizeof(int), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - *(int *)np->b_wptr = state->flags & RCV_FLAGS; - np->b_wptr += sizeof(int); - iop->ioc_count = sizeof(int); - error = 0; - break; - - case PPPIO_GETSTAT: - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - bzero((caddr_t)psp, sizeof(struct ppp_stats)); - psp->p = state->stats; - iop->ioc_count = sizeof(struct ppp_stats); - error = 0; - break; - - case PPPIO_LASTMOD: - /* we knew this anyway */ - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_count = 0; - iop->ioc_error = error; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: - state->mtu = ((unsigned short *)mp->b_rptr)[1]; - freemsg(mp); - break; - case PPPCTL_MRU: - state->mru = ((unsigned short *)mp->b_rptr)[1]; - freemsg(mp); - break; - case PPPCTL_UNIT: - state->unit = mp->b_rptr[1]; - break; - default: - putnext(q, mp); - } - break; - - default: - putnext(q, mp); - } - return 0; -} - -static int -ahdlc_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - mblk_t *np; - uchar_t *cp; - ahdlc_state_t *state; - - switch (mp->b_datap->db_type) { - case M_DATA: - unstuff_chars(q, mp); - freemsg(mp); - break; - - case M_HANGUP: - state = (ahdlc_state_t *) q->q_ptr; - if (state->cur_frame != 0) { - /* XXX would like to send this up for debugging */ - freemsg(state->cur_frame); - state->cur_frame = 0; - state->cur_blk = 0; - } - state->inlen = 0; - state->flags = IFLUSH; - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - return 0; -} - -/* Extract bit c from map m, to determine if c needs to be escaped. */ -#define ESCAPE(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f))) - -static void -stuff_frame(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - int ilen, olen, c, extra, i; - mblk_t *omsg, *op, *np; - uchar_t *sp, *sp0, *dp, *dp0, *spend; - ushort_t fcs; - u_int32_t *xaccm, lcp_xaccm[8]; - static uchar_t lcphdr[PPP_HDRLEN] = { 0xff, 0x03, 0xc0, 0x21 }; - uchar_t ppphdr[PPP_HDRLEN]; - - state = (ahdlc_state_t *) q->q_ptr; - ilen = msgdsize(mp); - - /* - * We estimate the length of the output packet as - * 1.25 * input length + 16 (for initial flag, FCS, final flag, slop). - */ - olen = ilen + (ilen >> 2) + 16; - if (olen > OFRAME_BSIZE) - olen = OFRAME_BSIZE; - omsg = op = allocb(olen, BPRI_MED); - if (omsg == 0) - goto bomb; - - /* - * Put in an initial flag for now. We'll remove it later - * if we decide we don't need it. - */ - dp = op->b_wptr; - *dp++ = PPP_FLAG; - --olen; - - /* - * For LCP packets, we must escape all control characters. - * Inspect the first PPP_HDRLEN bytes of the message to - * see whether it is an LCP packet. - * LCP packets must not be A/C or protocol compressed. - */ - xaccm = state->xaccm; - if (msg_copy(ppphdr, mp, PPP_HDRLEN) == PPP_HDRLEN - && bcmp((caddr_t) ppphdr, (caddr_t) lcphdr, PPP_HDRLEN) == 0) { - bcopy((caddr_t) state->xaccm, (caddr_t) lcp_xaccm, sizeof(lcp_xaccm)); - lcp_xaccm[0] = ~0; - xaccm = lcp_xaccm; - } - - sp = mp->b_rptr; - fcs = PPP_INITFCS; - for (;;) { - spend = mp->b_wptr; - extra = sp + olen - spend; - if (extra < 0) { - spend = sp + olen; - extra = 0; - } - /* - * We can safely process the input up to `spend' - * without overrunning the output, provided we don't - * hit more than `extra' characters which need to be escaped. - */ - sp0 = sp; - dp0 = dp; - while (sp < spend) { - c = *sp; - if (ESCAPE(c, xaccm)) { - if (extra > 0) - --extra; - else if (sp < spend - 1) - --spend; - else - break; - fcs = PPP_FCS(fcs, c); - *dp++ = PPP_ESCAPE; - c ^= PPP_TRANS; - } else - fcs = PPP_FCS(fcs, c); - *dp++ = c; - ++sp; - } - ilen -= sp - sp0; - olen -= dp - dp0; - - /* - * At this point, we have emptied an input block - * and/or filled an output block. - */ - if (sp >= mp->b_wptr) { - /* - * We've emptied an input block. Advance to the next. - */ - mp = mp->b_cont; - if (mp == 0) - break; /* all done */ - sp = mp->b_rptr; - } - if (olen < 2) { - /* - * The output block is full. Allocate a new one. - */ - op->b_wptr = dp; - olen = 2 * ilen + 5; - if (olen > OFRAME_BSIZE) - olen = OFRAME_BSIZE; - np = allocb(olen, BPRI_MED); - if (np == 0) - goto bomb; - op->b_cont = np; - op = np; - dp = op->b_wptr; - } - } - - /* - * Append the FCS and closing flag. - * This could require up to 5 characters. - */ - if (olen < 5) { - /* Sigh. Need another block. */ - op->b_wptr = dp; - np = allocb(5, BPRI_MED); - if (np == 0) - goto bomb; - op->b_cont = np; - op = np; - dp = op->b_wptr; - } - c = ~fcs & 0xff; - if (ESCAPE(c, xaccm)) { - *dp++ = PPP_ESCAPE; - c ^= PPP_TRANS; - } - *dp++ = c; - c = (~fcs >> 8) & 0xff; - if (ESCAPE(c, xaccm)) { - *dp++ = PPP_ESCAPE; - c ^= PPP_TRANS; - } - *dp++ = c; - *dp++ = PPP_FLAG; - op->b_wptr = dp; - - /* - * Remove the initial flag, if possible. - */ - if (qsize(q->q_next) > 0) - ++omsg->b_rptr; - - /* - * Update statistics. - */ - state->stats.ppp_obytes += msgdsize(omsg); - state->stats.ppp_opackets++; - - /* - * Send it on. - */ - putnext(q, omsg); - return; - - bomb: - if (omsg != 0) - freemsg(omsg); - state->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); -} - -static unsigned paritytab[8] = { - 0x96696996, 0x69969669, 0x69969669, 0x96696996, - 0x69969669, 0x96696996, 0x96696996, 0x69969669 -}; - -#define UPDATE_FLAGS(c) { \ - if ((c) & 0x80) \ - state->flags |= RCV_B7_1; \ - else \ - state->flags |= RCV_B7_0; \ - if (paritytab[(c) >> 5] & (1 << ((c) & 0x1F))) \ - state->flags |= RCV_ODDP; \ - else \ - state->flags |= RCV_EVNP; \ -} - -/* - * Process received characters. - */ -static void -unstuff_chars(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - mblk_t *om; - uchar_t *cp, *cpend, *dp, *dp0; - int c, len, extra, offset; - ushort_t fcs; - - state = (ahdlc_state_t *) q->q_ptr; - state->stats.ppp_ibytes += msgdsize(mp); - cp = mp->b_rptr; - for (;;) { - /* - * Advance to next input block if necessary. - */ - if (cp >= mp->b_wptr) { - mp = mp->b_cont; - if (mp == 0) - break; - cp = mp->b_rptr; - continue; - } - - if ((state->flags & (IFLUSH|ESCAPED)) == 0 - && state->inlen > 0 && (om = state->cur_blk) != 0) { - /* - * Process bulk chars as quickly as possible. - */ - dp = om->b_wptr; - len = om->b_datap->db_lim - dp; /* max # output bytes */ - extra = (mp->b_wptr - cp) - len;/* #input chars - #output bytes */ - if (extra < 0) { - len += extra; /* we'll run out of input first */ - extra = 0; - } - cpend = cp + len; - dp0 = dp; - fcs = state->infcs; - while (cp < cpend) { - c = *cp; - if (c == PPP_FLAG) - break; - ++cp; - UPDATE_FLAGS(c); - if (c == PPP_ESCAPE) { - if (extra > 0) { - --extra; - ++cpend; - } - if (cp >= cpend || (c = *cp) == PPP_FLAG) { - state->flags |= ESCAPED; - break; - } - ++cp; - UPDATE_FLAGS(c); - c ^= PPP_TRANS; - } - *dp++ = c; - fcs = PPP_FCS(fcs, c); - } - state->inlen += dp - dp0; - state->infcs = fcs; - om->b_wptr = dp; - if (cp >= mp->b_wptr) - continue; /* advance to the next mblk */ - } - - c = *cp++; - UPDATE_FLAGS(c); - if (c == PPP_FLAG) { - /* - * End of a frame. - * If the ESCAPE flag is set, the frame ended with - * the frame abort sequence "}~". - */ - om = state->cur_frame; - len = state->inlen; - state->cur_frame = 0; - state->inlen = 0; - if (len == 0 && (state->flags & IFLUSH) == 0) - continue; - state->stats.ppp_ipackets++; - if (om != 0 && (state->flags & (IFLUSH|ESCAPED)) == 0 - && len > PPP_FCSLEN) { - if (state->infcs == PPP_GOODFCS) { - adjmsg(om, -PPP_FCSLEN); /* chop off fcs */ - putnext(q, om); /* bombs away! */ - continue; - } -#if DEBUG - cmn_err(CE_CONT, "ppp_ahdl: bad fcs %x\n", state->infcs); -#endif - } - if (om != 0) - freemsg(om); - state->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - continue; - } - - if (state->flags & IFLUSH) - continue; - if (state->flags & ESCAPED) { - c ^= PPP_TRANS; - state->flags &= ~ESCAPED; - } else if (c == PPP_ESCAPE) { - state->flags |= ESCAPED; - continue; - } - if (state->inlen == 0) { - /* - * First byte of the frame: allocate the first message block. - */ - om = allocb(IFRAME_BSIZE, BPRI_MED); - if (om == 0) { - state->flags |= IFLUSH; - continue; - } - state->cur_frame = om; - state->cur_blk = om; - state->infcs = PPP_INITFCS; - } else { - om = state->cur_blk; - if (om->b_wptr >= om->b_datap->db_lim) { - /* - * Current message block is full. Allocate another one, - * unless we have run out of MRU. - */ - if (state->inlen >= state->mru + PPP_HDRLEN + PPP_FCSLEN) { -#if DEBUG - cmn_err(CE_CONT, "ppp_ahdl: frame too long (%d)\n", - state->inlen); -#endif - state->flags |= IFLUSH; - continue; - } - om = allocb(IFRAME_BSIZE, BPRI_MED); - if (om == 0) { - state->flags |= IFLUSH; - continue; - } - state->cur_blk->b_cont = om; - state->cur_blk = om; - } - } - - if (state->inlen == 0) { - /* - * We don't do address/control & protocol decompression here, - * but we try to put the first byte at an offset such that - * the info field starts on a word boundary. The code here - * will do this except for packets with protocol compression - * but not address/control compression. - */ - if (c != PPP_ALLSTATIONS) { - om->b_wptr += 2; - if (c & 1) - ++om->b_wptr; - om->b_rptr = om->b_wptr; - } - } - - *om->b_wptr++ = c; - ++state->inlen; - state->infcs = PPP_FCS(state->infcs, c); - } -} - -static int -msg_copy(buf, mp, n) - uchar_t *buf; - mblk_t *mp; - int n; -{ - int i; - uchar_t *cp; - - cp = mp->b_rptr; - for (i = 0; i < n; ++i) { - if (cp >= mp->b_wptr) { - do { - if ((mp = mp->b_cont) == 0) - return i; - } while (mp->b_rptr >= mp->b_wptr); - cp = mp->b_rptr; - } - buf[i] = *cp++; - } - return n; -} diff --git a/svr4/ppp_comp.c b/svr4/ppp_comp.c deleted file mode 100644 index 34eda24..0000000 --- a/svr4/ppp_comp.c +++ /dev/null @@ -1,891 +0,0 @@ -/* - * ppp_comp.c - STREAMS module for kernel-level compression and CCP support. - * - * 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_comp.c,v 1.5 1995/10/27 03:56:19 paulus Exp $ - */ - -/* - * This file is used under SVR4 and Solaris 2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef sun -#include -#include -#endif -#include -#include -#include -#include -#include -#include - -#define PACKETPTR mblk_t * -#include - -static int ppp_comp_open __P((queue_t *, dev_t *, int, int, cred_t *)); -static int ppp_comp_close __P((queue_t *, int, cred_t *)); -static int ppp_comp_rput __P((queue_t *, mblk_t *)); -static int ppp_comp_rsrv __P((queue_t *)); -static int ppp_comp_wput __P((queue_t *, mblk_t *)); -static int ppp_comp_wsrv __P((queue_t *)); -static void ppp_comp_ccp __P((queue_t *, mblk_t *, int)); - -static struct module_info minfo = { - 0xbadf, "ppp_comp", 0, INFPSZ, 16384, 4096, -}; - -static struct qinit r_init = { - ppp_comp_rput, ppp_comp_rsrv, ppp_comp_open, ppp_comp_close, - NULL, &minfo, NULL -}; - -static struct qinit w_init = { - ppp_comp_wput, ppp_comp_wsrv, NULL, NULL, NULL, &minfo, NULL -}; - -static struct streamtab ppp_compinfo = { - &r_init, &w_init, NULL, NULL -}; - -#if defined(sun) && defined(svr4) /* Solaris 2 */ -static struct fmodsw fsw = { - "ppp_comp", - &ppp_compinfo, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP compression module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; -#endif - -typedef struct comp_state { - int flags; - int mru; - int mtu; - int unit; - struct compressor *xcomp; - void *xstate; - struct compressor *rcomp; - void *rstate; - struct vjcompress vj_comp; - int vj_last_ierrors; - struct pppstat stats; -} comp_state_t; - -/* Bits in flags are as defined in pppio.h. */ -#define CCP_ERR (CCP_ERROR | CCP_FATALERROR) -#define LAST_MOD 0x1000000 /* no ppp modules below us */ - -#define MAX_IPHDR 128 /* max TCP/IP header size */ -#define MAX_VJHDR 20 /* max VJ compressed header size (?) */ - -#undef MIN /* just in case */ -#define MIN(a, b) ((a) < (b)? (a): (b)) - -#ifdef D_MP -/* Use msgpullup if we have other multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - mblk_t *np = msgpullup((mp), (len)); \ - freemsg(mp); \ - mp = np; \ - } while (0) - -#else -/* Use pullupmsg if we don't have any multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - if (!pullupmsg((mp), (len))) { \ - freemsg(mp); \ - mp = 0; \ - } \ - } while (0) - -#endif - - -/* - * List of compressors we know about. - */ - -extern struct compressor ppp_bsd_compress; - -struct compressor *ppp_compressors[] = { -#if DO_BSD_COMPRESS - &ppp_bsd_compress, -#endif - NULL -}; - -#ifdef sun -/* - * Entry points for modloading. - */ -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); -} -#endif - -#ifndef sun -# define qprocson(q) -# define qprocsoff(q) -#define canputnext(q) canput((q)->q_next) -#endif - -/* - * STREAMS module entry points. - */ -static int -ppp_comp_open(q, devp, flag, sflag, credp) - queue_t *q; - dev_t *devp; - int flag, sflag; - cred_t *credp; -{ - comp_state_t *cp; - - if (q->q_ptr == NULL) { - cp = (comp_state_t *) kmem_zalloc(sizeof(comp_state_t), KM_SLEEP); - if (cp == NULL) - return ENOSR; - WR(q)->q_ptr = q->q_ptr = cp; - bzero((caddr_t)cp, sizeof(comp_state_t)); - cp->mru = PPP_MRU; - cp->mtu = PPP_MRU; - cp->xstate = NULL; - cp->rstate = NULL; - vj_compress_init(&cp->vj_comp, -1); - qprocson(q); - } - return 0; -} - -static int -ppp_comp_close(q, flag, credp) - queue_t *q; - int flag; - cred_t *credp; -{ - comp_state_t *cp; - - qprocsoff(q); - cp = (comp_state_t *) q->q_ptr; - if (cp != NULL) { - if (cp->xstate != NULL) - (*cp->xcomp->comp_free)(cp->xstate); - if (cp->rstate != NULL) - (*cp->rcomp->decomp_free)(cp->rstate); - kmem_free(cp, sizeof(comp_state_t)); - q->q_ptr = NULL; - OTHERQ(q)->q_ptr = NULL; - } - return 0; -} - -static int -ppp_comp_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - struct iocblk *iop; - comp_state_t *cp; - int error, len; - int flags, mask; - mblk_t *np; - struct compressor **comp; - struct ppp_stats *psp; - struct ppp_comp_stats *csp; - unsigned char *opt_data; - int nxslots, nrslots; - - cp = (comp_state_t *) q->q_ptr; - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - - case PPPIO_CFLAGS: - /* set/get CCP state */ - if (iop->ioc_count != 2 * sizeof(int)) - break; - flags = ((int *) mp->b_cont->b_rptr)[0]; - mask = ((int *) mp->b_cont->b_rptr)[1]; - cp->flags = (cp->flags & ~mask) | (flags & mask); - if ((mask & CCP_ISOPEN) && (flags & CCP_ISOPEN) == 0) { - if (cp->xstate != NULL) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = NULL; - } - if (cp->rstate != NULL) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - cp->flags &= ~CCP_ISUP; - } - error = 0; - iop->ioc_count = sizeof(int); - ((int *) mp->b_cont->b_rptr)[0] = cp->flags; - mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int); - break; - - case PPPIO_VJINIT: - /* - * Initialize VJ compressor/decompressor - */ - if (iop->ioc_count != 2) - break; - nxslots = mp->b_cont->b_rptr[0] + 1; - nrslots = mp->b_cont->b_rptr[1] + 1; - if (nxslots > MAX_STATES || nrslots > MAX_STATES) - break; - vj_compress_init(&cp->vj_comp, nxslots); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_XCOMP: - case PPPIO_RCOMP: - if (iop->ioc_count <= 0) - break; - opt_data = mp->b_cont->b_rptr; - len = mp->b_cont->b_wptr - opt_data; - if (len > iop->ioc_count) - len = iop->ioc_count; - if (opt_data[1] < 2 || opt_data[1] > len) - break; - for (comp = ppp_compressors; *comp != NULL; ++comp) - if ((*comp)->compress_proto == opt_data[0]) { - /* here's the handler! */ - error = 0; - if (iop->ioc_cmd == PPPIO_XCOMP) { - if (cp->xstate != NULL) - (*cp->xcomp->comp_free)(cp->xstate); - cp->xcomp = *comp; - cp->xstate = (*comp)->comp_alloc(opt_data, len); - if (cp->xstate == NULL) - error = ENOSR; - } else { - if (cp->rstate != NULL) - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rcomp = *comp; - cp->rstate = (*comp)->decomp_alloc(opt_data, len); - if (cp->rstate == NULL) - error = ENOSR; - } - break; - } - iop->ioc_count = 0; - break; - - case PPPIO_GETSTAT: - if ((cp->flags & LAST_MOD) == 0) { - error = -1; /* let the ppp_ahdl module handle it */ - break; - } - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - iop->ioc_count = sizeof(struct ppp_stats); - psp->p = cp->stats; - psp->vj = cp->vj_comp.stats; - error = 0; - break; - - case PPPIO_GETCSTAT: - np = allocb(sizeof(struct ppp_comp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - csp = (struct ppp_comp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_comp_stats); - iop->ioc_count = sizeof(struct ppp_comp_stats); - bzero((caddr_t)csp, sizeof(struct ppp_comp_stats)); - if (cp->xstate != 0) - (*cp->xcomp->comp_stat)(cp->xstate, &csp->c); - if (cp->rstate != 0) - (*cp->rcomp->decomp_stat)(cp->rstate, &csp->d); - error = 0; - break; - - case PPPIO_LASTMOD: - cp->flags |= LAST_MOD; - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_error = error; - iop->ioc_count = 0; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: - cp->mtu = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_MRU: - cp->mru = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_UNIT: - cp->unit = mp->b_rptr[1]; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } -} - -static int -ppp_comp_wsrv(q) - queue_t *q; -{ - mblk_t *mp, *cmp = NULL, *np; - comp_state_t *cp; - int len, proto, type; - struct ip *ip; - unsigned char *vjhdr, *dp; - - cp = (comp_state_t *) q->q_ptr; - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ - if (!canputnext(q)) { - putbq(q, mp); - return; - } - - /* - * Make sure we've got a reasonable amount in the first - * mblk and that we are its only user. - * Then find out what the protocol is. - */ - len = msgdsize(mp); - if (len > PPP_HDRLEN + MAX_IPHDR) - len = PPP_HDRLEN + MAX_IPHDR; - if (mp->b_wptr < mp->b_rptr + len || mp->b_datap->db_ref > 1) { - PULLUP(mp, len); - if (mp == 0) { -#if DEBUG - cmn_err(CE_CONT, "ppp_comp_wsrv: pullup failed\n"); -#endif - cp->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - continue; - } - } - proto = PPP_PROTOCOL(mp->b_rptr); - - /* - * Do VJ compression if requested. - */ - if (proto == PPP_IP && (cp->flags & COMP_VJC)) { - ip = (struct ip *) (mp->b_rptr + PPP_HDRLEN); - if (ip->ip_p == IPPROTO_TCP) { - type = vj_compress_tcp(ip, len - PPP_HDRLEN, &cp->vj_comp, - (cp->flags & COMP_VJCCID), &vjhdr); - switch (type) { - case TYPE_UNCOMPRESSED_TCP: - mp->b_rptr[3] = proto = PPP_VJC_UNCOMP; - break; - case TYPE_COMPRESSED_TCP: - dp = vjhdr - PPP_HDRLEN; - dp[1] = mp->b_rptr[1]; /* copy control field */ - dp[0] = mp->b_rptr[0]; /* copy address field */ - dp[2] = 0; /* set protocol field */ - dp[3] = proto = PPP_VJC_COMP; - mp->b_rptr = dp; - break; - } - } - } - - /* - * Do packet compression if enabled. - */ - if (proto == PPP_CCP) - ppp_comp_ccp(q, mp, 0); - else if (proto != PPP_LCP && (cp->flags & CCP_COMP_RUN) - && cp->xstate != NULL) { - len = msgdsize(mp); - (*cp->xcomp->compress)(cp->xstate, &cmp, mp, len, - (cp->flags & CCP_ISUP? cp->mtu: 0)); - if (cmp != NULL) { - freemsg(mp); - mp = cmp; - } - } - - /* - * Do address/control and protocol compression if enabled. - */ - if (proto != PPP_LCP && (cp->flags & COMP_AC)) { - mp->b_rptr += 2; /* drop the address & ctrl fields */ - if (proto < 0x100 && (cp->flags & COMP_PROT)) - ++mp->b_rptr; /* drop the high protocol byte */ - } else if (proto < 0x100 && (cp->flags & COMP_PROT)) { - /* shuffle up the address & ctrl fields */ - mp->b_rptr[2] = mp->b_rptr[1]; - mp->b_rptr[1] = mp->b_rptr[0]; - ++mp->b_rptr; - } - - cp->stats.ppp_opackets++; - cp->stats.ppp_obytes += msgdsize(mp); - putnext(q, mp); - } -} - -static int -ppp_comp_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - comp_state_t *cp; - struct iocblk *iop; - struct ppp_stats *psp; - - cp = (comp_state_t *) q->q_ptr; - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCACK: - iop = (struct iocblk *) mp->b_rptr; - switch (iop->ioc_cmd) { - case PPPIO_GETSTAT: - /* - * Catch this on the way back from the ppp_ahdl module - * so we can fill in the VJ stats. - */ - if (mp->b_cont == 0 || iop->ioc_count != sizeof(struct ppp_stats)) - break; - psp = (struct ppp_stats *) mp->b_cont->b_rptr; - psp->vj = cp->vj_comp.stats; - break; - } - putnext(q, mp); - break; - - case M_CTL: - switch (mp->b_rptr[0]) { - case PPPCTL_IERROR: - ++cp->stats.ppp_ierrors; - break; - case PPPCTL_OERROR: - ++cp->stats.ppp_oerrors; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } -} - -static int -ppp_comp_rsrv(q) - queue_t *q; -{ - int proto, rv, i; - mblk_t *mp, *dmp = NULL, *np; - uchar_t *dp, *iphdr; - comp_state_t *cp; - int len, hlen, vjlen, iphlen; - - cp = (comp_state_t *) q->q_ptr; - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ - if (!canputnext(q)) { - putbq(q, mp); - return; - } - - len = msgdsize(mp); - cp->stats.ppp_ibytes += len; - cp->stats.ppp_ipackets++; - - /* - * First do address/control and protocol "decompression". - */ - hlen = MIN(len, PPP_HDRLEN); - if (mp->b_wptr < mp->b_rptr + hlen) { - PULLUP(mp, hlen); - if (mp == 0) - goto bad; - } - dp = mp->b_rptr; - if (PPP_ADDRESS(dp) == PPP_ALLSTATIONS - && PPP_CONTROL(dp) == PPP_UI) - dp += 2; /* skip address/control */ - else if ((cp->flags & DECOMP_AC) == 0) { - /* count these? */ - goto bad; - } - proto = 0; - if ((*dp & 1) == 0) - proto = *dp++ << 8; /* grab high byte of protocol */ - else if ((cp->flags & DECOMP_PROT) == 0) { - /* count these? */ - goto bad; - } - proto += *dp++; /* grab low byte of protocol */ - if (dp > mp->b_wptr) - goto bad; /* short/bogus packet */ - dp -= PPP_HDRLEN; - if (dp != mp->b_rptr) { - /* - * We need to put some bytes on the front of the packet - * to make a full-length PPP header. - * If we can put them in *mp, we do, otherwise we - * tack another mblk on the front. - * XXX we really shouldn't need to carry around - * the address and control at this stage. - */ - if (dp < mp->b_datap->db_base || mp->b_datap->db_ref > 1) { - np = allocb(PPP_HDRLEN, BPRI_MED); - if (np == 0) - goto bad; - np->b_cont = mp; - mp->b_rptr = dp + PPP_HDRLEN; - mp = np; - dp = mp->b_wptr; - mp->b_wptr += PPP_HDRLEN; - } else - mp->b_rptr = dp; - - dp[0] = PPP_ALLSTATIONS; - dp[1] = PPP_UI; - dp[2] = proto >> 8; - dp[3] = proto; - } - - /* - * Now see if we have a compressed packet to decompress, - * or a CCP packet to take notice of. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_CCP) - ppp_comp_ccp(q, mp, 1); - else if (proto == PPP_COMP) { - if ((cp->flags & CCP_ISUP) - && (cp->flags & CCP_DECOMP_RUN) && cp->rstate - && (cp->flags & CCP_ERR) == 0) { - rv = (*cp->rcomp->decompress)(cp->rstate, mp, &dmp); - switch (rv) { - case DECOMP_OK: - freemsg(mp); - mp = dmp; - if (mp == NULL) { - /* no error, but no packet returned either. */ - continue; - } - break; - case DECOMP_ERROR: - cp->flags |= CCP_ERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - case DECOMP_FATALERROR: - cp->flags |= CCP_FATALERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - } - } - } else if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->incomp)(cp->rstate, mp); - } - - /* - * Now do VJ decompression. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_VJC_COMP || proto == PPP_VJC_UNCOMP) { - len = msgdsize(mp) - PPP_HDRLEN; - if ((cp->flags & DECOMP_VJC) == 0 || len <= 0) - goto bad; - - /* - * Advance past the ppp header. - * Here we assume that the whole PPP header is in the first mblk. - */ - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - if (dp >= mp->b_wptr) { - np = np->b_cont; - dp = np->b_rptr; - } - - if (proto == PPP_VJC_COMP) { - hlen = MIN(len, MAX_VJHDR); - if (np->b_wptr < dp + hlen) { - PULLUP(mp, hlen + PPP_HDRLEN); - if (mp == 0) - goto bad; - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - } - - if (cp->stats.ppp_ierrors != cp->vj_last_ierrors) { - vj_uncompress_err(&cp->vj_comp); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - } - - vjlen = vj_uncompress_tcp(dp, np->b_wptr - dp, len, - &cp->vj_comp, &iphdr, &iphlen); - if (vjlen < 0) - goto bad; - - /* drop ppp and vj headers off */ - if (mp != np) { - freeb(mp); - mp = np; - } - mp->b_rptr = dp + vjlen; - - /* allocate a new mblk for the ppp and ip headers */ - if ((np = allocb(iphlen + PPP_HDRLEN + 4, BPRI_MED)) == 0) - goto bad; - dp = np->b_rptr; /* prepend mblk with TCP/IP hdr */ - dp[0] = PPP_ALLSTATIONS; /* reconstruct PPP header */ - dp[1] = PPP_UI; - dp[2] = PPP_IP >> 8; - dp[3] = PPP_IP; - bcopy(iphdr, dp + PPP_HDRLEN, iphlen); - np->b_wptr = dp + iphlen + PPP_HDRLEN; - np->b_cont = mp; - - /* XXX there seems to be a bug which causes panics in strread - if we make an mbuf with only the IP header in it :-( */ - if (mp->b_wptr - mp->b_rptr > 4) { - bcopy(mp->b_rptr, np->b_wptr, 4); - mp->b_rptr += 4; - np->b_wptr += 4; - } else { - bcopy(mp->b_rptr, np->b_wptr, mp->b_wptr - mp->b_rptr); - np->b_wptr += mp->b_wptr - mp->b_rptr; - np->b_cont = mp->b_cont; - freeb(mp); - } - - mp = np; - - } else { - hlen = MIN(len, MAX_IPHDR); - if (np->b_wptr < dp + hlen || np->b_datap->db_ref > 1 - || mp->b_datap->db_ref > 1) { - PULLUP(mp, hlen + PPP_HDRLEN); - if (mp == 0) - goto bad; - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - } - - if (!vj_uncompress_uncomp(dp, &cp->vj_comp)) - goto bad; - mp->b_rptr[3] = PPP_IP; /* fix up the PPP protocol field */ - } - } - - putnext(q, mp); - continue; - - bad: - if (mp != 0) - freemsg(mp); - cp->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - } -} - -/* - * Handle a CCP packet being sent or received. - */ -static void -ppp_comp_ccp(q, mp, rcvd) - queue_t *q; - mblk_t *mp; - int rcvd; -{ - int len, clen; - comp_state_t *cp; - unsigned char *dp; - mblk_t *np; - - len = msgdsize(mp); - if (len < PPP_HDRLEN + CCP_HDRLEN) - return; - if (mp->b_wptr < mp->b_rptr + len) { - /* XXX this isn't right, because it may free mp */ - PULLUP(mp, len); - if (mp == 0) { - cmn_err(CE_CONT, "ppp_comp_ccp: pullup failed\n"); - return; - } - } - np = mp; - - cp = (comp_state_t *) q->q_ptr; - dp = mp->b_rptr + PPP_HDRLEN; - len -= PPP_HDRLEN; - clen = CCP_LENGTH(dp); - if (clen > len) - goto bad; - - switch (CCP_CODE(dp)) { - case CCP_CONFREQ: - case CCP_TERMREQ: - case CCP_TERMACK: - cp->flags &= ~CCP_ISUP; - break; - - case CCP_CONFACK: - if ((cp->flags & (CCP_ISOPEN | CCP_ISUP)) == CCP_ISOPEN - && clen >= CCP_HDRLEN + CCP_OPT_MINLEN - && clen >= CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) { - if (!rcvd) { - if (cp->xstate != NULL - && (*cp->xcomp->comp_init) - (cp->xstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, 0)) - cp->flags |= CCP_COMP_RUN; - } else { - if (cp->rstate != NULL - && (*cp->rcomp->decomp_init) - (cp->rstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, cp->mru, 0)) - cp->flags = (cp->flags & ~CCP_ERR) - | CCP_DECOMP_RUN; - } - } - break; - - case CCP_RESETACK: - if (cp->flags & CCP_ISUP) { - if (!rcvd) { - if (cp->xstate && (cp->flags & CCP_COMP_RUN)) - (*cp->xcomp->comp_reset)(cp->xstate); - } else { - if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->decomp_reset)(cp->rstate); - cp->flags &= ~CCP_ERROR; - } - } - } - break; - } - - bad: - if (np != mp) - freemsg(np); -} - -#if DEBUG -dump_msg(mp) - mblk_t *mp; -{ - dblk_t *db; - - while (mp != 0) { - db = mp->b_datap; - cmn_err(CE_CONT, "mp=%x cont=%x rptr=%x wptr=%x datap=%x\n", - mp, mp->b_cont, mp->b_rptr, mp->b_wptr, db); - cmn_err(CE_CONT, " base=%x lim=%x ref=%d type=%d struioflag=%d\n", - db->db_base, db->db_lim, db->db_ref, db->db_type, - db->db_struioflag); - mp = mp->b_cont; - } -} -#endif