diff options
author | Mystery Man <unknown@mandriva.org> | 2002-07-31 23:10:55 +0000 |
---|---|---|
committer | Mystery Man <unknown@mandriva.org> | 2002-07-31 23:10:55 +0000 |
commit | 6b5bb447b11a31fc0961c20485505a633c9ab4eb (patch) | |
tree | eae73bee290e1e328b539f7649818d7584ee667e /mdk-stage1/ppp/solaris | |
parent | 79d226c48d6de4f26c604ddbd0ce769a58d548c6 (diff) | |
download | drakx-6b5bb447b11a31fc0961c20485505a633c9ab4eb.tar drakx-6b5bb447b11a31fc0961c20485505a633c9ab4eb.tar.gz drakx-6b5bb447b11a31fc0961c20485505a633c9ab4eb.tar.bz2 drakx-6b5bb447b11a31fc0961c20485505a633c9ab4eb.tar.xz drakx-6b5bb447b11a31fc0961c20485505a633c9ab4eb.zip |
This commit was manufactured by cvs2svn to create tag 'V1_1_8_16mdk'.V1_1_8_16mdk
Diffstat (limited to 'mdk-stage1/ppp/solaris')
-rw-r--r-- | mdk-stage1/ppp/solaris/Makedefs | 16 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/Makedefs.sol2 | 59 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/Makefile.sol2 | 66 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/Makefile.sol2-64 | 85 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/Makefile.top | 50 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp.c | 2486 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp.conf | 1 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp_ahdlc.c | 878 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp_ahdlc_mod.c | 49 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp_comp.c | 1126 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp_comp_mod.c | 81 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp_mod.c | 174 | ||||
-rw-r--r-- | mdk-stage1/ppp/solaris/ppp_mod.h | 190 |
13 files changed, 0 insertions, 5261 deletions
diff --git a/mdk-stage1/ppp/solaris/Makedefs b/mdk-stage1/ppp/solaris/Makedefs deleted file mode 100644 index 81db8ab2e..000000000 --- a/mdk-stage1/ppp/solaris/Makedefs +++ /dev/null @@ -1,16 +0,0 @@ -# -# defines common to several Makefiles -# - -INSTALL= /usr/sbin/install - -BINDIR = /usr/local/bin -MANDIR = /usr/local/man -ETCDIR = /etc/ppp - -COPTS = -O -Xa - -# For compiling with gcc, comment out the COPTS definition above and -# uncomment the next 2 definitions. -#CC = gcc -#COPTS = -O2 diff --git a/mdk-stage1/ppp/solaris/Makedefs.sol2 b/mdk-stage1/ppp/solaris/Makedefs.sol2 deleted file mode 100644 index 1282c6e74..000000000 --- a/mdk-stage1/ppp/solaris/Makedefs.sol2 +++ /dev/null @@ -1,59 +0,0 @@ -# -# Generic make definitions for Solaris 2 -# -# $Id$ -# - -include ../solaris/Makedefs - -CPPFLAGS = -D_KERNEL -DSVR4 -DSOL2 -DPRIOQ -DDEBUG -I../include -CFLAGS = $(CPPFLAGS) $(COPTS) - -# lint-specific variables -LINT = lint -LINT_OPT_32 = -LINT_OPT_64 = -Xarch=v9 -errchk=longptr64 - -LINT_32 = -LINT_32 += -erroff=E_BAD_PTR_CAST_ALIGN -LINT_32 += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED -LINT_32 += -erroff=E_SUSPICIOUS_COMPARISON -LINT_32 += -erroff=E_CAST_UINT_TO_SIGNED_INT -LINT_32 += -erroff=E_PASS_UINT_TO_SIGNED_INT -LINT_32 += -erroff=E_INVALID_ANNOTATION_NAME -LINT_32 += -erroff=E_FUNC_ARG_UNUSED -# This might be needed, but zlib.c and vjcompress.c will squawk -# when not ignored -LINT_32 += -erroff=E_CASE_FALLTHRU -LINT_32 += -erroff=E_RET_INT_IMPLICITLY -LINT_32 += -erroff=E_FUNC_NO_RET_VAL -# Some STREAMS macros will be noisy too when this isn't ignored -LINT_32 += -erroff=E_CONSTANT_CONDITION -LINT_32 += -erroff=E_CONST_EXPR - -# Extra noise suppressant for 64-bit -EXTRA_OFF = -EXTRA_OFF += -erroff=E_CAST_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_CAST_INT_CONST_TO_SMALL_INT -EXTRA_OFF += -erroff=E_CAST_TO_PTR_FROM_INT -EXTRA_OFF += -erroff=E_ASSIGN_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_ASSIGN_INT_FROM_BIG_CONST -EXTRA_OFF += -erroff=E_CONST_PROMOTED_UNSIGNED_LL -EXTRA_OFF += -erroff=E_CONST_PROMOTED_LONG_LONG -EXTRA_OFF += -erroff=E_CONST_TRUNCATED_BY_ASSIGN -EXTRA_OFF += -erroff=E_PASS_INT_FROM_BIG_CONST -EXTRA_OFF += -erroff=E_COMP_INT_WITH_LARGE_INT -EXTRA_OFF += -erroff=E_ASSIGN_UINT_TO_SIGNED_INT -EXTRA_OFF += -erroff=E_ASSIGN_NARROW_CONV -EXTRA_OFF += -erroff=E_PASS_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_PTR_CONV_LOSES_BITS - -LINT_64 = $(LINT_32) -LINT_64 += $(EXTRA_OFF) - -LINTFLAGS64 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_64) $(LINT_64) -LINT64 = $(LINT) -c $(LINTFLAGS64) $(CPPFLAGS) - -LINTFLAGS32 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_32) $(LINT_32) -LINT32 = $(LINT) -c $(LINTFLAGS32) $(CPPFLAGS) - diff --git a/mdk-stage1/ppp/solaris/Makefile.sol2 b/mdk-stage1/ppp/solaris/Makefile.sol2 deleted file mode 100644 index 78628847b..000000000 --- a/mdk-stage1/ppp/solaris/Makefile.sol2 +++ /dev/null @@ -1,66 +0,0 @@ -# -# Makefile for STREAMS modules for Solaris 2. -# -# $Id$ -# - -include Makedefs.sol2 - -COPTS += -xO2 -xspace -W0,-Lt - -COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \ - ppp_comp_mod.o - -all: ppp ppp_ahdl ppp_comp - -ppp: ppp.o ppp_mod.o - ld -r -o $@ ppp.o ppp_mod.o - chmod +x $@ - -ppp_ahdl: ppp_ahdlc.o ppp_ahdlc_mod.o - ld -r -o $@ ppp_ahdlc.o ppp_ahdlc_mod.o - chmod +x $@ - -ppp_comp: $(COMP_OBJS) - ld -r -o $@ $(COMP_OBJS) - chmod +x $@ - -bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -ppp.o: ppp.c - $(CC) $(CFLAGS) -c $? -ppp_mod.o: ppp_mod.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc_mod.o: ppp_ahdlc_mod.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc.o: ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -ppp_comp.o: ppp_comp.c - $(CC) $(CFLAGS) -c $? -ppp_comp_mod.o: ppp_comp_mod.c - $(CC) $(CFLAGS) -c $? -vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? - -install: - cp ppp ppp.conf /kernel/drv - cp ppp_comp ppp_ahdl /kernel/strmod - if grep clone:ppp /etc/minor_perm; then :; else \ - echo clone:ppp 0644 root sys >>/etc/minor_perm; fi - /usr/sbin/rem_drv ppp 2>/dev/null || true - /usr/sbin/add_drv ppp - -SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ - ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ - ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c - -lint: - $(LINT32) $(SRCS) - -clean: - rm -f ppp ppp_comp ppp_ahdl *.o *~ core - rm -f *.ln diff --git a/mdk-stage1/ppp/solaris/Makefile.sol2-64 b/mdk-stage1/ppp/solaris/Makefile.sol2-64 deleted file mode 100644 index 63e75fc54..000000000 --- a/mdk-stage1/ppp/solaris/Makefile.sol2-64 +++ /dev/null @@ -1,85 +0,0 @@ -# -# Makefile for 64-bit STREAMS modules for Solaris 2. -# -# $Id$ -# - -include Makedefs.sol2 - -# Sun's cc flag for LP64 compilation / linkage -COPTS += -xchip=ultra -xarch=v9 -Wc,-xcode=abs32 -Wc,-Qiselect-regsym=0 -xO3 -xspace -W0,-Lt - -# subdirectory where 64-bit objects / binaries will be placed -LP64DIR = sparcv9 - -# Name of legacy Makefile (for 32-bit binaries) -STD_MAKE = Makefile.sol2 - -COMP_OBJS = $(LP64DIR)/ppp_comp.o $(LP64DIR)/bsd-comp.o \ - $(LP64DIR)/deflate.o $(LP64DIR)/zlib.o $(LP64DIR)/vjcompress.o \ - $(LP64DIR)/ppp_comp_mod.o - -all: std_objs $(LP64DIR) ppp ppp_ahdl ppp_comp - -std_objs: - $(MAKE) -f $(STD_MAKE) all - -ppp: $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o - ld -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o - chmod +x $(LP64DIR)/$@ - -ppp_ahdl: $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o - ld -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o - chmod +x $(LP64DIR)/$@ - -ppp_comp: $(COMP_OBJS) - ld -r -o $(LP64DIR)/$@ $(COMP_OBJS) - chmod +x $(LP64DIR)/$@ - -$(LP64DIR)/bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp.o: ppp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_mod.o: ppp_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_ahdlc_mod.o: ppp_ahdlc_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_ahdlc.o: ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_comp.o: ppp_comp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_comp_mod.o: ppp_comp_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? -o $@ - -$(LP64DIR): - mkdir -m 755 -p $@ - -install: - cp ppp ppp.conf /kernel/drv - cp ppp_comp ppp_ahdl /kernel/strmod - cp $(LP64DIR)/ppp /kernel/drv/$(LP64DIR) - cp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl /kernel/strmod/$(LP64DIR) - if grep clone:ppp /etc/minor_perm; then :; else \ - echo clone:ppp 0644 root sys >>/etc/minor_perm; fi - /usr/sbin/rem_drv ppp 2>/dev/null || true - /usr/sbin/add_drv ppp - -SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ - ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ - ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c - -lint: - $(LINT64) $(SRCS) - -lint-32: - $(LINT32) $(SRCS) - -clean: - $(MAKE) -f $(STD_MAKE) clean - rm -f $(LP64DIR)/ppp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl $(LP64DIR)/*.o $(LP64DIR)/*~ $(LP64DIR)/core diff --git a/mdk-stage1/ppp/solaris/Makefile.top b/mdk-stage1/ppp/solaris/Makefile.top deleted file mode 100644 index f1200b852..000000000 --- a/mdk-stage1/ppp/solaris/Makefile.top +++ /dev/null @@ -1,50 +0,0 @@ -# -# ppp top level makefile for SVR4 and Solaris 2 -# -# $Id$ -# - -include solaris/Makedefs - -all: - cd chat; $(MAKE) all - cd pppd; $(MAKE) all - cd pppstats; $(MAKE) all - cd pppdump; $(MAKE) all - cd solaris; $(MAKE) all - -install: $(BINDIR) $(MANDIR)/man8 install-progs install-etcppp - -install-progs: - cd chat; $(MAKE) install - cd pppd; $(MAKE) install - cd pppstats; $(MAKE) install - cd pppdump; $(MAKE) install - cd solaris; $(MAKE) install - -install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ - $(ETCDIR)/chap-secrets - -$(ETCDIR)/options: - cp etc.ppp/options $@ - chmod go-w $@ -$(ETCDIR)/pap-secrets: - $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/pap-secrets -$(ETCDIR)/chap-secrets: - $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/chap-secrets - -$(BINDIR): - mkdir -m 755 -p $@ -$(MANDIR)/man8: - mkdir -m 755 -p $@ -$(ETCDIR): - mkdir -m 755 -p $@ - -clean: - rm -f *~ - cd chat; $(MAKE) clean - cd pppd; $(MAKE) clean - cd pppstats; $(MAKE) clean - cd pppdump; $(MAKE) clean - cd solaris; $(MAKE) clean - diff --git a/mdk-stage1/ppp/solaris/ppp.c b/mdk-stage1/ppp/solaris/ppp.c deleted file mode 100644 index 44bf08dff..000000000 --- a/mdk-stage1/ppp/solaris/ppp.c +++ /dev/null @@ -1,2486 +0,0 @@ -/* - * ppp.c - STREAMS multiplexing pseudo-device driver for PPP. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS 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$ - */ - -/* - * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/stream.h> -#include <sys/stropts.h> -#include <sys/errno.h> -#ifdef __osf__ -#include <sys/ioctl.h> -#include <sys/cmn_err.h> -#define queclass(mp) ((mp)->b_band & QPCTL) -#else -#include <sys/ioccom.h> -#endif -#include <sys/time.h> -#ifdef SVR4 -#include <sys/cmn_err.h> -#include <sys/conf.h> -#include <sys/dlpi.h> -#include <sys/ddi.h> -#ifdef SOL2 -#include <sys/ksynch.h> -#include <sys/kstat.h> -#include <sys/sunddi.h> -#include <sys/ethernet.h> -#else -#include <sys/socket.h> -#include <sys/sockio.h> -#include <net/if.h> -#include <netinet/in.h> -#endif /* SOL2 */ -#else /* not SVR4 */ -#include <sys/user.h> -#endif /* SVR4 */ -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -/* - * Modifications marked with #ifdef PRIOQ are for priority queueing of - * interactive traffic, and are due to Marko Zec <zec@japa.tel.fer.hr>. - */ -#ifdef PRIOQ -#endif /* PRIOQ */ - -#include <netinet/in.h> /* leave this outside of PRIOQ for htons */ - -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -/* - * The IP module may use this SAP value for IP packets. - */ -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x800 -#endif - -#if !defined(ETHERTYPE_IPV6) -#define ETHERTYPE_IPV6 0x86dd -#endif /* !defined(ETHERTYPE_IPV6) */ - -#if !defined(ETHERTYPE_ALLSAP) && defined(SOL2) -#define ETHERTYPE_ALLSAP 0 -#endif /* !defined(ETHERTYPE_ALLSAP) && defined(SOL2) */ - -#if !defined(PPP_ALLSAP) && defined(SOL2) -#define PPP_ALLSAP PPP_ALLSTATIONS -#endif /* !defined(PPP_ALLSAP) && defined(SOL2) */ - -extern time_t time; - -#ifdef SOL2 -/* - * We use this reader-writer lock to ensure that the lower streams - * stay connected to the upper streams while the lower-side put and - * service procedures are running. Essentially it is an existence - * lock for the upper stream associated with each lower stream. - */ -krwlock_t ppp_lower_lock; -#define LOCK_LOWER_W rw_enter(&ppp_lower_lock, RW_WRITER) -#define LOCK_LOWER_R rw_enter(&ppp_lower_lock, RW_READER) -#define TRYLOCK_LOWER_R rw_tryenter(&ppp_lower_lock, RW_READER) -#define UNLOCK_LOWER rw_exit(&ppp_lower_lock) - -#define MT_ENTER(x) mutex_enter(x) -#define MT_EXIT(x) mutex_exit(x) - -/* - * Notes on multithreaded implementation for Solaris 2: - * - * We use an inner perimeter around each queue pair and an outer - * perimeter around the whole driver. The inner perimeter is - * entered exclusively for all entry points (open, close, put, - * service). The outer perimeter is entered exclusively for open - * and close and shared for put and service. This is all done for - * us by the streams framework. - * - * I used to think that the perimeters were entered for the lower - * streams' put and service routines as well as for the upper streams'. - * Because of problems experienced by people, and after reading the - * documentation more closely, I now don't think that is true. So we - * now use ppp_lower_lock to give us an existence guarantee on the - * upper stream controlling each lower stream. - * - * Shared entry to the outer perimeter protects the existence of all - * the upper streams and their upperstr_t structures, and guarantees - * that the following fields of any upperstr_t won't change: - * nextmn, next, nextppa. It guarantees that the lowerq field of an - * upperstr_t won't go from non-zero to zero, that the global `ppas' - * won't change and that the no lower stream will get unlinked. - * - * Shared (reader) access to ppa_lower_lock guarantees that no lower - * stream will be unlinked and that the lowerq field of all upperstr_t - * structures won't change. - */ - -#else /* SOL2 */ -#define LOCK_LOWER_W 0 -#define LOCK_LOWER_R 0 -#define TRYLOCK_LOWER_R 1 -#define UNLOCK_LOWER 0 -#define MT_ENTER(x) 0 -#define MT_EXIT(x) 0 - -#endif /* SOL2 */ - -/* - * Private information; one per upper stream. - */ -typedef struct upperstr { - minor_t mn; /* minor device number */ - struct upperstr *nextmn; /* next minor device */ - queue_t *q; /* read q associated with this upper stream */ - int flags; /* flag bits, see below */ - int state; /* current DLPI state */ - int sap; /* service access point */ - int req_sap; /* which SAP the DLPI client requested */ - struct upperstr *ppa; /* control stream for our ppa */ - struct upperstr *next; /* next stream for this ppa */ - uint ioc_id; /* last ioctl ID for this stream */ - enum NPmode npmode; /* what to do with packets on this SAP */ - unsigned char rblocked; /* flow control has blocked upper read strm */ - /* N.B. rblocked is only changed by control stream's put/srv procs */ - /* - * There is exactly one control stream for each PPA. - * The following fields are only used for control streams. - */ - int ppa_id; - queue_t *lowerq; /* write queue attached below this PPA */ - struct upperstr *nextppa; /* next control stream */ - int mru; - int mtu; - struct pppstat stats; /* statistics */ - time_t last_sent; /* time last NP packet sent */ - time_t last_recv; /* time last NP packet rcvd */ -#ifdef SOL2 - kmutex_t stats_lock; /* lock for stats updates */ - kstat_t *kstats; /* stats for netstat */ -#endif /* SOL2 */ -#ifdef LACHTCP - int ifflags; - char ifname[IFNAMSIZ]; - struct ifstats ifstats; -#endif /* LACHTCP */ -} upperstr_t; - -/* Values for flags */ -#define US_PRIV 1 /* stream was opened by superuser */ -#define US_CONTROL 2 /* stream is a control stream */ -#define US_BLOCKED 4 /* flow ctrl has blocked lower write stream */ -#define US_LASTMOD 8 /* no PPP modules below us */ -#define US_DBGLOG 0x10 /* log various occurrences */ -#define US_RBLOCKED 0x20 /* flow ctrl has blocked upper read stream */ - -#if defined(SOL2) -#if DL_CURRENT_VERSION >= 2 -#define US_PROMISC 0x40 /* stream is promiscuous */ -#endif /* DL_CURRENT_VERSION >= 2 */ -#define US_RAWDATA 0x80 /* raw M_DATA, no DLPI header */ -#endif /* defined(SOL2) */ - -#ifdef PRIOQ -static u_char max_band=0; -static u_char def_band=0; - -#define IPPORT_DEFAULT 65535 - -/* - * Port priority table - * Highest priority ports are listed first, lowest are listed last. - * ICMP & packets using unlisted ports will be treated as "default". - * If IPPORT_DEFAULT is not listed here, "default" packets will be - * assigned lowest priority. - * Each line should be terminated with "0". - * Line containing only "0" marks the end of the list. - */ - -static u_short prioq_table[]= { - 113, 53, 0, - 22, 23, 513, 517, 518, 0, - 514, 21, 79, 111, 0, - 25, 109, 110, 0, - IPPORT_DEFAULT, 0, - 20, 70, 80, 8001, 8008, 8080, 0, /* 8001,8008,8080 - common proxy ports */ -0 }; - -#endif /* PRIOQ */ - - -static upperstr_t *minor_devs = NULL; -static upperstr_t *ppas = NULL; - -#ifdef SVR4 -static int pppopen __P((queue_t *, dev_t *, int, int, cred_t *)); -static int pppclose __P((queue_t *, int, cred_t *)); -#else -static int pppopen __P((queue_t *, int, int, int)); -static int pppclose __P((queue_t *, int)); -#endif /* SVR4 */ -static int pppurput __P((queue_t *, mblk_t *)); -static int pppuwput __P((queue_t *, mblk_t *)); -static int pppursrv __P((queue_t *)); -static int pppuwsrv __P((queue_t *)); -static int ppplrput __P((queue_t *, mblk_t *)); -static int ppplwput __P((queue_t *, mblk_t *)); -static int ppplrsrv __P((queue_t *)); -static int ppplwsrv __P((queue_t *)); -#ifndef NO_DLPI -static void dlpi_request __P((queue_t *, mblk_t *, upperstr_t *)); -static void dlpi_error __P((queue_t *, upperstr_t *, int, int, int)); -static void dlpi_ok __P((queue_t *, int)); -#endif -static int send_data __P((mblk_t *, upperstr_t *)); -static void new_ppa __P((queue_t *, mblk_t *)); -static void attach_ppa __P((queue_t *, mblk_t *)); -static void detach_ppa __P((queue_t *, mblk_t *)); -static void detach_lower __P((queue_t *, mblk_t *)); -static void debug_dump __P((queue_t *, mblk_t *)); -static upperstr_t *find_dest __P((upperstr_t *, int)); -#if defined(SOL2) -static upperstr_t *find_promisc __P((upperstr_t *, int)); -static mblk_t *prepend_ether __P((upperstr_t *, mblk_t *, int)); -static mblk_t *prepend_udind __P((upperstr_t *, mblk_t *, int)); -static void promisc_sendup __P((upperstr_t *, mblk_t *, int, int)); -#endif /* defined(SOL2) */ -static int putctl2 __P((queue_t *, int, int, int)); -static int putctl4 __P((queue_t *, int, int, int)); -static int pass_packet __P((upperstr_t *ppa, mblk_t *mp, int outbound)); -#ifdef FILTER_PACKETS -static int ip_hard_filter __P((upperstr_t *ppa, mblk_t *mp, int outbound)); -#endif /* FILTER_PACKETS */ - -#define PPP_ID 0xb1a6 -static struct module_info ppp_info = { -#ifdef PRIOQ - PPP_ID, "ppp", 0, 512, 512, 384 -#else - PPP_ID, "ppp", 0, 512, 512, 128 -#endif /* PRIOQ */ -}; - -static struct qinit pppurint = { - pppurput, pppursrv, pppopen, pppclose, NULL, &ppp_info, NULL -}; - -static struct qinit pppuwint = { - pppuwput, pppuwsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -static struct qinit ppplrint = { - ppplrput, ppplrsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -static struct qinit ppplwint = { - ppplwput, ppplwsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -#ifdef LACHTCP -extern struct ifstats *ifstats; -int pppdevflag = 0; -#endif - -struct streamtab pppinfo = { - &pppurint, &pppuwint, - &ppplrint, &ppplwint -}; - -int ppp_count; - -/* - * How we maintain statistics. - */ -#ifdef SOL2 -#define INCR_IPACKETS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[0].value.ul++; \ - } -#define INCR_IERRORS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[1].value.ul++; \ - } -#define INCR_OPACKETS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[2].value.ul++; \ - } -#define INCR_OERRORS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[3].value.ul++; \ - } -#endif - -#ifdef LACHTCP -#define INCR_IPACKETS(ppa) ppa->ifstats.ifs_ipackets++; -#define INCR_IERRORS(ppa) ppa->ifstats.ifs_ierrors++; -#define INCR_OPACKETS(ppa) ppa->ifstats.ifs_opackets++; -#define INCR_OERRORS(ppa) ppa->ifstats.ifs_oerrors++; -#endif - -/* - * STREAMS driver entry points. - */ -static int -#ifdef SVR4 -pppopen(q, devp, oflag, sflag, credp) - queue_t *q; - dev_t *devp; - int oflag, sflag; - cred_t *credp; -#else -pppopen(q, dev, oflag, sflag) - queue_t *q; - int dev; /* really dev_t */ - int oflag, sflag; -#endif -{ - upperstr_t *up; - upperstr_t **prevp; - minor_t mn; -#ifdef PRIOQ - u_short *ptr; - u_char new_band; -#endif /* PRIOQ */ - - if (q->q_ptr) - DRV_OPEN_OK(dev); /* device is already open */ - -#ifdef PRIOQ - /* Calculate max_bband & def_band from definitions in prioq.h - This colud be done at some more approtiate time (less often) - but this way it works well so I'll just leave it here */ - - max_band = 1; - def_band = 0; - ptr = prioq_table; - while (*ptr) { - new_band = 1; - while (*ptr) - if (*ptr++ == IPPORT_DEFAULT) { - new_band = 0; - def_band = max_band; - } - max_band += new_band; - ptr++; - } - if (def_band) - def_band = max_band - def_band; - --max_band; -#endif /* PRIOQ */ - - if (sflag == CLONEOPEN) { - mn = 0; - for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { - if (up->mn != mn) - break; - ++mn; - } - } else { -#ifdef SVR4 - mn = getminor(*devp); -#else - mn = minor(dev); -#endif - for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { - if (up->mn >= mn) - break; - } - if (up->mn == mn) { - /* this can't happen */ - q->q_ptr = WR(q)->q_ptr = (caddr_t) up; - DRV_OPEN_OK(dev); - } - } - - /* - * Construct a new minor node. - */ - up = (upperstr_t *) ALLOC_SLEEP(sizeof(upperstr_t)); - bzero((caddr_t) up, sizeof(upperstr_t)); - if (up == 0) { - DPRINT("pppopen: out of kernel memory\n"); - OPEN_ERROR(ENXIO); - } - up->nextmn = *prevp; - *prevp = up; - up->mn = mn; -#ifdef SVR4 - *devp = makedevice(getmajor(*devp), mn); -#endif - up->q = q; - if (NOTSUSER() == 0) - up->flags |= US_PRIV; -#ifndef NO_DLPI - up->state = DL_UNATTACHED; -#endif -#ifdef LACHTCP - up->ifflags = IFF_UP | IFF_POINTOPOINT; -#endif - up->sap = -1; - up->last_sent = up->last_recv = time; - up->npmode = NPMODE_DROP; - q->q_ptr = (caddr_t) up; - WR(q)->q_ptr = (caddr_t) up; - noenable(WR(q)); -#ifdef SOL2 - mutex_init(&up->stats_lock, NULL, MUTEX_DRIVER, NULL); -#endif - ++ppp_count; - - qprocson(q); - DRV_OPEN_OK(makedev(major(dev), mn)); -} - -static int -#ifdef SVR4 -pppclose(q, flag, credp) - queue_t *q; - int flag; - cred_t *credp; -#else -pppclose(q, flag) - queue_t *q; - int flag; -#endif -{ - upperstr_t *up, **upp; - upperstr_t *as, *asnext; - upperstr_t **prevp; - - qprocsoff(q); - - up = (upperstr_t *) q->q_ptr; - if (up == 0) { - DPRINT("pppclose: q_ptr = 0\n"); - return 0; - } - if (up->flags & US_DBGLOG) - DPRINT2("ppp/%d: close, flags=%x\n", up->mn, up->flags); - if (up->flags & US_CONTROL) { -#ifdef LACHTCP - struct ifstats *ifp, *pifp; -#endif - if (up->lowerq != 0) { - /* Gack! the lower stream should have be unlinked earlier! */ - DPRINT1("ppp%d: lower stream still connected on close?\n", - up->mn); - LOCK_LOWER_W; - up->lowerq->q_ptr = 0; - RD(up->lowerq)->q_ptr = 0; - up->lowerq = 0; - UNLOCK_LOWER; - } - - /* - * This stream represents a PPA: - * For all streams attached to the PPA, clear their - * references to this PPA. - * Then remove this PPA from the list of PPAs. - */ - for (as = up->next; as != 0; as = asnext) { - asnext = as->next; - as->next = 0; - as->ppa = 0; - if (as->flags & US_BLOCKED) { - as->flags &= ~US_BLOCKED; - flushq(WR(as->q), FLUSHDATA); - } - } - for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa) - if (*upp == up) { - *upp = up->nextppa; - break; - } -#ifdef LACHTCP - /* Remove the statistics from the active list. */ - for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) { - if (ifp == &up->ifstats) { - if (pifp) - pifp->ifs_next = ifp->ifs_next; - else - ifstats = ifp->ifs_next; - break; - } - pifp = ifp; - } -#endif - } else { - /* - * If this stream is attached to a PPA, - * remove it from the PPA's list. - */ - if ((as = up->ppa) != 0) { - for (; as->next != 0; as = as->next) - if (as->next == up) { - as->next = up->next; - break; - } - } - } - -#ifdef SOL2 - if (up->kstats) - kstat_delete(up->kstats); - mutex_destroy(&up->stats_lock); -#endif - - q->q_ptr = NULL; - WR(q)->q_ptr = NULL; - - for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) { - if (*prevp == up) { - *prevp = up->nextmn; - break; - } - } - FREE(up, sizeof(upperstr_t)); - --ppp_count; - - return 0; -} - -/* - * A message from on high. We do one of three things: - * - qreply() - * - put the message on the lower write stream - * - queue it for our service routine - */ -static int -pppuwput(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *ppa, *nps; - struct iocblk *iop; - struct linkblk *lb; -#ifdef LACHTCP - struct ifreq *ifr; - int i; -#endif - queue_t *lq; - int error, n, sap; - mblk_t *mq; - struct ppp_idle *pip; -#ifdef PRIOQ - queue_t *tlq; -#endif /* PRIOQ */ -#ifdef NO_DLPI - upperstr_t *os; -#endif - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppuwput: q_ptr = 0!\n"); - return 0; - } - if (mp == 0) { - DPRINT1("pppuwput/%d: mp = 0!\n", us->mn); - return 0; - } - if (mp->b_datap == 0) { - DPRINT1("pppuwput/%d: mp->b_datap = 0!\n", us->mn); - return 0; - } - switch (mp->b_datap->db_type) { -#ifndef NO_DLPI - case M_PCPROTO: - case M_PROTO: - dlpi_request(q, mp, us); - break; -#endif /* NO_DLPI */ - - case M_DATA: - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: uwput M_DATA len=%d flags=%x\n", - us->mn, msgdsize(mp), us->flags); - if (us->ppa == 0 || msgdsize(mp) > us->ppa->mtu + PPP_HDRLEN -#ifndef NO_DLPI - || (us->flags & US_CONTROL) == 0 -#endif /* NO_DLPI */ - ) { - DPRINT1("pppuwput: junk data len=%d\n", msgdsize(mp)); - freemsg(mp); - break; - } -#ifdef NO_DLPI - if ((us->flags & US_CONTROL) == 0 && !pass_packet(us, mp, 1)) - break; -#endif - if (!send_data(mp, us)) - putq(q, mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: ioctl %x count=%d\n", - us->mn, iop->ioc_cmd, iop->ioc_count); - switch (iop->ioc_cmd) { -#if defined(SOL2) - case DLIOCRAW: /* raw M_DATA mode */ - us->flags |= US_RAWDATA; - error = 0; - break; -#endif /* defined(SOL2) */ - case I_LINK: - if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl I_LINK b_cont = 0!\n", us->mn); - break; - } - lb = (struct linkblk *) mp->b_cont->b_rptr; - lq = lb->l_qbot; - if (lq == 0) { - DPRINT1("pppuwput/%d: ioctl I_LINK l_qbot = 0!\n", us->mn); - break; - } - LOCK_LOWER_W; - us->lowerq = lq; - lq->q_ptr = (caddr_t) q; - RD(lq)->q_ptr = (caddr_t) us->q; - UNLOCK_LOWER; - iop->ioc_count = 0; - error = 0; - us->flags &= ~US_LASTMOD; - /* Unblock upper streams which now feed this lower stream. */ - qenable(q); - /* Send useful information down to the modules which - are now linked below us. */ - putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id); - putctl4(lq, M_CTL, PPPCTL_MRU, us->mru); - putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu); -#ifdef PRIOQ - /* Lower tty driver's queue hiwat/lowat from default 4096/128 - to 256/128 since we don't want queueing of data on - output to physical device */ - - freezestr(lq); - for (tlq = lq; tlq->q_next != NULL; tlq = tlq->q_next) - ; - strqset(tlq, QHIWAT, 0, 256); - strqset(tlq, QLOWAT, 0, 128); - unfreezestr(lq); -#endif /* PRIOQ */ - break; - - case I_UNLINK: - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl I_UNLINK b_cont = 0!\n", us->mn); - break; - } - lb = (struct linkblk *) mp->b_cont->b_rptr; -#if DEBUG - if (us->lowerq != lb->l_qbot) { - DPRINT2("ppp unlink: lowerq=%x qbot=%x\n", - us->lowerq, lb->l_qbot); - break; - } -#endif - iop->ioc_count = 0; - qwriter(q, mp, detach_lower, PERIM_OUTER); - error = -1; - break; - - case PPPIO_NEWPPA: - if (us->flags & US_CONTROL) - break; - if ((us->flags & US_PRIV) == 0) { - error = EPERM; - break; - } - /* Arrange to return an int */ - if ((mq = mp->b_cont) == 0 - || mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) { - mq = allocb(sizeof(int), BPRI_HI); - if (mq == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = mq; - mq->b_cont = 0; - } - iop->ioc_count = sizeof(int); - mq->b_wptr = mq->b_rptr + sizeof(int); - qwriter(q, mp, new_ppa, PERIM_OUTER); - error = -1; - break; - - case PPPIO_ATTACH: - /* like dlpi_attach, for programs which can't write to - the stream (like pppstats) */ - if (iop->ioc_count != sizeof(int) || us->ppa != 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_ATTACH b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) - if (ppa->ppa_id == n) - break; - if (ppa == 0) - break; - us->ppa = ppa; - iop->ioc_count = 0; - qwriter(q, mp, attach_ppa, PERIM_OUTER); - error = -1; - break; - -#ifdef NO_DLPI - case PPPIO_BIND: - /* Attach to a given SAP. */ - if (iop->ioc_count != sizeof(int) || us->ppa == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_BIND b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - /* n must be a valid PPP network protocol number. */ - if (n < 0x21 || n > 0x3fff || (n & 0x101) != 1) - break; - /* check that no other stream is bound to this sap already. */ - for (os = us->ppa; os != 0; os = os->next) - if (os->sap == n) - break; - if (os != 0) - break; - us->sap = n; - iop->ioc_count = 0; - error = 0; - break; -#endif /* NO_DLPI */ - - case PPPIO_MRU: - if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_MRU b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n <= 0 || n > PPP_MAXMRU) - break; - if (n < PPP_MRU) - n = PPP_MRU; - us->mru = n; - if (us->lowerq) - putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n); - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_MTU: - if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_MTU b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n <= 0 || n > PPP_MAXMTU) - break; - us->mtu = n; -#ifdef LACHTCP - /* The MTU reported in netstat, not used as IP max packet size! */ - us->ifstats.ifs_mtu = n; -#endif - if (us->lowerq) - putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n); - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_LASTMOD: - us->flags |= US_LASTMOD; - error = 0; - break; - - case PPPIO_DEBUG: - if (iop->ioc_count != sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_DEBUG b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n == PPPDBG_DUMP + PPPDBG_DRIVER) { - qwriter(q, NULL, debug_dump, PERIM_OUTER); - iop->ioc_count = 0; - error = -1; - } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) { - DPRINT1("ppp/%d: debug log enabled\n", us->mn); - us->flags |= US_DBGLOG; - iop->ioc_count = 0; - error = 0; - } else { - if (us->ppa == 0 || us->ppa->lowerq == 0) - break; - putnext(us->ppa->lowerq, mp); - error = -1; - } - break; - - case PPPIO_NPMODE: - if (iop->ioc_count != 2 * sizeof(int)) - break; - if ((us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_NPMODE b_cont = 0!\n", us->mn); - break; - } - sap = ((int *)mp->b_cont->b_rptr)[0]; - for (nps = us->next; nps != 0; nps = nps->next) { - if (us->flags & US_DBGLOG) - DPRINT2("us = 0x%x, us->next->sap = 0x%x\n", nps, nps->sap); - if (nps->sap == sap) - break; - } - if (nps == 0) { - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: no stream for sap %x\n", us->mn, sap); - break; - } - /* XXX possibly should use qwriter here */ - nps->npmode = (enum NPmode) ((int *)mp->b_cont->b_rptr)[1]; - if (nps->npmode != NPMODE_QUEUE && (nps->flags & US_BLOCKED) != 0) - qenable(WR(nps->q)); - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_GIDLE: - if ((ppa = us->ppa) == 0) - break; - mq = allocb(sizeof(struct ppp_idle), BPRI_HI); - if (mq == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = mq; - mq->b_cont = 0; - pip = (struct ppp_idle *) mq->b_wptr; - pip->xmit_idle = time - ppa->last_sent; - pip->recv_idle = time - ppa->last_recv; - mq->b_wptr += sizeof(struct ppp_idle); - iop->ioc_count = sizeof(struct ppp_idle); - error = 0; - break; - -#ifdef LACHTCP - case SIOCSIFNAME: - /* Sent from IP down to us. Attach the ifstats structure. */ - if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0) - break; - ifr = (struct ifreq *)mp->b_cont->b_rptr; - /* Find the unit number in the interface name. */ - for (i = 0; i < IFNAMSIZ; i++) { - if (ifr->ifr_name[i] == 0 || - (ifr->ifr_name[i] >= '0' && - ifr->ifr_name[i] <= '9')) - break; - else - us->ifname[i] = ifr->ifr_name[i]; - } - us->ifname[i] = 0; - - /* Convert the unit number to binary. */ - for (n = 0; i < IFNAMSIZ; i++) { - if (ifr->ifr_name[i] == 0) { - break; - } - else { - n = n * 10 + ifr->ifr_name[i] - '0'; - } - } - - /* Verify the ppa. */ - if (us->ppa->ppa_id != n) - break; - ppa = us->ppa; - - /* Set up the netstat block. */ - strncpy (ppa->ifname, us->ifname, IFNAMSIZ); - - ppa->ifstats.ifs_name = ppa->ifname; - ppa->ifstats.ifs_unit = n; - ppa->ifstats.ifs_active = us->state != DL_UNBOUND; - ppa->ifstats.ifs_mtu = ppa->mtu; - - /* Link in statistics used by netstat. */ - ppa->ifstats.ifs_next = ifstats; - ifstats = &ppa->ifstats; - - iop->ioc_count = 0; - error = 0; - break; - - case SIOCGIFFLAGS: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags; - error = 0; - break; - - case SIOCSIFFLAGS: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags; - error = 0; - break; - - case SIOCSIFADDR: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - us->ifflags |= IFF_RUNNING; - ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING; - error = 0; - break; - - case SIOCSIFMTU: - /* - * Vanilla SVR4 systems don't handle SIOCSIFMTU, rather - * they take the MTU from the DL_INFO_ACK we sent in response - * to their DL_INFO_REQ. Fortunately, they will update the - * MTU if we send an unsolicited DL_INFO_ACK up. - */ - if ((mq = allocb(sizeof(dl_info_req_t), BPRI_HI)) == 0) - break; /* should do bufcall */ - ((union DL_primitives *)mq->b_rptr)->dl_primitive = DL_INFO_REQ; - mq->b_wptr = mq->b_rptr + sizeof(dl_info_req_t); - dlpi_request(q, mq, us); - error = 0; - break; - - case SIOCGIFNETMASK: - case SIOCSIFNETMASK: - case SIOCGIFADDR: - case SIOCGIFDSTADDR: - case SIOCSIFDSTADDR: - case SIOCGIFMETRIC: - error = 0; - break; -#endif /* LACHTCP */ - - default: - if (us->ppa == 0 || us->ppa->lowerq == 0) - break; - us->ioc_id = iop->ioc_id; - error = -1; - switch (iop->ioc_cmd) { - case PPPIO_GETSTAT: - case PPPIO_GETCSTAT: - if (us->flags & US_LASTMOD) { - error = EINVAL; - break; - } - putnext(us->ppa->lowerq, mp); - break; - default: - if (us->flags & US_PRIV) - putnext(us->ppa->lowerq, mp); - else { - DPRINT1("ppp ioctl %x rejected\n", iop->ioc_cmd); - error = EPERM; - } - break; - } - break; - } - - if (error > 0) { - iop->ioc_error = error; - mp->b_datap->db_type = M_IOCNAK; - qreply(q, mp); - } else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } - break; - - case M_FLUSH: - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: flush %x\n", us->mn, *mp->b_rptr); - if (*mp->b_rptr & FLUSHW) - flushq(q, FLUSHDATA); - if (*mp->b_rptr & FLUSHR) { - *mp->b_rptr &= ~FLUSHW; - qreply(q, mp); - } else - freemsg(mp); - break; - - default: - freemsg(mp); - break; - } - return 0; -} - -#ifndef NO_DLPI -static void -dlpi_request(q, mp, us) - queue_t *q; - mblk_t *mp; - upperstr_t *us; -{ - union DL_primitives *d = (union DL_primitives *) mp->b_rptr; - int size = mp->b_wptr - mp->b_rptr; - mblk_t *reply, *np; - upperstr_t *ppa, *os; - int sap, len; - dl_info_ack_t *info; - dl_bind_ack_t *ackp; -#if DL_CURRENT_VERSION >= 2 - dl_phys_addr_ack_t *paddrack; - static struct ether_addr eaddr = {0}; -#endif - - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: dlpi prim %x len=%d\n", us->mn, - d->dl_primitive, size); - switch (d->dl_primitive) { - case DL_INFO_REQ: - if (size < sizeof(dl_info_req_t)) - goto badprim; - if ((reply = allocb(sizeof(dl_info_ack_t), BPRI_HI)) == 0) - break; /* should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - info = (dl_info_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_info_ack_t); - bzero((caddr_t) info, sizeof(dl_info_ack_t)); - info->dl_primitive = DL_INFO_ACK; - info->dl_max_sdu = us->ppa? us->ppa->mtu: PPP_MAXMTU; - info->dl_min_sdu = 1; - info->dl_addr_length = sizeof(uint); - info->dl_mac_type = DL_ETHER; /* a bigger lie */ - info->dl_current_state = us->state; - info->dl_service_mode = DL_CLDLS; - info->dl_provider_style = DL_STYLE2; -#if DL_CURRENT_VERSION >= 2 - info->dl_sap_length = sizeof(uint); - info->dl_version = DL_CURRENT_VERSION; -#endif - qreply(q, reply); - break; - - case DL_ATTACH_REQ: - if (size < sizeof(dl_attach_req_t)) - goto badprim; - if (us->state != DL_UNATTACHED || us->ppa != 0) { - dlpi_error(q, us, DL_ATTACH_REQ, DL_OUTSTATE, 0); - break; - } - for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) - if (ppa->ppa_id == d->attach_req.dl_ppa) - break; - if (ppa == 0) { - dlpi_error(q, us, DL_ATTACH_REQ, DL_BADPPA, 0); - break; - } - us->ppa = ppa; - qwriter(q, mp, attach_ppa, PERIM_OUTER); - return; - - case DL_DETACH_REQ: - if (size < sizeof(dl_detach_req_t)) - goto badprim; - if (us->state != DL_UNBOUND || us->ppa == 0) { - dlpi_error(q, us, DL_DETACH_REQ, DL_OUTSTATE, 0); - break; - } - qwriter(q, mp, detach_ppa, PERIM_OUTER); - return; - - case DL_BIND_REQ: - if (size < sizeof(dl_bind_req_t)) - goto badprim; - if (us->state != DL_UNBOUND || us->ppa == 0) { - dlpi_error(q, us, DL_BIND_REQ, DL_OUTSTATE, 0); - break; - } -#if 0 - /* apparently this test fails (unnecessarily?) on some systems */ - if (d->bind_req.dl_service_mode != DL_CLDLS) { - dlpi_error(q, us, DL_BIND_REQ, DL_UNSUPPORTED, 0); - break; - } -#endif - - /* saps must be valid PPP network protocol numbers, - except that we accept ETHERTYPE_IP in place of PPP_IP. */ - sap = d->bind_req.dl_sap; - us->req_sap = sap; - -#if defined(SOL2) - if (us->flags & US_DBGLOG) - DPRINT2("DL_BIND_REQ: ip gives sap = 0x%x, us = 0x%x", sap, us); - - if (sap == ETHERTYPE_IP) /* normal IFF_IPV4 */ - sap = PPP_IP; - else if (sap == ETHERTYPE_IPV6) /* when IFF_IPV6 is set */ - sap = PPP_IPV6; - else if (sap == ETHERTYPE_ALLSAP) /* snoop gives sap of 0 */ - sap = PPP_ALLSAP; - else { - DPRINT2("DL_BIND_REQ: unrecognized sap = 0x%x, us = 0x%x", sap, us); - dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); - break; - } -#else - if (sap == ETHERTYPE_IP) - sap = PPP_IP; - if (sap < 0x21 || sap > 0x3fff || (sap & 0x101) != 1) { - dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); - break; - } -#endif /* defined(SOL2) */ - - /* check that no other stream is bound to this sap already. */ - for (os = us->ppa; os != 0; os = os->next) - if (os->sap == sap) - break; - if (os != 0) { - dlpi_error(q, us, DL_BIND_REQ, DL_NOADDR, 0); - break; - } - - us->sap = sap; - us->state = DL_IDLE; - - if ((reply = allocb(sizeof(dl_bind_ack_t) + sizeof(uint), - BPRI_HI)) == 0) - break; /* should do bufcall */ - ackp = (dl_bind_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_bind_ack_t) + sizeof(uint); - reply->b_datap->db_type = M_PCPROTO; - bzero((caddr_t) ackp, sizeof(dl_bind_ack_t)); - ackp->dl_primitive = DL_BIND_ACK; - ackp->dl_sap = sap; - ackp->dl_addr_length = sizeof(uint); - ackp->dl_addr_offset = sizeof(dl_bind_ack_t); - *(uint *)(ackp+1) = sap; - qreply(q, reply); - break; - - case DL_UNBIND_REQ: - if (size < sizeof(dl_unbind_req_t)) - goto badprim; - if (us->state != DL_IDLE) { - dlpi_error(q, us, DL_UNBIND_REQ, DL_OUTSTATE, 0); - break; - } - us->sap = -1; - us->state = DL_UNBOUND; -#ifdef LACHTCP - us->ppa->ifstats.ifs_active = 0; -#endif - dlpi_ok(q, DL_UNBIND_REQ); - break; - - case DL_UNITDATA_REQ: - if (size < sizeof(dl_unitdata_req_t)) - goto badprim; - if (us->state != DL_IDLE) { - dlpi_error(q, us, DL_UNITDATA_REQ, DL_OUTSTATE, 0); - break; - } - if ((ppa = us->ppa) == 0) { - cmn_err(CE_CONT, "ppp: in state dl_idle but ppa == 0?\n"); - break; - } - len = mp->b_cont == 0? 0: msgdsize(mp->b_cont); - if (len > ppa->mtu) { - DPRINT2("dlpi data too large (%d > %d)\n", len, ppa->mtu); - break; - } - -#if defined(SOL2) - /* - * Should there be any promiscuous stream(s), send the data - * up for each promiscuous stream that we recognize. - */ - if (mp->b_cont) - promisc_sendup(ppa, mp->b_cont, us->sap, 0); -#endif /* defined(SOL2) */ - - mp->b_band = 0; -#ifdef PRIOQ - /* Extract s_port & d_port from IP-packet, the code is a bit - dirty here, but so am I, too... */ - if (mp->b_datap->db_type == M_PROTO && us->sap == PPP_IP - && mp->b_cont != 0) { - u_char *bb, *tlh; - int iphlen, len; - u_short *ptr; - u_char band_unset, cur_band, syn; - u_short s_port, d_port; - - bb = mp->b_cont->b_rptr; /* bb points to IP-header*/ - len = mp->b_cont->b_wptr - mp->b_cont->b_rptr; - syn = 0; - s_port = IPPORT_DEFAULT; - d_port = IPPORT_DEFAULT; - if (len >= 20) { /* 20 = minimum length of IP header */ - iphlen = (bb[0] & 0x0f) * 4; - tlh = bb + iphlen; - len -= iphlen; - switch (bb[9]) { - case IPPROTO_TCP: - if (len >= 20) { /* min length of TCP header */ - s_port = (tlh[0] << 8) + tlh[1]; - d_port = (tlh[2] << 8) + tlh[3]; - syn = tlh[13] & 0x02; - } - break; - case IPPROTO_UDP: - if (len >= 8) { /* min length of UDP header */ - s_port = (tlh[0] << 8) + tlh[1]; - d_port = (tlh[2] << 8) + tlh[3]; - } - break; - } - } - - /* - * Now calculate b_band for this packet from the - * port-priority table. - */ - ptr = prioq_table; - cur_band = max_band; - band_unset = 1; - while (*ptr) { - while (*ptr && band_unset) - if (s_port == *ptr || d_port == *ptr++) { - mp->b_band = cur_band; - band_unset = 0; - break; - } - ptr++; - cur_band--; - } - if (band_unset) - mp->b_band = def_band; - /* It may be usable to urge SYN packets a bit */ - if (syn) - mp->b_band++; - } -#endif /* PRIOQ */ - /* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */ - if (mp->b_datap->db_ref > 1) { - np = allocb(PPP_HDRLEN, BPRI_HI); - if (np == 0) - break; /* gak! */ - np->b_cont = mp->b_cont; - mp->b_cont = 0; - freeb(mp); - mp = np; - } else - mp->b_datap->db_type = M_DATA; - /* XXX should use dl_dest_addr_offset/length here, - but we would have to translate ETHERTYPE_IP -> PPP_IP */ - mp->b_wptr = mp->b_rptr + PPP_HDRLEN; - mp->b_rptr[0] = PPP_ALLSTATIONS; - mp->b_rptr[1] = PPP_UI; - mp->b_rptr[2] = us->sap >> 8; - mp->b_rptr[3] = us->sap; - if (pass_packet(us, mp, 1)) { - if (!send_data(mp, us)) - putq(q, mp); - } - return; - -#if DL_CURRENT_VERSION >= 2 - case DL_PHYS_ADDR_REQ: - if (size < sizeof(dl_phys_addr_req_t)) - goto badprim; - - /* - * Don't check state because ifconfig sends this one down too - */ - - if ((reply = allocb(sizeof(dl_phys_addr_ack_t)+ETHERADDRL, - BPRI_HI)) == 0) - break; /* should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - paddrack = (dl_phys_addr_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_phys_addr_ack_t); - bzero((caddr_t) paddrack, sizeof(dl_phys_addr_ack_t)+ETHERADDRL); - paddrack->dl_primitive = DL_PHYS_ADDR_ACK; - paddrack->dl_addr_length = ETHERADDRL; - paddrack->dl_addr_offset = sizeof(dl_phys_addr_ack_t); - bcopy(&eaddr, reply->b_wptr, ETHERADDRL); - reply->b_wptr += ETHERADDRL; - qreply(q, reply); - break; - -#if defined(SOL2) - case DL_PROMISCON_REQ: - if (size < sizeof(dl_promiscon_req_t)) - goto badprim; - us->flags |= US_PROMISC; - dlpi_ok(q, DL_PROMISCON_REQ); - break; - - case DL_PROMISCOFF_REQ: - if (size < sizeof(dl_promiscoff_req_t)) - goto badprim; - us->flags &= ~US_PROMISC; - dlpi_ok(q, DL_PROMISCOFF_REQ); - break; -#else - case DL_PROMISCON_REQ: /* fall thru */ - case DL_PROMISCOFF_REQ: /* fall thru */ -#endif /* defined(SOL2) */ -#endif /* DL_CURRENT_VERSION >= 2 */ - -#if DL_CURRENT_VERSION >= 2 - case DL_SET_PHYS_ADDR_REQ: - case DL_SUBS_BIND_REQ: - case DL_SUBS_UNBIND_REQ: - case DL_ENABMULTI_REQ: - case DL_DISABMULTI_REQ: - case DL_XID_REQ: - case DL_TEST_REQ: - case DL_REPLY_UPDATE_REQ: - case DL_REPLY_REQ: - case DL_DATA_ACK_REQ: -#endif - case DL_CONNECT_REQ: - case DL_TOKEN_REQ: - dlpi_error(q, us, d->dl_primitive, DL_NOTSUPPORTED, 0); - break; - - case DL_CONNECT_RES: - case DL_DISCONNECT_REQ: - case DL_RESET_REQ: - case DL_RESET_RES: - dlpi_error(q, us, d->dl_primitive, DL_OUTSTATE, 0); - break; - - case DL_UDQOS_REQ: - dlpi_error(q, us, d->dl_primitive, DL_BADQOSTYPE, 0); - break; - -#if DL_CURRENT_VERSION >= 2 - case DL_TEST_RES: - case DL_XID_RES: - break; -#endif - - default: - cmn_err(CE_CONT, "ppp: unknown dlpi prim 0x%x\n", d->dl_primitive); - /* fall through */ - badprim: - dlpi_error(q, us, d->dl_primitive, DL_BADPRIM, 0); - break; - } - freemsg(mp); -} - -static void -dlpi_error(q, us, prim, err, uerr) - queue_t *q; - upperstr_t *us; - int prim, err, uerr; -{ - mblk_t *reply; - dl_error_ack_t *errp; - - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: dlpi error, prim=%x, err=%x\n", us->mn, prim, err); - reply = allocb(sizeof(dl_error_ack_t), BPRI_HI); - if (reply == 0) - return; /* XXX should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - errp = (dl_error_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_error_ack_t); - errp->dl_primitive = DL_ERROR_ACK; - errp->dl_error_primitive = prim; - errp->dl_errno = err; - errp->dl_unix_errno = uerr; - qreply(q, reply); -} - -static void -dlpi_ok(q, prim) - queue_t *q; - int prim; -{ - mblk_t *reply; - dl_ok_ack_t *okp; - - reply = allocb(sizeof(dl_ok_ack_t), BPRI_HI); - if (reply == 0) - return; /* XXX should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - okp = (dl_ok_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_ok_ack_t); - okp->dl_primitive = DL_OK_ACK; - okp->dl_correct_primitive = prim; - qreply(q, reply); -} -#endif /* NO_DLPI */ - -static int -pass_packet(us, mp, outbound) - upperstr_t *us; - mblk_t *mp; - int outbound; -{ - int pass; - upperstr_t *ppa; - - if ((ppa = us->ppa) == 0) { - freemsg(mp); - return 0; - } - -#ifdef FILTER_PACKETS - pass = ip_hard_filter(us, mp, outbound); -#else - /* - * Here is where we might, in future, decide whether to pass - * or drop the packet, and whether it counts as link activity. - */ - pass = 1; -#endif /* FILTER_PACKETS */ - - if (pass < 0) { - /* pass only if link already up, and don't update time */ - if (ppa->lowerq == 0) { - freemsg(mp); - return 0; - } - pass = 1; - } else if (pass) { - if (outbound) - ppa->last_sent = time; - else - ppa->last_recv = time; - } - - return pass; -} - -/* - * We have some data to send down to the lower stream (or up the - * control stream, if we don't have a lower stream attached). - * Returns 1 if the message was dealt with, 0 if it wasn't able - * to be sent on and should therefore be queued up. - */ -static int -send_data(mp, us) - mblk_t *mp; - upperstr_t *us; -{ - upperstr_t *ppa; - - if ((us->flags & US_BLOCKED) || us->npmode == NPMODE_QUEUE) - return 0; - ppa = us->ppa; - if (ppa == 0 || us->npmode == NPMODE_DROP || us->npmode == NPMODE_ERROR) { - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: dropping pkt (npmode=%d)\n", us->mn, us->npmode); - freemsg(mp); - return 1; - } - if (ppa->lowerq == 0) { - /* try to send it up the control stream */ - if (bcanputnext(ppa->q, mp->b_band)) { - /* - * The message seems to get corrupted for some reason if - * we just send the message up as it is, so we send a copy. - */ - mblk_t *np = copymsg(mp); - freemsg(mp); - if (np != 0) - putnext(ppa->q, np); - return 1; - } - } else { - if (bcanputnext(ppa->lowerq, mp->b_band)) { - MT_ENTER(&ppa->stats_lock); - ppa->stats.ppp_opackets++; - ppa->stats.ppp_obytes += msgdsize(mp); -#ifdef INCR_OPACKETS - INCR_OPACKETS(ppa); -#endif - MT_EXIT(&ppa->stats_lock); - /* - * The lower queue is only ever detached while holding an - * exclusive lock on the whole driver. So we can be confident - * that the lower queue is still there. - */ - putnext(ppa->lowerq, mp); - return 1; - } - } - us->flags |= US_BLOCKED; - return 0; -} - -/* - * Allocate a new PPA id and link this stream into the list of PPAs. - * This procedure is called with an exclusive lock on all queues in - * this driver. - */ -static void -new_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *up, **usp; - int ppa_id; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("new_ppa: q_ptr = 0!\n"); - return; - } - - usp = &ppas; - ppa_id = 0; - while ((up = *usp) != 0 && ppa_id == up->ppa_id) { - ++ppa_id; - usp = &up->nextppa; - } - us->ppa_id = ppa_id; - us->ppa = us; - us->next = 0; - us->nextppa = *usp; - *usp = us; - us->flags |= US_CONTROL; - us->npmode = NPMODE_PASS; - - us->mtu = PPP_MTU; - us->mru = PPP_MRU; - -#ifdef SOL2 - /* - * Create a kstats record for our statistics, so netstat -i works. - */ - if (us->kstats == 0) { - char unit[32]; - - sprintf(unit, "ppp%d", us->ppa->ppa_id); - us->kstats = kstat_create("ppp", us->ppa->ppa_id, unit, - "net", KSTAT_TYPE_NAMED, 4, 0); - if (us->kstats != 0) { - kstat_named_t *kn = KSTAT_NAMED_PTR(us->kstats); - - strcpy(kn[0].name, "ipackets"); - kn[0].data_type = KSTAT_DATA_ULONG; - strcpy(kn[1].name, "ierrors"); - kn[1].data_type = KSTAT_DATA_ULONG; - strcpy(kn[2].name, "opackets"); - kn[2].data_type = KSTAT_DATA_ULONG; - strcpy(kn[3].name, "oerrors"); - kn[3].data_type = KSTAT_DATA_ULONG; - kstat_install(us->kstats); - } - } -#endif /* SOL2 */ - - *(int *)mp->b_cont->b_rptr = ppa_id; - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -static void -attach_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *t; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("attach_ppa: q_ptr = 0!\n"); - return; - } - -#ifndef NO_DLPI - us->state = DL_UNBOUND; -#endif - for (t = us->ppa; t->next != 0; t = t->next) - ; - t->next = us; - us->next = 0; - if (mp->b_datap->db_type == M_IOCTL) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { -#ifndef NO_DLPI - dlpi_ok(q, DL_ATTACH_REQ); -#endif - } -} - -static void -detach_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *t; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("detach_ppa: q_ptr = 0!\n"); - return; - } - - for (t = us->ppa; t->next != 0; t = t->next) - if (t->next == us) { - t->next = us->next; - break; - } - us->next = 0; - us->ppa = 0; -#ifndef NO_DLPI - us->state = DL_UNATTACHED; - dlpi_ok(q, DL_DETACH_REQ); -#endif -} - -/* - * We call this with qwriter in order to give the upper queue procedures - * the guarantee that the lower queue is not going to go away while - * they are executing. - */ -static void -detach_lower(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("detach_lower: q_ptr = 0!\n"); - return; - } - - LOCK_LOWER_W; - us->lowerq->q_ptr = 0; - RD(us->lowerq)->q_ptr = 0; - us->lowerq = 0; - UNLOCK_LOWER; - - /* Unblock streams which now feed back up the control stream. */ - qenable(us->q); - - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -static int -pppuwsrv(q) - queue_t *q; -{ - upperstr_t *us, *as; - mblk_t *mp; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppuwsrv: q_ptr = 0!\n"); - return 0; - } - - /* - * If this is a control stream, then this service procedure - * probably got enabled because of flow control in the lower - * stream being enabled (or because of the lower stream going - * away). Therefore we enable the service procedure of all - * attached upper streams. - */ - if (us->flags & US_CONTROL) { - for (as = us->next; as != 0; as = as->next) - qenable(WR(as->q)); - } - - /* Try to send on any data queued here. */ - us->flags &= ~US_BLOCKED; - while ((mp = getq(q)) != 0) { - if (!send_data(mp, us)) { - putbq(q, mp); - break; - } - } - - return 0; -} - -/* should never get called... */ -static int -ppplwput(q, mp) - queue_t *q; - mblk_t *mp; -{ - putnext(q, mp); - return 0; -} - -static int -ppplwsrv(q) - queue_t *q; -{ - queue_t *uq; - - /* - * Flow control has back-enabled this stream: - * enable the upper write service procedure for - * the upper control stream for this lower stream. - */ - LOCK_LOWER_R; - uq = (queue_t *) q->q_ptr; - if (uq != 0) - qenable(uq); - UNLOCK_LOWER; - return 0; -} - -/* - * This should only get called for control streams. - */ -static int -pppurput(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *ppa, *us; - int proto, len; - struct iocblk *iop; - - ppa = (upperstr_t *) q->q_ptr; - if (ppa == 0) { - DPRINT("pppurput: q_ptr = 0!\n"); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_CTL: - MT_ENTER(&ppa->stats_lock); - switch (*mp->b_rptr) { - case PPPCTL_IERROR: -#ifdef INCR_IERRORS - INCR_IERRORS(ppa); -#endif - ppa->stats.ppp_ierrors++; - break; - case PPPCTL_OERROR: -#ifdef INCR_OERRORS - INCR_OERRORS(ppa); -#endif - ppa->stats.ppp_oerrors++; - break; - } - MT_EXIT(&ppa->stats_lock); - freemsg(mp); - break; - - case M_IOCACK: - case M_IOCNAK: - /* - * Attempt to match up the response with the stream - * that the request came from. - */ - iop = (struct iocblk *) mp->b_rptr; - for (us = ppa; us != 0; us = us->next) - if (us->ioc_id == iop->ioc_id) - break; - if (us == 0) - freemsg(mp); - else - putnext(us->q, mp); - break; - - case M_HANGUP: - /* - * The serial device has hung up. We don't want to send - * the M_HANGUP message up to pppd because that will stop - * us from using the control stream any more. Instead we - * send a zero-length message as an end-of-file indication. - */ - freemsg(mp); - mp = allocb(1, BPRI_HI); - if (mp == 0) { - DPRINT1("ppp/%d: couldn't allocate eof message!\n", ppa->mn); - break; - } - putnext(ppa->q, mp); - break; - - default: - if (mp->b_datap->db_type == M_DATA) { - len = msgdsize(mp); - if (mp->b_wptr - mp->b_rptr < PPP_HDRLEN) { - PULLUP(mp, PPP_HDRLEN); - if (mp == 0) { - DPRINT1("ppp_urput: msgpullup failed (len=%d)\n", len); - break; - } - } - MT_ENTER(&ppa->stats_lock); - ppa->stats.ppp_ipackets++; - ppa->stats.ppp_ibytes += len; -#ifdef INCR_IPACKETS - INCR_IPACKETS(ppa); -#endif - MT_EXIT(&ppa->stats_lock); - - proto = PPP_PROTOCOL(mp->b_rptr); - -#if defined(SOL2) - /* - * Should there be any promiscuous stream(s), send the data - * up for each promiscuous stream that we recognize. - */ - promisc_sendup(ppa, mp, proto, 1); -#endif /* defined(SOL2) */ - - if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) { - /* - * A data packet for some network protocol. - * Queue it on the upper stream for that protocol. - * XXX could we just putnext it? (would require thought) - * The rblocked flag is there to ensure that we keep - * messages in order for each network protocol. - */ - if (!pass_packet(us, mp, 0)) - break; - if (!us->rblocked && !canput(us->q)) - us->rblocked = 1; - if (!us->rblocked) - putq(us->q, mp); - else - putq(q, mp); - break; - } - } - /* - * A control frame, a frame for an unknown protocol, - * or some other message type. - * Send it up to pppd via the control stream. - */ - if (queclass(mp) == QPCTL || canputnext(ppa->q)) - putnext(ppa->q, mp); - else - putq(q, mp); - break; - } - - return 0; -} - -static int -pppursrv(q) - queue_t *q; -{ - upperstr_t *us, *as; - mblk_t *mp, *hdr; -#ifndef NO_DLPI - dl_unitdata_ind_t *ud; -#endif - int proto; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppursrv: q_ptr = 0!\n"); - return 0; - } - - if (us->flags & US_CONTROL) { - /* - * A control stream. - * If there is no lower queue attached, run the write service - * routines of other upper streams attached to this PPA. - */ - if (us->lowerq == 0) { - as = us; - do { - if (as->flags & US_BLOCKED) - qenable(WR(as->q)); - as = as->next; - } while (as != 0); - } - - /* - * Messages get queued on this stream's read queue if they - * can't be queued on the read queue of the attached stream - * that they are destined for. This is for flow control - - * when this queue fills up, the lower read put procedure will - * queue messages there and the flow control will propagate - * down from there. - */ - while ((mp = getq(q)) != 0) { - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto < 0x8000 && (as = find_dest(us, proto)) != 0) { - if (!canput(as->q)) - break; - putq(as->q, mp); - } else { - if (!canputnext(q)) - break; - putnext(q, mp); - } - } - if (mp) { - putbq(q, mp); - } else { - /* can now put stuff directly on network protocol streams again */ - for (as = us->next; as != 0; as = as->next) - as->rblocked = 0; - } - - /* - * If this stream has a lower stream attached, - * enable the read queue's service routine. - * XXX we should really only do this if the queue length - * has dropped below the low-water mark. - */ - if (us->lowerq != 0) - qenable(RD(us->lowerq)); - - } else { - /* - * A network protocol stream. Put a DLPI header on each - * packet and send it on. - * (Actually, it seems that the IP module will happily - * accept M_DATA messages without the DL_UNITDATA_IND header.) - */ - while ((mp = getq(q)) != 0) { - if (!canputnext(q)) { - putbq(q, mp); - break; - } -#ifndef NO_DLPI - proto = PPP_PROTOCOL(mp->b_rptr); - mp->b_rptr += PPP_HDRLEN; - hdr = allocb(sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint), - BPRI_MED); - if (hdr == 0) { - /* XXX should put it back and use bufcall */ - freemsg(mp); - continue; - } - hdr->b_datap->db_type = M_PROTO; - ud = (dl_unitdata_ind_t *) hdr->b_wptr; - hdr->b_wptr += sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint); - hdr->b_cont = mp; - ud->dl_primitive = DL_UNITDATA_IND; - ud->dl_dest_addr_length = sizeof(uint); - ud->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); - ud->dl_src_addr_length = sizeof(uint); - ud->dl_src_addr_offset = ud->dl_dest_addr_offset + sizeof(uint); -#if DL_CURRENT_VERSION >= 2 - ud->dl_group_address = 0; -#endif - /* Send the DLPI client the data with the SAP they requested, - (e.g. ETHERTYPE_IP) rather than the PPP protocol number - (e.g. PPP_IP) */ - ((uint *)(ud + 1))[0] = us->req_sap; /* dest SAP */ - ((uint *)(ud + 1))[1] = us->req_sap; /* src SAP */ - putnext(q, hdr); -#else /* NO_DLPI */ - putnext(q, mp); -#endif /* NO_DLPI */ - } - /* - * Now that we have consumed some packets from this queue, - * enable the control stream's read service routine so that we - * can process any packets for us that might have got queued - * there for flow control reasons. - */ - if (us->ppa) - qenable(us->ppa->q); - } - - return 0; -} - -static upperstr_t * -find_dest(ppa, proto) - upperstr_t *ppa; - int proto; -{ - upperstr_t *us; - - for (us = ppa->next; us != 0; us = us->next) - if (proto == us->sap) - break; - return us; -} - -#if defined (SOL2) -/* - * Test upstream promiscuous conditions. As of now, only pass IPv4 and - * Ipv6 packets upstream (let PPP packets be decoded elsewhere). - */ -static upperstr_t * -find_promisc(us, proto) - upperstr_t *us; - int proto; -{ - - if ((proto != PPP_IP) && (proto != PPP_IPV6)) - return (upperstr_t *)0; - - for ( ; us; us = us->next) { - if ((us->flags & US_PROMISC) && (us->state == DL_IDLE)) - return us; - } - - return (upperstr_t *)0; -} - -/* - * Prepend an empty Ethernet header to msg for snoop, et al. - */ -static mblk_t * -prepend_ether(us, mp, proto) - upperstr_t *us; - mblk_t *mp; - int proto; -{ - mblk_t *eh; - int type; - - if ((eh = allocb(sizeof(struct ether_header), BPRI_HI)) == 0) { - freemsg(mp); - return (mblk_t *)0; - } - - if (proto == PPP_IP) - type = ETHERTYPE_IP; - else if (proto == PPP_IPV6) - type = ETHERTYPE_IPV6; - else - type = proto; /* What else? Let decoder decide */ - - eh->b_wptr += sizeof(struct ether_header); - bzero((caddr_t)eh->b_rptr, sizeof(struct ether_header)); - ((struct ether_header *)eh->b_rptr)->ether_type = htons((short)type); - eh->b_cont = mp; - return (eh); -} - -/* - * Prepend DL_UNITDATA_IND mblk to msg - */ -static mblk_t * -prepend_udind(us, mp, proto) - upperstr_t *us; - mblk_t *mp; - int proto; -{ - dl_unitdata_ind_t *dlu; - mblk_t *dh; - size_t size; - - size = sizeof(dl_unitdata_ind_t); - if ((dh = allocb(size, BPRI_MED)) == 0) { - freemsg(mp); - return (mblk_t *)0; - } - - dh->b_datap->db_type = M_PROTO; - dh->b_wptr = dh->b_datap->db_lim; - dh->b_rptr = dh->b_wptr - size; - - dlu = (dl_unitdata_ind_t *)dh->b_rptr; - dlu->dl_primitive = DL_UNITDATA_IND; - dlu->dl_dest_addr_length = 0; - dlu->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); - dlu->dl_src_addr_length = 0; - dlu->dl_src_addr_offset = sizeof(dl_unitdata_ind_t); - dlu->dl_group_address = 0; - - dh->b_cont = mp; - return (dh); -} - -/* - * For any recognized promiscuous streams, send data upstream - */ -static void -promisc_sendup(ppa, mp, proto, skip) - upperstr_t *ppa; - mblk_t *mp; - int proto, skip; -{ - mblk_t *dup_mp, *dup_dup_mp; - upperstr_t *prus, *nprus; - - if ((prus = find_promisc(ppa, proto)) != 0) { - if (dup_mp = dupmsg(mp)) { - - if (skip) - dup_mp->b_rptr += PPP_HDRLEN; - - for ( ; nprus = find_promisc(prus->next, proto); - prus = nprus) { - - if (dup_dup_mp = dupmsg(dup_mp)) { - if (canputnext(prus->q)) { - if (prus->flags & US_RAWDATA) { - dup_dup_mp = prepend_ether(prus, dup_dup_mp, proto); - putnext(prus->q, dup_dup_mp); - } else { - dup_dup_mp = prepend_udind(prus, dup_dup_mp, proto); - putnext(prus->q, dup_dup_mp); - } - } else { - DPRINT("ppp_urput: data to promisc q dropped\n"); - freemsg(dup_dup_mp); - } - } - } - - if (canputnext(prus->q)) { - if (prus->flags & US_RAWDATA) { - dup_mp = prepend_ether(prus, dup_mp, proto); - putnext(prus->q, dup_mp); - } else { - dup_mp = prepend_udind(prus, dup_mp, proto); - putnext(prus->q, dup_mp); - } - } else { - DPRINT("ppp_urput: data to promisc q dropped\n"); - freemsg(dup_mp); - } - } - } -} -#endif /* defined(SOL2) */ - -/* - * We simply put the message on to the associated upper control stream - * (either here or in ppplrsrv). That way we enter the perimeters - * before looking through the list of attached streams to decide which - * stream it should go up. - */ -static int -ppplrput(q, mp) - queue_t *q; - mblk_t *mp; -{ - queue_t *uq; - struct iocblk *iop; - - switch (mp->b_datap->db_type) { - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - iop->ioc_error = EINVAL; - mp->b_datap->db_type = M_IOCNAK; - qreply(q, mp); - return 0; - case M_FLUSH: - if (*mp->b_rptr & FLUSHR) - flushq(q, FLUSHDATA); - if (*mp->b_rptr & FLUSHW) { - *mp->b_rptr &= ~FLUSHR; - qreply(q, mp); - } else - freemsg(mp); - return 0; - } - - /* - * If we can't get the lower lock straight away, queue this one - * rather than blocking, to avoid the possibility of deadlock. - */ - if (!TRYLOCK_LOWER_R) { - putq(q, mp); - return 0; - } - - /* - * Check that we're still connected to the driver. - */ - uq = (queue_t *) q->q_ptr; - if (uq == 0) { - UNLOCK_LOWER; - DPRINT1("ppplrput: q = %x, uq = 0??\n", q); - freemsg(mp); - return 0; - } - - /* - * Try to forward the message to the put routine for the upper - * control stream for this lower stream. - * If there are already messages queued here, queue this one so - * they don't get out of order. - */ - if (queclass(mp) == QPCTL || (qsize(q) == 0 && canput(uq))) - put(uq, mp); - else - putq(q, mp); - - UNLOCK_LOWER; - return 0; -} - -static int -ppplrsrv(q) - queue_t *q; -{ - mblk_t *mp; - queue_t *uq; - - /* - * Packets get queued here for flow control reasons - * or if the lrput routine couldn't get the lower lock - * without blocking. - */ - LOCK_LOWER_R; - uq = (queue_t *) q->q_ptr; - if (uq == 0) { - UNLOCK_LOWER; - flushq(q, FLUSHALL); - DPRINT1("ppplrsrv: q = %x, uq = 0??\n", q); - return 0; - } - while ((mp = getq(q)) != 0) { - if (queclass(mp) == QPCTL || canput(uq)) - put(uq, mp); - else { - putbq(q, mp); - break; - } - } - UNLOCK_LOWER; - return 0; -} - -static int -putctl2(q, type, code, val) - queue_t *q; - int type, code, val; -{ - mblk_t *mp; - - mp = allocb(2, BPRI_HI); - if (mp == 0) - return 0; - mp->b_datap->db_type = type; - mp->b_wptr[0] = code; - mp->b_wptr[1] = val; - mp->b_wptr += 2; - putnext(q, mp); - return 1; -} - -static int -putctl4(q, type, code, val) - queue_t *q; - int type, code, val; -{ - mblk_t *mp; - - mp = allocb(4, BPRI_HI); - if (mp == 0) - return 0; - mp->b_datap->db_type = type; - mp->b_wptr[0] = code; - ((short *)mp->b_wptr)[1] = val; - mp->b_wptr += 4; - putnext(q, mp); - return 1; -} - -static void -debug_dump(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us; - queue_t *uq, *lq; - - DPRINT("ppp upper streams:\n"); - for (us = minor_devs; us != 0; us = us->nextmn) { - uq = us->q; - DPRINT3(" %d: q=%x rlev=%d", - us->mn, uq, (uq? qsize(uq): 0)); - DPRINT3(" wlev=%d flags=0x%b", (uq? qsize(WR(uq)): 0), - us->flags, "\020\1priv\2control\3blocked\4last"); - DPRINT3(" state=%x sap=%x req_sap=%x", us->state, us->sap, - us->req_sap); - if (us->ppa == 0) - DPRINT(" ppa=?\n"); - else - DPRINT1(" ppa=%d\n", us->ppa->ppa_id); - if (us->flags & US_CONTROL) { - lq = us->lowerq; - DPRINT3(" control for %d lq=%x rlev=%d", - us->ppa_id, lq, (lq? qsize(RD(lq)): 0)); - DPRINT3(" wlev=%d mru=%d mtu=%d\n", - (lq? qsize(lq): 0), us->mru, us->mtu); - } - } - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -#ifdef FILTER_PACKETS -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/udp.h> -#include <netinet/tcp.h> - -#define MAX_IPHDR 128 /* max TCP/IP header size */ - - -/* The following table contains a hard-coded list of protocol/port pairs. - * Any matching packets are either discarded unconditionally, or, - * if ok_if_link_up is non-zero when a connection does not currently exist - * (i.e., they go through if the connection is present, but never initiate - * a dial-out). - * This idea came from a post by dm@garage.uun.org (David Mazieres) - */ -static struct pktfilt_tab { - int proto; - u_short port; - u_short ok_if_link_up; -} pktfilt_tab[] = { - { IPPROTO_UDP, 520, 1 }, /* RIP, ok to pass if link is up */ - { IPPROTO_UDP, 123, 1 }, /* NTP, don't keep up the link for it */ - { -1, 0, 0 } /* terminator entry has port == -1 */ -}; - - -static int -ip_hard_filter(us, mp, outbound) - upperstr_t *us; - mblk_t *mp; - int outbound; -{ - struct ip *ip; - struct pktfilt_tab *pft; - mblk_t *temp_mp; - int proto; - int len, hlen; - - - /* Note, the PPP header has already been pulled up in all cases */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: filter, proto=0x%x, out=%d\n", us->mn, proto, outbound); - - switch (proto) - { - case PPP_IP: - if ((mp->b_wptr - mp->b_rptr) == PPP_HDRLEN && mp->b_cont != 0) { - temp_mp = mp->b_cont; - len = msgdsize(temp_mp); - hlen = (len < MAX_IPHDR) ? len : MAX_IPHDR; - PULLUP(temp_mp, hlen); - if (temp_mp == 0) { - DPRINT2("ppp/%d: filter, pullup next failed, len=%d\n", - us->mn, hlen); - mp->b_cont = 0; /* PULLUP() freed the rest */ - freemsg(mp); - return 0; - } - ip = (struct ip *)mp->b_cont->b_rptr; - } - else { - len = msgdsize(mp); - hlen = (len < (PPP_HDRLEN+MAX_IPHDR)) ? len : (PPP_HDRLEN+MAX_IPHDR); - PULLUP(mp, hlen); - if (mp == 0) { - DPRINT2("ppp/%d: filter, pullup failed, len=%d\n", - us->mn, hlen); - return 0; - } - ip = (struct ip *)(mp->b_rptr + PPP_HDRLEN); - } - - /* For IP traffic, certain packets (e.g., RIP) may be either - * 1. ignored - dropped completely - * 2. will not initiate a connection, but - * will be passed if a connection is currently up. - */ - for (pft=pktfilt_tab; pft->proto != -1; pft++) { - if (ip->ip_p == pft->proto) { - switch(pft->proto) { - case IPPROTO_UDP: - if (((struct udphdr *) &((int *)ip)[ip->ip_hl])->uh_dport - == htons(pft->port)) goto endfor; - break; - case IPPROTO_TCP: - if (((struct tcphdr *) &((int *)ip)[ip->ip_hl])->th_dport - == htons(pft->port)) goto endfor; - break; - } - } - } - endfor: - if (pft->proto != -1) { - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: found IP pkt, proto=0x%x (%d)\n", - us->mn, pft->proto, pft->port); - /* Discard if not connected, or if not pass_with_link_up */ - /* else, if link is up let go by, but don't update time */ - return pft->ok_if_link_up? -1: 0; - } - break; - } /* end switch (proto) */ - - return 1; -} -#endif /* FILTER_PACKETS */ - diff --git a/mdk-stage1/ppp/solaris/ppp.conf b/mdk-stage1/ppp/solaris/ppp.conf deleted file mode 100644 index e443a7aac..000000000 --- a/mdk-stage1/ppp/solaris/ppp.conf +++ /dev/null @@ -1 +0,0 @@ -name="ppp" parent="pseudo" instance=0; diff --git a/mdk-stage1/ppp/solaris/ppp_ahdlc.c b/mdk-stage1/ppp/solaris/ppp_ahdlc.c deleted file mode 100644 index d0b961258..000000000 --- a/mdk-stage1/ppp/solaris/ppp_ahdlc.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * ppp_ahdlc.c - STREAMS module for doing PPP asynchronous HDLC. - * - * Re-written by Adi Masputra <adi.masputra@sun.com>, based on - * the original ppp_ahdlc.c - * - * Copyright (c) 2000 by Sun Microsystems, Inc. - * 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. - * - * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF - * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES - * - * 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 HAS 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$ - */ - -/* - * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stream.h> -#include <sys/errno.h> - -#ifdef SVR4 -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/cmn_err.h> -#include <sys/ddi.h> -#else -#include <sys/user.h> -#ifdef __osf__ -#include <sys/cmn_err.h> -#endif -#endif /* SVR4 */ - -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -/* - * Right now, mutex is only enabled for Solaris 2.x - */ -#if defined(SOL2) -#define USE_MUTEX -#endif /* SOL2 */ - -/* - * intpointer_t and uintpointer_t are signed and unsigned integer types - * large enough to hold any data pointer; that is, data pointers can be - * assigned into or from these integer types without losing precision. - * On recent Solaris releases, these types are defined in sys/int_types.h, - * but not on SunOS 4.x or the earlier Solaris versions. - */ -#if defined(_LP64) || defined(_I32LPx) -typedef long intpointer_t; -typedef unsigned long uintpointer_t; -#else -typedef int intpointer_t; -typedef unsigned int uintpointer_t; -#endif - -MOD_OPEN_DECL(ahdlc_open); -MOD_CLOSE_DECL(ahdlc_close); -static int ahdlc_wput __P((queue_t *, mblk_t *)); -static int ahdlc_rput __P((queue_t *, mblk_t *)); -static void ahdlc_encode __P((queue_t *, mblk_t *)); -static void ahdlc_decode __P((queue_t *, mblk_t *)); -static int msg_byte __P((mblk_t *, unsigned int)); - -#if defined(SOL2) -/* - * Don't send HDLC start flag is last transmit is within 1.5 seconds - - * FLAG_TIME is defined is microseconds - */ -#define FLAG_TIME 1500 -#define ABS(x) (x >= 0 ? x : (-x)) -#endif /* SOL2 */ - -/* - * Extract byte i of message mp - */ -#define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ - msg_byte((mp), (i))) - -/* - * Is this LCP packet one we have to transmit using LCP defaults? - */ -#define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) - -/* - * Standard STREAMS declarations - */ -static struct module_info minfo = { - 0x7d23, "ppp_ahdl", 0, INFPSZ, 32768, 512 -}; - -static struct qinit rinit = { - ahdlc_rput, NULL, ahdlc_open, ahdlc_close, NULL, &minfo, NULL -}; - -static struct qinit winit = { - ahdlc_wput, NULL, NULL, NULL, NULL, &minfo, NULL -}; - -#if defined(SVR4) && !defined(SOL2) -int phdldevflag = 0; -#define ppp_ahdlcinfo phdlinfo -#endif /* defined(SVR4) && !defined(SOL2) */ - -struct streamtab ppp_ahdlcinfo = { - &rinit, /* ptr to st_rdinit */ - &winit, /* ptr to st_wrinit */ - NULL, /* ptr to st_muxrinit */ - NULL, /* ptr to st_muxwinit */ -#if defined(SUNOS4) - NULL /* ptr to ptr to st_modlist */ -#endif /* SUNOS4 */ -}; - -#if defined(SUNOS4) -int ppp_ahdlc_count = 0; /* open counter */ -#endif /* SUNOS4 */ - -/* - * Per-stream state structure - */ -typedef struct ahdlc_state { -#if defined(USE_MUTEX) - kmutex_t lock; /* lock for this structure */ -#endif /* USE_MUTEX */ - int flags; /* link flags */ - mblk_t *rx_buf; /* ptr to receive buffer */ - int rx_buf_size; /* receive buffer size */ - ushort_t infcs; /* calculated rx HDLC FCS */ - u_int32_t xaccm[8]; /* 256-bit xmit ACCM */ - u_int32_t raccm; /* 32-bit rcv ACCM */ - int mtu; /* interface MTU */ - int mru; /* link MRU */ - int unit; /* current PPP unit number */ - struct pppstat stats; /* statistic structure */ -#if defined(SOL2) - clock_t flag_time; /* time in usec between flags */ - clock_t lbolt; /* last updated lbolt */ -#endif /* SOL2 */ -} ahdlc_state_t; - -/* - * Values for flags - */ -#define ESCAPED 0x100 /* last saw escape char on input */ -#define IFLUSH 0x200 /* flushing input due to error */ - -/* - * RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also. - */ -#define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP) - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -static u_int32_t paritytab[8] = -{ - 0x96696996, 0x69969669, 0x69969669, 0x96696996, - 0x69969669, 0x96696996, 0x96696996, 0x69969669 -}; - -/* - * STREAMS module open (entry) point - */ -MOD_OPEN(ahdlc_open) -{ - ahdlc_state_t *state; - - /* - * Return if it's already opened - */ - if (q->q_ptr) { - return 0; - } - - /* - * This can only be opened as a module - */ - if (sflag != MODOPEN) { - return 0; - } - - state = (ahdlc_state_t *) ALLOC_NOSLEEP(sizeof(ahdlc_state_t)); - if (state == 0) - OPEN_ERROR(ENOSR); - bzero((caddr_t) state, sizeof(ahdlc_state_t)); - - q->q_ptr = (caddr_t) state; - WR(q)->q_ptr = (caddr_t) state; - -#if defined(USE_MUTEX) - mutex_init(&state->lock, NULL, MUTEX_DEFAULT, NULL); - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - state->xaccm[0] = ~0; /* escape 0x00 through 0x1f */ - state->xaccm[3] = 0x60000000; /* escape 0x7d and 0x7e */ - state->mru = PPP_MRU; /* default of 1500 bytes */ -#if defined(SOL2) - state->flag_time = drv_usectohz(FLAG_TIME); -#endif /* SOL2 */ - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - -#if defined(SUNOS4) - ppp_ahdlc_count++; -#endif /* SUNOS4 */ - - qprocson(q); - - return 0; -} - -/* - * STREAMS module close (exit) point - */ -MOD_CLOSE(ahdlc_close) -{ - ahdlc_state_t *state; - - qprocsoff(q); - - state = (ahdlc_state_t *) q->q_ptr; - - if (state == 0) { - DPRINT("state == 0 in ahdlc_close\n"); - return 0; - } - -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - if (state->rx_buf != 0) { - freemsg(state->rx_buf); - state->rx_buf = 0; - } - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); - mutex_destroy(&state->lock); -#endif /* USE_MUTEX */ - - FREE(q->q_ptr, sizeof(ahdlc_state_t)); - q->q_ptr = NULL; - OTHERQ(q)->q_ptr = NULL; - -#if defined(SUNOS4) - if (ppp_ahdlc_count) - ppp_ahdlc_count--; -#endif /* SUNOS4 */ - - return 0; -} - -/* - * Write side put routine - */ -static int -ahdlc_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - struct iocblk *iop; - int error; - mblk_t *np; - struct ppp_stats *psp; - - state = (ahdlc_state_t *) q->q_ptr; - if (state == 0) { - DPRINT("state == 0 in ahdlc_wput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_DATA: - /* - * A data packet - do character-stuffing and FCS, and - * send it onwards. - */ - ahdlc_encode(q, mp); - freemsg(mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - case PPPIO_XACCM: - if ((iop->ioc_count < sizeof(u_int32_t)) || - (iop->ioc_count > sizeof(ext_accm))) { - break; - } - if (mp->b_cont == 0) { - DPRINT1("ahdlc_wput/%d: PPPIO_XACCM b_cont = 0!\n", state->unit); - break; - } -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)state->xaccm, - iop->ioc_count); - state->xaccm[2] &= ~0x40000000; /* don't escape 0x5e */ - state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */ -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_RACCM: - if (iop->ioc_count != sizeof(u_int32_t)) - break; - if (mp->b_cont == 0) { - DPRINT1("ahdlc_wput/%d: PPPIO_RACCM b_cont = 0!\n", state->unit); - break; - } -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)&state->raccm, - sizeof(u_int32_t)); -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_GCLEAN: - np = allocb(sizeof(int), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - *(int *)np->b_wptr = state->flags & RCV_FLAGS; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - np->b_wptr += sizeof(int); - iop->ioc_count = sizeof(int); - error = 0; - break; - - case PPPIO_GETSTAT: - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - bzero((caddr_t)psp, sizeof(struct ppp_stats)); - psp->p = state->stats; - iop->ioc_count = sizeof(struct ppp_stats); - error = 0; - break; - - case PPPIO_LASTMOD: - /* we knew this anyway */ - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_count = 0; - iop->ioc_error = error; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->mtu = ((unsigned short *)mp->b_rptr)[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - freemsg(mp); - break; - case PPPCTL_MRU: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->mru = ((unsigned short *)mp->b_rptr)[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - freemsg(mp); - break; - case PPPCTL_UNIT: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->unit = mp->b_rptr[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - break; - default: - putnext(q, mp); - } - break; - - default: - putnext(q, mp); - } - - return 0; -} - -/* - * Read side put routine - */ -static int -ahdlc_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - - state = (ahdlc_state_t *) q->q_ptr; - if (state == 0) { - DPRINT("state == 0 in ahdlc_rput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_DATA: - ahdlc_decode(q, mp); - freemsg(mp); - break; - - case M_HANGUP: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - if (state->rx_buf != 0) { - /* XXX would like to send this up for debugging */ - freemsg(state->rx_buf); - state->rx_buf = 0; - } - state->flags = IFLUSH; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - return 0; -} - -/* - * Extract bit c from map m, to determine if c needs to be escaped - */ -#define IN_TX_MAP(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f))) - -static void -ahdlc_encode(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - u_int32_t *xaccm, loc_xaccm[8]; - ushort_t fcs; - size_t outmp_len; - mblk_t *outmp, *tmp; - uchar_t *dp, fcs_val; - int is_lcp, code; -#if defined(SOL2) - clock_t lbolt; -#endif /* SOL2 */ - - if (msgdsize(mp) < 4) { - return; - } - - state = (ahdlc_state_t *)q->q_ptr; -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - /* - * Allocate an output buffer large enough to handle a case where all - * characters need to be escaped - */ - outmp_len = (msgdsize(mp) << 1) + /* input block x 2 */ - (sizeof(fcs) << 2) + /* HDLC FCS x 4 */ - (sizeof(uchar_t) << 1); /* HDLC flags x 2 */ - - outmp = allocb(outmp_len, BPRI_MED); - if (outmp == NULL) { - state->stats.ppp_oerrors++; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - return; - } - -#if defined(SOL2) - /* - * Check if our last transmit happenned within flag_time, using - * the system's LBOLT value in clock ticks - */ - if (drv_getparm(LBOLT, &lbolt) != -1) { - if (ABS((clock_t)lbolt - state->lbolt) > state->flag_time) { - *outmp->b_wptr++ = PPP_FLAG; - } - state->lbolt = lbolt; - } else { - *outmp->b_wptr++ = PPP_FLAG; - } -#else - /* - * If the driver below still has a message to process, skip the - * HDLC flag, otherwise, put one in the beginning - */ - if (qsize(q->q_next) == 0) { - *outmp->b_wptr++ = PPP_FLAG; - } -#endif - - /* - * All control characters must be escaped for LCP packets with code - * values between 1 (Conf-Req) and 7 (Code-Rej). - */ - is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) && - (MSG_BYTE(mp, 1) == PPP_UI) && - (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) && - (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) && - LCP_USE_DFLT(mp)); - - xaccm = state->xaccm; - if (is_lcp) { - bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm)); - loc_xaccm[0] = ~0; /* force escape on 0x00 through 0x1f */ - xaccm = loc_xaccm; - } - - fcs = PPP_INITFCS; /* Initial FCS is 0xffff */ - - /* - * Process this block and the rest (if any) attached to the this one - */ - for (tmp = mp; tmp; tmp = tmp->b_cont) { - if (tmp->b_datap->db_type == M_DATA) { - for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) { - fcs = PPP_FCS(fcs, *dp); - if (IN_TX_MAP(*dp, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = *dp ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = *dp; - } - } - } else { - continue; /* skip if db_type is something other than M_DATA */ - } - } - - /* - * Append the HDLC FCS, making sure that escaping is done on any - * necessary bytes - */ - fcs_val = (fcs ^ 0xffff) & 0xff; - if (IN_TX_MAP(fcs_val, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = fcs_val; - } - - fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff; - if (IN_TX_MAP(fcs_val, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = fcs_val; - } - - /* - * And finally, append the HDLC flag, and send it away - */ - *outmp->b_wptr++ = PPP_FLAG; - - state->stats.ppp_obytes += msgdsize(outmp); - state->stats.ppp_opackets++; - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - - putnext(q, outmp); - return; -} - -/* - * Checks the 32-bit receive ACCM to see if the byte needs un-escaping - */ -#define IN_RX_MAP(c, m) ((((unsigned int) (uchar_t) (c)) < 0x20) && \ - (m) & (1 << (c))) - - -/* - * Process received characters. - */ -static void -ahdlc_decode(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - mblk_t *om; - uchar_t *dp; - ushort_t fcs; -#if defined(SOL2) - mblk_t *zmp; -#endif /* SOL2 */ - -#if defined(SOL2) - /* - * In case the driver (or something below) doesn't send - * data upstream in one message block, concatenate everything - */ - if (!((mp->b_wptr - mp->b_rptr == msgdsize(mp)) && - ((intpointer_t)mp->b_rptr % sizeof(intpointer_t) == 0))) { - - zmp = msgpullup(mp, -1); - freemsg(mp); - mp = zmp; - if (mp == 0) - return; - } -#endif /* SOL2 */ - - state = (ahdlc_state_t *) q->q_ptr; - -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - state->stats.ppp_ibytes += msgdsize(mp); - - for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) { - - /* - * This should detect the lack of 8-bit communication channel - * which is necessary for PPP to work. In addition, it also - * checks on the parity. - */ - if (*dp & 0x80) - state->flags |= RCV_B7_1; - else - state->flags |= RCV_B7_0; - - if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f))) - state->flags |= RCV_ODDP; - else - state->flags |= RCV_EVNP; - - /* - * So we have a HDLC flag ... - */ - if (*dp == PPP_FLAG) { - - /* - * If we think that it marks the beginning of the frame, - * then continue to process the next octects - */ - if ((state->flags & IFLUSH) || - (state->rx_buf == 0) || - (msgdsize(state->rx_buf) == 0)) { - - state->flags &= ~IFLUSH; - continue; - } - - /* - * We get here because the above condition isn't true, - * in which case the HDLC flag was there to mark the end - * of the frame (or so we think) - */ - om = state->rx_buf; - - if (state->infcs == PPP_GOODFCS) { - state->stats.ppp_ipackets++; - adjmsg(om, -PPP_FCSLEN); - putnext(q, om); - } else { - DPRINT2("ppp%d: bad fcs (len=%d)\n", - state->unit, msgdsize(state->rx_buf)); - freemsg(state->rx_buf); - state->flags &= ~(IFLUSH | ESCAPED); - state->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - } - - state->rx_buf = 0; - continue; - } - - if (state->flags & IFLUSH) { - continue; - } - - /* - * Allocate a receive buffer, large enough to store a frame (after - * un-escaping) of at least 1500 octets. If MRU is negotiated to - * be more than the default, then allocate that much. In addition, - * we add an extra 32-bytes for a fudge factor - */ - if (state->rx_buf == 0) { - state->rx_buf_size = (state->mru < PPP_MRU ? PPP_MRU : state->mru); - state->rx_buf_size += (sizeof(u_int32_t) << 3); - state->rx_buf = allocb(state->rx_buf_size, BPRI_MED); - - /* - * If allocation fails, try again on the next frame - */ - if (state->rx_buf == 0) { - state->flags |= IFLUSH; - continue; - } - state->flags &= ~(IFLUSH | ESCAPED); - state->infcs = PPP_INITFCS; - } - - if (*dp == PPP_ESCAPE) { - state->flags |= ESCAPED; - continue; - } - - /* - * Make sure we un-escape the necessary characters, as well as the - * ones in our receive async control character map - */ - if (state->flags & ESCAPED) { - *dp ^= PPP_TRANS; - state->flags &= ~ESCAPED; - } else if (IN_RX_MAP(*dp, state->raccm)) - continue; - - /* - * Unless the peer lied to us about the negotiated MRU, we should - * never get a frame which is too long. If it happens, toss it away - * and grab the next incoming one - */ - if (msgdsize(state->rx_buf) < state->rx_buf_size) { - state->infcs = PPP_FCS(state->infcs, *dp); - *state->rx_buf->b_wptr++ = *dp; - } else { - DPRINT2("ppp%d: frame too long (%d)\n", - state->unit, msgdsize(state->rx_buf)); - freemsg(state->rx_buf); - state->rx_buf = 0; - state->flags |= IFLUSH; - } - } - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ -} - -static int -msg_byte(mp, i) - mblk_t *mp; - unsigned int i; -{ - while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) - mp = mp->b_cont; - if (mp == 0) - return -1; - return mp->b_rptr[i]; -} diff --git a/mdk-stage1/ppp/solaris/ppp_ahdlc_mod.c b/mdk-stage1/ppp/solaris/ppp_ahdlc_mod.c deleted file mode 100644 index f81be8abb..000000000 --- a/mdk-stage1/ppp/solaris/ppp_ahdlc_mod.c +++ /dev/null @@ -1,49 +0,0 @@ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> - -extern struct streamtab ppp_ahdlcinfo; - -static struct fmodsw fsw = { - "ppp_ahdl", - &ppp_ahdlcinfo, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP async HDLC module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; - -/* - * Entry points for modloading. - */ -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} diff --git a/mdk-stage1/ppp/solaris/ppp_comp.c b/mdk-stage1/ppp/solaris/ppp_comp.c deleted file mode 100644 index f6eef5ab1..000000000 --- a/mdk-stage1/ppp/solaris/ppp_comp.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * ppp_comp.c - STREAMS module for kernel-level compression and CCP support. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS 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$ - */ - -/* - * This file is used under SVR4, Solaris 2, SunOS 4, and Digital UNIX. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/stream.h> - -#ifdef SVR4 -#include <sys/conf.h> -#include <sys/cmn_err.h> -#include <sys/ddi.h> -#else -#include <sys/user.h> -#ifdef __osf__ -#include <sys/cmn_err.h> -#endif -#endif /* SVR4 */ - -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -#ifdef __osf__ -#include <sys/mbuf.h> -#include <sys/protosw.h> -#endif - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <net/vjcompress.h> - -#define PACKETPTR mblk_t * -#include <net/ppp-comp.h> - -MOD_OPEN_DECL(ppp_comp_open); -MOD_CLOSE_DECL(ppp_comp_close); -static int ppp_comp_rput __P((queue_t *, mblk_t *)); -static int ppp_comp_rsrv __P((queue_t *)); -static int ppp_comp_wput __P((queue_t *, mblk_t *)); -static int ppp_comp_wsrv __P((queue_t *)); -static void ppp_comp_ccp __P((queue_t *, mblk_t *, int)); -static int msg_byte __P((mblk_t *, unsigned int)); - -/* Extract byte i of message mp. */ -#define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ - msg_byte((mp), (i))) - -/* Is this LCP packet one we have to transmit using LCP defaults? */ -#define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) - -#define PPP_COMP_ID 0xbadf -static struct module_info minfo = { -#ifdef PRIOQ - PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16512, 16384, -#else - PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16384, 4096, -#endif -}; - -static struct qinit r_init = { - ppp_comp_rput, ppp_comp_rsrv, ppp_comp_open, ppp_comp_close, - NULL, &minfo, NULL -}; - -static struct qinit w_init = { - ppp_comp_wput, ppp_comp_wsrv, NULL, NULL, NULL, &minfo, NULL -}; - -#if defined(SVR4) && !defined(SOL2) -int pcmpdevflag = 0; -#define ppp_compinfo pcmpinfo -#endif -struct streamtab ppp_compinfo = { - &r_init, &w_init, NULL, NULL -}; - -int ppp_comp_count; /* number of module instances in use */ - -#ifdef __osf__ - -static void ppp_comp_alloc __P((comp_state_t *)); -typedef struct memreq { - unsigned char comp_opts[20]; - int cmd; - int thread_status; - char *returned_mem; -} memreq_t; - -#endif - -typedef struct comp_state { - int flags; - int mru; - int mtu; - int unit; - struct compressor *xcomp; - void *xstate; - struct compressor *rcomp; - void *rstate; - struct vjcompress vj_comp; - int vj_last_ierrors; - struct pppstat stats; -#ifdef __osf__ - memreq_t memreq; - thread_t thread; -#endif -} comp_state_t; - - -#ifdef __osf__ -extern task_t first_task; -#endif - -/* Bits in flags are as defined in pppio.h. */ -#define CCP_ERR (CCP_ERROR | CCP_FATALERROR) -#define LAST_MOD 0x1000000 /* no ppp modules below us */ -#define DBGLOG 0x2000000 /* log debugging stuff */ - -#define MAX_IPHDR 128 /* max TCP/IP header size */ -#define MAX_VJHDR 20 /* max VJ compressed header size (?) */ - -#undef MIN /* just in case */ -#define MIN(a, b) ((a) < (b)? (a): (b)) - -/* - * List of compressors we know about. - */ - -#if DO_BSD_COMPRESS -extern struct compressor ppp_bsd_compress; -#endif -#if DO_DEFLATE -extern struct compressor ppp_deflate, ppp_deflate_draft; -#endif - -struct compressor *ppp_compressors[] = { -#if DO_BSD_COMPRESS - &ppp_bsd_compress, -#endif -#if DO_DEFLATE - &ppp_deflate, - &ppp_deflate_draft, -#endif - NULL -}; - -/* - * STREAMS module entry points. - */ -MOD_OPEN(ppp_comp_open) -{ - comp_state_t *cp; -#ifdef __osf__ - thread_t thread; -#endif - - if (q->q_ptr == NULL) { - cp = (comp_state_t *) ALLOC_SLEEP(sizeof(comp_state_t)); - if (cp == NULL) - OPEN_ERROR(ENOSR); - bzero((caddr_t)cp, sizeof(comp_state_t)); - WR(q)->q_ptr = q->q_ptr = (caddr_t) cp; - cp->mru = PPP_MRU; - cp->mtu = PPP_MTU; - cp->xstate = NULL; - cp->rstate = NULL; - vj_compress_init(&cp->vj_comp, -1); -#ifdef __osf__ - if (!(thread = kernel_thread_w_arg(first_task, ppp_comp_alloc, (void *)cp))) - OPEN_ERROR(ENOSR); - cp->thread = thread; -#endif - ++ppp_comp_count; - qprocson(q); - } - return 0; -} - -MOD_CLOSE(ppp_comp_close) -{ - comp_state_t *cp; - - qprocsoff(q); - cp = (comp_state_t *) q->q_ptr; - if (cp != NULL) { - if (cp->xstate != NULL) - (*cp->xcomp->comp_free)(cp->xstate); - if (cp->rstate != NULL) - (*cp->rcomp->decomp_free)(cp->rstate); -#ifdef __osf__ - if (!cp->thread) - printf("ppp_comp_close: NULL thread!\n"); - else - thread_terminate(cp->thread); -#endif - FREE(cp, sizeof(comp_state_t)); - q->q_ptr = NULL; - OTHERQ(q)->q_ptr = NULL; - --ppp_comp_count; - } - return 0; -} - -#ifdef __osf__ - -/* thread for calling back to a compressor's memory allocator - * Needed for Digital UNIX since it's VM can't handle requests - * for large amounts of memory without blocking. The thread - * provides a context in which we can call a memory allocator - * that may block. - */ -static void -ppp_comp_alloc(comp_state_t *cp) -{ - int len, cmd; - unsigned char *compressor_options; - thread_t thread; - void *(*comp_allocator)(); - - -#if defined(MAJOR_VERSION) && (MAJOR_VERSION <= 2) - - /* In 2.x and earlier the argument gets passed - * in the thread structure itself. Yuck. - */ - thread = current_thread(); - cp = thread->reply_port; - thread->reply_port = PORT_NULL; - -#endif - - for (;;) { - assert_wait((vm_offset_t)&cp->memreq.thread_status, TRUE); - thread_block(); - - if (thread_should_halt(current_thread())) - thread_halt_self(); - cmd = cp->memreq.cmd; - compressor_options = &cp->memreq.comp_opts[0]; - len = compressor_options[1]; - if (cmd == PPPIO_XCOMP) { - cp->memreq.returned_mem = cp->xcomp->comp_alloc(compressor_options, len); - if (!cp->memreq.returned_mem) { - cp->memreq.thread_status = ENOSR; - } else { - cp->memreq.thread_status = 0; - } - } else { - cp->memreq.returned_mem = cp->rcomp->decomp_alloc(compressor_options, len); - if (!cp->memreq.returned_mem) { - cp->memreq.thread_status = ENOSR; - } else { - cp->memreq.thread_status = 0; - } - } - } -} - -#endif /* __osf__ */ - -/* here's the deal with memory allocation under Digital UNIX. - * Some other may also benefit from this... - * We can't ask for huge chunks of memory in a context where - * the caller can't be put to sleep (like, here.) The alloc - * is likely to fail. Instead we do this: the first time we - * get called, kick off a thread to do the allocation. Return - * immediately to the caller with EAGAIN, as an indication that - * they should send down the ioctl again. By the time the - * second call comes in it's likely that the memory allocation - * thread will have returned with the requested memory. We will - * continue to return EAGAIN however until the thread has completed. - * When it has, we return zero (and the memory) if the allocator - * was successful and ENOSR otherwise. - * - * Callers of the RCOMP and XCOMP ioctls are encouraged (but not - * required) to loop for some number of iterations with a small - * delay in the loop body (for instance a 1/10-th second "sleep" - * via select.) - */ -static int -ppp_comp_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - struct iocblk *iop; - comp_state_t *cp; - int error, len, n; - int flags, mask; - mblk_t *np; - struct compressor **comp; - struct ppp_stats *psp; - struct ppp_comp_stats *csp; - unsigned char *opt_data; - int nxslots, nrslots; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_wput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - - case PPPIO_CFLAGS: - /* set/get CCP state */ - if (iop->ioc_count != 2 * sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_CFLAGS b_cont = 0!\n", cp->unit); - break; - } - flags = ((int *) mp->b_cont->b_rptr)[0]; - mask = ((int *) mp->b_cont->b_rptr)[1]; - cp->flags = (cp->flags & ~mask) | (flags & mask); - if ((mask & CCP_ISOPEN) && (flags & CCP_ISOPEN) == 0) { - if (cp->xstate != NULL) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = NULL; - } - if (cp->rstate != NULL) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - cp->flags &= ~CCP_ISUP; - } - error = 0; - iop->ioc_count = sizeof(int); - ((int *) mp->b_cont->b_rptr)[0] = cp->flags; - mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int); - break; - - case PPPIO_VJINIT: - /* - * Initialize VJ compressor/decompressor - */ - if (iop->ioc_count != 2) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_VJINIT b_cont = 0!\n", cp->unit); - break; - } - nxslots = mp->b_cont->b_rptr[0] + 1; - nrslots = mp->b_cont->b_rptr[1] + 1; - if (nxslots > MAX_STATES || nrslots > MAX_STATES) - break; - vj_compress_init(&cp->vj_comp, nxslots); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_XCOMP: - case PPPIO_RCOMP: - if (iop->ioc_count <= 0) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_[XR]COMP b_cont = 0!\n", cp->unit); - break; - } - opt_data = mp->b_cont->b_rptr; - len = mp->b_cont->b_wptr - opt_data; - if (len > iop->ioc_count) - len = iop->ioc_count; - if (opt_data[1] < 2 || opt_data[1] > len) - break; - for (comp = ppp_compressors; *comp != NULL; ++comp) - if ((*comp)->compress_proto == opt_data[0]) { - /* here's the handler! */ - error = 0; -#ifndef __osf__ - if (iop->ioc_cmd == PPPIO_XCOMP) { - /* A previous call may have fetched memory for a compressor - * that's now being retired or reset. Free it using it's - * mechanism for freeing stuff. - */ - if (cp->xstate != NULL) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = NULL; - } - cp->xcomp = *comp; - cp->xstate = (*comp)->comp_alloc(opt_data, len); - if (cp->xstate == NULL) - error = ENOSR; - } else { - if (cp->rstate != NULL) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - cp->rcomp = *comp; - cp->rstate = (*comp)->decomp_alloc(opt_data, len); - if (cp->rstate == NULL) - error = ENOSR; - } -#else - if ((error = cp->memreq.thread_status) != EAGAIN) - if (iop->ioc_cmd == PPPIO_XCOMP) { - if (cp->xstate) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = 0; - } - /* sanity check for compressor options - */ - if (sizeof (cp->memreq.comp_opts) < len) { - printf("can't handle options for compressor %d (%d)\n", opt_data[0], - opt_data[1]); - cp->memreq.thread_status = ENOSR; - cp->memreq.returned_mem = 0; - } - /* fill in request for the thread and kick it off - */ - if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { - bcopy(opt_data, cp->memreq.comp_opts, len); - cp->memreq.cmd = PPPIO_XCOMP; - cp->xcomp = *comp; - error = cp->memreq.thread_status = EAGAIN; - thread_wakeup((vm_offset_t)&cp->memreq.thread_status); - } else { - cp->xstate = cp->memreq.returned_mem; - cp->memreq.returned_mem = 0; - cp->memreq.thread_status = 0; - } - } else { - if (cp->rstate) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - if (sizeof (cp->memreq.comp_opts) < len) { - printf("can't handle options for compressor %d (%d)\n", opt_data[0], - opt_data[1]); - cp->memreq.thread_status = ENOSR; - cp->memreq.returned_mem = 0; - } - if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { - bcopy(opt_data, cp->memreq.comp_opts, len); - cp->memreq.cmd = PPPIO_RCOMP; - cp->rcomp = *comp; - error = cp->memreq.thread_status = EAGAIN; - thread_wakeup((vm_offset_t)&cp->memreq.thread_status); - } else { - cp->rstate = cp->memreq.returned_mem; - cp->memreq.returned_mem = 0; - cp->memreq.thread_status = 0; - } - } -#endif - break; - } - iop->ioc_count = 0; - break; - - case PPPIO_GETSTAT: - if ((cp->flags & LAST_MOD) == 0) { - error = -1; /* let the ppp_ahdl module handle it */ - break; - } - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - iop->ioc_count = sizeof(struct ppp_stats); - psp->p = cp->stats; - psp->vj = cp->vj_comp.stats; - error = 0; - break; - - case PPPIO_GETCSTAT: - np = allocb(sizeof(struct ppp_comp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - csp = (struct ppp_comp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_comp_stats); - iop->ioc_count = sizeof(struct ppp_comp_stats); - bzero((caddr_t)csp, sizeof(struct ppp_comp_stats)); - if (cp->xstate != 0) - (*cp->xcomp->comp_stat)(cp->xstate, &csp->c); - if (cp->rstate != 0) - (*cp->rcomp->decomp_stat)(cp->rstate, &csp->d); - error = 0; - break; - - case PPPIO_DEBUG: - if (iop->ioc_count != sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_DEBUG b_cont = 0!\n", cp->unit); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n == PPPDBG_LOG + PPPDBG_COMP) { - DPRINT1("ppp_comp%d: debug log enabled\n", cp->unit); - cp->flags |= DBGLOG; - error = 0; - iop->ioc_count = 0; - } else { - error = -1; - } - break; - - case PPPIO_LASTMOD: - cp->flags |= LAST_MOD; - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_error = error; - iop->ioc_count = 0; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: - cp->mtu = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_MRU: - cp->mru = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_UNIT: - cp->unit = mp->b_rptr[1]; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_wsrv(q) - queue_t *q; -{ - mblk_t *mp, *cmp = NULL; - comp_state_t *cp; - int len, proto, type, hlen, code; - struct ip *ip; - unsigned char *vjhdr, *dp; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_wsrv\n"); - return 0; - } - - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ -#ifdef PRIOQ - if (!bcanputnext(q,mp->b_band)) -#else - if (!canputnext(q)) -#endif PRIOQ - { - putbq(q, mp); - break; - } - - /* - * First check the packet length and work out what the protocol is. - */ - len = msgdsize(mp); - if (len < PPP_HDRLEN) { - DPRINT1("ppp_comp_wsrv: bogus short packet (%d)\n", len); - freemsg(mp); - cp->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - continue; - } - proto = (MSG_BYTE(mp, 2) << 8) + MSG_BYTE(mp, 3); - - /* - * Make sure we've got enough data in the first mblk - * and that we are its only user. - */ - if (proto == PPP_CCP) - hlen = len; - else if (proto == PPP_IP) - hlen = PPP_HDRLEN + MAX_IPHDR; - else - hlen = PPP_HDRLEN; - if (hlen > len) - hlen = len; - if (mp->b_wptr < mp->b_rptr + hlen || mp->b_datap->db_ref > 1) { - PULLUP(mp, hlen); - if (mp == 0) { - DPRINT1("ppp_comp_wsrv: pullup failed (%d)\n", hlen); - cp->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - continue; - } - } - - /* - * Do VJ compression if requested. - */ - if (proto == PPP_IP && (cp->flags & COMP_VJC)) { - ip = (struct ip *) (mp->b_rptr + PPP_HDRLEN); - if (ip->ip_p == IPPROTO_TCP) { - type = vj_compress_tcp(ip, len - PPP_HDRLEN, &cp->vj_comp, - (cp->flags & COMP_VJCCID), &vjhdr); - switch (type) { - case TYPE_UNCOMPRESSED_TCP: - mp->b_rptr[3] = proto = PPP_VJC_UNCOMP; - break; - case TYPE_COMPRESSED_TCP: - dp = vjhdr - PPP_HDRLEN; - dp[1] = mp->b_rptr[1]; /* copy control field */ - dp[0] = mp->b_rptr[0]; /* copy address field */ - dp[2] = 0; /* set protocol field */ - dp[3] = proto = PPP_VJC_COMP; - mp->b_rptr = dp; - break; - } - } - } - - /* - * Do packet compression if enabled. - */ - if (proto == PPP_CCP) - ppp_comp_ccp(q, mp, 0); - else if (proto != PPP_LCP && (cp->flags & CCP_COMP_RUN) - && cp->xstate != NULL) { - len = msgdsize(mp); - (*cp->xcomp->compress)(cp->xstate, &cmp, mp, len, - (cp->flags & CCP_ISUP? cp->mtu + PPP_HDRLEN: 0)); - if (cmp != NULL) { -#ifdef PRIOQ - cmp->b_band=mp->b_band; -#endif PRIOQ - freemsg(mp); - mp = cmp; - } - } - - /* - * Do address/control and protocol compression if enabled. - */ - if ((cp->flags & COMP_AC) - && !(proto == PPP_LCP && LCP_USE_DFLT(mp))) { - mp->b_rptr += 2; /* drop the address & ctrl fields */ - if (proto < 0x100 && (cp->flags & COMP_PROT)) - ++mp->b_rptr; /* drop the high protocol byte */ - } else if (proto < 0x100 && (cp->flags & COMP_PROT)) { - /* shuffle up the address & ctrl fields */ - mp->b_rptr[2] = mp->b_rptr[1]; - mp->b_rptr[1] = mp->b_rptr[0]; - ++mp->b_rptr; - } - - cp->stats.ppp_opackets++; - cp->stats.ppp_obytes += msgdsize(mp); - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - comp_state_t *cp; - struct iocblk *iop; - struct ppp_stats *psp; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_rput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCACK: - iop = (struct iocblk *) mp->b_rptr; - switch (iop->ioc_cmd) { - case PPPIO_GETSTAT: - /* - * Catch this on the way back from the ppp_ahdl module - * so we can fill in the VJ stats. - */ - if (mp->b_cont == 0 || iop->ioc_count != sizeof(struct ppp_stats)) - break; - psp = (struct ppp_stats *) mp->b_cont->b_rptr; - psp->vj = cp->vj_comp.stats; - break; - } - putnext(q, mp); - break; - - case M_CTL: - switch (mp->b_rptr[0]) { - case PPPCTL_IERROR: - ++cp->stats.ppp_ierrors; - break; - case PPPCTL_OERROR: - ++cp->stats.ppp_oerrors; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_rsrv(q) - queue_t *q; -{ - int proto, rv, i; - mblk_t *mp, *dmp = NULL, *np; - uchar_t *dp, *iphdr; - comp_state_t *cp; - int len, hlen, vjlen; - u_int iphlen; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_rsrv\n"); - return 0; - } - - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ - if (!canputnext(q)) { - putbq(q, mp); - break; - } - - len = msgdsize(mp); - cp->stats.ppp_ibytes += len; - cp->stats.ppp_ipackets++; - - /* - * First work out the protocol and where the PPP header ends. - */ - i = 0; - proto = MSG_BYTE(mp, 0); - if (proto == PPP_ALLSTATIONS) { - i = 2; - proto = MSG_BYTE(mp, 2); - } - if ((proto & 1) == 0) { - ++i; - proto = (proto << 8) + MSG_BYTE(mp, i); - } - hlen = i + 1; - - /* - * Now reconstruct a complete, contiguous PPP header at the - * start of the packet. - */ - if (hlen < ((cp->flags & DECOMP_AC)? 0: 2) - + ((cp->flags & DECOMP_PROT)? 1: 2)) { - /* count these? */ - goto bad; - } - if (mp->b_rptr + hlen > mp->b_wptr) { - adjmsg(mp, hlen); /* XXX check this call */ - hlen = 0; - } - if (hlen != PPP_HDRLEN) { - /* - * We need to put some bytes on the front of the packet - * to make a full-length PPP header. - * If we can put them in *mp, we do, otherwise we - * tack another mblk on the front. - * XXX we really shouldn't need to carry around - * the address and control at this stage. - */ - dp = mp->b_rptr + hlen - PPP_HDRLEN; - if (dp < mp->b_datap->db_base || mp->b_datap->db_ref > 1) { - np = allocb(PPP_HDRLEN, BPRI_MED); - if (np == 0) - goto bad; - np->b_cont = mp; - mp->b_rptr += hlen; - mp = np; - dp = mp->b_wptr; - mp->b_wptr += PPP_HDRLEN; - } else - mp->b_rptr = dp; - - dp[0] = PPP_ALLSTATIONS; - dp[1] = PPP_UI; - dp[2] = proto >> 8; - dp[3] = proto; - } - - /* - * Now see if we have a compressed packet to decompress, - * or a CCP packet to take notice of. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_CCP) { - len = msgdsize(mp); - if (mp->b_wptr < mp->b_rptr + len) { - PULLUP(mp, len); - if (mp == 0) - goto bad; - } - ppp_comp_ccp(q, mp, 1); - } else if (proto == PPP_COMP) { - if ((cp->flags & CCP_ISUP) - && (cp->flags & CCP_DECOMP_RUN) && cp->rstate - && (cp->flags & CCP_ERR) == 0) { - rv = (*cp->rcomp->decompress)(cp->rstate, mp, &dmp); - switch (rv) { - case DECOMP_OK: - freemsg(mp); - mp = dmp; - if (mp == NULL) { - /* no error, but no packet returned either. */ - continue; - } - break; - case DECOMP_ERROR: - cp->flags |= CCP_ERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - case DECOMP_FATALERROR: - cp->flags |= CCP_FATALERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - } - } - } else if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->incomp)(cp->rstate, mp); - } - - /* - * Now do VJ decompression. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_VJC_COMP || proto == PPP_VJC_UNCOMP) { - len = msgdsize(mp) - PPP_HDRLEN; - if ((cp->flags & DECOMP_VJC) == 0 || len <= 0) - goto bad; - - /* - * Advance past the ppp header. - * Here we assume that the whole PPP header is in the first mblk. - */ - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - if (dp >= mp->b_wptr) { - np = np->b_cont; - dp = np->b_rptr; - } - - /* - * Make sure we have sufficient contiguous data at this point. - */ - hlen = (proto == PPP_VJC_COMP)? MAX_VJHDR: MAX_IPHDR; - if (hlen > len) - hlen = len; - if (np->b_wptr < dp + hlen || np->b_datap->db_ref > 1) { - PULLUP(mp, hlen + PPP_HDRLEN); - if (mp == 0) - goto bad; - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - } - - if (proto == PPP_VJC_COMP) { - /* - * Decompress VJ-compressed packet. - * First reset compressor if an input error has occurred. - */ - if (cp->stats.ppp_ierrors != cp->vj_last_ierrors) { - if (cp->flags & DBGLOG) - DPRINT1("ppp%d: resetting VJ\n", cp->unit); - vj_uncompress_err(&cp->vj_comp); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - } - - vjlen = vj_uncompress_tcp(dp, np->b_wptr - dp, len, - &cp->vj_comp, &iphdr, &iphlen); - if (vjlen < 0) { - if (cp->flags & DBGLOG) - DPRINT2("ppp%d: vj_uncomp_tcp failed, pkt len %d\n", - cp->unit, len); - ++cp->vj_last_ierrors; /* so we don't reset next time */ - goto bad; - } - - /* drop ppp and vj headers off */ - if (mp != np) { - freeb(mp); - mp = np; - } - mp->b_rptr = dp + vjlen; - - /* allocate a new mblk for the ppp and ip headers */ - if ((np = allocb(iphlen + PPP_HDRLEN + 4, BPRI_MED)) == 0) - goto bad; - dp = np->b_rptr; /* prepend mblk with TCP/IP hdr */ - dp[0] = PPP_ALLSTATIONS; /* reconstruct PPP header */ - dp[1] = PPP_UI; - dp[2] = PPP_IP >> 8; - dp[3] = PPP_IP; - bcopy((caddr_t)iphdr, (caddr_t)dp + PPP_HDRLEN, iphlen); - np->b_wptr = dp + iphlen + PPP_HDRLEN; - np->b_cont = mp; - - /* XXX there seems to be a bug which causes panics in strread - if we make an mbuf with only the IP header in it :-( */ - if (mp->b_wptr - mp->b_rptr > 4) { - bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, 4); - mp->b_rptr += 4; - np->b_wptr += 4; - } else { - bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, - mp->b_wptr - mp->b_rptr); - np->b_wptr += mp->b_wptr - mp->b_rptr; - np->b_cont = mp->b_cont; - freeb(mp); - } - - mp = np; - - } else { - /* - * "Decompress" a VJ-uncompressed packet. - */ - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - if (!vj_uncompress_uncomp(dp, hlen, &cp->vj_comp)) { - if (cp->flags & DBGLOG) - DPRINT2("ppp%d: vj_uncomp_uncomp failed, pkt len %d\n", - cp->unit, len); - ++cp->vj_last_ierrors; /* don't need to reset next time */ - goto bad; - } - mp->b_rptr[3] = PPP_IP; /* fix up the PPP protocol field */ - } - } - - putnext(q, mp); - continue; - - bad: - if (mp != 0) - freemsg(mp); - cp->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - } - - return 0; -} - -/* - * Handle a CCP packet being sent or received. - * Here all the data in the packet is in a single mbuf. - */ -static void -ppp_comp_ccp(q, mp, rcvd) - queue_t *q; - mblk_t *mp; - int rcvd; -{ - int len, clen; - comp_state_t *cp; - unsigned char *dp; - - len = msgdsize(mp); - if (len < PPP_HDRLEN + CCP_HDRLEN) - return; - - cp = (comp_state_t *) q->q_ptr; - dp = mp->b_rptr + PPP_HDRLEN; - len -= PPP_HDRLEN; - clen = CCP_LENGTH(dp); - if (clen > len) - return; - - switch (CCP_CODE(dp)) { - case CCP_CONFREQ: - case CCP_TERMREQ: - case CCP_TERMACK: - cp->flags &= ~CCP_ISUP; - break; - - case CCP_CONFACK: - if ((cp->flags & (CCP_ISOPEN | CCP_ISUP)) == CCP_ISOPEN - && clen >= CCP_HDRLEN + CCP_OPT_MINLEN - && clen >= CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) { - if (!rcvd) { - if (cp->xstate != NULL - && (*cp->xcomp->comp_init) - (cp->xstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, ((cp->flags & DBGLOG) != 0))) - cp->flags |= CCP_COMP_RUN; - } else { - if (cp->rstate != NULL - && (*cp->rcomp->decomp_init) - (cp->rstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, cp->mru, ((cp->flags & DBGLOG) != 0))) - cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN; - } - } - break; - - case CCP_RESETACK: - if (cp->flags & CCP_ISUP) { - if (!rcvd) { - if (cp->xstate && (cp->flags & CCP_COMP_RUN)) - (*cp->xcomp->comp_reset)(cp->xstate); - } else { - if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->decomp_reset)(cp->rstate); - cp->flags &= ~CCP_ERROR; - } - } - } - break; - } -} - -#if 0 -dump_msg(mp) - mblk_t *mp; -{ - dblk_t *db; - - while (mp != 0) { - db = mp->b_datap; - DPRINT2("mp=%x cont=%x ", mp, mp->b_cont); - DPRINT3("rptr=%x wptr=%x datap=%x\n", mp->b_rptr, mp->b_wptr, db); - DPRINT2(" base=%x lim=%x", db->db_base, db->db_lim); - DPRINT2(" ref=%d type=%d\n", db->db_ref, db->db_type); - mp = mp->b_cont; - } -} -#endif - -static int -msg_byte(mp, i) - mblk_t *mp; - unsigned int i; -{ - while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) - mp = mp->b_cont; - if (mp == 0) - return -1; - return mp->b_rptr[i]; -} diff --git a/mdk-stage1/ppp/solaris/ppp_comp_mod.c b/mdk-stage1/ppp/solaris/ppp_comp_mod.c deleted file mode 100644 index 83ff8e252..000000000 --- a/mdk-stage1/ppp/solaris/ppp_comp_mod.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ppp_comp_mod.c - modload support for PPP compression 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$ - */ - -/* - * This file is used under Solaris 2. - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> - -extern struct streamtab ppp_compinfo; - -static struct fmodsw fsw = { - "ppp_comp", - &ppp_compinfo, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP compression module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; - -/* - * Entry points for modloading. - */ -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} diff --git a/mdk-stage1/ppp/solaris/ppp_mod.c b/mdk-stage1/ppp/solaris/ppp_mod.c deleted file mode 100644 index a4b1538a5..000000000 --- a/mdk-stage1/ppp/solaris/ppp_mod.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * ppp_mod.c - modload support for PPP pseudo-device driver. - * - * 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$ - */ - -/* - * This file is used under Solaris 2. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> -#include <sys/ksynch.h> - -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -static int ppp_identify __P((dev_info_t *)); -static int ppp_attach __P((dev_info_t *, ddi_attach_cmd_t)); -static int ppp_detach __P((dev_info_t *, ddi_detach_cmd_t)); -static int ppp_devinfo __P((dev_info_t *, ddi_info_cmd_t, void *, void **)); - -extern struct streamtab pppinfo; -extern krwlock_t ppp_lower_lock; - -static dev_info_t *ppp_dip; - -static struct cb_ops cb_ppp_ops = { - nulldev, nulldev, nodev, nodev, /* cb_open, ... */ - nodev, nodev, nodev, nodev, /* cb_dump, ... */ - nodev, nodev, nodev, nochpoll, /* cb_devmap, ... */ - ddi_prop_op, /* cb_prop_op */ - &pppinfo, /* cb_stream */ - D_NEW|D_MP|D_MTQPAIR|D_MTOUTPERIM|D_MTOCEXCL /* cb_flag */ -}; - -static struct dev_ops ppp_ops = { - DEVO_REV, /* devo_rev */ - 0, /* devo_refcnt */ - ppp_devinfo, /* devo_getinfo */ - ppp_identify, /* devo_identify */ - nulldev, /* devo_probe */ - ppp_attach, /* devo_attach */ - ppp_detach, /* devo_detach */ - nodev, /* devo_reset */ - &cb_ppp_ops, /* devo_cb_ops */ - NULL /* devo_bus_ops */ -}; - -/* - * Module linkage information - */ - -static struct modldrv modldrv = { - &mod_driverops, /* says this is a pseudo driver */ - "PPP-2.3 multiplexing driver", - &ppp_ops /* driver ops */ -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modldrv, - NULL -}; - -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} - -static int -ppp_identify(dip) - dev_info_t *dip; -{ - return strcmp(ddi_get_name(dip), "ppp") == 0? DDI_IDENTIFIED: - DDI_NOT_IDENTIFIED; -} - -static int -ppp_attach(dip, cmd) - dev_info_t *dip; - ddi_attach_cmd_t cmd; -{ - - if (cmd != DDI_ATTACH) - return DDI_FAILURE; - if (ddi_create_minor_node(dip, "ppp", S_IFCHR, 0, DDI_PSEUDO, CLONE_DEV) - == DDI_FAILURE) { - ddi_remove_minor_node(dip, NULL); - return DDI_FAILURE; - } - rw_init(&ppp_lower_lock, NULL, RW_DRIVER, NULL); - return DDI_SUCCESS; -} - -static int -ppp_detach(dip, cmd) - dev_info_t *dip; - ddi_detach_cmd_t cmd; -{ - rw_destroy(&ppp_lower_lock); - ddi_remove_minor_node(dip, NULL); - return DDI_SUCCESS; -} - -static int -ppp_devinfo(dip, cmd, arg, result) - dev_info_t *dip; - ddi_info_cmd_t cmd; - void *arg; - void **result; -{ - int error; - - error = DDI_SUCCESS; - switch (cmd) { - case DDI_INFO_DEVT2DEVINFO: - if (ppp_dip == NULL) - error = DDI_FAILURE; - else - *result = (void *) ppp_dip; - break; - case DDI_INFO_DEVT2INSTANCE: - *result = NULL; - break; - default: - error = DDI_FAILURE; - } - return error; -} diff --git a/mdk-stage1/ppp/solaris/ppp_mod.h b/mdk-stage1/ppp/solaris/ppp_mod.h deleted file mode 100644 index f0af00886..000000000 --- a/mdk-stage1/ppp/solaris/ppp_mod.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Miscellaneous definitions for PPP STREAMS modules. - */ - -/* - * Macros for allocating and freeing kernel memory. - */ -#ifdef SVR4 /* SVR4, including Solaris 2 */ -#include <sys/kmem.h> -#define ALLOC_SLEEP(n) kmem_alloc((n), KM_SLEEP) -#define ALLOC_NOSLEEP(n) kmem_alloc((n), KM_NOSLEEP) -#define FREE(p, n) kmem_free((p), (n)) -#endif - -#ifdef SUNOS4 -#include <sys/kmem_alloc.h> /* SunOS 4.x */ -#define ALLOC_SLEEP(n) kmem_alloc((n), KMEM_SLEEP) -#define ALLOC_NOSLEEP(n) kmem_alloc((n), KMEM_NOSLEEP) -#define FREE(p, n) kmem_free((p), (n)) -#define NOTSUSER() (suser()? 0: EPERM) -#define bcanputnext(q, band) canputnext((q)) -#endif /* SunOS 4 */ - -#ifdef __osf__ -#include <sys/malloc.h> - -/* caution: this mirrors macros in sys/malloc.h, and uses interfaces - * which are subject to change. - * The problems are that: - * - the official MALLOC macro wants the lhs of the assignment as an argument, - * and it takes care of the assignment itself (yuck.) - * - PPP insists on using "FREE" which conflicts with a macro of the same name. - * - */ -#ifdef BUCKETINDX /* V2.0 */ -#define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_WAITOK) -#define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_NOWAIT) -#else -#define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_WAITOK) -#define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_NOWAIT) -#endif - -#define bcanputnext(q, band) canputnext((q)) - -#ifdef FREE -#undef FREE -#endif -#define FREE(p, n) free((void *)(p), M_DEVBUF) - -#define NO_DLPI 1 - -#ifndef IFT_PPP -#define IFT_PPP 0x17 -#endif - -#include <sys/proc.h> -#define NOTSUSER() (suser(u.u_procp->p_rcred, &u.u_acflag) ? EPERM : 0) - -/* #include "ppp_osf.h" */ - -#endif /* __osf__ */ - -#ifdef AIX4 -#define ALLOC_SLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ -#define ALLOC_NOSLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ -#define FREE(p, n) xmfree((p), pinned_heap) -#define NOTSUSER() (suser()? 0: EPERM) -#endif /* AIX */ - -/* - * Macros for printing debugging stuff. - */ -#ifdef DEBUG -#if defined(SVR4) || defined(__osf__) -#if defined(SNI) -#include <sys/strlog.h> -#define STRLOG_ID 4712 -#define DPRINT(f) strlog(STRLOG_ID, 0, 0, SL_TRACE, f) -#define DPRINT1(f, a1) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1) -#define DPRINT2(f, a1, a2) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2) -#define DPRINT3(f, a1, a2, a3) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2, a3) -#else -#define DPRINT(f) cmn_err(CE_CONT, f) -#define DPRINT1(f, a1) cmn_err(CE_CONT, f, a1) -#define DPRINT2(f, a1, a2) cmn_err(CE_CONT, f, a1, a2) -#define DPRINT3(f, a1, a2, a3) cmn_err(CE_CONT, f, a1, a2, a3) -#endif /* SNI */ -#else -#define DPRINT(f) printf(f) -#define DPRINT1(f, a1) printf(f, a1) -#define DPRINT2(f, a1, a2) printf(f, a1, a2) -#define DPRINT3(f, a1, a2, a3) printf(f, a1, a2, a3) -#endif /* SVR4 or OSF */ - -#else -#define DPRINT(f) 0 -#define DPRINT1(f, a1) 0 -#define DPRINT2(f, a1, a2) 0 -#define DPRINT3(f, a1, a2, a3) 0 -#endif /* DEBUG */ - -#ifndef SVR4 -typedef unsigned char uchar_t; -typedef unsigned short ushort_t; -#ifndef __osf__ -typedef int minor_t; -#endif -#endif - -/* - * If we don't have multithreading support, define substitutes. - */ -#ifndef D_MP -# define qprocson(q) -# define qprocsoff(q) -# define put(q, mp) ((*(q)->q_qinfo->qi_putp)((q), (mp))) -# define canputnext(q) canput((q)->q_next) -# define qwriter(q, mp, func, scope) (func)((q), (mp)) -#endif - -#ifdef D_MP -/* Use msgpullup if we have other multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - mblk_t *np = msgpullup((mp), (len)); \ - freemsg((mp)); \ - mp = np; \ - } while (0) - -#else -/* Use pullupmsg if we don't have any multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - if (!pullupmsg((mp), (len))) { \ - freemsg((mp)); \ - mp = 0; \ - } \ - } while (0) -#endif - -/* - * How to declare the open and close procedures for a module. - */ -#ifdef SVR4 -#define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, dev_t *, int, int, cred_t *)) - -#define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int, cred_t *)) - -#define MOD_OPEN(name) \ -static int name(q, devp, flag, sflag, credp) \ - queue_t *q; \ - dev_t *devp; \ - int flag, sflag; \ - cred_t *credp; - -#define MOD_CLOSE(name) \ -static int name(q, flag, credp) \ - queue_t *q; \ - int flag; \ - cred_t *credp; - -#define OPEN_ERROR(x) return (x) -#define DRV_OPEN_OK(dev) return 0 - -#define NOTSUSER() (drv_priv(credp)) - -#else /* not SVR4 */ -#define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, int, int, int)) - -#define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int)) - -#define MOD_OPEN(name) \ -static int name(q, dev, flag, sflag) \ - queue_t *q; \ - int dev; \ - int flag, sflag; - -#define MOD_CLOSE(name) \ -static int name(q, flag) \ - queue_t *q; \ - int flag; - -#define OPEN_ERROR(x) { u.u_error = (x); return OPENFAIL; } -#define DRV_OPEN_OK(dev) return (dev) - -#endif /* SVR4 */ |