add a lot of debian fixes to ppp (should fix persist and demand, too), clean up patches
authorFelix Fietkau <nbd@openwrt.org>
Tue, 12 Jul 2005 09:38:18 +0000 (09:38 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Tue, 12 Jul 2005 09:38:18 +0000 (09:38 +0000)
SVN-Revision: 1417

25 files changed:
openwrt/package/ppp/Makefile
openwrt/package/ppp/patches/100-debian_close_dev_ppp.patch [new file with mode: 0644]
openwrt/package/ppp/patches/101-debian_ip-up_option.patch [new file with mode: 0644]
openwrt/package/ppp/patches/102-debian_pppoe_multicast_pado.patch [new file with mode: 0644]
openwrt/package/ppp/patches/103-debian_pppoe_cleanup.patch [new file with mode: 0644]
openwrt/package/ppp/patches/104-debian_fix_linkpidfile.patch [new file with mode: 0644]
openwrt/package/ppp/patches/105-debian_pppoatm_cleanup.patch [new file with mode: 0644]
openwrt/package/ppp/patches/106-debian_pppoatm_fix_mtu.patch [new file with mode: 0644]
openwrt/package/ppp/patches/107-debian_stripMSdomain.patch [new file with mode: 0644]
openwrt/package/ppp/patches/108-debian_defaultroute.patch [new file with mode: 0644]
openwrt/package/ppp/patches/109-debian_demand.patch [new file with mode: 0644]
openwrt/package/ppp/patches/200-makefile.patch [new file with mode: 0644]
openwrt/package/ppp/patches/201-mppe_mppc_1.1.patch [new file with mode: 0644]
openwrt/package/ppp/patches/202-no_atm.patch [new file with mode: 0644]
openwrt/package/ppp/patches/203-no_strip.patch [new file with mode: 0644]
openwrt/package/ppp/patches/204-opt_flags.patch [new file with mode: 0644]
openwrt/package/ppp/patches/205-pppoe_iface_name.patch [new file with mode: 0644]
openwrt/package/ppp/patches/206-radius_config.patch [new file with mode: 0644]
openwrt/package/ppp/patches/ppp-2.4.3-makefile.patch [deleted file]
openwrt/package/ppp/patches/ppp-2.4.3-mppe-mppc-1.1.patch [deleted file]
openwrt/package/ppp/patches/ppp-2.4.3-no-atm.patch [deleted file]
openwrt/package/ppp/patches/ppp-2.4.3-no-strip.patch [deleted file]
openwrt/package/ppp/patches/ppp-2.4.3-opt-flags.patch [deleted file]
openwrt/package/ppp/patches/ppp-2.4.3-pppoe-iface-name.patch [deleted file]
openwrt/package/ppp/patches/ppp-2.4.3-radius-config.patch [deleted file]

index 1b95a76c72b6fbeeec8cdcc7e259aba841b2a0e4..43146328381e9f36fac5354b9808d87d512bbf61 100644 (file)
@@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ppp
 PKG_VERSION:=2.4.3
-PKG_RELEASE:=4
+PKG_RELEASE:=5
 PKG_MD5SUM:=848f6c3cafeb6074ffeb293c3af79b7c
 
 PKG_SOURCE_URL:=ftp://ftp.samba.org/pub/ppp/
diff --git a/openwrt/package/ppp/patches/100-debian_close_dev_ppp.patch b/openwrt/package/ppp/patches/100-debian_close_dev_ppp.patch
new file mode 100644 (file)
index 0000000..4e50118
--- /dev/null
@@ -0,0 +1,34 @@
+From: Simon Peter <dn.tlp@gmx.net>
+Subject: Bug#306261: pppd does not properly close /dev/ppp on persist
+
+When using the kernel PPPoE driver, pppd never
+closes /dev/ppp when the link has come down.
+
+It opens superfluous fds to the device each time it re-opens the
+connection, with the unclosed ones falsely reported always ready for
+data by select().
+
+This makes pppd eat up 100% CPU time after the first persist because of
+the always instantly returning select() on the unclosed fds.
+
+The problem also occurs with the upstream version, but does not occur
+when a pty/tty device is used for the ppp connection.
+
+
+diff -u -r ppp-2.4.3/pppd/sys-linux.c ppp-2.4.3/pppd/sys-linux.c
+--- ppp-2.4.3/pppd/sys-linux.c 2005-04-29 20:08:37.000000000 +0200
++++ ppp-2.4.3/pppd/sys-linux.c 2005-04-29 20:07:03.000000000 +0200
+@@ -455,6 +455,13 @@
+     if (new_style_driver) {
+       int flags;
++        /* if a ppp_fd is already open, close it first */
++        if(ppp_fd > 0) {
++          close(ppp_fd);
++          remove_fd(ppp_fd);
++          ppp_fd = -1;
++        }
++
+       /* Open an instance of /dev/ppp and connect the channel to it */
+       if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
+           error("Couldn't get channel number: %m");
diff --git a/openwrt/package/ppp/patches/101-debian_ip-up_option.patch b/openwrt/package/ppp/patches/101-debian_ip-up_option.patch
new file mode 100644 (file)
index 0000000..6033fda
--- /dev/null
@@ -0,0 +1,88 @@
+diff -ruNp ppp-2.4.3.orig/pppd/ipcp.c ppp-2.4.3/pppd/ipcp.c
+--- ppp-2.4.3.orig/pppd/ipcp.c 2004-11-13 13:03:26.000000000 +0100
++++ ppp-2.4.3/pppd/ipcp.c      2005-02-20 18:45:22.241810136 +0100
+@@ -1846,7 +1846,7 @@ ipcp_up(f)
+      */
+     if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
+       ipcp_script_state = s_up;
+-      ipcp_script(_PATH_IPUP);
++      ipcp_script(path_ipup);
+     }
+ }
+@@ -1896,7 +1896,7 @@ ipcp_down(f)
+     /* Execute the ip-down script */
+     if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
+       ipcp_script_state = s_down;
+-      ipcp_script(_PATH_IPDOWN);
++      ipcp_script(path_ipdown);
+     }
+ }
+@@ -1950,13 +1950,13 @@ ipcp_script_done(arg)
+     case s_up:
+       if (ipcp_fsm[0].state != OPENED) {
+           ipcp_script_state = s_down;
+-          ipcp_script(_PATH_IPDOWN);
++          ipcp_script(path_ipdown);
+       }
+       break;
+     case s_down:
+       if (ipcp_fsm[0].state == OPENED) {
+           ipcp_script_state = s_up;
+-          ipcp_script(_PATH_IPUP);
++          ipcp_script(path_ipup);
+       }
+       break;
+     }
+diff -ruNp ppp-2.4.3.orig/pppd/main.c ppp-2.4.3/pppd/main.c
+--- ppp-2.4.3.orig/pppd/main.c 2005-02-20 18:46:14.409879384 +0100
++++ ppp-2.4.3/pppd/main.c      2005-02-20 18:45:22.243809832 +0100
+@@ -314,6 +314,9 @@ main(argc, argv)
+     struct protent *protp;
+     char numbuf[16];
++    strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
++    strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
++
+     link_stats_valid = 0;
+     new_phase(PHASE_INITIALIZE);
+diff -ruNp ppp-2.4.3.orig/pppd/options.c ppp-2.4.3/pppd/options.c
+--- ppp-2.4.3.orig/pppd/options.c      2005-02-20 18:46:14.410879232 +0100
++++ ppp-2.4.3/pppd/options.c   2005-02-20 18:46:02.154742448 +0100
+@@ -108,6 +108,8 @@ char       linkname[MAXPATHLEN];   /* logical na
+ bool  tune_kernel;            /* may alter kernel settings */
+ int   connect_delay = 1000;   /* wait this many ms after connect script */
+ int   req_unit = -1;          /* requested interface unit */
++char  path_ipup[MAXPATHLEN];  /* pathname of ip-up script */
++char  path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
+ bool  multilink = 0;          /* Enable multilink operation */
+ char  *bundle_name = NULL;    /* bundle name for multilink */
+ bool  dump_options;           /* print out option values */
+@@ -276,6 +278,13 @@ option_t general_options[] = {
+       "Number of seconds to wait for child processes at exit",
+       OPT_PRIO },
++    { "ip-up-script", o_string, path_ipup,
++      "Set pathname of ip-up script",
++      OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
++    { "ip-down-script", o_string, path_ipdown,
++      "Set pathname of ip-down script",
++      OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
++
+ #ifdef HAVE_MULTILINK
+     { "multilink", o_bool, &multilink,
+       "Enable multilink operation", OPT_PRIO | 1 },
+diff -ruNp ppp-2.4.3.orig/pppd/pppd.h ppp-2.4.3/pppd/pppd.h
+--- ppp-2.4.3.orig/pppd/pppd.h 2005-02-20 18:46:14.414878624 +0100
++++ ppp-2.4.3/pppd/pppd.h      2005-02-20 18:45:22.247809224 +0100
+@@ -312,6 +312,8 @@ extern bool        tune_kernel;    /* May alter ke
+ extern int    connect_delay;  /* Time to delay after connect script */
+ extern int    max_data_rate;  /* max bytes/sec through charshunt */
+ extern int    req_unit;       /* interface unit number to use */
++extern char   path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
++extern char   path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
+ extern bool   multilink;      /* enable multilink operation */
+ extern bool   noendpoint;     /* don't send or accept endpt. discrim. */
+ extern char   *bundle_name;   /* bundle name for multilink */
diff --git a/openwrt/package/ppp/patches/102-debian_pppoe_multicast_pado.patch b/openwrt/package/ppp/patches/102-debian_pppoe_multicast_pado.patch
new file mode 100644 (file)
index 0000000..ea5275c
--- /dev/null
@@ -0,0 +1,14 @@
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/discovery.c ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/discovery.c   2004-11-04 11:07:37.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c        2005-02-24 21:00:11.586697752 +0100
+@@ -365,8 +365,8 @@ waitForPADO(PPPoEConnection *conn, int t
+       if (!packetIsForMe(conn, &packet)) continue;
+       if (packet.code == CODE_PADO) {
+-          if (NOT_UNICAST(packet.ethHdr.h_source)) {
+-              printErr("Ignoring PADO packet from non-unicast MAC address");
++          if (BROADCAST(packet.ethHdr.h_source)) {
++              printErr("Ignoring PADO packet from broadcast MAC address");
+               continue;
+           }
+           parsePacket(&packet, parsePADOTags, &pc);
diff --git a/openwrt/package/ppp/patches/103-debian_pppoe_cleanup.patch b/openwrt/package/ppp/patches/103-debian_pppoe_cleanup.patch
new file mode 100644 (file)
index 0000000..8a97a0b
--- /dev/null
@@ -0,0 +1,1079 @@
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/common.c ppp-2.4.3/pppd/plugins/rp-pppoe/common.c
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/common.c      2004-02-02 04:36:46.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/common.c   2005-03-11 02:09:19.000000000 +0100
+@@ -18,10 +18,6 @@ static char const RCSID[] =
+ #include "pppoe.h"
+-#ifdef HAVE_SYSLOG_H
+-#include <syslog.h>
+-#endif
+-
+ #include <string.h>
+ #include <errno.h>
+ #include <stdlib.h>
+@@ -50,17 +46,17 @@ parsePacket(PPPoEPacket *packet, ParseFu
+     UINT16_t tagType, tagLen;
+     if (packet->ver != 1) {
+-      syslog(LOG_ERR, "Invalid PPPoE version (%d)", (int) packet->ver);
++      error("Invalid PPPoE version (%u)", packet->ver);
+       return -1;
+     }
+     if (packet->type != 1) {
+-      syslog(LOG_ERR, "Invalid PPPoE type (%d)", (int) packet->type);
++      error("Invalid PPPoE type (%u)", packet->type);
+       return -1;
+     }
+     /* Do some sanity checks on packet */
+     if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */
+-      syslog(LOG_ERR, "Invalid PPPoE packet length (%u)", len);
++      error("Invalid PPPoE packet length (%u)", len);
+       return -1;
+     }
+@@ -76,7 +72,7 @@ parsePacket(PPPoEPacket *packet, ParseFu
+           return 0;
+       }
+       if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) {
+-          syslog(LOG_ERR, "Invalid PPPoE tag length (%u)", tagLen);
++          error("Invalid PPPoE tag length (%u)", tagLen);
+           return -1;
+       }
+       func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra);
+@@ -105,17 +101,17 @@ findTag(PPPoEPacket *packet, UINT16_t ty
+     UINT16_t tagType, tagLen;
+     if (packet->ver != 1) {
+-      syslog(LOG_ERR, "Invalid PPPoE version (%d)", (int) packet->ver);
++      error("Invalid PPPoE version (%u)", packet->ver);
+       return NULL;
+     }
+     if (packet->type != 1) {
+-      syslog(LOG_ERR, "Invalid PPPoE type (%d)", (int) packet->type);
++      error("Invalid PPPoE type (%u)", packet->type);
+       return NULL;
+     }
+     /* Do some sanity checks on packet */
+     if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */
+-      syslog(LOG_ERR, "Invalid PPPoE packet length (%u)", len);
++      error("Invalid PPPoE packet length (%u)", len);
+       return NULL;
+     }
+@@ -131,7 +127,7 @@ findTag(PPPoEPacket *packet, UINT16_t ty
+           return NULL;
+       }
+       if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) {
+-          syslog(LOG_ERR, "Invalid PPPoE tag length (%u)", tagLen);
++          error("Invalid PPPoE tag length (%u)", tagLen);
+           return NULL;
+       }
+       if (tagType == type) {
+@@ -143,6 +139,7 @@ findTag(PPPoEPacket *packet, UINT16_t ty
+     return NULL;
+ }
++#ifdef unused
+ /**********************************************************************
+ *%FUNCTION: printErr
+ *%ARGUMENTS:
+@@ -158,6 +155,7 @@ printErr(char const *str)
+     fprintf(stderr, "pppoe: %s\n", str);
+     syslog(LOG_ERR, "%s", str);
+ }
++#endif
+ /**********************************************************************
+@@ -172,7 +170,7 @@ strDup(char const *str)
+ {
+     char *copy = malloc(strlen(str)+1);
+     if (!copy) {
+-      rp_fatal("strdup failed");
++      fatal("strdup failed");
+     }
+     strcpy(copy, str);
+     return copy;
+@@ -467,9 +465,10 @@ sendPADT(PPPoEConnection *conn, char con
+       fprintf(conn->debugFile, "\n");
+       fflush(conn->debugFile);
+     }
+-    syslog(LOG_INFO,"Sent PADT");
++    info("Sent PADT");
+ }
++#ifdef unused
+ /**********************************************************************
+ *%FUNCTION: parseLogErrs
+ *%ARGUMENTS:
+@@ -501,4 +500,5 @@ parseLogErrs(UINT16_t type, UINT16_t len
+       break;
+     }
+ }
++#endif
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/discovery.c ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/discovery.c   2005-03-11 02:12:52.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c        2005-03-10 12:24:19.000000000 +0100
+@@ -13,10 +13,6 @@ static char const RCSID[] =
+ #include "pppoe.h"
+-#ifdef HAVE_SYSLOG_H
+-#include <syslog.h>
+-#endif
+-
+ #include <string.h>
+ #include <stdlib.h>
+ #include <errno.h>
+@@ -167,24 +163,21 @@ parsePADOTags(UINT16_t type, UINT16_t le
+       if (conn->printACNames) {
+           printf("Got a Service-Name-Error tag: %.*s\n", (int) len, data);
+       } else {
+-          syslog(LOG_ERR, "PADO: Service-Name-Error: %.*s", (int) len, data);
+-          exit(1);
++          fatal("PADO: Service-Name-Error: %.*s", (int) len, data);
+       }
+       break;
+     case TAG_AC_SYSTEM_ERROR:
+       if (conn->printACNames) {
+           printf("Got a System-Error tag: %.*s\n", (int) len, data);
+       } else {
+-          syslog(LOG_ERR, "PADO: System-Error: %.*s", (int) len, data);
+-          exit(1);
++          fatal("PADO: System-Error: %.*s", (int) len, data);
+       }
+       break;
+     case TAG_GENERIC_ERROR:
+       if (conn->printACNames) {
+           printf("Got a Generic-Error tag: %.*s\n", (int) len, data);
+       } else {
+-          syslog(LOG_ERR, "PADO: Generic-Error: %.*s", (int) len, data);
+-          exit(1);
++          fatal("PADO: Generic-Error: %.*s", (int) len, data);
+       }
+       break;
+     }
+@@ -209,20 +202,14 @@ parsePADSTags(UINT16_t type, UINT16_t le
+     PPPoEConnection *conn = (PPPoEConnection *) extra;
+     switch(type) {
+     case TAG_SERVICE_NAME:
+-      syslog(LOG_DEBUG, "PADS: Service-Name: '%.*s'", (int) len, data);
++      dbglog("PADS: Service-Name: '%.*s'", (int) len, data);
+       break;
+     case TAG_SERVICE_NAME_ERROR:
+-      syslog(LOG_ERR, "PADS: Service-Name-Error: %.*s", (int) len, data);
+-      fprintf(stderr, "PADS: Service-Name-Error: %.*s\n", (int) len, data);
+-      exit(1);
++      fatal("PADS: Service-Name-Error: %.*s", (int) len, data);
+     case TAG_AC_SYSTEM_ERROR:
+-      syslog(LOG_ERR, "PADS: System-Error: %.*s", (int) len, data);
+-      fprintf(stderr, "PADS: System-Error: %.*s\n", (int) len, data);
+-      exit(1);
++      fatal("PADS: System-Error: %.*s", (int) len, data);
+     case TAG_GENERIC_ERROR:
+-      syslog(LOG_ERR, "PADS: Generic-Error: %.*s", (int) len, data);
+-      fprintf(stderr, "PADS: Generic-Error: %.*s\n", (int) len, data);
+-      exit(1);
++      fatal("PADS: Generic-Error: %.*s", (int) len, data);
+     case TAG_RELAY_SESSION_ID:
+       conn->relayId.type = htons(type);
+       conn->relayId.length = htons(len);
+@@ -336,7 +323,7 @@ waitForPADO(PPPoEConnection *conn, int t
+               if (r >= 0 || errno != EINTR) break;
+           }
+           if (r < 0) {
+-              fatalSys("select (waitForPADO)");
++              fatal("waitForPADO: select: %m");
+           }
+           if (r == 0) return;        /* Timed out */
+       }
+@@ -346,8 +333,7 @@ waitForPADO(PPPoEConnection *conn, int t
+       /* Check length */
+       if (ntohs(packet.length) + HDR_SIZE > len) {
+-          syslog(LOG_ERR, "Bogus PPPoE length field (%u)",
+-                 (unsigned int) ntohs(packet.length));
++          error("Bogus PPPoE length field (%u)", ntohs(packet.length));
+           continue;
+       }
+@@ -366,16 +352,16 @@ waitForPADO(PPPoEConnection *conn, int t
+       if (packet.code == CODE_PADO) {
+           if (BROADCAST(packet.ethHdr.h_source)) {
+-              printErr("Ignoring PADO packet from broadcast MAC address");
++              error("Ignoring PADO packet from broadcast MAC address");
+               continue;
+           }
+           parsePacket(&packet, parsePADOTags, &pc);
+           if (!pc.seenACName) {
+-              printErr("Ignoring PADO packet with no AC-Name tag");
++              error("Ignoring PADO packet with no AC-Name tag");
+               continue;
+           }
+           if (!pc.seenServiceName) {
+-              printErr("Ignoring PADO packet with no Service-Name tag");
++              error("Ignoring PADO packet with no Service-Name tag");
+               continue;
+           }
+           conn->numPADOs++;
+@@ -513,7 +499,7 @@ waitForPADS(PPPoEConnection *conn, int t
+               if (r >= 0 || errno != EINTR) break;
+           }
+           if (r < 0) {
+-              fatalSys("select (waitForPADS)");
++              fatal("waitForPADS: select: %m");
+           }
+           if (r == 0) return;
+       }
+@@ -523,8 +509,7 @@ waitForPADS(PPPoEConnection *conn, int t
+       /* Check length */
+       if (ntohs(packet.length) + HDR_SIZE > len) {
+-          syslog(LOG_ERR, "Bogus PPPoE length field (%u)",
+-                 (unsigned int) ntohs(packet.length));
++          error("Bogus PPPoE length field (%u)", ntohs(packet.length));
+           continue;
+       }
+@@ -556,11 +541,12 @@ waitForPADS(PPPoEConnection *conn, int t
+     /* Don't bother with ntohs; we'll just end up converting it back... */
+     conn->session = packet.session;
+-    syslog(LOG_INFO, "PPP session is %d", (int) ntohs(conn->session));
++    info("PPP session is %d", ntohs(conn->session));
+     /* RFC 2516 says session id MUST NOT be zero or 0xFFFF */
+     if (ntohs(conn->session) == 0 || ntohs(conn->session) == 0xFFFF) {
+-      syslog(LOG_ERR, "Access concentrator used a session value of %x -- the AC is violating RFC 2516", (unsigned int) ntohs(conn->session));
++      error("Access concentrator used a session value of 0x%x"
++          " -- the AC is violating RFC 2516", ntohs(conn->session));
+     }
+ }
+@@ -620,7 +606,7 @@ discovery(PPPoEConnection *conn)
+     /* If we're only printing access concentrator names, we're done */
+     if (conn->printACNames) {
+-      die(0);
++      exit(0);
+     }
+     timeout = PADI_TIMEOUT;
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/if.c ppp-2.4.3/pppd/plugins/rp-pppoe/if.c
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/if.c  2001-12-14 03:55:20.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/if.c       2005-03-10 13:32:43.000000000 +0100
+@@ -40,10 +40,6 @@ static char const RCSID[] =
+ #include <sys/ioctl.h>
+ #endif
+-#ifdef HAVE_SYSLOG_H
+-#include <syslog.h>
+-#endif
+-
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -127,7 +123,7 @@ etherType(PPPoEPacket *packet)
+ {
+     UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto);
+     if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) {
+-      syslog(LOG_ERR, "Invalid ether type 0x%x", type);
++      error("Invalid ethernet type 0x%x", type);
+     }
+     return type;
+ }
+@@ -156,7 +152,7 @@ getHWaddr(int sock, char const *ifname, 
+     ifc.ifc_len = sizeof(inbuf);
+     ifc.ifc_buf = inbuf;
+     if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
+-      fatalSys("SIOCGIFCONF");
++      fatal("SIOCGIFCONF: %m");
+     }
+     ifr = ifc.ifc_req;
+     ifreq.ifr_name[0] = '\0';
+@@ -172,9 +168,7 @@ getHWaddr(int sock, char const *ifname, 
+               (sdl->sdl_alen == ETH_ALEN) &&
+               !strncmp(ifname, ifr->ifr_name, sizeof(ifr->ifr_name))) {
+               if (found) {
+-                  char buffer[256];
+-                  sprintf(buffer, "interface %.16s has more than one ethernet address", ifname);
+-                  rp_fatal(buffer);
++                  fatal("interface %s has more than one ethernet address", ifname);
+               } else {
+                   found = 1;
+                   memcpy(hwaddr, LLADDR(sdl), ETH_ALEN);
+@@ -183,9 +177,7 @@ getHWaddr(int sock, char const *ifname, 
+       }
+     }
+     if (!found) {
+-      char buffer[256];
+-        sprintf(buffer, "interface %.16s has no ethernet address", ifname);
+-      rp_fatal(buffer);
++        fatal("interface %s has no ethernet address", ifname);
+     }
+ }
+@@ -252,7 +244,7 @@ initFilter(int fd, UINT16_t type, unsign
+       
+       /* Apply the filter */
+       if (ioctl(fd, BIOCSETF, &bpfProgram) < 0) {
+-      fatalSys("ioctl(BIOCSETF)");
++      fatal("ioctl(BIOCSETF): %m");
+       }
+     }
+ }
+@@ -298,42 +290,36 @@ openInterface(char const *ifname, UINT16
+     if (fd < 0) {
+       switch (errno) {
+       case EACCES:            /* permission denied */
+-          {
+-              char buffer[256];
+-              sprintf(buffer, "Cannot open %.32s -- pppoe must be run as root.", bpfName);
+-              rp_fatal(buffer);
+-          }
++          fatal("Cannot open %s -- pppoe must be run as root.", bpfName);
+           break;
+       case EBUSY:
+       case ENOENT:            /* no such file */
+           if (i == 0) {
+-              rp_fatal("No /dev/bpf* devices (check your kernel configuration for BPF support)");
++              fatal("No /dev/bpf* devices (check your kernel configuration for BPF support)");
+           } else {
+-              rp_fatal("All /dev/bpf* devices are in use");
++              fatal("All /dev/bpf* devices are in use");
+           }
+           break;
+       }
+-      fatalSys(bpfName);
++      fatal("%s: %m", bpfName);
+     }
+     if ((sock = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) {
+-      fatalSys("socket");
++      fatal("socket: %m");
+     }
+     /* Check that the interface is up */
+     strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+     if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+-      fatalSys("ioctl(SIOCGIFFLAGS)");
++      fatal("ioctl(SIOCGIFFLAGS): %m");
+     }
+     if ((ifr.ifr_flags & IFF_UP) == 0) {
+-      char buffer[256];
+-      sprintf(buffer, "Interface %.16s is not up\n", ifname);
+-      rp_fatal(buffer);
++      fatal("Interface %s is not up", ifname);
+     }
+     /* Fill in hardware address and initialize the packet filter rules */
+     if (hwaddr == NULL) {
+-      rp_fatal("openInterface: no hwaddr arg.");
++      fatal("openInterface: no hwaddr arg.");
+     }
+     getHWaddr(sock, ifname, hwaddr);
+     initFilter(fd, type, hwaddr);
+@@ -342,58 +328,52 @@ openInterface(char const *ifname, UINT16
+ #if !defined(__OpenBSD__)
+     strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+     if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
+-      fatalSys("ioctl(SIOCGIFMTU)");
++      fatal("ioctl(SIOCGIFMTU): %m");
+     }
+     if (ifr.ifr_mtu < ETH_DATA_LEN) {
+-      char buffer[256];
+-      sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d.  You may have serious connection problems.",
++      error("Interface %s has MTU of %d -- should be %d."
++              "  You may have serious connection problems.",
+               ifname, ifr.ifr_mtu, ETH_DATA_LEN);
+-      printErr(buffer);
+     }
+ #endif
+     /* done with the socket */
+     if (close(sock) < 0) {
+-      fatalSys("close");
++      fatal("close: %m");
+     }
+     /* Check the BPF version number */
+     if (ioctl(fd, BIOCVERSION, &bpf_ver) < 0) {
+-      fatalSys("ioctl(BIOCVERSION)");
++      fatal("ioctl(BIOCVERSION): %m");
+     }
+     if ((bpf_ver.bv_major != BPF_MAJOR_VERSION) ||
+         (bpf_ver.bv_minor < BPF_MINOR_VERSION)) {
+-      char buffer[256];
+-      sprintf(buffer, "Unsupported BPF version: %d.%d (kernel: %d.%d)", 
++      fatal("Unsupported BPF version: %d.%d (kernel: %d.%d)",
+                       BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
+                       bpf_ver.bv_major, bpf_ver.bv_minor);
+-      rp_fatal(buffer);
+     }
+     /* allocate a receive packet buffer */
+     if (ioctl(fd, BIOCGBLEN, &bpfLength) < 0) {
+-      fatalSys("ioctl(BIOCGBLEN)");
++      fatal("ioctl(BIOCGBLEN): %m");
+     }
+     if (!(bpfBuffer = (unsigned char *) malloc(bpfLength))) {
+-      rp_fatal("malloc");
++      fatal("malloc");
+     }
+     /* reads should return as soon as there is a packet available */
+     optval = 1;
+     if (ioctl(fd, BIOCIMMEDIATE, &optval) < 0) {
+-      fatalSys("ioctl(BIOCIMMEDIATE)");
++      fatal("ioctl(BIOCIMMEDIATE): %m");
+     }
+     /* Bind the interface to the filter */
+     strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+     if (ioctl(fd, BIOCSETIF, &ifr) < 0) {
+-      char buffer[256];
+-      sprintf(buffer, "ioctl(BIOCSETIF) can't select interface %.16s",
+-              ifname);
+-      rp_fatal(buffer);
++      fatal("ioctl(BIOCSETIF) can't select interface %s: %m", ifname);
+     }
+-    syslog(LOG_INFO, "Interface=%.16s HWaddr=%02X:%02X:%02X:%02X:%02X:%02X Device=%.32s Buffer size=%d",
++    info("Interface=%s HWaddr=%02X:%02X:%02X:%02X:%02X:%02X Device=%s Buffer size=%d",
+          ifname, 
+          hwaddr[0], hwaddr[1], hwaddr[2],
+          hwaddr[3], hwaddr[4], hwaddr[5],
+@@ -442,48 +422,41 @@ openInterface(char const *ifname, UINT16
+     if ((fd = socket(domain, stype, htons(type))) < 0) {
+       /* Give a more helpful message for the common error case */
+       if (errno == EPERM) {
+-          rp_fatal("Cannot create raw socket -- pppoe must be run as root.");
++          fatal("Cannot create raw socket -- pppoe must be run as root.");
+       }
+-      fatalSys("socket");
++      fatal("cannot create the raw socket: %m");
+     }
+     if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) {
+-      fatalSys("setsockopt");
++      fatal("setsockopt(SOL_SOCKET, SO_BROADCAST): %m");
+     }
+     /* Fill in hardware address */
+     if (hwaddr) {
+       strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+-      if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
+-          fatalSys("ioctl(SIOCGIFHWADDR)");
+-      }
++      if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
++          fatal("ioctl(SIOCGIFHWADDR): %m");
+       memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+ #ifdef ARPHRD_ETHER
+       if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
+-          char buffer[256];
+-          sprintf(buffer, "Interface %.16s is not Ethernet", ifname);
+-          rp_fatal(buffer);
++          fatal("Interface %s is not Ethernet", ifname);
+       }
+ #endif
+       if (NOT_UNICAST(hwaddr)) {
+-          char buffer[256];
+-          sprintf(buffer,
+-                  "Interface %.16s has broadcast/multicast MAC address??",
++          fatal("Interface %s has broadcast/multicast MAC address",
+                   ifname);
+-          rp_fatal(buffer);
+       }
+     }
+     /* Sanity check on MTU */
+     strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+     if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) {
+-      fatalSys("ioctl(SIOCGIFMTU)");
++      fatal("ioctl(SIOCGIFMTU): %m");
+     }
+     if (ifr.ifr_mtu < ETH_DATA_LEN) {
+-      char buffer[256];
+-      sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d.  You may have serious connection problems.",
++      error("Interface %s has MTU of %d -- should be %d."
++              "  You may have serious connection problems.",
+               ifname, ifr.ifr_mtu, ETH_DATA_LEN);
+-      printErr(buffer);
+     }
+ #ifdef HAVE_STRUCT_SOCKADDR_LL
+@@ -493,7 +466,7 @@ openInterface(char const *ifname, UINT16
+     strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+     if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
+-      fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index");
++      fatal("ioctl(SIOCFIGINDEX): Could not get interface index: %m");
+     }
+     sa.sll_ifindex = ifr.ifr_ifindex;
+@@ -503,7 +476,7 @@ openInterface(char const *ifname, UINT16
+     /* We're only interested in packets on specified interface */
+     if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
+-      fatalSys("bind");
++      fatal("bind: %m");
+     }
+     return fd;
+@@ -527,13 +500,11 @@ sendPacket(PPPoEConnection *conn, int so
+ {
+ #if defined(USE_BPF)
+     if (write(sock, pkt, size) < 0) {
+-      sysErr("write (sendPacket)");
+-      return -1;
++      fatal("sendPacket: write: %m");
+     }
+ #elif defined(HAVE_STRUCT_SOCKADDR_LL)
+     if (send(sock, pkt, size, 0) < 0) {
+-      sysErr("send (sendPacket)");
+-      return -1;
++      fatal("sendPacket: send: %m");
+     }
+ #else
+ #ifdef USE_DLPI
+@@ -577,12 +548,11 @@ sendPacket(PPPoEConnection *conn, int so
+     struct sockaddr sa;
+     if (!conn) {
+-      rp_fatal("relay and server not supported on Linux 2.0 kernels");
++      fatal("relay and server not supported on Linux 2.0 kernels");
+     }
+     strcpy(sa.sa_data, conn->ifName);
+     if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) {
+-      sysErr("sendto (sendPacket)");
+-      return -1;
++      fatal("sendPacket: sendto: %m");
+     }
+ #endif
+ #endif
+@@ -632,26 +602,24 @@ receivePacket(int sock, PPPoEPacket *pkt
+     if (bpfSize <= 0) {
+       bpfOffset = 0;
+       if ((bpfSize = read(sock, bpfBuffer, bpfLength)) < 0) {
+-          sysErr("read (receivePacket)");
+-          return -1;
++          fatal("receivePacket: read: %m");
+       }
+     }
+     if (bpfSize < sizeof(hdr)) {
+-      syslog(LOG_ERR, "Truncated bpf packet header: len=%d", bpfSize);
++      error("Truncated bpf packet header: len=%d", bpfSize);
+       clearPacketHeader(pkt);         /* resets bpfSize and bpfOffset */
+       return 0;
+     }
+     memcpy(&hdr, bpfBuffer + bpfOffset, sizeof(hdr));
+     if (hdr.bh_caplen != hdr.bh_datalen) {
+-      syslog(LOG_ERR, "Truncated bpf packet: caplen=%d, datalen=%d",
++      error("Truncated bpf packet: caplen=%d, datalen=%d",
+              hdr.bh_caplen, hdr.bh_datalen);
+       clearPacketHeader(pkt);         /* resets bpfSize and bpfOffset */
+       return 0;
+     }
+     seglen = hdr.bh_hdrlen + hdr.bh_caplen;
+     if (seglen > bpfSize) {
+-      syslog(LOG_ERR, "Truncated bpf packet: seglen=%d, bpfSize=%d",
+-             seglen, bpfSize);
++      error("Truncated bpf packet: seglen=%d, bpfSize=%d", seglen, bpfSize);
+       clearPacketHeader(pkt);         /* resets bpfSize and bpfOffset */
+       return 0;
+     }
+@@ -676,16 +644,14 @@ receivePacket(int sock, PPPoEPacket *pkt
+       data.len = 0; 
+       
+       if ((retval = getmsg(sock, NULL, &data, &flags)) < 0) {
+-          sysErr("read (receivePacket)");
+-          return -1;
++          fatal("receivePacket: getmsg: %m");
+       }
+       *size = data.len; 
+ #else
+     if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) {
+-      sysErr("recv (receivePacket)");
+-      return -1;
++      fatal("receivePacket: recv: %m");
+     }
+ #endif
+ #endif
+@@ -716,7 +682,7 @@ openInterface(char const *ifname, UINT16
+     int ppa; 
+     if(strlen(ifname) > PATH_MAX) {
+-      rp_fatal("socket: string to long"); 
++      fatal("openInterface: interface name too long");
+     }
+     ppa = atoi(&ifname[strlen(ifname)-1]);
+@@ -729,9 +695,9 @@ openInterface(char const *ifname, UINT16
+     if (( fd = open(base_dev, O_RDWR)) < 0) {
+       /* Give a more helpful message for the common error case */
+       if (errno == EPERM) {
+-          rp_fatal("Cannot create raw socket -- pppoe must be run as root.");
++          fatal("Cannot create raw socket -- pppoe must be run as root.");
+       }
+-      fatalSys("socket");
++      fatal("open(%s): %m", base_dev);
+     }
+ /* rearranged order of DLPI code - delphys 20010803 */
+@@ -747,17 +713,18 @@ openInterface(char const *ifname, UINT16
+     dl_abssaplen = ABS(dlp->info_ack.dl_sap_length);
+     dl_saplen = dlp->info_ack.dl_sap_length;
+     if (ETHERADDRL != (dlp->info_ack.dl_addr_length - dl_abssaplen))
+-      fatalSys("invalid destination physical address length");
++      fatal("invalid destination physical address length");
+     dl_addrlen = dl_abssaplen + ETHERADDRL;
+ /* ethernet address retrieved as part of DL_INFO_ACK - delphys 20010803 */
+     memcpy(hwaddr, (u_char*)((char*)(dlp) + (int)(dlp->info_ack.dl_addr_offset)), ETHERADDRL);
+     if ( strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0 ) { 
+-      fatalSys("DLIOCRAW"); 
++      fatal("DLIOCRAW: %m");
+     }
+-    if (ioctl(fd, I_FLUSH, FLUSHR) < 0) fatalSys("I_FLUSH");
++    if (ioctl(fd, I_FLUSH, FLUSHR) < 0)
++      fatal("I_FLUSH: %m");
+     return fd;
+ }
+@@ -780,7 +747,7 @@ void dlpromisconreq(int fd, u_long level
+         flags = 0;
+         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+-                fatalSys("dlpromiscon:  putmsg");
++                fatal("dlpromiscon: putmsg: %m");
+ }
+@@ -799,7 +766,7 @@ void dlinforeq(int fd)
+         flags = RS_HIPRI;
+         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+-                fatalSys("dlinforeq:  putmsg");
++                fatal("dlinforeq: putmsg: %m");
+ }
+ void dlunitdatareq(int fd, u_char *addrp, int addrlen, u_long minpri, u_long maxpri, u_char *datap, int datalen)
+@@ -827,7 +794,7 @@ void dlunitdatareq(int fd, u_char *addrp
+         data.buf = (char *) datap;
+         if (putmsg(fd, &ctl, &data, 0) < 0)
+-                fatalSys("dlunitdatareq:  putmsg");
++                fatal("dlunitdatareq: putmsg: %m");
+ }
+ void dlinfoack(int fd, char *bufp)
+@@ -847,18 +814,14 @@ void dlinfoack(int fd, char *bufp)
+         expecting(DL_INFO_ACK, dlp);
+         if (ctl.len < sizeof (dl_info_ack_t)) {
+-              char buffer[256];
+-              sprintf(buffer, "dlinfoack:  response ctl.len too short:  %d", ctl.len); 
+-                rp_fatal(buffer); 
++              fatal("dlinfoack: response ctl.len too short: %d", ctl.len);
+       }
+         if (flags != RS_HIPRI)
+-                rp_fatal("dlinfoack:  DL_INFO_ACK was not M_PCPROTO");
++                fatal("dlinfoack: DL_INFO_ACK was not M_PCPROTO");
+         if (ctl.len < sizeof (dl_info_ack_t)) {
+-              char buffer[256];
+-              sprintf(buffer, "dlinfoack:  short response ctl.len:  %d", ctl.len); 
+-              rp_fatal(buffer); 
++              fatal("dlinfoack: short response ctl.len: %d", ctl.len);
+       }
+ }
+@@ -882,7 +845,7 @@ void dlbindreq(int fd, u_long sap, u_lon
+         flags = 0;
+         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+-                fatalSys("dlbindreq:  putmsg");
++                fatal("dlbindreq: putmsg: %m");
+ }
+ void dlattachreq(int fd, u_long ppa)
+@@ -901,7 +864,7 @@ void dlattachreq(int fd, u_long ppa)
+         flags = 0;
+         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
+-                fatalSys("dlattachreq:  putmsg");
++                fatal("dlattachreq: putmsg: %m");
+ }
+ void dlokack(int fd, char *bufp)
+@@ -921,18 +884,14 @@ void dlokack(int fd, char *bufp)
+         expecting(DL_OK_ACK, dlp);
+         if (ctl.len < sizeof (dl_ok_ack_t)) { 
+-              char buffer[256];
+-              sprintf(buffer, "dlokack:  response ctl.len too short:  %d", ctl.len);
+-              rp_fatal(buffer); 
++              fatal("dlokack: response ctl.len too short: %d", ctl.len);
+       }
+         if (flags != RS_HIPRI)
+-                rp_fatal("dlokack:  DL_OK_ACK was not M_PCPROTO");
++                fatal("dlokack: DL_OK_ACK was not M_PCPROTO");
+         if (ctl.len < sizeof (dl_ok_ack_t)) {
+-              char buffer[256]; 
+-              sprintf(buffer, "dlokack:  short response ctl.len:  %d", ctl.len);
+-              rp_fatal(buffer); 
++              fatal("dlokack: short response ctl.len: %d", ctl.len);
+       }
+ }
+@@ -953,12 +912,10 @@ void dlbindack(int fd, char *bufp)
+         expecting(DL_BIND_ACK, dlp);
+         if (flags != RS_HIPRI)
+-                rp_fatal("dlbindack:  DL_OK_ACK was not M_PCPROTO");
++                fatal("dlbindack: DL_OK_ACK was not M_PCPROTO");
+         if (ctl.len < sizeof (dl_bind_ack_t)) {
+-              char buffer[256];
+-              sprintf(buffer, "dlbindack:  short response ctl.len:  %d", ctl.len);
+-              rp_fatal(buffer); 
++              fatal("dlbindack: short response ctl.len: %d", ctl.len);
+       }
+ }
+@@ -989,8 +946,7 @@ void strgetmsg(int fd, struct strbuf *ct
+          */
+         (void) signal(SIGALRM, sigalrm);
+         if (alarm(MAXWAIT) < 0) {
+-                (void) sprintf(errmsg, "%s:  alarm", caller);
+-                fatalSys(errmsg);
++                fatal("%s: alarm", caller);
+         }
+         /*
+@@ -998,61 +954,48 @@ void strgetmsg(int fd, struct strbuf *ct
+          */
+         *flagsp = 0;
+         if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {
+-                (void) sprintf(errmsg, "%s:  getmsg", caller);
+-                fatalSys(errmsg);
++                fatal(errmsg, "%s: getmsg: %m", caller);
+         }
+         /*
+          * Stop timer.
+          */
+         if (alarm(0) < 0) {
+-                (void) sprintf(errmsg, "%s:  alarm", caller);
+-                fatalSys(errmsg);
++                fatal("%s: alarm", caller);
+         }
+         /*
+          * Check for MOREDATA and/or MORECTL.
+          */
+         if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) {
+-              char buffer[256]; 
+-              sprintf(buffer, "%s:  MORECTL|MOREDATA", caller);
+-              rp_fatal(buffer);
++              fatal("%s: MORECTL|MOREDATA", caller);
+       }
+                 
+         if (rc & MORECTL) {
+-              char buffer[256];
+-              sprintf(buffer, "%s:  MORECTL", caller);
+-              rp_fatal(buffer); 
++              fatal("%s: MORECTL", caller);
+       }
+         
+         if (rc & MOREDATA) {
+-              char buffer[256]; 
+-              sprintf(buffer, "%s:  MOREDATA", caller);
+-              rp_fatal(buffer);
++              fatal("%s: MOREDATA", caller);
+       }
+         /*
+          * Check for at least sizeof (long) control data portion.
+          */
+         if (ctlp->len < sizeof (long)) {
+-              char buffer[256]; 
+-              sprintf(buffer, "getmsg:  control portion length < sizeof (long):  %d", ctlp->len);
+-              rp_fatal(buffer); 
++              fatal("getmsg: control portion length < sizeof (long): %d", ctlp->len);
+       }
+ }
+ void sigalrm(int sig)
+ {
+-        (void) rp_fatal("sigalrm:  TIMEOUT");
++        fatal("sigalrm: TIMEOUT");
+ }
+ void expecting(int prim, union DL_primitives *dlp)
+ {
+         if (dlp->dl_primitive != (u_long)prim) {
+-              char buffer[256]; 
+-              sprintf(buffer, "expected %s got %s", dlprim(prim), dlprim(dlp->dl_primitive));
+-              rp_fatal(buffer); 
+-              exit(1); 
++              fatal("expected %s got %s", dlprim(prim), dlprim(dlp->dl_primitive));
+       }
+ }
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/Makefile.linux ppp-2.4.3/pppd/plugins/rp-pppoe/Makefile.linux
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/Makefile.linux        2004-11-14 08:58:37.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/Makefile.linux     2005-03-11 01:48:27.000000000 +0100
+@@ -28,8 +28,8 @@ COPTS=-O2 -g
+ CFLAGS=$(COPTS) -I../../../include/linux
+ all: rp-pppoe.so pppoe-discovery
+-pppoe-discovery: libplugin.a pppoe-discovery.o
+-      $(CC) -o pppoe-discovery pppoe-discovery.o libplugin.a
++pppoe-discovery: pppoe-discovery.o utils.o libplugin.a
++      $(CC) -o pppoe-discovery pppoe-discovery.o utils.o libplugin.a
+ pppoe-discovery.o: pppoe-discovery.c
+       $(CC) $(CFLAGS) '-DVERSION="$(VERSION)"' -c -o pppoe-discovery.o pppoe-discovery.c
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.3/pppd/plugins/rp-pppoe/plugin.c
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/plugin.c      2004-11-04 11:07:37.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/plugin.c   2005-03-11 02:12:39.000000000 +0100
+@@ -35,7 +35,6 @@ static char const RCSID[] =
+ #include "pppd/pathnames.h"
+ #include <linux/types.h>
+-#include <syslog.h>
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+@@ -173,10 +172,8 @@ PPPOEConnectDevice(void)
+           (unsigned) conn->peerEth[5]);
+     if (connect(conn->sessionSocket, (struct sockaddr *) &sp,
+-              sizeof(struct sockaddr_pppox)) < 0) {
++              sizeof(struct sockaddr_pppox)) < 0)
+       fatal("Failed to connect PPPoE socket: %d %m", errno);
+-      return -1;
+-    }
+     return conn->sessionSocket;
+ }
+@@ -365,11 +362,9 @@ plugin_init(void)
+     }
+     add_options(Options);
+-
+-    info("RP-PPPoE plugin version %s compiled against pppd %s",
+-       RP_VERSION, VERSION);
+ }
++#ifdef unused
+ /**********************************************************************
+ *%FUNCTION: fatalSys
+ *%ARGUMENTS:
+@@ -423,6 +418,7 @@ sysErr(char const *str)
+ {
+     rp_fatal(str);
+ }
++#endif
+ struct channel pppoe_channel = {
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/pppoe-discovery.c ppp-2.4.3/pppd/plugins/rp-pppoe/pppoe-discovery.c
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/pppoe-discovery.c     2004-11-13 13:12:05.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/pppoe-discovery.c  2005-03-11 02:06:13.000000000 +0100
+@@ -17,14 +17,8 @@
+ #include "pppoe.h"
+-char *xstrdup(const char *s);
+ void usage(void);
+-void die(int status)
+-{
+-      exit(status);
+-}
+-
+ int main(int argc, char *argv[])
+ {
+     int opt;
+@@ -32,17 +26,17 @@ int main(int argc, char *argv[])
+     conn = malloc(sizeof(PPPoEConnection));
+     if (!conn)
+-      fatalSys("malloc");
++      fatal("malloc");
+     memset(conn, 0, sizeof(PPPoEConnection));
+     while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) {
+       switch(opt) {
+       case 'S':
+-          conn->serviceName = xstrdup(optarg);
++          conn->serviceName = strDup(optarg);
+           break;
+       case 'C':
+-          conn->acName = xstrdup(optarg);
++          conn->acName = strDup(optarg);
+           break;
+       case 'U':
+           conn->useHostUniq = 1;
+@@ -57,7 +51,7 @@ int main(int argc, char *argv[])
+           fprintf(conn->debugFile, "pppoe-discovery %s\n", VERSION);
+           break;
+       case 'I':
+-          conn->ifName = xstrdup(optarg);
++          conn->ifName = strDup(optarg);
+           break;
+       case 'A':
+           /* this is the default */
+@@ -74,7 +68,7 @@ int main(int argc, char *argv[])
+     /* default interface name */
+     if (!conn->ifName)
+-      conn->ifName = strdup("eth0");
++      conn->ifName = strDup("eth0");
+     conn->discoverySocket = -1;
+     conn->sessionSocket = -1;
+@@ -84,39 +78,6 @@ int main(int argc, char *argv[])
+     exit(0);
+ }
+-void rp_fatal(char const *str)
+-{
+-    char buf[1024];
+-
+-    printErr(str);
+-    sprintf(buf, "pppoe-discovery: %.256s", str);
+-    exit(1);
+-}
+-
+-void fatalSys(char const *str)
+-{
+-    char buf[1024];
+-    int i = errno;
+-
+-    sprintf(buf, "%.256s: %.256s", str, strerror(i));
+-    printErr(buf);
+-    sprintf(buf, "pppoe-discovery: %.256s: %.256s", str, strerror(i));
+-    exit(1);
+-}
+-
+-void sysErr(char const *str)
+-{
+-    rp_fatal(str);
+-}
+-
+-char *xstrdup(const char *s)
+-{
+-    register char *ret = strdup(s);
+-    if (!ret)
+-      sysErr("strdup");
+-    return ret;
+-}
+-
+ void usage(void)
+ {
+     fprintf(stderr, "Usage: pppoe-discovery [options]\n");
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/pppoe.h ppp-2.4.3/pppd/plugins/rp-pppoe/pppoe.h
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/pppoe.h       2004-11-04 11:07:37.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/pppoe.h    2005-03-11 02:08:00.000000000 +0100
+@@ -307,12 +307,18 @@ void discovery(PPPoEConnection *conn);
+ unsigned char *findTag(PPPoEPacket *packet, UINT16_t tagType,
+                      PPPoETag *tag);
++void dbglog(char *, ...);     /* log a debug message */
++void info(char *, ...);               /* log an informational message */
++void warn(char *, ...);               /* log a warning message */
++void error(char *, ...);      /* log an error message */
++void fatal(char *, ...);      /* log an error message and die(1) */
++
+ #define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
+ #define CHECK_ROOM(cursor, start, len) \
+ do {\
+     if (((cursor)-(start))+(len) > MAX_PPPOE_PAYLOAD) { \
+-        syslog(LOG_ERR, "Would create too-long packet"); \
++        error("Would create too-long packet"); \
+         return; \
+     } \
+ } while(0)
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/utils.c ppp-2.4.3/pppd/plugins/rp-pppoe/utils.c
+--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/utils.c       1970-01-01 01:00:00.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/rp-pppoe/utils.c    2005-03-11 02:07:57.000000000 +0100
+@@ -0,0 +1,62 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <stdarg.h>
++#include <syslog.h>
++
++void dbglog(const char *fmt, ...)
++{
++    va_list ap;
++
++    va_start(ap, fmt);
++    vsyslog(LOG_DEBUG, fmt, ap);
++    vfprintf(stderr, fmt, ap);
++    fputs("\n", stderr);
++    va_end(ap);
++}
++
++void info(const char *fmt, ...)
++{
++    va_list ap;
++
++    va_start(ap, fmt);
++    vsyslog(LOG_INFO, fmt, ap);
++    vfprintf(stderr, fmt, ap);
++    fputs("\n", stderr);
++    va_end(ap);
++}
++
++void warn(const char *fmt, ...)
++{
++    va_list ap;
++
++    va_start(ap, fmt);
++    vsyslog(LOG_WARNING, fmt, ap);
++    vfprintf(stderr, fmt, ap);
++    fputs("\n", stderr);
++    va_end(ap);
++}
++
++void error(const char *fmt, ...)
++{
++    va_list ap;
++
++    va_start(ap, fmt);
++    vsyslog(LOG_ERR, fmt, ap);
++    vfprintf(stderr, fmt, ap);
++    fputs("\n", stderr);
++    va_end(ap);
++}
++
++void fatal(const char *fmt, ...)
++{
++    va_list ap;
++
++    va_start(ap, fmt);
++    vsyslog(LOG_ERR, fmt, ap);
++    vfprintf(stderr, fmt, ap);
++    fputs("\n", stderr);
++    va_end(ap);
++    exit(1);
++}
++
diff --git a/openwrt/package/ppp/patches/104-debian_fix_linkpidfile.patch b/openwrt/package/ppp/patches/104-debian_fix_linkpidfile.patch
new file mode 100644 (file)
index 0000000..9e32adc
--- /dev/null
@@ -0,0 +1,43 @@
+Subject: Bug#284382: ppp: linkpidfile is not created upon detachment
+From: <herbert@gondor.apana.org.au>
+
+Package: ppp
+Version: 2.4.2+20040428-2
+Severity: wishlist
+
+When pppd detaches from the parent normally, that is, without nodetach
+or updetach set, the linkpidfile is not created even when linkname is
+set.
+
+This is because the create_linkpidfile call in detach() is only made
+if the linkpidfile is filled in.  However, linkpidfile is never filled
+in until create_linkpidfile has been called.
+
+IMHO the call should be made uncondtionally in detach() since
+create_linkpidfile does its own check on linkname anyway.
+
+Please note that the version of pppd in woody always wrote the
+linkpidfile after detaching.  It did so in main() however.  That
+call has now been removed which is why I'm seeing this problem.
+
+[...]
+
+--
+Index: pppd/main.c
+===================================================================
+RCS file: /var/cvs/snwb/packages/ppp/pppd/main.c,v
+retrieving revision 1.11
+diff -u -r1.11 main.c
+--- ppp/pppd/main.c    29 Nov 2004 22:49:23 -0000      1.11
++++ ppp/pppd/main.c    5 Dec 2004 23:59:58 -0000
+@@ -819,8 +819,7 @@
+       /* update pid files if they have been written already */
+       if (pidfilename[0])
+           create_pidfile(pid);
+-      if (linkpidfile[0])
+-          create_linkpidfile(pid);
++      create_linkpidfile(pid);
+       exit(0);                /* parent dies */
+     }
+     setsid();
+
diff --git a/openwrt/package/ppp/patches/105-debian_pppoatm_cleanup.patch b/openwrt/package/ppp/patches/105-debian_pppoatm_cleanup.patch
new file mode 100644 (file)
index 0000000..2437a12
--- /dev/null
@@ -0,0 +1,95 @@
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c
+--- ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c      2005-03-22 14:44:18.000000000 +0100
++++ ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c   2005-03-22 14:44:02.000000000 +0100
+@@ -70,18 +70,20 @@ static int setdevname_pppoatm(const char
+ {
+       struct sockaddr_atmpvc addr;
+       extern struct stat devstat;
++
+       if (device_got_set)
+               return 0;
+-      //info("PPPoATM setdevname_pppoatm: '%s'", cp);
++
+       memset(&addr, 0, sizeof addr);
+       if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr),
+           T2A_PVC | T2A_NAME) < 0) {
+-               if(doit)
+-                   info("atm does not recognize: %s", cp);
++              if (doit)
++                      info("cannot parse the ATM address: %s", cp);
+               return 0;
+-           }
+-      if (!doit) return 1;
+-      //if (!dev_set_ok()) return -1;
++      }
++      if (!doit)
++              return 1;
++
+       memcpy(&pvcaddr, &addr, sizeof pvcaddr);
+       strlcpy(devnam, cp, sizeof devnam);
+       devstat.st_mode = S_IFSOCK;
+@@ -93,7 +95,6 @@ static int setdevname_pppoatm(const char
+               lcp_allowoptions[0].neg_asyncmap = 0;
+               lcp_wantoptions[0].neg_pcompression = 0;
+       }
+-      info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp);
+       device_got_set = 1;
+       return 1;
+ }
+@@ -108,6 +109,7 @@ static void no_device_given_pppoatm(void
+ static void set_line_discipline_pppoatm(int fd)
+ {
+       struct atm_backend_ppp be;
++
+       be.backend_num = ATM_BACKEND_PPP;
+       if (!llc_encaps)
+               be.encaps = PPPOATM_ENCAPS_VC;
+@@ -115,6 +117,7 @@ static void set_line_discipline_pppoatm(
+               be.encaps = PPPOATM_ENCAPS_LLC;
+       else
+               be.encaps = PPPOATM_ENCAPS_AUTODETECT;
++
+       if (ioctl(fd, ATM_SETBACKEND, &be) < 0)
+               fatal("ioctl(ATM_SETBACKEND): %m");
+ }
+@@ -179,16 +182,19 @@ static void send_config_pppoa(int mtu,
+ {
+       int sock;
+       struct ifreq ifr;
++
+       if (mtu > pppoatm_max_mtu)
+               error("Couldn't increase MTU to %d", mtu);
++
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock < 0)
+               fatal("Couldn't create IP socket: %m");
++
+       strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+       ifr.ifr_mtu = mtu;
+       if (ioctl(sock, SIOCSIFMTU, (caddr_t) &ifr) < 0)
+               fatal("ioctl(SIOCSIFMTU): %m");
+-      (void) close (sock);
++      close(sock);
+ }
+ static void recv_config_pppoa(int mru,
+@@ -202,7 +208,7 @@ static void recv_config_pppoa(int mru,
+ void plugin_init(void)
+ {
+-#if defined(__linux__)
++#ifdef linux
+       extern int new_style_driver;    /* From sys-linux.c */
+       if (!ppp_available() && !new_style_driver)
+               fatal("Kernel doesn't support ppp_generic - "
+@@ -210,9 +216,9 @@ void plugin_init(void)
+ #else
+       fatal("No PPPoATM support on this OS");
+ #endif
+-      info("PPPoATM plugin_init");
+       add_options(pppoa_options);
+ }
++
+ struct channel pppoa_channel = {
+     options: pppoa_options,
+     process_extra_options: NULL,
diff --git a/openwrt/package/ppp/patches/106-debian_pppoatm_fix_mtu.patch b/openwrt/package/ppp/patches/106-debian_pppoatm_fix_mtu.patch
new file mode 100644 (file)
index 0000000..ef28b5c
--- /dev/null
@@ -0,0 +1,31 @@
+diff -ruNp ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c
+--- ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c      2005-05-04 02:00:28.000000000 +0200
++++ ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c   2005-05-04 01:59:11.000000000 +0200
+@@ -183,8 +183,11 @@ static void send_config_pppoa(int mtu,
+       int sock;
+       struct ifreq ifr;
+-      if (mtu > pppoatm_max_mtu)
+-              error("Couldn't increase MTU to %d", mtu);
++      if (pppoatm_max_mtu && mtu > pppoatm_max_mtu) {
++              warn("Couldn't increase MTU to %d. Using %d",
++                      mtu, pppoatm_max_mtu);
++              mtu = pppoatm_max_mtu;
++      }
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock < 0)
+@@ -202,8 +205,11 @@ static void recv_config_pppoa(int mru,
+                             int pcomp,
+                             int accomp)
+ {
+-      if (mru > pppoatm_max_mru)
+-              error("Couldn't increase MRU to %d", mru);
++      if (pppoatm_max_mru && mru > pppoatm_max_mru) {
++              warn("Couldn't increase MRU to %d. Using %d",
++                      mru, pppoatm_max_mru);
++              mru = pppoatm_max_mru;
++      }
+ }
+ void plugin_init(void)
diff --git a/openwrt/package/ppp/patches/107-debian_stripMSdomain.patch b/openwrt/package/ppp/patches/107-debian_stripMSdomain.patch
new file mode 100644 (file)
index 0000000..d52e386
--- /dev/null
@@ -0,0 +1,35 @@
+diff -ruN ppp.orig/pppd/chap-new.c ppp/pppd/chap-new.c
+--- ppp.orig/pppd/chap-new.c   2003-11-27 23:25:17.000000000 +0100
++++ ppp/pppd/chap-new.c        2003-12-02 12:26:21.000000000 +0100
+@@ -57,6 +57,7 @@
+ int chap_timeout_time = 3;
+ int chap_max_transmits = 10;
+ int chap_rechallenge_time = 0;
++int chapms_strip_domain = 0;
+ /*
+  * Command-line options.
+@@ -68,6 +69,8 @@
+         "Set max #xmits for challenge", OPT_PRIO },
+       { "chap-interval", o_int, &chap_rechallenge_time,
+         "Set interval for rechallenge", OPT_PRIO },
++      { "chapms-strip-domain", o_bool, &chapms_strip_domain,
++        "Strip the domain prefix before the Username", 1 },
+       { NULL }
+ };
+@@ -338,6 +341,14 @@
+                       /* Null terminate and clean remote name. */
+                       slprintf(rname, sizeof(rname), "%.*v", len, name);
+                       name = rname;
++
++                      /* strip the MS domain name */
++                      if (chapms_strip_domain && strrchr(rname, '\\')) {
++                              char tmp[MAXNAMELEN+1];
++
++                              strcpy(tmp, strrchr(rname, '\\') + 1);
++                              strcpy(rname, tmp);
++                      }
+               }
+               if (chap_verify_hook)
diff --git a/openwrt/package/ppp/patches/108-debian_defaultroute.patch b/openwrt/package/ppp/patches/108-debian_defaultroute.patch
new file mode 100644 (file)
index 0000000..76b444e
--- /dev/null
@@ -0,0 +1,253 @@
+--- ppp/pppd/ipcp.c    Wed May 31 17:20:41 2000
++++ ppp/pppd/ipcp.c    Wed May 31 17:27:19 2000
+@@ -145,7 +145,17 @@
+     { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
+       "disable defaultroute option", OPT_A2COPY,
+       &ipcp_wantoptions[0].default_route },
+
++#ifdef __linux__
++    { "replacedefaultroute", o_bool,
++                              &ipcp_wantoptions[0].replace_default_route,
++      "Replace default route", 1
++    },
++    { "noreplacedefaultroute", o_bool,
++                              &ipcp_allowoptions[0].replace_default_route,
++      "Never replace default route", OPT_A2COPY,
++                              &ipcp_wantoptions[0].replace_default_route },
++#endif
+     { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
+       "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
+     { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
+@@ -195,7 +205,7 @@
+     ip_active_pkt
+ };
+-static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
++static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool));
+ static void ipcp_script __P((char *));                /* Run an up/down script */
+ static void ipcp_script_done __P((void *));
+@@ -1344,7 +1354,12 @@
+     if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
+       return 0;
+     if (wo->default_route)
++#ifndef __linux__
+       if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
++#else
++      if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
++                                          wo->replace_default_route))
++#endif
+           default_route_set[u] = 1;
+     if (wo->proxy_arp)
+       if (sifproxyarp(u, wo->hisaddr))
+@@ -1420,7 +1435,8 @@
+      */
+     if (demand) {
+       if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
+-          ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
++          ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
++                                    wo->replace_default_route);
+           if (go->ouraddr != wo->ouraddr) {
+               warn("Local IP address changed to %I", go->ouraddr);
+               script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr));
+@@ -1445,7 +1461,12 @@
+           /* assign a default route through the interface if required */
+           if (ipcp_wantoptions[f->unit].default_route) 
++#ifndef __linux__
+               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
++#else
++              if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
++                                           wo->replace_default_route))
++#endif
+                   default_route_set[f->unit] = 1;
+           /* Make a proxy ARP entry if requested. */
+@@ -1492,7 +1513,12 @@
+       /* assign a default route through the interface if required */
+       if (ipcp_wantoptions[f->unit].default_route) 
++#ifndef __linux__
+           if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
++#else
++          if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
++                                       wo->replace_default_route))
++#endif
+               default_route_set[f->unit] = 1;
+       /* Make a proxy ARP entry if requested. */
+@@ -1559,7 +1585,7 @@
+       sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
+       sifdown(f->unit);
+       ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
+-                       ipcp_hisoptions[f->unit].hisaddr);
++                       ipcp_hisoptions[f->unit].hisaddr, 0);
+     }
+     /* Execute the ip-down script */
+@@ -1575,16 +1601,25 @@
+  * proxy arp entries, etc.
+  */
+ static void
+-ipcp_clear_addrs(unit, ouraddr, hisaddr)
++ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute)
+     int unit;
+     u_int32_t ouraddr;  /* local address */
+     u_int32_t hisaddr;  /* remote address */
++    bool replacedefaultroute;
+ {
+     if (proxy_arp_set[unit]) {
+       cifproxyarp(unit, hisaddr);
+       proxy_arp_set[unit] = 0;
+     }
+-    if (default_route_set[unit]) {
++    /* If replacedefaultroute, sifdefaultroute will be called soon
++     * with replacedefaultroute set and that will overwrite the current
++     * default route. This is the case only when doing demand, otherwise
++     * during demand, this cifdefaultroute would restore the old default
++     * route which is not what we want in this case. In the non-demand
++     * case, we'll delete the default route and restore the old if there
++     * is one saved by an sifdefaultroute with replacedefaultroute.
++     */
++    if (!replacedefaultroute && default_route_set[unit]) {
+       cifdefaultroute(unit, ouraddr, hisaddr);
+       default_route_set[unit] = 0;
+     }
+--- ppp/pppd/ipcp.h    Wed May 31 17:20:41 2000
++++ ppp/pppd/ipcp.h    Wed May 31 15:56:17 2000
+@@ -47,6 +47,7 @@
+     bool old_addrs;           /* Use old (IP-Addresses) option? */
+     bool req_addr;            /* Ask peer to send IP address? */
+     bool default_route;               /* Assign default route through interface? */
++    bool replace_default_route;       /* Replace default route through interface? */
+     bool proxy_arp;           /* Make proxy ARP entry for peer? */
+     bool neg_vj;              /* Van Jacobson Compression? */
+     bool old_vj;              /* use old (short) form of VJ option? */
+--- ppp/pppd/pppd.h    Wed May 31 17:20:41 2000
++++ ppp/pppd/pppd.h    Wed May 31 15:56:17 2000
+@@ -416,7 +416,11 @@
+ int  cif6addr __P((int, eui64_t, eui64_t));
+                               /* Remove an IPv6 address from i/f */
+ #endif
++#ifndef __linux__
+ int  sifdefaultroute __P((int, u_int32_t, u_int32_t));
++#else
++int  sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt));
++#endif
+                               /* Create default route through i/f */
+ int  cifdefaultroute __P((int, u_int32_t, u_int32_t));
+                               /* Delete default route through i/f */
+--- ppp/pppd/sys-linux.c       Wed May 31 17:20:41 2000
++++ ppp/pppd/sys-linux.c       Wed May 31 17:37:23 2000
+@@ -143,6 +143,8 @@
+ static int    if_is_up;       /* Interface has been marked up */
+ static u_int32_t default_route_gateway;       /* Gateway for default route added */
++static struct rtentry old_def_rt;       /* Old default route */
++static int       default_rt_repl_rest;  /* replace and restore old default rt */
+ static u_int32_t proxy_arp_addr;      /* Addr for proxy arp entry added */
+ static char proxy_arp_dev[16];                /* Device for proxy arp entry */
+ static u_int32_t our_old_addr;                /* for detecting address changes */
+@@ -1209,6 +1211,9 @@
+       p = NULL;
+     }
++    SET_SA_FAMILY (rt->rt_dst,     AF_INET);
++    SET_SA_FAMILY (rt->rt_gateway, AF_INET);
++
+     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
+     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
+     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
+@@ -1278,19 +1283,53 @@
+ /********************************************************************
+  *
+  * sifdefaultroute - assign a default route through the address given.
++ *
++ * If the global default_rt_repl_rest flag is set, then this function
++ * already replaced the original system defaultroute with some other
++ * route and it should just replace the current defaultroute with
++ * another one, without saving the current route. Use: demand mode,
++ * when pppd sets first a defaultroute it it's temporary ppp0 addresses
++ * and then changes the temporary addresses to the addresses for the real
++ * ppp connection when it has come up.
+  */
+-int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
++int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
+ {
+-    struct rtentry rt;
+-
+-    if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
+-      u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
++    struct rtentry rt, tmp_rt;
++    struct rtentry *del_rt = NULL;
+-      if (old_gateway != gateway)
+-          error("not replacing existing default route to %s [%I]",
+-                rt.rt_dev, old_gateway);
+-      return 0;
++    
++    if (default_rt_repl_rest) {
++      /* We have already reclaced the original defaultroute, if we
++         * are called again, we will delete the current default route
++         * and set the new default route in this function.  
++         * - this is normally only the case the doing demand: */
++      if (defaultroute_exists( &tmp_rt ))
++              del_rt = &tmp_rt;
++    } else if ( defaultroute_exists( &old_def_rt                ) &&
++                           strcmp(  old_def_rt.rt_dev, ifname ) != 0) {
++      /* We did not yet replace an existing default route, let's
++       * check if we should save and replace a default route:
++         */
++      u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
++
++      if (old_gateway != gateway) {
++          if (!replace) {
++              error("not replacing default route to %s [%I]",
++                      old_def_rt.rt_dev, old_gateway);
++              return 0;
++          } else {
++              // we need to copy rt_dev because we need it permanent too:
++              char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
++              strcpy(tmp_dev, old_def_rt.rt_dev);
++              old_def_rt.rt_dev = tmp_dev;
++
++              notice("replacing old default route to %s [%I]",
++                      old_def_rt.rt_dev, old_gateway);
++              default_rt_repl_rest = 1;
++              del_rt = &old_def_rt;
++          }
++      }
+     }
+     memset (&rt, '\0', sizeof (rt));
+@@ -1310,6 +1349,12 @@
+           error("default route ioctl(SIOCADDRT): %m(%d)", errno);
+       return 0;
+     }
++    if (default_rt_repl_rest && del_rt)
++        if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
++          if ( ! ok_error ( errno ))
++              error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
++          return 0;
++        }
+     default_route_gateway = gateway;
+     return 1;
+@@ -1344,6 +1389,16 @@
+               error("default route ioctl(SIOCDELRT): %m (%d)", errno);
+           return 0;
+       }
++    }
++    if (default_rt_repl_rest) {
++      notice("restoring old default route to %s [%I]",
++                      old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
++        if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
++          if ( ! ok_error ( errno ))
++              error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
++          return 0;
++        }
++        default_rt_repl_rest = 0;
+     }
+     return 1;
diff --git a/openwrt/package/ppp/patches/109-debian_demand.patch b/openwrt/package/ppp/patches/109-debian_demand.patch
new file mode 100644 (file)
index 0000000..e024696
--- /dev/null
@@ -0,0 +1,172 @@
+--- ppp/pppd/demand.c
++++ ppp/pppd/demand.c  2000/06/28 14:54:04
+@@ -25,6 +25,8 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <netdb.h>
++#include <unistd.h>
++#include <syslog.h>
+ #include <sys/param.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+@@ -32,6 +34,8 @@
+ #include <sys/resource.h>
+ #include <sys/stat.h>
+ #include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
+ #ifdef PPP_FILTER
+ #include <net/if.h>
+ #include <net/bpf.h>
+@@ -210,6 +214,14 @@
+     int c, rv;
+     rv = 0;
++
++/* check for synchronous connection... */
++
++    if ( (p[0] == 0xFF) && (p[1] == 0x03) ) {
++        rv = loop_frame(p,n);
++        return rv;
++    }
++
+     for (; n > 0; --n) {
+       c = *p++;
+       if (c == PPP_FLAG) {
+@@ -288,17 +300,102 @@
+  * loopback, now that the real serial link is up.
+  */
+ void
+-demand_rexmit(proto)
++demand_rexmit(proto, newip)
+     int proto;
++    u_int32_t newip;
+ {
+     struct packet *pkt, *prev, *nextpkt;
++    unsigned short checksum;
++    unsigned short pkt_checksum = 0;
++    unsigned iphdr;
++    struct timeval tv;
++    char cv = 0;
++    char ipstr[16];
+     prev = NULL;
+     pkt = pend_q;
+     pend_q = NULL;
++    tv.tv_sec = 1;
++    tv.tv_usec = 0;
++    select(0,NULL,NULL,NULL,&tv);     /* Sleep for 1 Seconds */
+     for (; pkt != NULL; pkt = nextpkt) {
+       nextpkt = pkt->next;
+       if (PPP_PROTOCOL(pkt->data) == proto) {
++            if ( (proto == PPP_IP) && newip ) {
++              /* Get old checksum */
++
++              iphdr = (pkt->data[4] & 15) << 2;
++              checksum = *((unsigned short *) (pkt->data+14));
++                if (checksum == 0xFFFF) {
++                    checksum = 0;
++                }
++
++ 
++                if (pkt->data[13] == 17) {
++                    pkt_checksum =  *((unsigned short *) (pkt->data+10+iphdr));
++                  if (pkt_checksum) {
++                        cv = 1;
++                        if (pkt_checksum == 0xFFFF) {
++                            pkt_checksum = 0;
++                        }
++                    }
++                    else {
++                       cv = 0;
++                    }
++                }
++
++              if (pkt->data[13] == 6) {
++                  pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr));
++                  cv = 1;
++                    if (pkt_checksum == 0xFFFF) {
++                        pkt_checksum = 0;
++                    }
++              }
++
++              /* Delete old Source-IP-Address */
++                checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++                checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++              pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++              pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++              /* Change Source-IP-Address */
++                * ((u_int32_t *) (pkt->data + 16)) = newip;
++
++              /* Add new Source-IP-Address */
++                checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++                checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++                pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
++                pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
++
++              /* Write new checksum */
++                if (!checksum) {
++                    checksum = 0xFFFF;
++                }
++                *((unsigned short *) (pkt->data+14)) = checksum;
++              if (pkt->data[13] == 6) {
++                  *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum;
++              }
++              if (cv && (pkt->data[13] == 17) ) {
++                  *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum;
++              }
++
++              /* Log Packet */
++              strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16))));
++              if (pkt->data[13] == 1) {
++                  syslog(LOG_INFO,"Open ICMP %s -> %s\n",
++                      ipstr,
++                      inet_ntoa(*( (struct in_addr *) (pkt->data+20))));
++              } else {
++                  syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n",
++                      pkt->data[13] == 6 ? "TCP" : "UDP",
++                      ipstr,
++                      ntohs(*( (short *) (pkt->data+iphdr+4))),
++                      inet_ntoa(*( (struct in_addr *) (pkt->data+20))),
++                      ntohs(*( (short *) (pkt->data+iphdr+6))));
++                }
++            }
+           output(0, pkt->data, pkt->length);
+           free(pkt);
+       } else {
+--- ppp/pppd/ipcp.c
++++ ppp/pppd/ipcp.c    2000/06/28 12:32:05
+@@ -1454,7 +1454,7 @@
+                   proxy_arp_set[f->unit] = 1;
+       }
+-      demand_rexmit(PPP_IP);
++      demand_rexmit(PPP_IP,go->ouraddr);
+       sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
+     } else {
+--- ppp/pppd/ipv6cp.c
++++ ppp/pppd/ipv6cp.c  2000/06/28 12:32:06
+@@ -1153,7 +1153,7 @@
+           }
+       }
+-      demand_rexmit(PPP_IPV6);
++      demand_rexmit(PPP_IPV6,0);
+       sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
+     } else {
+--- ppp/pppd/pppd.h
++++ ppp/pppd/pppd.h    2000/06/28 12:32:06
+@@ -359,7 +359,7 @@
+ void demand_block __P((void));        /* set all NPs to queue up packets */
+ void demand_unblock __P((void)); /* set all NPs to pass packets */
+ void demand_discard __P((void)); /* set all NPs to discard packets */
+-void demand_rexmit __P((int));        /* retransmit saved frames for an NP */
++void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/
+ int  loop_chars __P((unsigned char *, int)); /* process chars from loopback */
+ int  loop_frame __P((unsigned char *, int)); /* should we bring link up? */
diff --git a/openwrt/package/ppp/patches/200-makefile.patch b/openwrt/package/ppp/patches/200-makefile.patch
new file mode 100644 (file)
index 0000000..5bbf860
--- /dev/null
@@ -0,0 +1,53 @@
+diff -ruN ppp-2.4.3-orig/pppd/Makefile.linux ppp-2.4.3-3/pppd/Makefile.linux
+--- ppp-2.4.3-orig/pppd/Makefile.linux 2004-11-13 13:02:22.000000000 +0100
++++ ppp-2.4.3-3/pppd/Makefile.linux    2004-12-16 04:43:41.000000000 +0100
+@@ -48,19 +48,19 @@
+ # Uncomment the next line to include support for PPP packet filtering.
+ # This requires that the libpcap library and headers be installed
+ # and that the kernel driver support PPP packet filtering.
+-FILTER=y
++#FILTER=y
+ # Uncomment the next line to enable multilink PPP (enabled by default)
+ # Linux distributions: Please leave multilink ENABLED in your builds
+ # of pppd!
+-HAVE_MULTILINK=y
++#HAVE_MULTILINK=y
+ # Uncomment the next line to enable the TDB database (enabled by default.)
+ # If you enable multilink, then TDB is automatically enabled also.
+ # Linux distributions: Please leave TDB ENABLED in your builds.
+-USE_TDB=y
++#USE_TDB=y
+-HAS_SHADOW=y
++#HAS_SHADOW=y
+ #USE_PAM=y
+ #HAVE_INET6=y
+@@ -77,7 +77,7 @@
+ INCLUDE_DIRS= -I../include
+-COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP
++COMPILE_FLAGS= -DHAVE_PATHS_H -DHAVE_MMAP
+ CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS)
+@@ -117,12 +117,12 @@
+ #LIBS     += -lshadow $(LIBS)
+ endif
+-ifneq ($(wildcard /usr/include/crypt.h),)
++#ifneq ($(wildcard /usr/include/crypt.h),)
+ CFLAGS   += -DHAVE_CRYPT_H=1
+-endif
+-ifneq ($(wildcard /usr/lib/libcrypt.*),)
++#endif
++#ifneq ($(wildcard /usr/lib/libcrypt.*),)
+ LIBS  += -lcrypt
+-endif
++#endif
+ ifdef NEEDDES
+ ifndef USE_CRYPT
diff --git a/openwrt/package/ppp/patches/201-mppe_mppc_1.1.patch b/openwrt/package/ppp/patches/201-mppe_mppc_1.1.patch
new file mode 100644 (file)
index 0000000..7e09f1a
--- /dev/null
@@ -0,0 +1,1585 @@
+diff -ruN ppp-2.4.3.orig/include/linux/ppp-comp.h ppp-2.4.3/include/linux/ppp-comp.h
+--- ppp-2.4.3.orig/include/linux/ppp-comp.h    2002-12-06 10:49:15.000000000 +0100
++++ ppp-2.4.3/include/linux/ppp-comp.h 2004-11-21 13:54:09.000000000 +0100
+@@ -36,7 +36,7 @@
+  */
+ /*
+- *  ==FILEVERSION 20020319==
++ *  ==FILEVERSION 20020715==
+  *
+  *  NOTE TO MAINTAINERS:
+  *     If you modify this file at all, please set the above date.
+@@ -86,7 +86,7 @@
+       /* Compress a packet */
+       int     (*compress) (void *state, unsigned char *rptr,
+-                            unsigned char *obuf, int isize, int osize);
++                           unsigned char *obuf, int isize, int osize);
+       /* Return compression statistics */
+       void    (*comp_stat) (void *state, struct compstat *stats);
+@@ -107,7 +107,7 @@
+       /* Decompress a packet. */
+       int     (*decompress) (void *state, unsigned char *ibuf, int isize,
+-                              unsigned char *obuf, int osize);
++                             unsigned char *obuf, int osize);
+       /* Update state for an incompressible packet received */
+       void    (*incomp) (void *state, unsigned char *ibuf, int icnt);
+@@ -288,6 +288,33 @@
+           opts |= MPPE_OPT_UNKNOWN;           \
+     } while (/* CONSTCOND */ 0)
++/* MPPE/MPPC definitions by J.D.*/
++#define MPPE_STATELESS          MPPE_H_BIT    /* configuration bit H */
++#define MPPE_40BIT              MPPE_L_BIT    /* configuration bit L */
++#define MPPE_56BIT              MPPE_M_BIT    /* configuration bit M */
++#define MPPE_128BIT             MPPE_S_BIT    /* configuration bit S */
++#define MPPE_MPPC               MPPE_C_BIT    /* configuration bit C */
++
++/*
++ * Definitions for Stac LZS.
++ */
++
++#define CI_LZS                        17      /* config option for Stac LZS */
++#define CILEN_LZS             5       /* length of config option */
++
++#define LZS_OVHD              4       /* max. LZS overhead */
++#define LZS_HIST_LEN          2048    /* LZS history size */
++#define LZS_MAX_CCOUNT                0x0FFF  /* max. coherency counter value */
++
++#define LZS_MODE_NONE         0
++#define LZS_MODE_LCB          1
++#define LZS_MODE_CRC          2
++#define LZS_MODE_SEQ          3
++#define LZS_MODE_EXT          4
++
++#define LZS_EXT_BIT_FLUSHED   0x80    /* bit A */
++#define LZS_EXT_BIT_COMP      0x20    /* bit C */
++
+ /*
+  * Definitions for other, as yet unsupported, compression methods.
+  */
+diff -ruN ppp-2.4.3.orig/include/net/ppp-comp.h ppp-2.4.3/include/net/ppp-comp.h
+--- ppp-2.4.3.orig/include/net/ppp-comp.h      2002-12-06 10:49:15.000000000 +0100
++++ ppp-2.4.3/include/net/ppp-comp.h   2004-11-21 13:54:09.000000000 +0100
+@@ -255,6 +255,33 @@
+           opts |= MPPE_OPT_UNKNOWN;           \
+     } while (/* CONSTCOND */ 0)
++/* MPPE/MPPC definitions by J.D.*/
++#define MPPE_STATELESS          MPPE_H_BIT    /* configuration bit H */
++#define MPPE_40BIT              MPPE_L_BIT    /* configuration bit L */
++#define MPPE_56BIT              MPPE_M_BIT    /* configuration bit M */
++#define MPPE_128BIT             MPPE_S_BIT    /* configuration bit S */
++#define MPPE_MPPC               MPPE_C_BIT    /* configuration bit C */
++
++/*
++ * Definitions for Stac LZS.
++ */
++
++#define CI_LZS                        17      /* config option for Stac LZS */
++#define CILEN_LZS             5       /* length of config option */
++
++#define LZS_OVHD              4       /* max. LZS overhead */
++#define LZS_HIST_LEN          2048    /* LZS history size */
++#define LZS_MAX_CCOUNT                0x0FFF  /* max. coherency counter value */
++
++#define LZS_MODE_NONE         0
++#define LZS_MODE_LCB          1
++#define LZS_MODE_CRC          2
++#define LZS_MODE_SEQ          3
++#define LZS_MODE_EXT          4
++
++#define LZS_EXT_BIT_FLUSHED   0x80    /* bit A */
++#define LZS_EXT_BIT_COMP      0x20    /* bit C */
++
+ /*
+  * Definitions for other, as yet unsupported, compression methods.
+  */
+diff -ruN ppp-2.4.3.orig/pppd/ccp.c ppp-2.4.3/pppd/ccp.c
+--- ppp-2.4.3.orig/pppd/ccp.c  2004-11-13 03:28:15.000000000 +0100
++++ ppp-2.4.3/pppd/ccp.c       2004-11-21 13:54:09.000000000 +0100
+@@ -62,12 +62,10 @@
+ static char bsd_value[8];
+ static char deflate_value[8];
+-/*
+- * Option variables.
+- */
+ #ifdef MPPE
+-bool refuse_mppe_stateful = 1;                /* Allow stateful mode? */
+-#endif
++static int setmppe(char **);
++static int setnomppe(void);
++#endif /* MPPE */
+ static option_t ccp_option_list[] = {
+     { "noccp", o_bool, &ccp_protent.enabled_flag,
+@@ -108,54 +106,36 @@
+       "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
+       &ccp_allowoptions[0].predictor_1 },
++    { "lzs", o_bool, &ccp_wantoptions[0].lzs,
++      "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_PRIO },
++    { "+lzs", o_bool, &ccp_wantoptions[0].lzs,
++      "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_ALIAS | OPT_PRIO },
++    { "nolzs", o_bool, &ccp_wantoptions[0].lzs,
++      "don't allow Stac LZS", OPT_PRIOSUB | OPT_A2CLR,
++      &ccp_allowoptions[0].lzs },
++    { "-lzs", o_bool, &ccp_wantoptions[0].lzs,
++      "don't allow Stac LZS", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
++      &ccp_allowoptions[0].lzs },
++
+ #ifdef MPPE
+-    /* MPPE options are symmetrical ... we only set wantoptions here */
+-    { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
+-      "require MPPE encryption",
+-      OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
+-    { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
+-      "require MPPE encryption",
+-      OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
+-    { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
+-      "don't allow MPPE encryption", OPT_PRIO },
+-    { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
+-      "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
+-
+-    /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
+-    { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+-      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
+-      &ccp_wantoptions[0].mppe },
+-    { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+-      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
+-      &ccp_wantoptions[0].mppe },
+-    { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
+-      "don't allow MPPE 40-bit encryption",
+-      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
+-    { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
+-      "don't allow MPPE 40-bit encryption",
+-      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
+-      &ccp_wantoptions[0].mppe },
+-
+-    { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+-      "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
+-      &ccp_wantoptions[0].mppe },
+-    { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+-      "require MPPE 128-bit encryption",
+-      OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
+-      &ccp_wantoptions[0].mppe },
+-    { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
+-      "don't allow MPPE 128-bit encryption",
+-      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
+-    { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
+-      "don't allow MPPE 128-bit encryption",
+-      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
+-      &ccp_wantoptions[0].mppe },
+-
+-    /* strange one; we always request stateless, but will we allow stateful? */
+-    { "mppe-stateful", o_bool, &refuse_mppe_stateful,
+-      "allow MPPE stateful mode", OPT_PRIO },
+-    { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
+-      "disallow MPPE stateful mode", OPT_PRIO | 1 },
++    { "mppc", o_bool, &ccp_wantoptions[0].mppc,
++      "request MPPC compression", 1, &ccp_allowoptions[0].mppc },
++    { "+mppc", o_bool, &ccp_wantoptions[0].mppc,
++      "request MPPC compression", 1, &ccp_allowoptions[0].mppc, OPT_ALIAS },
++    { "nomppc", o_bool, &ccp_wantoptions[0].mppc,
++      "don't allow MPPC compression", OPT_PRIOSUB | OPT_A2CLR,
++      &ccp_allowoptions[0].mppc },
++    { "-mppc", o_bool, &ccp_wantoptions[0].mppc,
++      "don't allow MPPC compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
++      &ccp_allowoptions[0].mppc },
++    { "mppe", o_special, (void *)setmppe,
++      "request MPPE encryption" },
++    { "+mppe", o_special, (void *)setmppe,
++      "request MPPE encryption" },
++    { "nomppe", o_special_noarg, (void *)setnomppe,
++      "don't allow MPPE encryption" },
++    { "-mppe", o_special_noarg, (void *)setnomppe,
++      "don't allow MPPE encryption" },
+ #endif /* MPPE */
+     { NULL }
+@@ -241,7 +221,7 @@
+  */
+ #define ANY_COMPRESS(opt)     ((opt).deflate || (opt).bsd_compress \
+                                || (opt).predictor_1 || (opt).predictor_2 \
+-                               || (opt).mppe)
++                               || (opt).lzs || (opt).mppc || (opt).mppe)
+ /*
+  * Local state (mainly for handling reset-reqs and reset-acks).
+@@ -344,6 +324,100 @@
+     return 1;
+ }
++#ifdef MPPE
++/*
++ * Functions called from config options
++ */
++/* 
++   MPPE suboptions:
++      required - require MPPE; disconnect if peer doesn't support it
++      stateless - use stateless mode
++      no40 - disable 40 bit keys
++      no56 - disable 56 bit keys
++      no128 - disable 128 bit keys
++*/
++int setmppe(char **argv)
++{
++    int i;
++    char *str, cmdbuf[16];
++
++    ccp_allowoptions[0].mppe = 1;
++    ccp_allowoptions[0].mppe_40 = 1;
++    ccp_allowoptions[0].mppe_56 = 1;
++    ccp_allowoptions[0].mppe_128 = 1;
++    ccp_allowoptions[0].mppe_stateless = 0;
++    ccp_wantoptions[0].mppe = 0;
++
++    str = *argv;
++
++    while (1) {
++      i = 0;
++      memset(cmdbuf, '\0', 16);
++      while ((i < 16) && (*str != ',') && (*str != '\0'))
++          cmdbuf[i++] = *str++;
++      cmdbuf[i] = '\0';
++      if (!strncasecmp(cmdbuf, "no40", strlen("no40"))) {
++          ccp_allowoptions[0].mppe_40 = 0;
++          goto next_param;
++      } else if (!strncasecmp(cmdbuf, "no56", strlen("no56"))) {
++          ccp_allowoptions[0].mppe_56 = 0;
++          goto next_param;
++      } else if (!strncasecmp(cmdbuf, "no128", strlen("no128"))) {
++          ccp_allowoptions[0].mppe_128 = 0;
++          goto next_param;
++      } else if (!strncasecmp(cmdbuf, "stateless", strlen("stateless"))) {
++          ccp_allowoptions[0].mppe_stateless = 1;
++          goto next_param;
++      } else if (!strncasecmp(cmdbuf, "required", strlen("required"))) {
++          ccp_wantoptions[0].mppe = 1;
++          goto next_param;
++      } else {
++          option_error("invalid parameter '%s' for mppe option", cmdbuf);
++          return 0;
++      }
++
++    next_param:
++      if (*str == ',') {
++          str++;
++          continue;
++      }
++      if (*str == '\0') {
++          if (!(ccp_allowoptions[0].mppe_40 || ccp_allowoptions[0].mppe_56 ||
++                ccp_allowoptions[0].mppe_128)) {
++              if (ccp_wantoptions[0].mppe == 1) {
++                  option_error("You require MPPE but you have switched off "
++                               "all encryption key lengths.");
++                  return 0;
++              }
++              ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
++              ccp_wantoptions[0].mppe_stateless =
++                  ccp_allowoptions[0].mppe_stateless = 0;
++          } else {
++              ccp_allowoptions[0].mppe = 1;
++              ccp_wantoptions[0].mppe_stateless =
++                  ccp_allowoptions[0].mppe_stateless;
++              if (ccp_wantoptions[0].mppe == 1) {
++                  ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40;
++                  ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56;
++                  ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128;
++              }
++          }
++          return 1;
++      }
++    }
++}
++
++int setnomppe(void)
++{
++    ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
++    ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40 = 0;
++    ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56 = 0;
++    ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128 = 0;
++    ccp_wantoptions[0].mppe_stateless = ccp_allowoptions[0].mppe_stateless = 0;
++    return 1;
++}
++#endif /* MPPE */
++
+ /*
+  * ccp_init - initialize CCP.
+  */
+@@ -378,6 +452,30 @@
+     ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
+     ccp_allowoptions[0].predictor_1 = 1;
++
++    ccp_wantoptions[0].lzs = 0; /* Stac LZS  - will be enabled in the future */
++    ccp_wantoptions[0].lzs_mode = LZS_MODE_SEQ;
++    ccp_wantoptions[0].lzs_hists = 1;
++    ccp_allowoptions[0].lzs = 0; /* Stac LZS  - will be enabled in the future */
++    ccp_allowoptions[0].lzs_mode = LZS_MODE_SEQ;
++    ccp_allowoptions[0].lzs_hists = 1;
++
++#ifdef MPPE
++    /* by default allow and request MPPC... */
++    ccp_wantoptions[0].mppc = ccp_allowoptions[0].mppc = 1;
++
++    /* ... and allow but don't request MPPE */
++    ccp_allowoptions[0].mppe = 1;
++    ccp_allowoptions[0].mppe_40 = 1;
++    ccp_allowoptions[0].mppe_56 = 1;
++    ccp_allowoptions[0].mppe_128 = 1;
++    ccp_allowoptions[0].mppe_stateless = 1;
++    ccp_wantoptions[0].mppe = 0;
++    ccp_wantoptions[0].mppe_40 = 0;
++    ccp_wantoptions[0].mppe_56 = 0;
++    ccp_wantoptions[0].mppe_128 = 0;
++    ccp_wantoptions[0].mppe_stateless = 0;
++#endif /* MPPE */
+ }
+ /*
+@@ -455,11 +553,11 @@
+     if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {
+       notice("Compression disabled by peer.");
+ #ifdef MPPE
+-      if (ccp_gotoptions[unit].mppe) {
++      if (ccp_wantoptions[unit].mppe) {
+           error("MPPE disabled, closing LCP");
+           lcp_close(unit, "MPPE disabled by peer");
+       }
+-#endif
++#endif /* MPPE */
+     }
+     /*
+@@ -487,6 +585,15 @@
+           break;
+       /* send a reset-ack, which the transmitter will see and
+          reset its compression state. */
++
++      /* In case of MPPE/MPPC or LZS we shouldn't send CCP_RESETACK,
++         but we do it in order to reset compressor; CCP_RESETACK is
++         then silently discarded. See functions ppp_send_frame and
++         ppp_ccp_peek in ppp_generic.c (Linux only !!!). All the
++         confusion is caused by the fact that CCP code is splited
++         into two parts - one part is handled by pppd, the other one
++         is handled by kernel. */
++
+       fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
+       break;
+@@ -515,12 +622,11 @@
+     fsm_lowerdown(&ccp_fsm[unit]);
+ #ifdef MPPE
+-    if (ccp_gotoptions[unit].mppe) {
++    if (ccp_wantoptions[unit].mppe) {
+       error("MPPE required but peer negotiation failed");
+       lcp_close(unit, "MPPE required but peer negotiation failed");
+     }
+-#endif
+-
++#endif /* MPPE */
+ }
+ /*
+@@ -537,7 +643,7 @@
+     all_rejected[f->unit] = 0;
+ #ifdef MPPE
+-    if (go->mppe) {
++    if (go->mppe || go->mppc) {
+       ccp_options *ao = &ccp_allowoptions[f->unit];
+       int auth_mschap_bits = auth_done[f->unit];
+       int numbits;
+@@ -551,80 +657,109 @@
+        * NB: If MPPE is required, all other compression opts are invalid.
+        *     So, we return right away if we can't do it.
+        */
++      if (ccp_wantoptions[f->unit].mppe) {
++          /* Leave only the mschap auth bits set */
++          auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
++                               CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
++          /* Count the mschap auths */
++          auth_mschap_bits >>= CHAP_MS_SHIFT;
++          numbits = 0;
++          do {
++              numbits += auth_mschap_bits & 1;
++              auth_mschap_bits >>= 1;
++          } while (auth_mschap_bits);
++          if (numbits > 1) {
++              error("MPPE required, but auth done in both directions.");
++              lcp_close(f->unit, "MPPE required but not available");
++              return;
++          }
++          if (!numbits) {
++              error("MPPE required, but MS-CHAP[v2] auth not performed.");
++              lcp_close(f->unit, "MPPE required but not available");
++              return;
++          }
+-      /* Leave only the mschap auth bits set */
+-      auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
+-                           CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
+-      /* Count the mschap auths */
+-      auth_mschap_bits >>= CHAP_MS_SHIFT;
+-      numbits = 0;
+-      do {
+-          numbits += auth_mschap_bits & 1;
+-          auth_mschap_bits >>= 1;
+-      } while (auth_mschap_bits);
+-      if (numbits > 1) {
+-          error("MPPE required, but auth done in both directions.");
+-          lcp_close(f->unit, "MPPE required but not available");
+-          return;
+-      }
+-      if (!numbits) {
+-          error("MPPE required, but MS-CHAP[v2] auth not performed.");
+-          lcp_close(f->unit, "MPPE required but not available");
+-          return;
+-      }
+-
+-      /* A plugin (eg radius) may not have obtained key material. */
+-      if (!mppe_keys_set) {
+-          error("MPPE required, but keys are not available.  "
+-                "Possible plugin problem?");
+-          lcp_close(f->unit, "MPPE required but not available");
+-          return;
+-      }
+-
+-      /* LM auth not supported for MPPE */
+-      if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
+-          /* This might be noise */
+-          if (go->mppe & MPPE_OPT_40) {
+-              notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
+-              go->mppe &= ~MPPE_OPT_40;
+-              ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
++          /* A plugin (eg radius) may not have obtained key material. */
++          if (!mppe_keys_set) {
++              error("MPPE required, but keys are not available.  "
++                    "Possible plugin problem?");
++              lcp_close(f->unit, "MPPE required but not available");
++              return;
+           }
+       }
+-      /* Last check: can we actually negotiate something? */
+-      if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
+-          /* Could be misconfig, could be 40-bit disabled above. */
+-          error("MPPE required, but both 40-bit and 128-bit disabled.");
+-          lcp_close(f->unit, "MPPE required but not available");
+-          return;
++      /*
++       * Check whether the kernel knows about the various
++       * compression methods we might request. Key material
++       * unimportant here.
++       */
++      if (go->mppc) {
++          opt_buf[0] = CI_MPPE;
++          opt_buf[1] = CILEN_MPPE;
++          opt_buf[2] = 0;
++          opt_buf[3] = 0;
++          opt_buf[4] = 0;
++          opt_buf[5] = MPPE_MPPC;
++          if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 0) <= 0)
++              go->mppc = 0;
++      }
++      if (go->mppe_40) {
++          opt_buf[0] = CI_MPPE;
++          opt_buf[1] = CILEN_MPPE;
++          opt_buf[2] = MPPE_STATELESS;
++          opt_buf[3] = 0;
++          opt_buf[4] = 0;
++          opt_buf[5] = MPPE_40BIT;
++          if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
++              go->mppe_40 = 0;
++      }
++      if (go->mppe_56) {
++          opt_buf[0] = CI_MPPE;
++          opt_buf[1] = CILEN_MPPE;
++          opt_buf[2] = MPPE_STATELESS;
++          opt_buf[3] = 0;
++          opt_buf[4] = 0;
++          opt_buf[5] = MPPE_56BIT;
++          if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
++              go->mppe_56 = 0;
++      }
++      if (go->mppe_128) {
++          opt_buf[0] = CI_MPPE;
++          opt_buf[1] = CILEN_MPPE;
++          opt_buf[2] = MPPE_STATELESS;
++          opt_buf[3] = 0;
++          opt_buf[4] = 0;
++          opt_buf[5] = MPPE_128BIT;
++          if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
++              go->mppe_128 = 0;
++      }
++      if (!go->mppe_40 && !go->mppe_56 && !go->mppe_128) {
++          if (ccp_wantoptions[f->unit].mppe) {
++              error("MPPE required, but kernel has no support.");
++              lcp_close(f->unit, "MPPE required but not available");
++          }
++          go->mppe = go->mppe_stateless = 0;
++      } else {
++          /* MPPE is not compatible with other compression types */
++          if (ccp_wantoptions[f->unit].mppe) {
++              ao->bsd_compress = go->bsd_compress = 0;
++              ao->predictor_1  = go->predictor_1  = 0;
++              ao->predictor_2  = go->predictor_2  = 0;
++              ao->deflate      = go->deflate      = 0;
++              ao->lzs          = go->lzs          = 0;
++          }
+       }
+-
+-      /* sync options */
+-      ao->mppe = go->mppe;
+-      /* MPPE is not compatible with other compression types */
+-      ao->bsd_compress = go->bsd_compress = 0;
+-      ao->predictor_1  = go->predictor_1  = 0;
+-      ao->predictor_2  = go->predictor_2  = 0;
+-      ao->deflate      = go->deflate      = 0;
+     }
+ #endif /* MPPE */
+-
+-    /*
+-     * Check whether the kernel knows about the various
+-     * compression methods we might request.
+-     */
+-#ifdef MPPE
+-    if (go->mppe) {
+-      opt_buf[0] = CI_MPPE;
+-      opt_buf[1] = CILEN_MPPE;
+-      MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
+-      /* Key material unimportant here. */
+-      if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) {
+-          error("MPPE required, but kernel has no support.");
+-          lcp_close(f->unit, "MPPE required but not available");
+-      }
++    if (go->lzs) {
++      opt_buf[0] = CI_LZS;
++      opt_buf[1] = CILEN_LZS;
++      opt_buf[2] = go->lzs_hists >> 8;
++      opt_buf[3] = go->lzs_hists & 0xff;
++      opt_buf[4] = LZS_MODE_SEQ;
++      if (ccp_test(f->unit, opt_buf, CILEN_LZS, 0) <= 0)
++          go->lzs = 0;
+     }
+-#endif
+     if (go->bsd_compress) {
+       opt_buf[0] = CI_BSD_COMPRESS;
+       opt_buf[1] = CILEN_BSD_COMPRESS;
+@@ -679,7 +814,8 @@
+       + (go->deflate? CILEN_DEFLATE: 0)
+       + (go->predictor_1? CILEN_PREDICTOR_1: 0)
+       + (go->predictor_2? CILEN_PREDICTOR_2: 0)
+-      + (go->mppe? CILEN_MPPE: 0);
++      + (go->lzs? CILEN_LZS: 0)
++      + ((go->mppe || go->mppc)? CILEN_MPPE: 0);
+ }
+ /*
+@@ -693,6 +829,8 @@
+ {
+     int res;
+     ccp_options *go = &ccp_gotoptions[f->unit];
++    ccp_options *ao = &ccp_allowoptions[f->unit];
++    ccp_options *wo = &ccp_wantoptions[f->unit];
+     u_char *p0 = p;
+     /*
+@@ -701,22 +839,43 @@
+      * in case it gets Acked.
+      */
+ #ifdef MPPE
+-    if (go->mppe) {
++    if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
+       u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
+-      p[0] = opt_buf[0] = CI_MPPE;
+-      p[1] = opt_buf[1] = CILEN_MPPE;
+-      MPPE_OPTS_TO_CI(go->mppe, &p[2]);
+-      MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
++      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_56 ? MPPE_56BIT : 0) |
++          (go->mppe_128 ? MPPE_128BIT : 0) | (go->mppc ? MPPE_MPPC : 0);
++
++      BCOPY(p, opt_buf, CILEN_MPPE);
+       BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
+       res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
+-      if (res > 0)
++      if (res > 0) {
+           p += CILEN_MPPE;
+-      else
++      } else {
+           /* This shouldn't happen, we've already tested it! */
+-          lcp_close(f->unit, "MPPE required but not available in kernel");
++          go->mppe = go->mppe_40 = go->mppe_56 = go->mppe_128 =
++              go->mppe_stateless = go->mppc = 0;
++          if (ccp_wantoptions[f->unit].mppe)
++              lcp_close(f->unit, "MPPE required but not available in kernel");
++      }
++    }
++#endif /* MPPE */
++    if (go->lzs) {
++      p[0] = CI_LZS;
++      p[1] = CILEN_LZS;
++      p[2] = go->lzs_hists >> 8;
++      p[3] = go->lzs_hists & 0xff;
++      p[4] = LZS_MODE_SEQ;
++      res = ccp_test(f->unit, p, CILEN_LZS, 0);
++      if (res > 0) {
++          p += CILEN_LZS;
++      } else
++          go->lzs = 0;
+     }
+-#endif
+     if (go->deflate) {
+       p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
+       p[1] = CILEN_DEFLATE;
+@@ -802,7 +961,7 @@
+ /*
+  * ccp_ackci - process a received configure-ack, and return
+- * 1 iff the packet was OK.
++ * 1 if the packet was OK.
+  */
+ static int
+ ccp_ackci(f, p, len)
+@@ -811,24 +970,44 @@
+     int len;
+ {
+     ccp_options *go = &ccp_gotoptions[f->unit];
++    ccp_options *ao = &ccp_allowoptions[f->unit];
++    ccp_options *wo = &ccp_wantoptions[f->unit];
+     u_char *p0 = p;
+ #ifdef MPPE
+-    if (go->mppe) {
+-      u_char opt_buf[CILEN_MPPE];
+-
+-      opt_buf[0] = CI_MPPE;
+-      opt_buf[1] = CILEN_MPPE;
+-      MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
+-      if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
++    if (go->mppe || go->mppc || (!wo->mppe && ao->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->mppc ? MPPE_MPPC : 0))
++              && p[5] != ((go->mppe_56 ? MPPE_56BIT : 0) |
++                          (go->mppc ? MPPE_MPPC : 0))
++              && p[5] != ((go->mppe_128 ? MPPE_128BIT : 0) |
++                          (go->mppc ? MPPE_MPPC : 0))))
+           return 0;
++      if (go->mppe_40 || go->mppe_56 || go->mppe_128)
++          go->mppe = 1;
+       p += CILEN_MPPE;
+       len -= CILEN_MPPE;
++      /* Cope with first/fast ack */
++      if (p == p0 && len == 0)
++          return 1;
++    }
++#endif /* MPPE */
++    if (go->lzs) {
++      if (len < CILEN_LZS || p[0] != CI_LZS || p[1] != CILEN_LZS
++          || p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff)
++          || p[4] != LZS_MODE_SEQ)
++          return 0;
++      p += CILEN_LZS;
++      len -= CILEN_LZS;
+       /* XXX Cope with first/fast ack */
+-      if (len == 0)
++      if (p == p0 && len == 0)
+           return 1;
+     }
+-#endif
+     if (go->deflate) {
+       if (len < CILEN_DEFLATE
+           || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+@@ -891,7 +1070,7 @@
+ /*
+  * ccp_nakci - process received configure-nak.
+- * Returns 1 iff the nak was OK.
++ * Returns 1 if the nak was OK.
+  */
+ static int
+ ccp_nakci(f, p, len, treat_as_reject)
+@@ -900,6 +1079,8 @@
+     int len;
+ {
+     ccp_options *go = &ccp_gotoptions[f->unit];
++    ccp_options *ao = &ccp_allowoptions[f->unit];
++    ccp_options *wo = &ccp_wantoptions[f->unit];
+     ccp_options no;           /* options we've seen already */
+     ccp_options try;          /* options to ask for next time */
+@@ -907,28 +1088,100 @@
+     try = *go;
+ #ifdef MPPE
+-    if (go->mppe && len >= CILEN_MPPE
+-      && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+-      no.mppe = 1;
+-      /*
+-       * Peer wants us to use a different strength or other setting.
+-       * Fail if we aren't willing to use his suggestion.
+-       */
+-      MPPE_CI_TO_OPTS(&p[2], try.mppe);
+-      if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) {
+-          error("Refusing MPPE stateful mode offered by peer");
+-          try.mppe = 0;
+-      } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) {
+-          /* Peer must have set options we didn't request (suggest) */
+-          try.mppe = 0;
+-      }
++    if ((go->mppe || go->mppc || (!wo->mppe && ao->mppe)) &&
++      len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+-      if (!try.mppe) {
+-          error("MPPE required but peer negotiation failed");
+-          lcp_close(f->unit, "MPPE required but peer negotiation failed");
++      if (go->mppc) {
++          no.mppc = 1;
++          if (!(p[5] & MPPE_MPPC))
++              try.mppc = 0;
++      }
++
++      if (go->mppe)
++          no.mppe = 1;
++      if (go->mppe_40)
++          no.mppe_40 = 1;
++      if (go->mppe_56)
++          no.mppe_56 = 1;
++      if (go->mppe_128)
++          no.mppe_128 = 1;
++      if (go->mppe_stateless)
++          no.mppe_stateless = 1;
++
++      if (ao->mppe_40) {
++          if ((p[5] & MPPE_40BIT))
++              try.mppe_40 = 1;
++          else
++              try.mppe_40 = (p[5] == 0) ? 1 : 0;
++      }
++      if (ao->mppe_56) {
++          if ((p[5] & MPPE_56BIT))
++              try.mppe_56 = 1;
++          else
++              try.mppe_56 = (p[5] == 0) ? 1 : 0;
++      }
++      if (ao->mppe_128) {
++          if ((p[5] & MPPE_128BIT))
++              try.mppe_128 = 1;
++          else
++              try.mppe_128 = (p[5] == 0) ? 1 : 0;
++      }
++
++      if (ao->mppe_stateless) {
++          if ((p[2] & MPPE_STATELESS) || wo->mppe_stateless)
++              try.mppe_stateless = 1;
++          else
++              try.mppe_stateless = 0;
++      }
++
++      if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128) {
++          try.mppe = try.mppe_stateless = 0;
++          if (wo->mppe) {
++              /* we require encryption, but peer doesn't support it
++                 so we close connection */
++              wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
++                  wo->mppe_56 = wo->mppe_128 = 0;
++              lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
++                        "key length");
++          }
++        }
++      if (wo->mppe && (wo->mppe_40 != try.mppe_40) &&
++          (wo->mppe_56 != try.mppe_56) && (wo->mppe_128 != try.mppe_128)) {
++          /* cannot negotiate key length */
++          wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
++              wo->mppe_56 = wo->mppe_128 = 0;
++          lcp_close(f->unit, "Cannot negotiate MPPE key length");
+       }
++      if (try.mppe_40 && try.mppe_56 && try.mppe_128)
++          try.mppe_40 = try.mppe_56 = 0;
++      else
++          if (try.mppe_56 && try.mppe_128)
++              try.mppe_56 = 0;
++          else
++              if (try.mppe_40 && try.mppe_128)
++                  try.mppe_40 = 0;
++              else
++                  if (try.mppe_40 && try.mppe_56)
++                      try.mppe_40 = 0;
++
++      p += CILEN_MPPE;
++      len -= CILEN_MPPE;
+     }
+ #endif /* MPPE */
++
++    if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
++      no.lzs = 1;
++      if (((p[2]<<8)|p[3]) > 1 || (p[4] != LZS_MODE_SEQ &&
++                                   p[4] != LZS_MODE_EXT))
++          try.lzs = 0;
++      else {
++          try.lzs_mode = p[4];
++          try.lzs_hists = (p[2] << 8) | p[3];
++      }
++      p += CILEN_LZS;
++      len -= CILEN_LZS;
++    }
++
+     if (go->deflate && len >= CILEN_DEFLATE
+       && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
+       && p[1] == CILEN_DEFLATE) {
+@@ -1001,14 +1254,50 @@
+       return -1;
+ #ifdef MPPE
+-    if (go->mppe && len >= CILEN_MPPE
++    if ((go->mppe || go->mppc) && len >= CILEN_MPPE
+       && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
+-      error("MPPE required but peer refused");
+-      lcp_close(f->unit, "MPPE required but peer refused");
++      ccp_options *wo = &ccp_wantoptions[f->unit];
++      if (p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0) ||
++          p[3] != 0 ||
++          p[4] != 0 ||
++          p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
++                   (go->mppe_56 ? MPPE_56BIT : 0) |
++                   (go->mppe_128 ? MPPE_128BIT : 0) |
++                   (go->mppc ? MPPE_MPPC : 0)))
++          return 0;
++      if (go->mppc)
++          try.mppc = 0;
++      if (go->mppe) {
++          try.mppe = 0;
++          if (go->mppe_40)
++              try.mppe_40 = 0;
++          if (go->mppe_56)
++              try.mppe_56 = 0;
++          if (go->mppe_128)
++              try.mppe_128 = 0;
++          if (go->mppe_stateless)
++              try.mppe_stateless = 0;
++          if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128)
++              try.mppe = try.mppe_stateless = 0;
++          if (wo->mppe) { /* we want MPPE but cannot negotiate key length */
++              wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
++                  wo->mppe_56 = wo->mppe_128 = 0;
++              lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
++                        "key length");
++          }
++      }
+       p += CILEN_MPPE;
+       len -= CILEN_MPPE;
+     }
+-#endif
++#endif /* MPPE */
++    if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
++      if (p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff) 
++          || p[4] != go->lzs_mode)
++          return 0;
++      try.lzs = 0;
++      p += CILEN_LZS;
++      len -= CILEN_LZS;
++    }
+     if (go->deflate_correct && len >= CILEN_DEFLATE
+       && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
+       if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
+@@ -1072,14 +1361,15 @@
+     int dont_nak;
+ {
+     int ret, newret, res;
+-    u_char *p0, *retp;
++    u_char *p0, *retp, p2, p5;
+     int len, clen, type, nb;
+     ccp_options *ho = &ccp_hisoptions[f->unit];
+     ccp_options *ao = &ccp_allowoptions[f->unit];
++    ccp_options *wo = &ccp_wantoptions[f->unit];
+ #ifdef MPPE
+-    bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */
+-                              /* CI_MPPE, or due to other options?       */
+-#endif
++    u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
++/*     int mtu; */
++#endif /* MPPE */
+     ret = CONFACK;
+     retp = p0 = p;
+@@ -1102,103 +1392,305 @@
+           switch (type) {
+ #ifdef MPPE
+           case CI_MPPE:
+-              if (!ao->mppe || clen != CILEN_MPPE) {
++              if ((!ao->mppc && !ao->mppe) || clen != CILEN_MPPE) {
+                   newret = CONFREJ;
+                   break;
+               }
+-              MPPE_CI_TO_OPTS(&p[2], ho->mppe);
+-              /* Nak if anything unsupported or unknown are set. */
+-              if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
+-                  newret = CONFNAK;
+-                  ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
+-              }
+-              if (ho->mppe & MPPE_OPT_UNKNOWN) {
++              p2 = p[2];
++              p5 = p[5];
++              /* not sure what they want, tell 'em what we got */
++              if (((p[2] & ~MPPE_STATELESS) != 0 || p[3] != 0 || p[4] != 0 ||
++                   (p[5] & ~(MPPE_40BIT | MPPE_56BIT | MPPE_128BIT |
++                             MPPE_MPPC)) != 0 || p[5] == 0) ||
++                  (p[2] == 0 && p[3] == 0 && p[4] == 0 &&  p[5] == 0)) {
+                   newret = CONFNAK;
+-                  ho->mppe &= ~MPPE_OPT_UNKNOWN;
++                  p[2] = (wo->mppe_stateless ? MPPE_STATELESS : 0);
++                  p[3] = 0;
++                  p[4] = 0;
++                  p[5] = (wo->mppe_40 ? MPPE_40BIT : 0) |
++                      (wo->mppe_56 ? MPPE_56BIT : 0) |
++                      (wo->mppe_128 ? MPPE_128BIT : 0) |
++                      (wo->mppc ? MPPE_MPPC : 0);
++                  break;
+               }
+-              /* Check state opt */
+-              if (ho->mppe & MPPE_OPT_STATEFUL) {
+-                  /*
+-                   * We can Nak and request stateless, but it's a
+-                   * lot easier to just assume the peer will request
+-                   * it if he can do it; stateful mode is bad over
+-                   * the Internet -- which is where we expect MPPE.
+-                   */
+-                 if (refuse_mppe_stateful) {
+-                      error("Refusing MPPE stateful mode offered by peer");
++              if ((p[5] & MPPE_MPPC)) {
++                  if (ao->mppc) {
++                      ho->mppc = 1;
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      opt_buf[2] = opt_buf[3] = opt_buf[4] = 0;
++                      opt_buf[5] = MPPE_MPPC;
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 1) <= 0) {
++                          ho->mppc = 0;
++                          p[5] &= ~MPPE_MPPC;
++                          newret = CONFNAK;
++                      }
++                  } else {
+                       newret = CONFREJ;
+-                      break;
++                      if (wo->mppe || ao->mppe) {
++                          p[5] &= ~MPPE_MPPC;
++                          newret = CONFNAK;
++                      }
++                  }
++              }
++
++              if (ao->mppe)
++                  ho->mppe = 1;
++
++              if ((p[2] & MPPE_STATELESS)) {
++                  if (ao->mppe_stateless) {
++                      if (wo->mppe_stateless)
++                          ho->mppe_stateless = 1;
++                      else {
++                          newret = CONFNAK;
++                          if (!dont_nak)
++                              p[2] &= ~MPPE_STATELESS;
++                      }
++                  } else {
++                      newret = CONFNAK;
++                      if (!dont_nak)
++                          p[2] &= ~MPPE_STATELESS;
++                  }
++              } else {
++                  if (wo->mppe_stateless && !dont_nak) {
++                      wo->mppe_stateless = 0;
++                      newret = CONFNAK;
++                      p[2] |= MPPE_STATELESS;
+                   }
+               }
+-              /* Find out which of {S,L} are set. */
+-              if ((ho->mppe & MPPE_OPT_128)
+-                   && (ho->mppe & MPPE_OPT_40)) {
+-                  /* Both are set, negotiate the strongest. */
++              if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT|MPPE_128BIT)) {
+                   newret = CONFNAK;
+-                  if (ao->mppe & MPPE_OPT_128)
+-                      ho->mppe &= ~MPPE_OPT_40;
+-                  else if (ao->mppe & MPPE_OPT_40)
+-                      ho->mppe &= ~MPPE_OPT_128;
+-                  else {
+-                      newret = CONFREJ;
+-                      break;
++                  if (ao->mppe_128) {
++                      ho->mppe_128 = 1;
++                      p[5] &= ~(MPPE_40BIT|MPPE_56BIT);
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++                            MPPE_MAX_KEY_LEN);
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
++                          ho->mppe_128 = 0;
++                          p[5] |= (MPPE_40BIT|MPPE_56BIT);
++                          p[5] &= ~MPPE_128BIT;
++                          goto check_mppe_56_40;
++                      }
++                      goto check_mppe;
+                   }
+-              } else if (ho->mppe & MPPE_OPT_128) {
+-                  if (!(ao->mppe & MPPE_OPT_128)) {
+-                      newret = CONFREJ;
+-                      break;
++                  p[5] &= ~MPPE_128BIT;
++                  goto check_mppe_56_40;
++              }
++              if ((p[5] & ~MPPE_MPPC) == (MPPE_56BIT|MPPE_128BIT)) {
++                  newret = CONFNAK;
++                  if (ao->mppe_128) {
++                      ho->mppe_128 = 1;
++                      p[5] &= ~MPPE_56BIT;
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++                            MPPE_MAX_KEY_LEN);
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
++                          ho->mppe_128 = 0;
++                          p[5] |= MPPE_56BIT;
++                          p[5] &= ~MPPE_128BIT;
++                          goto check_mppe_56;
++                      }
++                      goto check_mppe;
+                   }
+-              } else if (ho->mppe & MPPE_OPT_40) {
+-                  if (!(ao->mppe & MPPE_OPT_40)) {
+-                      newret = CONFREJ;
+-                      break;
++                  p[5] &= ~MPPE_128BIT;
++                  goto check_mppe_56;
++              }
++              if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_128BIT)) {
++                  newret = CONFNAK;
++                  if (ao->mppe_128) {
++                      ho->mppe_128 = 1;
++                      p[5] &= ~MPPE_40BIT;
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++                            MPPE_MAX_KEY_LEN);
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
++                          ho->mppe_128 = 0;
++                          p[5] |= MPPE_40BIT;
++                          p[5] &= ~MPPE_128BIT;
++                          goto check_mppe_40;
++                      }
++                      goto check_mppe;
++                  }
++                  p[5] &= ~MPPE_128BIT;
++                  goto check_mppe_40;
++              }
++              if ((p[5] & ~MPPE_MPPC) == MPPE_128BIT) {
++                  if (ao->mppe_128) {
++                      ho->mppe_128 = 1;
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++                            MPPE_MAX_KEY_LEN);
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
++                          ho->mppe_128 = 0;
++                          p[5] &= ~MPPE_128BIT;
++                          newret = CONFNAK;
++                      }
++                      goto check_mppe;
++                  }
++                  p[5] &= ~MPPE_128BIT;
++                  newret = CONFNAK;
++                  goto check_mppe;
++              }
++          check_mppe_56_40:
++              if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT)) {
++                  newret = CONFNAK;
++                  if (ao->mppe_56) {
++                      ho->mppe_56 = 1;
++                      p[5] &= ~MPPE_40BIT;
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++                            MPPE_MAX_KEY_LEN);
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
++                          ho->mppe_56 = 0;
++                          p[5] |= MPPE_40BIT;
++                          p[5] &= ~MPPE_56BIT;
++                          newret = CONFNAK;
++                          goto check_mppe_40;
++                      }
++                      goto check_mppe;
++                  }
++                  p[5] &= ~MPPE_56BIT;
++                  goto check_mppe_40;
++              }
++          check_mppe_56:
++              if ((p[5] & ~MPPE_MPPC) == MPPE_56BIT) {
++                  if (ao->mppe_56) {
++                      ho->mppe_56 = 1;
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++                            MPPE_MAX_KEY_LEN);
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
++                          ho->mppe_56 = 0;
++                          p[5] &= ~MPPE_56BIT;
++                          newret = CONFNAK;
++                      }
++                      goto check_mppe;
++                  }
++                  p[5] &= ~MPPE_56BIT;
++                  newret = CONFNAK;
++                  goto check_mppe;
++              }
++          check_mppe_40:
++              if ((p[5] & ~MPPE_MPPC) == MPPE_40BIT) {
++                  if (ao->mppe_40) {
++                      ho->mppe_40 = 1;
++                      BCOPY(p, opt_buf, CILEN_MPPE);
++                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
++                            MPPE_MAX_KEY_LEN);
++                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
++                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
++                          ho->mppe_40 = 0;
++                          p[5] &= ~MPPE_40BIT;
++                          newret = CONFNAK;
++                      }
++                      goto check_mppe;
++                  }
++                  p[5] &= ~MPPE_40BIT;
++              }
++
++          check_mppe:
++              if (!ho->mppe_40 && !ho->mppe_56 && !ho->mppe_128) {
++                  if (wo->mppe_40 || wo->mppe_56 || wo->mppe_128) {
++                      newret = CONFNAK;
++                      p[2] |= (wo->mppe_stateless ? MPPE_STATELESS : 0);
++                      p[5] |= (wo->mppe_40 ? MPPE_40BIT : 0) |
++                          (wo->mppe_56 ? MPPE_56BIT : 0) |
++                          (wo->mppe_128 ? MPPE_128BIT : 0) |
++                          (wo->mppc ? MPPE_MPPC : 0);
++                  } else {
++                      ho->mppe = ho->mppe_stateless = 0;
+                   }
+               } else {
+-                  /* Neither are set. */
++                  /* MPPE is not compatible with other compression types */
++                  if (wo->mppe) {
++                      ao->bsd_compress = 0;
++                      ao->predictor_1 = 0;
++                      ao->predictor_2 = 0;
++                      ao->deflate = 0;
++                      ao->lzs = 0;
++                  }
++              }
++              if ((!ho->mppc || !ao->mppc) && !ho->mppe) {
++                  p[2] = p2;
++                  p[5] = p5;
+                   newret = CONFREJ;
+                   break;
+               }
+-              /* rebuild the opts */
+-              MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
+-              if (newret == CONFACK) {
+-                  u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
+-                  int mtu;
+-
+-                  BCOPY(p, opt_buf, CILEN_MPPE);
+-                  BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
+-                        MPPE_MAX_KEY_LEN);
+-                  if (ccp_test(f->unit, opt_buf,
+-                               CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
+-                      /* This shouldn't happen, we've already tested it! */
+-                      error("MPPE required, but kernel has no support.");
+-                      lcp_close(f->unit, "MPPE required but not available");
+-                      newret = CONFREJ;
+-                      break;
+-                  }
+-                  /*
+-                   * We need to decrease the interface MTU by MPPE_PAD
+-                   * because MPPE frames **grow**.  The kernel [must]
+-                   * allocate MPPE_PAD extra bytes in xmit buffers.
+-                   */
+-                  mtu = netif_get_mtu(f->unit);
+-                  if (mtu)
+-                      netif_set_mtu(f->unit, mtu - MPPE_PAD);
+-                  else
+-                      newret = CONFREJ;
+-              }
++              /*
++               * I have commented the code below because according to RFC1547
++               * MTU is only information for higher level protocols about
++               * "the maximum allowable length for a packet (q.v.) transmitted
++               * over a point-to-point link without incurring network layer
++               * fragmentation." Of course a PPP implementation should be able
++               * to handle overhead added by MPPE - in our case apropriate code
++               * is located in drivers/net/ppp_generic.c in the kernel sources.
++               *
++               * According to RFC1661:
++               * - when negotiated MRU is less than 1500 octets, a PPP
++               *   implementation must still be able to receive at least 1500
++               *   octets,
++               * - when PFC is negotiated, a PPP implementation is still
++               *   required to receive frames with uncompressed protocol field.
++               *
++               * So why not to handle MPPE overhead without changing MTU value?
++               * I am sure that RFC3078, unfortunately silently, assumes that.
++               */
+               /*
+-               * We have accepted MPPE or are willing to negotiate
+-               * MPPE parameters.  A CONFREJ is due to subsequent
+-               * (non-MPPE) processing.
++               * We need to decrease the interface MTU by MPPE_PAD
++               * because MPPE frames **grow**.  The kernel [must]
++               * allocate MPPE_PAD extra bytes in xmit buffers.
+                */
+-              rej_for_ci_mppe = 0;
++/*
++              mtu = netif_get_mtu(f->unit);
++              if (mtu) {
++                  netif_set_mtu(f->unit, mtu - MPPE_PAD);
++              } else {
++                  newret = CONFREJ;
++                  if (ccp_wantoptions[f->unit].mppe) {
++                      error("Cannot adjust MTU needed by MPPE.");
++                      lcp_close(f->unit, "Cannot adjust MTU needed by MPPE.");
++                  }
++              }
++*/
+               break;
+ #endif /* MPPE */
++
++          case CI_LZS:
++              if (!ao->lzs || clen != CILEN_LZS) {
++                  newret = CONFREJ;
++                  break;
++              }
++
++              ho->lzs = 1;
++              ho->lzs_hists = (p[2] << 8) | p[3];
++              ho->lzs_mode = p[4];
++              if ((ho->lzs_hists != ao->lzs_hists) ||
++                  (ho->lzs_mode != ao->lzs_mode)) {
++                  newret = CONFNAK;
++                  if (!dont_nak) {
++                      p[2] = ao->lzs_hists >> 8;
++                      p[3] = ao->lzs_hists & 0xff;
++                      p[4] = ao->lzs_mode;
++                  } else
++                      break;
++              }
++
++              if (p == p0 && ccp_test(f->unit, p, CILEN_LZS, 1) <= 0) {
++                  newret = CONFREJ;
++              }
++              break;
++
+           case CI_DEFLATE:
+           case CI_DEFLATE_DRAFT:
+               if (!ao->deflate || clen != CILEN_DEFLATE
+@@ -1340,12 +1832,6 @@
+       else
+           *lenp = retp - p0;
+     }
+-#ifdef MPPE
+-    if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
+-      error("MPPE required but peer negotiation failed");
+-      lcp_close(f->unit, "MPPE required but peer negotiation failed");
+-    }
+-#endif
+     return ret;
+ }
+@@ -1367,24 +1853,35 @@
+       char *p = result;
+       char *q = result + sizeof(result); /* 1 past result */
+-      slprintf(p, q - p, "MPPE ");
+-      p += 5;
+-      if (opt->mppe & MPPE_OPT_128) {
+-          slprintf(p, q - p, "128-bit ");
+-          p += 8;
+-      }
+-      if (opt->mppe & MPPE_OPT_40) {
+-          slprintf(p, q - p, "40-bit ");
+-          p += 7;
+-      }
+-      if (opt->mppe & MPPE_OPT_STATEFUL)
+-          slprintf(p, q - p, "stateful");
+-      else
+-          slprintf(p, q - p, "stateless");
+-
++      if (opt->mppe) {
++          if (opt->mppc) {
++              slprintf(p, q - p, "MPPC/MPPE ");
++              p += 10;
++          } else {
++              slprintf(p, q - p, "MPPE ");
++              p += 5;
++          }
++          if (opt->mppe_128) {
++              slprintf(p, q - p, "128-bit ");
++              p += 8;
++          } else if (opt->mppe_56) {
++              slprintf(p, q - p, "56-bit ");
++              p += 7;
++          } else if (opt->mppe_40) {
++              slprintf(p, q - p, "40-bit ");
++              p += 7;
++          }
++          if (opt->mppe_stateless)
++              slprintf(p, q - p, "stateless");
++          else
++              slprintf(p, q - p, "stateful");
++      } else if (opt->mppc)
++          slprintf(p, q - p, "MPPC");
+       break;
+     }
+-#endif
++#endif /* MPPE */
++    case CI_LZS:
++      return "Stac LZS";
+     case CI_DEFLATE:
+     case CI_DEFLATE_DRAFT:
+       if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
+@@ -1440,12 +1937,12 @@
+     } else if (ANY_COMPRESS(*ho))
+       notice("%s transmit compression enabled", method_name(ho, NULL));
+ #ifdef MPPE
+-    if (go->mppe) {
++    if (go->mppe || go->mppc) {
+       BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
+       BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
+       continue_networks(f->unit);             /* Bring up IP et al */
+     }
+-#endif
++#endif /* MPPE */
+ }
+ /*
+@@ -1468,7 +1965,7 @@
+           lcp_close(f->unit, "MPPE disabled");
+       }
+     }
+-#endif
++#endif /* MPPE */
+ }
+ /*
+@@ -1528,24 +2025,28 @@
+ #ifdef MPPE
+           case CI_MPPE:
+               if (optlen >= CILEN_MPPE) {
+-                  u_char mppe_opts;
+-
+-                  MPPE_CI_TO_OPTS(&p[2], mppe_opts);
+-                  printer(arg, "mppe %s %s %s %s %s %s%s",
+-                          (p[2] & MPPE_H_BIT)? "+H": "-H",
+-                          (p[5] & MPPE_M_BIT)? "+M": "-M",
+-                          (p[5] & MPPE_S_BIT)? "+S": "-S",
+-                          (p[5] & MPPE_L_BIT)? "+L": "-L",
++                  printer(arg, "mppe %s %s %s %s %s %s",
++                          (p[2] & MPPE_STATELESS)? "+H": "-H",
++                          (p[5] & MPPE_56BIT)? "+M": "-M",
++                          (p[5] & MPPE_128BIT)? "+S": "-S",
++                          (p[5] & MPPE_40BIT)? "+L": "-L",
+                           (p[5] & MPPE_D_BIT)? "+D": "-D",
+-                          (p[5] & MPPE_C_BIT)? "+C": "-C",
+-                          (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
+-                  if (mppe_opts & MPPE_OPT_UNKNOWN)
++                          (p[5] & MPPE_MPPC)? "+C": "-C");
++                  if ((p[5] & ~(MPPE_56BIT | MPPE_128BIT | MPPE_40BIT |
++                                MPPE_D_BIT | MPPE_MPPC)) ||
++                      (p[2] & ~MPPE_STATELESS))
+                       printer(arg, " (%.2x %.2x %.2x %.2x)",
+                               p[2], p[3], p[4], p[5]);
+                   p += CILEN_MPPE;
+               }
+               break;
+-#endif
++#endif /* MPPE */
++          case CI_LZS:
++              if (optlen >= CILEN_LZS) {
++                  printer(arg, "lzs %.2x %.2x %.2x", p[2], p[3], p[4]);
++                  p += CILEN_LZS;
++              }
++              break;
+           case CI_DEFLATE:
+           case CI_DEFLATE_DRAFT:
+               if (optlen >= CILEN_DEFLATE) {
+@@ -1631,6 +2132,7 @@
+           error("Lost compression sync: disabling compression");
+           ccp_close(unit, "Lost compression sync");
+ #ifdef MPPE
++          /* My module dosn't need this. J.D., 2003-07-06 */
+           /*
+            * If we were doing MPPE, we must also take the link down.
+            */
+@@ -1638,9 +2140,18 @@
+               error("Too many MPPE errors, closing LCP");
+               lcp_close(unit, "Too many MPPE errors");
+           }
+-#endif
++#endif /* MPPE */
+       } else {
+           /*
++           * When LZS or MPPE/MPPC is negotiated we just send CCP_RESETREQ
++           * and don't wait for CCP_RESETACK
++           */
++          if ((ccp_gotoptions[f->unit].method == CI_LZS) ||
++              (ccp_gotoptions[f->unit].method == CI_MPPE)) {
++              fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
++              return;
++          }
++          /*
+            * Send a reset-request to reset the peer's compressor.
+            * We don't do that if we are still waiting for an
+            * acknowledgement to a previous reset-request.
+@@ -1671,4 +2182,3 @@
+     } else
+       ccp_localstate[f->unit] &= ~RACK_PENDING;
+ }
+-
+diff -ruN ppp-2.4.3.orig/pppd/ccp.h ppp-2.4.3/pppd/ccp.h
+--- ppp-2.4.3.orig/pppd/ccp.h  2004-11-04 11:02:26.000000000 +0100
++++ ppp-2.4.3/pppd/ccp.h       2004-11-21 13:54:09.000000000 +0100
+@@ -37,9 +37,17 @@
+     bool predictor_2;         /* do Predictor-2? */
+     bool deflate_correct;     /* use correct code for deflate? */
+     bool deflate_draft;               /* use draft RFC code for deflate? */
++    bool lzs;                 /* do Stac LZS? */
++    bool mppc;                        /* do MPPC? */
+     bool mppe;                        /* do MPPE? */
++    bool mppe_40;             /* allow 40 bit encryption? */
++    bool mppe_56;             /* allow 56 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 */
++    u_short lzs_mode;         /* LZS check mode */
++    u_short lzs_hists;                /* number of LZS histories */
+     short method;             /* code for chosen compression method */
+ } ccp_options;
+diff -ruN ppp-2.4.3.orig/pppd/chap_ms.c ppp-2.4.3/pppd/chap_ms.c
+--- ppp-2.4.3.orig/pppd/chap_ms.c      2004-11-12 10:57:43.000000000 +0100
++++ ppp-2.4.3/pppd/chap_ms.c   2004-11-21 13:54:09.000000000 +0100
+@@ -895,13 +895,17 @@
+     /*
+      * Disable undesirable encryption types.  Note that we don't ENABLE
+      * any encryption types, to avoid overriding manual configuration.
++     *
++     * It seems that 56 bit keys are unsupported in MS-RADIUS (see RFC 2548)
+      */
+     switch(types) {
+       case MPPE_ENC_TYPES_RC4_40:
+-          ccp_wantoptions[0].mppe &= ~MPPE_OPT_128;   /* disable 128-bit */
++          ccp_wantoptions[0].mppe_128 = 0;    /* disable 128-bit */
++          ccp_wantoptions[0].mppe_56 = 0;     /* disable 56-bit */
+           break;
+       case MPPE_ENC_TYPES_RC4_128:
+-          ccp_wantoptions[0].mppe &= ~MPPE_OPT_40;    /* disable 40-bit */
++          ccp_wantoptions[0].mppe_56 = 0;     /* disable 56-bit */
++          ccp_wantoptions[0].mppe_40 = 0;     /* disable 40-bit */
+           break;
+       default:
+           break;
+diff -ruN ppp-2.4.3.orig/pppd/pppd.8 ppp-2.4.3/pppd/pppd.8
+--- ppp-2.4.3.orig/pppd/pppd.8 2004-11-13 13:22:49.000000000 +0100
++++ ppp-2.4.3/pppd/pppd.8      2004-11-21 14:24:47.000000000 +0100
+@@ -622,9 +622,29 @@
+ Enables the use of PPP multilink; this is an alias for the `multilink'
+ option.  This option is currently only available under Linux.
+ .TP
+-.B mppe\-stateful
+-Allow MPPE to use stateful mode.  Stateless mode is still attempted first.
+-The default is to disallow stateful mode.  
++.B mppc
++Enables MPPC (Microsoft Point to Point Compression).  This is the default.
++.TP
++.B mppe \fIsubopt1[,subopt2[,subopt3[..]]]
++Modify MPPE (Microsoft Point to Point Encryption) parameters. In order
++for MPPE to successfully come up, you must have authenticated with either
++MS-CHAP or MS-CHAPv2. By default MPPE is optional, it means that pppd will
++not propose MPPE to the peer, but will negotiate MPPE if peer wants that.
++You can change this using \fIrequired\fR suboption.
++This option is presently only supported under Linux, and only if your
++kernel has been configured to include MPPE support.
++.IP
++MPPE suboptions:
++.br
++\fIrequired\fR - require MPPE; disconnect if peer doesn't support it,
++.br
++\fIstateless\fR - try to negotiate stateless mode; default is stateful,
++.br
++\fIno40\fR - disable 40 bit keys,
++.br
++\fIno56\fR - disable 56 bit keys,
++.br
++\fIno128\fR - disable 128 bit keys
+ .TP
+ .B mpshortseq
+ Enables the use of short (12-bit) sequence numbers in multilink
+@@ -757,17 +777,11 @@
+ Disables the use of PPP multilink.  This option is currently only
+ available under Linux.
+ .TP
+-.B nomppe
+-Disables MPPE (Microsoft Point to Point Encryption).  This is the default.
+-.TP
+-.B nomppe\-40
+-Disable 40-bit encryption with MPPE.
++.B nomppc
++Disables MPPC (Microsoft Point to Point Compression).
+ .TP
+-.B nomppe\-128
+-Disable 128-bit encryption with MPPE.
+-.TP
+-.B nomppe\-stateful
+-Disable MPPE stateful mode.  This is the default.
++.B nomppe
++Disables MPPE (Microsoft Point to Point Encryption).
+ .TP
+ .B nompshortseq
+ Disables the use of short (12-bit) sequence numbers in the PPP
+@@ -948,19 +962,6 @@
+ Require the peer to authenticate itself using CHAP [Challenge
+ Handshake Authentication Protocol] authentication.
+ .TP
+-.B require\-mppe
+-Require the use of MPPE (Microsoft Point to Point Encryption).  This
+-option disables all other compression types.  This option enables
+-both 40-bit and 128-bit encryption.  In order for MPPE to successfully
+-come up, you must have authenticated with either MS\-CHAP or MS\-CHAPv2.
+-This option is presently only supported under Linux, and only if your
+-kernel has been configured to include MPPE support.
+-.TP
+-.B require\-mppe\-40
+-Require the use of MPPE, with 40-bit encryption.
+-.TP
+-.B require\-mppe\-128
+-Require the use of MPPE, with 128-bit encryption.
+ .TP
+ .B require\-mschap
+ Require the peer to authenticate itself using MS\-CHAP [Microsoft Challenge
diff --git a/openwrt/package/ppp/patches/202-no_atm.patch b/openwrt/package/ppp/patches/202-no_atm.patch
new file mode 100644 (file)
index 0000000..a737cfa
--- /dev/null
@@ -0,0 +1,12 @@
+diff -ruN ppp-2.4.3-orig/pppd/plugins/Makefile.linux ppp-2.4.3-3/pppd/plugins/Makefile.linux
+--- ppp-2.4.3-orig/pppd/plugins/Makefile.linux 2004-11-14 08:57:35.000000000 +0100
++++ ppp-2.4.3-3/pppd/plugins/Makefile.linux    2004-12-05 17:03:59.000000000 +0100
+@@ -9,7 +9,7 @@
+ MANDIR = $(DESTDIR)/share/man/man8
+ LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
+-SUBDIRS := rp-pppoe pppoatm radius
++SUBDIRS := rp-pppoe radius
+ # Uncomment the next line to include the radius authentication plugin
+ # SUBDIRS += radius
+ PLUGINS := minconn.so passprompt.so passwordfd.so winbind.so
diff --git a/openwrt/package/ppp/patches/203-no_strip.patch b/openwrt/package/ppp/patches/203-no_strip.patch
new file mode 100644 (file)
index 0000000..216973c
--- /dev/null
@@ -0,0 +1,86 @@
+diff -ruN ppp-2.4.3-orig/chat/Makefile.linux ppp-2.4.3-3/chat/Makefile.linux
+--- ppp-2.4.3-orig/chat/Makefile.linux 2004-11-03 12:51:47.000000000 +0100
++++ ppp-2.4.3-3/chat/Makefile.linux    2004-12-05 17:42:43.000000000 +0100
+@@ -25,7 +25,7 @@
+ install: chat
+       mkdir -p $(BINDIR)
+-      $(INSTALL) -s -c chat $(BINDIR)
++      $(INSTALL) -c chat $(BINDIR)
+       $(INSTALL) -c -m 644 chat.8 $(MANDIR)
+ clean:
+diff -ruN ppp-2.4.3-orig/pppd/Makefile.linux ppp-2.4.3-3/pppd/Makefile.linux
+--- ppp-2.4.3-orig/pppd/Makefile.linux 2004-11-13 13:02:22.000000000 +0100
++++ ppp-2.4.3-3/pppd/Makefile.linux    2004-12-16 04:43:41.000000000 +0100
+@@ -99,7 +99,7 @@
+ CFLAGS        += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
+ LIBS  += -lsrp -L/usr/local/ssl/lib -lcrypto
+ TARGETS       += srp-entry
+-EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
++EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry
+ MANPAGES += srp-entry.8
+ EXTRACLEAN += srp-entry.o
+ NEEDDES=y
+@@ -202,7 +202,7 @@
+ install: pppd
+       mkdir -p $(BINDIR) $(MANDIR)
+       $(EXTRAINSTALL)
+-      $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd
++      $(INSTALL) -c -m 555 pppd $(BINDIR)/pppd
+       if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \
+         chmod o-rx,u+s $(BINDIR)/pppd; fi
+       $(INSTALL) -c -m 444 pppd.8 $(MANDIR)
+diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux
+--- ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux  2004-11-14 08:02:31.000000000 +0100
++++ ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux     2004-12-05 17:43:17.000000000 +0100
+@@ -36,9 +37,9 @@
+ install: all
+       $(INSTALL) -d -m 755 $(LIBDIR)
+-      $(INSTALL) -s -c -m 755 radius.so $(LIBDIR)
+-      $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR)
+-      $(INSTALL) -s -c -m 755 radrealms.so $(LIBDIR)
++      $(INSTALL) -c -m 755 radius.so $(LIBDIR)
++      $(INSTALL) -c -m 755 radattr.so $(LIBDIR)
++      $(INSTALL) -c -m 755 radrealms.so $(LIBDIR)
+       $(INSTALL) -c -m 444 pppd-radius.8 $(MANDIR)
+       $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
+diff -ruN ppp-2.4.3-orig/pppd/plugins/rp-pppoe/Makefile.linux ppp-2.4.3-3/pppd/plugins/rp-pppoe/Makefile.linux
+--- ppp-2.4.3-orig/pppd/plugins/rp-pppoe/Makefile.linux        2004-11-14 08:58:37.000000000 +0100
++++ ppp-2.4.3-3/pppd/plugins/rp-pppoe/Makefile.linux   2004-12-05 17:43:23.000000000 +0100
+@@ -39,9 +39,9 @@
+ install: all
+       $(INSTALL) -d -m 755 $(LIBDIR)
+-      $(INSTALL) -s -c -m 4550 rp-pppoe.so $(LIBDIR)
++      $(INSTALL) -c -m 4550 rp-pppoe.so $(LIBDIR)
+       $(INSTALL) -d -m 755 $(BINDIR)
+-      $(INSTALL) -s -c -m 555 pppoe-discovery $(BINDIR)
++      $(INSTALL) -c -m 555 pppoe-discovery $(BINDIR)
+ clean:
+       rm -f *.o *.so
+diff -ruN ppp-2.4.3-orig/pppdump/Makefile.linux ppp-2.4.3-3/pppdump/Makefile.linux
+--- ppp-2.4.3-orig/pppdump/Makefile.linux      2004-10-31 02:36:52.000000000 +0200
++++ ppp-2.4.3-3/pppdump/Makefile.linux 2004-12-05 17:50:34.000000000 +0100
+@@ -17,5 +18,5 @@
+ install:
+       mkdir -p $(BINDIR) $(MANDIR)
+-      $(INSTALL) -s -c pppdump $(BINDIR)
++      $(INSTALL) -c pppdump $(BINDIR)
+       $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)
+diff -ruN ppp-2.4.3-orig/pppstats/Makefile.linux ppp-2.4.3-3/pppstats/Makefile.linux
+--- ppp-2.4.3-orig/pppstats/Makefile.linux     2004-10-31 23:09:03.000000000 +0100
++++ ppp-2.4.3-3/pppstats/Makefile.linux        2004-12-05 17:43:38.000000000 +0100
+@@ -22,7 +22,7 @@
+ install: pppstats
+       -mkdir -p $(MANDIR)
+-      $(INSTALL) -s -c pppstats $(BINDIR)
++      $(INSTALL) -c pppstats $(BINDIR)
+       $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)
+ pppstats: $(PPPSTATSRCS)
diff --git a/openwrt/package/ppp/patches/204-opt_flags.patch b/openwrt/package/ppp/patches/204-opt_flags.patch
new file mode 100644 (file)
index 0000000..200e76b
--- /dev/null
@@ -0,0 +1,26 @@
+diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux
+--- ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux  2004-11-14 08:02:31.000000000 +0100
++++ ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux     2004-12-05 17:43:17.000000000 +0100
+@@ -12,7 +12,8 @@
+ INSTALL       = install
+ PLUGIN=radius.so radattr.so radrealms.so
+-CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
++COPTS = -O2
++CFLAGS=-I. -I../.. -I../../../include $(COPTS) -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
+ # Uncomment the next line to include support for Microsoft's
+ # MS-CHAP authentication protocol.
+diff -ruN ppp-2.4.3-orig/pppdump/Makefile.linux ppp-2.4.3-3/pppdump/Makefile.linux
+--- ppp-2.4.3-orig/pppdump/Makefile.linux      2004-10-31 02:36:52.000000000 +0200
++++ ppp-2.4.3-3/pppdump/Makefile.linux 2004-12-05 17:50:34.000000000 +0100
+@@ -2,7 +2,8 @@
+ BINDIR = $(DESTDIR)/sbin
+ MANDIR = $(DESTDIR)/share/man/man8
+-CFLAGS= -O -I../include/net
++COPTS = -O
++CFLAGS= $(COPTS) -I../include/net
+ OBJS = pppdump.o bsd-comp.o deflate.o zlib.o
+ INSTALL= install
diff --git a/openwrt/package/ppp/patches/205-pppoe_iface_name.patch b/openwrt/package/ppp/patches/205-pppoe_iface_name.patch
new file mode 100644 (file)
index 0000000..522d587
--- /dev/null
@@ -0,0 +1,12 @@
+diff -ruN ppp-2.4.3-orig/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.3-3/pppd/plugins/rp-pppoe/plugin.c
+--- ppp-2.4.3-orig/pppd/plugins/rp-pppoe/plugin.c      2004-11-04 11:07:37.000000000 +0100
++++ ppp-2.4.3-3/pppd/plugins/rp-pppoe/plugin.c 2004-12-16 01:07:22.000000000 +0100
+@@ -286,7 +286,7 @@
+       /* Strip off "nic-" */
+       cmd += 4;
+     } else if (strlen(cmd) < 4
+-             || (strncmp(cmd, "eth", 3) && strncmp(cmd, "nas", 3)
++             || (strncmp(cmd, "eth", 3) && strncmp(cmd, "nas", 3) && strncmp(cmd, "vlan", 4)
+                  && strncmp(cmd, "tap", 3) && strncmp(cmd, "br", 2))) {
+       return 0;
+     }
diff --git a/openwrt/package/ppp/patches/206-radius_config.patch b/openwrt/package/ppp/patches/206-radius_config.patch
new file mode 100644 (file)
index 0000000..90c02af
--- /dev/null
@@ -0,0 +1,74 @@
+diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/config.c ppp-2.4.3-3/pppd/plugins/radius/config.c
+--- ppp-2.4.3-orig/pppd/plugins/radius/config.c        2004-11-14 08:26:26.000000000 +0100
++++ ppp-2.4.3-3/pppd/plugins/radius/config.c   2004-12-16 04:03:46.000000000 +0100
+@@ -369,31 +369,37 @@
+       }
+ #endif
++#if 0
+       if (rc_conf_int("login_tries") <= 0)
+       {
+               error("%s: login_tries <= 0 is illegal", filename);
+               return (-1);
+       }
++#endif
+       if (rc_conf_str("seqfile") == NULL)
+       {
+               error("%s: seqfile not specified", filename);
+               return (-1);
+       }
++#if 0
+       if (rc_conf_int("login_timeout") <= 0)
+       {
+               error("%s: login_timeout <= 0 is illegal", filename);
+               return (-1);
+       }
++#endif
+       if (rc_conf_str("mapfile") == NULL)
+       {
+               error("%s: mapfile not specified", filename);
+               return (-1);
+       }
++#if 0
+       if (rc_conf_str("nologin") == NULL)
+       {
+               error("%s: nologin not specified", filename);
+               return (-1);
+       }
++#endif
+       return 0;
+ }
+diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/options.h ppp-2.4.3-3/pppd/plugins/radius/options.h
+--- ppp-2.4.3-orig/pppd/plugins/radius/options.h       2004-11-14 08:26:26.000000000 +0100
++++ ppp-2.4.3-3/pppd/plugins/radius/options.h  2004-12-16 04:09:16.000000000 +0100
+@@ -31,24 +31,21 @@
+ static SERVER acctserver = {0};
+ static SERVER authserver = {0};
+-int default_tries = 4;
+-int default_timeout = 60;
+-
+ static OPTION config_options[] = {
+ /* internally used options */
+ {"config_file",               OT_STR, ST_UNDEF, NULL},
+ /* General options */
+ {"auth_order",                OT_AUO, ST_UNDEF, NULL},
+-{"login_tries",               OT_INT, ST_UNDEF, &default_tries},
+-{"login_timeout",     OT_INT, ST_UNDEF, &default_timeout},
+-{"nologin",           OT_STR, ST_UNDEF, "/etc/nologin"},
+-{"issue",             OT_STR, ST_UNDEF, "/etc/radiusclient/issue"},
++{"login_tries",               OT_INT, ST_UNDEF, NULL},
++{"login_timeout",     OT_INT, ST_UNDEF, NULL},
++{"nologin",           OT_STR, ST_UNDEF, NULL},
++{"issue",             OT_STR, ST_UNDEF, NULL},
+ /* RADIUS specific options */
+ {"authserver",                OT_SRV, ST_UNDEF, &authserver},
+ {"acctserver",                OT_SRV, ST_UNDEF, &acctserver},
+ {"servers",           OT_STR, ST_UNDEF, NULL},
+ {"dictionary",                OT_STR, ST_UNDEF, NULL},
+-{"login_radius",      OT_STR, ST_UNDEF, "/usr/sbin/login.radius"},
++{"login_radius",      OT_STR, ST_UNDEF, NULL},
+ {"seqfile",           OT_STR, ST_UNDEF, NULL},
+ {"mapfile",           OT_STR, ST_UNDEF, NULL},
+ {"default_realm",     OT_STR, ST_UNDEF, NULL},
diff --git a/openwrt/package/ppp/patches/ppp-2.4.3-makefile.patch b/openwrt/package/ppp/patches/ppp-2.4.3-makefile.patch
deleted file mode 100644 (file)
index 5bbf860..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-diff -ruN ppp-2.4.3-orig/pppd/Makefile.linux ppp-2.4.3-3/pppd/Makefile.linux
---- ppp-2.4.3-orig/pppd/Makefile.linux 2004-11-13 13:02:22.000000000 +0100
-+++ ppp-2.4.3-3/pppd/Makefile.linux    2004-12-16 04:43:41.000000000 +0100
-@@ -48,19 +48,19 @@
- # Uncomment the next line to include support for PPP packet filtering.
- # This requires that the libpcap library and headers be installed
- # and that the kernel driver support PPP packet filtering.
--FILTER=y
-+#FILTER=y
- # Uncomment the next line to enable multilink PPP (enabled by default)
- # Linux distributions: Please leave multilink ENABLED in your builds
- # of pppd!
--HAVE_MULTILINK=y
-+#HAVE_MULTILINK=y
- # Uncomment the next line to enable the TDB database (enabled by default.)
- # If you enable multilink, then TDB is automatically enabled also.
- # Linux distributions: Please leave TDB ENABLED in your builds.
--USE_TDB=y
-+#USE_TDB=y
--HAS_SHADOW=y
-+#HAS_SHADOW=y
- #USE_PAM=y
- #HAVE_INET6=y
-@@ -77,7 +77,7 @@
- INCLUDE_DIRS= -I../include
--COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP
-+COMPILE_FLAGS= -DHAVE_PATHS_H -DHAVE_MMAP
- CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS)
-@@ -117,12 +117,12 @@
- #LIBS     += -lshadow $(LIBS)
- endif
--ifneq ($(wildcard /usr/include/crypt.h),)
-+#ifneq ($(wildcard /usr/include/crypt.h),)
- CFLAGS   += -DHAVE_CRYPT_H=1
--endif
--ifneq ($(wildcard /usr/lib/libcrypt.*),)
-+#endif
-+#ifneq ($(wildcard /usr/lib/libcrypt.*),)
- LIBS  += -lcrypt
--endif
-+#endif
- ifdef NEEDDES
- ifndef USE_CRYPT
diff --git a/openwrt/package/ppp/patches/ppp-2.4.3-mppe-mppc-1.1.patch b/openwrt/package/ppp/patches/ppp-2.4.3-mppe-mppc-1.1.patch
deleted file mode 100644 (file)
index 7e09f1a..0000000
+++ /dev/null
@@ -1,1585 +0,0 @@
-diff -ruN ppp-2.4.3.orig/include/linux/ppp-comp.h ppp-2.4.3/include/linux/ppp-comp.h
---- ppp-2.4.3.orig/include/linux/ppp-comp.h    2002-12-06 10:49:15.000000000 +0100
-+++ ppp-2.4.3/include/linux/ppp-comp.h 2004-11-21 13:54:09.000000000 +0100
-@@ -36,7 +36,7 @@
-  */
- /*
-- *  ==FILEVERSION 20020319==
-+ *  ==FILEVERSION 20020715==
-  *
-  *  NOTE TO MAINTAINERS:
-  *     If you modify this file at all, please set the above date.
-@@ -86,7 +86,7 @@
-       /* Compress a packet */
-       int     (*compress) (void *state, unsigned char *rptr,
--                            unsigned char *obuf, int isize, int osize);
-+                           unsigned char *obuf, int isize, int osize);
-       /* Return compression statistics */
-       void    (*comp_stat) (void *state, struct compstat *stats);
-@@ -107,7 +107,7 @@
-       /* Decompress a packet. */
-       int     (*decompress) (void *state, unsigned char *ibuf, int isize,
--                              unsigned char *obuf, int osize);
-+                             unsigned char *obuf, int osize);
-       /* Update state for an incompressible packet received */
-       void    (*incomp) (void *state, unsigned char *ibuf, int icnt);
-@@ -288,6 +288,33 @@
-           opts |= MPPE_OPT_UNKNOWN;           \
-     } while (/* CONSTCOND */ 0)
-+/* MPPE/MPPC definitions by J.D.*/
-+#define MPPE_STATELESS          MPPE_H_BIT    /* configuration bit H */
-+#define MPPE_40BIT              MPPE_L_BIT    /* configuration bit L */
-+#define MPPE_56BIT              MPPE_M_BIT    /* configuration bit M */
-+#define MPPE_128BIT             MPPE_S_BIT    /* configuration bit S */
-+#define MPPE_MPPC               MPPE_C_BIT    /* configuration bit C */
-+
-+/*
-+ * Definitions for Stac LZS.
-+ */
-+
-+#define CI_LZS                        17      /* config option for Stac LZS */
-+#define CILEN_LZS             5       /* length of config option */
-+
-+#define LZS_OVHD              4       /* max. LZS overhead */
-+#define LZS_HIST_LEN          2048    /* LZS history size */
-+#define LZS_MAX_CCOUNT                0x0FFF  /* max. coherency counter value */
-+
-+#define LZS_MODE_NONE         0
-+#define LZS_MODE_LCB          1
-+#define LZS_MODE_CRC          2
-+#define LZS_MODE_SEQ          3
-+#define LZS_MODE_EXT          4
-+
-+#define LZS_EXT_BIT_FLUSHED   0x80    /* bit A */
-+#define LZS_EXT_BIT_COMP      0x20    /* bit C */
-+
- /*
-  * Definitions for other, as yet unsupported, compression methods.
-  */
-diff -ruN ppp-2.4.3.orig/include/net/ppp-comp.h ppp-2.4.3/include/net/ppp-comp.h
---- ppp-2.4.3.orig/include/net/ppp-comp.h      2002-12-06 10:49:15.000000000 +0100
-+++ ppp-2.4.3/include/net/ppp-comp.h   2004-11-21 13:54:09.000000000 +0100
-@@ -255,6 +255,33 @@
-           opts |= MPPE_OPT_UNKNOWN;           \
-     } while (/* CONSTCOND */ 0)
-+/* MPPE/MPPC definitions by J.D.*/
-+#define MPPE_STATELESS          MPPE_H_BIT    /* configuration bit H */
-+#define MPPE_40BIT              MPPE_L_BIT    /* configuration bit L */
-+#define MPPE_56BIT              MPPE_M_BIT    /* configuration bit M */
-+#define MPPE_128BIT             MPPE_S_BIT    /* configuration bit S */
-+#define MPPE_MPPC               MPPE_C_BIT    /* configuration bit C */
-+
-+/*
-+ * Definitions for Stac LZS.
-+ */
-+
-+#define CI_LZS                        17      /* config option for Stac LZS */
-+#define CILEN_LZS             5       /* length of config option */
-+
-+#define LZS_OVHD              4       /* max. LZS overhead */
-+#define LZS_HIST_LEN          2048    /* LZS history size */
-+#define LZS_MAX_CCOUNT                0x0FFF  /* max. coherency counter value */
-+
-+#define LZS_MODE_NONE         0
-+#define LZS_MODE_LCB          1
-+#define LZS_MODE_CRC          2
-+#define LZS_MODE_SEQ          3
-+#define LZS_MODE_EXT          4
-+
-+#define LZS_EXT_BIT_FLUSHED   0x80    /* bit A */
-+#define LZS_EXT_BIT_COMP      0x20    /* bit C */
-+
- /*
-  * Definitions for other, as yet unsupported, compression methods.
-  */
-diff -ruN ppp-2.4.3.orig/pppd/ccp.c ppp-2.4.3/pppd/ccp.c
---- ppp-2.4.3.orig/pppd/ccp.c  2004-11-13 03:28:15.000000000 +0100
-+++ ppp-2.4.3/pppd/ccp.c       2004-11-21 13:54:09.000000000 +0100
-@@ -62,12 +62,10 @@
- static char bsd_value[8];
- static char deflate_value[8];
--/*
-- * Option variables.
-- */
- #ifdef MPPE
--bool refuse_mppe_stateful = 1;                /* Allow stateful mode? */
--#endif
-+static int setmppe(char **);
-+static int setnomppe(void);
-+#endif /* MPPE */
- static option_t ccp_option_list[] = {
-     { "noccp", o_bool, &ccp_protent.enabled_flag,
-@@ -108,54 +106,36 @@
-       "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
-       &ccp_allowoptions[0].predictor_1 },
-+    { "lzs", o_bool, &ccp_wantoptions[0].lzs,
-+      "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_PRIO },
-+    { "+lzs", o_bool, &ccp_wantoptions[0].lzs,
-+      "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_ALIAS | OPT_PRIO },
-+    { "nolzs", o_bool, &ccp_wantoptions[0].lzs,
-+      "don't allow Stac LZS", OPT_PRIOSUB | OPT_A2CLR,
-+      &ccp_allowoptions[0].lzs },
-+    { "-lzs", o_bool, &ccp_wantoptions[0].lzs,
-+      "don't allow Stac LZS", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
-+      &ccp_allowoptions[0].lzs },
-+
- #ifdef MPPE
--    /* MPPE options are symmetrical ... we only set wantoptions here */
--    { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
--      "require MPPE encryption",
--      OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
--    { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
--      "require MPPE encryption",
--      OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
--    { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
--      "don't allow MPPE encryption", OPT_PRIO },
--    { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
--      "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
--
--    /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
--    { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
--      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
--      &ccp_wantoptions[0].mppe },
--    { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
--      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
--      &ccp_wantoptions[0].mppe },
--    { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
--      "don't allow MPPE 40-bit encryption",
--      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
--    { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
--      "don't allow MPPE 40-bit encryption",
--      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
--      &ccp_wantoptions[0].mppe },
--
--    { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
--      "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
--      &ccp_wantoptions[0].mppe },
--    { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
--      "require MPPE 128-bit encryption",
--      OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
--      &ccp_wantoptions[0].mppe },
--    { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
--      "don't allow MPPE 128-bit encryption",
--      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
--    { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
--      "don't allow MPPE 128-bit encryption",
--      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
--      &ccp_wantoptions[0].mppe },
--
--    /* strange one; we always request stateless, but will we allow stateful? */
--    { "mppe-stateful", o_bool, &refuse_mppe_stateful,
--      "allow MPPE stateful mode", OPT_PRIO },
--    { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
--      "disallow MPPE stateful mode", OPT_PRIO | 1 },
-+    { "mppc", o_bool, &ccp_wantoptions[0].mppc,
-+      "request MPPC compression", 1, &ccp_allowoptions[0].mppc },
-+    { "+mppc", o_bool, &ccp_wantoptions[0].mppc,
-+      "request MPPC compression", 1, &ccp_allowoptions[0].mppc, OPT_ALIAS },
-+    { "nomppc", o_bool, &ccp_wantoptions[0].mppc,
-+      "don't allow MPPC compression", OPT_PRIOSUB | OPT_A2CLR,
-+      &ccp_allowoptions[0].mppc },
-+    { "-mppc", o_bool, &ccp_wantoptions[0].mppc,
-+      "don't allow MPPC compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
-+      &ccp_allowoptions[0].mppc },
-+    { "mppe", o_special, (void *)setmppe,
-+      "request MPPE encryption" },
-+    { "+mppe", o_special, (void *)setmppe,
-+      "request MPPE encryption" },
-+    { "nomppe", o_special_noarg, (void *)setnomppe,
-+      "don't allow MPPE encryption" },
-+    { "-mppe", o_special_noarg, (void *)setnomppe,
-+      "don't allow MPPE encryption" },
- #endif /* MPPE */
-     { NULL }
-@@ -241,7 +221,7 @@
-  */
- #define ANY_COMPRESS(opt)     ((opt).deflate || (opt).bsd_compress \
-                                || (opt).predictor_1 || (opt).predictor_2 \
--                               || (opt).mppe)
-+                               || (opt).lzs || (opt).mppc || (opt).mppe)
- /*
-  * Local state (mainly for handling reset-reqs and reset-acks).
-@@ -344,6 +324,100 @@
-     return 1;
- }
-+#ifdef MPPE
-+/*
-+ * Functions called from config options
-+ */
-+/* 
-+   MPPE suboptions:
-+      required - require MPPE; disconnect if peer doesn't support it
-+      stateless - use stateless mode
-+      no40 - disable 40 bit keys
-+      no56 - disable 56 bit keys
-+      no128 - disable 128 bit keys
-+*/
-+int setmppe(char **argv)
-+{
-+    int i;
-+    char *str, cmdbuf[16];
-+
-+    ccp_allowoptions[0].mppe = 1;
-+    ccp_allowoptions[0].mppe_40 = 1;
-+    ccp_allowoptions[0].mppe_56 = 1;
-+    ccp_allowoptions[0].mppe_128 = 1;
-+    ccp_allowoptions[0].mppe_stateless = 0;
-+    ccp_wantoptions[0].mppe = 0;
-+
-+    str = *argv;
-+
-+    while (1) {
-+      i = 0;
-+      memset(cmdbuf, '\0', 16);
-+      while ((i < 16) && (*str != ',') && (*str != '\0'))
-+          cmdbuf[i++] = *str++;
-+      cmdbuf[i] = '\0';
-+      if (!strncasecmp(cmdbuf, "no40", strlen("no40"))) {
-+          ccp_allowoptions[0].mppe_40 = 0;
-+          goto next_param;
-+      } else if (!strncasecmp(cmdbuf, "no56", strlen("no56"))) {
-+          ccp_allowoptions[0].mppe_56 = 0;
-+          goto next_param;
-+      } else if (!strncasecmp(cmdbuf, "no128", strlen("no128"))) {
-+          ccp_allowoptions[0].mppe_128 = 0;
-+          goto next_param;
-+      } else if (!strncasecmp(cmdbuf, "stateless", strlen("stateless"))) {
-+          ccp_allowoptions[0].mppe_stateless = 1;
-+          goto next_param;
-+      } else if (!strncasecmp(cmdbuf, "required", strlen("required"))) {
-+          ccp_wantoptions[0].mppe = 1;
-+          goto next_param;
-+      } else {
-+          option_error("invalid parameter '%s' for mppe option", cmdbuf);
-+          return 0;
-+      }
-+
-+    next_param:
-+      if (*str == ',') {
-+          str++;
-+          continue;
-+      }
-+      if (*str == '\0') {
-+          if (!(ccp_allowoptions[0].mppe_40 || ccp_allowoptions[0].mppe_56 ||
-+                ccp_allowoptions[0].mppe_128)) {
-+              if (ccp_wantoptions[0].mppe == 1) {
-+                  option_error("You require MPPE but you have switched off "
-+                               "all encryption key lengths.");
-+                  return 0;
-+              }
-+              ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
-+              ccp_wantoptions[0].mppe_stateless =
-+                  ccp_allowoptions[0].mppe_stateless = 0;
-+          } else {
-+              ccp_allowoptions[0].mppe = 1;
-+              ccp_wantoptions[0].mppe_stateless =
-+                  ccp_allowoptions[0].mppe_stateless;
-+              if (ccp_wantoptions[0].mppe == 1) {
-+                  ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40;
-+                  ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56;
-+                  ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128;
-+              }
-+          }
-+          return 1;
-+      }
-+    }
-+}
-+
-+int setnomppe(void)
-+{
-+    ccp_wantoptions[0].mppe = ccp_allowoptions[0].mppe = 0;
-+    ccp_wantoptions[0].mppe_40 = ccp_allowoptions[0].mppe_40 = 0;
-+    ccp_wantoptions[0].mppe_56 = ccp_allowoptions[0].mppe_56 = 0;
-+    ccp_wantoptions[0].mppe_128 = ccp_allowoptions[0].mppe_128 = 0;
-+    ccp_wantoptions[0].mppe_stateless = ccp_allowoptions[0].mppe_stateless = 0;
-+    return 1;
-+}
-+#endif /* MPPE */
-+
- /*
-  * ccp_init - initialize CCP.
-  */
-@@ -378,6 +452,30 @@
-     ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
-     ccp_allowoptions[0].predictor_1 = 1;
-+
-+    ccp_wantoptions[0].lzs = 0; /* Stac LZS  - will be enabled in the future */
-+    ccp_wantoptions[0].lzs_mode = LZS_MODE_SEQ;
-+    ccp_wantoptions[0].lzs_hists = 1;
-+    ccp_allowoptions[0].lzs = 0; /* Stac LZS  - will be enabled in the future */
-+    ccp_allowoptions[0].lzs_mode = LZS_MODE_SEQ;
-+    ccp_allowoptions[0].lzs_hists = 1;
-+
-+#ifdef MPPE
-+    /* by default allow and request MPPC... */
-+    ccp_wantoptions[0].mppc = ccp_allowoptions[0].mppc = 1;
-+
-+    /* ... and allow but don't request MPPE */
-+    ccp_allowoptions[0].mppe = 1;
-+    ccp_allowoptions[0].mppe_40 = 1;
-+    ccp_allowoptions[0].mppe_56 = 1;
-+    ccp_allowoptions[0].mppe_128 = 1;
-+    ccp_allowoptions[0].mppe_stateless = 1;
-+    ccp_wantoptions[0].mppe = 0;
-+    ccp_wantoptions[0].mppe_40 = 0;
-+    ccp_wantoptions[0].mppe_56 = 0;
-+    ccp_wantoptions[0].mppe_128 = 0;
-+    ccp_wantoptions[0].mppe_stateless = 0;
-+#endif /* MPPE */
- }
- /*
-@@ -455,11 +553,11 @@
-     if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {
-       notice("Compression disabled by peer.");
- #ifdef MPPE
--      if (ccp_gotoptions[unit].mppe) {
-+      if (ccp_wantoptions[unit].mppe) {
-           error("MPPE disabled, closing LCP");
-           lcp_close(unit, "MPPE disabled by peer");
-       }
--#endif
-+#endif /* MPPE */
-     }
-     /*
-@@ -487,6 +585,15 @@
-           break;
-       /* send a reset-ack, which the transmitter will see and
-          reset its compression state. */
-+
-+      /* In case of MPPE/MPPC or LZS we shouldn't send CCP_RESETACK,
-+         but we do it in order to reset compressor; CCP_RESETACK is
-+         then silently discarded. See functions ppp_send_frame and
-+         ppp_ccp_peek in ppp_generic.c (Linux only !!!). All the
-+         confusion is caused by the fact that CCP code is splited
-+         into two parts - one part is handled by pppd, the other one
-+         is handled by kernel. */
-+
-       fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
-       break;
-@@ -515,12 +622,11 @@
-     fsm_lowerdown(&ccp_fsm[unit]);
- #ifdef MPPE
--    if (ccp_gotoptions[unit].mppe) {
-+    if (ccp_wantoptions[unit].mppe) {
-       error("MPPE required but peer negotiation failed");
-       lcp_close(unit, "MPPE required but peer negotiation failed");
-     }
--#endif
--
-+#endif /* MPPE */
- }
- /*
-@@ -537,7 +643,7 @@
-     all_rejected[f->unit] = 0;
- #ifdef MPPE
--    if (go->mppe) {
-+    if (go->mppe || go->mppc) {
-       ccp_options *ao = &ccp_allowoptions[f->unit];
-       int auth_mschap_bits = auth_done[f->unit];
-       int numbits;
-@@ -551,80 +657,109 @@
-        * NB: If MPPE is required, all other compression opts are invalid.
-        *     So, we return right away if we can't do it.
-        */
-+      if (ccp_wantoptions[f->unit].mppe) {
-+          /* Leave only the mschap auth bits set */
-+          auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
-+                               CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
-+          /* Count the mschap auths */
-+          auth_mschap_bits >>= CHAP_MS_SHIFT;
-+          numbits = 0;
-+          do {
-+              numbits += auth_mschap_bits & 1;
-+              auth_mschap_bits >>= 1;
-+          } while (auth_mschap_bits);
-+          if (numbits > 1) {
-+              error("MPPE required, but auth done in both directions.");
-+              lcp_close(f->unit, "MPPE required but not available");
-+              return;
-+          }
-+          if (!numbits) {
-+              error("MPPE required, but MS-CHAP[v2] auth not performed.");
-+              lcp_close(f->unit, "MPPE required but not available");
-+              return;
-+          }
--      /* Leave only the mschap auth bits set */
--      auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
--                           CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
--      /* Count the mschap auths */
--      auth_mschap_bits >>= CHAP_MS_SHIFT;
--      numbits = 0;
--      do {
--          numbits += auth_mschap_bits & 1;
--          auth_mschap_bits >>= 1;
--      } while (auth_mschap_bits);
--      if (numbits > 1) {
--          error("MPPE required, but auth done in both directions.");
--          lcp_close(f->unit, "MPPE required but not available");
--          return;
--      }
--      if (!numbits) {
--          error("MPPE required, but MS-CHAP[v2] auth not performed.");
--          lcp_close(f->unit, "MPPE required but not available");
--          return;
--      }
--
--      /* A plugin (eg radius) may not have obtained key material. */
--      if (!mppe_keys_set) {
--          error("MPPE required, but keys are not available.  "
--                "Possible plugin problem?");
--          lcp_close(f->unit, "MPPE required but not available");
--          return;
--      }
--
--      /* LM auth not supported for MPPE */
--      if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
--          /* This might be noise */
--          if (go->mppe & MPPE_OPT_40) {
--              notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
--              go->mppe &= ~MPPE_OPT_40;
--              ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
-+          /* A plugin (eg radius) may not have obtained key material. */
-+          if (!mppe_keys_set) {
-+              error("MPPE required, but keys are not available.  "
-+                    "Possible plugin problem?");
-+              lcp_close(f->unit, "MPPE required but not available");
-+              return;
-           }
-       }
--      /* Last check: can we actually negotiate something? */
--      if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
--          /* Could be misconfig, could be 40-bit disabled above. */
--          error("MPPE required, but both 40-bit and 128-bit disabled.");
--          lcp_close(f->unit, "MPPE required but not available");
--          return;
-+      /*
-+       * Check whether the kernel knows about the various
-+       * compression methods we might request. Key material
-+       * unimportant here.
-+       */
-+      if (go->mppc) {
-+          opt_buf[0] = CI_MPPE;
-+          opt_buf[1] = CILEN_MPPE;
-+          opt_buf[2] = 0;
-+          opt_buf[3] = 0;
-+          opt_buf[4] = 0;
-+          opt_buf[5] = MPPE_MPPC;
-+          if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 0) <= 0)
-+              go->mppc = 0;
-+      }
-+      if (go->mppe_40) {
-+          opt_buf[0] = CI_MPPE;
-+          opt_buf[1] = CILEN_MPPE;
-+          opt_buf[2] = MPPE_STATELESS;
-+          opt_buf[3] = 0;
-+          opt_buf[4] = 0;
-+          opt_buf[5] = MPPE_40BIT;
-+          if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
-+              go->mppe_40 = 0;
-+      }
-+      if (go->mppe_56) {
-+          opt_buf[0] = CI_MPPE;
-+          opt_buf[1] = CILEN_MPPE;
-+          opt_buf[2] = MPPE_STATELESS;
-+          opt_buf[3] = 0;
-+          opt_buf[4] = 0;
-+          opt_buf[5] = MPPE_56BIT;
-+          if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
-+              go->mppe_56 = 0;
-+      }
-+      if (go->mppe_128) {
-+          opt_buf[0] = CI_MPPE;
-+          opt_buf[1] = CILEN_MPPE;
-+          opt_buf[2] = MPPE_STATELESS;
-+          opt_buf[3] = 0;
-+          opt_buf[4] = 0;
-+          opt_buf[5] = MPPE_128BIT;
-+          if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
-+              go->mppe_128 = 0;
-+      }
-+      if (!go->mppe_40 && !go->mppe_56 && !go->mppe_128) {
-+          if (ccp_wantoptions[f->unit].mppe) {
-+              error("MPPE required, but kernel has no support.");
-+              lcp_close(f->unit, "MPPE required but not available");
-+          }
-+          go->mppe = go->mppe_stateless = 0;
-+      } else {
-+          /* MPPE is not compatible with other compression types */
-+          if (ccp_wantoptions[f->unit].mppe) {
-+              ao->bsd_compress = go->bsd_compress = 0;
-+              ao->predictor_1  = go->predictor_1  = 0;
-+              ao->predictor_2  = go->predictor_2  = 0;
-+              ao->deflate      = go->deflate      = 0;
-+              ao->lzs          = go->lzs          = 0;
-+          }
-       }
--
--      /* sync options */
--      ao->mppe = go->mppe;
--      /* MPPE is not compatible with other compression types */
--      ao->bsd_compress = go->bsd_compress = 0;
--      ao->predictor_1  = go->predictor_1  = 0;
--      ao->predictor_2  = go->predictor_2  = 0;
--      ao->deflate      = go->deflate      = 0;
-     }
- #endif /* MPPE */
--
--    /*
--     * Check whether the kernel knows about the various
--     * compression methods we might request.
--     */
--#ifdef MPPE
--    if (go->mppe) {
--      opt_buf[0] = CI_MPPE;
--      opt_buf[1] = CILEN_MPPE;
--      MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
--      /* Key material unimportant here. */
--      if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) {
--          error("MPPE required, but kernel has no support.");
--          lcp_close(f->unit, "MPPE required but not available");
--      }
-+    if (go->lzs) {
-+      opt_buf[0] = CI_LZS;
-+      opt_buf[1] = CILEN_LZS;
-+      opt_buf[2] = go->lzs_hists >> 8;
-+      opt_buf[3] = go->lzs_hists & 0xff;
-+      opt_buf[4] = LZS_MODE_SEQ;
-+      if (ccp_test(f->unit, opt_buf, CILEN_LZS, 0) <= 0)
-+          go->lzs = 0;
-     }
--#endif
-     if (go->bsd_compress) {
-       opt_buf[0] = CI_BSD_COMPRESS;
-       opt_buf[1] = CILEN_BSD_COMPRESS;
-@@ -679,7 +814,8 @@
-       + (go->deflate? CILEN_DEFLATE: 0)
-       + (go->predictor_1? CILEN_PREDICTOR_1: 0)
-       + (go->predictor_2? CILEN_PREDICTOR_2: 0)
--      + (go->mppe? CILEN_MPPE: 0);
-+      + (go->lzs? CILEN_LZS: 0)
-+      + ((go->mppe || go->mppc)? CILEN_MPPE: 0);
- }
- /*
-@@ -693,6 +829,8 @@
- {
-     int res;
-     ccp_options *go = &ccp_gotoptions[f->unit];
-+    ccp_options *ao = &ccp_allowoptions[f->unit];
-+    ccp_options *wo = &ccp_wantoptions[f->unit];
-     u_char *p0 = p;
-     /*
-@@ -701,22 +839,43 @@
-      * in case it gets Acked.
-      */
- #ifdef MPPE
--    if (go->mppe) {
-+    if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
-       u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
--      p[0] = opt_buf[0] = CI_MPPE;
--      p[1] = opt_buf[1] = CILEN_MPPE;
--      MPPE_OPTS_TO_CI(go->mppe, &p[2]);
--      MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
-+      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_56 ? MPPE_56BIT : 0) |
-+          (go->mppe_128 ? MPPE_128BIT : 0) | (go->mppc ? MPPE_MPPC : 0);
-+
-+      BCOPY(p, opt_buf, CILEN_MPPE);
-       BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
-       res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
--      if (res > 0)
-+      if (res > 0) {
-           p += CILEN_MPPE;
--      else
-+      } else {
-           /* This shouldn't happen, we've already tested it! */
--          lcp_close(f->unit, "MPPE required but not available in kernel");
-+          go->mppe = go->mppe_40 = go->mppe_56 = go->mppe_128 =
-+              go->mppe_stateless = go->mppc = 0;
-+          if (ccp_wantoptions[f->unit].mppe)
-+              lcp_close(f->unit, "MPPE required but not available in kernel");
-+      }
-+    }
-+#endif /* MPPE */
-+    if (go->lzs) {
-+      p[0] = CI_LZS;
-+      p[1] = CILEN_LZS;
-+      p[2] = go->lzs_hists >> 8;
-+      p[3] = go->lzs_hists & 0xff;
-+      p[4] = LZS_MODE_SEQ;
-+      res = ccp_test(f->unit, p, CILEN_LZS, 0);
-+      if (res > 0) {
-+          p += CILEN_LZS;
-+      } else
-+          go->lzs = 0;
-     }
--#endif
-     if (go->deflate) {
-       p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
-       p[1] = CILEN_DEFLATE;
-@@ -802,7 +961,7 @@
- /*
-  * ccp_ackci - process a received configure-ack, and return
-- * 1 iff the packet was OK.
-+ * 1 if the packet was OK.
-  */
- static int
- ccp_ackci(f, p, len)
-@@ -811,24 +970,44 @@
-     int len;
- {
-     ccp_options *go = &ccp_gotoptions[f->unit];
-+    ccp_options *ao = &ccp_allowoptions[f->unit];
-+    ccp_options *wo = &ccp_wantoptions[f->unit];
-     u_char *p0 = p;
- #ifdef MPPE
--    if (go->mppe) {
--      u_char opt_buf[CILEN_MPPE];
--
--      opt_buf[0] = CI_MPPE;
--      opt_buf[1] = CILEN_MPPE;
--      MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
--      if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
-+    if (go->mppe || go->mppc || (!wo->mppe && ao->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->mppc ? MPPE_MPPC : 0))
-+              && p[5] != ((go->mppe_56 ? MPPE_56BIT : 0) |
-+                          (go->mppc ? MPPE_MPPC : 0))
-+              && p[5] != ((go->mppe_128 ? MPPE_128BIT : 0) |
-+                          (go->mppc ? MPPE_MPPC : 0))))
-           return 0;
-+      if (go->mppe_40 || go->mppe_56 || go->mppe_128)
-+          go->mppe = 1;
-       p += CILEN_MPPE;
-       len -= CILEN_MPPE;
-+      /* Cope with first/fast ack */
-+      if (p == p0 && len == 0)
-+          return 1;
-+    }
-+#endif /* MPPE */
-+    if (go->lzs) {
-+      if (len < CILEN_LZS || p[0] != CI_LZS || p[1] != CILEN_LZS
-+          || p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff)
-+          || p[4] != LZS_MODE_SEQ)
-+          return 0;
-+      p += CILEN_LZS;
-+      len -= CILEN_LZS;
-       /* XXX Cope with first/fast ack */
--      if (len == 0)
-+      if (p == p0 && len == 0)
-           return 1;
-     }
--#endif
-     if (go->deflate) {
-       if (len < CILEN_DEFLATE
-           || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
-@@ -891,7 +1070,7 @@
- /*
-  * ccp_nakci - process received configure-nak.
-- * Returns 1 iff the nak was OK.
-+ * Returns 1 if the nak was OK.
-  */
- static int
- ccp_nakci(f, p, len, treat_as_reject)
-@@ -900,6 +1079,8 @@
-     int len;
- {
-     ccp_options *go = &ccp_gotoptions[f->unit];
-+    ccp_options *ao = &ccp_allowoptions[f->unit];
-+    ccp_options *wo = &ccp_wantoptions[f->unit];
-     ccp_options no;           /* options we've seen already */
-     ccp_options try;          /* options to ask for next time */
-@@ -907,28 +1088,100 @@
-     try = *go;
- #ifdef MPPE
--    if (go->mppe && len >= CILEN_MPPE
--      && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
--      no.mppe = 1;
--      /*
--       * Peer wants us to use a different strength or other setting.
--       * Fail if we aren't willing to use his suggestion.
--       */
--      MPPE_CI_TO_OPTS(&p[2], try.mppe);
--      if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) {
--          error("Refusing MPPE stateful mode offered by peer");
--          try.mppe = 0;
--      } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) {
--          /* Peer must have set options we didn't request (suggest) */
--          try.mppe = 0;
--      }
-+    if ((go->mppe || go->mppc || (!wo->mppe && ao->mppe)) &&
-+      len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
--      if (!try.mppe) {
--          error("MPPE required but peer negotiation failed");
--          lcp_close(f->unit, "MPPE required but peer negotiation failed");
-+      if (go->mppc) {
-+          no.mppc = 1;
-+          if (!(p[5] & MPPE_MPPC))
-+              try.mppc = 0;
-+      }
-+
-+      if (go->mppe)
-+          no.mppe = 1;
-+      if (go->mppe_40)
-+          no.mppe_40 = 1;
-+      if (go->mppe_56)
-+          no.mppe_56 = 1;
-+      if (go->mppe_128)
-+          no.mppe_128 = 1;
-+      if (go->mppe_stateless)
-+          no.mppe_stateless = 1;
-+
-+      if (ao->mppe_40) {
-+          if ((p[5] & MPPE_40BIT))
-+              try.mppe_40 = 1;
-+          else
-+              try.mppe_40 = (p[5] == 0) ? 1 : 0;
-+      }
-+      if (ao->mppe_56) {
-+          if ((p[5] & MPPE_56BIT))
-+              try.mppe_56 = 1;
-+          else
-+              try.mppe_56 = (p[5] == 0) ? 1 : 0;
-+      }
-+      if (ao->mppe_128) {
-+          if ((p[5] & MPPE_128BIT))
-+              try.mppe_128 = 1;
-+          else
-+              try.mppe_128 = (p[5] == 0) ? 1 : 0;
-+      }
-+
-+      if (ao->mppe_stateless) {
-+          if ((p[2] & MPPE_STATELESS) || wo->mppe_stateless)
-+              try.mppe_stateless = 1;
-+          else
-+              try.mppe_stateless = 0;
-+      }
-+
-+      if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128) {
-+          try.mppe = try.mppe_stateless = 0;
-+          if (wo->mppe) {
-+              /* we require encryption, but peer doesn't support it
-+                 so we close connection */
-+              wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
-+                  wo->mppe_56 = wo->mppe_128 = 0;
-+              lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
-+                        "key length");
-+          }
-+        }
-+      if (wo->mppe && (wo->mppe_40 != try.mppe_40) &&
-+          (wo->mppe_56 != try.mppe_56) && (wo->mppe_128 != try.mppe_128)) {
-+          /* cannot negotiate key length */
-+          wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
-+              wo->mppe_56 = wo->mppe_128 = 0;
-+          lcp_close(f->unit, "Cannot negotiate MPPE key length");
-       }
-+      if (try.mppe_40 && try.mppe_56 && try.mppe_128)
-+          try.mppe_40 = try.mppe_56 = 0;
-+      else
-+          if (try.mppe_56 && try.mppe_128)
-+              try.mppe_56 = 0;
-+          else
-+              if (try.mppe_40 && try.mppe_128)
-+                  try.mppe_40 = 0;
-+              else
-+                  if (try.mppe_40 && try.mppe_56)
-+                      try.mppe_40 = 0;
-+
-+      p += CILEN_MPPE;
-+      len -= CILEN_MPPE;
-     }
- #endif /* MPPE */
-+
-+    if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
-+      no.lzs = 1;
-+      if (((p[2]<<8)|p[3]) > 1 || (p[4] != LZS_MODE_SEQ &&
-+                                   p[4] != LZS_MODE_EXT))
-+          try.lzs = 0;
-+      else {
-+          try.lzs_mode = p[4];
-+          try.lzs_hists = (p[2] << 8) | p[3];
-+      }
-+      p += CILEN_LZS;
-+      len -= CILEN_LZS;
-+    }
-+
-     if (go->deflate && len >= CILEN_DEFLATE
-       && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
-       && p[1] == CILEN_DEFLATE) {
-@@ -1001,14 +1254,50 @@
-       return -1;
- #ifdef MPPE
--    if (go->mppe && len >= CILEN_MPPE
-+    if ((go->mppe || go->mppc) && len >= CILEN_MPPE
-       && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
--      error("MPPE required but peer refused");
--      lcp_close(f->unit, "MPPE required but peer refused");
-+      ccp_options *wo = &ccp_wantoptions[f->unit];
-+      if (p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0) ||
-+          p[3] != 0 ||
-+          p[4] != 0 ||
-+          p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
-+                   (go->mppe_56 ? MPPE_56BIT : 0) |
-+                   (go->mppe_128 ? MPPE_128BIT : 0) |
-+                   (go->mppc ? MPPE_MPPC : 0)))
-+          return 0;
-+      if (go->mppc)
-+          try.mppc = 0;
-+      if (go->mppe) {
-+          try.mppe = 0;
-+          if (go->mppe_40)
-+              try.mppe_40 = 0;
-+          if (go->mppe_56)
-+              try.mppe_56 = 0;
-+          if (go->mppe_128)
-+              try.mppe_128 = 0;
-+          if (go->mppe_stateless)
-+              try.mppe_stateless = 0;
-+          if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128)
-+              try.mppe = try.mppe_stateless = 0;
-+          if (wo->mppe) { /* we want MPPE but cannot negotiate key length */
-+              wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
-+                  wo->mppe_56 = wo->mppe_128 = 0;
-+              lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
-+                        "key length");
-+          }
-+      }
-       p += CILEN_MPPE;
-       len -= CILEN_MPPE;
-     }
--#endif
-+#endif /* MPPE */
-+    if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
-+      if (p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff) 
-+          || p[4] != go->lzs_mode)
-+          return 0;
-+      try.lzs = 0;
-+      p += CILEN_LZS;
-+      len -= CILEN_LZS;
-+    }
-     if (go->deflate_correct && len >= CILEN_DEFLATE
-       && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
-       if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
-@@ -1072,14 +1361,15 @@
-     int dont_nak;
- {
-     int ret, newret, res;
--    u_char *p0, *retp;
-+    u_char *p0, *retp, p2, p5;
-     int len, clen, type, nb;
-     ccp_options *ho = &ccp_hisoptions[f->unit];
-     ccp_options *ao = &ccp_allowoptions[f->unit];
-+    ccp_options *wo = &ccp_wantoptions[f->unit];
- #ifdef MPPE
--    bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */
--                              /* CI_MPPE, or due to other options?       */
--#endif
-+    u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
-+/*     int mtu; */
-+#endif /* MPPE */
-     ret = CONFACK;
-     retp = p0 = p;
-@@ -1102,103 +1392,305 @@
-           switch (type) {
- #ifdef MPPE
-           case CI_MPPE:
--              if (!ao->mppe || clen != CILEN_MPPE) {
-+              if ((!ao->mppc && !ao->mppe) || clen != CILEN_MPPE) {
-                   newret = CONFREJ;
-                   break;
-               }
--              MPPE_CI_TO_OPTS(&p[2], ho->mppe);
--              /* Nak if anything unsupported or unknown are set. */
--              if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
--                  newret = CONFNAK;
--                  ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
--              }
--              if (ho->mppe & MPPE_OPT_UNKNOWN) {
-+              p2 = p[2];
-+              p5 = p[5];
-+              /* not sure what they want, tell 'em what we got */
-+              if (((p[2] & ~MPPE_STATELESS) != 0 || p[3] != 0 || p[4] != 0 ||
-+                   (p[5] & ~(MPPE_40BIT | MPPE_56BIT | MPPE_128BIT |
-+                             MPPE_MPPC)) != 0 || p[5] == 0) ||
-+                  (p[2] == 0 && p[3] == 0 && p[4] == 0 &&  p[5] == 0)) {
-                   newret = CONFNAK;
--                  ho->mppe &= ~MPPE_OPT_UNKNOWN;
-+                  p[2] = (wo->mppe_stateless ? MPPE_STATELESS : 0);
-+                  p[3] = 0;
-+                  p[4] = 0;
-+                  p[5] = (wo->mppe_40 ? MPPE_40BIT : 0) |
-+                      (wo->mppe_56 ? MPPE_56BIT : 0) |
-+                      (wo->mppe_128 ? MPPE_128BIT : 0) |
-+                      (wo->mppc ? MPPE_MPPC : 0);
-+                  break;
-               }
--              /* Check state opt */
--              if (ho->mppe & MPPE_OPT_STATEFUL) {
--                  /*
--                   * We can Nak and request stateless, but it's a
--                   * lot easier to just assume the peer will request
--                   * it if he can do it; stateful mode is bad over
--                   * the Internet -- which is where we expect MPPE.
--                   */
--                 if (refuse_mppe_stateful) {
--                      error("Refusing MPPE stateful mode offered by peer");
-+              if ((p[5] & MPPE_MPPC)) {
-+                  if (ao->mppc) {
-+                      ho->mppc = 1;
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      opt_buf[2] = opt_buf[3] = opt_buf[4] = 0;
-+                      opt_buf[5] = MPPE_MPPC;
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 1) <= 0) {
-+                          ho->mppc = 0;
-+                          p[5] &= ~MPPE_MPPC;
-+                          newret = CONFNAK;
-+                      }
-+                  } else {
-                       newret = CONFREJ;
--                      break;
-+                      if (wo->mppe || ao->mppe) {
-+                          p[5] &= ~MPPE_MPPC;
-+                          newret = CONFNAK;
-+                      }
-+                  }
-+              }
-+
-+              if (ao->mppe)
-+                  ho->mppe = 1;
-+
-+              if ((p[2] & MPPE_STATELESS)) {
-+                  if (ao->mppe_stateless) {
-+                      if (wo->mppe_stateless)
-+                          ho->mppe_stateless = 1;
-+                      else {
-+                          newret = CONFNAK;
-+                          if (!dont_nak)
-+                              p[2] &= ~MPPE_STATELESS;
-+                      }
-+                  } else {
-+                      newret = CONFNAK;
-+                      if (!dont_nak)
-+                          p[2] &= ~MPPE_STATELESS;
-+                  }
-+              } else {
-+                  if (wo->mppe_stateless && !dont_nak) {
-+                      wo->mppe_stateless = 0;
-+                      newret = CONFNAK;
-+                      p[2] |= MPPE_STATELESS;
-                   }
-               }
--              /* Find out which of {S,L} are set. */
--              if ((ho->mppe & MPPE_OPT_128)
--                   && (ho->mppe & MPPE_OPT_40)) {
--                  /* Both are set, negotiate the strongest. */
-+              if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT|MPPE_128BIT)) {
-                   newret = CONFNAK;
--                  if (ao->mppe & MPPE_OPT_128)
--                      ho->mppe &= ~MPPE_OPT_40;
--                  else if (ao->mppe & MPPE_OPT_40)
--                      ho->mppe &= ~MPPE_OPT_128;
--                  else {
--                      newret = CONFREJ;
--                      break;
-+                  if (ao->mppe_128) {
-+                      ho->mppe_128 = 1;
-+                      p[5] &= ~(MPPE_40BIT|MPPE_56BIT);
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-+                            MPPE_MAX_KEY_LEN);
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
-+                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
-+                          ho->mppe_128 = 0;
-+                          p[5] |= (MPPE_40BIT|MPPE_56BIT);
-+                          p[5] &= ~MPPE_128BIT;
-+                          goto check_mppe_56_40;
-+                      }
-+                      goto check_mppe;
-                   }
--              } else if (ho->mppe & MPPE_OPT_128) {
--                  if (!(ao->mppe & MPPE_OPT_128)) {
--                      newret = CONFREJ;
--                      break;
-+                  p[5] &= ~MPPE_128BIT;
-+                  goto check_mppe_56_40;
-+              }
-+              if ((p[5] & ~MPPE_MPPC) == (MPPE_56BIT|MPPE_128BIT)) {
-+                  newret = CONFNAK;
-+                  if (ao->mppe_128) {
-+                      ho->mppe_128 = 1;
-+                      p[5] &= ~MPPE_56BIT;
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-+                            MPPE_MAX_KEY_LEN);
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
-+                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
-+                          ho->mppe_128 = 0;
-+                          p[5] |= MPPE_56BIT;
-+                          p[5] &= ~MPPE_128BIT;
-+                          goto check_mppe_56;
-+                      }
-+                      goto check_mppe;
-                   }
--              } else if (ho->mppe & MPPE_OPT_40) {
--                  if (!(ao->mppe & MPPE_OPT_40)) {
--                      newret = CONFREJ;
--                      break;
-+                  p[5] &= ~MPPE_128BIT;
-+                  goto check_mppe_56;
-+              }
-+              if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_128BIT)) {
-+                  newret = CONFNAK;
-+                  if (ao->mppe_128) {
-+                      ho->mppe_128 = 1;
-+                      p[5] &= ~MPPE_40BIT;
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-+                            MPPE_MAX_KEY_LEN);
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
-+                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
-+                          ho->mppe_128 = 0;
-+                          p[5] |= MPPE_40BIT;
-+                          p[5] &= ~MPPE_128BIT;
-+                          goto check_mppe_40;
-+                      }
-+                      goto check_mppe;
-+                  }
-+                  p[5] &= ~MPPE_128BIT;
-+                  goto check_mppe_40;
-+              }
-+              if ((p[5] & ~MPPE_MPPC) == MPPE_128BIT) {
-+                  if (ao->mppe_128) {
-+                      ho->mppe_128 = 1;
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-+                            MPPE_MAX_KEY_LEN);
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
-+                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
-+                          ho->mppe_128 = 0;
-+                          p[5] &= ~MPPE_128BIT;
-+                          newret = CONFNAK;
-+                      }
-+                      goto check_mppe;
-+                  }
-+                  p[5] &= ~MPPE_128BIT;
-+                  newret = CONFNAK;
-+                  goto check_mppe;
-+              }
-+          check_mppe_56_40:
-+              if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT)) {
-+                  newret = CONFNAK;
-+                  if (ao->mppe_56) {
-+                      ho->mppe_56 = 1;
-+                      p[5] &= ~MPPE_40BIT;
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-+                            MPPE_MAX_KEY_LEN);
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
-+                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
-+                          ho->mppe_56 = 0;
-+                          p[5] |= MPPE_40BIT;
-+                          p[5] &= ~MPPE_56BIT;
-+                          newret = CONFNAK;
-+                          goto check_mppe_40;
-+                      }
-+                      goto check_mppe;
-+                  }
-+                  p[5] &= ~MPPE_56BIT;
-+                  goto check_mppe_40;
-+              }
-+          check_mppe_56:
-+              if ((p[5] & ~MPPE_MPPC) == MPPE_56BIT) {
-+                  if (ao->mppe_56) {
-+                      ho->mppe_56 = 1;
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-+                            MPPE_MAX_KEY_LEN);
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
-+                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
-+                          ho->mppe_56 = 0;
-+                          p[5] &= ~MPPE_56BIT;
-+                          newret = CONFNAK;
-+                      }
-+                      goto check_mppe;
-+                  }
-+                  p[5] &= ~MPPE_56BIT;
-+                  newret = CONFNAK;
-+                  goto check_mppe;
-+              }
-+          check_mppe_40:
-+              if ((p[5] & ~MPPE_MPPC) == MPPE_40BIT) {
-+                  if (ao->mppe_40) {
-+                      ho->mppe_40 = 1;
-+                      BCOPY(p, opt_buf, CILEN_MPPE);
-+                      BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-+                            MPPE_MAX_KEY_LEN);
-+                      if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
-+                                   MPPE_MAX_KEY_LEN, 1) <= 0) {
-+                          ho->mppe_40 = 0;
-+                          p[5] &= ~MPPE_40BIT;
-+                          newret = CONFNAK;
-+                      }
-+                      goto check_mppe;
-+                  }
-+                  p[5] &= ~MPPE_40BIT;
-+              }
-+
-+          check_mppe:
-+              if (!ho->mppe_40 && !ho->mppe_56 && !ho->mppe_128) {
-+                  if (wo->mppe_40 || wo->mppe_56 || wo->mppe_128) {
-+                      newret = CONFNAK;
-+                      p[2] |= (wo->mppe_stateless ? MPPE_STATELESS : 0);
-+                      p[5] |= (wo->mppe_40 ? MPPE_40BIT : 0) |
-+                          (wo->mppe_56 ? MPPE_56BIT : 0) |
-+                          (wo->mppe_128 ? MPPE_128BIT : 0) |
-+                          (wo->mppc ? MPPE_MPPC : 0);
-+                  } else {
-+                      ho->mppe = ho->mppe_stateless = 0;
-                   }
-               } else {
--                  /* Neither are set. */
-+                  /* MPPE is not compatible with other compression types */
-+                  if (wo->mppe) {
-+                      ao->bsd_compress = 0;
-+                      ao->predictor_1 = 0;
-+                      ao->predictor_2 = 0;
-+                      ao->deflate = 0;
-+                      ao->lzs = 0;
-+                  }
-+              }
-+              if ((!ho->mppc || !ao->mppc) && !ho->mppe) {
-+                  p[2] = p2;
-+                  p[5] = p5;
-                   newret = CONFREJ;
-                   break;
-               }
--              /* rebuild the opts */
--              MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
--              if (newret == CONFACK) {
--                  u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
--                  int mtu;
--
--                  BCOPY(p, opt_buf, CILEN_MPPE);
--                  BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
--                        MPPE_MAX_KEY_LEN);
--                  if (ccp_test(f->unit, opt_buf,
--                               CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
--                      /* This shouldn't happen, we've already tested it! */
--                      error("MPPE required, but kernel has no support.");
--                      lcp_close(f->unit, "MPPE required but not available");
--                      newret = CONFREJ;
--                      break;
--                  }
--                  /*
--                   * We need to decrease the interface MTU by MPPE_PAD
--                   * because MPPE frames **grow**.  The kernel [must]
--                   * allocate MPPE_PAD extra bytes in xmit buffers.
--                   */
--                  mtu = netif_get_mtu(f->unit);
--                  if (mtu)
--                      netif_set_mtu(f->unit, mtu - MPPE_PAD);
--                  else
--                      newret = CONFREJ;
--              }
-+              /*
-+               * I have commented the code below because according to RFC1547
-+               * MTU is only information for higher level protocols about
-+               * "the maximum allowable length for a packet (q.v.) transmitted
-+               * over a point-to-point link without incurring network layer
-+               * fragmentation." Of course a PPP implementation should be able
-+               * to handle overhead added by MPPE - in our case apropriate code
-+               * is located in drivers/net/ppp_generic.c in the kernel sources.
-+               *
-+               * According to RFC1661:
-+               * - when negotiated MRU is less than 1500 octets, a PPP
-+               *   implementation must still be able to receive at least 1500
-+               *   octets,
-+               * - when PFC is negotiated, a PPP implementation is still
-+               *   required to receive frames with uncompressed protocol field.
-+               *
-+               * So why not to handle MPPE overhead without changing MTU value?
-+               * I am sure that RFC3078, unfortunately silently, assumes that.
-+               */
-               /*
--               * We have accepted MPPE or are willing to negotiate
--               * MPPE parameters.  A CONFREJ is due to subsequent
--               * (non-MPPE) processing.
-+               * We need to decrease the interface MTU by MPPE_PAD
-+               * because MPPE frames **grow**.  The kernel [must]
-+               * allocate MPPE_PAD extra bytes in xmit buffers.
-                */
--              rej_for_ci_mppe = 0;
-+/*
-+              mtu = netif_get_mtu(f->unit);
-+              if (mtu) {
-+                  netif_set_mtu(f->unit, mtu - MPPE_PAD);
-+              } else {
-+                  newret = CONFREJ;
-+                  if (ccp_wantoptions[f->unit].mppe) {
-+                      error("Cannot adjust MTU needed by MPPE.");
-+                      lcp_close(f->unit, "Cannot adjust MTU needed by MPPE.");
-+                  }
-+              }
-+*/
-               break;
- #endif /* MPPE */
-+
-+          case CI_LZS:
-+              if (!ao->lzs || clen != CILEN_LZS) {
-+                  newret = CONFREJ;
-+                  break;
-+              }
-+
-+              ho->lzs = 1;
-+              ho->lzs_hists = (p[2] << 8) | p[3];
-+              ho->lzs_mode = p[4];
-+              if ((ho->lzs_hists != ao->lzs_hists) ||
-+                  (ho->lzs_mode != ao->lzs_mode)) {
-+                  newret = CONFNAK;
-+                  if (!dont_nak) {
-+                      p[2] = ao->lzs_hists >> 8;
-+                      p[3] = ao->lzs_hists & 0xff;
-+                      p[4] = ao->lzs_mode;
-+                  } else
-+                      break;
-+              }
-+
-+              if (p == p0 && ccp_test(f->unit, p, CILEN_LZS, 1) <= 0) {
-+                  newret = CONFREJ;
-+              }
-+              break;
-+
-           case CI_DEFLATE:
-           case CI_DEFLATE_DRAFT:
-               if (!ao->deflate || clen != CILEN_DEFLATE
-@@ -1340,12 +1832,6 @@
-       else
-           *lenp = retp - p0;
-     }
--#ifdef MPPE
--    if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
--      error("MPPE required but peer negotiation failed");
--      lcp_close(f->unit, "MPPE required but peer negotiation failed");
--    }
--#endif
-     return ret;
- }
-@@ -1367,24 +1853,35 @@
-       char *p = result;
-       char *q = result + sizeof(result); /* 1 past result */
--      slprintf(p, q - p, "MPPE ");
--      p += 5;
--      if (opt->mppe & MPPE_OPT_128) {
--          slprintf(p, q - p, "128-bit ");
--          p += 8;
--      }
--      if (opt->mppe & MPPE_OPT_40) {
--          slprintf(p, q - p, "40-bit ");
--          p += 7;
--      }
--      if (opt->mppe & MPPE_OPT_STATEFUL)
--          slprintf(p, q - p, "stateful");
--      else
--          slprintf(p, q - p, "stateless");
--
-+      if (opt->mppe) {
-+          if (opt->mppc) {
-+              slprintf(p, q - p, "MPPC/MPPE ");
-+              p += 10;
-+          } else {
-+              slprintf(p, q - p, "MPPE ");
-+              p += 5;
-+          }
-+          if (opt->mppe_128) {
-+              slprintf(p, q - p, "128-bit ");
-+              p += 8;
-+          } else if (opt->mppe_56) {
-+              slprintf(p, q - p, "56-bit ");
-+              p += 7;
-+          } else if (opt->mppe_40) {
-+              slprintf(p, q - p, "40-bit ");
-+              p += 7;
-+          }
-+          if (opt->mppe_stateless)
-+              slprintf(p, q - p, "stateless");
-+          else
-+              slprintf(p, q - p, "stateful");
-+      } else if (opt->mppc)
-+          slprintf(p, q - p, "MPPC");
-       break;
-     }
--#endif
-+#endif /* MPPE */
-+    case CI_LZS:
-+      return "Stac LZS";
-     case CI_DEFLATE:
-     case CI_DEFLATE_DRAFT:
-       if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
-@@ -1440,12 +1937,12 @@
-     } else if (ANY_COMPRESS(*ho))
-       notice("%s transmit compression enabled", method_name(ho, NULL));
- #ifdef MPPE
--    if (go->mppe) {
-+    if (go->mppe || go->mppc) {
-       BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
-       BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
-       continue_networks(f->unit);             /* Bring up IP et al */
-     }
--#endif
-+#endif /* MPPE */
- }
- /*
-@@ -1468,7 +1965,7 @@
-           lcp_close(f->unit, "MPPE disabled");
-       }
-     }
--#endif
-+#endif /* MPPE */
- }
- /*
-@@ -1528,24 +2025,28 @@
- #ifdef MPPE
-           case CI_MPPE:
-               if (optlen >= CILEN_MPPE) {
--                  u_char mppe_opts;
--
--                  MPPE_CI_TO_OPTS(&p[2], mppe_opts);
--                  printer(arg, "mppe %s %s %s %s %s %s%s",
--                          (p[2] & MPPE_H_BIT)? "+H": "-H",
--                          (p[5] & MPPE_M_BIT)? "+M": "-M",
--                          (p[5] & MPPE_S_BIT)? "+S": "-S",
--                          (p[5] & MPPE_L_BIT)? "+L": "-L",
-+                  printer(arg, "mppe %s %s %s %s %s %s",
-+                          (p[2] & MPPE_STATELESS)? "+H": "-H",
-+                          (p[5] & MPPE_56BIT)? "+M": "-M",
-+                          (p[5] & MPPE_128BIT)? "+S": "-S",
-+                          (p[5] & MPPE_40BIT)? "+L": "-L",
-                           (p[5] & MPPE_D_BIT)? "+D": "-D",
--                          (p[5] & MPPE_C_BIT)? "+C": "-C",
--                          (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
--                  if (mppe_opts & MPPE_OPT_UNKNOWN)
-+                          (p[5] & MPPE_MPPC)? "+C": "-C");
-+                  if ((p[5] & ~(MPPE_56BIT | MPPE_128BIT | MPPE_40BIT |
-+                                MPPE_D_BIT | MPPE_MPPC)) ||
-+                      (p[2] & ~MPPE_STATELESS))
-                       printer(arg, " (%.2x %.2x %.2x %.2x)",
-                               p[2], p[3], p[4], p[5]);
-                   p += CILEN_MPPE;
-               }
-               break;
--#endif
-+#endif /* MPPE */
-+          case CI_LZS:
-+              if (optlen >= CILEN_LZS) {
-+                  printer(arg, "lzs %.2x %.2x %.2x", p[2], p[3], p[4]);
-+                  p += CILEN_LZS;
-+              }
-+              break;
-           case CI_DEFLATE:
-           case CI_DEFLATE_DRAFT:
-               if (optlen >= CILEN_DEFLATE) {
-@@ -1631,6 +2132,7 @@
-           error("Lost compression sync: disabling compression");
-           ccp_close(unit, "Lost compression sync");
- #ifdef MPPE
-+          /* My module dosn't need this. J.D., 2003-07-06 */
-           /*
-            * If we were doing MPPE, we must also take the link down.
-            */
-@@ -1638,9 +2140,18 @@
-               error("Too many MPPE errors, closing LCP");
-               lcp_close(unit, "Too many MPPE errors");
-           }
--#endif
-+#endif /* MPPE */
-       } else {
-           /*
-+           * When LZS or MPPE/MPPC is negotiated we just send CCP_RESETREQ
-+           * and don't wait for CCP_RESETACK
-+           */
-+          if ((ccp_gotoptions[f->unit].method == CI_LZS) ||
-+              (ccp_gotoptions[f->unit].method == CI_MPPE)) {
-+              fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
-+              return;
-+          }
-+          /*
-            * Send a reset-request to reset the peer's compressor.
-            * We don't do that if we are still waiting for an
-            * acknowledgement to a previous reset-request.
-@@ -1671,4 +2182,3 @@
-     } else
-       ccp_localstate[f->unit] &= ~RACK_PENDING;
- }
--
-diff -ruN ppp-2.4.3.orig/pppd/ccp.h ppp-2.4.3/pppd/ccp.h
---- ppp-2.4.3.orig/pppd/ccp.h  2004-11-04 11:02:26.000000000 +0100
-+++ ppp-2.4.3/pppd/ccp.h       2004-11-21 13:54:09.000000000 +0100
-@@ -37,9 +37,17 @@
-     bool predictor_2;         /* do Predictor-2? */
-     bool deflate_correct;     /* use correct code for deflate? */
-     bool deflate_draft;               /* use draft RFC code for deflate? */
-+    bool lzs;                 /* do Stac LZS? */
-+    bool mppc;                        /* do MPPC? */
-     bool mppe;                        /* do MPPE? */
-+    bool mppe_40;             /* allow 40 bit encryption? */
-+    bool mppe_56;             /* allow 56 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 */
-+    u_short lzs_mode;         /* LZS check mode */
-+    u_short lzs_hists;                /* number of LZS histories */
-     short method;             /* code for chosen compression method */
- } ccp_options;
-diff -ruN ppp-2.4.3.orig/pppd/chap_ms.c ppp-2.4.3/pppd/chap_ms.c
---- ppp-2.4.3.orig/pppd/chap_ms.c      2004-11-12 10:57:43.000000000 +0100
-+++ ppp-2.4.3/pppd/chap_ms.c   2004-11-21 13:54:09.000000000 +0100
-@@ -895,13 +895,17 @@
-     /*
-      * Disable undesirable encryption types.  Note that we don't ENABLE
-      * any encryption types, to avoid overriding manual configuration.
-+     *
-+     * It seems that 56 bit keys are unsupported in MS-RADIUS (see RFC 2548)
-      */
-     switch(types) {
-       case MPPE_ENC_TYPES_RC4_40:
--          ccp_wantoptions[0].mppe &= ~MPPE_OPT_128;   /* disable 128-bit */
-+          ccp_wantoptions[0].mppe_128 = 0;    /* disable 128-bit */
-+          ccp_wantoptions[0].mppe_56 = 0;     /* disable 56-bit */
-           break;
-       case MPPE_ENC_TYPES_RC4_128:
--          ccp_wantoptions[0].mppe &= ~MPPE_OPT_40;    /* disable 40-bit */
-+          ccp_wantoptions[0].mppe_56 = 0;     /* disable 56-bit */
-+          ccp_wantoptions[0].mppe_40 = 0;     /* disable 40-bit */
-           break;
-       default:
-           break;
-diff -ruN ppp-2.4.3.orig/pppd/pppd.8 ppp-2.4.3/pppd/pppd.8
---- ppp-2.4.3.orig/pppd/pppd.8 2004-11-13 13:22:49.000000000 +0100
-+++ ppp-2.4.3/pppd/pppd.8      2004-11-21 14:24:47.000000000 +0100
-@@ -622,9 +622,29 @@
- Enables the use of PPP multilink; this is an alias for the `multilink'
- option.  This option is currently only available under Linux.
- .TP
--.B mppe\-stateful
--Allow MPPE to use stateful mode.  Stateless mode is still attempted first.
--The default is to disallow stateful mode.  
-+.B mppc
-+Enables MPPC (Microsoft Point to Point Compression).  This is the default.
-+.TP
-+.B mppe \fIsubopt1[,subopt2[,subopt3[..]]]
-+Modify MPPE (Microsoft Point to Point Encryption) parameters. In order
-+for MPPE to successfully come up, you must have authenticated with either
-+MS-CHAP or MS-CHAPv2. By default MPPE is optional, it means that pppd will
-+not propose MPPE to the peer, but will negotiate MPPE if peer wants that.
-+You can change this using \fIrequired\fR suboption.
-+This option is presently only supported under Linux, and only if your
-+kernel has been configured to include MPPE support.
-+.IP
-+MPPE suboptions:
-+.br
-+\fIrequired\fR - require MPPE; disconnect if peer doesn't support it,
-+.br
-+\fIstateless\fR - try to negotiate stateless mode; default is stateful,
-+.br
-+\fIno40\fR - disable 40 bit keys,
-+.br
-+\fIno56\fR - disable 56 bit keys,
-+.br
-+\fIno128\fR - disable 128 bit keys
- .TP
- .B mpshortseq
- Enables the use of short (12-bit) sequence numbers in multilink
-@@ -757,17 +777,11 @@
- Disables the use of PPP multilink.  This option is currently only
- available under Linux.
- .TP
--.B nomppe
--Disables MPPE (Microsoft Point to Point Encryption).  This is the default.
--.TP
--.B nomppe\-40
--Disable 40-bit encryption with MPPE.
-+.B nomppc
-+Disables MPPC (Microsoft Point to Point Compression).
- .TP
--.B nomppe\-128
--Disable 128-bit encryption with MPPE.
--.TP
--.B nomppe\-stateful
--Disable MPPE stateful mode.  This is the default.
-+.B nomppe
-+Disables MPPE (Microsoft Point to Point Encryption).
- .TP
- .B nompshortseq
- Disables the use of short (12-bit) sequence numbers in the PPP
-@@ -948,19 +962,6 @@
- Require the peer to authenticate itself using CHAP [Challenge
- Handshake Authentication Protocol] authentication.
- .TP
--.B require\-mppe
--Require the use of MPPE (Microsoft Point to Point Encryption).  This
--option disables all other compression types.  This option enables
--both 40-bit and 128-bit encryption.  In order for MPPE to successfully
--come up, you must have authenticated with either MS\-CHAP or MS\-CHAPv2.
--This option is presently only supported under Linux, and only if your
--kernel has been configured to include MPPE support.
--.TP
--.B require\-mppe\-40
--Require the use of MPPE, with 40-bit encryption.
--.TP
--.B require\-mppe\-128
--Require the use of MPPE, with 128-bit encryption.
- .TP
- .B require\-mschap
- Require the peer to authenticate itself using MS\-CHAP [Microsoft Challenge
diff --git a/openwrt/package/ppp/patches/ppp-2.4.3-no-atm.patch b/openwrt/package/ppp/patches/ppp-2.4.3-no-atm.patch
deleted file mode 100644 (file)
index a737cfa..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -ruN ppp-2.4.3-orig/pppd/plugins/Makefile.linux ppp-2.4.3-3/pppd/plugins/Makefile.linux
---- ppp-2.4.3-orig/pppd/plugins/Makefile.linux 2004-11-14 08:57:35.000000000 +0100
-+++ ppp-2.4.3-3/pppd/plugins/Makefile.linux    2004-12-05 17:03:59.000000000 +0100
-@@ -9,7 +9,7 @@
- MANDIR = $(DESTDIR)/share/man/man8
- LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
--SUBDIRS := rp-pppoe pppoatm radius
-+SUBDIRS := rp-pppoe radius
- # Uncomment the next line to include the radius authentication plugin
- # SUBDIRS += radius
- PLUGINS := minconn.so passprompt.so passwordfd.so winbind.so
diff --git a/openwrt/package/ppp/patches/ppp-2.4.3-no-strip.patch b/openwrt/package/ppp/patches/ppp-2.4.3-no-strip.patch
deleted file mode 100644 (file)
index 216973c..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-diff -ruN ppp-2.4.3-orig/chat/Makefile.linux ppp-2.4.3-3/chat/Makefile.linux
---- ppp-2.4.3-orig/chat/Makefile.linux 2004-11-03 12:51:47.000000000 +0100
-+++ ppp-2.4.3-3/chat/Makefile.linux    2004-12-05 17:42:43.000000000 +0100
-@@ -25,7 +25,7 @@
- install: chat
-       mkdir -p $(BINDIR)
--      $(INSTALL) -s -c chat $(BINDIR)
-+      $(INSTALL) -c chat $(BINDIR)
-       $(INSTALL) -c -m 644 chat.8 $(MANDIR)
- clean:
-diff -ruN ppp-2.4.3-orig/pppd/Makefile.linux ppp-2.4.3-3/pppd/Makefile.linux
---- ppp-2.4.3-orig/pppd/Makefile.linux 2004-11-13 13:02:22.000000000 +0100
-+++ ppp-2.4.3-3/pppd/Makefile.linux    2004-12-16 04:43:41.000000000 +0100
-@@ -99,7 +99,7 @@
- CFLAGS        += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
- LIBS  += -lsrp -L/usr/local/ssl/lib -lcrypto
- TARGETS       += srp-entry
--EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
-+EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry
- MANPAGES += srp-entry.8
- EXTRACLEAN += srp-entry.o
- NEEDDES=y
-@@ -202,7 +202,7 @@
- install: pppd
-       mkdir -p $(BINDIR) $(MANDIR)
-       $(EXTRAINSTALL)
--      $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd
-+      $(INSTALL) -c -m 555 pppd $(BINDIR)/pppd
-       if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \
-         chmod o-rx,u+s $(BINDIR)/pppd; fi
-       $(INSTALL) -c -m 444 pppd.8 $(MANDIR)
-diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux
---- ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux  2004-11-14 08:02:31.000000000 +0100
-+++ ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux     2004-12-05 17:43:17.000000000 +0100
-@@ -36,9 +37,9 @@
- install: all
-       $(INSTALL) -d -m 755 $(LIBDIR)
--      $(INSTALL) -s -c -m 755 radius.so $(LIBDIR)
--      $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR)
--      $(INSTALL) -s -c -m 755 radrealms.so $(LIBDIR)
-+      $(INSTALL) -c -m 755 radius.so $(LIBDIR)
-+      $(INSTALL) -c -m 755 radattr.so $(LIBDIR)
-+      $(INSTALL) -c -m 755 radrealms.so $(LIBDIR)
-       $(INSTALL) -c -m 444 pppd-radius.8 $(MANDIR)
-       $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
-diff -ruN ppp-2.4.3-orig/pppd/plugins/rp-pppoe/Makefile.linux ppp-2.4.3-3/pppd/plugins/rp-pppoe/Makefile.linux
---- ppp-2.4.3-orig/pppd/plugins/rp-pppoe/Makefile.linux        2004-11-14 08:58:37.000000000 +0100
-+++ ppp-2.4.3-3/pppd/plugins/rp-pppoe/Makefile.linux   2004-12-05 17:43:23.000000000 +0100
-@@ -39,9 +39,9 @@
- install: all
-       $(INSTALL) -d -m 755 $(LIBDIR)
--      $(INSTALL) -s -c -m 4550 rp-pppoe.so $(LIBDIR)
-+      $(INSTALL) -c -m 4550 rp-pppoe.so $(LIBDIR)
-       $(INSTALL) -d -m 755 $(BINDIR)
--      $(INSTALL) -s -c -m 555 pppoe-discovery $(BINDIR)
-+      $(INSTALL) -c -m 555 pppoe-discovery $(BINDIR)
- clean:
-       rm -f *.o *.so
-diff -ruN ppp-2.4.3-orig/pppdump/Makefile.linux ppp-2.4.3-3/pppdump/Makefile.linux
---- ppp-2.4.3-orig/pppdump/Makefile.linux      2004-10-31 02:36:52.000000000 +0200
-+++ ppp-2.4.3-3/pppdump/Makefile.linux 2004-12-05 17:50:34.000000000 +0100
-@@ -17,5 +18,5 @@
- install:
-       mkdir -p $(BINDIR) $(MANDIR)
--      $(INSTALL) -s -c pppdump $(BINDIR)
-+      $(INSTALL) -c pppdump $(BINDIR)
-       $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)
-diff -ruN ppp-2.4.3-orig/pppstats/Makefile.linux ppp-2.4.3-3/pppstats/Makefile.linux
---- ppp-2.4.3-orig/pppstats/Makefile.linux     2004-10-31 23:09:03.000000000 +0100
-+++ ppp-2.4.3-3/pppstats/Makefile.linux        2004-12-05 17:43:38.000000000 +0100
-@@ -22,7 +22,7 @@
- install: pppstats
-       -mkdir -p $(MANDIR)
--      $(INSTALL) -s -c pppstats $(BINDIR)
-+      $(INSTALL) -c pppstats $(BINDIR)
-       $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)
- pppstats: $(PPPSTATSRCS)
diff --git a/openwrt/package/ppp/patches/ppp-2.4.3-opt-flags.patch b/openwrt/package/ppp/patches/ppp-2.4.3-opt-flags.patch
deleted file mode 100644 (file)
index 200e76b..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux
---- ppp-2.4.3-orig/pppd/plugins/radius/Makefile.linux  2004-11-14 08:02:31.000000000 +0100
-+++ ppp-2.4.3-3/pppd/plugins/radius/Makefile.linux     2004-12-05 17:43:17.000000000 +0100
-@@ -12,7 +12,8 @@
- INSTALL       = install
- PLUGIN=radius.so radattr.so radrealms.so
--CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
-+COPTS = -O2
-+CFLAGS=-I. -I../.. -I../../../include $(COPTS) -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
- # Uncomment the next line to include support for Microsoft's
- # MS-CHAP authentication protocol.
-diff -ruN ppp-2.4.3-orig/pppdump/Makefile.linux ppp-2.4.3-3/pppdump/Makefile.linux
---- ppp-2.4.3-orig/pppdump/Makefile.linux      2004-10-31 02:36:52.000000000 +0200
-+++ ppp-2.4.3-3/pppdump/Makefile.linux 2004-12-05 17:50:34.000000000 +0100
-@@ -2,7 +2,8 @@
- BINDIR = $(DESTDIR)/sbin
- MANDIR = $(DESTDIR)/share/man/man8
--CFLAGS= -O -I../include/net
-+COPTS = -O
-+CFLAGS= $(COPTS) -I../include/net
- OBJS = pppdump.o bsd-comp.o deflate.o zlib.o
- INSTALL= install
diff --git a/openwrt/package/ppp/patches/ppp-2.4.3-pppoe-iface-name.patch b/openwrt/package/ppp/patches/ppp-2.4.3-pppoe-iface-name.patch
deleted file mode 100644 (file)
index 522d587..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -ruN ppp-2.4.3-orig/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.3-3/pppd/plugins/rp-pppoe/plugin.c
---- ppp-2.4.3-orig/pppd/plugins/rp-pppoe/plugin.c      2004-11-04 11:07:37.000000000 +0100
-+++ ppp-2.4.3-3/pppd/plugins/rp-pppoe/plugin.c 2004-12-16 01:07:22.000000000 +0100
-@@ -286,7 +286,7 @@
-       /* Strip off "nic-" */
-       cmd += 4;
-     } else if (strlen(cmd) < 4
--             || (strncmp(cmd, "eth", 3) && strncmp(cmd, "nas", 3)
-+             || (strncmp(cmd, "eth", 3) && strncmp(cmd, "nas", 3) && strncmp(cmd, "vlan", 4)
-                  && strncmp(cmd, "tap", 3) && strncmp(cmd, "br", 2))) {
-       return 0;
-     }
diff --git a/openwrt/package/ppp/patches/ppp-2.4.3-radius-config.patch b/openwrt/package/ppp/patches/ppp-2.4.3-radius-config.patch
deleted file mode 100644 (file)
index 90c02af..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/config.c ppp-2.4.3-3/pppd/plugins/radius/config.c
---- ppp-2.4.3-orig/pppd/plugins/radius/config.c        2004-11-14 08:26:26.000000000 +0100
-+++ ppp-2.4.3-3/pppd/plugins/radius/config.c   2004-12-16 04:03:46.000000000 +0100
-@@ -369,31 +369,37 @@
-       }
- #endif
-+#if 0
-       if (rc_conf_int("login_tries") <= 0)
-       {
-               error("%s: login_tries <= 0 is illegal", filename);
-               return (-1);
-       }
-+#endif
-       if (rc_conf_str("seqfile") == NULL)
-       {
-               error("%s: seqfile not specified", filename);
-               return (-1);
-       }
-+#if 0
-       if (rc_conf_int("login_timeout") <= 0)
-       {
-               error("%s: login_timeout <= 0 is illegal", filename);
-               return (-1);
-       }
-+#endif
-       if (rc_conf_str("mapfile") == NULL)
-       {
-               error("%s: mapfile not specified", filename);
-               return (-1);
-       }
-+#if 0
-       if (rc_conf_str("nologin") == NULL)
-       {
-               error("%s: nologin not specified", filename);
-               return (-1);
-       }
-+#endif
-       return 0;
- }
-diff -ruN ppp-2.4.3-orig/pppd/plugins/radius/options.h ppp-2.4.3-3/pppd/plugins/radius/options.h
---- ppp-2.4.3-orig/pppd/plugins/radius/options.h       2004-11-14 08:26:26.000000000 +0100
-+++ ppp-2.4.3-3/pppd/plugins/radius/options.h  2004-12-16 04:09:16.000000000 +0100
-@@ -31,24 +31,21 @@
- static SERVER acctserver = {0};
- static SERVER authserver = {0};
--int default_tries = 4;
--int default_timeout = 60;
--
- static OPTION config_options[] = {
- /* internally used options */
- {"config_file",               OT_STR, ST_UNDEF, NULL},
- /* General options */
- {"auth_order",                OT_AUO, ST_UNDEF, NULL},
--{"login_tries",               OT_INT, ST_UNDEF, &default_tries},
--{"login_timeout",     OT_INT, ST_UNDEF, &default_timeout},
--{"nologin",           OT_STR, ST_UNDEF, "/etc/nologin"},
--{"issue",             OT_STR, ST_UNDEF, "/etc/radiusclient/issue"},
-+{"login_tries",               OT_INT, ST_UNDEF, NULL},
-+{"login_timeout",     OT_INT, ST_UNDEF, NULL},
-+{"nologin",           OT_STR, ST_UNDEF, NULL},
-+{"issue",             OT_STR, ST_UNDEF, NULL},
- /* RADIUS specific options */
- {"authserver",                OT_SRV, ST_UNDEF, &authserver},
- {"acctserver",                OT_SRV, ST_UNDEF, &acctserver},
- {"servers",           OT_STR, ST_UNDEF, NULL},
- {"dictionary",                OT_STR, ST_UNDEF, NULL},
--{"login_radius",      OT_STR, ST_UNDEF, "/usr/sbin/login.radius"},
-+{"login_radius",      OT_STR, ST_UNDEF, NULL},
- {"seqfile",           OT_STR, ST_UNDEF, NULL},
- {"mapfile",           OT_STR, ST_UNDEF, NULL},
- {"default_realm",     OT_STR, ST_UNDEF, NULL},