diff options
author | dbj <dbj@pkgsrc.org> | 1999-10-08 04:34:43 +0000 |
---|---|---|
committer | dbj <dbj@pkgsrc.org> | 1999-10-08 04:34:43 +0000 |
commit | ff1c7a99858902f04a22c7c9e9dbd4453794921e (patch) | |
tree | 7b871c485a300ca6c1a195fba78b629093acf28b /net/ppp-mppe | |
parent | ab6f85f54a3979da8b359365352f8fb5c3eb0688 (diff) | |
download | pkgsrc-ff1c7a99858902f04a22c7c9e9dbd4453794921e.tar.gz |
PPP daemon and LKM with MPPE - Microsoft Point-to-Point Encryption
Diffstat (limited to 'net/ppp-mppe')
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 |