From bb0891f628e55fbdb149671d0e6344bc84983ec7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 19 Dec 1995 00:06:06 +0000 Subject: [PATCH] new modules for SunOS 4 --- sunos4/Makefile | 49 +++ sunos4/Makefile.top | 50 +++ sunos4/if_ppp.c | 733 +++++++++++++++++++++++++++++++++++++++ sunos4/if_ppp_vdcmd.c | 57 +++ sunos4/ppp.INSTALL | 104 ++++++ sunos4/ppp_ahdlc_vdcmd.c | 57 +++ sunos4/ppp_comp_vdcmd.c | 57 +++ sunos4/ppp_vdcmd.c | 65 ++++ 8 files changed, 1172 insertions(+) create mode 100644 sunos4/Makefile create mode 100644 sunos4/Makefile.top create mode 100644 sunos4/if_ppp.c create mode 100644 sunos4/if_ppp_vdcmd.c create mode 100755 sunos4/ppp.INSTALL create mode 100644 sunos4/ppp_ahdlc_vdcmd.c create mode 100644 sunos4/ppp_comp_vdcmd.c create mode 100644 sunos4/ppp_vdcmd.c diff --git a/sunos4/Makefile b/sunos4/Makefile new file mode 100644 index 0000000..6259e2e --- /dev/null +++ b/sunos4/Makefile @@ -0,0 +1,49 @@ +# +# Makefile for STREAMS modules for SunOS 4. +# +# $Id: Makefile,v 1.1 1995/12/19 00:05:55 paulus Exp $ +# + +ARCH:sh = /bin/arch -k +#CC = gcc + +BINDIR = /usr/local/etc +INSTALL = install -o root -g daemon + +# Defining __$(ARCH)__ is for gcc's broken version of sun/vddrv.h. +CFLAGS= -DKERNEL -I.. -O -DSUNOS4 -D$(ARCH) -D__$(ARCH)__ -DDEBUG -DNO_DLPI + +MODULES= ppp_mod.o ppp_ahdl_mod.o ppp_comp_mod.o if_ppp_mod.o + +all: $(MODULES) + +ppp_mod.o: ppp.o ppp_vdcmd.o + ld -r -o ppp_mod.o ppp.o ppp_vdcmd.o + +ppp_ahdl_mod.o: ppp_ahdlc.o ppp_ahdlc_vdcmd.o + ld -r -o ppp_ahdl_mod.o ppp_ahdlc.o ppp_ahdlc_vdcmd.o + +ppp_comp_mod.o: ppp_comp.o bsd-comp.o vjcompress.o ppp_comp_vdcmd.o + ld -r -o ppp_comp_mod.o ppp_comp.o bsd-comp.o vjcompress.o \ + ppp_comp_vdcmd.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 $? + +if_ppp_mod.o: if_ppp.o if_ppp_vdcmd.o + ld -r -o if_ppp_mod.o if_ppp.o if_ppp_vdcmd.o + +install: all + $(INSTALL) $(MODULES) $(BINDIR) + ./ppp.INSTALL + +clean: + rm -f ppp ppp_comp ppp_ahdl *.o *~ core diff --git a/sunos4/Makefile.top b/sunos4/Makefile.top new file mode 100644 index 0000000..b63276c --- /dev/null +++ b/sunos4/Makefile.top @@ -0,0 +1,50 @@ +# +# ppp top level makefile +# + +BINDIR = /usr/local/etc +MANDIR = /usr/local/man +ETCDIR = /etc/ppp + +INSTALL= install -o root -g daemon + +all: + cd chat; $(MAKE) all + cd pppd; $(MAKE) all + cd pppstats; $(MAKE) all + cd sunos4; $(MAKE) all + +install: $(BINDIR) $(MANDIR)/man8 install-progs install-etcppp + +install-progs: + cd chat; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) install + cd pppd; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) install + cd pppstats; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) install + cd sunos4; $(MAKE) BINDIR=$(BINDIR) install + +install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ + $(ETCDIR)/chap-secrets + +$(ETCDIR)/options: + if netstat -rn | grep default >/dev/null; then \ + $(INSTALL) -c -m 644 etc.ppp/options $@; \ + else $(INSTALL) -c -m 644 etc.ppp/options.leaf $@; fi +$(ETCDIR)/pap-secrets: + $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@ +$(ETCDIR)/chap-secrets: + $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@ + +$(BINDIR): + $(INSTALL) -d -m 755 $@ +$(MANDIR)/man8: + $(INSTALL) -d -m 755 $@ +$(ETCDIR): + $(INSTALL) -d -m 755 $@ + +clean: + rm -f *~ + cd chat; $(MAKE) clean + cd pppd; $(MAKE) clean + cd pppstats; $(MAKE) clean + cd sunos4; $(MAKE) clean + diff --git a/sunos4/if_ppp.c b/sunos4/if_ppp.c new file mode 100644 index 0000000..1b8eed5 --- /dev/null +++ b/sunos4/if_ppp.c @@ -0,0 +1,733 @@ +/* + * if_ppp.c - a network interface connected to a STREAMS module. + * + * 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: if_ppp.c,v 1.1 1995/12/19 00:05:59 paulus Exp $ + */ + +/* + * This file is used under SunOS 4. + */ + +#define INET 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NOTSUSER() (suser()? 0: EPERM) +#define ifr_mtu ifr_metric + +#define ZALLOC(n, t, how) ((t *) kmem_zalloc((n) * sizeof(t), (how))) +#define ZFREE(p, n, t) kmem_free((void *)(p), (n) * sizeof(t)) + +#define PPP_MINMTU 64 +#define PPP_MAXMTU 65536 + +typedef unsigned char uchar_t; +typedef unsigned short ushort_t; + +static int if_ppp_open __P((queue_t *, int, int, int)); +static int if_ppp_close __P((queue_t *, int)); +static int if_ppp_wput __P((queue_t *, mblk_t *)); +static int if_ppp_rput __P((queue_t *, mblk_t *)); + +static struct module_info minfo = { + 0x8021, "if_ppp", 0, INFPSZ, 4096, 128 +}; + +static struct qinit rinit = { + if_ppp_rput, NULL, if_ppp_open, if_ppp_close, NULL, &minfo, NULL +}; + +static struct qinit winit = { + if_ppp_wput, NULL, NULL, NULL, NULL, &minfo, NULL +}; + +struct streamtab if_pppinfo = { + &rinit, &winit, NULL, NULL +}; + +typedef struct if_ppp_state { + int unit; + queue_t *q; + int flags; +} if_ppp_t; + +/* Values for flags */ +#define DBGLOG 1 + +static int if_ppp_count; /* Number of currently-active streams */ + +static int ppp_nalloc; /* Number of elements of ifs and states */ +static struct ifnet **ifs; /* Array of pointers to interface structs */ +static if_ppp_t **states; /* Array of pointers to state structs */ + +static int if_ppp_output __P((struct ifnet *, struct mbuf *, + struct sockaddr *)); +static int if_ppp_ioctl __P((struct ifnet *, u_long, caddr_t)); +static struct mbuf *make_mbufs __P((mblk_t *, int)); +static mblk_t *make_message __P((struct mbuf *, int)); +static void ppp_if_detach __P((struct ifnet *)); + +/* + * Detach all the interfaces before unloading. + * Not sure this works. + */ +int +if_ppp_unload() +{ + int i; + + if (if_ppp_count > 0) + return EBUSY; + for (i = 0; i < ppp_nalloc; ++i) + if (ifs[i] != 0) + ppp_if_detach(ifs[i]); + ZFREE(ifs, ppp_nalloc, struct ifnet *); + ZFREE(states, ppp_nalloc, if_ppp_t *); + ppp_nalloc = 0; + return 0; +} + +/* + * STREAMS module entry points. + */ +static int +if_ppp_open(q, dev, flag, sflag) + queue_t *q; + int dev; + int flag, sflag; +{ + if_ppp_t *sp; + + if (q->q_ptr == 0) { + sp = ZALLOC(1, if_ppp_t, KMEM_SLEEP); + if (sp == 0) + return OPENFAIL; + q->q_ptr = (caddr_t) sp; + WR(q)->q_ptr = (caddr_t) sp; + sp->unit = -1; /* no interface unit attached at present */ + sp->q = WR(q); + sp->flags = 0; + ++if_ppp_count; + } + return 0; +} + +static int +if_ppp_close(q, flag) + queue_t *q; + int flag; +{ + if_ppp_t *sp; + struct ifnet *ifp; + + sp = (if_ppp_t *) q->q_ptr; + if (sp != 0) { + if (sp->flags & DBGLOG) + printf("if_ppp closed, q=%x sp=%x\n", q, sp); + if (sp->unit >= 0) { + if (sp->unit < ppp_nalloc) { + states[sp->unit] = 0; + ifp = ifs[sp->unit]; + if (ifp != 0) + ifp->if_flags &= ~(IFF_UP | IFF_RUNNING); +#ifdef DEBUG + } else { + printf("if_ppp: unit %d nonexistent!\n", sp->unit); +#endif + } + } + ZFREE(sp, 1, if_ppp_t); + --if_ppp_count; + } + return 0; +} + +static int +if_ppp_wput(q, mp) + queue_t *q; + mblk_t *mp; +{ + if_ppp_t *sp; + struct iocblk *iop; + int error, unit; + struct ifnet *ifp; + + sp = (if_ppp_t *) q->q_ptr; + switch (mp->b_datap->db_type) { + case M_DATA: + /* + * Now why would we be getting data coming in here?? + */ + if (sp->flags & DBGLOG) + printf("if_ppp: got M_DATA len=%d\n", msgdsize(mp)); + freemsg(mp); + break; + + case M_IOCTL: + iop = (struct iocblk *) mp->b_rptr; + error = EINVAL; + + if (sp->flags & DBGLOG) + printf("if_ppp: got ioctl cmd=%x count=%d\n", + iop->ioc_cmd, iop->ioc_count); + + switch (iop->ioc_cmd) { + case PPPIO_NEWPPA: /* well almost */ + if (iop->ioc_count != sizeof(int) || sp->unit >= 0) + break; + if ((error = NOTSUSER()) != 0) + break; + unit = *(int *)mp->b_cont->b_rptr; + + /* Check that this unit isn't already in use */ + if (unit < ppp_nalloc && states[unit] != 0) { + error = EADDRINUSE; + break; + } + + /* Extend ifs and states arrays if necessary. */ + error = ENOSR; + if (unit >= ppp_nalloc) { + int newn; + struct ifnet **newifs; + if_ppp_t **newstates; + + newn = unit + 4; + if (sp->flags & DBGLOG) + printf("if_ppp: extending ifs to %d\n", newn); + newifs = ZALLOC(newn, struct ifnet *, KMEM_NOSLEEP); + if (newifs == 0) + break; + newstates = ZALLOC(newn, if_ppp_t *, KMEM_NOSLEEP); + if (newstates == 0) { + ZFREE(newifs, newn, struct ifnet *); + break; + } + bcopy(ifs, newifs, ppp_nalloc * sizeof(struct ifnet *)); + bcopy(states, newstates, ppp_nalloc * sizeof(if_ppp_t *)); + ifs = newifs; + states = newstates; + ppp_nalloc = newn; + } + + /* Allocate a new ifnet struct if necessary. */ + ifp = ifs[unit]; + if (ifp == 0) { + ifp = ZALLOC(1, struct ifnet, KMEM_NOSLEEP); + if (ifp == 0) + break; + ifs[unit] = ifp; + ifp->if_name = "ppp"; + ifp->if_unit = unit; + ifp->if_mtu = PPP_MRU; + ifp->if_flags = IFF_POINTOPOINT | IFF_RUNNING; +#ifdef IFF_MULTICAST + ifp->if_flags |= IFF_MULTICAST; +#endif + ifp->if_output = if_ppp_output; + ifp->if_ioctl = if_ppp_ioctl; + ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + if_attach(ifp); + if (sp->flags & DBGLOG) + printf("if_ppp: created unit %d\n", unit); + } else { + ifp->if_mtu = PPP_MRU; + ifp->if_flags |= IFF_RUNNING; + } + + states[unit] = sp; + sp->unit = unit; + + error = 0; + iop->ioc_count = 0; + if (sp->flags & DBGLOG) + printf("if_ppp: attached unit %d, sp=%x q=%x\n", unit, + sp, sp->q); + break; + + case PPPIO_DEBUG: + error = -1; + if (iop->ioc_count == sizeof(int)) { + if (*(int *)mp->b_cont->b_rptr == PPPDBG_LOG + PPPDBG_IF) { + printf("if_ppp: debug log enabled, q=%x sp=%x\n", q, sp); + sp->flags |= DBGLOG; + error = 0; + iop->ioc_count = 0; + } + } + break; + + default: + error = -1; + break; + } + + if (sp->flags & DBGLOG) + printf("if_ppp: ioctl result %d\n", error); + 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; + + default: + putnext(q, mp); + } + return 0; +} + +static int +if_ppp_rput(q, mp) + queue_t *q; + mblk_t *mp; +{ + if_ppp_t *sp; + int proto, s; + struct mbuf *mb; + struct ifqueue *inq; + struct ifnet *ifp; + + sp = (if_ppp_t *) q->q_ptr; + switch (mp->b_datap->db_type) { + case M_DATA: + /* + * Convert the message into an mbuf chain + * and inject it into the network code. + */ + if (sp->flags & DBGLOG) + printf("if_ppp: rput pkt len %d data %x %x %x %x %x %x %x %x\n", + msgdsize(mp), mp->b_rptr[0], mp->b_rptr[1], mp->b_rptr[2], + mp->b_rptr[3], mp->b_rptr[4], mp->b_rptr[5], mp->b_rptr[6], + mp->b_rptr[7]); + + if (sp->unit < 0) { + freemsg(mp); + break; + } + if (sp->unit >= ppp_nalloc || (ifp = ifs[sp->unit]) == 0) { +#ifdef DEBUG + printf("if_ppp: no unit %d!\n", sp->unit); +#endif + freemsg(mp); + break; + } + + if ((ifp->if_flags & IFF_UP) == 0) { + freemsg(mp); + break; + } + ++ifp->if_ipackets; + + proto = PPP_PROTOCOL(mp->b_rptr); + adjmsg(mp, PPP_HDRLEN); + mb = make_mbufs(mp, sizeof(struct ifnet *)); + freemsg(mp); + if (mb == NULL) { + if (sp->flags & DBGLOG) + printf("if_ppp%d: make_mbufs failed\n", ifp->if_unit); + ++ifp->if_ierrors; + break; + } + mb->m_off -= sizeof(struct ifnet *); + mb->m_len += sizeof(struct ifnet *); + *mtod(mb, struct ifnet **) = ifp; + + inq = 0; + switch (proto) { + case PPP_IP: + inq = &ipintrq; + schednetisr(NETISR_IP); + } + + if (inq != 0) { + s = splhigh(); + if (IF_QFULL(inq)) { + IF_DROP(inq); + ++ifp->if_ierrors; + if (sp->flags & DBGLOG) + printf("if_ppp: inq full, proto=%x\n", proto); + m_freem(mb); + } else { + IF_ENQUEUE(inq, mb); + } + splx(s); + } else { + if (sp->flags & DBGLOG) + printf("if_ppp%d: proto=%x?\n", ifp->if_unit, proto); + ++ifp->if_ierrors; + m_freem(mb); + } + break; + + default: + putnext(q, mp); + } + return 0; +} + +/* + * Network code wants to output a packet. + * Turn it into a STREAMS message and send it down. + */ +static int +if_ppp_output(ifp, m0, dst) + struct ifnet *ifp; + struct mbuf *m0; + struct sockaddr *dst; +{ + mblk_t *mp; + int proto, s; + if_ppp_t *sp; + u_char *p; + + if ((ifp->if_flags & IFF_UP) == 0) { + m_freem(m0); + return ENETDOWN; + } + + if ((unsigned)ifp->if_unit >= ppp_nalloc) { +#ifdef DEBUG + printf("if_ppp_output: unit %d?\n", ifp->if_unit); +#endif + m_freem(m0); + return EINVAL; + } + sp = states[ifp->if_unit]; + if (sp == 0) { +#ifdef DEBUG + printf("if_ppp_output: no queue?\n"); +#endif + m_freem(m0); + return ENETDOWN; + } + + if (sp->flags & DBGLOG) { + p = mtod(m0, u_char *); + printf("if_ppp_output%d: af=%d data=%x %x %x %x %x %x %x %x q=%x\n", + ifp->if_unit, dst->sa_family, p[0], p[1], p[2], p[3], p[4], + p[5], p[6], p[7], sp->q); + } + + switch (dst->sa_family) { + case AF_INET: + proto = PPP_IP; + break; + default: + m_freem(m0); + return EAFNOSUPPORT; + } + + ++ifp->if_opackets; + mp = make_message(m0, PPP_HDRLEN); + m_freem(m0); + if (mp == 0) { + ++ifp->if_oerrors; + return ENOBUFS; + } + mp->b_rptr -= PPP_HDRLEN; + mp->b_rptr[0] = PPP_ALLSTATIONS; + mp->b_rptr[1] = PPP_UI; + mp->b_rptr[2] = proto >> 8; + mp->b_rptr[3] = proto; + + s = splstr(); + if (sp->flags & DBGLOG) + printf("if_ppp: putnext(%x, %x), r=%x w=%x p=%x\n", + sp->q, mp, mp->b_rptr, mp->b_wptr, proto); + putnext(sp->q, mp); + splx(s); + + return 0; +} + +/* + * Socket ioctl routine for ppp interfaces. + */ +static int +if_ppp_ioctl(ifp, cmd, data) + struct ifnet *ifp; + u_long cmd; + caddr_t data; +{ + int s, error; + struct ifreq *ifr = (struct ifreq *) data; + struct ifaddr *ifa = (struct ifaddr *) data; + + error = 0; + s = splimp(); + switch (cmd) { + case SIOCSIFFLAGS: + if ((ifp->if_flags & IFF_RUNNING) == 0) + ifp->if_flags &= ~IFF_UP; + break; + + case SIOCSIFADDR: + if (ifa->ifa_addr.sa_family != AF_INET) + error = EAFNOSUPPORT; + break; + + case SIOCSIFDSTADDR: + if (ifa->ifa_addr.sa_family != AF_INET) + error = EAFNOSUPPORT; + break; + + case SIOCSIFMTU: + if ((error = NOTSUSER()) != 0) + break; + if (ifr->ifr_mtu < PPP_MINMTU || ifr->ifr_mtu > PPP_MAXMTU) { + error = EINVAL; + break; + } + ifp->if_mtu = ifr->ifr_mtu; + break; + + case SIOCGIFMTU: + ifr->ifr_mtu = ifp->if_mtu; + break; + + case SIOCADDMULTI: + case SIOCDELMULTI: + switch(ifr->ifr_addr.sa_family) { + case AF_INET: + break; + default: + error = EAFNOSUPPORT; + break; + } + break; + + default: + error = EINVAL; + } + splx(s); + return (error); +} + +/* + * Turn a STREAMS message into an mbuf chain. + */ +static struct mbuf * +make_mbufs(mp, off) + mblk_t *mp; + int off; +{ + struct mbuf *head, **prevp, *m; + int len, space, n; + unsigned char *cp, *dp; + + len = msgdsize(mp); + if (len == 0) + return 0; + prevp = &head; + space = 0; + cp = mp->b_rptr; + for (;;) { + while (cp >= mp->b_wptr) { + mp = mp->b_cont; + if (mp == 0) { + *prevp = 0; + return head; + } + cp = mp->b_rptr; + } + n = mp->b_wptr - cp; + if (space == 0) { + MGET(m, M_DONTWAIT, MT_DATA); + *prevp = m; + if (m == 0) { + if (head != 0) + m_freem(head); + return 0; + } + if (len + off > 2 * MLEN) { + MCLGET(m); + } + space = (m->m_off > MMAXOFF? MCLBYTES: MLEN) - off; + m->m_off += off; + m->m_len = 0; + len -= space; + dp = mtod(m, unsigned char *); + off = 0; + prevp = &m->m_next; + } + if (n > space) + n = space; + bcopy(cp, dp, n); + cp += n; + dp += n; + space -= n; + m->m_len += n; + } +} + +/* + * Turn an mbuf chain into a STREAMS message. + */ +#define ALLOCB_MAX 4096 + +static mblk_t * +make_message(m, off) + struct mbuf *m; + int off; +{ + mblk_t *head, **prevp, *mp; + int len, space, n, nb; + unsigned char *cp, *dp; + struct mbuf *nm; + + len = 0; + for (nm = m; nm != 0; nm = nm->m_next) + len += nm->m_len; + prevp = &head; + space = 0; + cp = mtod(m, unsigned char *); + nb = m->m_len; + for (;;) { + while (nb <= 0) { + m = m->m_next; + if (m == 0) { + *prevp = 0; + return head; + } + cp = mtod(m, unsigned char *); + nb = m->m_len; + } + if (space == 0) { + space = len + off; + if (space > ALLOCB_MAX) + space = ALLOCB_MAX; + mp = allocb(space, BPRI_LO); + *prevp = mp; + if (mp == 0) { + if (head != 0) + freemsg(head); + return 0; + } + dp = mp->b_rptr += off; + space -= off; + len -= space; + off = 0; + prevp = &mp->b_cont; + } + n = nb < space? nb: space; + bcopy(cp, dp, n); + cp += n; + dp += n; + nb -= n; + space -= n; + mp->b_wptr = dp; + } +} + +/* + * Remove an interface from the system. + * This routine contains magic. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static void +ppp_if_detach(ifp) + struct ifnet *ifp; +{ + int s; + struct inpcb *pcb; + struct ifaddr *ifa; + struct in_ifaddr **inap; + struct ifnet **ifpp; + + s = splhigh(); + + /* + * Clear the interface from any routes currently cached in + * TCP or UDP protocol control blocks. + */ + for (pcb = tcb.inp_next; pcb != &tcb; pcb = pcb->inp_next) + if (pcb->inp_route.ro_rt && pcb->inp_route.ro_rt->rt_ifp == ifp) + in_losing(pcb); + for (pcb = udb.inp_next; pcb != &udb; pcb = pcb->inp_next) + if (pcb->inp_route.ro_rt && pcb->inp_route.ro_rt->rt_ifp == ifp) + in_losing(pcb); + + /* + * Delete routes through all addresses of the interface. + */ + for (ifa = ifp->if_addrlist; ifa != 0; ifa = ifa->ifa_next) { + rtinit(ifa, ifa, SIOCDELRT, RTF_HOST); + rtinit(ifa, ifa, SIOCDELRT, 0); + } + + /* + * Unlink the interface's address(es) from the in_ifaddr list. + */ + for (inap = &in_ifaddr; *inap != 0; ) { + if ((*inap)->ia_ifa.ifa_ifp == ifp) + *inap = (*inap)->ia_next; + else + inap = &(*inap)->ia_next; + } + + /* + * Delete the interface from the ifnet list. + */ + for (ifpp = &ifnet; (*ifpp) != 0; ) { + if (*ifpp == ifp) + break; + ifpp = &(*ifpp)->if_next; + } + if (*ifpp == 0) + printf("couldn't find interface ppp%d in ifnet list\n", ifp->if_unit); + else + *ifpp = ifp->if_next; + + splx(s); +} diff --git a/sunos4/if_ppp_vdcmd.c b/sunos4/if_ppp_vdcmd.c new file mode 100644 index 0000000..2bf9710 --- /dev/null +++ b/sunos4/if_ppp_vdcmd.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +extern struct streamtab if_pppinfo; + +static struct vdldrv vd = { + VDMAGIC_USER, + "if_ppp" +}; + +static int fmodsw_index = -1; + +int +if_ppp_vdcmd(fun, vdp, vdi, vds) + unsigned int fun; + struct vddrv *vdp; + addr_t vdi; + struct vdstat *vds; +{ + int n, error; + + switch (fun) { + case VDLOAD: + vdp->vdd_vdtab = (struct vdlinkage *) &vd; + if (fmodsw_index >= 0) + return EBUSY; + for (n = 0; n < fmodcnt; ++n) + if (fmodsw[n].f_str == 0) + break; + if (n >= fmodcnt) + return ENODEV; + strncpy(fmodsw[n].f_name, vd.Drv_name, FMNAMESZ+1); + fmodsw[n].f_str = &if_pppinfo; + fmodsw_index = n; + break; + + case VDUNLOAD: + if (fmodsw_index <= 0) + return EINVAL; + error = if_ppp_unload(); + if (error != 0) + return error; + fmodsw[fmodsw_index].f_name[0] = 0; + fmodsw[fmodsw_index].f_str = 0; + fmodsw_index = -1; + break; + + case VDSTAT: + break; + + default: + return EIO; + } + return 0; +} diff --git a/sunos4/ppp.INSTALL b/sunos4/ppp.INSTALL new file mode 100755 index 0000000..aa55a5d --- /dev/null +++ b/sunos4/ppp.INSTALL @@ -0,0 +1,104 @@ +#!/bin/sh + +# Script for loading, unloading, etc. ppp modules. + +moddir=/usr/local/etc +etcppp=/etc/ppp + +PATH=/usr/etc:/usr/bin + +# Check that we're superuser +touch /tmp/su$$ +if chown root /tmp/su$$ >/dev/null; then : +else + echo "$0: must be root." + rm -f /tmp/su$$ + exit 1 +fi +rm -f /tmp/su$$ + +case "$0" in +*ppp.INSTALL) + if [ ! -f ppp.INSTALL ]; then + echo "ppp.INSTALL: not found" + exit 1 + fi + for n in INSTALL LOAD UNLOAD MKDEV RMDEV; do + if [ -h /dev/ppp.$n -o -f /dev/ppp.$n ]; then + rm /dev/ppp.$n + fi + done + cp ppp.INSTALL /dev + for n in LOAD UNLOAD MKDEV RMDEV; do + ln -s ppp.INSTALL /dev/ppp.$n + done + ;; + +*ppp.LOAD) + if modstat | grep -w ppp >/dev/null; then + echo "ppp driver is already loaded." + exit 1 + fi + if modstat | grep -w if_ppp >/dev/null; then + echo "if_ppp module already loaded: not reloading." + else + echo -n "if_ppp: " + modload $moddir/if_ppp_mod.o -sym -entry _if_ppp_vdcmd \ + -o $etcppp/if_ppp_mod + fi + echo -n "ppp: " + modload $moddir/ppp_mod.o -sym -entry _ppp_vdcmd -exec /dev/ppp.MKDEV \ + -o $etcppp/ppp_mod + echo -n "ppp_comp: " + modload $moddir/ppp_comp_mod.o -sym -entry _ppp_comp_vdcmd \ + -o $etcppp/ppp_comp + echo -n "ppp_ahdl: " + modload $moddir/ppp_ahdl_mod.o -sym -entry _ppp_ahdlc_vdcmd \ + -o $etcppp/ppp_ahdl + exit 0 + ;; + +*ppp.MKDEV) + # args: module number, type, b-major, c-major + if [ $# -ne 4 ]; then + echo "Usage: $0 module-id module-type b-major c-major" + exit 1 + fi + if [ "$2" -ne "12345607" ]; then + echo "$0: $2: bad module type" + exit 1 + fi + rm -f /dev/ppp + # we "just know" that 37 is the major number of the clone driver + mknod /dev/ppp c 37 $3 + chmod 644 /dev/ppp + exit 0 + ;; + +*ppp.UNLOAD) + stat=0 + if modstat | grep -w if_ppp >/dev/null; then + echo "$0: not unloading if_ppp module." + fi + for mod in ppp ppp_comp ppp_ahdl; do + id=`modstat | grep -w $mod | awk '{print $1}'` + if [ x$id = x ]; then + echo "$mod is not loaded." + stat = 1 + else + modunload -id $id + fi + done + exit $stat + ;; + +*ppp.RMDEV) + echo "$# args: $*" + exit 0 + ;; + +*) + echo "Invocation names: ppp.INSTALL ppp.LOAD ppp.UNLOAD ppp.MKDEV ppp.RMDEV" + exit 1 + ;; +esac diff --git a/sunos4/ppp_ahdlc_vdcmd.c b/sunos4/ppp_ahdlc_vdcmd.c new file mode 100644 index 0000000..2dbe826 --- /dev/null +++ b/sunos4/ppp_ahdlc_vdcmd.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +extern struct streamtab ppp_ahdlcinfo; +extern int ppp_ahdlc_count; + +static struct vdldrv vd = { + VDMAGIC_USER, + "ppp_ahdl" +}; + +static int fmodsw_index = -1; + +int +ppp_ahdlc_vdcmd(fun, vdp, vdi, vds) + unsigned int fun; + struct vddrv *vdp; + addr_t vdi; + struct vdstat *vds; +{ + int n; + + switch (fun) { + case VDLOAD: + vdp->vdd_vdtab = (struct vdlinkage *) &vd; + if (fmodsw_index >= 0) + return EBUSY; + for (n = 0; n < fmodcnt; ++n) + if (fmodsw[n].f_str == 0) + break; + if (n >= fmodcnt) + return ENODEV; + strncpy(fmodsw[n].f_name, vd.Drv_name, FMNAMESZ+1); + fmodsw[n].f_str = &ppp_ahdlcinfo; + fmodsw_index = n; + break; + + case VDUNLOAD: + if (ppp_ahdlc_count > 0) + return EBUSY; + if (fmodsw_index <= 0) + return EINVAL; + fmodsw[fmodsw_index].f_name[0] = 0; + fmodsw[fmodsw_index].f_str = 0; + fmodsw_index = -1; + break; + + case VDSTAT: + break; + + default: + return EIO; + } + return 0; +} diff --git a/sunos4/ppp_comp_vdcmd.c b/sunos4/ppp_comp_vdcmd.c new file mode 100644 index 0000000..b81bc47 --- /dev/null +++ b/sunos4/ppp_comp_vdcmd.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +extern struct streamtab ppp_compinfo; +extern int ppp_comp_count; + +static struct vdldrv vd = { + VDMAGIC_USER, + "ppp_comp" +}; + +static int fmodsw_index = -1; + +int +ppp_comp_vdcmd(fun, vdp, vdi, vds) + unsigned int fun; + struct vddrv *vdp; + addr_t vdi; + struct vdstat *vds; +{ + int n; + + switch (fun) { + case VDLOAD: + vdp->vdd_vdtab = (struct vdlinkage *) &vd; + if (fmodsw_index >= 0) + return EBUSY; + for (n = 0; n < fmodcnt; ++n) + if (fmodsw[n].f_str == 0) + break; + if (n >= fmodcnt) + return ENODEV; + strncpy(fmodsw[n].f_name, vd.Drv_name, FMNAMESZ+1); + fmodsw[n].f_str = &ppp_compinfo; + fmodsw_index = n; + break; + + case VDUNLOAD: + if (ppp_comp_count > 0) + return EBUSY; + if (fmodsw_index <= 0) + return EINVAL; + fmodsw[fmodsw_index].f_name[0] = 0; + fmodsw[fmodsw_index].f_str = 0; + fmodsw_index = -1; + break; + + case VDSTAT: + break; + + default: + return EIO; + } + return 0; +} diff --git a/sunos4/ppp_vdcmd.c b/sunos4/ppp_vdcmd.c new file mode 100644 index 0000000..eeaa039 --- /dev/null +++ b/sunos4/ppp_vdcmd.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +extern struct streamtab pppinfo; +extern int ppp_count; +extern int nchrdev; + +static struct vdldrv vd = { + VDMAGIC_PSEUDO, + "ppp" +}; + +extern int nodev(); + +static struct cdevsw ppp_cdevsw = { + nodev, nodev, nodev, nodev, nodev, nodev, nodev, 0, + &pppinfo +}; + +static struct cdevsw old_entry; + +int +ppp_vdcmd(fun, vdp, vdi, vds) + unsigned int fun; + struct vddrv *vdp; + addr_t vdi; + struct vdstat *vds; +{ + int n, maj; + + switch (fun) { + case VDLOAD: + /* + * It seems like modload doesn't install the cdevsw entry + * for us. Oh well... + */ + for (maj = 1; maj < nchrdev; ++maj) + if (cdevsw[maj].d_open == &vd_unuseddev) + break; + if (maj >= nchrdev) + return ENODEV; + vd.Drv_charmajor = maj; + old_entry = cdevsw[maj]; + cdevsw[maj] = ppp_cdevsw; + vd.Drv_cdevsw = &ppp_cdevsw; + vdp->vdd_vdtab = (struct vdlinkage *) &vd; + break; + + case VDUNLOAD: + if (ppp_count > 0) + return EBUSY; + if (vd.Drv_charmajor > 0) + cdevsw[vd.Drv_charmajor] = old_entry; + break; + + case VDSTAT: + break; + + default: + return EIO; + } + return 0; +} -- 2.39.2