1/*
2 * ppp.c - STREAMS multiplexing pseudo-device driver for PPP.
3 *
4 * Copyright (c) 1994 The Australian National University.
5 * All rights reserved.
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation is hereby granted, provided that the above copyright
9 * notice appears in all copies.  This software is provided without any
10 * warranty, express or implied. The Australian National University
11 * makes no representations about the suitability of this software for
12 * any purpose.
13 *
14 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
15 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
17 * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
18 * OF SUCH DAMAGE.
19 *
20 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
23 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
24 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
25 * OR MODIFICATIONS.
26 *
27 * $Id: ppp.c,v 1.1.1.1 2008/10/15 03:30:13 james26_jang Exp $
28 */
29
30/*
31 * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX.
32 */
33
34#include <sys/types.h>
35#include <sys/param.h>
36#include <sys/stat.h>
37#include <sys/stream.h>
38#include <sys/stropts.h>
39#include <sys/errno.h>
40#ifdef __osf__
41#include <sys/ioctl.h>
42#include <sys/cmn_err.h>
43#define queclass(mp)	((mp)->b_band & QPCTL)
44#else
45#include <sys/ioccom.h>
46#endif
47#include <sys/time.h>
48#ifdef SVR4
49#include <sys/cmn_err.h>
50#include <sys/conf.h>
51#include <sys/dlpi.h>
52#include <sys/ddi.h>
53#ifdef SOL2
54#include <sys/ksynch.h>
55#include <sys/kstat.h>
56#include <sys/sunddi.h>
57#include <sys/ethernet.h>
58#else
59#include <sys/socket.h>
60#include <sys/sockio.h>
61#include <net/if.h>
62#include <netinet/in.h>
63#endif /* SOL2 */
64#else /* not SVR4 */
65#include <sys/user.h>
66#endif /* SVR4 */
67#include <net/ppp_defs.h>
68#include <net/pppio.h>
69#include "ppp_mod.h"
70
71/*
72 * Modifications marked with #ifdef PRIOQ are for priority queueing of
73 * interactive traffic, and are due to Marko Zec <zec@japa.tel.fer.hr>.
74 */
75#ifdef PRIOQ
76#endif	/* PRIOQ */
77
78#include <netinet/in.h>	/* leave this outside of PRIOQ for htons */
79
80#ifdef __STDC__
81#define __P(x)	x
82#else
83#define __P(x)	()
84#endif
85
86/*
87 * The IP module may use this SAP value for IP packets.
88 */
89#ifndef ETHERTYPE_IP
90#define ETHERTYPE_IP	0x800
91#endif
92
93#if !defined(ETHERTYPE_IPV6)
94#define ETHERTYPE_IPV6	0x86dd
95#endif /* !defined(ETHERTYPE_IPV6) */
96
97#if !defined(ETHERTYPE_ALLSAP) && defined(SOL2)
98#define ETHERTYPE_ALLSAP   0
99#endif /* !defined(ETHERTYPE_ALLSAP) && defined(SOL2) */
100
101#if !defined(PPP_ALLSAP) && defined(SOL2)
102#define PPP_ALLSAP  PPP_ALLSTATIONS
103#endif /* !defined(PPP_ALLSAP) && defined(SOL2) */
104
105extern time_t time;
106
107#ifdef SOL2
108/*
109 * We use this reader-writer lock to ensure that the lower streams
110 * stay connected to the upper streams while the lower-side put and
111 * service procedures are running.  Essentially it is an existence
112 * lock for the upper stream associated with each lower stream.
113 */
114krwlock_t ppp_lower_lock;
115#define LOCK_LOWER_W	rw_enter(&ppp_lower_lock, RW_WRITER)
116#define LOCK_LOWER_R	rw_enter(&ppp_lower_lock, RW_READER)
117#define TRYLOCK_LOWER_R	rw_tryenter(&ppp_lower_lock, RW_READER)
118#define UNLOCK_LOWER	rw_exit(&ppp_lower_lock)
119
120#define MT_ENTER(x)	mutex_enter(x)
121#define MT_EXIT(x)	mutex_exit(x)
122
123/*
124 * Notes on multithreaded implementation for Solaris 2:
125 *
126 * We use an inner perimeter around each queue pair and an outer
127 * perimeter around the whole driver.  The inner perimeter is
128 * entered exclusively for all entry points (open, close, put,
129 * service).  The outer perimeter is entered exclusively for open
130 * and close and shared for put and service.  This is all done for
131 * us by the streams framework.
132 *
133 * I used to think that the perimeters were entered for the lower
134 * streams' put and service routines as well as for the upper streams'.
135 * Because of problems experienced by people, and after reading the
136 * documentation more closely, I now don't think that is true.  So we
137 * now use ppp_lower_lock to give us an existence guarantee on the
138 * upper stream controlling each lower stream.
139 *
140 * Shared entry to the outer perimeter protects the existence of all
141 * the upper streams and their upperstr_t structures, and guarantees
142 * that the following fields of any upperstr_t won't change:
143 * nextmn, next, nextppa.  It guarantees that the lowerq field of an
144 * upperstr_t won't go from non-zero to zero, that the global `ppas'
145 * won't change and that the no lower stream will get unlinked.
146 *
147 * Shared (reader) access to ppa_lower_lock guarantees that no lower
148 * stream will be unlinked and that the lowerq field of all upperstr_t
149 * structures won't change.
150 */
151
152#else /* SOL2 */
153#define LOCK_LOWER_W	0
154#define LOCK_LOWER_R	0
155#define TRYLOCK_LOWER_R	1
156#define UNLOCK_LOWER	0
157#define MT_ENTER(x)	0
158#define MT_EXIT(x)	0
159
160#endif /* SOL2 */
161
162/*
163 * Private information; one per upper stream.
164 */
165typedef struct upperstr {
166    minor_t mn;			/* minor device number */
167    struct upperstr *nextmn;	/* next minor device */
168    queue_t *q;			/* read q associated with this upper stream */
169    int flags;			/* flag bits, see below */
170    int state;			/* current DLPI state */
171    int sap;			/* service access point */
172    int req_sap;		/* which SAP the DLPI client requested */
173    struct upperstr *ppa;	/* control stream for our ppa */
174    struct upperstr *next;	/* next stream for this ppa */
175    uint ioc_id;		/* last ioctl ID for this stream */
176    enum NPmode npmode;		/* what to do with packets on this SAP */
177    unsigned char rblocked;	/* flow control has blocked upper read strm */
178	/* N.B. rblocked is only changed by control stream's put/srv procs */
179    /*
180     * There is exactly one control stream for each PPA.
181     * The following fields are only used for control streams.
182     */
183    int ppa_id;
184    queue_t *lowerq;		/* write queue attached below this PPA */
185    struct upperstr *nextppa;	/* next control stream */
186    int mru;
187    int mtu;
188    struct pppstat stats;	/* statistics */
189    time_t last_sent;		/* time last NP packet sent */
190    time_t last_recv;		/* time last NP packet rcvd */
191#ifdef SOL2
192    kmutex_t stats_lock;	/* lock for stats updates */
193    kstat_t *kstats;		/* stats for netstat */
194#endif /* SOL2 */
195#ifdef LACHTCP
196    int ifflags;
197    char ifname[IFNAMSIZ];
198    struct ifstats ifstats;
199#endif /* LACHTCP */
200} upperstr_t;
201
202/* Values for flags */
203#define US_PRIV		1	/* stream was opened by superuser */
204#define US_CONTROL	2	/* stream is a control stream */
205#define US_BLOCKED	4	/* flow ctrl has blocked lower write stream */
206#define US_LASTMOD	8	/* no PPP modules below us */
207#define US_DBGLOG	0x10	/* log various occurrences */
208#define US_RBLOCKED	0x20	/* flow ctrl has blocked upper read stream */
209
210#if defined(SOL2)
211#if DL_CURRENT_VERSION >= 2
212#define US_PROMISC	0x40	/* stream is promiscuous */
213#endif /* DL_CURRENT_VERSION >= 2 */
214#define US_RAWDATA	0x80	/* raw M_DATA, no DLPI header */
215#endif /* defined(SOL2) */
216
217#ifdef PRIOQ
218static u_char max_band=0;
219static u_char def_band=0;
220
221#define IPPORT_DEFAULT		65535
222
223/*
224 * Port priority table
225 * Highest priority ports are listed first, lowest are listed last.
226 * ICMP & packets using unlisted ports will be treated as "default".
227 * If IPPORT_DEFAULT is not listed here, "default" packets will be
228 * assigned lowest priority.
229 * Each line should be terminated with "0".
230 * Line containing only "0" marks the end of the list.
231 */
232
233static u_short prioq_table[]= {
234    113, 53, 0,
235    22, 23, 513, 517, 518, 0,
236    514, 21, 79, 111, 0,
237    25, 109, 110, 0,
238    IPPORT_DEFAULT, 0,
239    20, 70, 80, 8001, 8008, 8080, 0, /* 8001,8008,8080 - common proxy ports */
2400 };
241
242#endif	/* PRIOQ */
243
244
245static upperstr_t *minor_devs = NULL;
246static upperstr_t *ppas = NULL;
247
248#ifdef SVR4
249static int pppopen __P((queue_t *, dev_t *, int, int, cred_t *));
250static int pppclose __P((queue_t *, int, cred_t *));
251#else
252static int pppopen __P((queue_t *, int, int, int));
253static int pppclose __P((queue_t *, int));
254#endif /* SVR4 */
255static int pppurput __P((queue_t *, mblk_t *));
256static int pppuwput __P((queue_t *, mblk_t *));
257static int pppursrv __P((queue_t *));
258static int pppuwsrv __P((queue_t *));
259static int ppplrput __P((queue_t *, mblk_t *));
260static int ppplwput __P((queue_t *, mblk_t *));
261static int ppplrsrv __P((queue_t *));
262static int ppplwsrv __P((queue_t *));
263#ifndef NO_DLPI
264static void dlpi_request __P((queue_t *, mblk_t *, upperstr_t *));
265static void dlpi_error __P((queue_t *, upperstr_t *, int, int, int));
266static void dlpi_ok __P((queue_t *, int));
267#endif
268static int send_data __P((mblk_t *, upperstr_t *));
269static void new_ppa __P((queue_t *, mblk_t *));
270static void attach_ppa __P((queue_t *, mblk_t *));
271static void detach_ppa __P((queue_t *, mblk_t *));
272static void detach_lower __P((queue_t *, mblk_t *));
273static void debug_dump __P((queue_t *, mblk_t *));
274static upperstr_t *find_dest __P((upperstr_t *, int));
275#if defined(SOL2)
276static upperstr_t *find_promisc __P((upperstr_t *, int));
277static mblk_t *prepend_ether __P((upperstr_t *, mblk_t *, int));
278static mblk_t *prepend_udind __P((upperstr_t *, mblk_t *, int));
279static void promisc_sendup __P((upperstr_t *, mblk_t *, int, int));
280#endif /* defined(SOL2) */
281static int putctl2 __P((queue_t *, int, int, int));
282static int putctl4 __P((queue_t *, int, int, int));
283static int pass_packet __P((upperstr_t *ppa, mblk_t *mp, int outbound));
284#ifdef FILTER_PACKETS
285static int ip_hard_filter __P((upperstr_t *ppa, mblk_t *mp, int outbound));
286#endif /* FILTER_PACKETS */
287
288#define PPP_ID 0xb1a6
289static struct module_info ppp_info = {
290#ifdef PRIOQ
291    PPP_ID, "ppp", 0, 512, 512, 384
292#else
293    PPP_ID, "ppp", 0, 512, 512, 128
294#endif	/* PRIOQ */
295};
296
297static struct qinit pppurint = {
298    pppurput, pppursrv, pppopen, pppclose, NULL, &ppp_info, NULL
299};
300
301static struct qinit pppuwint = {
302    pppuwput, pppuwsrv, NULL, NULL, NULL, &ppp_info, NULL
303};
304
305static struct qinit ppplrint = {
306    ppplrput, ppplrsrv, NULL, NULL, NULL, &ppp_info, NULL
307};
308
309static struct qinit ppplwint = {
310    ppplwput, ppplwsrv, NULL, NULL, NULL, &ppp_info, NULL
311};
312
313#ifdef LACHTCP
314extern struct ifstats *ifstats;
315int pppdevflag = 0;
316#endif
317
318struct streamtab pppinfo = {
319    &pppurint, &pppuwint,
320    &ppplrint, &ppplwint
321};
322
323int ppp_count;
324
325/*
326 * How we maintain statistics.
327 */
328#ifdef SOL2
329#define INCR_IPACKETS(ppa)				\
330	if (ppa->kstats != 0) {				\
331	    KSTAT_NAMED_PTR(ppa->kstats)[0].value.ul++;	\
332	}
333#define INCR_IERRORS(ppa)				\
334	if (ppa->kstats != 0) {				\
335	    KSTAT_NAMED_PTR(ppa->kstats)[1].value.ul++;	\
336	}
337#define INCR_OPACKETS(ppa)				\
338	if (ppa->kstats != 0) {				\
339	    KSTAT_NAMED_PTR(ppa->kstats)[2].value.ul++;	\
340	}
341#define INCR_OERRORS(ppa)				\
342	if (ppa->kstats != 0) {				\
343	    KSTAT_NAMED_PTR(ppa->kstats)[3].value.ul++;	\
344	}
345#endif
346
347#ifdef LACHTCP
348#define INCR_IPACKETS(ppa)	ppa->ifstats.ifs_ipackets++;
349#define INCR_IERRORS(ppa)	ppa->ifstats.ifs_ierrors++;
350#define INCR_OPACKETS(ppa)	ppa->ifstats.ifs_opackets++;
351#define INCR_OERRORS(ppa)	ppa->ifstats.ifs_oerrors++;
352#endif
353
354/*
355 * STREAMS driver entry points.
356 */
357static int
358#ifdef SVR4
359pppopen(q, devp, oflag, sflag, credp)
360    queue_t *q;
361    dev_t *devp;
362    int oflag, sflag;
363    cred_t *credp;
364#else
365pppopen(q, dev, oflag, sflag)
366    queue_t *q;
367    int dev;			/* really dev_t */
368    int oflag, sflag;
369#endif
370{
371    upperstr_t *up;
372    upperstr_t **prevp;
373    minor_t mn;
374#ifdef PRIOQ
375    u_short *ptr;
376    u_char new_band;
377#endif	/* PRIOQ */
378
379    if (q->q_ptr)
380	DRV_OPEN_OK(dev);	/* device is already open */
381
382#ifdef PRIOQ
383    /* Calculate max_bband & def_band from definitions in prioq.h
384       This colud be done at some more approtiate time (less often)
385       but this way it works well so I'll just leave it here */
386
387    max_band = 1;
388    def_band = 0;
389    ptr = prioq_table;
390    while (*ptr) {
391        new_band = 1;
392        while (*ptr)
393	    if (*ptr++ == IPPORT_DEFAULT) {
394		new_band = 0;
395		def_band = max_band;
396	    }
397        max_band += new_band;
398        ptr++;
399    }
400    if (def_band)
401        def_band = max_band - def_band;
402    --max_band;
403#endif	/* PRIOQ */
404
405    if (sflag == CLONEOPEN) {
406	mn = 0;
407	for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) {
408	    if (up->mn != mn)
409		break;
410	    ++mn;
411	}
412    } else {
413#ifdef SVR4
414	mn = getminor(*devp);
415#else
416	mn = minor(dev);
417#endif
418	for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) {
419	    if (up->mn >= mn)
420		break;
421	}
422	if (up->mn == mn) {
423	    /* this can't happen */
424	    q->q_ptr = WR(q)->q_ptr = (caddr_t) up;
425	    DRV_OPEN_OK(dev);
426	}
427    }
428
429    /*
430     * Construct a new minor node.
431     */
432    up = (upperstr_t *) ALLOC_SLEEP(sizeof(upperstr_t));
433    bzero((caddr_t) up, sizeof(upperstr_t));
434    if (up == 0) {
435	DPRINT("pppopen: out of kernel memory\n");
436	OPEN_ERROR(ENXIO);
437    }
438    up->nextmn = *prevp;
439    *prevp = up;
440    up->mn = mn;
441#ifdef SVR4
442    *devp = makedevice(getmajor(*devp), mn);
443#endif
444    up->q = q;
445    if (NOTSUSER() == 0)
446	up->flags |= US_PRIV;
447#ifndef NO_DLPI
448    up->state = DL_UNATTACHED;
449#endif
450#ifdef LACHTCP
451    up->ifflags = IFF_UP | IFF_POINTOPOINT;
452#endif
453    up->sap = -1;
454    up->last_sent = up->last_recv = time;
455    up->npmode = NPMODE_DROP;
456    q->q_ptr = (caddr_t) up;
457    WR(q)->q_ptr = (caddr_t) up;
458    noenable(WR(q));
459#ifdef SOL2
460    mutex_init(&up->stats_lock, NULL, MUTEX_DRIVER, NULL);
461#endif
462    ++ppp_count;
463
464    qprocson(q);
465    DRV_OPEN_OK(makedev(major(dev), mn));
466}
467
468static int
469#ifdef SVR4
470pppclose(q, flag, credp)
471    queue_t *q;
472    int flag;
473    cred_t *credp;
474#else
475pppclose(q, flag)
476    queue_t *q;
477    int flag;
478#endif
479{
480    upperstr_t *up, **upp;
481    upperstr_t *as, *asnext;
482    upperstr_t **prevp;
483
484    qprocsoff(q);
485
486    up = (upperstr_t *) q->q_ptr;
487    if (up == 0) {
488	DPRINT("pppclose: q_ptr = 0\n");
489	return 0;
490    }
491    if (up->flags & US_DBGLOG)
492	DPRINT2("ppp/%d: close, flags=%x\n", up->mn, up->flags);
493    if (up->flags & US_CONTROL) {
494#ifdef LACHTCP
495	struct ifstats *ifp, *pifp;
496#endif
497	if (up->lowerq != 0) {
498	    /* Gack! the lower stream should have be unlinked earlier! */
499	    DPRINT1("ppp%d: lower stream still connected on close?\n",
500		    up->mn);
501	    LOCK_LOWER_W;
502	    up->lowerq->q_ptr = 0;
503	    RD(up->lowerq)->q_ptr = 0;
504	    up->lowerq = 0;
505	    UNLOCK_LOWER;
506	}
507
508	/*
509	 * This stream represents a PPA:
510	 * For all streams attached to the PPA, clear their
511	 * references to this PPA.
512	 * Then remove this PPA from the list of PPAs.
513	 */
514	for (as = up->next; as != 0; as = asnext) {
515	    asnext = as->next;
516	    as->next = 0;
517	    as->ppa = 0;
518	    if (as->flags & US_BLOCKED) {
519		as->flags &= ~US_BLOCKED;
520		flushq(WR(as->q), FLUSHDATA);
521	    }
522	}
523	for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa)
524	    if (*upp == up) {
525		*upp = up->nextppa;
526		break;
527	    }
528#ifdef LACHTCP
529	/* Remove the statistics from the active list.  */
530	for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) {
531	    if (ifp == &up->ifstats) {
532		if (pifp)
533		    pifp->ifs_next = ifp->ifs_next;
534		else
535		    ifstats = ifp->ifs_next;
536		break;
537	    }
538	    pifp = ifp;
539	}
540#endif
541    } else {
542	/*
543	 * If this stream is attached to a PPA,
544	 * remove it from the PPA's list.
545	 */
546	if ((as = up->ppa) != 0) {
547	    for (; as->next != 0; as = as->next)
548		if (as->next == up) {
549		    as->next = up->next;
550		    break;
551		}
552	}
553    }
554
555#ifdef SOL2
556    if (up->kstats)
557	kstat_delete(up->kstats);
558    mutex_destroy(&up->stats_lock);
559#endif
560
561    q->q_ptr = NULL;
562    WR(q)->q_ptr = NULL;
563
564    for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) {
565	if (*prevp == up) {
566	    *prevp = up->nextmn;
567	    break;
568	}
569    }
570    FREE(up, sizeof(upperstr_t));
571    --ppp_count;
572
573    return 0;
574}
575
576/*
577 * A message from on high.  We do one of three things:
578 *	- qreply()
579 *	- put the message on the lower write stream
580 *	- queue it for our service routine
581 */
582static int
583pppuwput(q, mp)
584    queue_t *q;
585    mblk_t *mp;
586{
587    upperstr_t *us, *ppa, *nps;
588    struct iocblk *iop;
589    struct linkblk *lb;
590#ifdef LACHTCP
591    struct ifreq *ifr;
592    int i;
593#endif
594    queue_t *lq;
595    int error, n, sap;
596    mblk_t *mq;
597    struct ppp_idle *pip;
598#ifdef PRIOQ
599    queue_t *tlq;
600#endif	/* PRIOQ */
601#ifdef NO_DLPI
602    upperstr_t *os;
603#endif
604
605    us = (upperstr_t *) q->q_ptr;
606    if (us == 0) {
607	DPRINT("pppuwput: q_ptr = 0!\n");
608	return 0;
609    }
610    if (mp == 0) {
611	DPRINT1("pppuwput/%d: mp = 0!\n", us->mn);
612	return 0;
613    }
614    if (mp->b_datap == 0) {
615	DPRINT1("pppuwput/%d: mp->b_datap = 0!\n", us->mn);
616	return 0;
617    }
618    switch (mp->b_datap->db_type) {
619#ifndef NO_DLPI
620    case M_PCPROTO:
621    case M_PROTO:
622	dlpi_request(q, mp, us);
623	break;
624#endif /* NO_DLPI */
625
626    case M_DATA:
627	if (us->flags & US_DBGLOG)
628	    DPRINT3("ppp/%d: uwput M_DATA len=%d flags=%x\n",
629		    us->mn, msgdsize(mp), us->flags);
630	if (us->ppa == 0 || msgdsize(mp) > us->ppa->mtu + PPP_HDRLEN
631#ifndef NO_DLPI
632	    || (us->flags & US_CONTROL) == 0
633#endif /* NO_DLPI */
634	    ) {
635	    DPRINT1("pppuwput: junk data len=%d\n", msgdsize(mp));
636	    freemsg(mp);
637	    break;
638	}
639#ifdef NO_DLPI
640	if ((us->flags & US_CONTROL) == 0 && !pass_packet(us, mp, 1))
641	    break;
642#endif
643	if (!send_data(mp, us))
644	    putq(q, mp);
645	break;
646
647    case M_IOCTL:
648	iop = (struct iocblk *) mp->b_rptr;
649	error = EINVAL;
650	if (us->flags & US_DBGLOG)
651	    DPRINT3("ppp/%d: ioctl %x count=%d\n",
652		    us->mn, iop->ioc_cmd, iop->ioc_count);
653	switch (iop->ioc_cmd) {
654#if defined(SOL2)
655	case DLIOCRAW:	    /* raw M_DATA mode */
656	    us->flags |= US_RAWDATA;
657	    error = 0;
658	    break;
659#endif /* defined(SOL2) */
660	case I_LINK:
661	    if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0)
662		break;
663	    if (mp->b_cont == 0) {
664		DPRINT1("pppuwput/%d: ioctl I_LINK b_cont = 0!\n", us->mn);
665		break;
666	    }
667	    lb = (struct linkblk *) mp->b_cont->b_rptr;
668	    lq = lb->l_qbot;
669	    if (lq == 0) {
670		DPRINT1("pppuwput/%d: ioctl I_LINK l_qbot = 0!\n", us->mn);
671		break;
672	    }
673	    LOCK_LOWER_W;
674	    us->lowerq = lq;
675	    lq->q_ptr = (caddr_t) q;
676	    RD(lq)->q_ptr = (caddr_t) us->q;
677	    UNLOCK_LOWER;
678	    iop->ioc_count = 0;
679	    error = 0;
680	    us->flags &= ~US_LASTMOD;
681	    /* Unblock upper streams which now feed this lower stream. */
682	    qenable(q);
683	    /* Send useful information down to the modules which
684	       are now linked below us. */
685	    putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id);
686	    putctl4(lq, M_CTL, PPPCTL_MRU, us->mru);
687	    putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu);
688#ifdef PRIOQ
689            /* Lower tty driver's queue hiwat/lowat from default 4096/128
690               to 256/128 since we don't want queueing of data on
691               output to physical device */
692
693            freezestr(lq);
694            for (tlq = lq; tlq->q_next != NULL; tlq = tlq->q_next)
695		;
696            strqset(tlq, QHIWAT, 0, 256);
697            strqset(tlq, QLOWAT, 0, 128);
698            unfreezestr(lq);
699#endif	/* PRIOQ */
700	    break;
701
702	case I_UNLINK:
703	    if (mp->b_cont == 0) {
704		DPRINT1("pppuwput/%d: ioctl I_UNLINK b_cont = 0!\n", us->mn);
705		break;
706	    }
707	    lb = (struct linkblk *) mp->b_cont->b_rptr;
708#if DEBUG
709	    if (us->lowerq != lb->l_qbot) {
710		DPRINT2("ppp unlink: lowerq=%x qbot=%x\n",
711			us->lowerq, lb->l_qbot);
712		break;
713	    }
714#endif
715	    iop->ioc_count = 0;
716	    qwriter(q, mp, detach_lower, PERIM_OUTER);
717	    error = -1;
718	    break;
719
720	case PPPIO_NEWPPA:
721	    if (us->flags & US_CONTROL)
722		break;
723	    if ((us->flags & US_PRIV) == 0) {
724		error = EPERM;
725		break;
726	    }
727	    /* Arrange to return an int */
728	    if ((mq = mp->b_cont) == 0
729		|| mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) {
730		mq = allocb(sizeof(int), BPRI_HI);
731		if (mq == 0) {
732		    error = ENOSR;
733		    break;
734		}
735		if (mp->b_cont != 0)
736		    freemsg(mp->b_cont);
737		mp->b_cont = mq;
738		mq->b_cont = 0;
739	    }
740	    iop->ioc_count = sizeof(int);
741	    mq->b_wptr = mq->b_rptr + sizeof(int);
742	    qwriter(q, mp, new_ppa, PERIM_OUTER);
743	    error = -1;
744	    break;
745
746	case PPPIO_ATTACH:
747	    /* like dlpi_attach, for programs which can't write to
748	       the stream (like pppstats) */
749	    if (iop->ioc_count != sizeof(int) || us->ppa != 0)
750		break;
751	    if (mp->b_cont == 0) {
752		DPRINT1("pppuwput/%d: ioctl PPPIO_ATTACH b_cont = 0!\n", us->mn);
753		break;
754	    }
755	    n = *(int *)mp->b_cont->b_rptr;
756	    for (ppa = ppas; ppa != 0; ppa = ppa->nextppa)
757		if (ppa->ppa_id == n)
758		    break;
759	    if (ppa == 0)
760		break;
761	    us->ppa = ppa;
762	    iop->ioc_count = 0;
763	    qwriter(q, mp, attach_ppa, PERIM_OUTER);
764	    error = -1;
765	    break;
766
767#ifdef NO_DLPI
768	case PPPIO_BIND:
769	    /* Attach to a given SAP. */
770	    if (iop->ioc_count != sizeof(int) || us->ppa == 0)
771		break;
772	    if (mp->b_cont == 0) {
773		DPRINT1("pppuwput/%d: ioctl PPPIO_BIND b_cont = 0!\n", us->mn);
774		break;
775	    }
776	    n = *(int *)mp->b_cont->b_rptr;
777	    /* n must be a valid PPP network protocol number. */
778	    if (n < 0x21 || n > 0x3fff || (n & 0x101) != 1)
779		break;
780	    /* check that no other stream is bound to this sap already. */
781	    for (os = us->ppa; os != 0; os = os->next)
782		if (os->sap == n)
783		    break;
784	    if (os != 0)
785		break;
786	    us->sap = n;
787	    iop->ioc_count = 0;
788	    error = 0;
789	    break;
790#endif /* NO_DLPI */
791
792	case PPPIO_MRU:
793	    if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0)
794		break;
795	    if (mp->b_cont == 0) {
796		DPRINT1("pppuwput/%d: ioctl PPPIO_MRU b_cont = 0!\n", us->mn);
797		break;
798	    }
799	    n = *(int *)mp->b_cont->b_rptr;
800	    if (n <= 0 || n > PPP_MAXMRU)
801		break;
802	    if (n < PPP_MRU)
803		n = PPP_MRU;
804	    us->mru = n;
805	    if (us->lowerq)
806		putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n);
807	    error = 0;
808	    iop->ioc_count = 0;
809	    break;
810
811	case PPPIO_MTU:
812	    if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0)
813		break;
814	    if (mp->b_cont == 0) {
815		DPRINT1("pppuwput/%d: ioctl PPPIO_MTU b_cont = 0!\n", us->mn);
816		break;
817	    }
818	    n = *(int *)mp->b_cont->b_rptr;
819	    if (n <= 0 || n > PPP_MAXMTU)
820		break;
821	    us->mtu = n;
822#ifdef LACHTCP
823	    /* The MTU reported in netstat, not used as IP max packet size! */
824	    us->ifstats.ifs_mtu = n;
825#endif
826	    if (us->lowerq)
827		putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n);
828	    error = 0;
829	    iop->ioc_count = 0;
830	    break;
831
832	case PPPIO_LASTMOD:
833	    us->flags |= US_LASTMOD;
834	    error = 0;
835	    break;
836
837	case PPPIO_DEBUG:
838	    if (iop->ioc_count != sizeof(int))
839		break;
840	    if (mp->b_cont == 0) {
841		DPRINT1("pppuwput/%d: ioctl PPPIO_DEBUG b_cont = 0!\n", us->mn);
842		break;
843	    }
844	    n = *(int *)mp->b_cont->b_rptr;
845	    if (n == PPPDBG_DUMP + PPPDBG_DRIVER) {
846		qwriter(q, NULL, debug_dump, PERIM_OUTER);
847		iop->ioc_count = 0;
848		error = -1;
849	    } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) {
850		DPRINT1("ppp/%d: debug log enabled\n", us->mn);
851		us->flags |= US_DBGLOG;
852		iop->ioc_count = 0;
853		error = 0;
854	    } else {
855		if (us->ppa == 0 || us->ppa->lowerq == 0)
856		    break;
857		putnext(us->ppa->lowerq, mp);
858		error = -1;
859	    }
860	    break;
861
862	case PPPIO_NPMODE:
863	    if (iop->ioc_count != 2 * sizeof(int))
864		break;
865	    if ((us->flags & US_CONTROL) == 0)
866		break;
867	    if (mp->b_cont == 0) {
868		DPRINT1("pppuwput/%d: ioctl PPPIO_NPMODE b_cont = 0!\n", us->mn);
869		break;
870	    }
871	    sap = ((int *)mp->b_cont->b_rptr)[0];
872	    for (nps = us->next; nps != 0; nps = nps->next) {
873		if (us->flags & US_DBGLOG)
874		    DPRINT2("us = 0x%x, us->next->sap = 0x%x\n", nps, nps->sap);
875		if (nps->sap == sap)
876		    break;
877	    }
878	    if (nps == 0) {
879		if (us->flags & US_DBGLOG)
880		    DPRINT2("ppp/%d: no stream for sap %x\n", us->mn, sap);
881		break;
882	    }
883	    nps->npmode = (enum NPmode) ((int *)mp->b_cont->b_rptr)[1];
884	    if (nps->npmode != NPMODE_QUEUE && (nps->flags & US_BLOCKED) != 0)
885		qenable(WR(nps->q));
886	    iop->ioc_count = 0;
887	    error = 0;
888	    break;
889
890	case PPPIO_GIDLE:
891	    if ((ppa = us->ppa) == 0)
892		break;
893	    mq = allocb(sizeof(struct ppp_idle), BPRI_HI);
894	    if (mq == 0) {
895		error = ENOSR;
896		break;
897	    }
898	    if (mp->b_cont != 0)
899		freemsg(mp->b_cont);
900	    mp->b_cont = mq;
901	    mq->b_cont = 0;
902	    pip = (struct ppp_idle *) mq->b_wptr;
903	    pip->xmit_idle = time - ppa->last_sent;
904	    pip->recv_idle = time - ppa->last_recv;
905	    mq->b_wptr += sizeof(struct ppp_idle);
906	    iop->ioc_count = sizeof(struct ppp_idle);
907	    error = 0;
908	    break;
909
910#ifdef LACHTCP
911	case SIOCSIFNAME:
912	    /* Sent from IP down to us.  Attach the ifstats structure.  */
913	    if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0)
914	        break;
915	    ifr = (struct ifreq *)mp->b_cont->b_rptr;
916	    /* Find the unit number in the interface name.  */
917	    for (i = 0; i < IFNAMSIZ; i++) {
918		if (ifr->ifr_name[i] == 0 ||
919		    (ifr->ifr_name[i] >= '0' &&
920		     ifr->ifr_name[i] <= '9'))
921		    break;
922		else
923		    us->ifname[i] = ifr->ifr_name[i];
924	    }
925	    us->ifname[i] = 0;
926
927	    /* Convert the unit number to binary.  */
928	    for (n = 0; i < IFNAMSIZ; i++) {
929		if (ifr->ifr_name[i] == 0) {
930		    break;
931		}
932	        else {
933		    n = n * 10 + ifr->ifr_name[i] - '0';
934		}
935	    }
936
937	    /* Verify the ppa.  */
938	    if (us->ppa->ppa_id != n)
939		break;
940	    ppa = us->ppa;
941
942	    /* Set up the netstat block.  */
943	    strncpy (ppa->ifname, us->ifname, IFNAMSIZ);
944
945	    ppa->ifstats.ifs_name = ppa->ifname;
946	    ppa->ifstats.ifs_unit = n;
947	    ppa->ifstats.ifs_active = us->state != DL_UNBOUND;
948	    ppa->ifstats.ifs_mtu = ppa->mtu;
949
950	    /* Link in statistics used by netstat.  */
951	    ppa->ifstats.ifs_next = ifstats;
952	    ifstats = &ppa->ifstats;
953
954	    iop->ioc_count = 0;
955	    error = 0;
956	    break;
957
958	case SIOCGIFFLAGS:
959	    if (!(us->flags & US_CONTROL)) {
960		if (us->ppa)
961		    us = us->ppa;
962	        else
963		    break;
964	    }
965	    ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags;
966	    error = 0;
967	    break;
968
969	case SIOCSIFFLAGS:
970	    if (!(us->flags & US_CONTROL)) {
971		if (us->ppa)
972		    us = us->ppa;
973		else
974		    break;
975	    }
976	    us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags;
977	    error = 0;
978	    break;
979
980	case SIOCSIFADDR:
981	    if (!(us->flags & US_CONTROL)) {
982		if (us->ppa)
983		    us = us->ppa;
984		else
985		    break;
986	    }
987	    us->ifflags |= IFF_RUNNING;
988	    ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING;
989	    error = 0;
990	    break;
991
992	case SIOCSIFMTU:
993	    /*
994	     * Vanilla SVR4 systems don't handle SIOCSIFMTU, rather
995	     * they take the MTU from the DL_INFO_ACK we sent in response
996	     * to their DL_INFO_REQ.  Fortunately, they will update the
997	     * MTU if we send an unsolicited DL_INFO_ACK up.
998	     */
999	    if ((mq = allocb(sizeof(dl_info_req_t), BPRI_HI)) == 0)
1000		break;		/* should do bufcall */
1001	    ((union DL_primitives *)mq->b_rptr)->dl_primitive = DL_INFO_REQ;
1002	    mq->b_wptr = mq->b_rptr + sizeof(dl_info_req_t);
1003	    dlpi_request(q, mq, us);
1004	    error = 0;
1005	    break;
1006
1007	case SIOCGIFNETMASK:
1008	case SIOCSIFNETMASK:
1009	case SIOCGIFADDR:
1010	case SIOCGIFDSTADDR:
1011	case SIOCSIFDSTADDR:
1012	case SIOCGIFMETRIC:
1013	    error = 0;
1014	    break;
1015#endif /* LACHTCP */
1016
1017	default:
1018	    if (us->ppa == 0 || us->ppa->lowerq == 0)
1019		break;
1020	    us->ioc_id = iop->ioc_id;
1021	    error = -1;
1022	    switch (iop->ioc_cmd) {
1023	    case PPPIO_GETSTAT:
1024	    case PPPIO_GETCSTAT:
1025		if (us->flags & US_LASTMOD) {
1026		    error = EINVAL;
1027		    break;
1028		}
1029		putnext(us->ppa->lowerq, mp);
1030		break;
1031	    default:
1032		if (us->flags & US_PRIV)
1033		    putnext(us->ppa->lowerq, mp);
1034		else {
1035		    DPRINT1("ppp ioctl %x rejected\n", iop->ioc_cmd);
1036		    error = EPERM;
1037		}
1038		break;
1039	    }
1040	    break;
1041	}
1042
1043	if (error > 0) {
1044	    iop->ioc_error = error;
1045	    mp->b_datap->db_type = M_IOCNAK;
1046	    qreply(q, mp);
1047	} else if (error == 0) {
1048	    mp->b_datap->db_type = M_IOCACK;
1049	    qreply(q, mp);
1050	}
1051	break;
1052
1053    case M_FLUSH:
1054	if (us->flags & US_DBGLOG)
1055	    DPRINT2("ppp/%d: flush %x\n", us->mn, *mp->b_rptr);
1056	if (*mp->b_rptr & FLUSHW)
1057	    flushq(q, FLUSHDATA);
1058	if (*mp->b_rptr & FLUSHR) {
1059	    *mp->b_rptr &= ~FLUSHW;
1060	    qreply(q, mp);
1061	} else
1062	    freemsg(mp);
1063	break;
1064
1065    default:
1066	freemsg(mp);
1067	break;
1068    }
1069    return 0;
1070}
1071
1072#ifndef NO_DLPI
1073static void
1074dlpi_request(q, mp, us)
1075    queue_t *q;
1076    mblk_t *mp;
1077    upperstr_t *us;
1078{
1079    union DL_primitives *d = (union DL_primitives *) mp->b_rptr;
1080    int size = mp->b_wptr - mp->b_rptr;
1081    mblk_t *reply, *np;
1082    upperstr_t *ppa, *os;
1083    int sap, len;
1084    dl_info_ack_t *info;
1085    dl_bind_ack_t *ackp;
1086#if DL_CURRENT_VERSION >= 2
1087    dl_phys_addr_ack_t	*paddrack;
1088    static struct ether_addr eaddr = {0};
1089#endif
1090
1091    if (us->flags & US_DBGLOG)
1092	DPRINT3("ppp/%d: dlpi prim %x len=%d\n", us->mn,
1093		d->dl_primitive, size);
1094    switch (d->dl_primitive) {
1095    case DL_INFO_REQ:
1096	if (size < sizeof(dl_info_req_t))
1097	    goto badprim;
1098	if ((reply = allocb(sizeof(dl_info_ack_t), BPRI_HI)) == 0)
1099	    break;		/* should do bufcall */
1100	reply->b_datap->db_type = M_PCPROTO;
1101	info = (dl_info_ack_t *) reply->b_wptr;
1102	reply->b_wptr += sizeof(dl_info_ack_t);
1103	bzero((caddr_t) info, sizeof(dl_info_ack_t));
1104	info->dl_primitive = DL_INFO_ACK;
1105	info->dl_max_sdu = us->ppa? us->ppa->mtu: PPP_MAXMTU;
1106	info->dl_min_sdu = 1;
1107	info->dl_addr_length = sizeof(uint);
1108	info->dl_mac_type = DL_ETHER;	/* a bigger lie */
1109	info->dl_current_state = us->state;
1110	info->dl_service_mode = DL_CLDLS;
1111	info->dl_provider_style = DL_STYLE2;
1112#if DL_CURRENT_VERSION >= 2
1113	info->dl_sap_length = sizeof(uint);
1114	info->dl_version = DL_CURRENT_VERSION;
1115#endif
1116	qreply(q, reply);
1117	break;
1118
1119    case DL_ATTACH_REQ:
1120	if (size < sizeof(dl_attach_req_t))
1121	    goto badprim;
1122	if (us->state != DL_UNATTACHED || us->ppa != 0) {
1123	    dlpi_error(q, us, DL_ATTACH_REQ, DL_OUTSTATE, 0);
1124	    break;
1125	}
1126	for (ppa = ppas; ppa != 0; ppa = ppa->nextppa)
1127	    if (ppa->ppa_id == d->attach_req.dl_ppa)
1128		break;
1129	if (ppa == 0) {
1130	    dlpi_error(q, us, DL_ATTACH_REQ, DL_BADPPA, 0);
1131	    break;
1132	}
1133	us->ppa = ppa;
1134	qwriter(q, mp, attach_ppa, PERIM_OUTER);
1135	return;
1136
1137    case DL_DETACH_REQ:
1138	if (size < sizeof(dl_detach_req_t))
1139	    goto badprim;
1140	if (us->state != DL_UNBOUND || us->ppa == 0) {
1141	    dlpi_error(q, us, DL_DETACH_REQ, DL_OUTSTATE, 0);
1142	    break;
1143	}
1144	qwriter(q, mp, detach_ppa, PERIM_OUTER);
1145	return;
1146
1147    case DL_BIND_REQ:
1148	if (size < sizeof(dl_bind_req_t))
1149	    goto badprim;
1150	if (us->state != DL_UNBOUND || us->ppa == 0) {
1151	    dlpi_error(q, us, DL_BIND_REQ, DL_OUTSTATE, 0);
1152	    break;
1153	}
1154
1155	/* saps must be valid PPP network protocol numbers,
1156	   except that we accept ETHERTYPE_IP in place of PPP_IP. */
1157	sap = d->bind_req.dl_sap;
1158	us->req_sap = sap;
1159
1160#if defined(SOL2)
1161	if (us->flags & US_DBGLOG)
1162	    DPRINT2("DL_BIND_REQ: ip gives sap = 0x%x, us = 0x%x", sap, us);
1163
1164	if (sap == ETHERTYPE_IP)	    /* normal IFF_IPV4 */
1165	    sap = PPP_IP;
1166	else if (sap == ETHERTYPE_IPV6)	    /* when IFF_IPV6 is set */
1167	    sap = PPP_IPV6;
1168	else if (sap == ETHERTYPE_ALLSAP)   /* snoop gives sap of 0 */
1169	    sap = PPP_ALLSAP;
1170	else {
1171	    DPRINT2("DL_BIND_REQ: unrecognized sap = 0x%x, us = 0x%x", sap, us);
1172	    dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0);
1173	    break;
1174	}
1175#else
1176	if (sap == ETHERTYPE_IP)
1177	    sap = PPP_IP;
1178	if (sap < 0x21 || sap > 0x3fff || (sap & 0x101) != 1) {
1179	    dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0);
1180	    break;
1181	}
1182#endif /* defined(SOL2) */
1183
1184	/* check that no other stream is bound to this sap already. */
1185	for (os = us->ppa; os != 0; os = os->next)
1186	    if (os->sap == sap)
1187		break;
1188	if (os != 0) {
1189	    dlpi_error(q, us, DL_BIND_REQ, DL_NOADDR, 0);
1190	    break;
1191	}
1192
1193	us->sap = sap;
1194	us->state = DL_IDLE;
1195
1196	if ((reply = allocb(sizeof(dl_bind_ack_t) + sizeof(uint),
1197			    BPRI_HI)) == 0)
1198	    break;		/* should do bufcall */
1199	ackp = (dl_bind_ack_t *) reply->b_wptr;
1200	reply->b_wptr += sizeof(dl_bind_ack_t) + sizeof(uint);
1201	reply->b_datap->db_type = M_PCPROTO;
1202	bzero((caddr_t) ackp, sizeof(dl_bind_ack_t));
1203	ackp->dl_primitive = DL_BIND_ACK;
1204	ackp->dl_sap = sap;
1205	ackp->dl_addr_length = sizeof(uint);
1206	ackp->dl_addr_offset = sizeof(dl_bind_ack_t);
1207	*(uint *)(ackp+1) = sap;
1208	qreply(q, reply);
1209	break;
1210
1211    case DL_UNBIND_REQ:
1212	if (size < sizeof(dl_unbind_req_t))
1213	    goto badprim;
1214	if (us->state != DL_IDLE) {
1215	    dlpi_error(q, us, DL_UNBIND_REQ, DL_OUTSTATE, 0);
1216	    break;
1217	}
1218	us->sap = -1;
1219	us->state = DL_UNBOUND;
1220#ifdef LACHTCP
1221	us->ppa->ifstats.ifs_active = 0;
1222#endif
1223	dlpi_ok(q, DL_UNBIND_REQ);
1224	break;
1225
1226    case DL_UNITDATA_REQ:
1227	if (size < sizeof(dl_unitdata_req_t))
1228	    goto badprim;
1229	if (us->state != DL_IDLE) {
1230	    dlpi_error(q, us, DL_UNITDATA_REQ, DL_OUTSTATE, 0);
1231	    break;
1232	}
1233	if ((ppa = us->ppa) == 0) {
1234	    cmn_err(CE_CONT, "ppp: in state dl_idle but ppa == 0?\n");
1235	    break;
1236	}
1237	len = mp->b_cont == 0? 0: msgdsize(mp->b_cont);
1238	if (len > ppa->mtu) {
1239	    DPRINT2("dlpi data too large (%d > %d)\n", len, ppa->mtu);
1240	    break;
1241	}
1242
1243#if defined(SOL2)
1244	/*
1245	 * Should there be any promiscuous stream(s), send the data
1246	 * up for each promiscuous stream that we recognize.
1247	 */
1248	if (mp->b_cont)
1249	    promisc_sendup(ppa, mp->b_cont, us->sap, 0);
1250#endif /* defined(SOL2) */
1251
1252	mp->b_band = 0;
1253#ifdef PRIOQ
1254        /* Extract s_port & d_port from IP-packet, the code is a bit
1255           dirty here, but so am I, too... */
1256        if (mp->b_datap->db_type == M_PROTO && us->sap == PPP_IP
1257	    && mp->b_cont != 0) {
1258	    u_char *bb, *tlh;
1259	    int iphlen, len;
1260	    u_short *ptr;
1261	    u_char band_unset, cur_band, syn;
1262	    u_short s_port, d_port;
1263
1264            bb = mp->b_cont->b_rptr; /* bb points to IP-header*/
1265	    len = mp->b_cont->b_wptr - mp->b_cont->b_rptr;
1266            syn = 0;
1267	    s_port = IPPORT_DEFAULT;
1268	    d_port = IPPORT_DEFAULT;
1269	    if (len >= 20) {	/* 20 = minimum length of IP header */
1270		iphlen = (bb[0] & 0x0f) * 4;
1271		tlh = bb + iphlen;
1272		len -= iphlen;
1273		switch (bb[9]) {
1274		case IPPROTO_TCP:
1275		    if (len >= 20) {	      /* min length of TCP header */
1276			s_port = (tlh[0] << 8) + tlh[1];
1277			d_port = (tlh[2] << 8) + tlh[3];
1278			syn = tlh[13] & 0x02;
1279		    }
1280		    break;
1281		case IPPROTO_UDP:
1282		    if (len >= 8) {	      /* min length of UDP header */
1283			s_port = (tlh[0] << 8) + tlh[1];
1284			d_port = (tlh[2] << 8) + tlh[3];
1285		    }
1286		    break;
1287		}
1288	    }
1289
1290            /*
1291	     * Now calculate b_band for this packet from the
1292	     * port-priority table.
1293	     */
1294            ptr = prioq_table;
1295            cur_band = max_band;
1296            band_unset = 1;
1297            while (*ptr) {
1298                while (*ptr && band_unset)
1299                    if (s_port == *ptr || d_port == *ptr++) {
1300                        mp->b_band = cur_band;
1301                        band_unset = 0;
1302                        break;
1303		    }
1304                ptr++;
1305                cur_band--;
1306	    }
1307            if (band_unset)
1308		mp->b_band = def_band;
1309            /* It may be usable to urge SYN packets a bit */
1310            if (syn)
1311		mp->b_band++;
1312	}
1313#endif	/* PRIOQ */
1314	/* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */
1315	if (mp->b_datap->db_ref > 1) {
1316	    np = allocb(PPP_HDRLEN, BPRI_HI);
1317	    if (np == 0)
1318		break;		/* gak! */
1319	    np->b_cont = mp->b_cont;
1320	    mp->b_cont = 0;
1321	    freeb(mp);
1322	    mp = np;
1323	} else
1324	    mp->b_datap->db_type = M_DATA;
1325	mp->b_wptr = mp->b_rptr + PPP_HDRLEN;
1326	mp->b_rptr[0] = PPP_ALLSTATIONS;
1327	mp->b_rptr[1] = PPP_UI;
1328	mp->b_rptr[2] = us->sap >> 8;
1329	mp->b_rptr[3] = us->sap;
1330	if (pass_packet(us, mp, 1)) {
1331	    if (!send_data(mp, us))
1332		putq(q, mp);
1333	}
1334	return;
1335
1336#if DL_CURRENT_VERSION >= 2
1337    case DL_PHYS_ADDR_REQ:
1338	if (size < sizeof(dl_phys_addr_req_t))
1339	    goto badprim;
1340
1341	/*
1342	 * Don't check state because ifconfig sends this one down too
1343	 */
1344
1345	if ((reply = allocb(sizeof(dl_phys_addr_ack_t)+ETHERADDRL,
1346			BPRI_HI)) == 0)
1347	    break;		/* should do bufcall */
1348	reply->b_datap->db_type = M_PCPROTO;
1349	paddrack = (dl_phys_addr_ack_t *) reply->b_wptr;
1350	reply->b_wptr += sizeof(dl_phys_addr_ack_t);
1351	bzero((caddr_t) paddrack, sizeof(dl_phys_addr_ack_t)+ETHERADDRL);
1352	paddrack->dl_primitive = DL_PHYS_ADDR_ACK;
1353	paddrack->dl_addr_length = ETHERADDRL;
1354	paddrack->dl_addr_offset = sizeof(dl_phys_addr_ack_t);
1355	bcopy(&eaddr, reply->b_wptr, ETHERADDRL);
1356	reply->b_wptr += ETHERADDRL;
1357	qreply(q, reply);
1358	break;
1359
1360#if defined(SOL2)
1361    case DL_PROMISCON_REQ:
1362	if (size < sizeof(dl_promiscon_req_t))
1363	    goto badprim;
1364	us->flags |= US_PROMISC;
1365	dlpi_ok(q, DL_PROMISCON_REQ);
1366	break;
1367
1368    case DL_PROMISCOFF_REQ:
1369	if (size < sizeof(dl_promiscoff_req_t))
1370	    goto badprim;
1371	us->flags &= ~US_PROMISC;
1372	dlpi_ok(q, DL_PROMISCOFF_REQ);
1373	break;
1374#else
1375    case DL_PROMISCON_REQ:	    /* fall thru */
1376    case DL_PROMISCOFF_REQ:	    /* fall thru */
1377#endif /* defined(SOL2) */
1378#endif /* DL_CURRENT_VERSION >= 2 */
1379
1380#if DL_CURRENT_VERSION >= 2
1381    case DL_SET_PHYS_ADDR_REQ:
1382    case DL_SUBS_BIND_REQ:
1383    case DL_SUBS_UNBIND_REQ:
1384    case DL_ENABMULTI_REQ:
1385    case DL_DISABMULTI_REQ:
1386    case DL_XID_REQ:
1387    case DL_TEST_REQ:
1388    case DL_REPLY_UPDATE_REQ:
1389    case DL_REPLY_REQ:
1390    case DL_DATA_ACK_REQ:
1391#endif
1392    case DL_CONNECT_REQ:
1393    case DL_TOKEN_REQ:
1394	dlpi_error(q, us, d->dl_primitive, DL_NOTSUPPORTED, 0);
1395	break;
1396
1397    case DL_CONNECT_RES:
1398    case DL_DISCONNECT_REQ:
1399    case DL_RESET_REQ:
1400    case DL_RESET_RES:
1401	dlpi_error(q, us, d->dl_primitive, DL_OUTSTATE, 0);
1402	break;
1403
1404    case DL_UDQOS_REQ:
1405	dlpi_error(q, us, d->dl_primitive, DL_BADQOSTYPE, 0);
1406	break;
1407
1408#if DL_CURRENT_VERSION >= 2
1409    case DL_TEST_RES:
1410    case DL_XID_RES:
1411	break;
1412#endif
1413
1414    default:
1415	cmn_err(CE_CONT, "ppp: unknown dlpi prim 0x%x\n", d->dl_primitive);
1416	/* fall through */
1417    badprim:
1418	dlpi_error(q, us, d->dl_primitive, DL_BADPRIM, 0);
1419	break;
1420    }
1421    freemsg(mp);
1422}
1423
1424static void
1425dlpi_error(q, us, prim, err, uerr)
1426    queue_t *q;
1427    upperstr_t *us;
1428    int prim, err, uerr;
1429{
1430    mblk_t *reply;
1431    dl_error_ack_t *errp;
1432
1433    if (us->flags & US_DBGLOG)
1434        DPRINT3("ppp/%d: dlpi error, prim=%x, err=%x\n", us->mn, prim, err);
1435    reply = allocb(sizeof(dl_error_ack_t), BPRI_HI);
1436    if (reply == 0)
1437	return;
1438    reply->b_datap->db_type = M_PCPROTO;
1439    errp = (dl_error_ack_t *) reply->b_wptr;
1440    reply->b_wptr += sizeof(dl_error_ack_t);
1441    errp->dl_primitive = DL_ERROR_ACK;
1442    errp->dl_error_primitive = prim;
1443    errp->dl_errno = err;
1444    errp->dl_unix_errno = uerr;
1445    qreply(q, reply);
1446}
1447
1448static void
1449dlpi_ok(q, prim)
1450    queue_t *q;
1451    int prim;
1452{
1453    mblk_t *reply;
1454    dl_ok_ack_t *okp;
1455
1456    reply = allocb(sizeof(dl_ok_ack_t), BPRI_HI);
1457    if (reply == 0)
1458	return;
1459    reply->b_datap->db_type = M_PCPROTO;
1460    okp = (dl_ok_ack_t *) reply->b_wptr;
1461    reply->b_wptr += sizeof(dl_ok_ack_t);
1462    okp->dl_primitive = DL_OK_ACK;
1463    okp->dl_correct_primitive = prim;
1464    qreply(q, reply);
1465}
1466#endif /* NO_DLPI */
1467
1468static int
1469pass_packet(us, mp, outbound)
1470    upperstr_t *us;
1471    mblk_t *mp;
1472    int outbound;
1473{
1474    int pass;
1475    upperstr_t *ppa;
1476
1477    if ((ppa = us->ppa) == 0) {
1478	freemsg(mp);
1479	return 0;
1480    }
1481
1482#ifdef FILTER_PACKETS
1483    pass = ip_hard_filter(us, mp, outbound);
1484#else
1485    /*
1486     * Here is where we might, in future, decide whether to pass
1487     * or drop the packet, and whether it counts as link activity.
1488     */
1489    pass = 1;
1490#endif /* FILTER_PACKETS */
1491
1492    if (pass < 0) {
1493	/* pass only if link already up, and don't update time */
1494	if (ppa->lowerq == 0) {
1495	    freemsg(mp);
1496	    return 0;
1497	}
1498	pass = 1;
1499    } else if (pass) {
1500	if (outbound)
1501	    ppa->last_sent = time;
1502	else
1503	    ppa->last_recv = time;
1504    }
1505
1506    return pass;
1507}
1508
1509/*
1510 * We have some data to send down to the lower stream (or up the
1511 * control stream, if we don't have a lower stream attached).
1512 * Returns 1 if the message was dealt with, 0 if it wasn't able
1513 * to be sent on and should therefore be queued up.
1514 */
1515static int
1516send_data(mp, us)
1517    mblk_t *mp;
1518    upperstr_t *us;
1519{
1520    upperstr_t *ppa;
1521
1522    if ((us->flags & US_BLOCKED) || us->npmode == NPMODE_QUEUE)
1523	return 0;
1524    ppa = us->ppa;
1525    if (ppa == 0 || us->npmode == NPMODE_DROP || us->npmode == NPMODE_ERROR) {
1526	if (us->flags & US_DBGLOG)
1527	    DPRINT2("ppp/%d: dropping pkt (npmode=%d)\n", us->mn, us->npmode);
1528	freemsg(mp);
1529	return 1;
1530    }
1531    if (ppa->lowerq == 0) {
1532	/* try to send it up the control stream */
1533        if (bcanputnext(ppa->q, mp->b_band)) {
1534	    /*
1535	     * The message seems to get corrupted for some reason if
1536	     * we just send the message up as it is, so we send a copy.
1537	     */
1538	    mblk_t *np = copymsg(mp);
1539	    freemsg(mp);
1540	    if (np != 0)
1541		putnext(ppa->q, np);
1542	    return 1;
1543	}
1544    } else {
1545        if (bcanputnext(ppa->lowerq, mp->b_band)) {
1546	    MT_ENTER(&ppa->stats_lock);
1547	    ppa->stats.ppp_opackets++;
1548	    ppa->stats.ppp_obytes += msgdsize(mp);
1549#ifdef INCR_OPACKETS
1550	    INCR_OPACKETS(ppa);
1551#endif
1552	    MT_EXIT(&ppa->stats_lock);
1553	    /*
1554	     * The lower queue is only ever detached while holding an
1555	     * exclusive lock on the whole driver.  So we can be confident
1556	     * that the lower queue is still there.
1557	     */
1558	    putnext(ppa->lowerq, mp);
1559	    return 1;
1560	}
1561    }
1562    us->flags |= US_BLOCKED;
1563    return 0;
1564}
1565
1566/*
1567 * Allocate a new PPA id and link this stream into the list of PPAs.
1568 * This procedure is called with an exclusive lock on all queues in
1569 * this driver.
1570 */
1571static void
1572new_ppa(q, mp)
1573    queue_t *q;
1574    mblk_t *mp;
1575{
1576    upperstr_t *us, *up, **usp;
1577    int ppa_id;
1578
1579    us = (upperstr_t *) q->q_ptr;
1580    if (us == 0) {
1581	DPRINT("new_ppa: q_ptr = 0!\n");
1582	return;
1583    }
1584
1585    usp = &ppas;
1586    ppa_id = 0;
1587    while ((up = *usp) != 0 && ppa_id == up->ppa_id) {
1588	++ppa_id;
1589	usp = &up->nextppa;
1590    }
1591    us->ppa_id = ppa_id;
1592    us->ppa = us;
1593    us->next = 0;
1594    us->nextppa = *usp;
1595    *usp = us;
1596    us->flags |= US_CONTROL;
1597    us->npmode = NPMODE_PASS;
1598
1599    us->mtu = PPP_MTU;
1600    us->mru = PPP_MRU;
1601
1602#ifdef SOL2
1603    /*
1604     * Create a kstats record for our statistics, so netstat -i works.
1605     */
1606    if (us->kstats == 0) {
1607	char unit[32];
1608
1609	sprintf(unit, "ppp%d", us->ppa->ppa_id);
1610	us->kstats = kstat_create("ppp", us->ppa->ppa_id, unit,
1611				  "net", KSTAT_TYPE_NAMED, 4, 0);
1612	if (us->kstats != 0) {
1613	    kstat_named_t *kn = KSTAT_NAMED_PTR(us->kstats);
1614
1615	    strcpy(kn[0].name, "ipackets");
1616	    kn[0].data_type = KSTAT_DATA_ULONG;
1617	    strcpy(kn[1].name, "ierrors");
1618	    kn[1].data_type = KSTAT_DATA_ULONG;
1619	    strcpy(kn[2].name, "opackets");
1620	    kn[2].data_type = KSTAT_DATA_ULONG;
1621	    strcpy(kn[3].name, "oerrors");
1622	    kn[3].data_type = KSTAT_DATA_ULONG;
1623	    kstat_install(us->kstats);
1624	}
1625    }
1626#endif /* SOL2 */
1627
1628    *(int *)mp->b_cont->b_rptr = ppa_id;
1629    mp->b_datap->db_type = M_IOCACK;
1630    qreply(q, mp);
1631}
1632
1633static void
1634attach_ppa(q, mp)
1635    queue_t *q;
1636    mblk_t *mp;
1637{
1638    upperstr_t *us, *t;
1639
1640    us = (upperstr_t *) q->q_ptr;
1641    if (us == 0) {
1642	DPRINT("attach_ppa: q_ptr = 0!\n");
1643	return;
1644    }
1645
1646#ifndef NO_DLPI
1647    us->state = DL_UNBOUND;
1648#endif
1649    for (t = us->ppa; t->next != 0; t = t->next)
1650	;
1651    t->next = us;
1652    us->next = 0;
1653    if (mp->b_datap->db_type == M_IOCTL) {
1654	mp->b_datap->db_type = M_IOCACK;
1655	qreply(q, mp);
1656    } else {
1657#ifndef NO_DLPI
1658	dlpi_ok(q, DL_ATTACH_REQ);
1659#endif
1660    }
1661}
1662
1663static void
1664detach_ppa(q, mp)
1665    queue_t *q;
1666    mblk_t *mp;
1667{
1668    upperstr_t *us, *t;
1669
1670    us = (upperstr_t *) q->q_ptr;
1671    if (us == 0) {
1672	DPRINT("detach_ppa: q_ptr = 0!\n");
1673	return;
1674    }
1675
1676    for (t = us->ppa; t->next != 0; t = t->next)
1677	if (t->next == us) {
1678	    t->next = us->next;
1679	    break;
1680	}
1681    us->next = 0;
1682    us->ppa = 0;
1683#ifndef NO_DLPI
1684    us->state = DL_UNATTACHED;
1685    dlpi_ok(q, DL_DETACH_REQ);
1686#endif
1687}
1688
1689/*
1690 * We call this with qwriter in order to give the upper queue procedures
1691 * the guarantee that the lower queue is not going to go away while
1692 * they are executing.
1693 */
1694static void
1695detach_lower(q, mp)
1696    queue_t *q;
1697    mblk_t *mp;
1698{
1699    upperstr_t *us;
1700
1701    us = (upperstr_t *) q->q_ptr;
1702    if (us == 0) {
1703	DPRINT("detach_lower: q_ptr = 0!\n");
1704	return;
1705    }
1706
1707    LOCK_LOWER_W;
1708    us->lowerq->q_ptr = 0;
1709    RD(us->lowerq)->q_ptr = 0;
1710    us->lowerq = 0;
1711    UNLOCK_LOWER;
1712
1713    /* Unblock streams which now feed back up the control stream. */
1714    qenable(us->q);
1715
1716    mp->b_datap->db_type = M_IOCACK;
1717    qreply(q, mp);
1718}
1719
1720static int
1721pppuwsrv(q)
1722    queue_t *q;
1723{
1724    upperstr_t *us, *as;
1725    mblk_t *mp;
1726
1727    us = (upperstr_t *) q->q_ptr;
1728    if (us == 0) {
1729	DPRINT("pppuwsrv: q_ptr = 0!\n");
1730	return 0;
1731    }
1732
1733    /*
1734     * If this is a control stream, then this service procedure
1735     * probably got enabled because of flow control in the lower
1736     * stream being enabled (or because of the lower stream going
1737     * away).  Therefore we enable the service procedure of all
1738     * attached upper streams.
1739     */
1740    if (us->flags & US_CONTROL) {
1741	for (as = us->next; as != 0; as = as->next)
1742	    qenable(WR(as->q));
1743    }
1744
1745    /* Try to send on any data queued here. */
1746    us->flags &= ~US_BLOCKED;
1747    while ((mp = getq(q)) != 0) {
1748	if (!send_data(mp, us)) {
1749	    putbq(q, mp);
1750	    break;
1751	}
1752    }
1753
1754    return 0;
1755}
1756
1757/* should never get called... */
1758static int
1759ppplwput(q, mp)
1760    queue_t *q;
1761    mblk_t *mp;
1762{
1763    putnext(q, mp);
1764    return 0;
1765}
1766
1767static int
1768ppplwsrv(q)
1769    queue_t *q;
1770{
1771    queue_t *uq;
1772
1773    /*
1774     * Flow control has back-enabled this stream:
1775     * enable the upper write service procedure for
1776     * the upper control stream for this lower stream.
1777     */
1778    LOCK_LOWER_R;
1779    uq = (queue_t *) q->q_ptr;
1780    if (uq != 0)
1781	qenable(uq);
1782    UNLOCK_LOWER;
1783    return 0;
1784}
1785
1786/*
1787 * This should only get called for control streams.
1788 */
1789static int
1790pppurput(q, mp)
1791    queue_t *q;
1792    mblk_t *mp;
1793{
1794    upperstr_t *ppa, *us;
1795    int proto, len;
1796    struct iocblk *iop;
1797
1798    ppa = (upperstr_t *) q->q_ptr;
1799    if (ppa == 0) {
1800	DPRINT("pppurput: q_ptr = 0!\n");
1801	return 0;
1802    }
1803
1804    switch (mp->b_datap->db_type) {
1805    case M_CTL:
1806	MT_ENTER(&ppa->stats_lock);
1807	switch (*mp->b_rptr) {
1808	case PPPCTL_IERROR:
1809#ifdef INCR_IERRORS
1810	    INCR_IERRORS(ppa);
1811#endif
1812	    ppa->stats.ppp_ierrors++;
1813	    break;
1814	case PPPCTL_OERROR:
1815#ifdef INCR_OERRORS
1816	    INCR_OERRORS(ppa);
1817#endif
1818	    ppa->stats.ppp_oerrors++;
1819	    break;
1820	}
1821	MT_EXIT(&ppa->stats_lock);
1822	freemsg(mp);
1823	break;
1824
1825    case M_IOCACK:
1826    case M_IOCNAK:
1827	/*
1828	 * Attempt to match up the response with the stream
1829	 * that the request came from.
1830	 */
1831	iop = (struct iocblk *) mp->b_rptr;
1832	for (us = ppa; us != 0; us = us->next)
1833	    if (us->ioc_id == iop->ioc_id)
1834		break;
1835	if (us == 0)
1836	    freemsg(mp);
1837	else
1838	    putnext(us->q, mp);
1839	break;
1840
1841    case M_HANGUP:
1842	/*
1843	 * The serial device has hung up.  We don't want to send
1844	 * the M_HANGUP message up to pppd because that will stop
1845	 * us from using the control stream any more.  Instead we
1846	 * send a zero-length message as an end-of-file indication.
1847	 */
1848	freemsg(mp);
1849	mp = allocb(1, BPRI_HI);
1850	if (mp == 0) {
1851	    DPRINT1("ppp/%d: couldn't allocate eof message!\n", ppa->mn);
1852	    break;
1853	}
1854	putnext(ppa->q, mp);
1855	break;
1856
1857    default:
1858	if (mp->b_datap->db_type == M_DATA) {
1859	    len = msgdsize(mp);
1860	    if (mp->b_wptr - mp->b_rptr < PPP_HDRLEN) {
1861		PULLUP(mp, PPP_HDRLEN);
1862		if (mp == 0) {
1863		    DPRINT1("ppp_urput: msgpullup failed (len=%d)\n", len);
1864		    break;
1865		}
1866	    }
1867	    MT_ENTER(&ppa->stats_lock);
1868	    ppa->stats.ppp_ipackets++;
1869	    ppa->stats.ppp_ibytes += len;
1870#ifdef INCR_IPACKETS
1871	    INCR_IPACKETS(ppa);
1872#endif
1873	    MT_EXIT(&ppa->stats_lock);
1874
1875	    proto = PPP_PROTOCOL(mp->b_rptr);
1876
1877#if defined(SOL2)
1878	    /*
1879	     * Should there be any promiscuous stream(s), send the data
1880	     * up for each promiscuous stream that we recognize.
1881	     */
1882	    promisc_sendup(ppa, mp, proto, 1);
1883#endif /* defined(SOL2) */
1884
1885	    if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) {
1886		if (!pass_packet(us, mp, 0))
1887		    break;
1888		if (!us->rblocked && !canput(us->q))
1889		    us->rblocked = 1;
1890		if (!us->rblocked)
1891		    putq(us->q, mp);
1892		else
1893		    putq(q, mp);
1894		break;
1895	    }
1896	}
1897	/*
1898	 * A control frame, a frame for an unknown protocol,
1899	 * or some other message type.
1900	 * Send it up to pppd via the control stream.
1901	 */
1902	if (queclass(mp) == QPCTL || canputnext(ppa->q))
1903	    putnext(ppa->q, mp);
1904	else
1905	    putq(q, mp);
1906	break;
1907    }
1908
1909    return 0;
1910}
1911
1912static int
1913pppursrv(q)
1914    queue_t *q;
1915{
1916    upperstr_t *us, *as;
1917    mblk_t *mp, *hdr;
1918#ifndef NO_DLPI
1919    dl_unitdata_ind_t *ud;
1920#endif
1921    int proto;
1922
1923    us = (upperstr_t *) q->q_ptr;
1924    if (us == 0) {
1925	DPRINT("pppursrv: q_ptr = 0!\n");
1926	return 0;
1927    }
1928
1929    if (us->flags & US_CONTROL) {
1930	/*
1931	 * A control stream.
1932	 * If there is no lower queue attached, run the write service
1933	 * routines of other upper streams attached to this PPA.
1934	 */
1935	if (us->lowerq == 0) {
1936	    as = us;
1937	    do {
1938		if (as->flags & US_BLOCKED)
1939		    qenable(WR(as->q));
1940		as = as->next;
1941	    } while (as != 0);
1942	}
1943
1944	/*
1945	 * Messages get queued on this stream's read queue if they
1946	 * can't be queued on the read queue of the attached stream
1947	 * that they are destined for.  This is for flow control -
1948	 * when this queue fills up, the lower read put procedure will
1949	 * queue messages there and the flow control will propagate
1950	 * down from there.
1951	 */
1952	while ((mp = getq(q)) != 0) {
1953	    proto = PPP_PROTOCOL(mp->b_rptr);
1954	    if (proto < 0x8000 && (as = find_dest(us, proto)) != 0) {
1955		if (!canput(as->q))
1956		    break;
1957		putq(as->q, mp);
1958	    } else {
1959		if (!canputnext(q))
1960		    break;
1961		putnext(q, mp);
1962	    }
1963	}
1964	if (mp) {
1965	    putbq(q, mp);
1966	} else {
1967	    /* can now put stuff directly on network protocol streams again */
1968	    for (as = us->next; as != 0; as = as->next)
1969		as->rblocked = 0;
1970	}
1971
1972	if (us->lowerq != 0)
1973	    qenable(RD(us->lowerq));
1974
1975    } else {
1976	/*
1977	 * A network protocol stream.  Put a DLPI header on each
1978	 * packet and send it on.
1979	 * (Actually, it seems that the IP module will happily
1980	 * accept M_DATA messages without the DL_UNITDATA_IND header.)
1981	 */
1982	while ((mp = getq(q)) != 0) {
1983	    if (!canputnext(q)) {
1984		putbq(q, mp);
1985		break;
1986	    }
1987#ifndef NO_DLPI
1988	    proto = PPP_PROTOCOL(mp->b_rptr);
1989	    mp->b_rptr += PPP_HDRLEN;
1990	    hdr = allocb(sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint),
1991			 BPRI_MED);
1992	    if (hdr == 0) {
1993		freemsg(mp);
1994		continue;
1995	    }
1996	    hdr->b_datap->db_type = M_PROTO;
1997	    ud = (dl_unitdata_ind_t *) hdr->b_wptr;
1998	    hdr->b_wptr += sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint);
1999	    hdr->b_cont = mp;
2000	    ud->dl_primitive = DL_UNITDATA_IND;
2001	    ud->dl_dest_addr_length = sizeof(uint);
2002	    ud->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t);
2003	    ud->dl_src_addr_length = sizeof(uint);
2004	    ud->dl_src_addr_offset = ud->dl_dest_addr_offset + sizeof(uint);
2005#if DL_CURRENT_VERSION >= 2
2006	    ud->dl_group_address = 0;
2007#endif
2008	    /* Send the DLPI client the data with the SAP they requested,
2009	       (e.g. ETHERTYPE_IP) rather than the PPP protocol number
2010	       (e.g. PPP_IP) */
2011	    ((uint *)(ud + 1))[0] = us->req_sap;	/* dest SAP */
2012	    ((uint *)(ud + 1))[1] = us->req_sap;	/* src SAP */
2013	    putnext(q, hdr);
2014#else /* NO_DLPI */
2015	    putnext(q, mp);
2016#endif /* NO_DLPI */
2017	}
2018	/*
2019	 * Now that we have consumed some packets from this queue,
2020	 * enable the control stream's read service routine so that we
2021	 * can process any packets for us that might have got queued
2022	 * there for flow control reasons.
2023	 */
2024	if (us->ppa)
2025	    qenable(us->ppa->q);
2026    }
2027
2028    return 0;
2029}
2030
2031static upperstr_t *
2032find_dest(ppa, proto)
2033    upperstr_t *ppa;
2034    int proto;
2035{
2036    upperstr_t *us;
2037
2038    for (us = ppa->next; us != 0; us = us->next)
2039	if (proto == us->sap)
2040	    break;
2041    return us;
2042}
2043
2044#if defined(SOL2)
2045/*
2046 * Test upstream promiscuous conditions. As of now, only pass IPv4 and
2047 * Ipv6 packets upstream (let PPP packets be decoded elsewhere).
2048 */
2049static upperstr_t *
2050find_promisc(us, proto)
2051    upperstr_t *us;
2052    int proto;
2053{
2054
2055    if ((proto != PPP_IP) && (proto != PPP_IPV6))
2056	return (upperstr_t *)0;
2057
2058    for ( ; us; us = us->next) {
2059	if ((us->flags & US_PROMISC) && (us->state == DL_IDLE))
2060	    return us;
2061    }
2062
2063    return (upperstr_t *)0;
2064}
2065
2066/*
2067 * Prepend an empty Ethernet header to msg for snoop, et al.
2068 */
2069static mblk_t *
2070prepend_ether(us, mp, proto)
2071    upperstr_t *us;
2072    mblk_t *mp;
2073    int proto;
2074{
2075    mblk_t *eh;
2076    int type;
2077
2078    if ((eh = allocb(sizeof(struct ether_header), BPRI_HI)) == 0) {
2079	freemsg(mp);
2080	return (mblk_t *)0;
2081    }
2082
2083    if (proto == PPP_IP)
2084	type = ETHERTYPE_IP;
2085    else if (proto == PPP_IPV6)
2086	type = ETHERTYPE_IPV6;
2087    else
2088	type = proto;	    /* What else? Let decoder decide */
2089
2090    eh->b_wptr += sizeof(struct ether_header);
2091    bzero((caddr_t)eh->b_rptr, sizeof(struct ether_header));
2092    ((struct ether_header *)eh->b_rptr)->ether_type = htons((short)type);
2093    eh->b_cont = mp;
2094    return (eh);
2095}
2096
2097/*
2098 * Prepend DL_UNITDATA_IND mblk to msg
2099 */
2100static mblk_t *
2101prepend_udind(us, mp, proto)
2102    upperstr_t *us;
2103    mblk_t *mp;
2104    int proto;
2105{
2106    dl_unitdata_ind_t *dlu;
2107    mblk_t *dh;
2108    size_t size;
2109
2110    size = sizeof(dl_unitdata_ind_t);
2111    if ((dh = allocb(size, BPRI_MED)) == 0) {
2112	freemsg(mp);
2113	return (mblk_t *)0;
2114    }
2115
2116    dh->b_datap->db_type = M_PROTO;
2117    dh->b_wptr = dh->b_datap->db_lim;
2118    dh->b_rptr = dh->b_wptr - size;
2119
2120    dlu = (dl_unitdata_ind_t *)dh->b_rptr;
2121    dlu->dl_primitive = DL_UNITDATA_IND;
2122    dlu->dl_dest_addr_length = 0;
2123    dlu->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t);
2124    dlu->dl_src_addr_length = 0;
2125    dlu->dl_src_addr_offset = sizeof(dl_unitdata_ind_t);
2126    dlu->dl_group_address = 0;
2127
2128    dh->b_cont = mp;
2129    return (dh);
2130}
2131
2132/*
2133 * For any recognized promiscuous streams, send data upstream
2134 */
2135static void
2136promisc_sendup(ppa, mp, proto, skip)
2137    upperstr_t *ppa;
2138    mblk_t *mp;
2139    int proto, skip;
2140{
2141    mblk_t *dup_mp, *dup_dup_mp;
2142    upperstr_t *prus, *nprus;
2143
2144    if ((prus = find_promisc(ppa, proto)) != 0) {
2145	if (dup_mp = dupmsg(mp)) {
2146
2147	    if (skip)
2148		dup_mp->b_rptr += PPP_HDRLEN;
2149
2150	    for ( ; nprus = find_promisc(prus->next, proto);
2151		    prus = nprus) {
2152
2153		if (dup_dup_mp = dupmsg(dup_mp)) {
2154		    if (canputnext(prus->q)) {
2155			if (prus->flags & US_RAWDATA) {
2156			    dup_dup_mp = prepend_ether(prus, dup_dup_mp, proto);
2157			    putnext(prus->q, dup_dup_mp);
2158			} else {
2159			    dup_dup_mp = prepend_udind(prus, dup_dup_mp, proto);
2160			    putnext(prus->q, dup_dup_mp);
2161			}
2162		    } else {
2163			DPRINT("ppp_urput: data to promisc q dropped\n");
2164			freemsg(dup_dup_mp);
2165		    }
2166		}
2167	    }
2168
2169	    if (canputnext(prus->q)) {
2170		if (prus->flags & US_RAWDATA) {
2171		    dup_mp = prepend_ether(prus, dup_mp, proto);
2172		    putnext(prus->q, dup_mp);
2173		} else {
2174		    dup_mp = prepend_udind(prus, dup_mp, proto);
2175		    putnext(prus->q, dup_mp);
2176		}
2177	    } else {
2178		DPRINT("ppp_urput: data to promisc q dropped\n");
2179		freemsg(dup_mp);
2180	    }
2181	}
2182    }
2183}
2184#endif /* defined(SOL2) */
2185
2186/*
2187 * We simply put the message on to the associated upper control stream
2188 * (either here or in ppplrsrv).  That way we enter the perimeters
2189 * before looking through the list of attached streams to decide which
2190 * stream it should go up.
2191 */
2192static int
2193ppplrput(q, mp)
2194    queue_t *q;
2195    mblk_t *mp;
2196{
2197    queue_t *uq;
2198    struct iocblk *iop;
2199
2200    switch (mp->b_datap->db_type) {
2201    case M_IOCTL:
2202	iop = (struct iocblk *) mp->b_rptr;
2203	iop->ioc_error = EINVAL;
2204	mp->b_datap->db_type = M_IOCNAK;
2205	qreply(q, mp);
2206	return 0;
2207    case M_FLUSH:
2208	if (*mp->b_rptr & FLUSHR)
2209	    flushq(q, FLUSHDATA);
2210	if (*mp->b_rptr & FLUSHW) {
2211	    *mp->b_rptr &= ~FLUSHR;
2212	    qreply(q, mp);
2213	} else
2214	    freemsg(mp);
2215	return 0;
2216    }
2217
2218    /*
2219     * If we can't get the lower lock straight away, queue this one
2220     * rather than blocking, to avoid the possibility of deadlock.
2221     */
2222    if (!TRYLOCK_LOWER_R) {
2223	putq(q, mp);
2224	return 0;
2225    }
2226
2227    /*
2228     * Check that we're still connected to the driver.
2229     */
2230    uq = (queue_t *) q->q_ptr;
2231    if (uq == 0) {
2232	UNLOCK_LOWER;
2233	DPRINT1("ppplrput: q = %x, uq = 0??\n", q);
2234	freemsg(mp);
2235	return 0;
2236    }
2237
2238    /*
2239     * Try to forward the message to the put routine for the upper
2240     * control stream for this lower stream.
2241     * If there are already messages queued here, queue this one so
2242     * they don't get out of order.
2243     */
2244    if (queclass(mp) == QPCTL || (qsize(q) == 0 && canput(uq)))
2245	put(uq, mp);
2246    else
2247	putq(q, mp);
2248
2249    UNLOCK_LOWER;
2250    return 0;
2251}
2252
2253static int
2254ppplrsrv(q)
2255    queue_t *q;
2256{
2257    mblk_t *mp;
2258    queue_t *uq;
2259
2260    /*
2261     * Packets get queued here for flow control reasons
2262     * or if the lrput routine couldn't get the lower lock
2263     * without blocking.
2264     */
2265    LOCK_LOWER_R;
2266    uq = (queue_t *) q->q_ptr;
2267    if (uq == 0) {
2268	UNLOCK_LOWER;
2269	flushq(q, FLUSHALL);
2270	DPRINT1("ppplrsrv: q = %x, uq = 0??\n", q);
2271	return 0;
2272    }
2273    while ((mp = getq(q)) != 0) {
2274	if (queclass(mp) == QPCTL || canput(uq))
2275	    put(uq, mp);
2276	else {
2277	    putbq(q, mp);
2278	    break;
2279	}
2280    }
2281    UNLOCK_LOWER;
2282    return 0;
2283}
2284
2285static int
2286putctl2(q, type, code, val)
2287    queue_t *q;
2288    int type, code, val;
2289{
2290    mblk_t *mp;
2291
2292    mp = allocb(2, BPRI_HI);
2293    if (mp == 0)
2294	return 0;
2295    mp->b_datap->db_type = type;
2296    mp->b_wptr[0] = code;
2297    mp->b_wptr[1] = val;
2298    mp->b_wptr += 2;
2299    putnext(q, mp);
2300    return 1;
2301}
2302
2303static int
2304putctl4(q, type, code, val)
2305    queue_t *q;
2306    int type, code, val;
2307{
2308    mblk_t *mp;
2309
2310    mp = allocb(4, BPRI_HI);
2311    if (mp == 0)
2312	return 0;
2313    mp->b_datap->db_type = type;
2314    mp->b_wptr[0] = code;
2315    ((short *)mp->b_wptr)[1] = val;
2316    mp->b_wptr += 4;
2317    putnext(q, mp);
2318    return 1;
2319}
2320
2321static void
2322debug_dump(q, mp)
2323    queue_t *q;
2324    mblk_t *mp;
2325{
2326    upperstr_t *us;
2327    queue_t *uq, *lq;
2328
2329    DPRINT("ppp upper streams:\n");
2330    for (us = minor_devs; us != 0; us = us->nextmn) {
2331	uq = us->q;
2332	DPRINT3(" %d: q=%x rlev=%d",
2333		us->mn, uq, (uq? qsize(uq): 0));
2334	DPRINT3(" wlev=%d flags=0x%b", (uq? qsize(WR(uq)): 0),
2335		us->flags, "\020\1priv\2control\3blocked\4last");
2336	DPRINT3(" state=%x sap=%x req_sap=%x", us->state, us->sap,
2337		us->req_sap);
2338	if (us->ppa == 0)
2339	    DPRINT(" ppa=?\n");
2340	else
2341	    DPRINT1(" ppa=%d\n", us->ppa->ppa_id);
2342	if (us->flags & US_CONTROL) {
2343	    lq = us->lowerq;
2344	    DPRINT3("    control for %d lq=%x rlev=%d",
2345		    us->ppa_id, lq, (lq? qsize(RD(lq)): 0));
2346	    DPRINT3(" wlev=%d mru=%d mtu=%d\n",
2347		    (lq? qsize(lq): 0), us->mru, us->mtu);
2348	}
2349    }
2350    mp->b_datap->db_type = M_IOCACK;
2351    qreply(q, mp);
2352}
2353
2354#ifdef FILTER_PACKETS
2355#include <netinet/in_systm.h>
2356#include <netinet/ip.h>
2357#include <netinet/udp.h>
2358#include <netinet/tcp.h>
2359
2360#define MAX_IPHDR    128     /* max TCP/IP header size */
2361
2362
2363/* The following table contains a hard-coded list of protocol/port pairs.
2364 * Any matching packets are either discarded unconditionally, or,
2365 * if ok_if_link_up is non-zero when a connection does not currently exist
2366 * (i.e., they go through if the connection is present, but never initiate
2367 * a dial-out).
2368 * This idea came from a post by dm@garage.uun.org (David Mazieres)
2369 */
2370static struct pktfilt_tab {
2371	int proto;
2372	u_short port;
2373	u_short ok_if_link_up;
2374} pktfilt_tab[] = {
2375	{ IPPROTO_UDP,	520,	1 },	/* RIP, ok to pass if link is up */
2376	{ IPPROTO_UDP,	123,	1 },	/* NTP, don't keep up the link for it */
2377	{ -1, 		0,	0 }	/* terminator entry has port == -1 */
2378};
2379
2380
2381static int
2382ip_hard_filter(us, mp, outbound)
2383    upperstr_t *us;
2384    mblk_t *mp;
2385    int outbound;
2386{
2387    struct ip *ip;
2388    struct pktfilt_tab *pft;
2389    mblk_t *temp_mp;
2390    int proto;
2391    int len, hlen;
2392
2393
2394    /* Note, the PPP header has already been pulled up in all cases */
2395    proto = PPP_PROTOCOL(mp->b_rptr);
2396    if (us->flags & US_DBGLOG)
2397        DPRINT3("ppp/%d: filter, proto=0x%x, out=%d\n", us->mn, proto, outbound);
2398
2399    switch (proto)
2400    {
2401    case PPP_IP:
2402	if ((mp->b_wptr - mp->b_rptr) == PPP_HDRLEN && mp->b_cont != 0) {
2403	    temp_mp = mp->b_cont;
2404    	    len = msgdsize(temp_mp);
2405	    hlen = (len < MAX_IPHDR) ? len : MAX_IPHDR;
2406	    PULLUP(temp_mp, hlen);
2407	    if (temp_mp == 0) {
2408		DPRINT2("ppp/%d: filter, pullup next failed, len=%d\n",
2409			us->mn, hlen);
2410		mp->b_cont = 0;		/* PULLUP() freed the rest */
2411	        freemsg(mp);
2412	        return 0;
2413	    }
2414	    ip = (struct ip *)mp->b_cont->b_rptr;
2415	}
2416	else {
2417	    len = msgdsize(mp);
2418	    hlen = (len < (PPP_HDRLEN+MAX_IPHDR)) ? len : (PPP_HDRLEN+MAX_IPHDR);
2419	    PULLUP(mp, hlen);
2420	    if (mp == 0) {
2421		DPRINT2("ppp/%d: filter, pullup failed, len=%d\n",
2422			us->mn, hlen);
2423	        return 0;
2424	    }
2425	    ip = (struct ip *)(mp->b_rptr + PPP_HDRLEN);
2426	}
2427
2428	/* For IP traffic, certain packets (e.g., RIP) may be either
2429	 *   1.  ignored - dropped completely
2430	 *   2.  will not initiate a connection, but
2431	 *       will be passed if a connection is currently up.
2432	 */
2433	for (pft=pktfilt_tab; pft->proto != -1; pft++) {
2434	    if (ip->ip_p == pft->proto) {
2435		switch(pft->proto) {
2436		case IPPROTO_UDP:
2437		    if (((struct udphdr *) &((int *)ip)[ip->ip_hl])->uh_dport
2438				== htons(pft->port)) goto endfor;
2439		    break;
2440		case IPPROTO_TCP:
2441		    if (((struct tcphdr *) &((int *)ip)[ip->ip_hl])->th_dport
2442				== htons(pft->port)) goto endfor;
2443		    break;
2444		}
2445	    }
2446	}
2447	endfor:
2448	if (pft->proto != -1) {
2449	    if (us->flags & US_DBGLOG)
2450		DPRINT3("ppp/%d: found IP pkt, proto=0x%x (%d)\n",
2451				us->mn, pft->proto, pft->port);
2452	    /* Discard if not connected, or if not pass_with_link_up */
2453	    /* else, if link is up let go by, but don't update time */
2454	    return pft->ok_if_link_up? -1: 0;
2455	}
2456        break;
2457    } /* end switch (proto) */
2458
2459    return 1;
2460}
2461#endif /* FILTER_PACKETS */
2462
2463