summaryrefslogtreecommitdiff
path: root/net/ppp-mppe
diff options
context:
space:
mode:
authordbj <dbj@pkgsrc.org>1999-10-08 04:34:43 +0000
committerdbj <dbj@pkgsrc.org>1999-10-08 04:34:43 +0000
commitff1c7a99858902f04a22c7c9e9dbd4453794921e (patch)
tree7b871c485a300ca6c1a195fba78b629093acf28b /net/ppp-mppe
parentab6f85f54a3979da8b359365352f8fb5c3eb0688 (diff)
downloadpkgsrc-ff1c7a99858902f04a22c7c9e9dbd4453794921e.tar.gz
PPP daemon and LKM with MPPE - Microsoft Point-to-Point Encryption
Diffstat (limited to 'net/ppp-mppe')
-rw-r--r--net/ppp-mppe/Makefile47
-rw-r--r--net/ppp-mppe/files/md54
-rw-r--r--net/ppp-mppe/patches/patch-aa15
-rw-r--r--net/ppp-mppe/patches/patch-ab133
-rw-r--r--net/ppp-mppe/patches/patch-ac16
-rw-r--r--net/ppp-mppe/patches/patch-ad27
-rw-r--r--net/ppp-mppe/patches/patch-ae17
-rw-r--r--net/ppp-mppe/patches/patch-af42
-rw-r--r--net/ppp-mppe/patches/patch-ag148
-rw-r--r--net/ppp-mppe/patches/patch-ah78
-rw-r--r--net/ppp-mppe/patches/patch-ai32
-rw-r--r--net/ppp-mppe/patches/patch-aj293
-rw-r--r--net/ppp-mppe/patches/patch-ak15
-rw-r--r--net/ppp-mppe/patches/patch-al17
-rw-r--r--net/ppp-mppe/patches/patch-am62
-rw-r--r--net/ppp-mppe/patches/patch-an27
-rw-r--r--net/ppp-mppe/patches/patch-ao22
-rw-r--r--net/ppp-mppe/patches/patch-ap1621
-rw-r--r--net/ppp-mppe/patches/patch-aq131
-rw-r--r--net/ppp-mppe/patches/patch-ar685
-rw-r--r--net/ppp-mppe/patches/patch-as1287
-rw-r--r--net/ppp-mppe/patches/patch-at633
-rw-r--r--net/ppp-mppe/patches/patch-au83
-rw-r--r--net/ppp-mppe/patches/patch-ba50
-rw-r--r--net/ppp-mppe/patches/patch-bb181
-rw-r--r--net/ppp-mppe/patches/patch-bc520
-rw-r--r--net/ppp-mppe/patches/patch-bd356
-rw-r--r--net/ppp-mppe/patches/patch-be24
-rw-r--r--net/ppp-mppe/patches/patch-bf206
-rw-r--r--net/ppp-mppe/patches/patch-bg28
-rw-r--r--net/ppp-mppe/patches/patch-bh470
-rw-r--r--net/ppp-mppe/patches/patch-bi24
-rw-r--r--net/ppp-mppe/patches/patch-bj167
-rw-r--r--net/ppp-mppe/patches/patch-bk21
-rw-r--r--net/ppp-mppe/patches/patch-bl43
-rw-r--r--net/ppp-mppe/patches/patch-bm207
-rw-r--r--net/ppp-mppe/patches/patch-bn14
-rw-r--r--net/ppp-mppe/patches/patch-bo234
-rw-r--r--net/ppp-mppe/patches/patch-bp68
-rw-r--r--net/ppp-mppe/patches/patch-bq160
-rw-r--r--net/ppp-mppe/patches/patch-br13
-rw-r--r--net/ppp-mppe/patches/patch-bs21
-rw-r--r--net/ppp-mppe/patches/patch-bt790
-rw-r--r--net/ppp-mppe/patches/patch-bu56
-rw-r--r--net/ppp-mppe/patches/patch-bv37
-rw-r--r--net/ppp-mppe/patches/patch-bw22
-rw-r--r--net/ppp-mppe/patches/patch-bx13
-rw-r--r--net/ppp-mppe/patches/patch-by13
-rw-r--r--net/ppp-mppe/patches/patch-bz14
-rw-r--r--net/ppp-mppe/patches/patch-ca121
-rw-r--r--net/ppp-mppe/patches/patch-cb21
-rw-r--r--net/ppp-mppe/patches/patch-da63
-rw-r--r--net/ppp-mppe/patches/patch-db68
-rw-r--r--net/ppp-mppe/patches/patch-dc87
-rw-r--r--net/ppp-mppe/patches/patch-dd25
-rw-r--r--net/ppp-mppe/patches/patch-de24
-rw-r--r--net/ppp-mppe/patches/patch-df99
-rw-r--r--net/ppp-mppe/pkg/COMMENT1
-rw-r--r--net/ppp-mppe/pkg/DESCR23
-rw-r--r--net/ppp-mppe/pkg/PLIST12
60 files changed, 9731 insertions, 0 deletions
diff --git a/net/ppp-mppe/Makefile b/net/ppp-mppe/Makefile
new file mode 100644
index 00000000000..73a430d9e5c
--- /dev/null
+++ b/net/ppp-mppe/Makefile
@@ -0,0 +1,47 @@
+# $NetBSD: Makefile,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+DISTNAME= ppp-2.3.9
+PKGNAME= ppp-mppe-2.3.9
+CATEGORIES= net
+MASTER_SITES= ftp://cs.anu.edu.au/pub/software/ppp/
+
+MAINTAINER= dbj@netbsd.org
+HOMEPAGE= http://www.moretonbay.com/vpn/releases/
+
+BUILD_DEPENDS= ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/rc4:../../security/openssl:extract
+
+HAS_CONFIGURE= yes
+MANCOMPRESSED_IF_MANZ= yes
+
+post-extract:
+ @${MKDIR} ${WRKSRC}/netbsd-1.4
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/sha/sha.h ${WRKSRC}/pppd/sha.h
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/sha/sha1dgst.c ${WRKSRC}/pppd/sha1dgst.c
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/sha/sha_locl.h ${WRKSRC}/pppd/sha_locl.h
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/opensslv.h ${WRKSRC}/pppd/opensslv.h
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/rc4/rc4_skey.c ${WRKSRC}/netbsd-1.4/rc4_skey.c
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/rc4/rc4.h ${WRKSRC}/netbsd-1.4/rc4.h
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/rc4/rc4_locl.h ${WRKSRC}/netbsd-1.4/rc4_locl.h
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/rc4/rc4_enc.c ${WRKSRC}/netbsd-1.4/rc4_enc.c
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/opensslv.h ${WRKSRC}/netbsd-1.4/opensslv.h
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/sha/sha1dgst.c ${WRKSRC}/netbsd-1.4/sha1dgst.c
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/sha/sha_locl.h ${WRKSRC}/netbsd-1.4/sha_locl.h
+ @${CP} ${BUILD_ROOT}/security/openssl/${WRKDIR:T}/openssl-0.9.2b/crypto/sha/sha.h ${WRKSRC}/netbsd-1.4/sha.h
+ @${MV} ${WRKSRC}/pppd/md4.h ${WRKSRC}/pppd/md4.h.hide
+ @${MV} ${WRKSRC}/pppd/md5.h ${WRKSRC}/pppd/md5.h.hide
+
+pre-install:
+ ${INSTALL_PROGRAM_DIR} ${PREFIX}/lkm
+
+SYSDIR?=/sys
+MAKE_ENV+= SYSDIR="${SYSDIR}"
+
+# until PR 5377 is addressed, we need kernel src around to build lkm's
+pre-build:
+.if !exists(${SYSDIR}/lib/libkern/libkern.h)
+ @${ECHO} "This package requires the kernel source to build its lkm."
+ @${ECHO} "Install it in ${SYSDIR} or set the SYSDIR variable to its location."
+ @${FALSE}
+.endif
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/net/ppp-mppe/files/md5 b/net/ppp-mppe/files/md5
new file mode 100644
index 00000000000..381f03a926f
--- /dev/null
+++ b/net/ppp-mppe/files/md5
@@ -0,0 +1,4 @@
+$NetBSD: md5,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+MD5 (ppp-2.3.9.tar.gz) = 3bda111ae5391ac8b875c14a49514fd1
+MD5 (ppp-2.3.8-mppe-others-norc4_TH7.diff.gz) = 07480c9f47268d66fe93cf42b3a7ed9a
diff --git a/net/ppp-mppe/patches/patch-aa b/net/ppp-mppe/patches/patch-aa
new file mode 100644
index 00000000000..0c2e9467b18
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-aa
@@ -0,0 +1,15 @@
+$NetBSD: patch-aa,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: chat/chat.8
+diff -u chat/chat.8:1.1.1.5 chat/chat.8:1.11
+--- chat/chat.8:1.1.1.5 Tue Aug 24 19:50:05 1999
++++ chat/chat.8 Tue Aug 24 19:52:15 1999
+@@ -424,7 +425,7 @@
+ .B \\\\s
+ Represents a space character in the string. This may be used when it
+ is not desirable to quote the strings which contains spaces. The
+-sequence 'HI TIM' and HI\\sTIM are the same.
++sequence 'HI\ TIM' and HI\\sTIM are the same.
+ .TP
+ .B \\\\t
+ Send or expect a tab character.
diff --git a/net/ppp-mppe/patches/patch-ab b/net/ppp-mppe/patches/patch-ab
new file mode 100644
index 00000000000..070b05e4a43
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ab
@@ -0,0 +1,133 @@
+$NetBSD: patch-ab,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: chat/chat.c
+diff -u chat/chat.c:1.1.1.5 chat/chat.c:1.18
+--- chat/chat.c:1.1.1.5 Tue Aug 24 19:50:04 1999
++++ chat/chat.c Tue Aug 24 20:15:00 1999
+@@ -144,18 +150,6 @@
+ "unknown error")
+ #endif
+
+-/*************** Micro getopt() *********************************************/
+-#define OPTION(c,v) (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \
+- (--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\
+- &&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0))
+-#define OPTARG(c,v) (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \
+- (_O=4,(char*)0):(char*)0)
+-#define OPTONLYARG(c,v) (_O&2&&**v?(_O=1,--c,*v++):(char*)0)
+-#define ARG(c,v) (c?(--c,*v++):(char*)0)
+-
+-static int _O = 0; /* Internal state */
+-/*************** Micro getopt() *********************************************/
+-
+ char *program_name;
+
+ #define MAX_ABORTS 50
+@@ -269,12 +263,12 @@
+ char **argv;
+ {
+ int option;
+- char *arg;
++ int i;
+
+ program_name = *argv;
+ tzset();
+
+- while ((option = OPTION(argc, argv)) != 0) {
++ while ((option = getopt(argc, argv, ":evVf:t:r:sST:U:")) != -1) {
+ switch (option) {
+ case 'e':
+ ++echo;
+@@ -297,25 +291,24 @@
+ break;
+
+ case 'f':
+- if ((arg = OPTARG(argc, argv)) != NULL)
+- chat_file = copy_of(arg);
++ if (optarg != NULL)
++ chat_file = copy_of(optarg);
+ else
+ usage();
+ break;
+
+ case 't':
+- if ((arg = OPTARG(argc, argv)) != NULL)
+- timeout = atoi(arg);
++ if (optarg != NULL)
++ timeout = atoi(optarg);
+ else
+ usage();
+ break;
+
+ case 'r':
+- arg = OPTARG (argc, argv);
+- if (arg) {
++ if (optarg) {
+ if (report_fp != NULL)
+ fclose (report_fp);
+- report_file = copy_of (arg);
++ report_file = copy_of (optarg);
+ report_fp = fopen (report_file, "a");
+ if (report_fp != NULL) {
+ if (verbose)
+@@ -327,15 +320,15 @@
+ break;
+
+ case 'T':
+- if ((arg = OPTARG(argc, argv)) != NULL)
+- phone_num = copy_of(arg);
++ if (optarg != NULL)
++ phone_num = copy_of(optarg);
+ else
+ usage();
+ break;
+
+ case 'U':
+- if ((arg = OPTARG(argc, argv)) != NULL)
+- phone_num2 = copy_of(arg);
++ if (optarg != NULL)
++ phone_num2 = copy_of(optarg);
+ else
+ usage();
+ break;
+@@ -345,6 +338,8 @@
+ break;
+ }
+ }
++ argc -= optind;
++ argv += optind;
+ /*
+ * Default the report file to the stderr location
+ */
+@@ -367,17 +362,15 @@
+ init();
+
+ if (chat_file != NULL) {
+- arg = ARG(argc, argv);
+- if (arg != NULL)
++ if (argc)
+ usage();
+ else
+ do_file (chat_file);
+ } else {
+- while ((arg = ARG(argc, argv)) != NULL) {
+- chat_expect(arg);
+-
+- if ((arg = ARG(argc, argv)) != NULL)
+- chat_send(arg);
++ for (i = 0; i < argc; i++) {
++ chat_expect(argv[i]);
++ if (++i < argc)
++ chat_send(argv[i]);
+ }
+ }
+
+@@ -590,7 +583,7 @@
+ have_tty_parameters = 1;
+
+ t.c_iflag |= IGNBRK | ISTRIP | IGNPAR;
+- t.c_oflag = 0;
++ t.c_oflag |= OPOST | ONLCR;
+ t.c_lflag = 0;
+ t.c_cc[VERASE] =
+ t.c_cc[VKILL] = 0;
diff --git a/net/ppp-mppe/patches/patch-ac b/net/ppp-mppe/patches/patch-ac
new file mode 100644
index 00000000000..7299a3aa8c2
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ac
@@ -0,0 +1,16 @@
+$NetBSD: patch-ac,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: pppd/auth.c
+diff -u pppd/auth.c:1.1.1.5 pppd/auth.c:1.25
+--- pppd/auth.c:1.1.1.5 Tue Aug 24 13:25:45 1999
++++ pppd/auth.c Tue Aug 24 19:07:41 1999
+@@ -450,7 +461,8 @@
+ phase = PHASE_NETWORK;
+ #if 0
+ if (!demand)
+- set_filters(&pass_filter, &active_filter);
++ set_filters(&pass_filter_in, &pass_filter_out,
++ &active_filter_int, &active_filter_out);
+ #endif
+ for (i = 0; (protp = protocols[i]) != NULL; ++i)
+ if (protp->protocol < 0xC000 && protp->enabled_flag
diff --git a/net/ppp-mppe/patches/patch-ad b/net/ppp-mppe/patches/patch-ad
new file mode 100644
index 00000000000..378ce204fdf
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ad
@@ -0,0 +1,27 @@
+$NetBSD: patch-ad,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: pppd/demand.c
+diff -u pppd/demand.c:1.1.1.5 pppd/demand.c:1.9
+--- pppd/demand.c:1.1.1.5 Tue Aug 24 13:25:44 1999
++++ pppd/demand.c Tue Aug 24 19:07:42 1999
+@@ -89,7 +100,8 @@
+ ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
+
+ #ifdef PPP_FILTER
+- set_filters(&pass_filter, &active_filter);
++ set_filters(&pass_filter_in, &pass_filter_out,
++ &active_filter_in, &active_filter_out);
+ #endif
+
+ /*
+@@ -330,8 +342,8 @@
+ return 0;
+ proto = PPP_PROTOCOL(p);
+ #ifdef PPP_FILTER
+- if (active_filter.bf_len != 0
+- && bpf_filter(active_filter.bf_insns, frame, len, len) == 0)
++ if (active_filter_out.bf_len != 0
++ && bpf_filter(active_filter_out.bf_insns, frame, len, len) == 0)
+ return 0;
+ #endif
+ for (i = 0; (protp = protocols[i]) != NULL; ++i) {
diff --git a/net/ppp-mppe/patches/patch-ae b/net/ppp-mppe/patches/patch-ae
new file mode 100644
index 00000000000..2fb1f2c58c6
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ae
@@ -0,0 +1,17 @@
+$NetBSD: patch-ae,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/eui64.c.orig Sat Sep 18 00:27:38 1999
++++ pppd/eui64.c Sat Sep 18 00:27:59 1999
+@@ -24,6 +24,7 @@
+
+ static const char rcsid[] = RCSID;
+
++#ifdef INET6
+ /*
+ * eui64_ntoa - Make an ascii representation of an interface identifier
+ */
+@@ -38,3 +39,4 @@
+ e.e8[4], e.e8[5], e.e8[6], e.e8[7]);
+ return buf;
+ }
++#endif
diff --git a/net/ppp-mppe/patches/patch-af b/net/ppp-mppe/patches/patch-af
new file mode 100644
index 00000000000..8b6706f1de0
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-af
@@ -0,0 +1,42 @@
+$NetBSD: patch-af,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/ipv6cp.c.orig Fri Aug 13 02:46:13 1999
++++ pppd/ipv6cp.c Sat Sep 18 00:53:19 1999
+@@ -50,12 +50,15 @@
+ #include "pppd.h"
+ #include "fsm.h"
+ #include "ipcp.h"
++#ifdef INET6
+ #include "ipv6cp.h"
++#endif
+ #include "magic.h"
+ #include "pathnames.h"
+
+ static const char rcsid[] = RCSID;
+
++#ifdef INET6
+ /* global vars */
+ ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */
+ ipv6cp_options ipv6cp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
+@@ -79,6 +82,7 @@
+ static void ipv6cp_up __P((fsm *)); /* We're UP */
+ static void ipv6cp_down __P((fsm *)); /* We're DOWN */
+ static void ipv6cp_finished __P((fsm *)); /* Don't need lower layer */
++static char *llv6_ntoa __P((eui64_t));
+
+ fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */
+
+@@ -242,7 +246,7 @@
+ /*
+ * Make a string representation of a network address.
+ */
+-char *
++static char *
+ llv6_ntoa(ifaceid)
+ eui64_t ifaceid;
+ {
+@@ -1360,3 +1364,4 @@
+ return 0;
+ return 1;
+ }
++#endif
diff --git a/net/ppp-mppe/patches/patch-ag b/net/ppp-mppe/patches/patch-ag
new file mode 100644
index 00000000000..d131dd3e61d
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ag
@@ -0,0 +1,148 @@
+$NetBSD: patch-ag,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: pppd/options.c
+diff -u pppd/options.c:1.1.1.5 pppd/options.c:1.30
+--- pppd/options.c:1.1.1.5 Tue Aug 24 13:25:41 1999
++++ pppd/options.c Tue Aug 24 19:07:44 1999
+@@ -108,8 +119,14 @@
+ struct option_info ptycommand_info;
+
+ #ifdef PPP_FILTER
+-struct bpf_program pass_filter;/* Filter program for packets to pass */
+-struct bpf_program active_filter; /* Filter program for link-active pkts */
++/* Filter program for packets to pass */
++struct bpf_program pass_filter_in;
++struct bpf_program pass_filter_out;
++
++/* Filter program for link-active packets */
++struct bpf_program active_filter_in;
++struct bpf_program active_filter_out;
++
+ pcap_t pc; /* Fake struct pcap so we can compile expr */
+ #endif
+
+@@ -136,11 +153,12 @@
+ static int setlogfile __P((char **));
+
+ #ifdef PPP_FILTER
+-static int setpassfilter __P((char **));
+-static int setactivefilter __P((char **));
++static int setpassfilter_in __P((char **));
++static int setpassfilter_out __P((char **));
++static int setactivefilter_in __P((char **));
++static int setactivefilter_out __P((char **));
+ #endif
+
+-
+ static option_t *find_option __P((char *name));
+ static int process_option __P((option_t *, char **));
+ static int n_arguments __P((option_t *));
+@@ -250,10 +268,14 @@
+ #ifdef PPP_FILTER
+ { "pdebug", o_int, &dflag,
+ "libpcap debugging" },
+- { "pass-filter", 1, setpassfilter,
+- "set filter for packets to pass" },
+- { "active-filter", 1, setactivefilter,
+- "set filter for active pkts" },
++ { "pass-filter-in", 1, setpassfilter_in,
++ "set filter for packets to pass inwards" },
++ { "pass-filter-out", 1, setpassfilter_out,
++ "set filter for packets to pass outwards" },
++ { "active-filter-in", 1, setactivefilter_in,
++ "set filter for active pkts inwards" },
++ { "active-filter-out", 1, setactivefilter_out,
++ "set filter for active pkts outwards" },
+ #endif
+
+ { NULL }
+@@ -274,6 +296,7 @@
+ auth Require authentication from peer\n\
+ connect <p> Invoke shell command <p> to set up the serial line\n\
+ crtscts Use hardware RTS/CTS flow control\n\
++ cdtrcts Use hardware DTR/CTS flow control (if supported)\n\
+ defaultroute Add default route through interface\n\
+ file <f> Take options from file <f>\n\
+ modem Use modem control lines\n\
+@@ -1185,44 +1208,68 @@
+
+ #ifdef PPP_FILTER
+ /*
+- * setpdebug - Set libpcap debugging level.
++ * setpassfilter_in - Set the incoming pass filter
+ */
+ static int
+-setpdebug(argv)
++setpassfilter_in(argv)
+ char **argv;
+ {
+- return int_option(*argv, &dflag);
++ pc.linktype = DLT_PPP_SERIAL;
++ pc.snapshot = PPP_HDRLEN;
++
++ if (pcap_compile(&pc, &pass_filter_in, *argv, 1, netmask) == 0)
++ return 1;
++ option_error("error in pass-filter-in expression: %s\n", pcap_geterr(&pc));
++ return 0;
+ }
+
+ /*
+- * setpassfilter - Set the pass filter for packets
++ * setpassfilter_out - Set the outgoing pass filter
+ */
+ static int
+-setpassfilter(argv)
++setpassfilter_out(argv)
+ char **argv;
+ {
+- pc.linktype = DLT_PPP;
++ pc.linktype = DLT_PPP_SERIAL;
+ pc.snapshot = PPP_HDRLEN;
+
+- if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0)
++ if (pcap_compile(&pc, &pass_filter_out, *argv, 1, netmask) == 0)
++ return 1;
++ option_error("error in pass-filter-out expression: %s\n", pcap_geterr(&pc));
++ return 0;
++}
++
++/*
++ * setactivefilter_in - Set the incoming active filter
++ */
++static int
++setactivefilter_in(argv)
++ char **argv;
++{
++ pc.linktype = DLT_PPP_SERIAL;
++ pc.snapshot = PPP_HDRLEN;
++
++ if (pcap_compile(&pc, &active_filter_in, *argv, 1, netmask) == 0)
+ return 1;
+- option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc));
++ option_error("error in active-filter-in expression: %s\n",
++ pcap_geterr(&pc));
+ return 0;
+ }
+
+ /*
+- * setactivefilter - Set the active filter for packets
++ * setactivefilter_out - Set the outgoing active filter
+ */
+ static int
+-setactivefilter(argv)
++setactivefilter_out(argv)
+ char **argv;
+ {
+- pc.linktype = DLT_PPP;
++ pc.linktype = DLT_PPP_SERIAL;
+ pc.snapshot = PPP_HDRLEN;
+
+- if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0)
++ if (pcap_compile(&pc, &active_filter_out, *argv, 1, netmask) == 0)
+ return 1;
+- option_error("error in active-filter expression: %s\n", pcap_geterr(&pc));
++ option_error("error in active-filter-out expression: %s\n",
++ pcap_geterr(&pc));
+ return 0;
+ }
+ #endif
diff --git a/net/ppp-mppe/patches/patch-ah b/net/ppp-mppe/patches/patch-ah
new file mode 100644
index 00000000000..ca245d32496
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ah
@@ -0,0 +1,78 @@
+$NetBSD: patch-ah,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: pppd/pppd.8
+diff -u pppd/pppd.8:1.1.1.5 pppd/pppd.8:1.25
+--- pppd/pppd.8:1.1.1.5 Tue Aug 24 13:25:40 1999
++++ pppd/pppd.8 Tue Aug 24 19:07:45 1999
+@@ -45,6 +46,24 @@
+ 4.4BSD and NetBSD, any speed can be specified. Other systems
+ (e.g. SunOS) allow only a limited set of speeds.
+ .TP
++.B active-filter-in \fIfilter-expression
++.TP
++.B active-filter-out \fIfilter-expression
++Specifies an incoming and outgoing packet filter to be applied to data
++packets to determine which packets are to be regarded as link activity,
++and therefore reset the idle timer, or cause the link to be brought up
++in demand-dialling mode. This option is useful in conjunction with the
++\fBidle\fR option if there are packets being sent or received
++regularly over the link (for example, routing information packets)
++which would otherwise prevent the link from ever appearing to be idle.
++The \fIfilter-expression\fR syntax is as described for tcpdump(8),
++except that qualifiers which are inappropriate for a PPP link, such as
++\fBether\fR and \fBarp\fR, are not permitted. Generally the filter
++expression should be enclosed in single-quotes to prevent whitespace
++in the expression from being interpreted by the shell. This option
++is currently only available under NetBSD, and then only
++if both the kernel and pppd were compiled with PPP_FILTER defined.
++.TP
+ .B asyncmap \fI<map>
+ Set the async character map to <map>. This map describes which
+ control characters cannot be successfully received over the serial
+@@ -296,8 +315,8 @@
+ seconds. The link is idle when no data packets (i.e. IP packets) are
+ being sent or received. Note: it is not advisable to use this option
+ with the \fIpersist\fR option without the \fIdemand\fR option.
+-If the \fBactive-filter\fR
+-option is given, data packets which are rejected by the specified
++If the \fBactive-filter-in\fR and/or \fBactive-filter-out\fR
++options are given, data packets which are rejected by the specified
+ activity filter also count as the link being idle.
+ .TP
+ .B ipcp-accept-local
+@@ -664,23 +683,23 @@
+ .B pap-timeout \fIn
+ Set the maximum time that pppd will wait for the peer to authenticate
+ itself with PAP to \fIn\fR seconds (0 means no limit).
++.TP
++.B pass-filter-in \fIfilter-expression
+ .TP
+-.B pass-filter \fIfilter-expression
+-Specifies a packet filter to applied to data packets being sent or
+-received to determine which packets should be allowed to pass.
+-Packets which are rejected by the filter are silently discarded. This
+-option can be used to prevent specific network daemons (such as
+-routed) using up link bandwidth, or to provide a basic firewall
++.B pass-filter-out \fIfilter-expression
++Specifies an incoming and outgoing packet filter to applied to data
++packets being sent or received to determine which packets should be
++allowed to pass. Packets which are rejected by the filter are silently
++discarded. This option can be used to prevent specific network daemons
++(such as routed) using up link bandwidth, or to provide a basic firewall
+ capability.
+-The \fIfilter-expression\fR syntax is as described for tcpdump(1),
++The \fIfilter-expression\fR syntax is as described for tcpdump(8),
+ except that qualifiers which are inappropriate for a PPP link, such as
+ \fBether\fR and \fBarp\fR, are not permitted. Generally the filter
+ expression should be enclosed in single-quotes to prevent whitespace
+-in the expression from being interpreted by the shell. Note that it
+-is possible to apply different constraints to incoming and outgoing
+-packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. This
+-option is currently only available under NetBSD, and then only if both
+-the kernel and pppd were compiled with PPP_FILTER defined.
++in the expression from being interpreted by the shell. This option is
++currently only available under NetBSD, and then only if both the kernel
++and pppd were compiled with PPP_FILTER defined.
+ .TP
+ .B persist
+ Do not exit after a connection is terminated; instead try to reopen
diff --git a/net/ppp-mppe/patches/patch-ai b/net/ppp-mppe/patches/patch-ai
new file mode 100644
index 00000000000..651d28e0deb
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ai
@@ -0,0 +1,32 @@
+$NetBSD: patch-ai,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: pppd/pppd.h
+diff -u pppd/pppd.h:1.1.1.5 pppd/pppd.h:1.19
+--- pppd/pppd.h:1.1.1.5 Tue Aug 24 13:25:39 1999
++++ pppd/pppd.h Tue Aug 24 19:07:45 1999
+@@ -207,8 +209,13 @@
+ extern char linkname[MAXPATHLEN]; /* logical name for link */
+
+ #ifdef PPP_FILTER
+-extern struct bpf_program pass_filter; /* Filter for pkts to pass */
+-extern struct bpf_program active_filter; /* Filter for link-active pkts */
++/* Filter for packets to pass */
++extern struct bpf_program pass_filter_in;
++extern struct bpf_program pass_filter_out;
++
++/* Filter for link-active packets */
++extern struct bpf_program active_filter_in;
++extern struct bpf_program active_filter_out;
+ #endif
+
+ #ifdef MSLANMAN
+@@ -422,7 +429,8 @@
+ int get_host_seed __P((void)); /* Get host-dependent random number seed */
+ int have_route_to __P((u_int32_t)); /* Check if route to addr exists */
+ #ifdef PPP_FILTER
+-int set_filters __P((struct bpf_program *pass, struct bpf_program *active));
++int set_filters __P((struct bpf_program *pass_in, struct bpf_program *pass_out,
++ struct bpf_program *active_in, struct bpf_program *active_out));
+ /* Set filter programs in kernel */
+ #endif
+ #ifdef IPX_CHANGE
diff --git a/net/ppp-mppe/patches/patch-aj b/net/ppp-mppe/patches/patch-aj
new file mode 100644
index 00000000000..e97c5bc2c4a
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-aj
@@ -0,0 +1,293 @@
+$NetBSD: patch-aj,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/sys-bsd.c.orig Fri Aug 13 02:46:18 1999
++++ pppd/sys-bsd.c Sat Sep 18 02:28:45 1999
+@@ -25,4 +25,3 @@
+-#endif
+
+ /*
+ * TODO:
+@@ -42,7 +41,7 @@
+ #include <sys/time.h>
+ #include <sys/stat.h>
+ #include <sys/param.h>
+-#ifdef NetBSD1_2
++#if defined(NetBSD1_2) || defined(__NetBSD_Version__)
+ #include <util.h>
+ #endif
+ #ifdef PPP_FILTER
+@@ -55,6 +54,10 @@
+ #include <net/route.h>
+ #include <net/if_dl.h>
+ #include <netinet/in.h>
++#ifdef __KAME__
++#include <netinet6/in6_var.h>
++#include <netinet6/nd6.h>
++#endif
+
+ #if RTM_VERSION >= 3
+ #include <sys/param.h>
+@@ -91,6 +94,9 @@
+ static unsigned char inbuf[512]; /* buffer for chars read from loopback */
+
+ static int sockfd; /* socket for doing interface ioctls */
++#ifdef INET6
++static int sock6_fd = -1; /* socket for doing ipv6 interface ioctls */
++#endif /* INET6 */
+
+ static fd_set in_fds; /* set of fds that wait_input waits for */
+ static int max_in_fd; /* highest fd set in in_fds */
+@@ -115,6 +121,11 @@
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ fatal("Couldn't create IP socket: %m");
+
++#ifdef INET6
++ if ((sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
++ fatal("Couldn't create IPv6 socket: %m");
++#endif
++
+ FD_ZERO(&in_fds);
+ max_in_fd = 0;
+ }
+@@ -191,10 +202,16 @@
+ ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
+ close(s);
+
++#ifdef __NetBSD__
++ no_ppp_msg = "\
++This system lacks kernel support for PPP. To include PPP support\n\
++in the kernel, please read the ppp(4) manual page.\n";
++#else
+ no_ppp_msg = "\
+ This system lacks kernel support for PPP. To include PPP support\n\
+ in the kernel, please follow the steps detailed in the README.bsd\n\
+ file in the ppp-2.2 distribution.\n";
++#endif
+ return ok;
+ }
+
+@@ -459,6 +476,176 @@
+ ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
+ }
+
++#ifdef INET6
++/*
++ * sif6addr - Config the interface with an IPv6 link-local address
++ */
++int
++sif6addr(unit, our_eui64, his_eui64)
++ int unit;
++ eui64_t our_eui64, his_eui64;
++{
++#ifdef __KAME__
++ int ifindex;
++ struct in6_aliasreq addreq6;
++
++ /* actually, this part is not kame local - RFC2553 conformant */
++ ifindex = if_nametoindex(ifname);
++ if (ifindex == 0) {
++ error("sifaddr6: no interface %s", ifname);
++ return 0;
++ }
++
++ memset(&addreq6, 0, sizeof(addreq6));
++ strlcpy(addreq6.ifra_name, ifname, sizeof(addreq6.ifra_name));
++
++ /* my addr */
++ addreq6.ifra_addr.sin6_family = AF_INET6;
++ addreq6.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
++ addreq6.ifra_addr.sin6_addr.s6_addr[0] = 0xfe;
++ addreq6.ifra_addr.sin6_addr.s6_addr[1] = 0x80;
++ memcpy(&addreq6.ifra_addr.sin6_addr.s6_addr[8], &our_eui64,
++ sizeof(our_eui64));
++ /* KAME ifindex hack */
++ *(u_int16_t *)&addreq6.ifra_addr.sin6_addr.s6_addr[2] = htons(ifindex);
++
++ /* his addr */
++ addreq6.ifra_dstaddr.sin6_family = AF_INET6;
++ addreq6.ifra_dstaddr.sin6_len = sizeof(struct sockaddr_in6);
++ addreq6.ifra_dstaddr.sin6_addr.s6_addr[0] = 0xfe;
++ addreq6.ifra_dstaddr.sin6_addr.s6_addr[1] = 0x80;
++ memcpy(&addreq6.ifra_dstaddr.sin6_addr.s6_addr[8], &his_eui64,
++ sizeof(our_eui64));
++ /* KAME ifindex hack */
++ *(u_int16_t *)&addreq6.ifra_dstaddr.sin6_addr.s6_addr[2] = htons(ifindex);
++
++ /* prefix mask: 128bit (correct?) */
++ addreq6.ifra_prefixmask.sin6_family = AF_INET6;
++ addreq6.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
++ memset(&addreq6.ifra_prefixmask.sin6_addr, 0xff,
++ sizeof(addreq6.ifra_prefixmask.sin6_addr));
++
++ /* address lifetime (infty) */
++ addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
++ addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
++
++ if (ioctl(sock6_fd, SIOCAIFADDR_IN6, &addreq6) < 0) {
++ error("sif6addr: ioctl(SIOCAIFADDR_IN6): %m");
++ return 0;
++ }
++
++ return 1;
++#else
++ struct in6_ifreq ifr6;
++ struct ifreq ifr;
++ struct in6_rtmsg rt6;
++
++ memset(&ifr, 0, sizeof (ifr));
++ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
++ if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
++ error("sif6addr: ioctl(SIOCGIFINDEX): %m");
++ return 0;
++ }
++
++ /* Local interface */
++ memset(&ifr6, 0, sizeof(ifr6));
++ IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
++ ifr6.ifr6_ifindex = ifindex;
++ ifr6.ifr6_prefixlen = 10;
++
++ if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
++ error("sif6addr: ioctl(SIOCSIFADDR): %m");
++ return 0;
++ }
++
++ /* Route to remote host */
++ memset(&rt6, 0, sizeof(rt6));
++ IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
++ rt6.rtmsg_flags = RTF_UP | RTF_HOST;
++ rt6.rtmsg_dst_len = 128;
++ rt6.rtmsg_ifindex = ifr.ifr_ifindex;
++ rt6.rtmsg_metric = 1;
++
++ if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
++ error("sif6addr: ioctl(SIOCADDRT): %m");
++ return 0;
++ }
++
++ return 1;
++#endif
++}
++
++
++/*
++ * cif6addr - Remove IPv6 address from interface
++ */
++int
++cif6addr(unit, our_eui64, his_eui64)
++ int unit;
++ eui64_t our_eui64, his_eui64;
++{
++#ifdef __KAME__
++ int ifindex;
++ struct in6_ifreq delreq6;
++
++ /* actually, this part is not kame local - RFC2553 conformant */
++ ifindex = if_nametoindex(ifname);
++ if (ifindex == 0) {
++ error("cifaddr6: no interface %s", ifname);
++ return 0;
++ }
++
++ memset(&delreq6, 0, sizeof(delreq6));
++ strlcpy(delreq6.ifr_name, ifname, sizeof(delreq6.ifr_name));
++
++ /* my addr */
++ delreq6.ifr_ifru.ifru_addr.sin6_family = AF_INET6;
++ delreq6.ifr_ifru.ifru_addr.sin6_len = sizeof(struct sockaddr_in6);
++ delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[0] = 0xfe;
++ delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[1] = 0x80;
++ memcpy(&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[8], &our_eui64,
++ sizeof(our_eui64));
++ /* KAME ifindex hack */
++ *(u_int16_t *)&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[2] =
++ htons(ifindex);
++
++ if (ioctl(sock6_fd, SIOCDIFADDR_IN6, &delreq6) < 0) {
++ error("cif6addr: ioctl(SIOCDIFADDR_IN6): %m");
++ return 0;
++ }
++
++ return 1;
++#else
++ struct ifreq ifr;
++ struct in6_ifreq ifr6;
++
++ memset(&ifr, 0, sizeof(ifr));
++ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
++ if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
++ error("cif6addr: ioctl(SIOCGIFINDEX): %m");
++ return 0;
++ }
++
++ memset(&ifr6, 0, sizeof(ifr6));
++ IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
++ ifr6.ifr6_ifindex = ifr.ifr_ifindex;
++ ifr6.ifr6_prefixlen = 10;
++
++ if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
++ if (errno != EADDRNOTAVAIL) {
++ if (! ok_error (errno))
++ error("cif6addr: ioctl(SIOCDIFADDR): %m");
++ }
++ else {
++ warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
++ }
++ return (0);
++ }
++ return 1;
++#endif
++}
++#endif /* INET6 */
++
+ /*
+ * get_pty - get a pty master/slave pair and chown the slave side
+ * to the uid given. Assumes slave_name points to >= 12 bytes of space.
+@@ -851,23 +1038,39 @@
+ * set_filters - transfer the pass and active filters to the kernel.
+ */
+ int
+-set_filters(pass, active)
+- struct bpf_program *pass, *active;
++set_filters(pass_in, pass_out, active_in, active_out)
++ struct bpf_program *pass_in, *pass_out, *active_in, *active_out;
+ {
+ int ret = 1;
+
+- if (pass->bf_len > 0) {
+- if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) {
+- error("Couldn't set pass-filter in kernel: %m");
++ if (pass_in->bf_len > 0) {
++ if (ioctl(ppp_fd, PPPIOCSIPASS, pass_in) < 0) {
++ error("Couldn't set pass-filter-in in kernel: %m");
++ ret = 0;
++ }
++ }
++
++ if (pass_out->bf_len > 0) {
++ if (ioctl(ppp_fd, PPPIOCSOPASS, pass_out) < 0) {
++ error("Couldn't set pass-filter-out in kernel: %m");
+ ret = 0;
+ }
+ }
+- if (active->bf_len > 0) {
+- if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) {
+- error("Couldn't set active-filter in kernel: %m");
++
++ if (active_in->bf_len > 0) {
++ if (ioctl(ppp_fd, PPPIOCSIACTIVE, active_in) < 0) {
++ error("Couldn't set active-filter-in in kernel: %m");
+ ret = 0;
+ }
+ }
++
++ if (active_out->bf_len > 0) {
++ if (ioctl(ppp_fd, PPPIOCSOACTIVE, active_out) < 0) {
++ error("Couldn't set active-filter-out in kernel: %m");
++ ret = 0;
++ }
++ }
++
+ return ret;
+ }
+ #endif
diff --git a/net/ppp-mppe/patches/patch-ak b/net/ppp-mppe/patches/patch-ak
new file mode 100644
index 00000000000..2fba807967e
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ak
@@ -0,0 +1,15 @@
+$NetBSD: patch-ak,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: pppstats/pppstats.8
+diff -u pppstats/pppstats.8:1.1.1.5 pppstats/pppstats.8:1.12
+--- pppstats/pppstats.8:1.1.1.5 Tue Aug 24 19:57:32 1999
++++ pppstats/pppstats.8 Tue Aug 24 20:00:12 1999
+@@ -172,7 +173,7 @@
+ When the
+ .B -z
+ option is specified,
+-.Nm pppstats
++.B pppstats
+ instead displays the following fields, relating to the packet
+ compression algorithm currently in use. If packet compression is not
+ in use, these fields will all display zeroes. The fields displayed on
diff --git a/net/ppp-mppe/patches/patch-al b/net/ppp-mppe/patches/patch-al
new file mode 100644
index 00000000000..5d2fe89a57d
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-al
@@ -0,0 +1,17 @@
+$NetBSD: patch-al,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- configure.orig Wed May 12 20:31:38 1999
++++ configure Sat Sep 18 01:30:26 1999
+@@ -17,8 +17,10 @@
+ 1.0*) state="ancient";;
+ 1.1*) state="known"; ksrc="netbsd-1.1";;
+ 1.2*) state="known"; ksrc="netbsd-1.2"; makext="netbsd-1.2";;
+- 1.[3-9]*|[2-9]*)
+- state="late"; ksrc="netbsd-1.2";;
++ 1.3*) state="late"; ksrc="netbsd-1.2";;
++ 1.4*) state="known"; ksrc="netbsd-1.4"; makext="netbsd-1.4";;
++ 1.[5-9]*|[2-9]*)
++ state="late"; ksrc="netbsd-1.4"; makext="netbsd-1.4";;
+ esac;;
+ SunOS)
+ case $release in
diff --git a/net/ppp-mppe/patches/patch-am b/net/ppp-mppe/patches/patch-am
new file mode 100644
index 00000000000..6a49d11e5a2
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-am
@@ -0,0 +1,62 @@
+$NetBSD: patch-am,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: Makefile
+diff -u /dev/null Makefile:1.17
+--- /dev/null Fri Sep 17 20:40:08 1999
++++ netbsd-1.4/Makefile.top Fri Sep 26 12:52:08 1997
+@@ -0,0 +1,5 @@
++# NetBSD: Makefile,v 1.17 1997/09/26 19:52:08 christos Exp
++
++SUBDIR= chat pppd pppstats
++
++.include <bsd.subdir.mk>
+Index: chat/Makefile
+diff -u /dev/null chat/Makefile:1.8
+--- /dev/null Fri Sep 17 20:40:09 1999
++++ chat/Makefile.netbsd-1.4 Fri Oct 17 05:07:34 1997
+@@ -0,0 +1,6 @@
++# NetBSD: Makefile,v 1.8 1997/10/17 12:07:34 lukem Exp
++
++PROG= chat
++MAN= chat.8
++
++.include <bsd.prog.mk>
+Index: pppd/Makefile
+diff -u /dev/null pppd/Makefile:1.26
+--- /dev/null Fri Sep 17 20:40:09 1999
++++ pppd/Makefile.netbsd-1.4 Tue Aug 24 19:07:41 1999
+@@ -0,0 +1,23 @@
++# NetBSD: Makefile,v 1.26 1999/08/25 02:07:41 christos Exp
++
++PCAPDIR=${.CURDIR}/../../../lib/libpcap
++
++PROG= pppd
++SRCS= auth.c cbcp.c ccp.c chap.c chap_ms.c demand.c eui64.c fsm.c \
++ ipcp.c ipv6cp.c ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c \
++ upap.c utils.c
++
++.PATH: ${PCAPDIR}
++MAN= pppd.8
++BINMODE=4555
++BINOWN= root
++
++LDADD= -lpcap -lcrypt -lutil
++DPADD= ${LIBPCAP} ${LIBCRYPT} ${LIBUTIL}
++CPPFLAGS+= -I. -DHAVE_PATHS_H
++CPPFLAGS+= -I${PCAPDIR} -DPPP_FILTER
++CPPFLAGS+= -DCBCP_SUPPORT -DCHAPMS -DUSE_CRYPT -DMSLANMAN
++# XXX: Does not work (yet)
++#CPPFLAGS+= -DINET6
++
++.include <bsd.prog.mk>
+Index: pppstats/Makefile
+diff -u /dev/null pppstats/Makefile:1.14
+--- /dev/null Fri Sep 17 20:40:12 1999
++++ pppstats/Makefile.netbsd-1.4 Fri Oct 17 05:07:47 1997
+@@ -0,0 +1,6 @@
++# NetBSD: Makefile,v 1.14 1997/10/17 12:07:47 lukem Exp
++
++PROG= pppstats
++MAN= pppstats.8
++
++.include <bsd.prog.mk>
diff --git a/net/ppp-mppe/patches/patch-an b/net/ppp-mppe/patches/patch-an
new file mode 100644
index 00000000000..3a3c9b729a8
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-an
@@ -0,0 +1,27 @@
+$NetBSD: patch-an,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- include/net/if_ppp.h.orig Sat Sep 18 03:06:38 1999
++++ include/net/if_ppp.h Sat Sep 18 03:09:15 1999
+@@ -107,8 +109,22 @@
+ #define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */
+ #define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */
+ #ifdef PPP_FILTER
++/*
++ * XXX These are deprecated; they can no longer be used, because they
++ * XXX don't play well with multiple encaps. The defs are here so that
++ * XXX we can return decent errors to old pppds, and so that new pppds
++ * XXX will work with old kernels.
++ */
+ #define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */
+ #define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */
++
++/*
++ * Use these instead.
++ */
++#define PPPIOCSIPASS _IOW('t', 69, struct bpf_program) /* set in pass flt */
++#define PPPIOCSOPASS _IOW('t', 68, struct bpf_program) /* set out pass flt */
++#define PPPIOCSIACTIVE _IOW('t', 67, struct bpf_program) /* set in act flt */
++#define PPPIOCSOACTIVE _IOW('t', 66, struct bpf_program) /* set out act flt */
+ #endif /* PPP_FILTER */
+
+ /* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */
diff --git a/net/ppp-mppe/patches/patch-ao b/net/ppp-mppe/patches/patch-ao
new file mode 100644
index 00000000000..edac2e556b2
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ao
@@ -0,0 +1,22 @@
+$NetBSD: patch-ao,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- include/net/slcompress.h.orig Sat Sep 18 03:06:38 1999
++++ include/net/slcompress.h Sat Sep 18 03:09:30 1999
+@@ -101,7 +122,7 @@
+ */
+ struct cstate {
+ struct cstate *cs_next; /* next most recently used cstate (xmit only) */
+- u_short cs_hlen; /* size of hdr (receive only) */
++ u_int16_t cs_hlen; /* size of hdr (receive only) */
+ u_char cs_id; /* connection # associated with this state */
+ u_char cs_filler;
+ union {
+@@ -120,7 +141,7 @@
+ struct cstate *last_cs; /* most recently used tstate */
+ u_char last_recv; /* last rcvd conn. id */
+ u_char last_xmit; /* last sent conn. id */
+- u_short flags;
++ u_int16_t flags;
+ #ifndef SL_NO_STATS
+ int sls_packets; /* outbound packets */
+ int sls_compressed; /* outbound compressed packets */
diff --git a/net/ppp-mppe/patches/patch-ap b/net/ppp-mppe/patches/patch-ap
new file mode 100644
index 00000000000..2761d93041d
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ap
@@ -0,0 +1,1621 @@
+$NetBSD: patch-ap,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 04:00:15 1999
++++ netbsd-1.4/if_ppp.c Sat Sep 18 04:06:21 1999
+@@ -0,0 +1,1616 @@
++/* NetBSD: if_ppp.c,v 1.55 1999/07/30 10:35:38 itojun Exp */
++/* Id: if_ppp.c,v 1.6 1997/03/04 03:33:00 paulus Exp */
++
++/*
++ * if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver.
++ *
++ * Copyright (c) 1989 Carnegie Mellon University.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms are permitted
++ * provided that the above copyright notice and this paragraph are
++ * duplicated in all such forms and that any documentation,
++ * advertising materials, and other materials related to such
++ * distribution and use acknowledge that the software was developed
++ * by Carnegie Mellon University. The name of the
++ * University may not be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * Drew D. Perkins
++ * Carnegie Mellon University
++ * 4910 Forbes Ave.
++ * Pittsburgh, PA 15213
++ * (412) 268-8576
++ * ddp@andrew.cmu.edu
++ *
++ * Based on:
++ * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
++ *
++ * Copyright (c) 1987 Regents of the University of California.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms are permitted
++ * provided that the above copyright notice and this paragraph are
++ * duplicated in all such forms and that any documentation,
++ * advertising materials, and other materials related to such
++ * distribution and use acknowledge that the software was developed
++ * by the University of California, Berkeley. The name of the
++ * University may not be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * Serial Line interface
++ *
++ * Rick Adams
++ * Center for Seismic Studies
++ * 1300 N 17th Street, Suite 1450
++ * Arlington, Virginia 22209
++ * (703)276-7900
++ * rick@seismo.ARPA
++ * seismo!rick
++ *
++ * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
++ * Converted to 4.3BSD Beta by Chris Torek.
++ * Other changes made at Berkeley, based in part on code by Kirk Smith.
++ *
++ * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
++ * Added VJ tcp header compression; more unified ioctls
++ *
++ * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
++ * Cleaned up a lot of the mbuf-related code to fix bugs that
++ * caused system crashes and packet corruption. Changed pppstart
++ * so that it doesn't just give up with a collision if the whole
++ * packet doesn't fit in the output ring buffer.
++ *
++ * Added priority queueing for interactive IP packets, following
++ * the model of if_sl.c, plus hooks for bpf.
++ * Paul Mackerras (paulus@cs.anu.edu.au).
++ */
++
++/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
++/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
++
++#include "ppp.h"
++#if NPPP > 0
++
++#define VJC
++#define PPP_COMPRESS
++
++#include "opt_inet.h"
++#include "opt_gateway.h"
++#include "opt_ppp.h"
++
++#include <sys/param.h>
++#include <sys/proc.h>
++#include <sys/mbuf.h>
++#include <sys/socket.h>
++#include <sys/ioctl.h>
++#include <sys/kernel.h>
++#include <sys/systm.h>
++#include <sys/time.h>
++#include <sys/malloc.h>
++
++#include <net/if.h>
++#include <net/if_types.h>
++#include <net/netisr.h>
++#include <net/route.h>
++#ifdef PPP_FILTER
++#include <net/bpf.h>
++#endif
++
++#ifdef INET
++#include <netinet/in.h>
++#include <netinet/in_systm.h>
++#include <netinet/in_var.h>
++#include <netinet/ip.h>
++#else
++#ifdef _KERNEL
++#ifdef VJC
++#error ppp device with VJC assumes INET
++#endif
++#endif
++#endif
++
++#include "bpfilter.h"
++#if NBPFILTER > 0
++#include <sys/time.h>
++#include <net/bpf.h>
++#endif
++
++#if defined(PPP_FILTER) || NBPFILTER > 0
++#include <net/slip.h>
++#endif
++
++#ifdef VJC
++#include <net/slcompress.h>
++#endif
++
++#include <net/ppp_defs.h>
++#include <net/if_ppp.h>
++#include <net/if_pppvar.h>
++#include <machine/cpu.h>
++
++#ifdef PPP_COMPRESS
++#define PACKETPTR struct mbuf *
++#include <net/ppp-comp.h>
++#endif
++
++static int pppsioctl __P((struct ifnet *, u_long, caddr_t));
++static void ppp_requeue __P((struct ppp_softc *));
++static void ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd));
++static void ppp_ccp_closed __P((struct ppp_softc *));
++static void ppp_inproc __P((struct ppp_softc *, struct mbuf *));
++static void pppdumpm __P((struct mbuf *m0));
++
++/*
++ * Some useful mbuf macros not in mbuf.h.
++ */
++#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
++
++#define M_DATASTART(m) \
++ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
++ (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
++
++#define M_DATASIZE(m) \
++ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
++ (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
++
++/*
++ * We define two link layer specific mbuf flags, to mark high-priority
++ * packets for output, and received packets following lost/corrupted
++ * packets.
++ */
++#define M_HIGHPRI M_LINK0 /* output packet for sc_fastq */
++#define M_ERRMARK M_LINK1 /* rx packet following lost/corrupted pkt */
++
++#ifdef PPP_COMPRESS
++/*
++ * List of compressors we know about.
++ * We leave some space so maybe we can modload compressors.
++ */
++
++extern struct compressor ppp_bsd_compress;
++extern struct compressor ppp_deflate, ppp_deflate_draft;
++
++struct compressor *ppp_compressors[8] = {
++#if DO_BSD_COMPRESS && defined(PPP_BSDCOMP)
++ &ppp_bsd_compress,
++#endif
++#if DO_DEFLATE && defined(PPP_DEFLATE)
++ &ppp_deflate,
++ &ppp_deflate_draft,
++#endif
++ NULL
++};
++#endif /* PPP_COMPRESS */
++
++
++/*
++ * Called from boot code to establish ppp interfaces.
++ */
++void
++pppattach()
++{
++ register struct ppp_softc *sc;
++ register int i = 0;
++
++ for (sc = ppp_softc; i < NPPP; sc++) {
++ sc->sc_unit = i; /* XXX */
++ sprintf(sc->sc_if.if_xname, "ppp%d", i++);
++ sc->sc_if.if_softc = sc;
++ sc->sc_if.if_mtu = PPP_MTU;
++ sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
++ sc->sc_if.if_type = IFT_PPP;
++ sc->sc_if.if_hdrlen = PPP_HDRLEN;
++ sc->sc_if.if_ioctl = pppsioctl;
++ sc->sc_if.if_output = pppoutput;
++ sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
++ sc->sc_inq.ifq_maxlen = IFQ_MAXLEN;
++ sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN;
++ sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN;
++ if_attach(&sc->sc_if);
++#if NBPFILTER > 0
++ bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_NULL, 0);
++#endif
++ }
++}
++
++/*
++ * Allocate a ppp interface unit and initialize it.
++ */
++struct ppp_softc *
++pppalloc(pid)
++ pid_t pid;
++{
++ int nppp, i;
++ struct ppp_softc *sc;
++
++ for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++)
++ if (sc->sc_xfer == pid) {
++ sc->sc_xfer = 0;
++ return sc;
++ }
++ for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++)
++ if (sc->sc_devp == NULL)
++ break;
++ if (nppp >= NPPP)
++ return NULL;
++
++ sc->sc_flags = 0;
++ sc->sc_mru = PPP_MRU;
++ sc->sc_relinq = NULL;
++ bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats));
++#ifdef VJC
++ MALLOC(sc->sc_comp, struct slcompress *, sizeof(struct slcompress),
++ M_DEVBUF, M_NOWAIT);
++ if (sc->sc_comp)
++ sl_compress_init(sc->sc_comp);
++#endif
++#ifdef PPP_COMPRESS
++ sc->sc_xc_state = NULL;
++ sc->sc_rc_state = NULL;
++#endif /* PPP_COMPRESS */
++ for (i = 0; i < NUM_NP; ++i)
++ sc->sc_npmode[i] = NPMODE_ERROR;
++ sc->sc_npqueue = NULL;
++ sc->sc_npqtail = &sc->sc_npqueue;
++ sc->sc_last_sent = sc->sc_last_recv = time.tv_sec;
++
++ return sc;
++}
++
++/*
++ * Deallocate a ppp unit. Must be called at splsoftnet or higher.
++ */
++void
++pppdealloc(sc)
++ struct ppp_softc *sc;
++{
++ struct mbuf *m;
++
++ if_down(&sc->sc_if);
++ sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
++ sc->sc_devp = NULL;
++ sc->sc_xfer = 0;
++ for (;;) {
++ IF_DEQUEUE(&sc->sc_rawq, m);
++ if (m == NULL)
++ break;
++ m_freem(m);
++ }
++ for (;;) {
++ IF_DEQUEUE(&sc->sc_inq, m);
++ if (m == NULL)
++ break;
++ m_freem(m);
++ }
++ for (;;) {
++ IF_DEQUEUE(&sc->sc_fastq, m);
++ if (m == NULL)
++ break;
++ m_freem(m);
++ }
++ while ((m = sc->sc_npqueue) != NULL) {
++ sc->sc_npqueue = m->m_nextpkt;
++ m_freem(m);
++ }
++ if (sc->sc_togo != NULL) {
++ m_freem(sc->sc_togo);
++ sc->sc_togo = NULL;
++ }
++#ifdef PPP_COMPRESS
++ ppp_ccp_closed(sc);
++ sc->sc_xc_state = NULL;
++ sc->sc_rc_state = NULL;
++#endif /* PPP_COMPRESS */
++#ifdef PPP_FILTER
++ if (sc->sc_pass_filt_in.bf_insns != 0) {
++ FREE(sc->sc_pass_filt_in.bf_insns, M_DEVBUF);
++ sc->sc_pass_filt_in.bf_insns = 0;
++ sc->sc_pass_filt_in.bf_len = 0;
++ }
++ if (sc->sc_pass_filt_out.bf_insns != 0) {
++ FREE(sc->sc_pass_filt_out.bf_insns, M_DEVBUF);
++ sc->sc_pass_filt_out.bf_insns = 0;
++ sc->sc_pass_filt_out.bf_len = 0;
++ }
++ if (sc->sc_active_filt_in.bf_insns != 0) {
++ FREE(sc->sc_active_filt_in.bf_insns, M_DEVBUF);
++ sc->sc_active_filt_in.bf_insns = 0;
++ sc->sc_active_filt_in.bf_len = 0;
++ }
++ if (sc->sc_active_filt_out.bf_insns != 0) {
++ FREE(sc->sc_active_filt_out.bf_insns, M_DEVBUF);
++ sc->sc_active_filt_out.bf_insns = 0;
++ sc->sc_active_filt_out.bf_len = 0;
++ }
++#endif /* PPP_FILTER */
++#ifdef VJC
++ if (sc->sc_comp != 0) {
++ FREE(sc->sc_comp, M_DEVBUF);
++ sc->sc_comp = 0;
++ }
++#endif
++}
++
++/*
++ * Ioctl routine for generic ppp devices.
++ */
++int
++pppioctl(sc, cmd, data, flag, p)
++ struct ppp_softc *sc;
++ u_long cmd;
++ caddr_t data;
++ int flag;
++ struct proc *p;
++{
++ int s, error, flags, mru, nb, npx;
++ struct ppp_option_data *odp;
++ struct compressor **cp;
++ struct npioctl *npi;
++ time_t t;
++#ifdef PPP_FILTER
++ struct bpf_program *bp, *nbp;
++ struct bpf_insn *newcode, *oldcode;
++ int newcodelen;
++#endif /* PPP_FILTER */
++#ifdef PPP_COMPRESS
++ u_char ccp_option[CCP_MAX_OPTION_LENGTH];
++#endif
++
++ switch (cmd) {
++ case FIONREAD:
++ *(int *)data = sc->sc_inq.ifq_len;
++ break;
++
++ case PPPIOCGUNIT:
++ *(int *)data = sc->sc_unit; /* XXX */
++ break;
++
++ case PPPIOCGFLAGS:
++ *(u_int *)data = sc->sc_flags;
++ break;
++
++ case PPPIOCSFLAGS:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ return (error);
++ flags = *(int *)data & SC_MASK;
++ s = splsoftnet();
++#ifdef PPP_COMPRESS
++ if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN))
++ ppp_ccp_closed(sc);
++#endif
++ splimp();
++ sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags;
++ splx(s);
++ break;
++
++ case PPPIOCSMRU:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ return (error);
++ mru = *(int *)data;
++ if (mru >= PPP_MRU && mru <= PPP_MAXMRU)
++ sc->sc_mru = mru;
++ break;
++
++ case PPPIOCGMRU:
++ *(int *)data = sc->sc_mru;
++ break;
++
++#ifdef VJC
++ case PPPIOCSMAXCID:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ return (error);
++ if (sc->sc_comp) {
++ s = splsoftnet();
++ sl_compress_setup(sc->sc_comp, *(int *)data);
++ splx(s);
++ }
++ break;
++#endif
++
++ case PPPIOCXFERUNIT:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ return (error);
++ sc->sc_xfer = p->p_pid;
++ break;
++
++#ifdef PPP_COMPRESS
++ case PPPIOCSCOMPRESS:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ return (error);
++ odp = (struct ppp_option_data *) data;
++ nb = odp->length;
++ if (nb > sizeof(ccp_option))
++ nb = sizeof(ccp_option);
++ if ((error = copyin(odp->ptr, ccp_option, nb)) != 0)
++ return (error);
++ if (ccp_option[1] < 2) /* preliminary check on the length byte */
++ return (EINVAL);
++ for (cp = ppp_compressors; *cp != NULL; ++cp)
++ if ((*cp)->compress_proto == ccp_option[0]) {
++ /*
++ * Found a handler for the protocol - try to allocate
++ * a compressor or decompressor.
++ */
++ error = 0;
++ if (odp->transmit) {
++ s = splsoftnet();
++ if (sc->sc_xc_state != NULL)
++ (*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
++ sc->sc_xcomp = *cp;
++ sc->sc_xc_state = (*cp)->comp_alloc(ccp_option, nb);
++ if (sc->sc_xc_state == NULL) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: comp_alloc failed\n",
++ sc->sc_if.if_xname);
++ error = ENOBUFS;
++ }
++ splimp();
++ sc->sc_flags &= ~SC_COMP_RUN;
++ splx(s);
++ } else {
++ s = splsoftnet();
++ if (sc->sc_rc_state != NULL)
++ (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
++ sc->sc_rcomp = *cp;
++ sc->sc_rc_state = (*cp)->decomp_alloc(ccp_option, nb);
++ if (sc->sc_rc_state == NULL) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: decomp_alloc failed\n",
++ sc->sc_if.if_xname);
++ error = ENOBUFS;
++ }
++ splimp();
++ sc->sc_flags &= ~SC_DECOMP_RUN;
++ splx(s);
++ }
++ return (error);
++ }
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: no compressor for [%x %x %x], %x\n",
++ sc->sc_if.if_xname, ccp_option[0], ccp_option[1],
++ ccp_option[2], nb);
++ return (EINVAL); /* no handler found */
++#endif /* PPP_COMPRESS */
++
++ case PPPIOCGNPMODE:
++ case PPPIOCSNPMODE:
++ npi = (struct npioctl *) data;
++ switch (npi->protocol) {
++ case PPP_IP:
++ npx = NP_IP;
++ break;
++ case PPP_IPV6:
++ npx = NP_IPV6;
++ break;
++ default:
++ return EINVAL;
++ }
++ if (cmd == PPPIOCGNPMODE) {
++ npi->mode = sc->sc_npmode[npx];
++ } else {
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ return (error);
++ if (npi->mode != sc->sc_npmode[npx]) {
++ s = splimp();
++ sc->sc_npmode[npx] = npi->mode;
++ if (npi->mode != NPMODE_QUEUE) {
++ ppp_requeue(sc);
++ ppp_restart(sc);
++ }
++ splx(s);
++ }
++ }
++ break;
++
++ case PPPIOCGIDLE:
++ s = splsoftnet();
++ t = time.tv_sec;
++ ((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
++ ((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
++ splx(s);
++ break;
++
++#ifdef PPP_FILTER
++ case PPPIOCSPASS:
++ case PPPIOCSACTIVE:
++ /* These are no longer supported. */
++ return EOPNOTSUPP;
++
++ case PPPIOCSIPASS:
++ case PPPIOCSOPASS:
++ case PPPIOCSIACTIVE:
++ case PPPIOCSOACTIVE:
++ nbp = (struct bpf_program *) data;
++ if ((unsigned) nbp->bf_len > BPF_MAXINSNS)
++ return EINVAL;
++ newcodelen = nbp->bf_len * sizeof(struct bpf_insn);
++ if (newcodelen != 0) {
++ newcode = malloc(newcodelen, M_DEVBUF, M_WAITOK);
++ /* WAITOK -- malloc() never fails. */
++ if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode,
++ newcodelen)) != 0) {
++ free(newcode, M_DEVBUF);
++ return error;
++ }
++ if (!bpf_validate(newcode, nbp->bf_len)) {
++ free(newcode, M_DEVBUF);
++ return EINVAL;
++ }
++ } else
++ newcode = 0;
++ switch (cmd) {
++ case PPPIOCSIPASS:
++ bp = &sc->sc_pass_filt_in;
++ break;
++
++ case PPPIOCSOPASS:
++ bp = &sc->sc_pass_filt_out;
++ break;
++
++ case PPPIOCSIACTIVE:
++ bp = &sc->sc_active_filt_in;
++ break;
++
++ case PPPIOCSOACTIVE:
++ bp = &sc->sc_active_filt_out;
++ break;
++ }
++ oldcode = bp->bf_insns;
++ s = splimp();
++ bp->bf_len = nbp->bf_len;
++ bp->bf_insns = newcode;
++ splx(s);
++ if (oldcode != 0)
++ free(oldcode, M_DEVBUF);
++ break;
++#endif /* PPP_FILTER */
++
++ default:
++ return (-1);
++ }
++ return (0);
++}
++
++/*
++ * Process an ioctl request to the ppp network interface.
++ */
++static int
++pppsioctl(ifp, cmd, data)
++ register struct ifnet *ifp;
++ u_long cmd;
++ caddr_t data;
++{
++ register struct proc *p = curproc; /* XXX */
++ register struct ppp_softc *sc = ifp->if_softc;
++ register struct ifaddr *ifa = (struct ifaddr *)data;
++ register struct ifreq *ifr = (struct ifreq *)data;
++ struct ppp_stats *psp;
++#ifdef PPP_COMPRESS
++ struct ppp_comp_stats *pcp;
++#endif
++ int s = splimp(), error = 0;
++
++ switch (cmd) {
++ case SIOCSIFFLAGS:
++ if ((ifp->if_flags & IFF_RUNNING) == 0)
++ ifp->if_flags &= ~IFF_UP;
++ break;
++
++ case SIOCSIFADDR:
++ switch (ifa->ifa_addr->sa_family) {
++#ifdef INET
++ case AF_INET:
++ break;
++#endif
++#ifdef INET6
++ case AF_INET6:
++ break;
++#endif
++ default:
++ error = EAFNOSUPPORT;
++ break;
++ }
++ break;
++
++ case SIOCSIFDSTADDR:
++ switch (ifa->ifa_addr->sa_family) {
++#ifdef INET
++ case AF_INET:
++ break;
++#endif
++#ifdef INET6
++ case AF_INET6:
++ break;
++#endif
++ default:
++ error = EAFNOSUPPORT;
++ break;
++ }
++ break;
++
++ case SIOCSIFMTU:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ break;
++ sc->sc_if.if_mtu = ifr->ifr_mtu;
++ break;
++
++ case SIOCGIFMTU:
++ ifr->ifr_mtu = sc->sc_if.if_mtu;
++ break;
++
++ case SIOCADDMULTI:
++ case SIOCDELMULTI:
++ if (ifr == 0) {
++ error = EAFNOSUPPORT;
++ break;
++ }
++ switch(ifr->ifr_addr.sa_family) {
++#ifdef INET
++ case AF_INET:
++ break;
++#endif
++#ifdef INET6
++ case AF_INET6:
++ break;
++#endif
++ default:
++ error = EAFNOSUPPORT;
++ break;
++ }
++ break;
++
++ case SIOCGPPPSTATS:
++ psp = &((struct ifpppstatsreq *) data)->stats;
++ bzero(psp, sizeof(*psp));
++ psp->p = sc->sc_stats;
++#if defined(VJC) && !defined(SL_NO_STATS)
++ if (sc->sc_comp) {
++ psp->vj.vjs_packets = sc->sc_comp->sls_packets;
++ psp->vj.vjs_compressed = sc->sc_comp->sls_compressed;
++ psp->vj.vjs_searches = sc->sc_comp->sls_searches;
++ psp->vj.vjs_misses = sc->sc_comp->sls_misses;
++ psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin;
++ psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin;
++ psp->vj.vjs_errorin = sc->sc_comp->sls_errorin;
++ psp->vj.vjs_tossed = sc->sc_comp->sls_tossed;
++ }
++#endif /* VJC */
++ break;
++
++#ifdef PPP_COMPRESS
++ case SIOCGPPPCSTATS:
++ pcp = &((struct ifpppcstatsreq *) data)->stats;
++ bzero(pcp, sizeof(*pcp));
++ if (sc->sc_xc_state != NULL)
++ (*sc->sc_xcomp->comp_stat)(sc->sc_xc_state, &pcp->c);
++ if (sc->sc_rc_state != NULL)
++ (*sc->sc_rcomp->decomp_stat)(sc->sc_rc_state, &pcp->d);
++ break;
++#endif /* PPP_COMPRESS */
++
++ default:
++ error = EINVAL;
++ }
++ splx(s);
++ return (error);
++}
++
++/*
++ * Queue a packet. Start transmission if not active.
++ * Packet is placed in Information field of PPP frame.
++ */
++int
++pppoutput(ifp, m0, dst, rtp)
++ struct ifnet *ifp;
++ struct mbuf *m0;
++ struct sockaddr *dst;
++ struct rtentry *rtp;
++{
++ register struct ppp_softc *sc = ifp->if_softc;
++ int protocol, address, control;
++ u_char *cp;
++ int s, error;
++ struct ip *ip;
++ struct ifqueue *ifq;
++ enum NPmode mode;
++ int len;
++ struct mbuf *m;
++
++ if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0
++ || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) {
++ error = ENETDOWN; /* sort of */
++ goto bad;
++ }
++
++ /*
++ * Compute PPP header.
++ */
++ m0->m_flags &= ~M_HIGHPRI;
++ switch (dst->sa_family) {
++#ifdef INET
++ case AF_INET:
++ address = PPP_ALLSTATIONS;
++ control = PPP_UI;
++ protocol = PPP_IP;
++ mode = sc->sc_npmode[NP_IP];
++
++ /*
++ * If this packet has the "low delay" bit set in the IP header,
++ * put it on the fastq instead.
++ */
++ ip = mtod(m0, struct ip *);
++ if (ip->ip_tos & IPTOS_LOWDELAY)
++ m0->m_flags |= M_HIGHPRI;
++ break;
++#endif
++#ifdef INET6
++ case AF_INET6:
++ address = PPP_ALLSTATIONS; /*XXX*/
++ control = PPP_UI; /*XXX*/
++ protocol = PPP_IPV6;
++ mode = sc->sc_npmode[NP_IPV6];
++
++#if 0 /* XXX flowinfo/traffic class, maybe? */
++ /*
++ * If this packet has the "low delay" bit set in the IP header,
++ * put it on the fastq instead.
++ */
++ ip = mtod(m0, struct ip *);
++ if (ip->ip_tos & IPTOS_LOWDELAY)
++ m0->m_flags |= M_HIGHPRI;
++ break;
++#endif
++#endif
++ case AF_UNSPEC:
++ address = PPP_ADDRESS(dst->sa_data);
++ control = PPP_CONTROL(dst->sa_data);
++ protocol = PPP_PROTOCOL(dst->sa_data);
++ mode = NPMODE_PASS;
++ break;
++ default:
++ printf("%s: af%d not supported\n", ifp->if_xname, dst->sa_family);
++ error = EAFNOSUPPORT;
++ goto bad;
++ }
++
++ /*
++ * Drop this packet, or return an error, if necessary.
++ */
++ if (mode == NPMODE_ERROR) {
++ error = ENETDOWN;
++ goto bad;
++ }
++ if (mode == NPMODE_DROP) {
++ error = 0;
++ goto bad;
++ }
++
++ /*
++ * Add PPP header. If no space in first mbuf, allocate another.
++ * (This assumes M_LEADINGSPACE is always 0 for a cluster mbuf.)
++ */
++ if (M_LEADINGSPACE(m0) < PPP_HDRLEN) {
++ m0 = m_prepend(m0, PPP_HDRLEN, M_DONTWAIT);
++ if (m0 == 0) {
++ error = ENOBUFS;
++ goto bad;
++ }
++ m0->m_len = 0;
++ } else
++ m0->m_data -= PPP_HDRLEN;
++
++ cp = mtod(m0, u_char *);
++ *cp++ = address;
++ *cp++ = control;
++ *cp++ = protocol >> 8;
++ *cp++ = protocol & 0xff;
++ m0->m_len += PPP_HDRLEN;
++
++ len = 0;
++ for (m = m0; m != 0; m = m->m_next)
++ len += m->m_len;
++
++ if (sc->sc_flags & SC_LOG_OUTPKT) {
++ printf("%s output: ", ifp->if_xname);
++ pppdumpm(m0);
++ }
++
++ if ((protocol & 0x8000) == 0) {
++#ifdef PPP_FILTER
++ /*
++ * Apply the pass and active filters to the packet,
++ * but only if it is a data packet.
++ */
++ if (sc->sc_pass_filt_out.bf_insns != 0
++ && bpf_filter(sc->sc_pass_filt_out.bf_insns, (u_char *) m0,
++ len, 0) == 0) {
++ error = 0; /* drop this packet */
++ goto bad;
++ }
++
++ /*
++ * Update the time we sent the most recent packet.
++ */
++ if (sc->sc_active_filt_out.bf_insns == 0
++ || bpf_filter(sc->sc_active_filt_out.bf_insns, (u_char *) m0,
++ len, 0))
++ sc->sc_last_sent = time.tv_sec;
++#else
++ /*
++ * Update the time we sent the most recent packet.
++ */
++ sc->sc_last_sent = time.tv_sec;
++#endif /* PPP_FILTER */
++ }
++
++#if NBPFILTER > 0
++ /*
++ * See if bpf wants to look at the packet.
++ */
++ if (sc->sc_bpf)
++ bpf_mtap(sc->sc_bpf, m0);
++#endif
++
++ /*
++ * Put the packet on the appropriate queue.
++ */
++ s = splimp();
++ if (mode == NPMODE_QUEUE) {
++ /* XXX we should limit the number of packets on this queue */
++ *sc->sc_npqtail = m0;
++ m0->m_nextpkt = NULL;
++ sc->sc_npqtail = &m0->m_nextpkt;
++ } else {
++ ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd;
++ if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) {
++ IF_DROP(ifq);
++ splx(s);
++ sc->sc_if.if_oerrors++;
++ sc->sc_stats.ppp_oerrors++;
++ error = ENOBUFS;
++ goto bad;
++ }
++ IF_ENQUEUE(ifq, m0);
++ ppp_restart(sc);
++ }
++ ifp->if_lastchange = time;
++ ifp->if_opackets++;
++ ifp->if_obytes += len;
++
++ splx(s);
++ return (0);
++
++bad:
++ m_freem(m0);
++ return (error);
++}
++
++/*
++ * After a change in the NPmode for some NP, move packets from the
++ * npqueue to the send queue or the fast queue as appropriate.
++ * Should be called at splimp, since we muck with the queues.
++ */
++static void
++ppp_requeue(sc)
++ struct ppp_softc *sc;
++{
++ struct mbuf *m, **mpp;
++ struct ifqueue *ifq;
++ enum NPmode mode;
++
++ for (mpp = &sc->sc_npqueue; (m = *mpp) != NULL; ) {
++ switch (PPP_PROTOCOL(mtod(m, u_char *))) {
++ case PPP_IP:
++ mode = sc->sc_npmode[NP_IP];
++ break;
++ case PPP_IPV6:
++ mode = sc->sc_npmode[NP_IPV6];
++ break;
++ default:
++ mode = NPMODE_PASS;
++ }
++
++ switch (mode) {
++ case NPMODE_PASS:
++ /*
++ * This packet can now go on one of the queues to be sent.
++ */
++ *mpp = m->m_nextpkt;
++ m->m_nextpkt = NULL;
++ ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd;
++ if (IF_QFULL(ifq)) {
++ IF_DROP(ifq);
++ sc->sc_if.if_oerrors++;
++ sc->sc_stats.ppp_oerrors++;
++ } else
++ IF_ENQUEUE(ifq, m);
++ break;
++
++ case NPMODE_DROP:
++ case NPMODE_ERROR:
++ *mpp = m->m_nextpkt;
++ m_freem(m);
++ break;
++
++ case NPMODE_QUEUE:
++ mpp = &m->m_nextpkt;
++ break;
++ }
++ }
++ sc->sc_npqtail = mpp;
++}
++
++/*
++ * Transmitter has finished outputting some stuff;
++ * remember to call sc->sc_start later at splsoftnet.
++ */
++void
++ppp_restart(sc)
++ struct ppp_softc *sc;
++{
++ int s = splimp();
++
++ sc->sc_flags &= ~SC_TBUSY;
++ schednetisr(NETISR_PPP);
++ splx(s);
++}
++
++/*
++ * Get a packet to send. This procedure is intended to be called at
++ * splsoftnet, since it may involve time-consuming operations such as
++ * applying VJ compression, packet compression, address/control and/or
++ * protocol field compression to the packet.
++ */
++struct mbuf *
++ppp_dequeue(sc)
++ struct ppp_softc *sc;
++{
++ struct mbuf *m, *mp;
++ u_char *cp;
++ int address, control, protocol;
++ int s;
++
++ /*
++ * Grab a packet to send: first try the fast queue, then the
++ * normal queue.
++ */
++ s = splimp();
++ IF_DEQUEUE(&sc->sc_fastq, m);
++ if (m == NULL)
++ IF_DEQUEUE(&sc->sc_if.if_snd, m);
++ splx(s);
++
++ if (m == NULL)
++ return NULL;
++
++ ++sc->sc_stats.ppp_opackets;
++
++ /*
++ * Extract the ppp header of the new packet.
++ * The ppp header will be in one mbuf.
++ */
++ cp = mtod(m, u_char *);
++ address = PPP_ADDRESS(cp);
++ control = PPP_CONTROL(cp);
++ protocol = PPP_PROTOCOL(cp);
++
++ switch (protocol) {
++ case PPP_IP:
++#ifdef VJC
++ /*
++ * If the packet is a TCP/IP packet, see if we can compress it.
++ */
++ if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) {
++ struct ip *ip;
++ int type;
++
++ mp = m;
++ ip = (struct ip *) (cp + PPP_HDRLEN);
++ if (mp->m_len <= PPP_HDRLEN) {
++ mp = mp->m_next;
++ if (mp == NULL)
++ break;
++ ip = mtod(mp, struct ip *);
++ }
++ /* this code assumes the IP/TCP header is in one non-shared mbuf */
++ if (ip->ip_p == IPPROTO_TCP) {
++ type = sl_compress_tcp(mp, ip, sc->sc_comp,
++ !(sc->sc_flags & SC_NO_TCP_CCID));
++ switch (type) {
++ case TYPE_UNCOMPRESSED_TCP:
++ protocol = PPP_VJC_UNCOMP;
++ break;
++ case TYPE_COMPRESSED_TCP:
++ protocol = PPP_VJC_COMP;
++ cp = mtod(m, u_char *);
++ cp[0] = address; /* header has moved */
++ cp[1] = control;
++ cp[2] = 0;
++ break;
++ }
++ cp[3] = protocol; /* update protocol in PPP header */
++ }
++ }
++#endif /* VJC */
++ break;
++
++#ifdef PPP_COMPRESS
++ case PPP_CCP:
++ ppp_ccp(sc, m, 0);
++ break;
++#endif /* PPP_COMPRESS */
++ }
++
++#ifdef PPP_COMPRESS
++ if (protocol != PPP_LCP && protocol != PPP_CCP
++ && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
++ struct mbuf *mcomp = NULL;
++ int slen, clen;
++
++ slen = 0;
++ for (mp = m; mp != NULL; mp = mp->m_next)
++ slen += mp->m_len;
++ clen = (*sc->sc_xcomp->compress)
++ (sc->sc_xc_state, &mcomp, m, slen, sc->sc_if.if_mtu + PPP_HDRLEN);
++ if (mcomp != NULL) {
++ if (sc->sc_flags & SC_CCP_UP) {
++ /* Send the compressed packet instead of the original. */
++ m_freem(m);
++ m = mcomp;
++ cp = mtod(m, u_char *);
++ protocol = cp[3];
++ } else {
++ /* Can't transmit compressed packets until CCP is up. */
++ m_freem(mcomp);
++ }
++ }
++ }
++#endif /* PPP_COMPRESS */
++
++ /*
++ * Compress the address/control and protocol, if possible.
++ */
++ if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS &&
++ control == PPP_UI && protocol != PPP_ALLSTATIONS &&
++ protocol != PPP_LCP) {
++ /* can compress address/control */
++ m->m_data += 2;
++ m->m_len -= 2;
++ }
++ if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) {
++ /* can compress protocol */
++ if (mtod(m, u_char *) == cp) {
++ cp[2] = cp[1]; /* move address/control up */
++ cp[1] = cp[0];
++ }
++ ++m->m_data;
++ --m->m_len;
++ }
++
++ return m;
++}
++
++/*
++ * Software interrupt routine, called at splsoftnet.
++ */
++void
++pppintr()
++{
++ struct ppp_softc *sc;
++ int i, s, s2;
++ struct mbuf *m;
++
++ sc = ppp_softc;
++ s = splsoftnet();
++ for (i = 0; i < NPPP; ++i, ++sc) {
++ if (!(sc->sc_flags & SC_TBUSY)
++ && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head
++ || sc->sc_outm)) {
++ s2 = splimp();
++ sc->sc_flags |= SC_TBUSY;
++ splx(s2);
++ (*sc->sc_start)(sc);
++ }
++ for (;;) {
++ s2 = splimp();
++ IF_DEQUEUE(&sc->sc_rawq, m);
++ splx(s2);
++ if (m == NULL)
++ break;
++ ppp_inproc(sc, m);
++ }
++ }
++ splx(s);
++}
++
++#ifdef PPP_COMPRESS
++/*
++ * Handle a CCP packet. `rcvd' is 1 if the packet was received,
++ * 0 if it is about to be transmitted.
++ */
++static void
++ppp_ccp(sc, m, rcvd)
++ struct ppp_softc *sc;
++ struct mbuf *m;
++ int rcvd;
++{
++ u_char *dp, *ep;
++ struct mbuf *mp;
++ int slen, s;
++
++ /*
++ * Get a pointer to the data after the PPP header.
++ */
++ if (m->m_len <= PPP_HDRLEN) {
++ mp = m->m_next;
++ if (mp == NULL)
++ return;
++ dp = (mp != NULL)? mtod(mp, u_char *): NULL;
++ } else {
++ mp = m;
++ dp = mtod(mp, u_char *) + PPP_HDRLEN;
++ }
++
++ ep = mtod(mp, u_char *) + mp->m_len;
++ if (dp + CCP_HDRLEN > ep)
++ return;
++ slen = CCP_LENGTH(dp);
++ if (dp + slen > ep) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("if_ppp/ccp: not enough data in mbuf (%p+%x > %p+%x)\n",
++ dp, slen, mtod(mp, u_char *), mp->m_len);
++ return;
++ }
++
++ switch (CCP_CODE(dp)) {
++ case CCP_CONFREQ:
++ case CCP_TERMREQ:
++ case CCP_TERMACK:
++ /* CCP must be going down - disable compression */
++ if (sc->sc_flags & SC_CCP_UP) {
++ s = splimp();
++ sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN);
++ splx(s);
++ }
++ break;
++
++ case CCP_CONFACK:
++ if (sc->sc_flags & SC_CCP_OPEN && !(sc->sc_flags & SC_CCP_UP)
++ && slen >= CCP_HDRLEN + CCP_OPT_MINLEN
++ && slen >= CCP_OPT_LENGTH(dp + CCP_HDRLEN) + CCP_HDRLEN) {
++ if (!rcvd) {
++ /* we're agreeing to send compressed packets. */
++ if (sc->sc_xc_state != NULL
++ && (*sc->sc_xcomp->comp_init)
++ (sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
++ sc->sc_unit, 0, sc->sc_flags & SC_DEBUG)) {
++ s = splimp();
++ sc->sc_flags |= SC_COMP_RUN;
++ splx(s);
++ }
++ } else {
++ /* peer is agreeing to send compressed packets. */
++ if (sc->sc_rc_state != NULL
++ && (*sc->sc_rcomp->decomp_init)
++ (sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
++ sc->sc_unit, 0, sc->sc_mru,
++ sc->sc_flags & SC_DEBUG)) {
++ s = splimp();
++ sc->sc_flags |= SC_DECOMP_RUN;
++ sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR);
++ splx(s);
++ }
++ }
++ }
++ break;
++
++ case CCP_RESETACK:
++ if (sc->sc_flags & SC_CCP_UP) {
++ if (!rcvd) {
++ if (sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN))
++ (*sc->sc_xcomp->comp_reset)(sc->sc_xc_state);
++ } else {
++ if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) {
++ (*sc->sc_rcomp->decomp_reset)(sc->sc_rc_state);
++ s = splimp();
++ sc->sc_flags &= ~SC_DC_ERROR;
++ splx(s);
++ }
++ }
++ }
++ break;
++ }
++}
++
++/*
++ * CCP is down; free (de)compressor state if necessary.
++ */
++static void
++ppp_ccp_closed(sc)
++ struct ppp_softc *sc;
++{
++ if (sc->sc_xc_state) {
++ (*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
++ sc->sc_xc_state = NULL;
++ }
++ if (sc->sc_rc_state) {
++ (*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
++ sc->sc_rc_state = NULL;
++ }
++}
++#endif /* PPP_COMPRESS */
++
++/*
++ * PPP packet input routine.
++ * The caller has checked and removed the FCS and has inserted
++ * the address/control bytes and the protocol high byte if they
++ * were omitted.
++ */
++void
++ppppktin(sc, m, lost)
++ struct ppp_softc *sc;
++ struct mbuf *m;
++ int lost;
++{
++ int s = splimp();
++
++ if (lost)
++ m->m_flags |= M_ERRMARK;
++ IF_ENQUEUE(&sc->sc_rawq, m);
++ schednetisr(NETISR_PPP);
++ splx(s);
++}
++
++/*
++ * Process a received PPP packet, doing decompression as necessary.
++ * Should be called at splsoftnet.
++ */
++#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
++ TYPE_UNCOMPRESSED_TCP)
++
++static void
++ppp_inproc(sc, m)
++ struct ppp_softc *sc;
++ struct mbuf *m;
++{
++ struct ifnet *ifp = &sc->sc_if;
++ struct ifqueue *inq;
++ int s, ilen, xlen, proto, rv;
++ u_char *cp, adrs, ctrl;
++ struct mbuf *mp, *dmp = NULL;
++ u_char *iphdr;
++ u_int hlen;
++
++ sc->sc_stats.ppp_ipackets++;
++
++ if (sc->sc_flags & SC_LOG_INPKT) {
++ ilen = 0;
++ for (mp = m; mp != NULL; mp = mp->m_next)
++ ilen += mp->m_len;
++ printf("%s: got %d bytes\n", ifp->if_xname, ilen);
++ pppdumpm(m);
++ }
++
++ cp = mtod(m, u_char *);
++ adrs = PPP_ADDRESS(cp);
++ ctrl = PPP_CONTROL(cp);
++ proto = PPP_PROTOCOL(cp);
++
++ if (m->m_flags & M_ERRMARK) {
++ m->m_flags &= ~M_ERRMARK;
++ s = splimp();
++ sc->sc_flags |= SC_VJ_RESET;
++ splx(s);
++ }
++
++#ifdef PPP_COMPRESS
++ /*
++ * Decompress this packet if necessary, update the receiver's
++ * dictionary, or take appropriate action on a CCP packet.
++ */
++ if (proto == PPP_COMP && sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)
++ && !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) {
++ /* decompress this packet */
++ rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp);
++ if (rv == DECOMP_OK) {
++ m_freem(m);
++ if (dmp == NULL) {
++ /* no error, but no decompressed packet produced */
++ return;
++ }
++ m = dmp;
++ cp = mtod(m, u_char *);
++ proto = PPP_PROTOCOL(cp);
++
++ } else {
++ /*
++ * An error has occurred in decompression.
++ * Pass the compressed packet up to pppd, which may take
++ * CCP down or issue a Reset-Req.
++ */
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: decompress failed %d\n", ifp->if_xname, rv);
++ s = splimp();
++ sc->sc_flags |= SC_VJ_RESET;
++ if (rv == DECOMP_ERROR)
++ sc->sc_flags |= SC_DC_ERROR;
++ else
++ sc->sc_flags |= SC_DC_FERROR;
++ splx(s);
++ }
++
++ } else {
++ if (sc->sc_rc_state && (sc->sc_flags & SC_DECOMP_RUN)) {
++ (*sc->sc_rcomp->incomp)(sc->sc_rc_state, m);
++ }
++ if (proto == PPP_CCP) {
++ ppp_ccp(sc, m, 1);
++ }
++ }
++#endif
++
++ ilen = 0;
++ for (mp = m; mp != NULL; mp = mp->m_next)
++ ilen += mp->m_len;
++
++#ifdef VJC
++ if (sc->sc_flags & SC_VJ_RESET) {
++ /*
++ * If we've missed a packet, we must toss subsequent compressed
++ * packets which don't have an explicit connection ID.
++ */
++ if (sc->sc_comp)
++ sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp);
++ s = splimp();
++ sc->sc_flags &= ~SC_VJ_RESET;
++ splx(s);
++ }
++
++ /*
++ * See if we have a VJ-compressed packet to uncompress.
++ */
++ if (proto == PPP_VJC_COMP) {
++ if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
++ goto bad;
++
++ xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
++ ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP,
++ sc->sc_comp, &iphdr, &hlen);
++
++ if (xlen <= 0) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: VJ uncompress failed on type comp\n",
++ ifp->if_xname);
++ goto bad;
++ }
++
++ /* Copy the PPP and IP headers into a new mbuf. */
++ MGETHDR(mp, M_DONTWAIT, MT_DATA);
++ if (mp == NULL)
++ goto bad;
++ mp->m_len = 0;
++ mp->m_next = NULL;
++ if (hlen + PPP_HDRLEN > MHLEN) {
++ MCLGET(mp, M_DONTWAIT);
++ if (M_TRAILINGSPACE(mp) < hlen + PPP_HDRLEN) {
++ m_freem(mp);
++ goto bad; /* lose if big headers and no clusters */
++ }
++ }
++ cp = mtod(mp, u_char *);
++ cp[0] = adrs;
++ cp[1] = ctrl;
++ cp[2] = 0;
++ cp[3] = PPP_IP;
++ proto = PPP_IP;
++ bcopy(iphdr, cp + PPP_HDRLEN, hlen);
++ mp->m_len = hlen + PPP_HDRLEN;
++
++ /*
++ * Trim the PPP and VJ headers off the old mbuf
++ * and stick the new and old mbufs together.
++ */
++ m->m_data += PPP_HDRLEN + xlen;
++ m->m_len -= PPP_HDRLEN + xlen;
++ if (m->m_len <= M_TRAILINGSPACE(mp)) {
++ bcopy(mtod(m, u_char *), mtod(mp, u_char *) + mp->m_len, m->m_len);
++ mp->m_len += m->m_len;
++ MFREE(m, mp->m_next);
++ } else
++ mp->m_next = m;
++ m = mp;
++ ilen += hlen - xlen;
++
++ } else if (proto == PPP_VJC_UNCOMP) {
++ if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0)
++ goto bad;
++
++ xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN,
++ ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP,
++ sc->sc_comp, &iphdr, &hlen);
++
++ if (xlen < 0) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: VJ uncompress failed on type uncomp\n",
++ ifp->if_xname);
++ goto bad;
++ }
++
++ proto = PPP_IP;
++ cp[3] = PPP_IP;
++ }
++#endif /* VJC */
++
++ /*
++ * If the packet will fit in a header mbuf, don't waste a
++ * whole cluster on it.
++ */
++ if (ilen <= MHLEN && M_IS_CLUSTER(m)) {
++ MGETHDR(mp, M_DONTWAIT, MT_DATA);
++ if (mp != NULL) {
++ m_copydata(m, 0, ilen, mtod(mp, caddr_t));
++ m_freem(m);
++ m = mp;
++ m->m_len = ilen;
++ }
++ }
++ m->m_pkthdr.len = ilen;
++ m->m_pkthdr.rcvif = ifp;
++
++ if ((proto & 0x8000) == 0) {
++#ifdef PPP_FILTER
++ /*
++ * See whether we want to pass this packet, and
++ * if it counts as link activity.
++ */
++ if (sc->sc_pass_filt_in.bf_insns != 0
++ && bpf_filter(sc->sc_pass_filt_in.bf_insns, (u_char *) m,
++ ilen, 0) == 0) {
++ /* drop this packet */
++ m_freem(m);
++ return;
++ }
++ if (sc->sc_active_filt_in.bf_insns == 0
++ || bpf_filter(sc->sc_active_filt_in.bf_insns, (u_char *) m,
++ ilen, 0))
++ sc->sc_last_recv = time.tv_sec;
++#else
++ /*
++ * Record the time that we received this packet.
++ */
++ sc->sc_last_recv = time.tv_sec;
++#endif /* PPP_FILTER */
++ }
++
++#if NBPFILTER > 0
++ /* See if bpf wants to look at the packet. */
++ if (sc->sc_bpf)
++ bpf_mtap(sc->sc_bpf, m);
++#endif
++
++ rv = 0;
++ switch (proto) {
++#ifdef INET
++ case PPP_IP:
++ /*
++ * IP packet - take off the ppp header and pass it up to IP.
++ */
++ if ((ifp->if_flags & IFF_UP) == 0
++ || sc->sc_npmode[NP_IP] != NPMODE_PASS) {
++ /* interface is down - drop the packet. */
++ m_freem(m);
++ return;
++ }
++ m->m_pkthdr.len -= PPP_HDRLEN;
++ m->m_data += PPP_HDRLEN;
++ m->m_len -= PPP_HDRLEN;
++#ifdef GATEWAY
++ if (ipflow_fastforward(m))
++ return;
++#endif
++ schednetisr(NETISR_IP);
++ inq = &ipintrq;
++ break;
++#endif
++
++#ifdef INET6
++ case PPP_IPV6:
++ /*
++ * IPv6 packet - take off the ppp header and pass it up to IPv6.
++ */
++ if ((ifp->if_flags & IFF_UP) == 0
++ || sc->sc_npmode[NP_IPV6] != NPMODE_PASS) {
++ /* interface is down - drop the packet. */
++ m_freem(m);
++ return;
++ }
++ m->m_pkthdr.len -= PPP_HDRLEN;
++ m->m_data += PPP_HDRLEN;
++ m->m_len -= PPP_HDRLEN;
++ schednetisr(NETISR_IPV6);
++ inq = &ip6intrq;
++ break;
++#endif
++
++ default:
++ /*
++ * Some other protocol - place on input queue for read().
++ */
++ inq = &sc->sc_inq;
++ rv = 1;
++ break;
++ }
++
++ /*
++ * Put the packet on the appropriate input queue.
++ */
++ s = splimp();
++ if (IF_QFULL(inq)) {
++ IF_DROP(inq);
++ splx(s);
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: input queue full\n", ifp->if_xname);
++ ifp->if_iqdrops++;
++ goto bad;
++ }
++ IF_ENQUEUE(inq, m);
++ splx(s);
++ ifp->if_ipackets++;
++ ifp->if_ibytes += ilen;
++ ifp->if_lastchange = time;
++
++ if (rv)
++ (*sc->sc_ctlp)(sc);
++
++ return;
++
++ bad:
++ m_freem(m);
++ sc->sc_if.if_ierrors++;
++ sc->sc_stats.ppp_ierrors++;
++}
++
++#define MAX_DUMP_BYTES 128
++
++static void
++pppdumpm(m0)
++ struct mbuf *m0;
++{
++ char buf[3*MAX_DUMP_BYTES+4];
++ char *bp = buf;
++ struct mbuf *m;
++ static char digits[] = "0123456789abcdef";
++
++ for (m = m0; m; m = m->m_next) {
++ int l = m->m_len;
++ u_char *rptr = (u_char *)m->m_data;
++
++ while (l--) {
++ if (bp > buf + sizeof(buf) - 4)
++ goto done;
++ *bp++ = digits[*rptr >> 4]; /* convert byte to ascii hex */
++ *bp++ = digits[*rptr++ & 0xf];
++ }
++
++ if (m->m_next) {
++ if (bp > buf + sizeof(buf) - 3)
++ goto done;
++ *bp++ = '|';
++ } else
++ *bp++ = ' ';
++ }
++done:
++ if (m)
++ *bp++ = '>';
++ *bp = 0;
++ printf("%s\n", buf);
++}
++
++#endif /* NPPP > 0 */
diff --git a/net/ppp-mppe/patches/patch-aq b/net/ppp-mppe/patches/patch-aq
new file mode 100644
index 00000000000..3bbe00c6da6
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-aq
@@ -0,0 +1,131 @@
+$NetBSD: patch-aq,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 04:00:15 1999
++++ netbsd-1.4/if_pppvar.h Sat Sep 18 04:06:25 1999
+@@ -0,0 +1,126 @@
++/* NetBSD: if_pppvar.h,v 1.10 1999/07/30 10:35:38 itojun Exp */
++/* Id: if_pppvar.h,v 1.3 1996/07/01 01:04:37 paulus Exp */
++
++/*
++ * if_pppvar.h - private structures and declarations for PPP.
++ *
++ * Copyright (c) 1994 The Australian National University.
++ * All rights reserved.
++ *
++ * Permission to use, copy, modify, and distribute this software and its
++ * documentation is hereby granted, provided that the above copyright
++ * notice appears in all copies. This software is provided without any
++ * warranty, express or implied. The Australian National University
++ * makes no representations about the suitability of this software for
++ * any purpose.
++ *
++ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
++ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
++ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
++ * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
++ * OF SUCH DAMAGE.
++ *
++ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
++ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
++ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
++ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
++ * OR MODIFICATIONS.
++ *
++ * Copyright (c) 1989 Carnegie Mellon University.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms are permitted
++ * provided that the above copyright notice and this paragraph are
++ * duplicated in all such forms and that any documentation,
++ * advertising materials, and other materials related to such
++ * distribution and use acknowledge that the software was developed
++ * by Carnegie Mellon University. The name of the
++ * University may not be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ */
++
++#ifndef _NET_IF_PPPVAR_H_
++#define _NET_IF_PPPVAR_H_
++
++/*
++ * Supported network protocols. These values are used for
++ * indexing sc_npmode.
++ */
++#define NP_IP 0 /* Internet Protocol */
++#define NP_IPV6 1 /* Internet Protocol version 6 */
++#define NUM_NP 2 /* Number of NPs. */
++
++/*
++ * Structure describing each ppp unit.
++ */
++struct ppp_softc {
++ struct ifnet sc_if; /* network-visible interface */
++ int sc_unit; /* XXX unit number */
++ u_int sc_flags; /* control/status bits; see if_ppp.h */
++ void *sc_devp; /* pointer to device-dep structure */
++ void (*sc_start) __P((struct ppp_softc *)); /* start output proc */
++ void (*sc_ctlp) __P((struct ppp_softc *)); /* rcvd control pkt */
++ void (*sc_relinq) __P((struct ppp_softc *)); /* relinquish ifunit */
++ u_int16_t sc_mru; /* max receive unit */
++ pid_t sc_xfer; /* used in transferring unit */
++ struct ifqueue sc_rawq; /* received packets */
++ struct ifqueue sc_inq; /* queue of input packets for daemon */
++ struct ifqueue sc_fastq; /* interactive output packet q */
++ struct mbuf *sc_togo; /* output packet ready to go */
++ struct mbuf *sc_npqueue; /* output packets not to be sent yet */
++ struct mbuf **sc_npqtail; /* ptr to last next ptr in npqueue */
++ struct pppstat sc_stats; /* count of bytes/pkts sent/rcvd */
++ caddr_t sc_bpf; /* hook for BPF */
++ enum NPmode sc_npmode[NUM_NP]; /* what to do with each NP */
++ struct compressor *sc_xcomp; /* transmit compressor */
++ void *sc_xc_state; /* transmit compressor state */
++ struct compressor *sc_rcomp; /* receive decompressor */
++ void *sc_rc_state; /* receive decompressor state */
++ time_t sc_last_sent; /* time (secs) last NP pkt sent */
++ time_t sc_last_recv; /* time (secs) last NP pkt rcvd */
++#ifdef PPP_FILTER
++ /* Filter for packets to pass. */
++ struct bpf_program sc_pass_filt_in;
++ struct bpf_program sc_pass_filt_out;
++
++ /* Filter for "non-idle" packets. */
++ struct bpf_program sc_active_filt_in;
++ struct bpf_program sc_active_filt_out;
++#endif /* PPP_FILTER */
++#ifdef VJC
++ struct slcompress *sc_comp; /* vjc control buffer */
++#endif
++
++ /* Device-dependent part for async lines. */
++ ext_accm sc_asyncmap; /* async control character map */
++ u_int32_t sc_rasyncmap; /* receive async control char map */
++ struct mbuf *sc_outm; /* mbuf chain currently being output */
++ struct mbuf *sc_m; /* pointer to input mbuf chain */
++ struct mbuf *sc_mc; /* pointer to current input mbuf */
++ char *sc_mp; /* ptr to next char in input mbuf */
++ u_int16_t sc_ilen; /* length of input packet so far */
++ u_int16_t sc_fcs; /* FCS so far (input) */
++ u_int16_t sc_outfcs; /* FCS so far for output packet */
++ u_char sc_rawin[16]; /* chars as received */
++ int sc_rawin_count; /* # in sc_rawin */
++};
++
++#ifdef _KERNEL
++struct ppp_softc ppp_softc[NPPP];
++
++struct ppp_softc *pppalloc __P((pid_t pid));
++void pppdealloc __P((struct ppp_softc *sc));
++int pppioctl __P((struct ppp_softc *sc, u_long cmd, caddr_t data,
++ int flag, struct proc *p));
++void ppp_restart __P((struct ppp_softc *sc));
++void ppppktin __P((struct ppp_softc *sc, struct mbuf *m, int lost));
++struct mbuf *ppp_dequeue __P((struct ppp_softc *sc));
++int pppoutput __P((struct ifnet *, struct mbuf *,
++ struct sockaddr *, struct rtentry *));
++#endif /* _KERNEL */
++
++#endif /* _NET_IF_PPPVAR_H_ */
diff --git a/net/ppp-mppe/patches/patch-ar b/net/ppp-mppe/patches/patch-ar
new file mode 100644
index 00000000000..df1a9ed8d73
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ar
@@ -0,0 +1,685 @@
+$NetBSD: patch-ar,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 04:00:15 1999
++++ netbsd-1.4/ppp-deflate.c Sat Sep 18 04:06:29 1999
+@@ -0,0 +1,680 @@
++/* NetBSD: ppp-deflate.c,v 1.6 1998/05/02 14:34:25 christos Exp */
++/* Id: ppp-deflate.c,v 1.5 1997/03/04 03:33:28 paulus Exp */
++
++/*
++ * ppp_deflate.c - interface the zlib procedures for Deflate compression
++ * and decompression (as used by gzip) to the PPP code.
++ * This version is for use with mbufs on BSD-derived systems.
++ *
++ * 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.
++ */
++
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/systm.h>
++#include <sys/mbuf.h>
++#include <net/ppp_defs.h>
++#include <net/zlib.h>
++
++#define PACKETPTR struct mbuf *
++#include <net/ppp-comp.h>
++
++#if DO_DEFLATE
++
++#define DEFLATE_DEBUG 1
++
++/*
++ * State for a Deflate (de)compressor.
++ */
++struct deflate_state {
++ int seqno;
++ int w_size;
++ int unit;
++ int hdrlen;
++ int mru;
++ int debug;
++ z_stream strm;
++ struct compstat stats;
++};
++
++#define DEFLATE_OVHD 2 /* Deflate overhead/packet */
++
++static void *zalloc __P((void *, u_int items, u_int size));
++static void zfree __P((void *, void *ptr));
++static void *z_comp_alloc __P((u_char *options, int opt_len));
++static void *z_decomp_alloc __P((u_char *options, int opt_len));
++static void z_comp_free __P((void *state));
++static void z_decomp_free __P((void *state));
++static int z_comp_init __P((void *state, u_char *options, int opt_len,
++ int unit, int hdrlen, int debug));
++static int z_decomp_init __P((void *state, u_char *options, int opt_len,
++ int unit, int hdrlen, int mru, int debug));
++static int z_compress __P((void *state, struct mbuf **mret,
++ struct mbuf *mp, int slen, int maxolen));
++static void z_incomp __P((void *state, struct mbuf *dmsg));
++static int z_decompress __P((void *state, struct mbuf *cmp,
++ struct mbuf **dmpp));
++static void z_comp_reset __P((void *state));
++static void z_decomp_reset __P((void *state));
++static void z_comp_stats __P((void *state, struct compstat *stats));
++
++/*
++ * Procedures exported to if_ppp.c.
++ */
++struct compressor ppp_deflate = {
++ CI_DEFLATE, /* compress_proto */
++ z_comp_alloc, /* comp_alloc */
++ z_comp_free, /* comp_free */
++ z_comp_init, /* comp_init */
++ z_comp_reset, /* comp_reset */
++ z_compress, /* compress */
++ z_comp_stats, /* comp_stat */
++ z_decomp_alloc, /* decomp_alloc */
++ z_decomp_free, /* decomp_free */
++ z_decomp_init, /* decomp_init */
++ z_decomp_reset, /* decomp_reset */
++ z_decompress, /* decompress */
++ z_incomp, /* incomp */
++ z_comp_stats, /* decomp_stat */
++};
++
++struct compressor ppp_deflate_draft = {
++ CI_DEFLATE_DRAFT, /* compress_proto */
++ z_comp_alloc, /* comp_alloc */
++ z_comp_free, /* comp_free */
++ z_comp_init, /* comp_init */
++ z_comp_reset, /* comp_reset */
++ z_compress, /* compress */
++ z_comp_stats, /* comp_stat */
++ z_decomp_alloc, /* decomp_alloc */
++ z_decomp_free, /* decomp_free */
++ z_decomp_init, /* decomp_init */
++ z_decomp_reset, /* decomp_reset */
++ z_decompress, /* decompress */
++ z_incomp, /* incomp */
++ z_comp_stats, /* decomp_stat */
++};
++/*
++ * Space allocation and freeing routines for use by zlib routines.
++ */
++void *
++zalloc(notused, items, size)
++ void *notused;
++ u_int items, size;
++{
++ void *ptr;
++
++ MALLOC(ptr, void *, items * size, M_DEVBUF, M_NOWAIT);
++ return ptr;
++}
++
++void
++zfree(notused, ptr)
++ void *notused;
++ void *ptr;
++{
++ FREE(ptr, M_DEVBUF);
++}
++
++/*
++ * Allocate space for a compressor.
++ */
++static void *
++z_comp_alloc(options, opt_len)
++ u_char *options;
++ int opt_len;
++{
++ struct deflate_state *state;
++ int w_size;
++
++ if (opt_len != CILEN_DEFLATE
++ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
++ || options[1] != CILEN_DEFLATE
++ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
++ || options[3] != DEFLATE_CHK_SEQUENCE)
++ return NULL;
++ w_size = DEFLATE_SIZE(options[2]);
++ if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
++ return NULL;
++
++ MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
++ M_DEVBUF, M_NOWAIT);
++ if (state == NULL)
++ return NULL;
++
++ state->strm.next_in = NULL;
++ state->strm.zalloc = zalloc;
++ state->strm.zfree = zfree;
++ if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
++ -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
++ FREE(state, M_DEVBUF);
++ return NULL;
++ }
++
++ state->w_size = w_size;
++ bzero(&state->stats, sizeof(state->stats));
++ return (void *) state;
++}
++
++static void
++z_comp_free(arg)
++ void *arg;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++
++ deflateEnd(&state->strm);
++ FREE(state, M_DEVBUF);
++}
++
++static int
++z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
++ void *arg;
++ u_char *options;
++ int opt_len, unit, hdrlen, debug;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++
++ if (opt_len < CILEN_DEFLATE
++ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
++ || options[1] != CILEN_DEFLATE
++ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
++ || DEFLATE_SIZE(options[2]) != state->w_size
++ || options[3] != DEFLATE_CHK_SEQUENCE)
++ return 0;
++
++ state->seqno = 0;
++ state->unit = unit;
++ state->hdrlen = hdrlen;
++ state->debug = debug;
++
++ deflateReset(&state->strm);
++
++ return 1;
++}
++
++static void
++z_comp_reset(arg)
++ void *arg;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++
++ state->seqno = 0;
++ deflateReset(&state->strm);
++}
++
++int
++z_compress(arg, mret, mp, orig_len, maxolen)
++ void *arg;
++ struct mbuf **mret; /* compressed packet (out) */
++ struct mbuf *mp; /* uncompressed packet (in) */
++ int orig_len, maxolen;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++ u_char *rptr, *wptr;
++ int proto, olen, wspace, r, flush;
++ struct mbuf *m;
++
++ /*
++ * Check that the protocol is in the range we handle.
++ */
++ rptr = mtod(mp, u_char *);
++ proto = PPP_PROTOCOL(rptr);
++ if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
++ *mret = NULL;
++ return orig_len;
++ }
++
++ /* Allocate one mbuf initially. */
++ if (maxolen > orig_len)
++ maxolen = orig_len;
++ MGET(m, M_DONTWAIT, MT_DATA);
++ *mret = m;
++ if (m != NULL) {
++ m->m_len = 0;
++ if (maxolen + state->hdrlen > MLEN)
++ MCLGET(m, M_DONTWAIT);
++ wspace = M_TRAILINGSPACE(m);
++ if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
++ m->m_data += state->hdrlen;
++ wspace -= state->hdrlen;
++ }
++ wptr = mtod(m, u_char *);
++
++ /*
++ * Copy over the PPP header and store the 2-byte sequence number.
++ */
++ wptr[0] = PPP_ADDRESS(rptr);
++ wptr[1] = PPP_CONTROL(rptr);
++ wptr[2] = PPP_COMP >> 8;
++ wptr[3] = PPP_COMP;
++ wptr += PPP_HDRLEN;
++ wptr[0] = state->seqno >> 8;
++ wptr[1] = state->seqno;
++ wptr += 2;
++ state->strm.next_out = wptr;
++ state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
++ } else {
++ state->strm.next_out = NULL;
++ state->strm.avail_out = 1000000;
++ wptr = NULL;
++ wspace = 0;
++ }
++ ++state->seqno;
++
++ rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */
++ state->strm.next_in = rptr;
++ state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
++ mp = mp->m_next;
++ flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
++ olen = 0;
++ for (;;) {
++ r = deflate(&state->strm, flush);
++ if (r != Z_OK) {
++ printf("z_compress: deflate returned %d (%s)\n",
++ r, (state->strm.msg? state->strm.msg: ""));
++ break;
++ }
++ if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
++ break; /* all done */
++ if (state->strm.avail_in == 0 && mp != NULL) {
++ state->strm.next_in = mtod(mp, u_char *);
++ state->strm.avail_in = mp->m_len;
++ mp = mp->m_next;
++ if (mp == NULL)
++ flush = Z_PACKET_FLUSH;
++ }
++ if (state->strm.avail_out == 0) {
++ if (m != NULL) {
++ m->m_len = wspace;
++ olen += wspace;
++ MGET(m->m_next, M_DONTWAIT, MT_DATA);
++ m = m->m_next;
++ if (m != NULL) {
++ m->m_len = 0;
++ if (maxolen - olen > MLEN)
++ MCLGET(m, M_DONTWAIT);
++ state->strm.next_out = mtod(m, u_char *);
++ state->strm.avail_out = wspace = M_TRAILINGSPACE(m);
++ }
++ }
++ if (m == NULL) {
++ state->strm.next_out = NULL;
++ state->strm.avail_out = 1000000;
++ }
++ }
++ }
++ if (m != NULL)
++ olen += (m->m_len = wspace - state->strm.avail_out);
++
++ /*
++ * See if we managed to reduce the size of the packet.
++ */
++ if (m != NULL && olen < orig_len) {
++ state->stats.comp_bytes += olen;
++ state->stats.comp_packets++;
++ } else {
++ if (*mret != NULL) {
++ m_freem(*mret);
++ *mret = NULL;
++ }
++ state->stats.inc_bytes += orig_len;
++ state->stats.inc_packets++;
++ olen = orig_len;
++ }
++ state->stats.unc_bytes += orig_len;
++ state->stats.unc_packets++;
++
++ return olen;
++}
++
++static void
++z_comp_stats(arg, stats)
++ void *arg;
++ struct compstat *stats;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++ u_int out;
++
++ *stats = state->stats;
++ stats->ratio = stats->unc_bytes;
++ out = stats->comp_bytes + stats->inc_bytes;
++ if (stats->ratio <= 0x7ffffff)
++ stats->ratio <<= 8;
++ else
++ out >>= 8;
++ if (out != 0)
++ stats->ratio /= out;
++}
++
++/*
++ * Allocate space for a decompressor.
++ */
++static void *
++z_decomp_alloc(options, opt_len)
++ u_char *options;
++ int opt_len;
++{
++ struct deflate_state *state;
++ int w_size;
++
++ if (opt_len != CILEN_DEFLATE
++ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
++ || options[1] != CILEN_DEFLATE
++ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
++ || options[3] != DEFLATE_CHK_SEQUENCE)
++ return NULL;
++ w_size = DEFLATE_SIZE(options[2]);
++ if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
++ return NULL;
++
++ MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
++ M_DEVBUF, M_NOWAIT);
++ if (state == NULL)
++ return NULL;
++
++ state->strm.next_out = NULL;
++ state->strm.zalloc = zalloc;
++ state->strm.zfree = zfree;
++ if (inflateInit2(&state->strm, -w_size) != Z_OK) {
++ FREE(state, M_DEVBUF);
++ return NULL;
++ }
++
++ state->w_size = w_size;
++ bzero(&state->stats, sizeof(state->stats));
++ return (void *) state;
++}
++
++static void
++z_decomp_free(arg)
++ void *arg;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++
++ inflateEnd(&state->strm);
++ FREE(state, M_DEVBUF);
++}
++
++static int
++z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
++ void *arg;
++ u_char *options;
++ int opt_len, unit, hdrlen, mru, debug;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++
++ if (opt_len < CILEN_DEFLATE
++ || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
++ || options[1] != CILEN_DEFLATE
++ || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
++ || DEFLATE_SIZE(options[2]) != state->w_size
++ || options[3] != DEFLATE_CHK_SEQUENCE)
++ return 0;
++
++ state->seqno = 0;
++ state->unit = unit;
++ state->hdrlen = hdrlen;
++ state->debug = debug;
++ state->mru = mru;
++
++ inflateReset(&state->strm);
++
++ return 1;
++}
++
++static void
++z_decomp_reset(arg)
++ void *arg;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++
++ state->seqno = 0;
++ inflateReset(&state->strm);
++}
++
++/*
++ * Decompress a Deflate-compressed packet.
++ *
++ * Because of patent problems, we return DECOMP_ERROR for errors
++ * found by inspecting the input data and for system problems, but
++ * DECOMP_FATALERROR for any errors which could possibly be said to
++ * be being detected "after" decompression. For DECOMP_ERROR,
++ * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
++ * infringing a patent of Motorola's if we do, so we take CCP down
++ * instead.
++ *
++ * Given that the frame has the correct sequence number and a good FCS,
++ * errors such as invalid codes in the input most likely indicate a
++ * bug, so we return DECOMP_FATALERROR for them in order to turn off
++ * compression, even though they are detected by inspecting the input.
++ */
++int
++z_decompress(arg, mi, mop)
++ void *arg;
++ struct mbuf *mi, **mop;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++ struct mbuf *mo, *mo_head;
++ u_char *rptr, *wptr;
++ int rlen, olen, ospace;
++ int seq, i, flush, r, decode_proto;
++ u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
++
++ *mop = NULL;
++ rptr = mtod(mi, u_char *);
++ rlen = mi->m_len;
++ for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
++ while (rlen <= 0) {
++ mi = mi->m_next;
++ if (mi == NULL)
++ return DECOMP_ERROR;
++ rptr = mtod(mi, u_char *);
++ rlen = mi->m_len;
++ }
++ hdr[i] = *rptr++;
++ --rlen;
++ }
++
++ /* Check the sequence number. */
++ seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
++ if (seq != state->seqno) {
++ if (state->debug)
++ printf("z_decompress%d: bad seq # %d, expected %d\n",
++ state->unit, seq, state->seqno);
++ return DECOMP_ERROR;
++ }
++ ++state->seqno;
++
++ /* Allocate an output mbuf. */
++ MGETHDR(mo, M_DONTWAIT, MT_DATA);
++ if (mo == NULL)
++ return DECOMP_ERROR;
++ mo_head = mo;
++ mo->m_len = 0;
++ mo->m_next = NULL;
++ MCLGET(mo, M_DONTWAIT);
++ ospace = M_TRAILINGSPACE(mo);
++ if (state->hdrlen + PPP_HDRLEN < ospace) {
++ mo->m_data += state->hdrlen;
++ ospace -= state->hdrlen;
++ }
++
++ /*
++ * Fill in the first part of the PPP header. The protocol field
++ * comes from the decompressed data.
++ */
++ wptr = mtod(mo, u_char *);
++ wptr[0] = PPP_ADDRESS(hdr);
++ wptr[1] = PPP_CONTROL(hdr);
++ wptr[2] = 0;
++
++ /*
++ * Set up to call inflate. We set avail_out to 1 initially so we can
++ * look at the first byte of the output and decide whether we have
++ * a 1-byte or 2-byte protocol field.
++ */
++ state->strm.next_in = rptr;
++ state->strm.avail_in = rlen;
++ mi = mi->m_next;
++ flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
++ rlen += PPP_HDRLEN + DEFLATE_OVHD;
++ state->strm.next_out = wptr + 3;
++ state->strm.avail_out = 1;
++ decode_proto = 1;
++ olen = PPP_HDRLEN;
++
++ /*
++ * Call inflate, supplying more input or output as needed.
++ */
++ for (;;) {
++ r = inflate(&state->strm, flush);
++ if (r != Z_OK) {
++#if !DEFLATE_DEBUG
++ if (state->debug)
++#endif
++ printf("z_decompress%d: inflate returned %d (%s)\n",
++ state->unit, r, (state->strm.msg? state->strm.msg: ""));
++ m_freem(mo_head);
++ return DECOMP_FATALERROR;
++ }
++ if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
++ break; /* all done */
++ if (state->strm.avail_in == 0 && mi != NULL) {
++ state->strm.next_in = mtod(mi, u_char *);
++ state->strm.avail_in = mi->m_len;
++ rlen += mi->m_len;
++ mi = mi->m_next;
++ if (mi == NULL)
++ flush = Z_PACKET_FLUSH;
++ }
++ if (state->strm.avail_out == 0) {
++ if (decode_proto) {
++ state->strm.avail_out = ospace - PPP_HDRLEN;
++ if ((wptr[3] & 1) == 0) {
++ /* 2-byte protocol field */
++ wptr[2] = wptr[3];
++ --state->strm.next_out;
++ ++state->strm.avail_out;
++ --olen;
++ }
++ decode_proto = 0;
++ } else {
++ mo->m_len = ospace;
++ olen += ospace;
++ MGET(mo->m_next, M_DONTWAIT, MT_DATA);
++ mo = mo->m_next;
++ if (mo == NULL) {
++ m_freem(mo_head);
++ return DECOMP_ERROR;
++ }
++ MCLGET(mo, M_DONTWAIT);
++ state->strm.next_out = mtod(mo, u_char *);
++ state->strm.avail_out = ospace = M_TRAILINGSPACE(mo);
++ }
++ }
++ }
++ if (decode_proto) {
++ m_freem(mo_head);
++ return DECOMP_ERROR;
++ }
++ olen += (mo->m_len = ospace - state->strm.avail_out);
++#if DEFLATE_DEBUG
++ if (olen > state->mru + PPP_HDRLEN)
++ printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
++ state->unit, olen, state->mru + PPP_HDRLEN);
++#endif
++
++ state->stats.unc_bytes += olen;
++ state->stats.unc_packets++;
++ state->stats.comp_bytes += rlen;
++ state->stats.comp_packets++;
++
++ *mop = mo_head;
++ return DECOMP_OK;
++}
++
++/*
++ * Incompressible data has arrived - add it to the history.
++ */
++static void
++z_incomp(arg, mi)
++ void *arg;
++ struct mbuf *mi;
++{
++ struct deflate_state *state = (struct deflate_state *) arg;
++ u_char *rptr;
++ int rlen, proto, r;
++
++ /*
++ * Check that the protocol is one we handle.
++ */
++ rptr = mtod(mi, u_char *);
++ proto = PPP_PROTOCOL(rptr);
++ if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
++ return;
++
++ ++state->seqno;
++
++ /*
++ * Iterate through the mbufs, adding the characters in them
++ * to the decompressor's history. For the first mbuf, we start
++ * at the either the 1st or 2nd byte of the protocol field,
++ * depending on whether the protocol value is compressible.
++ */
++ rlen = mi->m_len;
++ state->strm.next_in = rptr + 3;
++ state->strm.avail_in = rlen - 3;
++ if (proto > 0xff) {
++ --state->strm.next_in;
++ ++state->strm.avail_in;
++ }
++ for (;;) {
++ r = inflateIncomp(&state->strm);
++ if (r != Z_OK) {
++ /* gak! */
++#if !DEFLATE_DEBUG
++ if (state->debug)
++#endif
++ printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
++ state->unit, r, (state->strm.msg? state->strm.msg: ""));
++ return;
++ }
++ mi = mi->m_next;
++ if (mi == NULL)
++ break;
++ state->strm.next_in = mtod(mi, u_char *);
++ state->strm.avail_in = mi->m_len;
++ rlen += mi->m_len;
++ }
++
++ /*
++ * Update stats.
++ */
++ state->stats.inc_bytes += rlen;
++ state->stats.inc_packets++;
++ state->stats.unc_bytes += rlen;
++ state->stats.unc_packets++;
++}
++
++#endif /* DO_DEFLATE */
diff --git a/net/ppp-mppe/patches/patch-as b/net/ppp-mppe/patches/patch-as
new file mode 100644
index 00000000000..57001ef6b8b
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-as
@@ -0,0 +1,1287 @@
+$NetBSD: patch-as,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 04:00:15 1999
++++ netbsd-1.4/ppp_tty.c Sat Sep 18 04:06:33 1999
+@@ -0,0 +1,1282 @@
++/* NetBSD: ppp_tty.c,v 1.18 1999/08/25 02:04:06 christos Exp */
++/* Id: ppp_tty.c,v 1.3 1996/07/01 01:04:11 paulus Exp */
++
++/*
++ * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
++ * tty devices.
++ *
++ * Copyright (c) 1989 Carnegie Mellon University.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms are permitted
++ * provided that the above copyright notice and this paragraph are
++ * duplicated in all such forms and that any documentation,
++ * advertising materials, and other materials related to such
++ * distribution and use acknowledge that the software was developed
++ * by Carnegie Mellon University. The name of the
++ * University may not be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * Drew D. Perkins
++ * Carnegie Mellon University
++ * 4910 Forbes Ave.
++ * Pittsburgh, PA 15213
++ * (412) 268-8576
++ * ddp@andrew.cmu.edu
++ *
++ * Based on:
++ * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
++ *
++ * Copyright (c) 1987 Regents of the University of California.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms are permitted
++ * provided that the above copyright notice and this paragraph are
++ * duplicated in all such forms and that any documentation,
++ * advertising materials, and other materials related to such
++ * distribution and use acknowledge that the software was developed
++ * by the University of California, Berkeley. The name of the
++ * University may not be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * Serial Line interface
++ *
++ * Rick Adams
++ * Center for Seismic Studies
++ * 1300 N 17th Street, Suite 1450
++ * Arlington, Virginia 22209
++ * (703)276-7900
++ * rick@seismo.ARPA
++ * seismo!rick
++ *
++ * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
++ * Converted to 4.3BSD Beta by Chris Torek.
++ * Other changes made at Berkeley, based in part on code by Kirk Smith.
++ *
++ * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
++ * Added VJ tcp header compression; more unified ioctls
++ *
++ * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
++ * Cleaned up a lot of the mbuf-related code to fix bugs that
++ * caused system crashes and packet corruption. Changed pppstart
++ * so that it doesn't just give up with a "collision" if the whole
++ * packet doesn't fit in the output ring buffer.
++ *
++ * Added priority queueing for interactive IP packets, following
++ * the model of if_sl.c, plus hooks for bpf.
++ * Paul Mackerras (paulus@cs.anu.edu.au).
++ */
++
++/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
++/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
++
++#include "ppp.h"
++#if NPPP > 0
++
++#include "opt_ppp.h"
++#define VJC
++#define PPP_COMPRESS
++
++#include <sys/param.h>
++#include <sys/proc.h>
++#include <sys/mbuf.h>
++#include <sys/dkstat.h>
++#include <sys/socket.h>
++#include <sys/ioctl.h>
++#include <sys/file.h>
++#include <sys/tty.h>
++#include <sys/kernel.h>
++#include <sys/conf.h>
++#include <sys/vnode.h>
++#include <sys/systm.h>
++
++#include <net/if.h>
++#include <net/if_types.h>
++
++#ifdef VJC
++#include <netinet/in.h>
++#include <netinet/in_systm.h>
++#include <netinet/ip.h>
++#include <net/slcompress.h>
++#endif
++
++#include "bpfilter.h"
++#if NBPFILTER > 0 || defined(PPP_FILTER)
++#include <net/bpf.h>
++#endif
++#include <net/ppp_defs.h>
++#include <net/if_ppp.h>
++#include <net/if_pppvar.h>
++
++int pppopen __P((dev_t dev, struct tty *tp));
++int pppclose __P((struct tty *tp, int flag));
++int pppread __P((struct tty *tp, struct uio *uio, int flag));
++int pppwrite __P((struct tty *tp, struct uio *uio, int flag));
++int ppptioctl __P((struct tty *tp, u_long cmd, caddr_t data, int flag,
++ struct proc *));
++int pppinput __P((int c, struct tty *tp));
++int pppstart __P((struct tty *tp));
++
++static void ppprcvframe __P((struct ppp_softc *sc, struct mbuf *m));
++static u_int16_t pppfcs __P((u_int16_t fcs, u_char *cp, int len));
++static void pppsyncstart __P((struct ppp_softc *sc));
++static void pppasyncstart __P((struct ppp_softc *));
++static void pppasyncctlp __P((struct ppp_softc *));
++static void pppasyncrelinq __P((struct ppp_softc *));
++static void ppp_timeout __P((void *));
++static void pppgetm __P((struct ppp_softc *sc));
++static void pppdumpb __P((u_char *b, int l));
++static void ppplogchar __P((struct ppp_softc *, int));
++static void pppdumpframe __P((struct ppp_softc *sc, struct mbuf* m,
++ int xmit));
++
++/*
++ * Some useful mbuf macros not in mbuf.h.
++ */
++#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
++
++#define M_DATASTART(m) \
++ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
++ (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
++
++#define M_DATASIZE(m) \
++ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
++ (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
++
++/*
++ * Does c need to be escaped?
++ */
++#define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
++
++/*
++ * Procedures for using an async tty interface for PPP.
++ */
++
++/* This is a NetBSD-1.0 or later kernel. */
++#define CCOUNT(q) ((q)->c_cc)
++
++#define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */
++#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
++
++/*
++ * Line specific open routine for async tty devices.
++ * Attach the given tty to the first available ppp unit.
++ * Called from device open routine or ttioctl.
++ */
++/* ARGSUSED */
++int
++pppopen(dev, tp)
++ dev_t dev;
++ register struct tty *tp;
++{
++ struct proc *p = curproc; /* XXX */
++ register struct ppp_softc *sc;
++ int error, s;
++
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ return (error);
++
++ s = spltty();
++
++ if (tp->t_line == PPPDISC) {
++ sc = (struct ppp_softc *) tp->t_sc;
++ if (sc != NULL && sc->sc_devp == (void *) tp) {
++ splx(s);
++ return (0);
++ }
++ }
++
++ if ((sc = pppalloc(p->p_pid)) == NULL) {
++ splx(s);
++ return ENXIO;
++ }
++
++ if (sc->sc_relinq)
++ (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
++
++#if NBPFILTER > 0
++ /* Switch DLT to PPP-over-serial. */
++ bpf_change_type(&sc->sc_bpf, DLT_PPP_SERIAL, PPP_HDRLEN);
++#endif
++
++ sc->sc_ilen = 0;
++ sc->sc_m = NULL;
++ bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
++ sc->sc_asyncmap[0] = 0xffffffff;
++ sc->sc_asyncmap[3] = 0x60000000;
++ sc->sc_rasyncmap = 0;
++ sc->sc_devp = (void *) tp;
++ sc->sc_start = pppasyncstart;
++ sc->sc_ctlp = pppasyncctlp;
++ sc->sc_relinq = pppasyncrelinq;
++ sc->sc_outm = NULL;
++ pppgetm(sc);
++ sc->sc_if.if_flags |= IFF_RUNNING;
++ sc->sc_if.if_baudrate = tp->t_ospeed;
++
++ tp->t_sc = (caddr_t) sc;
++ ttyflush(tp, FREAD | FWRITE);
++
++ splx(s);
++ return (0);
++}
++
++/*
++ * Line specific close routine, called from device close routine
++ * and from ttioctl.
++ * Detach the tty from the ppp unit.
++ * Mimics part of ttyclose().
++ */
++int
++pppclose(tp, flag)
++ struct tty *tp;
++ int flag;
++{
++ register struct ppp_softc *sc;
++ int s;
++
++ s = spltty();
++ ttyflush(tp, FREAD|FWRITE);
++ tp->t_line = 0;
++ sc = (struct ppp_softc *) tp->t_sc;
++ if (sc != NULL) {
++ tp->t_sc = NULL;
++ if (tp == (struct tty *) sc->sc_devp) {
++ pppasyncrelinq(sc);
++ pppdealloc(sc);
++ }
++ }
++ splx(s);
++ return 0;
++}
++
++/*
++ * Relinquish the interface unit to another device.
++ */
++static void
++pppasyncrelinq(sc)
++ struct ppp_softc *sc;
++{
++ int s;
++
++#if NBPFILTER > 0
++ /* Change DLT to back none. */
++ bpf_change_type(&sc->sc_bpf, DLT_NULL, 0);
++#endif
++
++ s = spltty();
++ if (sc->sc_outm) {
++ m_freem(sc->sc_outm);
++ sc->sc_outm = NULL;
++ }
++ if (sc->sc_m) {
++ m_freem(sc->sc_m);
++ sc->sc_m = NULL;
++ }
++ if (sc->sc_flags & SC_TIMEOUT) {
++ untimeout(ppp_timeout, (void *) sc);
++ sc->sc_flags &= ~SC_TIMEOUT;
++ }
++ splx(s);
++}
++
++/*
++ * Line specific (tty) read routine.
++ */
++int
++pppread(tp, uio, flag)
++ register struct tty *tp;
++ struct uio *uio;
++ int flag;
++{
++ register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
++ struct mbuf *m, *m0;
++ register int s;
++ int error = 0;
++
++ if (sc == NULL)
++ return 0;
++ /*
++ * Loop waiting for input, checking that nothing disasterous
++ * happens in the meantime.
++ */
++ s = spltty();
++ for (;;) {
++ if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
++ splx(s);
++ return 0;
++ }
++ if (sc->sc_inq.ifq_head != NULL)
++ break;
++ if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0
++ && (tp->t_state & TS_ISOPEN)) {
++ splx(s);
++ return 0; /* end of file */
++ }
++ if (tp->t_state & TS_ASYNC || flag & IO_NDELAY) {
++ splx(s);
++ return (EWOULDBLOCK);
++ }
++ error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI|PCATCH, ttyin, 0);
++ if (error) {
++ splx(s);
++ return error;
++ }
++ }
++
++ /* Pull place-holder byte out of canonical queue */
++ getc(&tp->t_canq);
++
++ /* Get the packet from the input queue */
++ IF_DEQUEUE(&sc->sc_inq, m0);
++ splx(s);
++
++ for (m = m0; m && uio->uio_resid; m = m->m_next)
++ if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0)
++ break;
++ m_freem(m0);
++ return (error);
++}
++
++/*
++ * Line specific (tty) write routine.
++ */
++int
++pppwrite(tp, uio, flag)
++ register struct tty *tp;
++ struct uio *uio;
++ int flag;
++{
++ register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
++ struct mbuf *m, *m0, **mp;
++ struct sockaddr dst;
++ int len, error;
++
++ if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
++ return 0; /* wrote 0 bytes */
++ if (tp->t_line != PPPDISC)
++ return (EINVAL);
++ if (sc == NULL || tp != (struct tty *) sc->sc_devp)
++ return EIO;
++ if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
++ uio->uio_resid < PPP_HDRLEN)
++ return (EMSGSIZE);
++ for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
++ MGET(m, M_WAIT, MT_DATA);
++ if ((*mp = m) == NULL) {
++ m_freem(m0);
++ return (ENOBUFS);
++ }
++ m->m_len = 0;
++ if (uio->uio_resid >= MCLBYTES / 2)
++ MCLGET(m, M_DONTWAIT);
++ len = M_TRAILINGSPACE(m);
++ if (len > uio->uio_resid)
++ len = uio->uio_resid;
++ if ((error = uiomove(mtod(m, u_char *), len, uio)) != 0) {
++ m_freem(m0);
++ return (error);
++ }
++ m->m_len = len;
++ }
++ dst.sa_family = AF_UNSPEC;
++ bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
++ m0->m_data += PPP_HDRLEN;
++ m0->m_len -= PPP_HDRLEN;
++ return ((*sc->sc_if.if_output)(&sc->sc_if, m0, &dst, (struct rtentry *)0));
++}
++
++/*
++ * Line specific (tty) ioctl routine.
++ * This discipline requires that tty device drivers call
++ * the line specific l_ioctl routine from their ioctl routines.
++ */
++/* ARGSUSED */
++int
++ppptioctl(tp, cmd, data, flag, p)
++ struct tty *tp;
++ u_long cmd;
++ caddr_t data;
++ int flag;
++ struct proc *p;
++{
++ struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
++ int error, s;
++
++ if (sc == NULL || tp != (struct tty *) sc->sc_devp)
++ return -1;
++
++ error = 0;
++ switch (cmd) {
++ case TIOCRCVFRAME:
++ ppprcvframe(sc,*((struct mbuf **)data));
++ break;
++
++ case PPPIOCSASYNCMAP:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ break;
++ sc->sc_asyncmap[0] = *(u_int *)data;
++ break;
++
++ case PPPIOCGASYNCMAP:
++ *(u_int *)data = sc->sc_asyncmap[0];
++ break;
++
++ case PPPIOCSRASYNCMAP:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ break;
++ sc->sc_rasyncmap = *(u_int *)data;
++ break;
++
++ case PPPIOCGRASYNCMAP:
++ *(u_int *)data = sc->sc_rasyncmap;
++ break;
++
++ case PPPIOCSXASYNCMAP:
++ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
++ break;
++ s = spltty();
++ bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
++ sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
++ sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
++ sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
++ splx(s);
++ break;
++
++ case PPPIOCGXASYNCMAP:
++ bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
++ break;
++
++ default:
++ error = pppioctl(sc, cmd, data, flag, p);
++ if (error == 0 && cmd == PPPIOCSMRU)
++ pppgetm(sc);
++ }
++
++ return error;
++}
++
++/* receive a complete ppp frame from device in synchronous
++ * hdlc mode. caller gives up ownership of mbuf
++ */
++static void
++ppprcvframe(sc, m)
++ struct ppp_softc *sc;
++ struct mbuf *m;
++{
++ int len, s;
++ struct mbuf *n;
++ u_char hdr[4];
++ int hlen,count;
++
++ for (n=m,len=0;n != NULL;n = n->m_next)
++ len += n->m_len;
++ if (len==0) {
++ m_freem(m);
++ return;
++ }
++
++ /* extract PPP header from mbuf chain (1 to 4 bytes) */
++ for (n=m,hlen=0;n!=NULL && hlen<sizeof(hdr);n=n->m_next) {
++ count = (sizeof(hdr)-hlen) < n->m_len ?
++ sizeof(hdr)-hlen : n->m_len;
++ bcopy(mtod(n,u_char*),&hdr[hlen],count);
++ hlen+=count;
++ }
++
++ s = spltty();
++
++ /* if AFCF compressed then prepend AFCF */
++ if (hdr[0] != PPP_ALLSTATIONS) {
++ if (sc->sc_flags & SC_REJ_COMP_AC) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf(
++ "%s: garbage received: 0x%x (need 0xFF)\n",
++ sc->sc_if.if_xname, hdr[0]);
++ goto bail;
++ }
++ M_PREPEND(m,2,M_DONTWAIT);
++ if (m==NULL) {
++ splx(s);
++ return;
++ }
++ hdr[3] = hdr[1];
++ hdr[2] = hdr[0];
++ hdr[0] = PPP_ALLSTATIONS;
++ hdr[1] = PPP_UI;
++ len += 2;
++ }
++
++ /* if protocol field compressed, add MSB of protocol field = 0 */
++ if (hdr[2] & 1) {
++ /* a compressed protocol */
++ M_PREPEND(m,1,M_DONTWAIT);
++ if (m==NULL) {
++ splx(s);
++ return;
++ }
++ hdr[3] = hdr[2];
++ hdr[2] = 0;
++ len++;
++ }
++
++ /* valid LSB of protocol field has bit0 set */
++ if (!(hdr[3] & 1)) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: bad protocol %x\n", sc->sc_if.if_xname,
++ (hdr[2] << 8) + hdr[3]);
++ goto bail;
++ }
++
++ /* packet beyond configured mru? */
++ if (len > sc->sc_mru + PPP_HDRLEN) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: packet too big\n", sc->sc_if.if_xname);
++ goto bail;
++ }
++
++ /* add expanded 4 byte header to mbuf chain */
++ for (n=m,hlen=0;n!=NULL && hlen<sizeof(hdr);n=n->m_next) {
++ count = (sizeof(hdr)-hlen) < n->m_len ?
++ sizeof(hdr)-hlen : n->m_len;
++ bcopy(&hdr[hlen],mtod(n,u_char*),count);
++ hlen+=count;
++ }
++
++ /* if_ppp.c requires the PPP header and IP header */
++ /* to be contiguous */
++ count = len < MHLEN ? len : MHLEN;
++ if (m->m_len < count) {
++ m = m_pullup(m,count);
++ if (m==NULL)
++ goto bail;
++ }
++
++ sc->sc_stats.ppp_ibytes += len;
++
++ if (sc->sc_flags & SC_LOG_RAWIN)
++ pppdumpframe(sc,m,0);
++
++ ppppktin(sc, m, 0);
++ splx(s);
++ return;
++bail:
++ m_freem(m);
++ splx(s);
++}
++
++/*
++ * FCS lookup table as calculated by genfcstab.
++ */
++static u_int16_t 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
++};
++
++/*
++ * Calculate a new FCS given the current FCS and the new data.
++ */
++static u_int16_t
++pppfcs(fcs, cp, len)
++ register u_int16_t fcs;
++ register u_char *cp;
++ register int len;
++{
++ while (len--)
++ fcs = PPP_FCS(fcs, *cp++);
++ return (fcs);
++}
++
++/* This gets called at splsoftnet from pppasyncstart at various times
++ * when there is data ready to be sent.
++ */
++static void
++pppsyncstart(sc)
++ struct ppp_softc *sc;
++{
++ struct tty *tp = (struct tty *) sc->sc_devp;
++ struct mbuf *m, *n;
++ int len;
++
++ for(m = sc->sc_outm;;) {
++ if (m == NULL) {
++ m = ppp_dequeue(sc); /* get new packet */
++ if (m == NULL)
++ break; /* no more packets */
++ if (sc->sc_flags & SC_DEBUG)
++ pppdumpframe(sc,m,1);
++ }
++ microtime(&sc->sc_if.if_lastchange);
++ for(n=m,len=0;n!=NULL;n=n->m_next)
++ len += n->m_len;
++
++ /* call device driver IOCTL to transmit a frame */
++ if ((*cdevsw[major(tp->t_dev)].d_ioctl)
++ (tp->t_dev, TIOCXMTFRAME, (caddr_t)&m, 0, 0)) {
++ /* busy or error, set as current packet */
++ sc->sc_outm = m;
++ break;
++ }
++ sc->sc_outm = m = NULL;
++ sc->sc_stats.ppp_obytes += len;
++ }
++}
++
++/*
++ * This gets called at splsoftnet from if_ppp.c at various times
++ * when there is data ready to be sent.
++ */
++static void
++pppasyncstart(sc)
++ register struct ppp_softc *sc;
++{
++ register struct tty *tp = (struct tty *) sc->sc_devp;
++ register struct mbuf *m;
++ register int len;
++ register u_char *start, *stop, *cp;
++ int n, ndone, done, idle;
++ struct mbuf *m2;
++ int s;
++
++ if (sc->sc_flags & SC_SYNC){
++ pppsyncstart(sc);
++ return;
++ }
++
++ idle = 0;
++ while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
++ /*
++ * See if we have an existing packet partly sent.
++ * If not, get a new packet and start sending it.
++ */
++ m = sc->sc_outm;
++ if (m == NULL) {
++ /*
++ * Get another packet to be sent.
++ */
++ m = ppp_dequeue(sc);
++ if (m == NULL) {
++ idle = 1;
++ break;
++ }
++
++ /*
++ * The extra PPP_FLAG will start up a new packet, and thus
++ * will flush any accumulated garbage. We do this whenever
++ * the line may have been idle for some time.
++ */
++ if (CCOUNT(&tp->t_outq) == 0) {
++ ++sc->sc_stats.ppp_obytes;
++ (void) putc(PPP_FLAG, &tp->t_outq);
++ }
++
++ /* Calculate the FCS for the first mbuf's worth. */
++ sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
++ sc->sc_if.if_lastchange = time;
++ }
++
++ for (;;) {
++ start = mtod(m, u_char *);
++ len = m->m_len;
++ stop = start + len;
++ while (len > 0) {
++ /*
++ * Find out how many bytes in the string we can
++ * handle without doing something special.
++ */
++ for (cp = start; cp < stop; cp++)
++ if (ESCAPE_P(*cp))
++ break;
++ n = cp - start;
++ if (n) {
++ /* NetBSD (0.9 or later), 4.3-Reno or similar. */
++ ndone = n - b_to_q(start, n, &tp->t_outq);
++ len -= ndone;
++ start += ndone;
++ sc->sc_stats.ppp_obytes += ndone;
++
++ if (ndone < n)
++ break; /* packet doesn't fit */
++ }
++ /*
++ * If there are characters left in the mbuf,
++ * the first one must be special.
++ * Put it out in a different form.
++ */
++ if (len) {
++ s = spltty();
++ if (putc(PPP_ESCAPE, &tp->t_outq)) {
++ splx(s);
++ break;
++ }
++ if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
++ (void) unputc(&tp->t_outq);
++ splx(s);
++ break;
++ }
++ splx(s);
++ sc->sc_stats.ppp_obytes += 2;
++ start++;
++ len--;
++ }
++ }
++
++ /*
++ * If we didn't empty this mbuf, remember where we're up to.
++ * If we emptied the last mbuf, try to add the FCS and closing
++ * flag, and if we can't, leave sc_outm pointing to m, but with
++ * m->m_len == 0, to remind us to output the FCS and flag later.
++ */
++ done = len == 0;
++ if (done && m->m_next == NULL) {
++ u_char *p, *q;
++ int c;
++ u_char endseq[8];
++
++ /*
++ * We may have to escape the bytes in the FCS.
++ */
++ p = endseq;
++ c = ~sc->sc_outfcs & 0xFF;
++ if (ESCAPE_P(c)) {
++ *p++ = PPP_ESCAPE;
++ *p++ = c ^ PPP_TRANS;
++ } else
++ *p++ = c;
++ c = (~sc->sc_outfcs >> 8) & 0xFF;
++ if (ESCAPE_P(c)) {
++ *p++ = PPP_ESCAPE;
++ *p++ = c ^ PPP_TRANS;
++ } else
++ *p++ = c;
++ *p++ = PPP_FLAG;
++
++ /*
++ * Try to output the FCS and flag. If the bytes
++ * don't all fit, back out.
++ */
++ s = spltty();
++ for (q = endseq; q < p; ++q)
++ if (putc(*q, &tp->t_outq)) {
++ done = 0;
++ for (; q > endseq; --q)
++ unputc(&tp->t_outq);
++ break;
++ }
++ splx(s);
++ if (done)
++ sc->sc_stats.ppp_obytes += q - endseq;
++ }
++
++ if (!done) {
++ /* remember where we got to */
++ m->m_data = start;
++ m->m_len = len;
++ break;
++ }
++
++ /* Finished with this mbuf; free it and move on. */
++ MFREE(m, m2);
++ m = m2;
++ if (m == NULL) {
++ /* Finished a packet */
++ break;
++ }
++ sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
++ }
++
++ /*
++ * If m == NULL, we have finished a packet.
++ * If m != NULL, we've either done as much work this time
++ * as we need to, or else we've filled up the output queue.
++ */
++ sc->sc_outm = m;
++ if (m)
++ break;
++ }
++
++ /* Call pppstart to start output again if necessary. */
++ s = spltty();
++ pppstart(tp);
++
++ /*
++ * This timeout is needed for operation on a pseudo-tty,
++ * because the pty code doesn't call pppstart after it has
++ * drained the t_outq.
++ */
++ if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
++ timeout(ppp_timeout, (void *) sc, 1);
++ sc->sc_flags |= SC_TIMEOUT;
++ }
++
++ splx(s);
++}
++
++/*
++ * This gets called when a received packet is placed on
++ * the inq, at splsoftnet.
++ */
++static void
++pppasyncctlp(sc)
++ struct ppp_softc *sc;
++{
++ struct tty *tp;
++ int s;
++
++ /* Put a placeholder byte in canq for ttselect()/ttnread(). */
++ s = spltty();
++ tp = (struct tty *) sc->sc_devp;
++ putc(0, &tp->t_canq);
++ ttwakeup(tp);
++ splx(s);
++}
++
++/*
++ * Start output on async tty interface. If the transmit queue
++ * has drained sufficiently, arrange for pppasyncstart to be
++ * called later at splsoftnet.
++ * Called at spltty or higher.
++ */
++int
++pppstart(tp)
++ register struct tty *tp;
++{
++ register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
++
++ /*
++ * If there is stuff in the output queue, send it now.
++ * We are being called in lieu of ttstart and must do what it would.
++ */
++ if (tp->t_oproc != NULL)
++ (*tp->t_oproc)(tp);
++
++ /*
++ * If the transmit queue has drained and the tty has not hung up
++ * or been disconnected from the ppp unit, then tell if_ppp.c that
++ * we need more output.
++ */
++ if ((CCOUNT(&tp->t_outq) >= PPP_LOWAT)
++ && ((sc == NULL) || (sc->sc_flags & SC_TIMEOUT)))
++ return 0;
++ if (!((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
++ && sc != NULL && tp == (struct tty *) sc->sc_devp) {
++ ppp_restart(sc);
++ }
++
++ return 0;
++}
++
++/*
++ * Timeout routine - try to start some more output.
++ */
++static void
++ppp_timeout(x)
++ void *x;
++{
++ struct ppp_softc *sc = (struct ppp_softc *) x;
++ struct tty *tp = (struct tty *) sc->sc_devp;
++ int s;
++
++ s = spltty();
++ sc->sc_flags &= ~SC_TIMEOUT;
++ pppstart(tp);
++ splx(s);
++}
++
++/*
++ * Allocate enough mbuf to handle current MRU.
++ */
++static void
++pppgetm(sc)
++ register struct ppp_softc *sc;
++{
++ struct mbuf *m, **mp;
++ int len;
++
++ mp = &sc->sc_m;
++ for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
++ if ((m = *mp) == NULL) {
++ MGETHDR(m, M_DONTWAIT, MT_DATA);
++ if (m == NULL)
++ break;
++ *mp = m;
++ MCLGET(m, M_DONTWAIT);
++ }
++ len -= M_DATASIZE(m);
++ mp = &m->m_next;
++ }
++}
++
++/*
++ * tty interface receiver interrupt.
++ */
++static unsigned paritytab[8] = {
++ 0x96696996, 0x69969669, 0x69969669, 0x96696996,
++ 0x69969669, 0x96696996, 0x96696996, 0x69969669
++};
++
++int
++pppinput(c, tp)
++ int c;
++ register struct tty *tp;
++{
++ register struct ppp_softc *sc;
++ struct mbuf *m;
++ int ilen, s;
++
++ sc = (struct ppp_softc *) tp->t_sc;
++ if (sc == NULL || tp != (struct tty *) sc->sc_devp)
++ return 0;
++
++ ++tk_nin;
++ ++sc->sc_stats.ppp_ibytes;
++
++ if (c & TTY_FE) {
++ /* framing error or overrun on this char - abort packet */
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: bad char %x\n", sc->sc_if.if_xname, c);
++ goto flush;
++ }
++
++ c &= 0xff;
++
++ /*
++ * Handle software flow control of output.
++ */
++ if (tp->t_iflag & IXON) {
++ if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
++ if ((tp->t_state & TS_TTSTOP) == 0) {
++ tp->t_state |= TS_TTSTOP;
++ (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
++ }
++ return 0;
++ }
++ if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
++ tp->t_state &= ~TS_TTSTOP;
++ if (tp->t_oproc != NULL)
++ (*tp->t_oproc)(tp);
++ return 0;
++ }
++ }
++
++ s = spltty();
++ if (c & 0x80)
++ sc->sc_flags |= SC_RCV_B7_1;
++ else
++ sc->sc_flags |= SC_RCV_B7_0;
++ if (paritytab[c >> 5] & (1 << (c & 0x1F)))
++ sc->sc_flags |= SC_RCV_ODDP;
++ else
++ sc->sc_flags |= SC_RCV_EVNP;
++ splx(s);
++
++ if (sc->sc_flags & SC_LOG_RAWIN)
++ ppplogchar(sc, c);
++
++ if (c == PPP_FLAG) {
++ ilen = sc->sc_ilen;
++ sc->sc_ilen = 0;
++
++ if (sc->sc_rawin_count > 0)
++ ppplogchar(sc, -1);
++
++ /*
++ * If SC_ESCAPED is set, then we've seen the packet
++ * abort sequence "}~".
++ */
++ if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
++ || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
++ s = spltty();
++ sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
++ if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: bad fcs %x\n", sc->sc_if.if_xname,
++ sc->sc_fcs);
++ sc->sc_if.if_ierrors++;
++ sc->sc_stats.ppp_ierrors++;
++ } else
++ sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
++ splx(s);
++ return 0;
++ }
++
++ if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
++ if (ilen) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: too short (%d)\n", sc->sc_if.if_xname, ilen);
++ s = spltty();
++ sc->sc_if.if_ierrors++;
++ sc->sc_stats.ppp_ierrors++;
++ sc->sc_flags |= SC_PKTLOST;
++ splx(s);
++ }
++ return 0;
++ }
++
++ /*
++ * Remove FCS trailer. Somewhat painful...
++ */
++ ilen -= 2;
++ if (--sc->sc_mc->m_len == 0) {
++ for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
++ ;
++ sc->sc_mc = m;
++ }
++ sc->sc_mc->m_len--;
++
++ /* excise this mbuf chain */
++ m = sc->sc_m;
++ sc->sc_m = sc->sc_mc->m_next;
++ sc->sc_mc->m_next = NULL;
++
++ ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
++ if (sc->sc_flags & SC_PKTLOST) {
++ s = spltty();
++ sc->sc_flags &= ~SC_PKTLOST;
++ splx(s);
++ }
++
++ pppgetm(sc);
++ return 0;
++ }
++
++ if (sc->sc_flags & SC_FLUSH) {
++ if (sc->sc_flags & SC_LOG_FLUSH)
++ ppplogchar(sc, c);
++ return 0;
++ }
++
++ if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
++ return 0;
++
++ s = spltty();
++ if (sc->sc_flags & SC_ESCAPED) {
++ sc->sc_flags &= ~SC_ESCAPED;
++ c ^= PPP_TRANS;
++ } else if (c == PPP_ESCAPE) {
++ sc->sc_flags |= SC_ESCAPED;
++ splx(s);
++ return 0;
++ }
++ splx(s);
++
++ /*
++ * Initialize buffer on first octet received.
++ * First octet could be address or protocol (when compressing
++ * address/control).
++ * Second octet is control.
++ * Third octet is first or second (when compressing protocol)
++ * octet of protocol.
++ * Fourth octet is second octet of protocol.
++ */
++ if (sc->sc_ilen == 0) {
++ /* reset the first input mbuf */
++ if (sc->sc_m == NULL) {
++ pppgetm(sc);
++ if (sc->sc_m == NULL) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: no input mbufs!\n", sc->sc_if.if_xname);
++ goto flush;
++ }
++ }
++ m = sc->sc_m;
++ m->m_len = 0;
++ m->m_data = M_DATASTART(sc->sc_m);
++ sc->sc_mc = m;
++ sc->sc_mp = mtod(m, char *);
++ sc->sc_fcs = PPP_INITFCS;
++ if (c != PPP_ALLSTATIONS) {
++ if (sc->sc_flags & SC_REJ_COMP_AC) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: garbage received: 0x%x (need 0xFF)\n",
++ sc->sc_if.if_xname, c);
++ goto flush;
++ }
++ *sc->sc_mp++ = PPP_ALLSTATIONS;
++ *sc->sc_mp++ = PPP_UI;
++ sc->sc_ilen += 2;
++ m->m_len += 2;
++ }
++ }
++ if (sc->sc_ilen == 1 && c != PPP_UI) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: missing UI (0x3), got 0x%x\n",
++ sc->sc_if.if_xname, c);
++ goto flush;
++ }
++ if (sc->sc_ilen == 2 && (c & 1) == 1) {
++ /* a compressed protocol */
++ *sc->sc_mp++ = 0;
++ sc->sc_ilen++;
++ sc->sc_mc->m_len++;
++ }
++ if (sc->sc_ilen == 3 && (c & 1) == 0) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: bad protocol %x\n", sc->sc_if.if_xname,
++ (sc->sc_mp[-1] << 8) + c);
++ goto flush;
++ }
++
++ /* packet beyond configured mru? */
++ if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: packet too big\n", sc->sc_if.if_xname);
++ goto flush;
++ }
++
++ /* is this mbuf full? */
++ m = sc->sc_mc;
++ if (M_TRAILINGSPACE(m) <= 0) {
++ if (m->m_next == NULL) {
++ pppgetm(sc);
++ if (m->m_next == NULL) {
++ if (sc->sc_flags & SC_DEBUG)
++ printf("%s: too few input mbufs!\n", sc->sc_if.if_xname);
++ goto flush;
++ }
++ }
++ sc->sc_mc = m = m->m_next;
++ m->m_len = 0;
++ m->m_data = M_DATASTART(m);
++ sc->sc_mp = mtod(m, char *);
++ }
++
++ ++m->m_len;
++ *sc->sc_mp++ = c;
++ sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
++ return 0;
++
++ flush:
++ if (!(sc->sc_flags & SC_FLUSH)) {
++ s = spltty();
++ sc->sc_if.if_ierrors++;
++ sc->sc_stats.ppp_ierrors++;
++ sc->sc_flags |= SC_FLUSH;
++ splx(s);
++ if (sc->sc_flags & SC_LOG_FLUSH)
++ ppplogchar(sc, c);
++ }
++ return 0;
++}
++
++#define MAX_DUMP_BYTES 128
++
++static void
++ppplogchar(sc, c)
++ struct ppp_softc *sc;
++ int c;
++{
++ if (c >= 0)
++ sc->sc_rawin[sc->sc_rawin_count++] = c;
++ if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
++ || (c < 0 && sc->sc_rawin_count > 0)) {
++ printf("%s input: ", sc->sc_if.if_xname);
++ pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
++ sc->sc_rawin_count = 0;
++ }
++}
++
++static void
++pppdumpb(b, l)
++ u_char *b;
++ int l;
++{
++ char buf[3*MAX_DUMP_BYTES+4];
++ char *bp = buf;
++ static char digits[] = "0123456789abcdef";
++
++ while (l--) {
++ if (bp >= buf + sizeof(buf) - 3) {
++ *bp++ = '>';
++ break;
++ }
++ *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
++ *bp++ = digits[*b++ & 0xf];
++ *bp++ = ' ';
++ }
++
++ *bp = 0;
++ printf("%s\n", buf);
++}
++
++static void
++pppdumpframe(sc, m, xmit)
++ struct ppp_softc *sc;
++ struct mbuf* m;
++ int xmit;
++{
++ int i,lcount,copycount,count;
++ char lbuf[16];
++ char *data;
++
++ if (m == NULL)
++ return;
++
++ for(count=m->m_len,data=mtod(m,char*);m != NULL;) {
++ /* build a line of output */
++ for(lcount=0;lcount < sizeof(lbuf);lcount += copycount) {
++ if (!count) {
++ m = m->m_next;
++ if (m == NULL)
++ break;
++ count = m->m_len;
++ data = mtod(m,char*);
++ }
++ copycount = (count > sizeof(lbuf)-lcount) ?
++ sizeof(lbuf)-lcount : count;
++ bcopy(data,&lbuf[lcount],copycount);
++ data += copycount;
++ count -= copycount;
++ }
++
++ /* output line (hex 1st, then ascii) */
++ printf("%s %s:", sc->sc_if.if_xname,
++ xmit ? "output" : "input ");
++ for(i=0;i<lcount;i++)
++ printf("%02x ",(u_char)lbuf[i]);
++ for(;i<sizeof(lbuf);i++)
++ printf(" ");
++ for(i=0;i<lcount;i++)
++ printf("%c",(lbuf[i] >= 040 &&
++ lbuf[i] <= 0176) ? lbuf[i] : '.');
++ printf("\n");
++ }
++}
++
++#endif /* NPPP > 0 */
diff --git a/net/ppp-mppe/patches/patch-at b/net/ppp-mppe/patches/patch-at
new file mode 100644
index 00000000000..8fb45f633f1
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-at
@@ -0,0 +1,633 @@
+$NetBSD: patch-at,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 04:00:15 1999
++++ netbsd-1.4/slcompress.c Sat Sep 18 04:06:38 1999
+@@ -0,0 +1,628 @@
++/* NetBSD: slcompress.c,v 1.20 1999/03/13 14:09:46 drochner Exp */
++/* Id: slcompress.c,v 1.3 1996/05/24 07:04:47 paulus Exp */
++
++/*
++ * Copyright (c) 1989, 1993, 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ * must display the following acknowledgement:
++ * This product includes software developed by the University of
++ * California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ * @(#)slcompress.c 8.2 (Berkeley) 4/16/94
++ */
++
++/*
++ * Routines to compress and uncompess tcp packets (for transmission
++ * over low speed serial lines.
++ *
++ * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
++ * - Initial distribution.
++ */
++
++#include <sys/param.h>
++#include <sys/mbuf.h>
++#include <sys/systm.h>
++
++#include <netinet/in.h>
++#include <netinet/in_systm.h>
++#include <netinet/ip.h>
++#include <netinet/tcp.h>
++
++#include <net/slcompress.h>
++
++#ifndef SL_NO_STATS
++#define INCR(counter) ++comp->counter;
++#else
++#define INCR(counter)
++#endif
++
++#define BCMP(p1, p2, n) bcmp((char *)(p1), (char *)(p2), (int)(n))
++#define BCOPY(p1, p2, n) bcopy((char *)(p1), (char *)(p2), (int)(n))
++
++
++void
++sl_compress_init(comp)
++ struct slcompress *comp;
++{
++ register u_int i;
++ register struct cstate *tstate = comp->tstate;
++
++ bzero((char *)comp, sizeof(*comp));
++ for (i = MAX_STATES - 1; i > 0; --i) {
++ tstate[i].cs_id = i;
++ tstate[i].cs_next = &tstate[i - 1];
++ }
++ tstate[0].cs_next = &tstate[MAX_STATES - 1];
++ tstate[0].cs_id = 0;
++ comp->last_cs = &tstate[0];
++ comp->last_recv = 255;
++ comp->last_xmit = 255;
++ comp->flags = SLF_TOSS;
++}
++
++
++/*
++ * Like sl_compress_init, but we get to specify the maximum connection
++ * ID to use on transmission.
++ */
++void
++sl_compress_setup(comp, max_state)
++ struct slcompress *comp;
++ int max_state;
++{
++ register u_int i;
++ register struct cstate *tstate = comp->tstate;
++
++ if (max_state == -1) {
++ max_state = MAX_STATES - 1;
++ bzero((char *)comp, sizeof(*comp));
++ } else {
++ /* Don't reset statistics */
++ bzero((char *)comp->tstate, sizeof(comp->tstate));
++ bzero((char *)comp->rstate, sizeof(comp->rstate));
++ }
++ for (i = max_state; i > 0; --i) {
++ tstate[i].cs_id = i;
++ tstate[i].cs_next = &tstate[i - 1];
++ }
++ tstate[0].cs_next = &tstate[max_state];
++ tstate[0].cs_id = 0;
++ comp->last_cs = &tstate[0];
++ comp->last_recv = 255;
++ comp->last_xmit = 255;
++ comp->flags = SLF_TOSS;
++}
++
++
++/* ENCODE encodes a number that is known to be non-zero. ENCODEZ
++ * checks for zero (since zero has to be encoded in the long, 3 byte
++ * form).
++ */
++#define ENCODE(n) { \
++ if ((u_int16_t)(n) >= 256) { \
++ *cp++ = 0; \
++ cp[1] = (n); \
++ cp[0] = (n) >> 8; \
++ cp += 2; \
++ } else { \
++ *cp++ = (n); \
++ } \
++}
++#define ENCODEZ(n) { \
++ if ((u_int16_t)(n) >= 256 || (u_int16_t)(n) == 0) { \
++ *cp++ = 0; \
++ cp[1] = (n); \
++ cp[0] = (n) >> 8; \
++ cp += 2; \
++ } else { \
++ *cp++ = (n); \
++ } \
++}
++
++#define DECODEL(f) { \
++ if (*cp == 0) {\
++ (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
++ cp += 3; \
++ } else { \
++ (f) = htonl(ntohl(f) + (u_int32_t)*cp++); \
++ } \
++}
++
++#define DECODES(f) { \
++ if (*cp == 0) {\
++ (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
++ cp += 3; \
++ } else { \
++ (f) = htons(ntohs(f) + (u_int32_t)*cp++); \
++ } \
++}
++
++#define DECODEU(f) { \
++ if (*cp == 0) {\
++ (f) = htons((cp[1] << 8) | cp[2]); \
++ cp += 3; \
++ } else { \
++ (f) = htons((u_int32_t)*cp++); \
++ } \
++}
++
++u_int
++sl_compress_tcp(m, ip, comp, compress_cid)
++ struct mbuf *m;
++ register struct ip *ip;
++ struct slcompress *comp;
++ int compress_cid;
++{
++ register struct cstate *cs = comp->last_cs->cs_next;
++ register u_int hlen = ip->ip_hl;
++ register struct tcphdr *oth;
++ register struct tcphdr *th;
++ register u_int deltaS, deltaA;
++ register u_int changes = 0;
++ u_char new_seq[16];
++ register u_char *cp = new_seq;
++
++ /*
++ * Bail if this is an IP fragment or if the TCP packet isn't
++ * `compressible' (i.e., ACK isn't set or some other control bit is
++ * set). (We assume that the caller has already made sure the
++ * packet is IP proto TCP).
++ */
++ if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40)
++ return (TYPE_IP);
++
++ th = (struct tcphdr *)&((int32_t *)ip)[hlen];
++ if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK)
++ return (TYPE_IP);
++ /*
++ * Packet is compressible -- we're going to send either a
++ * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need
++ * to locate (or create) the connection state. Special case the
++ * most recently used connection since it's most likely to be used
++ * again & we don't have to do any reordering if it's used.
++ */
++ INCR(sls_packets)
++ if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr ||
++ ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr ||
++ *(int32_t *)th != ((int32_t *)&cs->cs_ip)[cs->cs_ip.ip_hl]) {
++ /*
++ * Wasn't the first -- search for it.
++ *
++ * States are kept in a circularly linked list with
++ * last_cs pointing to the end of the list. The
++ * list is kept in lru order by moving a state to the
++ * head of the list whenever it is referenced. Since
++ * the list is short and, empirically, the connection
++ * we want is almost always near the front, we locate
++ * states via linear search. If we don't find a state
++ * for the datagram, the oldest state is (re-)used.
++ */
++ register struct cstate *lcs;
++ register struct cstate *lastcs = comp->last_cs;
++
++ do {
++ lcs = cs; cs = cs->cs_next;
++ INCR(sls_searches)
++ if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
++ && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
++ && *(int32_t *)th ==
++ ((int32_t *)&cs->cs_ip)[cs->cs_ip.ip_hl])
++ goto found;
++ } while (cs != lastcs);
++
++ /*
++ * Didn't find it -- re-use oldest cstate. Send an
++ * uncompressed packet that tells the other side what
++ * connection number we're using for this conversation.
++ * Note that since the state list is circular, the oldest
++ * state points to the newest and we only need to set
++ * last_cs to update the lru linkage.
++ */
++ INCR(sls_misses)
++ comp->last_cs = lcs;
++ hlen += th->th_off;
++ hlen <<= 2;
++ if (hlen > m->m_len)
++ return (TYPE_IP);
++ goto uncompressed;
++
++ found:
++ /*
++ * Found it -- move to the front on the connection list.
++ */
++ if (cs == lastcs)
++ comp->last_cs = lcs;
++ else {
++ lcs->cs_next = cs->cs_next;
++ cs->cs_next = lastcs->cs_next;
++ lastcs->cs_next = cs;
++ }
++ }
++
++ /*
++ * Make sure that only what we expect to change changed. The first
++ * line of the `if' checks the IP protocol version, header length &
++ * type of service. The 2nd line checks the "Don't fragment" bit.
++ * The 3rd line checks the time-to-live and protocol (the protocol
++ * check is unnecessary but costless). The 4th line checks the TCP
++ * header length. The 5th line checks IP options, if any. The 6th
++ * line checks TCP options, if any. If any of these things are
++ * different between the previous & current datagram, we send the
++ * current datagram `uncompressed'.
++ */
++ oth = (struct tcphdr *)&((int32_t *)&cs->cs_ip)[hlen];
++ deltaS = hlen;
++ hlen += th->th_off;
++ hlen <<= 2;
++ if (hlen > m->m_len)
++ return (TYPE_IP);
++
++ if (((u_int16_t *)ip)[0] != ((u_int16_t *)&cs->cs_ip)[0] ||
++ ((u_int16_t *)ip)[3] != ((u_int16_t *)&cs->cs_ip)[3] ||
++ ((u_int16_t *)ip)[4] != ((u_int16_t *)&cs->cs_ip)[4] ||
++ th->th_off != oth->th_off ||
++ (deltaS > 5 &&
++ BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) ||
++ (th->th_off > 5 &&
++ BCMP(th + 1, oth + 1, (th->th_off - 5) << 2)))
++ goto uncompressed;
++
++ /*
++ * Figure out which of the changing fields changed. The
++ * receiver expects changes in the order: urgent, window,
++ * ack, seq (the order minimizes the number of temporaries
++ * needed in this section of code).
++ */
++ if (th->th_flags & TH_URG) {
++ deltaS = ntohs(th->th_urp);
++ ENCODEZ(deltaS);
++ changes |= NEW_U;
++ } else if (th->th_urp != oth->th_urp)
++ /* argh! URG not set but urp changed -- a sensible
++ * implementation should never do this but RFC793
++ * doesn't prohibit the change so we have to deal
++ * with it. */
++ goto uncompressed;
++
++ deltaS = (u_int16_t)(ntohs(th->th_win) - ntohs(oth->th_win));
++ if (deltaS) {
++ ENCODE(deltaS);
++ changes |= NEW_W;
++ }
++
++ deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack);
++ if (deltaA) {
++ if (deltaA > 0xffff)
++ goto uncompressed;
++ ENCODE(deltaA);
++ changes |= NEW_A;
++ }
++
++ deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq);
++ if (deltaS) {
++ if (deltaS > 0xffff)
++ goto uncompressed;
++ ENCODE(deltaS);
++ changes |= NEW_S;
++ }
++
++ switch(changes) {
++
++ case 0:
++ /*
++ * Nothing changed. If this packet contains data and the
++ * last one didn't, this is probably a data packet following
++ * an ack (normal on an interactive connection) and we send
++ * it compressed. Otherwise it's probably a retransmit,
++ * retransmitted ack or window probe. Send it uncompressed
++ * in case the other side missed the compressed version.
++ */
++ if (ip->ip_len != cs->cs_ip.ip_len &&
++ ntohs(cs->cs_ip.ip_len) == hlen)
++ break;
++
++ /* (fall through) */
++
++ case SPECIAL_I:
++ case SPECIAL_D:
++ /*
++ * actual changes match one of our special case encodings --
++ * send packet uncompressed.
++ */
++ goto uncompressed;
++
++ case NEW_S|NEW_A:
++ if (deltaS == deltaA &&
++ deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
++ /* special case for echoed terminal traffic */
++ changes = SPECIAL_I;
++ cp = new_seq;
++ }
++ break;
++
++ case NEW_S:
++ if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
++ /* special case for data xfer */
++ changes = SPECIAL_D;
++ cp = new_seq;
++ }
++ break;
++ }
++
++ deltaS = ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id);
++ if (deltaS != 1) {
++ ENCODEZ(deltaS);
++ changes |= NEW_I;
++ }
++ if (th->th_flags & TH_PUSH)
++ changes |= TCP_PUSH_BIT;
++ /*
++ * Grab the cksum before we overwrite it below. Then update our
++ * state with this packet's header.
++ */
++ deltaA = ntohs(th->th_sum);
++ BCOPY(ip, &cs->cs_ip, hlen);
++
++ /*
++ * We want to use the original packet as our compressed packet.
++ * (cp - new_seq) is the number of bytes we need for compressed
++ * sequence numbers. In addition we need one byte for the change
++ * mask, one for the connection id and two for the tcp checksum.
++ * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how
++ * many bytes of the original packet to toss so subtract the two to
++ * get the new packet size.
++ */
++ deltaS = cp - new_seq;
++ cp = (u_char *)ip;
++ if (compress_cid == 0 || comp->last_xmit != cs->cs_id) {
++ comp->last_xmit = cs->cs_id;
++ hlen -= deltaS + 4;
++ cp += hlen;
++ *cp++ = changes | NEW_C;
++ *cp++ = cs->cs_id;
++ } else {
++ hlen -= deltaS + 3;
++ cp += hlen;
++ *cp++ = changes;
++ }
++ m->m_len -= hlen;
++ m->m_data += hlen;
++ *cp++ = deltaA >> 8;
++ *cp++ = deltaA;
++ BCOPY(new_seq, cp, deltaS);
++ INCR(sls_compressed)
++ return (TYPE_COMPRESSED_TCP);
++
++ /*
++ * Update connection state cs & send uncompressed packet ('uncompressed'
++ * means a regular ip/tcp packet but with the 'conversation id' we hope
++ * to use on future compressed packets in the protocol field).
++ */
++uncompressed:
++ BCOPY(ip, &cs->cs_ip, hlen);
++ ip->ip_p = cs->cs_id;
++ comp->last_xmit = cs->cs_id;
++ return (TYPE_UNCOMPRESSED_TCP);
++}
++
++
++int
++sl_uncompress_tcp(bufp, len, type, comp)
++ u_char **bufp;
++ int len;
++ u_int type;
++ struct slcompress *comp;
++{
++ u_char *hdr, *cp;
++ int vjlen;
++ u_int hlen;
++
++ cp = bufp? *bufp: NULL;
++ vjlen = sl_uncompress_tcp_core(cp, len, len, type, comp, &hdr, &hlen);
++ if (vjlen < 0)
++ return (0); /* error */
++ if (vjlen == 0)
++ return (len); /* was uncompressed already */
++
++ cp += vjlen;
++ len -= vjlen;
++
++ /*
++ * At this point, cp points to the first byte of data in the
++ * packet. If we're not aligned on a 4-byte boundary, copy the
++ * data down so the ip & tcp headers will be aligned. Then back up
++ * cp by the tcp/ip header length to make room for the reconstructed
++ * header (we assume the packet we were handed has enough space to
++ * prepend 128 bytes of header).
++ */
++ if ((long)cp & 3) {
++ if (len > 0)
++ memmove((caddr_t)((long)cp &~ 3), cp, len);
++ cp = (u_char *)((long)cp &~ 3);
++ }
++ cp -= hlen;
++ len += hlen;
++ BCOPY(hdr, cp, hlen);
++
++ *bufp = cp;
++ return (len);
++}
++
++/*
++ * Uncompress a packet of total length total_len. The first buflen
++ * bytes are at buf; this must include the entire (compressed or
++ * uncompressed) TCP/IP header. This procedure returns the length
++ * of the VJ header, with a pointer to the uncompressed IP header
++ * in *hdrp and its length in *hlenp.
++ */
++int
++sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
++ u_char *buf;
++ int buflen, total_len;
++ u_int type;
++ struct slcompress *comp;
++ u_char **hdrp;
++ u_int *hlenp;
++{
++ register u_char *cp;
++ register u_int hlen, changes;
++ register struct tcphdr *th;
++ register struct cstate *cs;
++ register struct ip *ip;
++ register u_int16_t *bp;
++ register u_int vjlen;
++
++ switch (type) {
++
++ case TYPE_UNCOMPRESSED_TCP:
++ ip = (struct ip *) buf;
++ if (ip->ip_p >= MAX_STATES)
++ goto bad;
++ cs = &comp->rstate[comp->last_recv = ip->ip_p];
++ comp->flags &=~ SLF_TOSS;
++ ip->ip_p = IPPROTO_TCP;
++ /*
++ * Calculate the size of the TCP/IP header and make sure that
++ * we don't overflow the space we have available for it.
++ */
++ hlen = ip->ip_hl << 2;
++ if (hlen + sizeof(struct tcphdr) > buflen)
++ goto bad;
++ hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
++ if (hlen > MAX_HDR || hlen > buflen)
++ goto bad;
++ BCOPY(ip, &cs->cs_ip, hlen);
++ cs->cs_hlen = hlen;
++ INCR(sls_uncompressedin)
++ *hdrp = (u_char *) &cs->cs_ip;
++ *hlenp = hlen;
++ return (0);
++
++ default:
++ goto bad;
++
++ case TYPE_COMPRESSED_TCP:
++ break;
++ }
++ /* We've got a compressed packet. */
++ INCR(sls_compressedin)
++ cp = buf;
++ changes = *cp++;
++ if (changes & NEW_C) {
++ /* Make sure the state index is in range, then grab the state.
++ * If we have a good state index, clear the 'discard' flag. */
++ if (*cp >= MAX_STATES)
++ goto bad;
++
++ comp->flags &=~ SLF_TOSS;
++ comp->last_recv = *cp++;
++ } else {
++ /* this packet has an implicit state index. If we've
++ * had a line error since the last time we got an
++ * explicit state index, we have to toss the packet. */
++ if (comp->flags & SLF_TOSS) {
++ INCR(sls_tossed)
++ return (-1);
++ }
++ }
++ cs = &comp->rstate[comp->last_recv];
++ hlen = cs->cs_ip.ip_hl << 2;
++ th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
++ th->th_sum = htons((*cp << 8) | cp[1]);
++ cp += 2;
++ if (changes & TCP_PUSH_BIT)
++ th->th_flags |= TH_PUSH;
++ else
++ th->th_flags &=~ TH_PUSH;
++
++ switch (changes & SPECIALS_MASK) {
++ case SPECIAL_I:
++ {
++ register u_int i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
++ th->th_ack = htonl(ntohl(th->th_ack) + i);
++ th->th_seq = htonl(ntohl(th->th_seq) + i);
++ }
++ break;
++
++ case SPECIAL_D:
++ th->th_seq = htonl(ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len)
++ - cs->cs_hlen);
++ break;
++
++ default:
++ if (changes & NEW_U) {
++ th->th_flags |= TH_URG;
++ DECODEU(th->th_urp)
++ } else
++ th->th_flags &=~ TH_URG;
++ if (changes & NEW_W)
++ DECODES(th->th_win)
++ if (changes & NEW_A)
++ DECODEL(th->th_ack)
++ if (changes & NEW_S)
++ DECODEL(th->th_seq)
++ break;
++ }
++ if (changes & NEW_I) {
++ DECODES(cs->cs_ip.ip_id)
++ } else
++ cs->cs_ip.ip_id = htons(ntohs(cs->cs_ip.ip_id) + 1);
++
++ /*
++ * At this point, cp points to the first byte of data in the
++ * packet. Fill in the IP total length and update the IP
++ * header checksum.
++ */
++ vjlen = cp - buf;
++ buflen -= vjlen;
++ if (buflen < 0)
++ /* we must have dropped some characters (crc should detect
++ * this but the old slip framing won't) */
++ goto bad;
++
++ total_len += cs->cs_hlen - vjlen;
++ cs->cs_ip.ip_len = htons(total_len);
++
++ /* recompute the ip header checksum */
++ bp = (u_int16_t *) &cs->cs_ip;
++ cs->cs_ip.ip_sum = 0;
++ for (changes = 0; hlen > 0; hlen -= 2)
++ changes += *bp++;
++ changes = (changes & 0xffff) + (changes >> 16);
++ changes = (changes & 0xffff) + (changes >> 16);
++ cs->cs_ip.ip_sum = ~ changes;
++
++ *hdrp = (u_char *) &cs->cs_ip;
++ *hlenp = cs->cs_hlen;
++ return vjlen;
++
++bad:
++ comp->flags |= SLF_TOSS;
++ INCR(sls_errorin)
++ return (-1);
++}
diff --git a/net/ppp-mppe/patches/patch-au b/net/ppp-mppe/patches/patch-au
new file mode 100644
index 00000000000..fe176a2d8bb
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-au
@@ -0,0 +1,83 @@
+$NetBSD: patch-au,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 04:13:35 1999
++++ netbsd-1.4/kinstall.sh Sat Sep 18 04:15:32 1999
+@@ -0,0 +1,78 @@
++#!/bin/sh
++
++# This script modifies the kernel sources in /sys to install
++# ppp-2.3. It is intended to be run in the ppp-2.3 directory.
++#
++# Paul Mackerras 11-Dec-95
++
++ARCH=$(uname -m)
++CONF=$(uname -v | sed 's/.*(\(.*\)).*/\1/')
++SYS=/sys
++ARCHDIR=$SYS/arch/$ARCH
++CFILE=$ARCHDIR/conf/$CONF
++SRC=netbsd-1.4
++DOCONF=
++DOMAKE=
++CONFIG=config
++
++# Copy new versions of files into /sys/net
++
++for f in include/net/if_ppp.h include/net/ppp-comp.h include/net/ppp_defs.h \
++ $SRC/bsd-comp.c $SRC/ppp-deflate.c $SRC/if_ppp.c $SRC/if_pppvar.h \
++ $SRC/ppp_tty.c $SRC/slcompress.c include/net/slcompress.h \
++ common/zlib.c common/zlib.h; do
++ dest=$SYS/net/$(basename $f)
++ if [ -f $dest ]; then
++ if ! diff -qBI '[ ]\$[IN][de].*:.*\$' $f $dest >/dev/null; then
++ echo "Copying $f to $dest"
++ mv -f $dest $dest.orig && echo " (old version saved in $dest.orig)"
++ cp $f $dest
++ DOMAKE=yes
++ fi
++ else
++ echo "Copying $f to $dest"
++ cp $f $dest
++ DOMAKE=yes
++ fi
++done
++
++# Tell the user to add a pseudo-device line to the configuration file
++# and remake the kernel, if necessary.
++
++if [ -f $CFILE ]; then
++ if ! grep -q '^[ ]*pseudo-device[ ][ ]*ppp' $CFILE; then
++ echo
++ echo "The currently-running kernel was built from configuration file"
++ echo "$CFILE, which does not include PPP."
++ echo "You need either to add a line like 'pseudo-device ppp 2' to"
++ echo "this file, or use another configuration file which includes"
++ echo "a line like this."
++ DOCONF=yes
++ fi
++fi
++
++if [ $DOCONF ]; then
++ echo
++ echo "You need to configure and build a new kernel."
++ echo "The procedure for doing this involves the following commands:"
++ echo "(\"$CONF\" may be replaced by the name of another config file.)"
++ echo
++ echo " cd $ARCHDIR/conf"
++ echo " /usr/sbin/$CONFIG $CONF"
++ echo " cd ../compile/$CONF"
++ echo " make depend"
++ DOMAKE=yes
++elif [ $DOMAKE ]; then
++ echo
++ echo "You need to build a new kernel."
++ echo "The procedure for doing this involves the following commands:"
++ echo
++ echo " cd $ARCHDIR/compile/$CONF"
++fi
++if [ $DOMAKE ]; then
++ echo " make"
++ echo
++ echo "Then copy the new kernel ($ARCHDIR/compile/$CONF/netbsd)"
++ echo "to /netbsd and reboot. (Keep a copy of the old /netbsd,"
++ echo "just in case.)"
++fi
diff --git a/net/ppp-mppe/patches/patch-ba b/net/ppp-mppe/patches/patch-ba
new file mode 100644
index 00000000000..dcd10eb64c0
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ba
@@ -0,0 +1,50 @@
+$NetBSD: patch-ba,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Wed Dec 31 16:00:00 1969
++++ README.MPPE Tue Jun 29 10:24:14 1999
+@@ -0,0 +1,45 @@
++Just a few quick notes.
++
++MPPE support was started by Árpád Magosányi <mag@bunuel.tii.matav.hu> in 1994,
++and was finished by Tim Hockin, Cobalt Networks Inc. <thockin@cobaltnet.com>
++in 1999. If you helped, and I don't know it (which could be) please notify
++the maintainer of this code, and it will be rectified. As far as I know, only i
++Linux is supported (sorry - it's all we had available).
++
++MPPE - Microsoft Point-to-Point Encryption uses rc4 (40 or 128 bit) as a
++bi-directional encryption algorithm. The keys are based on your MS-CHAP
++authentication info, so you must use chapms or chapms-v2. Rc4 is owned by
++RSA Data Security, and you may have to pay to use it, or not use it at all,
++depending on your place of residence. No author listed in this file claims
++any responsibility for misuse of this software. Copyright for some code is
++owned by Eric Young (see ./linux/rc4.h for details). Depending on where you
++got this code from (either in patch or tar.gz form), you may need to obtain
++the actual rc4 code from a different site. The implementation of rc4 found in
++the SSLeay package, by Eric Young, version 0.6.6. This package can be found
++at ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/. Newer versions than 0.6.6 may
++require some minor source code or header file changes. Once obtained, copy
++rc4.h and rc4_enc.c to the linux/ subdir of this package.
++
++This is NOT a particularly secure mode of operation. For maximum possible
++security using MPPE, it is advised in the RFC's to use the highest mode of
++encryption that is legal, and to enable stateless mode (which renogotiates
++keys with every packet). Even with these precautions, MPPE is not very secure,
++but anything is better than nothing, right?
++
++That said, it seems to work pretty well, for what it is. MSChap-v2 support
++was added by someone along the way, and MPPE needed some finishing. It
++appears to work with Windows (tm) clients, with encryption specified.
++
++How to use it:
++* Compile this pppd, and teh associated kernel modules.
++* Add +chapms and/or +chapms-v2 to your pppd command line.
++* Add mppe-40 and/or mppe-128 and/or mppe-stateless to your pppd command line.
++* Either load ppp_mppe.o manually or put this line in your /etc/conf.modules.
++ alias ppp-compress-18 ppp_mppe
++* Go for it.
++
++
++For further reading:
++ Use the source, Luke.
++ draft-ietf-pppext-mppe-03.txt (any RFC site should have this)
++ draft-ietf-pppext-mppe-keys-00.txt (ditto)
diff --git a/net/ppp-mppe/patches/patch-bb b/net/ppp-mppe/patches/patch-bb
new file mode 100644
index 00000000000..a7498c23170
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bb
@@ -0,0 +1,181 @@
+$NetBSD: patch-bb,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/auth.c.orig2 Sat Sep 25 12:36:32 1999
++++ pppd/auth.c Sat Sep 25 12:48:02 1999
+@@ -74,8 +74,16 @@
+ #ifdef CBCP_SUPPORT
+ #include "cbcp.h"
+ #endif
++#ifdef CHAPMS
++#include "chap_ms.h"
++#endif
+ #include "pathnames.h"
+
++#ifdef DYNAMIC
++#define _PATH_DYNAMIC "/etc/ppp/getaddr"
++#endif
++static char xuser[MAXNAMELEN];
++
+ static const char rcsid[] = RCSID;
+
+ /* Bits in scan_authfile return value */
+@@ -108,6 +116,11 @@
+ /* Set if we got the contents of passwd[] from the pap-secrets file. */
+ static int passwd_from_file;
+
++#ifdef CBCP_SUPPORT
++/* Set if we have done call-back sequences. */
++static int did_callback;
++#endif
++
+ /*
+ * This is used to ensure that we don't start an auth-up/down
+ * script while one is already running.
+@@ -144,7 +157,7 @@
+
+ /* Prototypes for procedures local to this file. */
+
+-static void network_phase __P((int));
++void network_phase __P((int));
+ static void check_idle __P((void *));
+ static void connect_time_expired __P((void *));
+ static int plogin __P((char *, char *, char **, int *));
+@@ -177,14 +190,36 @@
+ "Don't agree to auth to peer with PAP", 1 },
+ { "-pap", o_bool, &refuse_pap,
+ "Don't allow PAP authentication with peer", 1 },
+- { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap,
+- "Require CHAP authentication from peer", 1, &auth_required },
+- { "+chap", o_bool, &lcp_wantoptions[0].neg_chap,
+- "Require CHAP authentication from peer", 1, &auth_required },
++ { "require-chap", o_special_noarg, reqchap,
++ "Require CHAP authentication from peer" },
++ { "+chap", o_special_noarg, reqchap,
++ "Require CHAP authentication from peer" },
+ { "refuse-chap", o_bool, &refuse_chap,
+ "Don't agree to auth to peer with CHAP", 1 },
+ { "-chap", o_bool, &refuse_chap,
+ "Don't allow CHAP authentication with peer", 1 },
++ { "refuse-chap-md5", o_bool, &lcp_wantoptions[0].use_digest,
++ "Don't allow md5-digest style CHAP", 0 },
++ { "-chap-md5", o_bool, &lcp_wantoptions[0].use_digest,
++ "Don't allow md5-digest style CHAP", 0 },
++#ifdef CHAPMS
++ { "require-chapms", o_special_noarg, reqchapms,
++ "Require MSCHAP (v1) authentication" },
++ { "+chapms", o_special_noarg, reqchapms,
++ "Require MSCHAP (v1) authentication" },
++ { "refuse-chapms", o_special_noarg, nochapms,
++ "Refuse MSCHAP (v1) authentication" },
++ { "-chapms", o_special_noarg, nochapms,
++ "Refuse MSCHAP (v1) authentication" },
++ { "require-chapms-v2", o_special_noarg, reqchapms_v2,
++ "Require MSCHAP-v2 authentication" },
++ { "+chapms-v2", o_special_noarg, reqchapms_v2,
++ "Require MSCHAP-v2 authentication" },
++ { "refuse-chapms-v2", o_special_noarg, nochapms_v2,
++ "Refuse MSCHAP-v2 authentication" },
++ { "-chapms-v2", o_special_noarg, nochapms_v2,
++ "Refuse MSCHAP-v2 authentication" },
++#endif
+ { "name", o_string, our_name,
+ "Set local name for authentication",
+ OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN },
+@@ -402,11 +437,14 @@
+ /*
+ * Proceed to the network phase.
+ */
+-static void
++void
+ network_phase(unit)
+ int unit;
+ {
+ lcp_options *go = &lcp_gotoptions[unit];
++#ifdef CBCP_SUPPORT
++ lcp_options *ho = &lcp_hisoptions[unit];
++#endif
+
+ /*
+ * If the peer had to authenticate, run the auth-up script now.
+@@ -423,8 +461,9 @@
+ /*
+ * If we negotiated callback, do it now.
+ */
+- if (go->neg_cbcp) {
++ if ((go->neg_cbcp || ho->neg_cbcp) && !did_callback) {
+ phase = PHASE_CALLBACK;
++ did_callback = 1;
+ (*cbcp_protent.open)(unit);
+ return;
+ }
+@@ -510,6 +549,8 @@
+ namelen = sizeof(peer_authname) - 1;
+ BCOPY(name, peer_authname, namelen);
+ peer_authname[namelen] = 0;
++ BCOPY(name, xuser, namelen);
++ xuser[namelen] = 0;
+ script_setenv("PEERNAME", peer_authname);
+
+ /*
+@@ -1291,6 +1332,61 @@
+
+ return 1;
+ }
++
++#ifdef DYNAMIC
++/*
++ * get_ip_addr_dynamic - scans dynamic-givable address space for
++ * most recently used address for given user.
++ */
++int
++get_ip_addr_dynamic(unit, addr)
++ int unit;
++ u_int32_t *addr;
++{
++ u_int32_t a;
++ struct wordlist *addrs;
++ FILE *fd;
++ int dfd;
++ char command[256];
++ char mypid[40], *s;
++ char address[50];
++ u_int32_t mask;
++
++ if ((addrs = addresses[unit]) == NULL)
++ return 0; /* no restriction */
++
++ fd = (FILE *)NULL;
++ for(; addrs != NULL; addrs = addrs->next) {
++ if(strcmp(addrs->word, "*") != 0)
++ continue;
++ sprintf(mypid, "/var/tmp/ppp_dynamic.%d", getpid());
++ sprintf(command, "%s %s %s %s", _PATH_DYNAMIC, xuser, devnam, mypid);
++ dfd = open("/dev/null", O_RDWR);
++ device_script(command, dfd, dfd);
++ close(dfd);
++ fd = fopen(mypid, "r");
++ if(fd == (FILE *)NULL)
++ break;
++ if(fgets(address, sizeof(address), fd) == (char *)NULL)
++ break;
++ if((s = strchr(address, '\n')) != (char *)NULL)
++ *s = '\0';
++ a = inet_addr(address);
++ if(a == -1L)
++ break;
++ fclose(fd);
++ unlink(mypid);
++ *addr = a;
++ return 1;
++ }
++ if(fd != (FILE *)NULL)
++ {
++ fclose(fd);
++ unlink(mypid);
++ }
++ return 0;
++}
++#endif
+
+ /*
+ * set_allowed_addrs() - set the list of allowed addresses.
diff --git a/net/ppp-mppe/patches/patch-bc b/net/ppp-mppe/patches/patch-bc
new file mode 100644
index 00000000000..527773e21e8
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bc
@@ -0,0 +1,520 @@
+$NetBSD: patch-bc,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/cbcp.c.orig2 Sat Sep 25 12:51:36 1999
++++ pppd/cbcp.c Sat Sep 25 13:11:31 1999
+@@ -17,4 +17,25 @@
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
++
++/*
++ * Microsoft Call Back Configuration Protocol.
++ * by Pedro Roque Marques
++ *
++ * The CBCP is a method by which the Microsoft Windows NT Server may
++ * implement additional security. It is possible to configure the server
++ * in such a manner so as to require that the client systems which
++ * connect with it are required that following a valid authentication to
++ * leave a method by which the number may be returned call.
++ *
++ * It is a requirement of servers so configured that the protocol be
++ * exchanged.
++ *
++ * So, this set of patches may be applied to the pppd process to enable
++ * the cbcp client *only* portion of the specification. It is primarily
++ * meant to permit connection with Windows NT Servers.
++ *
++ * The ietf-working specification may be obtained from ftp.microsoft.com
++ * in the developr/rfc directory.
++ */
+
+@@ -32,14 +52,25 @@
+
+ static const char rcsid[] = RCSID;
+
++void network_phase __P((int));
++
+ /*
+ * Options.
+ */
+ static int setcbcp __P((char **));
++static int setcbcpreq __P((char **));
++static int setnocbcp __P((char **));
+
+ static option_t cbcp_option_list[] = {
+ { "callback", o_special, setcbcp,
+ "Ask for callback" },
++ { "+callback", o_special_noarg, setcbcpreq,
++ "Ask for callback" },
++ { "nocallback", o_special, setnocbcp,
++ "Don't allow callbacks" },
++ { "-callback", o_special, setnocbcp,
++ "Don't allow callbacks" },
++
+ { NULL }
+ };
+
+@@ -48,7 +79,9 @@
+ */
+ static void cbcp_init __P((int unit));
+ static void cbcp_open __P((int unit));
++static void cbcp_close __P((int unit, char *));
+ static void cbcp_lowerup __P((int unit));
++static void cbcp_lowerdown __P((int unit));
+ static void cbcp_input __P((int unit, u_char *pkt, int len));
+ static void cbcp_protrej __P((int unit));
+ static int cbcp_printpkt __P((u_char *pkt, int len,
+@@ -61,12 +94,12 @@
+ cbcp_input,
+ cbcp_protrej,
+ cbcp_lowerup,
+- NULL,
++ cbcp_lowerdown,
+ cbcp_open,
+- NULL,
++ cbcp_close,
+ cbcp_printpkt,
+ NULL,
+- 0,
++ 1,
+ "CBCP",
+ NULL,
+ cbcp_option_list,
+@@ -80,23 +113,46 @@
+ /* internal prototypes */
+
+ static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
+-static void cbcp_resp __P((cbcp_state *us));
+-static void cbcp_up __P((cbcp_state *us));
+ static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
++static void cbcp_recvresp __P((cbcp_state *us, char *pckt, int len));
++static void cbcp_resp __P((cbcp_state *us));
++static void cbcp_req __P((cbcp_state *us));
++static void cbcp_ack __P((cbcp_state *us));
+ static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
++static void cbcp_up __P((cbcp_state *us));
+
+ /* option processing */
+ static int
+ setcbcp(argv)
+ char **argv;
+ {
+- lcp_wantoptions[0].neg_cbcp = 1;
+- cbcp_protent.enabled_flag = 1;
++ lcp_allowoptions[0].neg_cbcp = 1;
+ cbcp[0].us_number = strdup(*argv);
+ if (cbcp[0].us_number == 0)
+ novm("callback number");
+- cbcp[0].us_type |= (1 << CB_CONF_USER);
+- cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
++ if (cbcp[0].us_number[0] == '-')
++ cbcp[0].us_type = (1 << CB_CONF_NO);
++ else
++ {
++ cbcp[0].us_type = (1 << CB_CONF_USER);
++ cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
++ }
++ return (1);
++}
++
++static int
++setnocbcp(argv)
++ char **argv;
++{
++ lcp_allowoptions[0].neg_cbcp = lcp_wantoptions[0].neg_cbcp = 0;
++ return (1);
++}
++
++static int
++setcbcpreq(argv)
++ char **argv;
++{
++ lcp_wantoptions[0].neg_cbcp = 1;
+ return (1);
+ }
+
+@@ -110,7 +166,8 @@
+ us = &cbcp[iface];
+ memset(us, 0, sizeof(cbcp_state));
+ us->us_unit = iface;
+- us->us_type |= (1 << CB_CONF_NO);
++ us->us_type = (1 << CB_CONF_NO);
++ us->us_id = 1;
+ }
+
+ /* lower layer is up */
+@@ -120,18 +177,60 @@
+ {
+ cbcp_state *us = &cbcp[iface];
+
+- dbglog("cbcp_lowerup");
+- dbglog("want: %d", us->us_type);
++ if (debug)
++ {
++ dbglog("cbcp_lowerup");
++ dbglog("want: %d", us->us_type);
+
+- if (us->us_type == CB_CONF_USER)
+- dbglog("phone no: %s", us->us_number);
++ if (us->us_type & (1 << CB_CONF_USER))
++ dbglog("phone no: %s", us->us_number);
++ }
++}
++
++static void
++cbcp_lowerdown(iface)
++ int iface;
++{
++ if(debug)
++ dbglog("cbcp_lowerdown");
+ }
+
+ static void
+ cbcp_open(unit)
+ int unit;
+ {
+- dbglog("cbcp_open");
++ lcp_options *ho = &lcp_hisoptions[unit];
++ lcp_options *ao = &lcp_allowoptions[unit];
++ lcp_options *wo = &lcp_wantoptions[unit];
++ lcp_options *go = &lcp_gotoptions[unit];
++ cbcp_state *us = &cbcp[unit];
++
++ if(debug)
++ dbglog("cbcp_open");
++ if(ao->neg_cbcp)
++ {
++ if(ho->neg_cbcp)
++ {
++ cbcp_req(us);
++ return;
++ }
++ }
++ else if(wo->neg_cbcp)
++ {
++ if(!go->neg_cbcp)
++ lcp_close(0, "Callback required");
++ return;
++ }
++ cbcp_up(us);
++}
++
++static void
++cbcp_close(unit, reason)
++ int unit;
++ char *reason;
++{
++ if(debug)
++ dbglog("cbcp_close: %s", reason);
+ }
+
+ /* process an incomming packet */
+@@ -174,11 +273,13 @@
+ break;
+
+ case CBCP_RESP:
+- dbglog("CBCP_RESP received");
++ if (id != us->us_id && debug)
++ dbglog("id doesn't match: expected %d recv %d", us->us_id, id);
++ cbcp_recvresp(us, inp, len);
+ break;
+
+ case CBCP_ACK:
+- if (id != us->us_id)
++ if (id != us->us_id && debug)
+ dbglog("id doesn't match: expected %d recv %d",
+ us->us_id, id);
+
+@@ -298,7 +399,8 @@
+ address[0] = 0;
+
+ while (len) {
+- dbglog("length: %d", len);
++ if (debug)
++ dbglog("length: %d", len);
+
+ GETCHAR(type, pckt);
+ GETCHAR(opt_len, pckt);
+@@ -310,22 +412,22 @@
+
+ switch(type) {
+ case CB_CONF_NO:
+- dbglog("no callback allowed");
++ dbglog("Callback: none");
+ break;
+
+ case CB_CONF_USER:
+- dbglog("user callback allowed");
+ if (opt_len > 4) {
+ GETCHAR(addr_type, pckt);
+ memcpy(address, pckt, opt_len - 4);
+ address[opt_len - 4] = 0;
+- if (address[0])
+- dbglog("address: %s", address);
++ dbglog("Callback: user callback, address: '%s'", address);
+ }
++ else
++ dbglog("Callback: user callback");
+ break;
+
+ case CB_CONF_ADMIN:
+- dbglog("user admin defined allowed");
++ dbglog("Callback: user admin defined");
+ break;
+
+ case CB_CONF_LIST:
+@@ -347,29 +449,35 @@
+ int len = 0;
+
+ cb_type = us->us_allowed & us->us_type;
+- dbglog("cbcp_resp cb_type=%d", cb_type);
++ if (debug)
++ dbglog("cbcp_resp cb_type=%d", cb_type);
+
++ if (!cb_type) {
++ dbglog("Your remote side wanted a callback-type you don't allow -> doing no callback");
++ cb_type = 1 << CB_CONF_NO;
+ #if 0
+- if (!cb_type)
+ lcp_down(us->us_unit);
+ #endif
++ }
+
+ if (cb_type & ( 1 << CB_CONF_USER ) ) {
+- dbglog("cbcp_resp CONF_USER");
++ if (debug)
++ dbglog("cbcp_resp CONF_USER");
+ PUTCHAR(CB_CONF_USER, bufp);
+- len = 3 + 1 + strlen(us->us_number) + 1;
++ len = 2 + 1 + strlen(us->us_number);
+ PUTCHAR(len , bufp);
+ PUTCHAR(5, bufp); /* delay */
+ PUTCHAR(1, bufp);
+- BCOPY(us->us_number, bufp, strlen(us->us_number) + 1);
++ BCOPY(us->us_number, bufp, strlen(us->us_number));
+ cbcp_send(us, CBCP_RESP, buf, len);
+ return;
+ }
+
+ if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
+- dbglog("cbcp_resp CONF_ADMIN");
++ if (debug)
++ dbglog("cbcp_resp CONF_ADMIN");
+ PUTCHAR(CB_CONF_ADMIN, bufp);
+- len = 3;
++ len = 2 + 1;
+ PUTCHAR(len, bufp);
+ PUTCHAR(5, bufp); /* delay */
+ cbcp_send(us, CBCP_RESP, buf, len);
+@@ -377,18 +485,181 @@
+ }
+
+ if (cb_type & ( 1 << CB_CONF_NO ) ) {
+- dbglog("cbcp_resp CONF_NO");
++ if (debug)
++ dbglog("cbcp_resp CONF_NO");
+ PUTCHAR(CB_CONF_NO, bufp);
+- len = 3;
++ len = 2;
+ PUTCHAR(len , bufp);
+- PUTCHAR(0, bufp);
+ cbcp_send(us, CBCP_RESP, buf, len);
+- start_networks();
+ return;
+ }
+ }
+
+ static void
++cbcp_ack(us)
++ cbcp_state *us;
++{
++ u_char cb_type;
++ u_char buf[256];
++ u_char *bufp = buf;
++ int len = 0;
++
++ cb_type = us->us_allowed & us->us_type;
++ if(debug)
++ dbglog("cbcp_ack cb_type=%d", cb_type);
++
++ if (!cb_type) {
++ dbglog("Your remote side wanted a callback-type you don't allow -> doing no callback");
++ cb_type = 1 << CB_CONF_NO;
++ lcp_close(us->us_unit, "Invalid callback requested");
++ return;
++ }
++
++ if (cb_type & ( 1 << CB_CONF_USER ) ) {
++ if(debug)
++ dbglog("cbcp_ack CONF_USER");
++ PUTCHAR(CB_CONF_USER, bufp);
++ len = 2 + 1 + strlen(us->us_number);
++ PUTCHAR(len , bufp);
++ PUTCHAR(5, bufp); /* delay */
++ PUTCHAR(1, bufp);
++ BCOPY(us->us_number, bufp, strlen(us->us_number));
++ cbcp_send(us, CBCP_ACK, buf, len);
++ cbcp_up(us);
++ return;
++ }
++
++ if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
++ if(debug)
++ dbglog("cbcp_ack CONF_ADMIN");
++ PUTCHAR(CB_CONF_ADMIN, bufp);
++ len = 2 + 1;
++ PUTCHAR(len , bufp);
++ PUTCHAR(5, bufp); /* delay */
++ PUTCHAR(0, bufp);
++ cbcp_send(us, CBCP_ACK, buf, len);
++ cbcp_up(us);
++ return;
++ }
++
++ if (cb_type & ( 1 << CB_CONF_NO ) ) {
++ if(debug)
++ dbglog("cbcp_ack CONF_NO");
++ PUTCHAR(CB_CONF_NO, bufp);
++ len = 2;
++ PUTCHAR(len , bufp);
++ cbcp_send(us, CBCP_ACK, buf, len);
++ cbcp_up(us);
++ return;
++ }
++}
++
++static void
++cbcp_req(us)
++ cbcp_state *us;
++{
++ u_char cb_type;
++ u_char buf[256];
++ u_char *bufp = buf;
++ int len = 0;
++
++ cb_type = us->us_type;
++
++ if (cb_type & ( 1 << CB_CONF_USER ) ) {
++ if(debug)
++ dbglog("cbcp_req CONF_USER");
++ PUTCHAR(CB_CONF_USER, bufp);
++ len = 2 + 1 + strlen(us->us_number);
++ PUTCHAR(len , bufp);
++ PUTCHAR(5, bufp); /* delay */
++ PUTCHAR(1, bufp);
++ BCOPY(us->us_number, bufp, strlen(us->us_number));
++ cbcp_send(us, CBCP_REQ, buf, len);
++ return;
++ }
++
++ if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
++ if(debug)
++ dbglog("cbcp_req CONF_ADMIN");
++ PUTCHAR(CB_CONF_ADMIN, bufp);
++ len = 2 + 1;
++ PUTCHAR(len , bufp);
++ PUTCHAR(5, bufp); /* delay */
++ PUTCHAR(0, bufp);
++ cbcp_send(us, CBCP_REQ, buf, len);
++ return;
++ }
++
++ if (cb_type & ( 1 << CB_CONF_NO ) ) {
++ if(debug)
++ dbglog("cbcp_req CONF_NO");
++ PUTCHAR(CB_CONF_NO, bufp);
++ len = 2;
++ PUTCHAR(len , bufp);
++ cbcp_send(us, CBCP_REQ, buf, len);
++ return;
++ }
++}
++
++/* received CBCP request */
++static void
++cbcp_recvresp(us, pckt, pcktlen)
++ cbcp_state *us;
++ char *pckt;
++ int pcktlen;
++{
++ u_char type, opt_len, delay, addr_type;
++ char address[256];
++ int len = pcktlen;
++
++ address[0] = 0;
++
++ if(debug)
++ dbglog("CBCP_RESP received");
++
++ while (len) {
++ if(debug)
++ dbglog("length: %d", len);
++
++ GETCHAR(type, pckt);
++ GETCHAR(opt_len, pckt);
++
++ if (opt_len > 2)
++ GETCHAR(delay, pckt);
++
++ us->us_allowed |= (1 << type);
++
++ switch(type) {
++ case CB_CONF_NO:
++ dbglog("Callback: none");
++ break;
++
++ case CB_CONF_USER:
++ if (opt_len > 4) {
++ GETCHAR(addr_type, pckt);
++ memcpy(address, pckt, opt_len - 4);
++ address[opt_len - 4] = 0;
++ dbglog("Callback: user callback, address: '%s'", address);
++ }
++ else
++ dbglog("Callback: user callback");
++ break;
++
++ case CB_CONF_ADMIN:
++ dbglog("Callback: user admin defined");
++ break;
++
++ case CB_CONF_LIST:
++ break;
++ }
++ len -= opt_len;
++ }
++
++ cbcp_ack(us);
++}
++
++
++static void
+ cbcp_send(us, code, buf, len)
+ cbcp_state *us;
+ u_char code;
+@@ -436,10 +707,14 @@
+ memcpy(address, pckt, opt_len - 4);
+ address[opt_len - 4] = 0;
+ if (address[0])
+- dbglog("peer will call: %s", address);
++ dbglog("Callback: peer will call: '%s'", address);
+ }
+- if (type == CB_CONF_NO)
++ if (type != CB_CONF_NO)
++ {
++ persist = 0;
++ lcp_close(0, "Call me back, please");
+ return;
++ }
+ }
+
+ cbcp_up(us);
+@@ -450,7 +725,6 @@
+ cbcp_up(us)
+ cbcp_state *us;
+ {
+- persist = 0;
+- lcp_close(0, "Call me back, please");
++ network_phase(us->us_unit);
+ status = EXIT_CALLBACK;
+ }
diff --git a/net/ppp-mppe/patches/patch-bd b/net/ppp-mppe/patches/patch-bd
new file mode 100644
index 00000000000..011a77eb29d
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bd
@@ -0,0 +1,356 @@
+$NetBSD: patch-bd,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/ccp.c.orig Fri Aug 13 02:46:11 1999
++++ pppd/ccp.c Sat Sep 25 14:31:25 1999
+@@ -33,6 +33,9 @@
+ #include "pppd.h"
+ #include "fsm.h"
+ #include "ccp.h"
++#ifdef MPPE
++#include "mppe.h"
++#endif
+ #include <net/ppp-comp.h>
+
+ static const char rcsid[] = RCSID;
+@@ -75,6 +78,32 @@
+ { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
+ "don't allow Predictor-1", OPT_A2COPY,
+ &ccp_allowoptions[0].predictor_1 },
++#ifdef MPPE
++ { "mppe-40", o_special_noarg, setmppe_40,
++ "Allow 40 bit MPPE encryption" },
++ { "+mppe-40", o_special_noarg, setmppe_40,
++ "Allow 40 bit MPPE encryption" },
++ { "nomppe-40", o_special_noarg, setnomppe_40,
++ "Disallow 40 bit MPPE encryption" },
++ { "-mppe-40", o_special_noarg, setnomppe_40,
++ "Disallow 40 bit MPPE encryption" },
++ { "mppe-128", o_special_noarg, setmppe_128,
++ "Allow 128 bit MPPE encryption" },
++ { "+mppe-128", o_special_noarg, setmppe_128,
++ "Allow 128 bit MPPE encryption" },
++ { "nomppe-128", o_special_noarg, setnomppe_128,
++ "Disallow 128 bit MPPE encryption" },
++ { "-mppe-128", o_special_noarg, setnomppe_128,
++ "Disallow 128 bit MPPE encryption" },
++ { "mppe-stateless", o_special_noarg, setmppe_stateless,
++ "Allow stateless MPPE encryption" },
++ { "+mppe-stateless", o_special_noarg, setmppe_stateless,
++ "Allow stateless MPPE encryption" },
++ { "nomppe-stateless", o_special_noarg, setnomppe_stateless,
++ "Disallow stateless MPPE encryption" },
++ { "-mppe-stateless", o_special_noarg, setnomppe_stateless,
++ "Disallow stateless MPPE encryption" },
++#endif
+
+ { NULL }
+ };
+@@ -157,8 +186,14 @@
+ /*
+ * Do we want / did we get any compression?
+ */
++#ifdef MPPE
++#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
++ || (opt).predictor_1 || (opt).predictor_2 \
++ || (opt).mppe )
++#else
+ #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
+ || (opt).predictor_1 || (opt).predictor_2)
++#endif
+
+ /*
+ * Local state (mainly for handling reset-reqs and reset-acks).
+@@ -282,6 +317,16 @@
+ ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
+
+ ccp_allowoptions[0].predictor_1 = 1;
++#ifdef MPPE
++ ccp_wantoptions[0].mppe = 0;
++ ccp_wantoptions[0].mppe_stateless = 0;
++ ccp_wantoptions[0].mppe_40 = 0;
++ ccp_wantoptions[0].mppe_128 = 0;
++ ccp_allowoptions[0].mppe_stateless = 1;
++ ccp_allowoptions[0].mppe = 1;
++ ccp_allowoptions[0].mppe_40 = 1;
++ ccp_allowoptions[0].mppe_128 = 1;
++#endif /* MPPE*/
+ }
+
+ /*
+@@ -420,7 +465,7 @@
+ fsm *f;
+ {
+ ccp_options *go = &ccp_gotoptions[f->unit];
+- u_char opt_buf[16];
++ u_char opt_buf[256];
+
+ *go = ccp_wantoptions[f->unit];
+ all_rejected[f->unit] = 0;
+@@ -436,6 +481,18 @@
+ if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0)
+ go->bsd_compress = 0;
+ }
++#ifdef MPPE
++ if (go->mppe) {
++ opt_buf[0] = CI_MPPE;
++ opt_buf[1] = CILEN_MPPE;
++ opt_buf[2] = 0;
++ /* keysize is 8 here */
++ BCOPY(mppe_master_send_key_40, opt_buf+3, 8);
++ BCOPY(mppe_master_recv_key_40, opt_buf+11, 8);
++ if (ccp_test(f->unit, opt_buf, (2*8)+3, 0) <= 0)
++ go->mppe = 0;
++ }
++#endif /*MPPE*/
+ if (go->deflate) {
+ if (go->deflate_correct) {
+ opt_buf[0] = CI_DEFLATE;
+@@ -481,6 +538,9 @@
+
+ return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
+ + (go->deflate? CILEN_DEFLATE: 0)
++#ifdef MPPE
++ + (go->mppe? CILEN_MPPE: 0)
++#endif
+ + (go->predictor_1? CILEN_PREDICTOR_1: 0)
+ + (go->predictor_2? CILEN_PREDICTOR_2: 0);
+ }
+@@ -529,6 +589,41 @@
+ p += CILEN_DEFLATE;
+ }
+ }
++#ifdef MPPE
++ if (go->mppe) {
++ u_char opt_buf[64];
++ u_int keysize = 0;
++
++ if(!mppe_allowed)
++ go->mppe_stateless = go->mppe_40 = go->mppe_128 = 0;
++ p[0]=CI_MPPE;
++ p[1]=CILEN_MPPE;
++ p[2]=(go->mppe_stateless ? MPPE_STATELESS : 0);
++ p[3]=0;
++ p[4]=0;
++ p[5]=(go->mppe_40 ? MPPE_40BIT : 0) | (go->mppe_128 ? MPPE_128BIT : 0);
++ if(p[5] & MPPE_40BIT) {
++ keysize = 8;
++ BCOPY(mppe_master_send_key_40, opt_buf+3, keysize);
++ BCOPY(mppe_master_recv_key_40, opt_buf+11, keysize);
++ } else if(p[5] & MPPE_128BIT) {
++ keysize = 16;
++ BCOPY(mppe_master_send_key_128, opt_buf+3, keysize);
++ BCOPY(mppe_master_recv_key_128, opt_buf+19, keysize);
++ }
++ if(p[5] != 0) {
++ opt_buf[0]=CI_MPPE;
++ opt_buf[1]=CILEN_MPPE;
++ opt_buf[2] = (go->mppe_stateless) ? 1 : 0;
++ res = ccp_test(f->unit, opt_buf, (2*keysize)+3, 0);
++ } else {
++ res = -1;
++ }
++ if (res > 0) {
++ p += CILEN_MPPE;
++ }
++ }
++#endif /* MPPE*/
+ if (go->bsd_compress) {
+ p[0] = CI_BSD_COMPRESS;
+ p[1] = CILEN_BSD_COMPRESS;
+@@ -612,6 +707,22 @@
+ len -= CILEN_DEFLATE;
+ }
+ }
++#ifdef MPPE
++ if (go->mppe) {
++ if ( len < CILEN_MPPE
++ || p[1] != CILEN_MPPE || p[0] != CI_MPPE
++ || p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0)
++ || p[3] != 0
++ || p[4] != 0
++ || p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) | (go->mppe_128 ? MPPE_128BIT : 0)))
++ return 0;
++ p += CILEN_MPPE;
++ len -= CILEN_MPPE;
++ /* Cope with first/fast ack */
++ if (len == 0)
++ return 1;
++ }
++#endif /* MPPE */
+ if (go->bsd_compress) {
+ if (len < CILEN_BSD_COMPRESS
+ || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
+@@ -690,6 +801,23 @@
+ }
+ }
+
++#ifdef MPPE
++ if (len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
++ no.mppe = 1;
++ if((p[5] & MPPE_128BIT) == 0)
++ try.mppe_128 = 0;
++ if((p[5] & MPPE_40BIT) == 0)
++ try.mppe_40 = 0;
++ if((p[2] & MPPE_STATELESS) == 0)
++ try.mppe_stateless = 0;
++ if(!try.mppe_128 && !try.mppe_40) {
++ no.mppe = 0;
++ try.mppe = 0;
++ }
++ p += CILEN_MPPE;
++ len -= CILEN_MPPE;
++ }
++#endif /* MPPE */
+ if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
+ && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
+ no.bsd_compress = 1;
+@@ -762,6 +890,14 @@
+ if (!try.deflate_correct && !try.deflate_draft)
+ try.deflate = 0;
+ }
++#ifdef MPPE
++ if (go->mppe && len >= CILEN_MPPE
++ && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
++ try.mppe = 0;
++ p += CILEN_MPPE;
++ len -= CILEN_MPPE;
++ }
++#endif /*MPPE*/
+ if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
+ && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
+ if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
+@@ -875,6 +1011,78 @@
+ }
+ break;
+
++#ifdef MPPE
++ case CI_MPPE:
++ if (!ao->mppe || clen != CILEN_MPPE) {
++ newret = CONFREJ;
++ break;
++ }
++ if(!mppe_allowed)
++ {
++ newret = CONFREJ;
++ break;
++ }
++ ho->mppe = 1;
++ if((p[5]&(MPPE_40BIT|MPPE_128BIT)) == (MPPE_40BIT|MPPE_128BIT))
++ {
++ /* if both are available, select the stronger */
++ p[5] &= ~MPPE_40BIT;
++ newret = CONFNAK;
++ }
++ if((p[2] & ~MPPE_STATELESS) != 0
++ || p[3] != 0
++ || p[4] != 0
++ || (p[5] & ~(MPPE_40BIT | MPPE_128BIT)) != 0)
++ {
++ ccp_options *wo = &ccp_wantoptions[f->unit];
++ /* not sure what they want, tell 'em what we got */
++ p[2] &= MPPE_STATELESS;
++ p[3] &= 0;
++ p[4] &= 0;
++ p[5] &= MPPE_40BIT | MPPE_128BIT;
++ if(wo->mppe_40)
++ p[5] |= MPPE_40BIT;
++ if(wo->mppe_128)
++ p[5] |= MPPE_128BIT;
++ newret = CONFNAK;
++ }
++
++ if((newret == CONFACK) || (newret == CONFNAK))
++ {
++ /*
++ * The kernel ppp driver needs the session key
++ * which is not sent via CCP :(
++ */
++ unsigned int keysize;
++ unsigned char opt_buf[64];
++ opt_buf[0] = CI_MPPE;
++ opt_buf[1] = CILEN_MPPE;
++ opt_buf[2] = ((p[2] & MPPE_STATELESS) ? 1 : 0);
++ /* push in our send/receive keys */
++ if(p[5] & MPPE_40BIT) {
++ ho->mppe_40 = 1;
++ keysize = 8;
++ BCOPY(mppe_master_send_key_40, opt_buf+3, keysize);
++ BCOPY(mppe_master_recv_key_40, opt_buf+11, keysize);
++ } else if(p[5] & MPPE_128BIT) {
++ ho->mppe_128 = 1;
++ keysize = 16;
++ BCOPY(mppe_master_send_key_128, opt_buf+3, keysize);
++ BCOPY(mppe_master_recv_key_128, opt_buf+19, keysize);
++ } else {
++ ho->mppe = 0;
++ newret = CONFREJ;
++ break;
++ }
++ /* call ioctl and pass this nasty stuff to the kernel */
++ if (ccp_test(f->unit, opt_buf, (2*keysize)+3, 1) <= 0){
++ ho->mppe = 0;
++ newret = CONFREJ;
++ break;
++ }
++ }
++ break;
++#endif /* MPPE */
+ case CI_BSD_COMPRESS:
+ if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
+ newret = CONFREJ;
+@@ -996,6 +1204,28 @@
+ (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
+ opt->deflate_size);
+ break;
++#ifdef MPPE
++ case CI_MPPE:
++ if (opt->mppe_40) {
++ if (opt->mppe_stateless) {
++ return "MPPE 40 bit, stateless";
++ } else {
++ return "MPPE 40 bit, non-stateless";
++ }
++ } else if (opt->mppe_128) {
++ if (opt->mppe_stateless) {
++ return "MPPE 128 bit, stateless";
++ } else {
++ return "MPPE 128 bit, non-stateless";
++ }
++ } else {
++ if (opt->mppe_stateless) {
++ return "MPPE unknown strength, stateless";
++ } else {
++ return "MPPE unknown strength, stateless";
++ }
++ }
++#endif
+ case CI_BSD_COMPRESS:
+ if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
+ slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",
+@@ -1134,6 +1364,14 @@
+ p += CILEN_PREDICTOR_1;
+ }
+ break;
++#ifdef MPPE
++ case CI_MPPE:
++ if (optlen >= CILEN_MPPE) {
++ printer(arg, "mppe %x %x %x %x",p[2],p[3],p[4],p[5]);
++ p += CILEN_MPPE;
++ }
++ break;
++#endif
+ case CI_PREDICTOR_2:
+ if (optlen >= CILEN_PREDICTOR_2) {
+ printer(arg, "predictor 2");
+@@ -1193,6 +1431,11 @@
+ error("Lost compression sync: disabling compression");
+ ccp_close(unit, "Lost compression sync");
+ } else {
++#ifdef MPPE
++ /* MPPE/MPPC does not requires CCP_RESETREQ */
++ if (ccp_gotoptions[f->unit].method == CI_MPPE)
++ return;
++#endif
+ /*
+ * Send a reset-request to reset the peer's compressor.
+ * We don't do that if we are still waiting for an
diff --git a/net/ppp-mppe/patches/patch-be b/net/ppp-mppe/patches/patch-be
new file mode 100644
index 00000000000..3d71e047a50
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-be
@@ -0,0 +1,24 @@
+$NetBSD: patch-be,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/ccp.h Fri Nov 6 22:58:11 1998
++++ pppd/ccp.h Tue Jun 22 15:27:31 1999
+@@ -34,6 +34,10 @@
+ bool predictor_2; /* do Predictor-2? */
+ bool deflate_correct; /* use correct code for deflate? */
+ bool deflate_draft; /* use draft RFC code for deflate? */
++ bool mppe; /* do M$ encryption? */
++ bool mppe_40; /* allow 40 bit encryption */
++ bool mppe_128; /* allow 128 bit encryption */
++ bool mppe_stateless; /* allow stateless encryption */
+ u_short bsd_bits; /* # bits/code for BSD Compress */
+ u_short deflate_size; /* lg(window size) for Deflate */
+ short method; /* code for chosen compression method */
+@@ -46,3 +50,8 @@
+ extern ccp_options ccp_hisoptions[];
+
+ extern struct protent ccp_protent;
++
++#ifdef MPPE
++size_t mppe_generate_session_key(char *optbuf);
++#endif
++
diff --git a/net/ppp-mppe/patches/patch-bf b/net/ppp-mppe/patches/patch-bf
new file mode 100644
index 00000000000..118157d49f0
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bf
@@ -0,0 +1,206 @@
+$NetBSD: patch-bf,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/chap.c.orig Fri Aug 13 02:46:11 1999
++++ pppd/chap.c Sat Sep 25 13:23:26 1999
+@@ -47,6 +47,8 @@
+ #include "pppd.h"
+ #include "chap.h"
+ #include "md5.h"
++#include "fsm.h"
++#include "lcp.h"
+ #ifdef CHAPMS
+ #include "chap_ms.h"
+ #endif
+@@ -113,7 +115,7 @@
+ static void ChapSendStatus __P((chap_state *, int));
+ static void ChapSendChallenge __P((chap_state *));
+ static void ChapSendResponse __P((chap_state *));
+-static void ChapGenChallenge __P((chap_state *));
++void ChapGenChallenge __P((chap_state *));
+
+ extern double drand48 __P((void));
+ extern void srand48 __P((long));
+@@ -460,6 +462,7 @@
+ switch (cstate->resp_type) {
+
+ case CHAP_DIGEST_MD5:
++ CHAPDEBUG(("ChapReceiveChallenge: rcvd type CHAP-DIGEST-MD5"));
+ MD5Init(&mdContext);
+ MD5Update(&mdContext, &cstate->resp_id, 1);
+ MD5Update(&mdContext, secret, secret_len);
+@@ -471,8 +474,24 @@
+
+ #ifdef CHAPMS
+ case CHAP_MICROSOFT:
++ CHAPDEBUG(("ChapReceiveChallenge: rcvd type MS-CHAP-V1."));
++ if(rchallenge_len != 8)
++ {
++ CHAPDEBUG(("Invalid challenge length for MS-CHAP-V1"));
++ return;
++ }
+ ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
+ break;
++
++ case CHAP_MICROSOFT_V2:
++ CHAPDEBUG(("ChapReceiveChallenge: rcvd type MS-CHAP-V2."));
++ if(rchallenge_len != 16)
++ {
++ CHAPDEBUG(("Invalid challenge length for MS-CHAP-V2"));
++ return;
++ }
++ ChapMS_v2(cstate, rchallenge, rchallenge_len, secret, secret_len);
++ break;
+ #endif
+
+ default:
+@@ -560,7 +579,8 @@
+ /* generate MD based on negotiated type */
+ switch (cstate->chal_type) {
+
+- case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
++ case CHAP_DIGEST_MD5:
++ CHAPDEBUG(("ChapReceiveResponse: rcvd type CHAP-DIGEST-MD5"));
+ if (remmd_len != MD5_SIGNATURE_SIZE)
+ break; /* it's not even the right length */
+ MD5Init(&mdContext);
+@@ -574,6 +594,27 @@
+ code = CHAP_SUCCESS; /* they are the same! */
+ break;
+
++#ifdef CHAPMS
++ case CHAP_MICROSOFT:
++ CHAPDEBUG(("ChapReceiveResponse: rcvd type MS-CHAP-V1"));
++ if(remmd_len != MS_CHAP_RESPONSE_LEN)
++ break;
++ if(ChapMS_Resp(cstate, secret, secret_len, remmd) == 0)
++ code = CHAP_SUCCESS;
++ break;
++
++ case CHAP_MICROSOFT_V2:
++ CHAPDEBUG(("ChapReceiveResponse: rcvd type MS-CHAP-V2"));
++ if(remmd_len != MS_CHAP_RESPONSE_LEN)
++ break;
++ if(ChapMS_v2_Resp(cstate,secret,secret_len,remmd,rhostname) == 0)
++ {
++ code = CHAP_SUCCESS_R;
++ ChapMS_v2_Auth(cstate, secret, secret_len, remmd, rhostname);
++ }
++ break;
++#endif
++
+ default:
+ CHAPDEBUG(("unknown digest type %d", cstate->chal_type));
+ }
+@@ -582,7 +623,7 @@
+ BZERO(secret, sizeof(secret));
+ ChapSendStatus(cstate, code);
+
+- if (code == CHAP_SUCCESS) {
++ if ((code == CHAP_SUCCESS) || (code == CHAP_SUCCESS_R)) {
+ old_state = cstate->serverstate;
+ cstate->serverstate = CHAPSS_OPEN;
+ if (old_state == CHAPSS_INITIAL_CHAL) {
+@@ -590,10 +631,43 @@
+ }
+ if (cstate->chal_interval != 0)
+ TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
+- notice("CHAP peer authentication succeeded for %q", rhostname);
+-
++ switch (cstate->chal_type) {
++ case CHAP_DIGEST_MD5:
++ notice("CHAP peer authentication succeeded for %q", rhostname);
++ break;
++#ifdef CHAPMS
++ case CHAP_MICROSOFT:
++ notice("MSCHAP peer authentication succeeded for %q", rhostname);
++ break;
++ case CHAP_MICROSOFT_V2:
++ notice("MSCHAP-v2 peer authentication succeeded for %q", rhostname);
++ break;
++#endif
++ default:
++ notice("CHAP (unknown) peer authentication succeeded for %q",
++ rhostname);
++ break;
++ }
+ } else {
+- error("CHAP peer authentication failed for remote host %q", rhostname);
++ switch (cstate->chal_type) {
++ case CHAP_DIGEST_MD5:
++ error("CHAP peer authentication failed for remote host %q",
++ rhostname);
++ break;
++#ifdef CHAPMS
++ case CHAP_MICROSOFT:
++ error("MSCHAP peer authentication failed for remote host %q",
++ rhostname);
++ break;
++ case CHAP_MICROSOFT_V2:
++ error("MSCHAP-v2 peer authentication failed for remote host %q",
++ rhostname);
++ break;
++#endif
++ default:
++ error("CHAP (unknown) peer authentication failed for remote host %q", rhostname);
++ break;
++ }
+ cstate->serverstate = CHAPSS_BADAUTH;
+ auth_peer_fail(cstate->unit, PPP_CHAP);
+ }
+@@ -712,6 +786,8 @@
+
+ if (code == CHAP_SUCCESS)
+ slprintf(msg, sizeof(msg), "Welcome to %s.", hostname);
++ else if(code == CHAP_SUCCESS_R)
++ strcpy(msg, cstate->response);
+ else
+ slprintf(msg, sizeof(msg), "I don't like you. Go 'way.");
+ msglen = strlen(msg);
+@@ -721,7 +797,7 @@
+
+ MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
+
+- PUTCHAR(code, outp);
++ PUTCHAR(code == CHAP_SUCCESS_R ? CHAP_SUCCESS : code, outp);
+ PUTCHAR(cstate->chal_id, outp);
+ PUTSHORT(outlen, outp);
+ BCOPY(msg, outp, msglen);
+@@ -735,7 +811,7 @@
+ * *cstate are initialized.
+ */
+
+-static void
++void
+ ChapGenChallenge(cstate)
+ chap_state *cstate;
+ {
+@@ -743,6 +819,14 @@
+ u_char *ptr = cstate->challenge;
+ unsigned int i;
+
++#ifdef CHAPMS
++ if(cstate->chal_type == CHAP_MICROSOFT)
++ chal_len = 8;
++ else if(cstate->chal_type == CHAP_MICROSOFT_V2)
++ chal_len = 16;
++ else
++#endif
++
+ /* pick a random challenge length between MIN_CHALLENGE_LENGTH and
+ MAX_CHALLENGE_LENGTH */
+ chal_len = (unsigned) ((drand48() *
+@@ -857,4 +941,14 @@
+ }
+
+ return len + CHAP_HEADERLEN;
++}
++
++int
++reqchap(argv)
++ char **argv;
++{
++ lcp_wantoptions[0].neg_chap = 1;
++ lcp_wantoptions[0].use_digest = 1;
++ auth_required = 1;
++ return 1;
+ }
diff --git a/net/ppp-mppe/patches/patch-bg b/net/ppp-mppe/patches/patch-bg
new file mode 100644
index 00000000000..a4a1a4a38ec
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bg
@@ -0,0 +1,28 @@
+$NetBSD: patch-bg,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/chap.h Fri Nov 6 22:55:38 1998
++++ pppd/chap.h Thu Jun 24 13:06:30 1999
+@@ -46,11 +46,13 @@
+ #define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */
+ #define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */
+ #define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */
++#define CHAP_MICROSOFT_V2 0x81 /* use MS-CHAP v2 */
+
+ #define CHAP_CHALLENGE 1
+ #define CHAP_RESPONSE 2
+ #define CHAP_SUCCESS 3
+ #define CHAP_FAILURE 4
++#define CHAP_SUCCESS_R 13 /* Send response, not text message */
+
+ /*
+ * Challenge lengths (for challenges we send) and other limits.
+@@ -117,6 +119,9 @@
+
+ void ChapAuthWithPeer __P((int, char *, int));
+ void ChapAuthPeer __P((int, char *, int));
++void ChapGenChallenge __P((chap_state *));
++
++int reqchap(char **);
+
+ extern struct protent chap_protent;
+
diff --git a/net/ppp-mppe/patches/patch-bh b/net/ppp-mppe/patches/patch-bh
new file mode 100644
index 00000000000..7d3aafc4237
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bh
@@ -0,0 +1,470 @@
+$NetBSD$
+
+--- pppd/chap_ms.c Mon Mar 15 19:14:24 1999
++++ pppd/chap_ms.c Thu Jun 24 16:05:42 1999
+@@ -31,4 +31,12 @@
+ * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
+ */
++
++/*
++ * Mods by Tim Hockin, Cobalt Networks Inc. <thockin@cobaltnet.com> June 1999
++ *
++ * Cleanup, fixes and major reorganization.
++ * Migrated all MPPE code to mppe.c, shared crypto code to extra_crypto.c
++ *
++ */
+
+ #ifndef lint
+@@ -51,11 +59,13 @@
+ #include "pppd.h"
+ #include "chap.h"
+ #include "chap_ms.h"
+-#include "md4.h"
+-
+-#ifndef USE_CRYPT
+-#include <des.h>
++#include "sha.h"
++#include "fsm.h"
++#include "lcp.h"
++#ifdef MPPE
++#include "mppe.h"
+ #endif
++#include "extra_crypto.h"
+
+ typedef struct {
+ u_char LANManResp[24];
+@@ -65,21 +75,19 @@
+ /* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
+ in case this struct gets padded. */
+
++typedef struct {
++ u_char PeerChallenge[16];
++ u_char Reserved[8];
++ u_char NTResp[24];
++ u_char Flags;
++} MS_ChapResponse_v2;
+
+ static void ChallengeResponse __P((u_char *, u_char *, u_char *));
+-static void DesEncrypt __P((u_char *, u_char *, u_char *));
+-static void MakeKey __P((u_char *, u_char *));
+-static u_char Get7Bits __P((u_char *, int));
+ static void ChapMS_NT __P((char *, int, char *, int, MS_ChapResponse *));
+ #ifdef MSLANMAN
+ static void ChapMS_LANMan __P((char *, int, char *, int, MS_ChapResponse *));
+ #endif
+
+-#ifdef USE_CRYPT
+-static void Expand __P((u_char *, u_char *));
+-static void Collapse __P((u_char *, u_char *));
+-#endif
+-
+ #ifdef MSLANMAN
+ bool ms_lanman = 0; /* Use LanMan password instead of NT */
+ /* Has meaning only with MS-CHAP challenges */
+@@ -110,142 +118,6 @@
+ #endif
+ }
+
+-
+-#ifdef USE_CRYPT
+-static void
+-DesEncrypt(clear, key, cipher)
+- u_char *clear; /* IN 8 octets */
+- u_char *key; /* IN 7 octets */
+- u_char *cipher; /* OUT 8 octets */
+-{
+- u_char des_key[8];
+- u_char crypt_key[66];
+- u_char des_input[66];
+-
+- MakeKey(key, des_key);
+-
+- Expand(des_key, crypt_key);
+- setkey(crypt_key);
+-
+-#if 0
+- CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
+-#endif
+-
+- Expand(clear, des_input);
+- encrypt(des_input, 0);
+- Collapse(des_input, cipher);
+-
+-#if 0
+- CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
+-#endif
+-}
+-
+-#else /* USE_CRYPT */
+-
+-static void
+-DesEncrypt(clear, key, cipher)
+- u_char *clear; /* IN 8 octets */
+- u_char *key; /* IN 7 octets */
+- u_char *cipher; /* OUT 8 octets */
+-{
+- des_cblock des_key;
+- des_key_schedule key_schedule;
+-
+- MakeKey(key, des_key);
+-
+- des_set_key(&des_key, key_schedule);
+-
+-#if 0
+- CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
+-#endif
+-
+- des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
+-
+-#if 0
+- CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
+-#endif
+-}
+-
+-#endif /* USE_CRYPT */
+-
+-
+-static u_char Get7Bits(input, startBit)
+- u_char *input;
+- int startBit;
+-{
+- register unsigned int word;
+-
+- word = (unsigned)input[startBit / 8] << 8;
+- word |= (unsigned)input[startBit / 8 + 1];
+-
+- word >>= 15 - (startBit % 8 + 7);
+-
+- return word & 0xFE;
+-}
+-
+-#ifdef USE_CRYPT
+-
+-/* in == 8-byte string (expanded version of the 56-bit key)
+- * out == 64-byte string where each byte is either 1 or 0
+- * Note that the low-order "bit" is always ignored by by setkey()
+- */
+-static void Expand(in, out)
+- u_char *in;
+- u_char *out;
+-{
+- int j, c;
+- int i;
+-
+- for(i = 0; i < 64; in++){
+- c = *in;
+- for(j = 7; j >= 0; j--)
+- *out++ = (c >> j) & 01;
+- i += 8;
+- }
+-}
+-
+-/* The inverse of Expand
+- */
+-static void Collapse(in, out)
+- u_char *in;
+- u_char *out;
+-{
+- int j;
+- int i;
+- unsigned int c;
+-
+- for (i = 0; i < 64; i += 8, out++) {
+- c = 0;
+- for (j = 7; j >= 0; j--, in++)
+- c |= *in << j;
+- *out = c & 0xff;
+- }
+-}
+-#endif
+-
+-static void MakeKey(key, des_key)
+- u_char *key; /* IN 56 bit DES key missing parity bits */
+- u_char *des_key; /* OUT 64 bit DES key with parity bits added */
+-{
+- des_key[0] = Get7Bits(key, 0);
+- des_key[1] = Get7Bits(key, 7);
+- des_key[2] = Get7Bits(key, 14);
+- des_key[3] = Get7Bits(key, 21);
+- des_key[4] = Get7Bits(key, 28);
+- des_key[5] = Get7Bits(key, 35);
+- des_key[6] = Get7Bits(key, 42);
+- des_key[7] = Get7Bits(key, 49);
+-
+-#ifndef USE_CRYPT
+- des_set_odd_parity((des_cblock *)des_key);
+-#endif
+-
+-#if 0
+- CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %.7B", key));
+- CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %.8B", des_key));
+-#endif
+-}
+-
+ static void
+ ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, response)
+ char *rchallenge;
+@@ -254,34 +126,13 @@
+ int secret_len;
+ MS_ChapResponse *response;
+ {
+- int i;
+-#ifdef __NetBSD__
+- /* NetBSD uses the libc md4 routines which take bytes instead of bits */
+- int mdlen = secret_len * 2;
+-#else
+- int mdlen = secret_len * 2 * 8;
+-#endif
+- MD4_CTX md4Context;
+ u_char hash[MD4_SIGNATURE_SIZE];
+- u_char unicodePassword[MAX_NT_PASSWORD * 2];
+-
+- /* Initialize the Unicode version of the secret (== password). */
+- /* This implicitly supports 8-bit ISO8859/1 characters. */
+- BZERO(unicodePassword, sizeof(unicodePassword));
+- for (i = 0; i < secret_len; i++)
+- unicodePassword[i * 2] = (u_char)secret[i];
+-
+- MD4Init(&md4Context);
+- MD4Update(&md4Context, unicodePassword, mdlen);
+-
+- MD4Final(hash, &md4Context); /* Tell MD4 we're done */
+
++ NtPasswordHash(secret, secret_len, hash);
+ ChallengeResponse(rchallenge, hash, response->NTResp);
+ }
+
+ #ifdef MSLANMAN
+-static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
+-
+ static void
+ ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, response)
+ char *rchallenge;
+@@ -290,16 +141,9 @@
+ int secret_len;
+ MS_ChapResponse *response;
+ {
+- int i;
+- u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
+ u_char PasswordHash[MD4_SIGNATURE_SIZE];
+
+- /* LANMan password is case insensitive */
+- BZERO(UcasePassword, sizeof(UcasePassword));
+- for (i = 0; i < secret_len; i++)
+- UcasePassword[i] = (u_char)toupper(secret[i]);
+- DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
+- DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
++ LmPasswordHash(secret, secret_len, PasswordHash);
+ ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
+ }
+ #endif
+@@ -331,8 +175,209 @@
+ response.UseNT = 1;
+ #endif
+
++#ifdef MPPE
++ mppe_gen_master_key(secret, secret_len, rchallenge);
++#endif
+ BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
+ cstate->resp_length = MS_CHAP_RESPONSE_LEN;
++}
++
++int
++ChapMS_Resp(cstate, secret, secret_len, remmd)
++ chap_state *cstate;
++ char *secret;
++ int secret_len;
++ u_char *remmd;
++{
++ MS_ChapResponse local;
++ MS_ChapResponse *response = (MS_ChapResponse *)remmd;
++ int i;
++
++ BZERO(&local, sizeof(response));
++
++ if(response->UseNT)
++ {
++ ChapMS_NT(cstate->challenge,cstate->chal_len, secret, secret_len, &local);
++ i = memcmp(local.NTResp, response->NTResp, sizeof(local.NTResp));
++
++#ifdef MPPE
++ if(i == 0)
++ mppe_gen_master_key(secret, secret_len, cstate->challenge);
++#endif
++ return(i);
++ }
++
++#ifdef MSLANMAN
++ ChapMS_LANMan(cstate->challenge, cstate->chal_len, secret, secret_len,
++ &local);
++ if(memcmp(local.LANManResp, response->LANManResp,
++ sizeof(local.LANManResp)) == 0) {
++#ifdef MPPE
++ mppe_gen_master_key(secret, secret_len, cstate->challenge);
++#endif
++ return(0);
++ }
++#endif /* MSLANMAN */
++ return(1);
++}
++
++void
++ChallengeHash(PeerChallenge, AuthenticatorChallenge, UserName, Challenge)
++ char *PeerChallenge;
++ char *AuthenticatorChallenge;
++ char *UserName;
++ char *Challenge;
++{
++ SHA_CTX Context;
++ u_char Digest[SHA_DIGEST_LENGTH];
++ char *username;
++
++ if((username = strrchr(UserName, '\\')) != (char *)NULL)
++ ++username;
++ else
++ username = UserName;
++ SHA1_Init(&Context);
++ SHA1_Update(&Context, PeerChallenge, 16);
++ SHA1_Update(&Context, AuthenticatorChallenge, 16);
++ SHA1_Update(&Context, username, strlen(username));
++ SHA1_Final(Digest, &Context);
++ BCOPY(Digest, Challenge, 8);
++}
++
++void
++ChapMS_v2(cstate, AuthenticatorChallenge, AuthenticatorChallengeLen, Password, PasswordLen)
++ chap_state *cstate;
++ char *AuthenticatorChallenge;
++ int AuthenticatorChallengeLen;
++ char *Password;
++ int PasswordLen;
++{
++ u_char Challenge[8];
++ u_char PasswordHash[MD4_SIGNATURE_SIZE];
++ MS_ChapResponse_v2 response;
++
++ BZERO(&response, sizeof(response));
++ ChapGenChallenge(cstate);
++ BCOPY(cstate->challenge, response.PeerChallenge,
++ sizeof(response.PeerChallenge));
++ ChallengeHash(response.PeerChallenge, AuthenticatorChallenge,
++ cstate->resp_name, Challenge);
++ NtPasswordHash(Password, PasswordLen, PasswordHash);
++ ChallengeResponse(Challenge, PasswordHash, response.NTResp);
++ BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
++ cstate->resp_length = MS_CHAP_RESPONSE_LEN;
++#ifdef MPPE
++ mppe_gen_master_key_v2(Password, PasswordLen, response.NTResp, 0);
++#endif
++}
++
++int
++ChapMS_v2_Resp(cstate, Password, PasswordLen, remmd, UserName)
++ chap_state *cstate;
++ char *Password;
++ int PasswordLen;
++ u_char *remmd;
++ char *UserName;
++{
++ u_char Challenge[8];
++ u_char PasswordHash[MD4_SIGNATURE_SIZE];
++ MS_ChapResponse_v2 response, response1;
++ int i;
++
++ BCOPY(remmd, &response, MS_CHAP_RESPONSE_LEN);
++ ChallengeHash(response.PeerChallenge,cstate->challenge,UserName,Challenge);
++ NtPasswordHash(Password, PasswordLen, PasswordHash);
++ ChallengeResponse(Challenge, PasswordHash, response1.NTResp);
++ i = memcmp(response.NTResp, response1.NTResp, sizeof(response.NTResp));
++#ifdef MPPE
++ if(i == 0)
++ mppe_gen_master_key_v2(Password, PasswordLen, response1.NTResp, 1);
++#endif
++ return(i);
++}
++
++void
++ChapMS_v2_Auth(cstate, Password, PasswordLen, remmd, UserName)
++ chap_state *cstate;
++ char *Password;
++ int PasswordLen;
++ u_char *remmd;
++ char *UserName;
++{
++ u_char PasswordHash[MD4_SIGNATURE_SIZE];
++ u_char PasswordHashHash[MD4_SIGNATURE_SIZE];
++ u_char Challenge[8];
++ static char Magic1[] = "Magic server to client signing constant";
++ static char Magic2[] = "Pad to make it do more than one iteration";
++
++ SHA_CTX Context;
++ u_char Digest[SHA_DIGEST_LENGTH];
++ MS_ChapResponse_v2 *response = (MS_ChapResponse_v2 *)remmd;
++ char StrResponse[SHA_DIGEST_LENGTH * 2 + 3], *s;
++ int i;
++ static char HexDigs[] = "0123456789ABCDEF";
++
++ NtPasswordHash(Password, PasswordLen, PasswordHash);
++ md4(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
++
++ SHA1_Init(&Context);
++ SHA1_Update(&Context, PasswordHashHash, 16);
++ SHA1_Update(&Context, response->NTResp, 24);
++ SHA1_Update(&Context, Magic1, sizeof(Magic1) - 1);
++ SHA1_Final(Digest, &Context);
++
++ ChallengeHash(response->PeerChallenge,cstate->challenge,UserName,Challenge);
++
++ SHA1_Init(&Context);
++ SHA1_Update(&Context, Digest, SHA_DIGEST_LENGTH);
++ SHA1_Update(&Context, Challenge, 8);
++ SHA1_Update(&Context, Magic2, sizeof(Magic2) - 1);
++ SHA1_Final(Digest, &Context);
++ s = strcpy(StrResponse, "S=")+2;
++ for(i = 0; i < SHA_DIGEST_LENGTH; ++i) {
++ *s++ = HexDigs[Digest[i] >> 4];
++ *s++ = HexDigs[Digest[i] & 0x0F];
++ }
++ *s = '\0';
++ BCOPY(StrResponse, cstate->response, sizeof(StrResponse));
++ cstate->resp_length = sizeof(StrResponse) - 1;
++}
++
++/*
++ * functions called from config options
++ */
++int
++reqchapms(char **argv)
++{
++ lcp_wantoptions[0].neg_chap = 1;
++ lcp_wantoptions[0].use_chapms = 1;
++ auth_required = 1;
++
++ return 1;
++}
++
++int
++nochapms(char **argv)
++{
++ lcp_wantoptions[0].use_chapms = 0;
++ return 1;
++}
++
++int
++reqchapms_v2(char **argv)
++{
++ lcp_wantoptions[0].neg_chap = 1;
++ lcp_wantoptions[0].use_chapms_v2 = 1;
++ auth_required = 1;
++
++ return 1;
++}
++
++int
++nochapms_v2(char **argv)
++{
++ lcp_wantoptions[0].use_chapms_v2 = 0;
++ return 1;
+ }
+
+ #endif /* CHAPMS */
diff --git a/net/ppp-mppe/patches/patch-bi b/net/ppp-mppe/patches/patch-bi
new file mode 100644
index 00000000000..384e895d709
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bi
@@ -0,0 +1,24 @@
+$NetBSD: patch-bi,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/chap_ms.h Fri Nov 6 22:55:39 1998
++++ pppd/chap_ms.h Tue Jun 22 18:52:12 1999
+@@ -24,10 +24,16 @@
+
+ #ifndef __CHAPMS_INCLUDE__
+
+-#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */
+-#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */
+-
+ void ChapMS __P((chap_state *, char *, int, char *, int));
++int ChapMS_Resp __P((chap_state *, char *, int, u_char *));
++void ChapMS_v2 __P((chap_state *, char *, int, char *, int));
++int ChapMS_v2_Resp __P((chap_state *, char *, int, u_char *, char *));
++void ChapMS_v2_Auth __P((chap_state *, char *, int, u_char *, char *));
++
++int reqchapms(char **);
++int nochapms(char **);
++int reqchapms_v2(char **);
++int nochapms_v2(char **);
+
+ #define __CHAPMS_INCLUDE__
+ #endif /* __CHAPMS_INCLUDE__ */
diff --git a/net/ppp-mppe/patches/patch-bj b/net/ppp-mppe/patches/patch-bj
new file mode 100644
index 00000000000..396f05f99e7
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bj
@@ -0,0 +1,167 @@
+$NetBSD: patch-bj,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/extra_crypto.c Wed Dec 31 16:00:00 1969
++++ pppd/extra_crypto.c Thu Jun 24 16:05:42 1999
+@@ -0,0 +1,162 @@
++/*
++ * Copyright (c) Tim Hockin, Cobalt Networks Inc. and others
++ *
++ * crypto routines used by multiple c files
++ */
++#include <stdio.h>
++#include <ctype.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include "extra_crypto.h"
++#include "pppd.h"
++#include "md4.h"
++#ifndef USE_CRYPT
++#include <des.h>
++#endif
++
++/* quick wrapper for easy md4 */
++void
++md4(unsigned char *from, int from_len, unsigned char *to)
++{
++ MD4_CTX Context;
++
++#ifndef __NetBSD__
++ from_len <<= 3; /* bytes->bits */
++#endif
++
++ MD4Init(&Context);
++ MD4Update(&Context, from, from_len);
++ MD4Final(to, &Context);
++}
++
++
++/* Microsoft LANMAN Password hashing */
++static u_char *MSStdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
++
++void
++LmPasswordHash(char *password, int len, char *hash)
++{
++ int i;
++ u_char up_pass[MAX_NT_PASSWORD]; /* max is actually 14 */
++
++ /* LANMan password is case insensitive */
++ BZERO(up_pass, sizeof(up_pass));
++ for (i = 0; i < len; i++)
++ up_pass[i] = (u_char)toupper(up_pass[i]);
++ DesEncrypt(MSStdText, up_pass + 0, hash + 0);
++ DesEncrypt(MSStdText, up_pass + 7, hash + 8);
++}
++
++void
++NtPasswordHash(char *secret, int secret_len, unsigned char *hash)
++{
++ int i;
++ u_char unicodePassword[MAX_NT_PASSWORD * 2];
++
++ /* Initialize the Unicode version of the secret (== password). */
++ /* This implicitly supports 8-bit ISO8859/1 characters. */
++ BZERO(unicodePassword, sizeof(unicodePassword));
++ for (i = 0; i < secret_len; i++)
++ unicodePassword[i * 2] = (u_char)secret[i];
++
++ /* Unicode is 2 bytes per char */
++ md4(unicodePassword, secret_len * 2, hash);
++}
++
++
++static u_char Get7Bits(unsigned char *input, int startBit)
++{
++ register unsigned int word;
++
++ word = (unsigned)input[startBit / 8] << 8;
++ word |= (unsigned)input[startBit / 8 + 1];
++
++ word >>= 15 - (startBit % 8 + 7);
++
++ return word & 0xFE;
++}
++
++
++static void MakeKey(unsigned char *key, unsigned char *des_key)
++{
++ des_key[0] = Get7Bits(key, 0);
++ des_key[1] = Get7Bits(key, 7);
++ des_key[2] = Get7Bits(key, 14);
++ des_key[3] = Get7Bits(key, 21);
++ des_key[4] = Get7Bits(key, 28);
++ des_key[5] = Get7Bits(key, 35);
++ des_key[6] = Get7Bits(key, 42);
++ des_key[7] = Get7Bits(key, 49);
++
++#ifndef USE_CRYPT
++ des_set_odd_parity((des_cblock *)des_key);
++#endif
++}
++
++
++#ifdef USE_CRYPT
++/* in == 8-byte string (expanded version of the 56-bit key)
++ * out == 64-byte string where each byte is either 1 or 0
++ * Note that the low-order "bit" is always ignored by by setkey()
++ */
++static void Expand(unsigned char *in, unsigned char *out)
++{
++ int j, c;
++ int i;
++
++ for(i = 0; i < 64; in++){
++ c = *in;
++ for(j = 7; j >= 0; j--)
++ *out++ = (c >> j) & 01;
++ i += 8;
++ }
++}
++
++/* The inverse of Expand
++ */
++static void Collapse(unsigned char *in, unsigned char *out)
++{
++ int j;
++ int i;
++ unsigned int c;
++
++ for (i = 0; i < 64; i += 8, out++) {
++ c = 0;
++ for (j = 7; j >= 0; j--, in++)
++ c |= *in << j;
++ *out = c & 0xff;
++ }
++}
++void
++DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher)
++{
++ u_char des_key[8];
++ u_char crypt_key[66];
++ u_char des_input[66];
++
++ MakeKey(key, des_key);
++
++ Expand(des_key, crypt_key);
++ setkey(crypt_key);
++
++ Expand(clear, des_input);
++ encrypt(des_input, 0);
++ Collapse(des_input, cipher);
++}
++#else /* don't USE_CRYPT */
++void
++DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher)
++{
++ des_cblock des_key;
++ des_key_schedule key_schedule;
++
++ MakeKey(key, des_key);
++
++ des_set_key(&des_key, key_schedule);
++
++ des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
++}
++#endif /* USE_CRYPT */
++
++
diff --git a/net/ppp-mppe/patches/patch-bk b/net/ppp-mppe/patches/patch-bk
new file mode 100644
index 00000000000..83e95f02ded
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bk
@@ -0,0 +1,21 @@
+$NetBSD: patch-bk,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/extra_crypto.h Wed Dec 31 16:00:00 1969
++++ pppd/extra_crypto.h Tue Jun 22 13:52:28 1999
+@@ -0,0 +1,16 @@
++#ifndef __EXTRA_CRYPTO_INCLUDE__
++/*
++ * This is just a bunch of crypto routines that are needed by more than one
++ * piece of functionality, so they were broken out
++ */
++
++void md4 __P((unsigned char *, int, unsigned char *));
++void LmPasswordHash __P((char *, int, char *));
++void NtPasswordHash __P((char *, int, unsigned char *));
++void DesEncrypt __P((unsigned char *, unsigned char *, unsigned char *));
++
++#define MAX_NT_PASSWORD 256 /* Max len of a (Unicode) NT passwd */
++#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */
++
++#define __EXTRA_CRYPTO_INCLUDE__
++#endif /* __EXTRA_CRYPTO_INCLUDE__ */
diff --git a/net/ppp-mppe/patches/patch-bl b/net/ppp-mppe/patches/patch-bl
new file mode 100644
index 00000000000..2dcbc3db7f0
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bl
@@ -0,0 +1,43 @@
+$NetBSD: patch-bl,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/ipcp.c.orig Fri Aug 13 02:46:12 1999
++++ pppd/ipcp.c Sat Sep 25 13:48:29 1999
+@@ -121,6 +121,8 @@
+ "Don't use name for default IP adrs", 1 },
+ { "ms-dns", 1, setdnsaddr,
+ "DNS address for the peer's use" },
++ { "dns-addr", 1, setdnsaddr,
++ "DNS address for the peer's use" },
+ { "ms-wins", 1, setwinsaddr,
+ "Nameserver for SMB over TCP/IP for peer" },
+ { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
+@@ -1057,6 +1059,14 @@
+ */
+ GETLONG(tl, p); /* Parse source address (his) */
+ ciaddr1 = htonl(tl);
++#ifdef DYNAMIC
++ if(!auth_ip_addr(f->unit, ciaddr1))
++ if(get_ip_addr_dynamic(f->unit, &tl))
++ {
++ wo->hisaddr = tl;
++ ciaddr1 = 0;
++ }
++#endif
+ if (ciaddr1 != wo->hisaddr
+ && (ciaddr1 == 0 || !wo->accept_remote)) {
+ orc = CONFNAK;
+@@ -1114,6 +1124,14 @@
+ */
+ GETLONG(tl, p); /* Parse source address (his) */
+ ciaddr1 = htonl(tl);
++#ifdef DYNAMIC
++ if(!auth_ip_addr(f->unit, ciaddr1))
++ if(get_ip_addr_dynamic(f->unit, &tl))
++ {
++ wo->hisaddr = tl;
++ ciaddr1 = 0;
++ }
++#endif
+ if (ciaddr1 != wo->hisaddr
+ && (ciaddr1 == 0 || !wo->accept_remote)) {
+ orc = CONFNAK;
diff --git a/net/ppp-mppe/patches/patch-bm b/net/ppp-mppe/patches/patch-bm
new file mode 100644
index 00000000000..1ae4d8431d9
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bm
@@ -0,0 +1,207 @@
+$NetBSD: patch-bm,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/lcp.c.orig Wed May 12 17:33:32 1999
++++ pppd/lcp.c Thu Jun 24 16:05:42 1999
+@@ -35,6 +35,8 @@
+ #include "chap.h"
+ #include "magic.h"
+
++extern bool refuse_chap;
++
+ /*
+ * LCP-related command-line options.
+ */
+@@ -277,19 +279,47 @@
+ wo->asyncmap = 0;
+ wo->neg_chap = 0; /* Set to 1 on server */
+ wo->neg_upap = 0; /* Set to 1 on server */
+- wo->chap_mdtype = CHAP_DIGEST_MD5;
++ wo->use_digest = 1;
++#ifdef CHAPMS
++ if(wo->use_chapms_v2)
++ wo->chap_mdtype = CHAP_MICROSOFT_V2;
++ else if(wo->use_chapms)
++ wo->chap_mdtype = CHAP_MICROSOFT;
++ else
++#endif
++ if(wo->use_digest)
++ wo->chap_mdtype = CHAP_DIGEST_MD5;
++ else
++ refuse_chap = 1;
+ wo->neg_magicnumber = 1;
+ wo->neg_pcompression = 1;
+ wo->neg_accompression = 1;
+ wo->neg_lqr = 0; /* no LQR implementation yet */
++#ifdef CBCP_SUPPORT
++ wo->neg_cbcp = 1;
++#else
+ wo->neg_cbcp = 0;
++#endif
+
+ ao->neg_mru = 1;
+ ao->mru = MAXMRU;
+ ao->neg_asyncmap = 1;
+ ao->asyncmap = 0;
+ ao->neg_chap = 1;
+- ao->chap_mdtype = CHAP_DIGEST_MD5;
++ ao->use_digest = 1;
++#ifdef CHAPMS
++ ao->use_chapms_v2 = ao->use_chapms = 1;
++ if(ao->use_chapms_v2)
++ ao->chap_mdtype = CHAP_MICROSOFT_V2;
++ else if(ao->use_chapms)
++ ao->chap_mdtype = CHAP_MICROSOFT;
++ else
++#else
++ if(ao->use_digest)
++ ao->chap_mdtype = CHAP_DIGEST_MD5;
++ else
++ refuse_chap = 1;
++#endif
+ ao->neg_upap = 1;
+ ao->neg_magicnumber = 1;
+ ao->neg_pcompression = 1;
+@@ -557,6 +587,18 @@
+ * NB: we only ask for one of CHAP and UPAP, even if we will
+ * accept either.
+ */
++#ifdef CHAPMS
++ if(go->use_chapms_v2)
++ go->chap_mdtype = CHAP_MICROSOFT_V2;
++ else if(go->use_chapms)
++ go->chap_mdtype = CHAP_MICROSOFT;
++ else
++#endif
++ if(go->use_digest)
++ go->chap_mdtype = CHAP_DIGEST_MD5;
++ else
++ go->neg_chap = 0;
++
+ return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
+ LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
+ LENCICHAP(go->neg_chap) +
+@@ -922,7 +964,34 @@
+ * algorithm. If they can't do MD5, we'll have to stop
+ * asking for CHAP.
+ */
+- if (cichar != go->chap_mdtype)
++ if (go->chap_mdtype == CHAP_MICROSOFT_V2)
++ {
++ try.use_chapms_v2 = 0;
++ if(try.use_chapms)
++ try.chap_mdtype = CHAP_MICROSOFT;
++ else if(try.use_digest)
++ try.chap_mdtype = CHAP_DIGEST_MD5;
++ else
++ try.neg_chap = 0;
++ }
++ else if(go->chap_mdtype == CHAP_MICROSOFT)
++ {
++ try.use_chapms = 0;
++ if(try.use_digest)
++ try.chap_mdtype = CHAP_DIGEST_MD5;
++ else
++ try.neg_chap = 0;
++ }
++ else if(go->chap_mdtype == CHAP_DIGEST_MD5)
++ {
++ try.use_digest = 0;
++ try.neg_chap = 0;
++ }
++ else
++ try.neg_chap = 0;
++ if ((cichar != CHAP_MICROSOFT_V2) &&
++ (cichar != CHAP_MICROSOFT) &&
++ (cichar != CHAP_DIGEST_MD5))
+ try.neg_chap = 0;
+ } else {
+ /*
+@@ -1133,8 +1202,22 @@
+ /* Check rejected value. */ \
+ if (cishort != val || cichar != digest) \
+ goto bad; \
+- try.neg = 0; \
+- try.neg_upap = 0; \
++ switch(digest) \
++ { \
++ case CHAP_MICROSOFT_V2: \
++ try.use_chapms_v2 = 0; \
++ break; \
++ case CHAP_MICROSOFT: \
++ try.use_chapms = 0; \
++ break; \
++ case CHAP_DIGEST_MD5: \
++ try.use_digest = 0; \
++ } \
++ if(!try.use_chapms_v2 && !try.use_chapms && !try.use_digest) \
++ { \
++ try.neg = 0; \
++ try.neg_upap = 0; \
++ } \
+ }
+ #define REJCILONG(opt, neg, val) \
+ if (go->neg && \
+@@ -1370,9 +1453,10 @@
+ if (cichar != CHAP_DIGEST_MD5
+ #ifdef CHAPMS
+ && cichar != CHAP_MICROSOFT
++ && cichar != CHAP_MICROSOFT_V2
+ #endif
+ ) {
+- orc = CONFNAK;
++ orc = CONFREJ; /* !!! CONFNAK !!! */
+ PUTCHAR(CI_AUTHTYPE, nakp);
+ PUTCHAR(CILEN_CHAP, nakp);
+ PUTSHORT(PPP_CHAP, nakp);
+@@ -1449,6 +1533,23 @@
+ ho->magicnumber = cilong;
+ break;
+
++#ifdef CBCP_SUPPORT
++ case CI_CALLBACK:
++ LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd CBCP"));
++ if (!ao->neg_cbcp ||
++ cilen != CILEN_CHAR) {
++ orc = CONFREJ;
++ break;
++ }
++ GETCHAR(cichar, p);
++ if(cichar != CBCP_OPT)
++ {
++ orc = CONFREJ;
++ break;
++ }
++ ho->neg_cbcp = 1;
++ break;
++#endif
+
+ case CI_PCOMPRESSION:
+ if (!ao->neg_pcompression ||
+@@ -1721,20 +1822,23 @@
+ }
+ }
+ break;
++#ifdef CBCP_SUPPORT
+ case CI_CALLBACK:
+- if (olen >= CILEN_CHAR) {
++ if (olen == CILEN_CHAR) {
++ u_char cichar;
+ p += 2;
+ printer(arg, "callback ");
+- GETCHAR(cishort, p);
+- switch (cishort) {
++ GETCHAR(cichar, p);
++ switch (cichar) {
+ case CBCP_OPT:
+ printer(arg, "CBCP");
+ break;
+ default:
+- printer(arg, "0x%x", cishort);
++ printer(arg, "0x%x", cichar);
+ }
+ }
+ break;
++#endif
+ case CI_MAGICNUMBER:
+ if (olen == CILEN_LONG) {
+ p += 2;
diff --git a/net/ppp-mppe/patches/patch-bn b/net/ppp-mppe/patches/patch-bn
new file mode 100644
index 00000000000..a1370678d55
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bn
@@ -0,0 +1,14 @@
+$NetBSD: patch-bn,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/lcp.h Fri Nov 6 22:58:13 1998
++++ pppd/lcp.h Tue Jun 22 17:13:59 1999
+@@ -56,6 +56,9 @@
+ bool neg_accompression; /* HDLC Address/Control Field Compression? */
+ bool neg_lqr; /* Negotiate use of Link Quality Reports */
+ bool neg_cbcp; /* Negotiate use of CBCP */
++ bool use_digest;
++ bool use_chapms;
++ bool use_chapms_v2;
+ int mru; /* Value of MRU */
+ u_char chap_mdtype; /* which MD type (hashing algorithm) */
+ u_int32_t asyncmap; /* Value of async map */
diff --git a/net/ppp-mppe/patches/patch-bo b/net/ppp-mppe/patches/patch-bo
new file mode 100644
index 00000000000..cf35ec16a16
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bo
@@ -0,0 +1,234 @@
+$NetBSD: patch-bo,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Wed Dec 31 16:00:00 1969
++++ pppd/mppe.c Thu Jun 24 16:05:42 1999
+@@ -0,0 +1,229 @@
++/*
++ * mppe - Mucking with PpP Encription
++ *
++ * Copyright (c) 1995 Árpád Magossányi
++ * All rights reserved.
++ *
++ * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc.
++ *
++ * Redistribution and use in source and binary forms are permitted
++ * provided that the above copyright notice and this paragraph are
++ * duplicated in all such forms and that any documentation,
++ * advertising materials, and other materials related to such
++ * distribution and use acknowledge that the software was developed
++ * by Pedro Roque Marques. The name of the author may not be used to
++ * endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ */
++
++#ifdef MPPE
++
++#include <stdio.h>
++#include <sys/types.h>
++#include <string.h>
++#include <ctype.h>
++#include <syslog.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include "pppd.h"
++#include "chap.h"
++#include "fsm.h"
++#include "ccp.h"
++#include "md4.h"
++#include "sha.h"
++#include "chap_ms.h"
++#include "extra_crypto.h"
++
++static void
++mppe_get_start_key __P((unsigned char *, unsigned char *, unsigned char *));
++static void
++mppe_get_master_key __P((unsigned char *, unsigned char *, unsigned char *));
++static void
++GetAsymetricStartKey __P((unsigned char *, unsigned char *, int, int, int));
++
++unsigned char mppe_master_send_key_40[8];
++unsigned char mppe_master_recv_key_40[8];
++unsigned char mppe_master_send_key_128[16];
++unsigned char mppe_master_recv_key_128[16];
++unsigned int mppe_allowed = 0;
++
++/*
++ * Pads used in key derivation - from sha1dgst.c
++ */
++static unsigned char SHApad1[40] =
++ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
++static unsigned char SHApad2[40] =
++ {0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
++ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
++ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
++ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2};
++
++
++/* This is used with chap-ms (v1) */
++void
++mppe_gen_master_key(char *secret, int secret_len, unsigned char *challenge)
++{
++ unsigned char PasswordHash[MD4_SIGNATURE_SIZE];
++ unsigned char PasswordHashHash[MD4_SIGNATURE_SIZE];
++
++ /* 40 bit */
++ LmPasswordHash(secret, secret_len, PasswordHash);
++ BCOPY(PasswordHash, mppe_master_send_key_40, 8);
++ BCOPY(mppe_master_send_key_40, mppe_master_recv_key_40, 8);
++
++ /* 128 bit */
++ NtPasswordHash(secret, secret_len, PasswordHash);
++ md4(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
++ mppe_get_start_key(challenge, PasswordHashHash, mppe_master_send_key_128);
++ BCOPY(mppe_master_send_key_128, mppe_master_recv_key_128, 16);
++
++ mppe_allowed = 1;
++}
++
++
++/* This is used with chap-ms-v2 (per MS' draft RFC) - 2 different keys */
++void
++mppe_gen_master_key_v2(char *secret, int secret_len, unsigned char *response,
++ int is_server)
++{
++ unsigned char PasswordHash[MD4_SIGNATURE_SIZE];
++ unsigned char PasswordHashHash[MD4_SIGNATURE_SIZE];
++ unsigned char MasterKey[MD4_SIGNATURE_SIZE];
++
++ /* 128 bit - 2 keys */
++ NtPasswordHash(secret, secret_len, PasswordHash);
++ md4(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
++ mppe_get_master_key(PasswordHashHash, response, MasterKey);
++ GetAsymetricStartKey(MasterKey, mppe_master_send_key_128, 16,1, is_server);
++ GetAsymetricStartKey(MasterKey, mppe_master_recv_key_128, 16,0, is_server);
++
++ /* 40 bit - 2 keys */
++ BCOPY(mppe_master_send_key_128, mppe_master_send_key_40, 8);
++ BCOPY(mppe_master_recv_key_128, mppe_master_recv_key_40, 8);
++
++ mppe_allowed = 1;
++}
++
++
++static void
++mppe_get_start_key(unsigned char *Challenge, unsigned char *NtPasswordHashHash,
++ unsigned char *InitialSessionKey)
++{
++ unsigned char Digest[SHA_DIGEST_LENGTH];
++ SHA_CTX Context;
++
++ SHA1_Init(&Context);
++ SHA1_Update(&Context, NtPasswordHashHash, 16);
++ SHA1_Update(&Context, Challenge, 24);
++ SHA1_Final(Digest, &Context);
++ BCOPY(Digest, InitialSessionKey, 16);
++}
++
++static void
++mppe_get_master_key(unsigned char *PasswordHashHash, unsigned char *NtResponse,
++ unsigned char *MasterKey)
++{
++ unsigned char Digest[SHA_DIGEST_LENGTH];
++ SHA_CTX Context;
++ static char Magic1[] = "This is the MPPE Master Key";
++
++ BZERO(Digest, sizeof(Digest));
++
++ SHA1_Init(&Context);
++ SHA1_Update(&Context, PasswordHashHash, 16);
++ SHA1_Update(&Context, NtResponse, 24);
++ SHA1_Update(&Context, Magic1, sizeof(Magic1) - 1);
++ SHA1_Final(Digest, &Context);
++
++ BCOPY(Digest, MasterKey, 16);
++}
++
++static void
++GetAsymetricStartKey(unsigned char *MasterKey, unsigned char *SessionKey,
++ int SessionKeyLength, int IsSend, int IsServer)
++{
++ unsigned char Digest[SHA_DIGEST_LENGTH];
++ SHA_CTX Context;
++ char *s;
++ static char Magic2[] = "On the client side, this is the send key; on the server side, it is the receive key.";
++ static char Magic3[] = "On the client side, this is the receive key; on the server side, it is the send key.";
++
++ BZERO(Digest, sizeof(Digest));
++ if(IsSend)
++ {
++ if(IsServer)
++ s = Magic3;
++ else
++ s = Magic2;
++ }
++ else
++ {
++ if(IsServer)
++ s = Magic2;
++ else
++ s = Magic3;
++ }
++
++ SHA1_Init(&Context);
++ SHA1_Update(&Context, MasterKey, 16);
++ SHA1_Update(&Context, SHApad1, 40);
++ SHA1_Update(&Context, s, 84);
++ SHA1_Update(&Context, SHApad2, 40);
++ SHA1_Final(Digest, &Context);
++ BCOPY(Digest, SessionKey, SessionKeyLength);
++}
++
++/*
++ * Functions called from config options
++ */
++int
++setmppe_40(char **argv)
++{
++ ccp_allowoptions[0].mppe = ccp_wantoptions[0].mppe = 1;
++ ccp_allowoptions[0].mppe_40 = ccp_wantoptions[0].mppe_40 = 1;
++ return 1;
++}
++
++int
++setnomppe_40(char **argv)
++{
++ ccp_allowoptions[0].mppe_40 = ccp_wantoptions[0].mppe_40 = 0;
++ return 1;
++}
++
++int
++setmppe_128(char **argv)
++{
++ ccp_allowoptions[0].mppe = ccp_wantoptions[0].mppe = 1;
++ ccp_allowoptions[0].mppe_128 = ccp_wantoptions[0].mppe_128 = 1;
++ return 1;
++}
++
++int
++setnomppe_128(char **argv)
++{
++ ccp_allowoptions[0].mppe_128 = ccp_wantoptions[0].mppe_128 = 0;
++ return 1;
++}
++
++int
++setmppe_stateless(char **argv)
++{
++ ccp_allowoptions[0].mppe_stateless = ccp_wantoptions[0].mppe_stateless = 1;
++ return 1;
++}
++
++int
++setnomppe_stateless(char **argv)
++{
++ ccp_allowoptions[0].mppe_stateless = ccp_wantoptions[0].mppe_stateless = 0;
++ return 1;
++}
++#endif /* MPPE */
diff --git a/net/ppp-mppe/patches/patch-bp b/net/ppp-mppe/patches/patch-bp
new file mode 100644
index 00000000000..3c3cfb5e255
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bp
@@ -0,0 +1,68 @@
+$NetBSD: patch-bp,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Wed Dec 31 16:00:00 1969
++++ pppd/mppe.h Tue Jun 22 18:44:01 1999
+@@ -0,0 +1,63 @@
++#ifndef __MPPE_INCLUDE__
++
++#ifndef CI_MPPE
++#define CI_MPPE 18 /* config. option for MPPE */
++#endif CI_MPPE
++#ifndef CILEN_MPPE
++#define CILEN_MPPE 6 /* length of config. option */
++#endif CILEN_MPPE
++
++typedef struct mppe_state {
++ int us_unit; /* Interface unit number */
++ u_char us_id; /* Current id */
++ u_char us_allowed;
++ int us_type;
++ char *us_number; /* Telefone Number */
++} mppe_state;
++
++
++extern struct protent mppe_protent;
++
++#define MPPE_CONFOPTION CI_MPPE /* p[0] */
++#define MPPE_STATELESS 0x01 /* p[2] */
++#define MPPE_40BIT 0x20 /* p[5] */
++#define MPPE_128BIT 0x40 /* p[5] */
++
++#define PPP_MPPE 0x00FD
++
++#define MPPE_BIT_A 0x80
++#define MPPE_BIT_B 0x40
++#define MPPE_BIT_C 0x20
++#define MPPE_BIT_D 0x10
++#define MPPE_BIT_FLUSHED MPPE_BIT_A
++#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
++#define MPPE_CCOUNT 0x0FFF
++
++#define MPPE_40_SALT0 0xD1
++#define MPPE_40_SALT1 0x26
++#define MPPE_40_SALT2 0x9E
++
++#define MPPE_MINLEN 4
++
++#define MPPE_REQ 1
++#define MPPE_RESP 2
++#define MPPE_ACK 3
++
++extern char mppe_master_send_key_40[8];
++extern char mppe_master_send_key_128[16];
++extern char mppe_master_recv_key_40[8];
++extern char mppe_master_recv_key_128[16];
++extern unsigned int mppe_allowed;
++
++void mppe_gen_master_key __P((char *, int, unsigned char *));
++void mppe_gen_master_key_v2 __P((char *, int, unsigned char *, int));
++
++int setmppe_40(char **);
++int setnomppe_40(char **);
++int setmppe_128(char **);
++int setnomppe_128(char **);
++int setmppe_stateless(char **);
++int setnomppe_stateless(char **);
++
++#define __MPPE_INCLUDE__
++#endif /* __MPPE_INCLUDE__ */
diff --git a/net/ppp-mppe/patches/patch-bq b/net/ppp-mppe/patches/patch-bq
new file mode 100644
index 00000000000..3a7cdd1aa4d
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bq
@@ -0,0 +1,160 @@
+$NetBSD: patch-bq,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/pppd.8.orig Sat Sep 25 13:47:24 1999
++++ pppd/pppd.8 Sat Sep 25 13:57:21 1999
+@@ -27,9 +27,14 @@
+ and configuring different network-layer protocols.
+ .LP
+ The encapsulation scheme is provided by driver code in the kernel.
+-Pppd provides the basic LCP, authentication support, and an NCP for
++PPPD provides the basic LCP, authentication support, and an NCP for
+ establishing and configuring the Internet Protocol (IP) (called the IP
+ Control Protocol, IPCP).
++.LP
++This version includes support for multilink operations, Microsoft
++specific CHAP authentication algorithms (known as CHAP-MS-V1 and
++CHAP-MS-V2) and transparent encryption (Microsoft Point-to-Point
++Encryption, MPPE) also.
+ .SH FREQUENTLY USED OPTIONS
+ .TP
+ .I <tty_name>
+@@ -90,6 +95,15 @@
+ or include .. as a pathname component. The format of the options file
+ is described below.
+ .TP
++.B callback \fIphone
++Request client to call back to specified \fIphone\fR number.
++.TP
++.B nocallback
++Don't argee to use callback negotiation.
++.TP
++.B +callback
++Request server to negotiate callback and log negotiated results.
++.TP
+ .B connect \fIscript
+ Use the executable or shell command specified by \fIscript\fR to set
+ up the serial line. This script would typically use the chat(8)
+@@ -309,6 +323,10 @@
+ options are given, data packets which are rejected by the specified
+ activity filter also count as the link being idle.
+ .TP
++.B ip
++Enable IPCP and IP protocols. You can disable IP negotiation if you
++want to use other protocols only.
++.TP
+ .B ipcp-accept-local
+ With this option, pppd will accept the peer's idea of our local IP
+ address, even if the local IP address was specified in an option.
+@@ -493,7 +511,7 @@
+ the connect script. On Ultrix, this option implies hardware flow
+ control, as for the \fIcrtscts\fR option.
+ .TP
+-.B ms-dns \fI<addr>
++.B ms-dns \fI<addr>\fR
+ If pppd is acting as a server for Microsoft Windows clients, this
+ option allows pppd to supply one or two DNS (Domain Name Server)
+ addresses to the clients. The first instance of this option specifies
+@@ -723,7 +741,11 @@
+ .TP
+ .B refuse-chap
+ With this option, pppd will not agree to authenticate itself to the
+-peer using CHAP.
++peer using any CHAP protocol.
++.TP
++.B refuse-chap-md5
++With this option, pppd will not agree to authenticate itself to the
++peer using standard MD5 CHAP.
+ .TP
+ .B refuse-pap
+ With this option, pppd will not agree to authenticate itself to the
+@@ -783,6 +805,48 @@
+ .B xonxoff
+ Use software flow control (i.e. XON/XOFF) to control the flow of data on
+ the serial port.
++.SH MICROSOFT SPECIFIC EXTENSIONS
++This version of PPPD supports some Microsoft-specific extensions such
++as non-standard CHAP algorithms (known as CHAP-MS-V1 and CHAP-MS-V2) and
++transparent encryption of all sending and receiving traffic.
++.LP
++Those options allows to configure PPPD to work with Microsoft extensions of
++standard PPP protocol.
++.TP
++.B require-chapms
++Require the peer to authenticate itself using CHAP [Challenge
++Handshake Authentication Protocol] authentication with Microsoft
++extensions [known as CHAP-MS-V1].
++.TP
++.B require-chapms-v2
++Require the peer to authenticate itself using CHAP authentication
++with Microsoft extensions [known as CHAP-MS-V2].
++.TP
++.B refuse-chapms
++With this option, pppd will not agree to authenticate itself to the
++peer using CHAP-MS-V1.
++.TP
++.B refuse-chapms-v2
++With this option, pppd will not agree to authenticate itself to the
++peer using CHAP-MS-V2.
++.TP
++.B mppe-40
++This option enables use of Microsoft Point-to-point Encryption (MPPE)
++using 40-bit encryption keys. These keys can be used with any Microsoft
++software (Windows 95, Windows 98, Windows NT) because their cryptographic
++strength is relatively low. This option requires that chapms or chapms-v2
++be enabled.
++.TP
++.B mppe-128
++This option enables use of Microsoft Point-to-Point Encryption (MPPE)
++using 128-bit encryption keys. These keys can be used with software designed
++for domestic usage (within US and Canada). This option requires that chapms
++or chapms-v2 be enabled.
++.TP
++.B mppe-stateless
++This option negotiates stateless mode for Microsoft Point-to-Point Encryption
++(MPPE), which changes the encryption keys on every packet. The default mode is
++stateful (non-stateless, or single key).
+ .SH OPTIONS FILES
+ Options can be taken from files as well as the command line. Pppd
+ reads options from the files /etc/ppp/options, ~/.ppprc and
+@@ -1093,9 +1157,40 @@
+ rlogin implementations are not transparent; they will remove the
+ sequence [0xff, 0xff, 0x73, 0x73, followed by any 8 bytes] from the
+ stream.
++.SH EXAMPLES OF MICROSOFT EXTENSIONS
++To enable full-featured Microsoft encryption you must add those options
++to your \fI/etc/ppp/options/fR file:
++.IP
+++chapms
++.br
+++chapms-v2
++.br
++mppe-40
++.br
++mppe-128
++.br
++mppe-stateless
++.LP
++To authentificate client with Microsoft CHAP version 1 or 2, you need to
++use those options:
++.IP
++auth
++.br
+++chap
++.br
+++chapms
++.br
+++chapms-v2
++.LP
++To make possible to authentificate itself with Microsoft CHAP version 1
++or 2, you need to add those options:
++.IP
+++chapms
++.br
+++chapms-v2
+ .SH DIAGNOSTICS
+ .LP
+-Messages are sent to the syslog daemon using facility LOG_DAEMON.
++.Messages are sent to the syslog daemon using facility LOG_DAEMON.
+ (This can be overriden by recompiling pppd with the macro
+ LOG_PPP defined as the desired facility.) In order to see the error
+ and debug messages, you will need to edit your /etc/syslog.conf file
diff --git a/net/ppp-mppe/patches/patch-br b/net/ppp-mppe/patches/patch-br
new file mode 100644
index 00000000000..fb0955dafef
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-br
@@ -0,0 +1,13 @@
+$NetBSD: patch-br,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/pppd.h.orig Thu May 13 18:09:08 1999
++++ pppd/pppd.h Thu Jun 24 13:41:46 1999
+@@ -320,6 +320,8 @@
+ /* check if IP address is authorized */
+ int bad_ip_adrs __P((u_int32_t));
+ /* check if IP address is unreasonable */
++int get_ip_addr_dynamic __P((int, u_int32_t *));
++ /* get dynamically-allocated IP address */
+
+ /* Procedures exported from demand.c */
+ void demand_conf __P((void)); /* config interface(s) for demand-dial */
diff --git a/net/ppp-mppe/patches/patch-bs b/net/ppp-mppe/patches/patch-bs
new file mode 100644
index 00000000000..51313685603
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bs
@@ -0,0 +1,21 @@
+$NetBSD: patch-bs,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/Makefile.netbsd-1.4.orig2 Sat Sep 25 15:23:52 1999
++++ pppd/Makefile.netbsd-1.4 Sat Sep 25 15:26:56 1999
+@@ -5,7 +5,7 @@
+ PROG= pppd
+ SRCS= auth.c cbcp.c ccp.c chap.c chap_ms.c demand.c eui64.c fsm.c \
+ ipcp.c ipv6cp.c ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c \
+- upap.c utils.c
++ upap.c utils.c mppe.c sha1dgst.c extra_crypto.c
+
+ .PATH: ${PCAPDIR}
+ MAN= pppd.8
+@@ -17,6 +17,7 @@
+ CPPFLAGS+= -I. -DHAVE_PATHS_H
+ CPPFLAGS+= -I${PCAPDIR} -DPPP_FILTER
+ CPPFLAGS+= -DCBCP_SUPPORT -DCHAPMS -DUSE_CRYPT -DMSLANMAN
++CPPFLAGS+= -DMPPE
+ # XXX: Does not work (yet)
+ #CPPFLAGS+= -DINET6
+
diff --git a/net/ppp-mppe/patches/patch-bt b/net/ppp-mppe/patches/patch-bt
new file mode 100644
index 00000000000..769932e3abe
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bt
@@ -0,0 +1,790 @@
+$NetBSD: patch-bt,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Mon Sep 27 01:09:07 1999
++++ netbsd-1.4/ppp_mppe.c Mon Sep 27 02:11:53 1999
+@@ -0,0 +1,785 @@
++/* NetBSD
++ *
++ * taken from: FILEVERSION 9906180
++ *
++ * ppp_mppe.c - MPPE "compressor/decompressor" module.
++ *
++ * Copyright (c) 1994 Árpád Magosányi <mag@bunuel.tii.matav.hu>
++ * All rights reserved.
++ * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc. <thockin@cobaltnet.com>
++ * Copyright (c) 1999 Darrin B. Jewell <dbj@netbsd.org>
++ *
++ * 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.
++ *
++ * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
++ */
++
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/systm.h>
++#include <sys/mbuf.h>
++#include <sys/malloc.h>
++
++#include <net/ppp_defs.h>
++
++#define PACKETPTR struct mbuf *
++#include <net/ppp-comp.h>
++
++#include "rc4.h"
++#include "rc4_enc.c"
++#include "sha1dgst.c"
++#include "mppe.h"
++
++extern void
++GetNewKeyFromSHA(unsigned char *StartKey,
++ unsigned char *SessionKey,
++ unsigned long SessionKeyLength,
++ unsigned char *InterimKey);
++
++#if defined(LKM) || defined(_LKM)
++int mppe_in_use = 0;
++#define MOD_DEC_USE_COUNT (mppe_in_use--)
++#define MOD_INC_USE_COUNT (mppe_in_use++)
++#else
++#define MOD_DEC_USE_COUNT while (0)
++#define MOD_INC_USE_COUNT while (0)
++#endif
++
++#ifndef CI_MPPE
++#define CI_MPPE 18 /* config. option for MPPE */
++#define CILEN_MPPE 6 /* length of config. option */
++#endif
++
++#ifdef MPPE_DEBUG
++#define DPRINTF(x) printf x
++#else
++#define DPRINTF(x)
++#endif
++
++/*
++ * State for a mppe "(de)compressor".
++ */
++struct ppp_mppe_state {
++ unsigned int ccount; /*coherency count */
++ RC4_KEY RC4_send_key; /* chap-ms-v2 dictates 2 keys */
++ RC4_KEY RC4_recv_key;
++ unsigned char session_send_key[16];
++ unsigned char session_recv_key[16];
++ unsigned char master_send_key[16];
++ unsigned char master_recv_key[16];
++ int keylen;
++ int stateless;
++ int decomp_error;
++ unsigned int bits;
++ int unit;
++ int debug;
++ int mru;
++ struct compstat stats;
++};
++
++#define MPPE_CCOUNT_FROM_PACKET(ibuf) ((((ibuf)[4] & 0x0f) << 8) + (ibuf)[5])
++#define MPPE_BITS(ibuf) ((ibuf)[4] & 0xf0 )
++#define MPPE_CTRLHI(state) ((((state)->ccount & 0xf00)>>8)|((state)->bits))
++#define MPPE_CTRLLO(state) ((state)->ccount & 0xff)
++
++#define MPPE_OVHD 4
++
++void mppe_synchronize_key(struct ppp_mppe_state *);
++void mppe_initialize_key(struct ppp_mppe_state *);
++void mppe_change_key(struct ppp_mppe_state *);
++void mppe_update_count(struct ppp_mppe_state *);
++
++/* Procedures from the MPPE draft */
++void
++mppe_synchronize_key(struct ppp_mppe_state *state)
++{
++ /* get new keys and flag our state as such */
++ RC4_set_key(&(state->RC4_send_key),state->keylen,state->session_send_key);
++ RC4_set_key(&(state->RC4_recv_key),state->keylen,state->session_recv_key);
++
++ state->bits=MPPE_BIT_FLUSHED|MPPE_BIT_ENCRYPTED;
++}
++
++
++void
++mppe_initialize_key(struct ppp_mppe_state *state)
++{
++ /* generate new session keys */
++ GetNewKeyFromSHA(state->master_send_key, state->master_send_key,
++ state->keylen, state->session_send_key);
++ GetNewKeyFromSHA(state->master_recv_key, state->master_recv_key,
++ state->keylen, state->session_recv_key);
++
++ if(state->keylen == 8) {
++ /* cripple them from 64bit->40bit */
++ state->session_send_key[0]=state->session_recv_key[0] = MPPE_40_SALT0;
++ state->session_send_key[1]=state->session_recv_key[1] = MPPE_40_SALT1;
++ state->session_send_key[2]=state->session_recv_key[2] = MPPE_40_SALT2;
++ }
++
++ mppe_synchronize_key(state);
++}
++
++
++void
++mppe_change_key(struct ppp_mppe_state *state)
++{
++ unsigned char InterimSendKey[16];
++ unsigned char InterimRecvKey[16];
++
++ /* get temp keys */
++ GetNewKeyFromSHA(state->master_send_key, state->session_send_key,
++ state->keylen, InterimSendKey);
++ GetNewKeyFromSHA(state->master_recv_key, state->session_recv_key,
++ state->keylen, InterimRecvKey);
++
++ /* build RC4 keys from the temp keys */
++ RC4_set_key(&(state->RC4_send_key), state->keylen, InterimSendKey);
++ RC4_set_key(&(state->RC4_recv_key), state->keylen, InterimRecvKey);
++
++ /* make new session keys */
++ RC4(&(state->RC4_send_key), state->keylen, InterimSendKey,
++ state->session_send_key);
++ RC4(&(state->RC4_recv_key), state->keylen, InterimRecvKey,
++ state->session_recv_key);
++
++ if(state->keylen == 8)
++ {
++ /* cripple them from 64->40 bits*/
++ state->session_send_key[0]=state->session_recv_key[0] = MPPE_40_SALT0;
++ state->session_send_key[1]=state->session_recv_key[1] = MPPE_40_SALT1;
++ state->session_send_key[2]=state->session_recv_key[2] = MPPE_40_SALT2;
++ }
++
++ /* make the final rc4 keys */
++ RC4_set_key(&(state->RC4_send_key), state->keylen, state->session_send_key);
++ RC4_set_key(&(state->RC4_recv_key), state->keylen, state->session_recv_key);
++
++ state->bits=MPPE_BIT_ENCRYPTED;
++}
++
++
++#if defined(MPPE_DEBUG) && (MPEE_DEBUG > 1)
++typedef u_int8_t __u8;
++/* Utility procedures to print a buffer in hex/ascii */
++static void
++ppp_print_hex (register __u8 *out, const __u8 *in, int count)
++{
++ register __u8 next_ch;
++ static char hex[] = "0123456789ABCDEF";
++
++ while (count-- > 0) {
++ next_ch = *in++;
++ *out++ = hex[(next_ch >> 4) & 0x0F];
++ *out++ = hex[next_ch & 0x0F];
++ ++out;
++ }
++}
++
++
++static void
++ppp_print_char (register __u8 *out, const __u8 *in, int count)
++{
++ register __u8 next_ch;
++
++ while (count-- > 0) {
++ next_ch = *in++;
++
++ if (next_ch < 0x20 || next_ch > 0x7e)
++ *out++ = '.';
++ else {
++ *out++ = next_ch;
++ if (next_ch == '%') /* printk/syslogd has a bug !! */
++ *out++ = '%';
++ }
++ }
++ *out = '\0';
++}
++
++static void
++ppp_print_buffer (const __u8 *name, const __u8 *buf, int count)
++{
++ __u8 line[44];
++
++ if (name != (__u8 *) NULL)
++ printf("ppp: %s, count = %d\n", name, count);
++
++ while (count > 8) {
++ memset (line, 32, 44);
++ ppp_print_hex (line, buf, 8);
++ ppp_print_char (&line[8 * 3], buf, 8);
++ printf("%s\n", line);
++ count -= 8;
++ buf += 8;
++ }
++
++ if (count > 0) {
++ memset (line, 32, 44);
++ ppp_print_hex (line, buf, count);
++ ppp_print_char (&line[8 * 3], buf, count);
++ printf("%s\n", line);
++ }
++}
++#endif
++
++/* our 'compressor' proper */
++void *mppe_comp_alloc __P((unsigned char *, int));
++void mppe_comp_free __P((void *));
++int mppe_comp_init __P((void *, unsigned char *,
++ int, int, int, int));
++int mppe_decomp_init __P((void *, unsigned char *,
++ int, int, int, int, int));
++int mppe_compress __P((void *, struct mbuf **,
++ struct mbuf *,int, int));
++void mppe_incomp __P((void *, struct mbuf *));
++int mppe_decompress __P((void *, struct mbuf *, struct mbuf **));
++void mppe_comp_reset __P((void *));
++void mppe_comp_stats __P((void *, struct compstat *));
++
++
++/* cleanup the compressor */
++void
++mppe_comp_free(void *arg)
++{
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
++
++ if (state) {
++ free(state,M_DEVBUF);
++ MOD_DEC_USE_COUNT;
++ }
++}
++
++
++/* allocate space for a compressor. */
++void *
++mppe_comp_alloc(unsigned char *options, int opt_len)
++{
++ struct ppp_mppe_state *state;
++
++ if (((2*8)+3 != opt_len && (2*16)+3 != opt_len) /* 2 keys + 3 */
++ || options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
++ DPRINTF(("ppp/mppe: compress rejected: opt_len=%u,o[0]=%x,o[1]=%x\n",
++ opt_len,options[0],options[1]));
++ if (opt_len == 32) {
++ DPRINTF(("ppp/mppe: try increasing CCP_MAX_OPTION_LENGTH in ppp-comp.h\n"));
++ }
++ return NULL;
++ }
++
++ state = (struct ppp_mppe_state *)malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
++ if (state == NULL)
++ return NULL;
++
++ MOD_INC_USE_COUNT;
++
++ memset (state, 0, sizeof (struct ppp_mppe_state));
++
++ /* write the data in options to the right places */
++ memcpy(&state->stateless,options+2,1);
++
++ state->keylen = (opt_len-3)/2;
++ memcpy(state->master_send_key,options+3,state->keylen);
++ memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
++
++ mppe_initialize_key(state);
++
++ return (void *) state;
++}
++
++
++int
++mppe_comp_init(void *arg, unsigned char *options, int opt_len, int unit,
++ int hdrlen, int debug)
++{
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
++
++ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
++ DPRINTF(("ppp%d/mppe: compress rejected: opt_len=%u,o[0]=%x,o[1]=%x\n",
++ state->unit,opt_len,options[0],options[1]));
++ return 0;
++ }
++
++ state->ccount = 0;
++ state->unit = unit;
++ state->debug = debug;
++
++ /* 19 is the min (2*keylen) + 3 */
++ if(opt_len >= 19) {
++ memcpy(&state->stateless,options+2,1);
++
++ state->keylen = (opt_len-3)/2;
++ memcpy(state->master_send_key,options+3,state->keylen);
++ memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
++
++ mppe_initialize_key(state);
++ }
++
++ return 1;
++}
++
++
++int
++mppe_decomp_init(void *arg, unsigned char *options, int opt_len, int unit,
++ int hdrlen, int mru, int debug)
++{
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
++
++ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
++ DPRINTF(("ppp%d/MPPE: options are bad: %x %x\n",
++ state->unit,options[0],options[1]));
++ return 0;
++ }
++
++ state->ccount = 0;
++ state->unit = unit;
++ state->debug = debug;
++ state->mru = mru;
++
++ /* 19 is the min (2*keylen)+3 */
++ if(opt_len >= 19) {
++ memcpy(&state->stateless,options+2,1);
++
++ state->keylen = (opt_len-3)/2;
++ memcpy(state->master_send_key,options+3,state->keylen);
++ memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
++
++ mppe_initialize_key(state);
++ }
++
++ return 1;
++}
++
++
++void
++mppe_comp_reset(void *arg)
++{
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
++
++ DPRINTF(("mppe_comp_reset\n"));
++
++ (state->stats).ratio = 0;
++
++ mppe_synchronize_key(state);
++}
++
++
++void
++mppe_update_count(struct ppp_mppe_state *state)
++{
++ if(!state->stateless)
++ {
++ if ( 0xff == (state->ccount&0xff)){
++ /* time to change keys */
++ if ( 0xfff == (state->ccount&0xfff)){
++ state->ccount = 0;
++ } else {
++ (state->ccount)++;
++ }
++ mppe_change_key(state);
++ } else {
++ state->ccount++;
++ }
++ } else {
++ if ( 0xFFF == (state->ccount & 0xFFF)) {
++ state->ccount = 0;
++ } else {
++ (state->ccount)++;
++ }
++ mppe_change_key(state);
++ }
++}
++
++
++/* the big nasty */
++int
++mppe_compress(void *arg, struct mbuf **mret, struct mbuf *mp,
++ int isize, int osize)
++{
++ unsigned char *rptr;
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
++ int proto, olen;
++ unsigned char *wptr;
++
++ *mret = NULL;
++
++#ifdef DIAGNOSTIC
++ /* XXX: dbj -- we cheat, and allow ourselves to go up to MPPE_OVHD
++ * past the osize handed to us. This implies we may send a packet
++ * greater than the mtu. We don't have much other choice.
++ */
++ if (osize+MPPE_OVHD < isize+MPPE_OVHD) {
++ /* XXX: what should we do here? If we return NULL, the data
++ * will go out unencrypted!
++ */
++ panic("ppp%d/mppe: Not enough space to encrypt packet: %d<%d+%d!\n",
++ state->unit,isize, osize, MPPE_OVHD);
++ }
++
++ /* Sanity check that at least the header is contigous,
++ * if this ever fails, we should just copy the header out by hand
++ * rather than actually do a pullup. This can't happen
++ * with the current if_ppp implementation
++ */
++ if (mp->m_len < PPP_HDRLEN) {
++ panic("ppp%d/mppe: m_pullup required to get ppp header!",
++ state->unit);
++ }
++#endif
++
++#if defined(MPPE_DEBUG) && (MPEE_DEBUG > 1)
++ ppp_print_buffer("mppe_encrypt",rptr,isize);
++#endif
++
++ rptr = mtod(mp, unsigned char *);
++
++ /* Check that the protocol is in the range we handle. */
++ proto = PPP_PROTOCOL(rptr);
++ if (proto < 0x0021 || proto > 0x00FA )
++ return 0;
++
++#ifdef DIAGNOSTIC
++ if (!(mp->m_flags & M_PKTHDR)) {
++ panic("ppp%d/mppe: expecting pkthdr in mbuf",state->unit);
++ }
++#endif
++
++ /* Allocate an mbuf chain to hold the encrypted packet */
++ {
++ struct mbuf *mfirst = NULL;
++ struct mbuf *mprev;
++ struct mbuf *m = NULL;
++ int bleft = isize+MPPE_OVHD;
++ do {
++ mprev = m;
++ MGET(m,M_DONTWAIT, MT_DATA);
++ if (m == NULL) {
++ m_freem(mfirst);
++ /* XXX: what should we do here? If we return NULL, the data
++ * will go out unencrypted. We can't use M_WAITOK, since this
++ * will get get called from splsoftnet()
++ */
++ panic("ppp%d/mppe: unable to allocate mbuf to encrypt packet",
++ state->unit);
++ }
++ m->m_len = 0;
++ if (mfirst == NULL) {
++ mfirst = m;
++ M_COPY_PKTHDR(m,mp);
++ if (bleft > MHLEN) {
++ MCLGET(m, M_DONTWAIT);
++ }
++ } else {
++ mprev->m_next = m;
++ if (bleft > MLEN) {
++ MCLGET(m, M_DONTWAIT);
++ }
++ }
++ bleft -= M_TRAILINGSPACE(m);
++ } while (bleft > 0);
++ *mret = mfirst;
++ }
++
++ wptr = mtod(*mret, unsigned char *);
++
++ /* Copy over the PPP header and store the 2-byte sequence number. */
++ wptr[0] = PPP_ADDRESS(rptr);
++ wptr[1] = PPP_CONTROL(rptr);
++ wptr[2] = PPP_MPPE >>8;
++ wptr[3] = PPP_MPPE;
++ wptr += PPP_HDRLEN;
++ wptr[0] = MPPE_CTRLHI(state);
++ wptr[1] = MPPE_CTRLLO(state);
++ wptr += 2;
++ (*mret)->m_len = PPP_HDRLEN+2;
++
++ state->bits=MPPE_BIT_ENCRYPTED;
++ mppe_update_count(state);
++
++ /* March down input and output mbuf chains, encoding with RC4 */
++ {
++ struct mbuf *mi = mp; /* mbuf in */
++ struct mbuf *mo = *mret; /* mbuf out */
++ int maxi, maxo;
++ maxi = mi->m_len-2;
++ maxo = M_TRAILINGSPACE(mo);
++ while (mi) {
++ if (maxi < maxo) {
++ RC4(&(state->RC4_send_key),maxi,
++ mtod(mi,unsigned char *)+mi->m_len-maxi,
++ mtod(mo,unsigned char *)+mo->m_len);
++ mo->m_len += maxi;
++ maxo -= maxi;
++ mi = mi->m_next;
++ if (mi) {
++ maxi = mi->m_len;
++ }
++ } else if (maxi > maxo) {
++ RC4(&(state->RC4_send_key),maxo,
++ mtod(mi,unsigned char *)+mi->m_len-maxi,
++ mtod(mo,unsigned char *)+mo->m_len);
++ mo->m_len += maxo;
++ maxi -= maxo;
++ mo = mo->m_next;
++ if (mo) {
++ maxo = M_TRAILINGSPACE(mo);
++ }
++ } else {
++ RC4(&(state->RC4_send_key),maxi,
++ mtod(mi,unsigned char *)+mi->m_len-maxi,
++ mtod(mo,unsigned char *)+mo->m_len);
++ mo->m_len += maxi;
++ mi = mi->m_next;
++ mo = mo->m_next;
++ if (mi) {
++ maxi = mi->m_len;
++ maxo = M_TRAILINGSPACE(mo);
++ }
++ }
++ }
++ }
++ olen=isize+MPPE_OVHD;
++
++ (state->stats).comp_bytes += isize;
++ (state->stats).comp_packets++;
++
++#if defined(MPPE_DEBUG) && (MPEE_DEBUG > 1)
++ ppp_print_buffer("mppe_encrypt out",obuf,olen);
++#endif
++
++ return olen;
++}
++
++
++void
++mppe_comp_stats(void *arg, struct compstat *stats)
++{
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
++
++ /* this _SHOULD_ always be 1 */
++ (state->stats).ratio = (state->stats).unc_bytes/(state->stats).comp_bytes;
++
++ *stats = state->stats;
++
++}
++
++
++/* the other big nasty */
++int
++mppe_decompress(void *arg, struct mbuf *mp, struct mbuf **mret)
++{
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
++ int seq;
++ unsigned char *ibuf;
++ int isize;
++ unsigned char *obuf;
++
++ if (!mp) {
++ DPRINTF(("ppp%d/mppe: null input packet\n",state->unit));
++ return DECOMP_ERROR;
++ }
++
++ /* Sanity check that at least the header is contigous,
++ * and the packet is long enough.
++ */
++ if (mp->m_len <= PPP_HDRLEN + MPPE_OVHD) {
++ if (state->debug) {
++ DPRINTF(("ppp%d/mppe: short start mbuf (len=%d)\n",
++ state->unit, mp->m_len));
++ }
++
++ return DECOMP_ERROR;
++ }
++
++ ibuf = mtod(mp,unsigned char *);
++
++ /* Check the sequence number. */
++ seq = MPPE_CCOUNT_FROM_PACKET(ibuf);
++
++ if(!state->stateless && (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED)) {
++ state->decomp_error = 0;
++ state->ccount = seq;
++ }
++
++ if(state->decomp_error) {
++ return DECOMP_ERROR;
++ }
++
++ if (seq != state->ccount) {
++ if (state->debug) {
++ DPRINTF(("ppp%d/mppe: decompress: bad seq # %d, expected %d\n",
++ state->unit, seq, state->ccount));
++ }
++
++ while(state->ccount != seq) {
++ mppe_update_count(state);
++ }
++
++ mppe_update_count(state);
++
++ return DECOMP_ERROR;
++ }
++
++ if(!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
++ DPRINTF(("ppp%d/mppe: ERROR: not an encrypted packet\n",state->unit));
++ mppe_synchronize_key(state);
++ return DECOMP_ERROR;
++ }
++
++ /* Allocate an mbuf chain to hold the decrypted packet */
++ {
++ struct mbuf *mfirst = 0;
++ struct mbuf *mprev;
++ struct mbuf *m = 0;
++ int bleft;
++ isize = 0;
++ for (m=mp; m; m= m->m_next) isize += m->m_len;
++ bleft = isize-MPPE_OVHD;
++ do {
++ mprev = m;
++ MGET(m,M_DONTWAIT, MT_DATA);
++ if (m == NULL) {
++ m_freem(mfirst);
++ DPRINTF(("ppp%d/mppe: unable to allocate mbuf to decrypt packet\n",
++ state->unit));
++ return DECOMP_ERROR;
++ }
++ m->m_len = 0;
++ if (mfirst == NULL) {
++ mfirst=m;
++ M_COPY_PKTHDR(m,mp);
++ if (bleft > MHLEN) {
++ MCLGET(m, M_DONTWAIT);
++ }
++ } else {
++ mprev->m_next = m;
++ if (bleft > MLEN) {
++ MCLGET(m, M_DONTWAIT);
++ }
++ }
++ bleft -= M_TRAILINGSPACE(m);
++ } while (bleft > 0);
++ *mret = mfirst;
++ }
++
++ obuf = mtod(*mret,unsigned char *);
++
++ /*
++ * Fill in the first part of the PPP header. The protocol field
++ * comes from the decompressed data.
++ */
++ obuf[0] = PPP_ADDRESS(ibuf);
++ obuf[1] = PPP_CONTROL(ibuf);
++ obuf += 2;
++ (*mret)->m_len += 2;
++
++ {
++ if(!state->stateless && (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED))
++ mppe_synchronize_key(state);
++ mppe_update_count(state);
++
++ /* March down input and output mbuf chains, decoding with RC4 */
++ {
++ struct mbuf *mi = mp; /* mbuf in */
++ struct mbuf *mo = *mret; /* mbuf out */
++ int maxi, maxo;
++ maxi = mi->m_len-6; /* adjust for PPP_HDRLEN and MPPE_OVERHEAD */
++ maxo = M_TRAILINGSPACE(mo);
++ while (mi) {
++ if (maxi < maxo) {
++ RC4(&(state->RC4_recv_key),maxi,
++ mtod(mi,unsigned char *)+mi->m_len-maxi,
++ mtod(mo,unsigned char *)+mo->m_len);
++ mo->m_len += maxi;
++ maxo -= maxi;
++ mi = mi->m_next;
++ if (mi) {
++ maxi = mi->m_len;
++ }
++ } else if (maxi > maxo) {
++ RC4(&(state->RC4_recv_key),maxo,
++ mtod(mi,unsigned char *)+mi->m_len-maxi,
++ mtod(mo,unsigned char *)+mo->m_len);
++ mo->m_len += maxo;
++ maxi -= maxo;
++ mo = mo->m_next;
++ if (mo) {
++ maxo = M_TRAILINGSPACE(mo);
++ }
++ } else {
++ RC4(&(state->RC4_recv_key),maxi,
++ mtod(mi,unsigned char *)+mi->m_len-maxi,
++ mtod(mo,unsigned char *)+mo->m_len);
++ mo->m_len += maxi;
++ mi = mi->m_next;
++ mo = mo->m_next;
++ if (mi) {
++ maxi = mi->m_len;
++ maxo = M_TRAILINGSPACE(mo);
++ }
++ }
++ }
++ }
++
++ (state->stats).unc_bytes += (isize-MPPE_OVHD);
++ (state->stats).unc_packets ++;
++
++ return DECOMP_OK;
++ }
++}
++
++
++/* Incompressible data has arrived - add it to the history. */
++void
++mppe_incomp(void *arg, struct mbuf *mp)
++{
++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
++ struct mbuf *m;
++ for (m=mp;m;m = m->m_next) {
++ (state->stats).inc_bytes += m->m_len;
++ }
++ (state->stats).inc_packets++;
++}
++
++
++/*************************************************************
++ * Module interface table
++ *************************************************************/
++
++/*
++ * Procedures exported to if_ppp.c.
++ */
++struct compressor ppp_mppe = {
++ CI_MPPE, /* compress_proto */
++ mppe_comp_alloc, /* comp_alloc */
++ mppe_comp_free, /* comp_free */
++ mppe_comp_init, /* comp_init */
++ mppe_comp_reset, /* comp_reset */
++ mppe_compress, /* compress */
++ mppe_comp_stats, /* comp_stat */
++ mppe_comp_alloc, /* decomp_alloc */
++ mppe_comp_free, /* decomp_free */
++ mppe_decomp_init, /* decomp_init */
++ mppe_comp_reset, /* decomp_reset */
++ mppe_decompress, /* decompress */
++ mppe_incomp, /* incomp */
++ mppe_comp_stats, /* decomp_stat */
++};
++
diff --git a/net/ppp-mppe/patches/patch-bu b/net/ppp-mppe/patches/patch-bu
new file mode 100644
index 00000000000..4a245bd0904
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bu
@@ -0,0 +1,56 @@
+$NetBSD: patch-bu,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 25 16:45:44 1999
++++ netbsd-1.4/getkey.c Sat Sep 25 17:06:23 1999
+@@ -0,0 +1,51 @@
++/*
++ * Microsoft's Get_Key() per mppe draft by mag <mag@bunuel.tii.matav.hu>
++ */
++#include <sys/param.h>
++#include <sys/systm.h>
++#include "sha.h"
++
++ /*
++ * Pads used in key derivation
++ */
++static unsigned char SHAPad1[40] =
++ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
++static unsigned char SHAPad2[40] =
++ {0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
++ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
++ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
++ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2};
++
++ /*
++ * SHAInit(), SHAUpdate() and SHAFinal() functions are an
++ * implementation of Secure Hash Algorithm (SHA-1) [7]. These are
++ * available in public domain or can be licensed from
++ * RSA Data Security, Inc.
++ *
++ * 1) H is 8 bytes long for 40 bit session keys.
++ * 2) H is 16 bytes long for 128 bit session keys.
++ * 3) H' is same as H when this routine is called for the first time
++ * for the session.
++ * 4) The generated key is returned in H'. This is the "current" key.
++ */
++void
++GetNewKeyFromSHA(StartKey, SessionKey, SessionKeyLength, InterimKey)
++ unsigned char *StartKey;
++ unsigned char *SessionKey;
++ unsigned long SessionKeyLength;
++ unsigned char *InterimKey;
++{
++ SHA_CTX Context;
++ unsigned char Digest[SHA_DIGEST_LENGTH];
++
++ SHA1_Init(&Context);
++ SHA1_Update(&Context, StartKey, SessionKeyLength);
++ SHA1_Update(&Context, SHAPad1, 40);
++ SHA1_Update(&Context, SessionKey, SessionKeyLength);
++ SHA1_Update(&Context, SHAPad2, 40);
++ SHA1_Final(Digest,&Context);
++ memcpy(InterimKey, Digest, SessionKeyLength);
++}
diff --git a/net/ppp-mppe/patches/patch-bv b/net/ppp-mppe/patches/patch-bv
new file mode 100644
index 00000000000..49066eec766
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bv
@@ -0,0 +1,37 @@
+$NetBSD: patch-bv,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /u1/tmp/ppp-2.3.9/include/net/ppp-comp.h Tue Mar 24 22:33:32 1998
++++ include/net/ppp-comp.h Wed Sep 29 23:00:54 1999
+@@ -42,6 +42,9 @@
+ #endif
+ #define DO_PREDICTOR_1 0
+ #define DO_PREDICTOR_2 0
++#ifndef DO_MPPENCRYPT
++#define DO_MPPENCRYPT 1
++#endif
+
+ /*
+ * Structure giving methods for compression/decompression.
+@@ -109,7 +112,7 @@
+ /*
+ * Max # bytes for a CCP option
+ */
+-#define CCP_MAX_OPTION_LENGTH 32
++#define CCP_MAX_OPTION_LENGTH 64
+
+ /*
+ * Parts of a CCP packet.
+@@ -153,6 +156,13 @@
+ #define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \
+ + DEFLATE_METHOD_VAL)
+ #define DEFLATE_CHK_SEQUENCE 0
++
++/*
++ * Definitions for MPPE.
++ */
++
++#define CI_MPPE 18 /* config. option for MPPE */
++#define CILEN_MPPE 6 /* length of config. option */
+
+ /*
+ * Definitions for other, as yet unsupported, compression methods.
diff --git a/net/ppp-mppe/patches/patch-bw b/net/ppp-mppe/patches/patch-bw
new file mode 100644
index 00000000000..e1b2a8c6578
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bw
@@ -0,0 +1,22 @@
+$NetBSD: patch-bw,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- netbsd-1.4/if_ppp.c.orig2 Wed Sep 29 22:46:03 1999
++++ netbsd-1.4/if_ppp.c Wed Sep 29 22:55:33 1999
+@@ -176,6 +176,7 @@
+
+ extern struct compressor ppp_bsd_compress;
+ extern struct compressor ppp_deflate, ppp_deflate_draft;
++extern struct compressor ppp_mppe;
+
+ struct compressor *ppp_compressors[8] = {
+ #if DO_BSD_COMPRESS && defined(PPP_BSDCOMP)
+@@ -184,6 +185,9 @@
+ #if DO_DEFLATE && defined(PPP_DEFLATE)
+ &ppp_deflate,
+ &ppp_deflate_draft,
++#endif
++#ifdef DO_MPPE && defined(PPP_MPPENCRYPT)
++ &ppp_mppe,
+ #endif
+ NULL
+ };
diff --git a/net/ppp-mppe/patches/patch-bx b/net/ppp-mppe/patches/patch-bx
new file mode 100644
index 00000000000..1ab4e3af1c8
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bx
@@ -0,0 +1,13 @@
+$NetBSD: patch-bx,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- netbsd-1.4/sha_locl.h.orig Wed Sep 29 23:42:05 1999
++++ netbsd-1.4/sha_locl.h Wed Sep 29 23:44:04 1999
+@@ -56,8 +56,6 @@
+ * [including the GNU Public Licence.]
+ */
+
+-#include <stdlib.h>
+-#include <string.h>
+
+ #ifdef undef
+ /* one or the other needs to be defined */
diff --git a/net/ppp-mppe/patches/patch-by b/net/ppp-mppe/patches/patch-by
new file mode 100644
index 00000000000..bb05575c00e
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-by
@@ -0,0 +1,13 @@
+$NetBSD: patch-by,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- netbsd-1.4/sha1dgst.c.orig Wed Sep 29 23:42:05 1999
++++ netbsd-1.4/sha1dgst.c Wed Sep 29 23:43:55 1999
+@@ -56,8 +56,6 @@
+ * [including the GNU Public Licence.]
+ */
+
+-#include <stdio.h>
+-#include <string.h>
+ #undef SHA_0
+ #define SHA_1
+ #include "sha.h"
diff --git a/net/ppp-mppe/patches/patch-bz b/net/ppp-mppe/patches/patch-bz
new file mode 100644
index 00000000000..918ce6257f2
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-bz
@@ -0,0 +1,14 @@
+$NetBSD: patch-bz,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- netbsd-1.4/kinstall.sh.orig2 Wed Sep 29 23:48:37 1999
++++ netbsd-1.4/kinstall.sh Wed Sep 29 23:54:34 1999
+@@ -20,6 +20,9 @@
+ for f in include/net/if_ppp.h include/net/ppp-comp.h include/net/ppp_defs.h \
+ $SRC/bsd-comp.c $SRC/ppp-deflate.c $SRC/if_ppp.c $SRC/if_pppvar.h \
+ $SRC/ppp_tty.c $SRC/slcompress.c include/net/slcompress.h \
++ $SRC/ppp_mppe.c $SRC/rc4_skey.c $SRC/getkey.c $SRC/opensslv.h \
++ $SRC/rc4.h $SRC/rc4.h $SRC/rc4_locl.h $SRC/sha.h $SRC/sha1dgst.c \
++ $SRC/sha_locl.h pppd/mppe.h \
+ common/zlib.c common/zlib.h; do
+ dest=$SYS/net/$(basename $f)
+ if [ -f $dest ]; then
diff --git a/net/ppp-mppe/patches/patch-ca b/net/ppp-mppe/patches/patch-ca
new file mode 100644
index 00000000000..3a9a26f6d9e
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-ca
@@ -0,0 +1,121 @@
+$NetBSD: patch-ca,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Mon Sep 27 01:09:07 1999
++++ netbsd-1.4/lkm_mppe.c Mon Sep 27 02:03:12 1999
+@@ -0,0 +1,116 @@
++/* NetBSD */
++/*
++ * Copyright (c) 1999 Darrin B. Jewell
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ * must display the following acknowledgement:
++ * This product includes software developed by Darrin B. Jewell
++ * 4. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <sys/param.h>
++#include <sys/systm.h>
++#include <sys/conf.h>
++#include <sys/exec.h>
++#include <sys/lkm.h>
++
++#include <sys/tty.h>
++#include <sys/ttycom.h>
++
++MOD_MISC("mppe");
++
++extern struct compressor ppp_mppe;
++extern struct compressor *ppp_compressors[];
++extern int mppe_in_use;
++
++int mppe_lkmentry __P((struct lkm_table *, int, int));
++int mppe_lkm_load __P((struct lkm_table *, int));
++
++int
++mppe_lkm_load(lkmtp, cmd)
++ struct lkm_table *lkmtp;
++ int cmd;
++{
++ int i;
++ if (lkmexists(lkmtp)) return EEXIST;
++
++ for(i=0;i<7;i++) {
++ if (ppp_compressors[i] == NULL) {
++ ppp_compressors[i] = &ppp_mppe;
++ ppp_compressors[i+1] = NULL;
++ break;
++ }
++ }
++ if (i==7) {
++ printf("MPPE: no free compressor slots\n");
++ return ENODEV;
++ }
++
++ printf("MPPE: loaded into ppp at slot %d\n",i);
++
++ return 0;
++}
++
++int
++mppe_lkm_unload(lkmtp, cmd)
++ struct lkm_table *lkmtp;
++ int cmd;
++{
++ int i;
++ if (mppe_in_use) {
++ printf("MPPE: cannot unload lkm while in use (count=%d)\n",
++ mppe_in_use);
++ return EBUSY;
++ }
++ for(i=0;ppp_compressors[i];i++) {
++ if (ppp_compressors[i] == &ppp_mppe) break;
++ }
++ if (ppp_compressors[i] == NULL) {
++ printf("MPPE: cannot find mppe in ppp compressor slots\n");
++ return ENODEV;
++ }
++ printf("MPPE: unloaded from ppp at slot %d\n",i);
++ do {
++ ppp_compressors[i] = ppp_compressors[i+1];
++ } while(ppp_compressors[i++]);
++
++ return 0;
++}
++
++int
++mppe_lkm_stat(lkmtp, cmd)
++ struct lkm_table *lkmtp;
++ int cmd;
++{
++ printf("MPPE: use count %d\n",mppe_in_use);
++ return 0;
++}
++
++int
++mppe_lkmentry(lkmtp, cmd, ver)
++ struct lkm_table *lkmtp;
++ int cmd, ver;
++{
++ DISPATCH(lkmtp, cmd, ver, mppe_lkm_load,mppe_lkm_unload,mppe_lkm_stat);
++}
diff --git a/net/ppp-mppe/patches/patch-cb b/net/ppp-mppe/patches/patch-cb
new file mode 100644
index 00000000000..1acd0fb77c3
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-cb
@@ -0,0 +1,21 @@
+$NetBSD: patch-cb,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 25 16:21:45 1999
++++ netbsd-1.4/Makefile Sat Sep 25 16:38:19 1999
+@@ -0,0 +1,16 @@
++
++.if defined(SYSDIR)
++S=${SYSDIR}
++.endif
++.PATH: $S/net
++
++CFLAGS+= -DMPPE_DEBUG=1 -DDIAGNOSTIC -I ${.CURDIR}/../pppd
++
++KMOD= mppe
++SRCS= ppp_mppe.c lkm_mppe.c rc4_skey.c getkey.c
++MKMAN= no
++
++# We set LDFLAGS becuase bsd.pkg.mk will put cc specific flags in it.
++LDFLAGS=
++
++.include <bsd.kmod.mk>
diff --git a/net/ppp-mppe/patches/patch-da b/net/ppp-mppe/patches/patch-da
new file mode 100644
index 00000000000..29849ad6853
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-da
@@ -0,0 +1,63 @@
+$NetBSD: patch-da,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+Index: Makefile.inc
+diff -u /dev/null Makefile.inc
+--- /dev/null Fri Sep 17 20:40:08 1999
++++ Makefile.inc Fri Sep 26 12:52:08 1997
+@@ -0,0 +1,3 @@
++BINDIR=${PREFIX}/sbin
++MANDIR=${PREFIX}/man
++KMODDIR=${PREFIX}/lkm
+--- netbsd-1.4/Makefile.top.orig2 Sat Sep 18 11:32:36 1999
++++ netbsd-1.4/Makefile.top Sat Sep 18 11:33:06 1999
+@@ -1,5 +1,5 @@
+ # NetBSD: Makefile,v 1.17 1997/09/26 19:52:08 christos Exp
+
+-SUBDIR= chat pppd pppstats
++SUBDIR= chat pppd pppstats netbsd-1.4
+
+ .include <bsd.subdir.mk>
+--- pppd/Makefile.netbsd-1.4.orig2 Sat Sep 25 17:30:52 1999
++++ pppd/Makefile.netbsd-1.4 Sat Sep 25 17:33:27 1999
+@@ -1,13 +1,11 @@
+ # NetBSD: Makefile,v 1.26 1999/08/25 02:07:41 christos Exp
+
+-PCAPDIR=${.CURDIR}/../../../lib/libpcap
+
+ PROG= pppd
+ SRCS= auth.c cbcp.c ccp.c chap.c chap_ms.c demand.c eui64.c fsm.c \
+ ipcp.c ipv6cp.c ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c \
+ upap.c utils.c mppe.c sha1dgst.c extra_crypto.c
+
+-.PATH: ${PCAPDIR}
+ MAN= pppd.8
+ BINMODE=4555
+ BINOWN= root
+@@ -15,7 +13,8 @@
+ LDADD= -lpcap -lcrypt -lutil
+ DPADD= ${LIBPCAP} ${LIBCRYPT} ${LIBUTIL}
+ CPPFLAGS+= -I. -DHAVE_PATHS_H
+-CPPFLAGS+= -I${PCAPDIR} -DPPP_FILTER
++CPPFLAGS+= -I ${.CURDIR}/../include
++CPPFLAGS+= -DPPP_FILTER
+ CPPFLAGS+= -DCBCP_SUPPORT -DCHAPMS -DUSE_CRYPT -DMSLANMAN
+ CPPFLAGS+= -DMPPE
+ # XXX: Does not work (yet)
+--- chat/Makefile.netbsd-1.4.orig2 Sat Sep 25 17:38:55 1999
++++ chat/Makefile.netbsd-1.4 Sat Sep 25 17:39:34 1999
+@@ -2,5 +2,6 @@
+
+ PROG= chat
+ MAN= chat.8
++CPPFLAGS+= -I ${.CURDIR}/../include
+
+ .include <bsd.prog.mk>
+--- pppstats/Makefile.netbsd-1.4.orig2 Sat Sep 25 17:40:19 1999
++++ pppstats/Makefile.netbsd-1.4 Sat Sep 25 17:40:36 1999
+@@ -2,5 +2,6 @@
+
+ PROG= pppstats
+ MAN= pppstats.8
++CPPFLAGS+= -I ${.CURDIR}/../include
+
+ .include <bsd.prog.mk>
diff --git a/net/ppp-mppe/patches/patch-db b/net/ppp-mppe/patches/patch-db
new file mode 100644
index 00000000000..b4bef31009d
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-db
@@ -0,0 +1,68 @@
+$NetBSD: patch-db,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- pppd/options.c.orig2 Sat Sep 18 02:11:16 1999
++++ pppd/options.c Sat Sep 18 02:22:19 1999
+@@ -36,7 +36,15 @@
+ #include <arpa/inet.h>
+ #ifdef PPP_FILTER
+ #include <pcap.h>
++#if 0
+ #include <pcap-int.h> /* XXX: To get struct pcap */
++#else
++struct pcap {
++ int fd;
++ int snapshot;
++ int linktype;
++};
++#endif
+ #endif
+
+ #include "pppd.h"
+@@ -1203,7 +1212,11 @@
+ setpassfilter_in(argv)
+ char **argv;
+ {
++#ifdef DLT_PPP_SERIAL
+ pc.linktype = DLT_PPP_SERIAL;
++#else
++ pc.linktype = DLT_PPP;
++#endif
+ pc.snapshot = PPP_HDRLEN;
+
+ if (pcap_compile(&pc, &pass_filter_in, *argv, 1, netmask) == 0)
+@@ -1219,7 +1232,11 @@
+ setpassfilter_out(argv)
+ char **argv;
+ {
++#ifdef DLT_PPP_SERIAL
+ pc.linktype = DLT_PPP_SERIAL;
++#else
++ pc.linktype = DLT_PPP;
++#endif
+ pc.snapshot = PPP_HDRLEN;
+
+ if (pcap_compile(&pc, &pass_filter_out, *argv, 1, netmask) == 0)
+@@ -1235,7 +1252,11 @@
+ setactivefilter_in(argv)
+ char **argv;
+ {
++#ifdef DLT_PPP_SERIAL
+ pc.linktype = DLT_PPP_SERIAL;
++#else
++ pc.linktype = DLT_PPP;
++#endif
+ pc.snapshot = PPP_HDRLEN;
+
+ if (pcap_compile(&pc, &active_filter_in, *argv, 1, netmask) == 0)
+@@ -1252,7 +1273,11 @@
+ setactivefilter_out(argv)
+ char **argv;
+ {
++#ifdef DLT_PPP_SERIAL
+ pc.linktype = DLT_PPP_SERIAL;
++#else
++ pc.linktype = DLT_PPP;
++#endif
+ pc.snapshot = PPP_HDRLEN;
+
+ if (pcap_compile(&pc, &active_filter_out, *argv, 1, netmask) == 0)
diff --git a/net/ppp-mppe/patches/patch-dc b/net/ppp-mppe/patches/patch-dc
new file mode 100644
index 00000000000..eba6d129d59
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-dc
@@ -0,0 +1,87 @@
+$NetBSD: patch-dc,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- netbsd-1.4/ppp_tty.c.orig2 Sat Sep 18 11:06:15 1999
++++ netbsd-1.4/ppp_tty.c Sat Sep 18 11:09:46 1999
+@@ -123,9 +123,13 @@
+ int pppinput __P((int c, struct tty *tp));
+ int pppstart __P((struct tty *tp));
+
++#ifdef TIOCRCVFRAME
+ static void ppprcvframe __P((struct ppp_softc *sc, struct mbuf *m));
++#endif
+ static u_int16_t pppfcs __P((u_int16_t fcs, u_char *cp, int len));
++#ifdef TIOCXMTFRAME
+ static void pppsyncstart __P((struct ppp_softc *sc));
++#endif
+ static void pppasyncstart __P((struct ppp_softc *));
+ static void pppasyncctlp __P((struct ppp_softc *));
+ static void pppasyncrelinq __P((struct ppp_softc *));
+@@ -202,7 +206,11 @@
+
+ #if NBPFILTER > 0
+ /* Switch DLT to PPP-over-serial. */
++#ifdef DLT_PPP_SERIAL
+ bpf_change_type(&sc->sc_bpf, DLT_PPP_SERIAL, PPP_HDRLEN);
++#else
++ bpf_change_type(&sc->sc_bpf, DLT_PPP, PPP_HDRLEN);
++#endif
+ #endif
+
+ sc->sc_ilen = 0;
+@@ -414,9 +422,11 @@
+
+ error = 0;
+ switch (cmd) {
++#ifdef TIOCRCVFRAME
+ case TIOCRCVFRAME:
+ ppprcvframe(sc,*((struct mbuf **)data));
+ break;
++#endif
+
+ case PPPIOCSASYNCMAP:
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+@@ -462,6 +472,7 @@
+ return error;
+ }
+
++#ifdef TIOCRCVFRAME
+ /* receive a complete ppp frame from device in synchronous
+ * hdlc mode. caller gives up ownership of mbuf
+ */
+@@ -570,6 +581,7 @@
+ m_freem(m);
+ splx(s);
+ }
++#endif
+
+ /*
+ * FCS lookup table as calculated by genfcstab.
+@@ -623,6 +635,7 @@
+ return (fcs);
+ }
+
++#ifdef TIOCXMTFRAME
+ /* This gets called at splsoftnet from pppasyncstart at various times
+ * when there is data ready to be sent.
+ */
+@@ -657,6 +670,7 @@
+ sc->sc_stats.ppp_obytes += len;
+ }
+ }
++#endif
+
+ /*
+ * This gets called at splsoftnet from if_ppp.c at various times
+@@ -674,10 +688,12 @@
+ struct mbuf *m2;
+ int s;
+
++#ifdef TIOCXMTFRAME
+ if (sc->sc_flags & SC_SYNC){
+ pppsyncstart(sc);
+ return;
+ }
++#endif
+
+ idle = 0;
+ while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
diff --git a/net/ppp-mppe/patches/patch-dd b/net/ppp-mppe/patches/patch-dd
new file mode 100644
index 00000000000..72e1e8f8f9a
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-dd
@@ -0,0 +1,25 @@
+$NetBSD: patch-dd,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 04:53:17 1999
++++ netbsd-1.4/ppp.h Sat Sep 18 05:06:12 1999
+@@ -0,0 +1 @@
++#define NPPP 4
+--- /dev/null Sat Sep 18 04:53:17 1999
++++ netbsd-1.4/opt_gateway.h Sat Sep 18 05:06:09 1999
+@@ -0,0 +1 @@
++/* option `GATEWAY' not defined */
+--- /dev/null Sat Sep 18 04:53:17 1999
++++ netbsd-1.4/opt_inet.h Sat Sep 18 05:06:09 1999
+@@ -0,0 +1,2 @@
++/* option `INET6' not defined */
++#define INET 1
+--- /dev/null Sat Sep 18 04:53:17 1999
++++ netbsd-1.4/opt_ppp.h Sat Sep 18 05:06:09 1999
+@@ -0,0 +1,3 @@
++#define PPP_FILTER 1
++#define PPP_BSDCOMP 1
++#define PPP_DEFLATE 1
+--- /dev/null Sat Sep 18 04:53:17 1999
++++ netbsd-1.4/bpfilter.h Sat Sep 18 05:10:37 1999
+@@ -0,0 +1 @@
++#define NBPFILTER 8
diff --git a/net/ppp-mppe/patches/patch-de b/net/ppp-mppe/patches/patch-de
new file mode 100644
index 00000000000..720d1a7be16
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-de
@@ -0,0 +1,24 @@
+$NetBSD: patch-de,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 10:57:59 1999
++++ netbsd-1.4/Makefile.lkm_ppp Sat Sep 18 11:04:00 1999
+@@ -0,0 +1,19 @@
++
++.PATH: ${.CURDIR}/../common
++CFLAGS+= -I ${.CURDIR}/../include
++KMOD= if_ppp_lkm
++SRCS= lkm_ppp.c if_ppp.c ppp-deflate.c ppp_tty.c slcompress.c zlib.c
++MKMAN= no
++
++# We set LDFLAGS becuase bsd.pkg.mk will put cc specific flags in it.
++LDFLAGS=
++
++.PHONY: net-links
++depend: net-links
++all: net-links
++net-links:
++ -rm -f net && ln -s ${.CURDIR} net
++
++CLEANFILES+=net
++
++.include <bsd.kmod.mk>
diff --git a/net/ppp-mppe/patches/patch-df b/net/ppp-mppe/patches/patch-df
new file mode 100644
index 00000000000..018f85d1be6
--- /dev/null
+++ b/net/ppp-mppe/patches/patch-df
@@ -0,0 +1,99 @@
+$NetBSD: patch-df,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+
+--- /dev/null Sat Sep 18 11:13:03 1999
++++ netbsd-1.4/lkm_ppp.c Sat Sep 18 11:16:47 1999
+@@ -0,0 +1,94 @@
++/* NetBSD */
++/*
++ * Copyright (c) 1999 Darrin B. Jewell
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ * must display the following acknowledgement:
++ * This product includes software developed by Darrin B. Jewell
++ * 4. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <sys/param.h>
++#include <sys/systm.h>
++#include <sys/conf.h>
++#include <sys/exec.h>
++#include <sys/lkm.h>
++
++#include <sys/tty.h>
++#include <sys/ttycom.h>
++
++void pppattach __P((void));
++int pppopen __P((dev_t dev, struct tty *tp));
++int pppclose __P((struct tty *tp, int flags));
++int ppptioctl __P((struct tty *tp, u_long cmd, caddr_t data,
++ int flag, struct proc *p));
++int pppinput __P((int c, struct tty *tp));
++int pppstart __P((struct tty *tp));
++int pppread __P((struct tty *tp, struct uio *uio, int flag));
++int pppwrite __P((struct tty *tp, struct uio *uio, int flag));
++
++MOD_MISC("ppp");
++
++int if_ppp_lkm_lkmentry __P((struct lkm_table *, int, int));
++int if_ppp_lkm_load __P((struct lkm_table *, int));
++
++struct linesw ppp_linesw = {
++ pppopen,
++ pppclose,
++ pppread,
++ pppwrite,
++ ppptioctl,
++ pppinput,
++ pppstart,
++ ttymodem
++};
++
++int
++if_ppp_lkm_load(lkmtp, cmd)
++ struct lkm_table *lkmtp;
++ int cmd;
++{
++ if (lkmexists(lkmtp)) return EEXIST;
++
++ linesw[PPPDISC] = ppp_linesw;
++ pppattach();
++
++ /* XXX, in order for this lkm to work, we would need to
++ * arrange to have pppintr() called at splsoftnet()
++ * I might at some point use a kernel thread to invoke
++ * this when needed instead, but for now, I just plan
++ * to use ppp compiled into the kernel. --darrin
++ */
++#error "Not Yet Implemented, if_ppp_lkm_load"
++
++ return 0;
++}
++
++int
++if_ppp_lkm_lkmentry(lkmtp, cmd, ver)
++ struct lkm_table *lkmtp;
++ int cmd, ver;
++{
++ DISPATCH(lkmtp, cmd, ver, if_ppp_lkm_load,lkm_nofunc,lkm_nofunc);
++}
diff --git a/net/ppp-mppe/pkg/COMMENT b/net/ppp-mppe/pkg/COMMENT
new file mode 100644
index 00000000000..564249eafbd
--- /dev/null
+++ b/net/ppp-mppe/pkg/COMMENT
@@ -0,0 +1 @@
+PPP daemon and LKM with MPPE - Microsoft Point-to-Point Encryption
diff --git a/net/ppp-mppe/pkg/DESCR b/net/ppp-mppe/pkg/DESCR
new file mode 100644
index 00000000000..65c80d56bda
--- /dev/null
+++ b/net/ppp-mppe/pkg/DESCR
@@ -0,0 +1,23 @@
+The Point-to-Point Protocol (PPP) provides a standard way to establish a
+network connection over a serial link. At present, this package supports
+IP and the protocols layered above IP, such as TCP and UDP.
+
+This software consists of two parts:
+ - Loadable Kernel module, which establishes a network interface and
+ passes packets between the serial port, the kernel networking code and
+ the PPP daemon (pppd).
+ - The PPP daemon (pppd), which negotiates with the peer to establish the
+ link and sets up the ppp network interface. Pppd includes support for
+ authentication, so you can control which other systems may make a PPP
+ connection and what IP addresses they may use.
+
+This version is patched to support MPPE:
+ MPPE - Microsoft Point-to-Point Encryption uses rc4 (40 or 128 bit) as a
+ bi-directional encryption algorithm. The keys are based on your MS-CHAP
+ authentication info, so you must use chapms or chapms-v2.
+
+MPPE is NOT a particularly secure mode of operation. For maximum possible
+security using MPPE, it is advised in the RFC's to use the highest mode of
+encryption that is legal, and to enable stateless mode (which renogotiates
+keys with every packet). Even with these precautions, MPPE is not very
+secure, but anything is better than nothing, right?
diff --git a/net/ppp-mppe/pkg/PLIST b/net/ppp-mppe/pkg/PLIST
new file mode 100644
index 00000000000..c85f5a3149b
--- /dev/null
+++ b/net/ppp-mppe/pkg/PLIST
@@ -0,0 +1,12 @@
+@comment $NetBSD: PLIST,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
+sbin/chat
+man/man8/chat.8
+man/cat8/chat.0
+sbin/pppd
+man/man8/pppd.8
+man/cat8/pppd.0
+sbin/pppstats
+man/man8/pppstats.8
+man/cat8/pppstats.0
+lkm/mppe.o
+@dirrm lkm