diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-10-13 20:51:49 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-10-13 20:51:49 +0000 |
commit | f52d66ff00b24111f87c274d3d7085ef2e1d27b1 (patch) | |
tree | d993cf48b4d89166701fe2f33976389d7634235d /package/ppp/patches | |
parent | 725611a466f2edf12f809d22339b22223af4afe7 (diff) | |
parent | 0c0df9eb082d5ff83d0f22f6e00bf580729fb49d (diff) |
finally move buildroot-ng to trunk
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@5059 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/ppp/patches')
24 files changed, 4212 insertions, 0 deletions
diff --git a/package/ppp/patches/010-use_target_for_configure.patch b/package/ppp/patches/010-use_target_for_configure.patch new file mode 100644 index 0000000000..56439a6122 --- /dev/null +++ b/package/ppp/patches/010-use_target_for_configure.patch @@ -0,0 +1,20 @@ + + Use values exported from $(TOPDIR)/rules.mk for determining + the target system instead of the host configuration + +--- ppp-2.4.3/configure.orig Sat Nov 6 11:36:32 2004 ++++ ppp-2.4.3/configure Sun Jun 18 23:40:46 2006 +@@ -8,9 +8,9 @@ SYSCONF=/etc + # if [ -d /NextApps ]; then + # system="NeXTStep" + # else +- system=`uname -s` +- release=`uname -r` +- arch=`uname -m` ++ system=${UNAME_S:-`uname -s`} ++ release=${UNAME_R:-`uname -r`} ++ arch=${UNAME_M:-`uname -m`} + # fi + state="unknown" + + diff --git a/package/ppp/patches/100-debian_close_dev_ppp.patch b/package/ppp/patches/100-debian_close_dev_ppp.patch new file mode 100644 index 0000000000..4e50118e87 --- /dev/null +++ b/package/ppp/patches/100-debian_close_dev_ppp.patch @@ -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/package/ppp/patches/101-debian_ip-up_option.patch b/package/ppp/patches/101-debian_ip-up_option.patch new file mode 100644 index 0000000000..6033fda247 --- /dev/null +++ b/package/ppp/patches/101-debian_ip-up_option.patch @@ -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/package/ppp/patches/102-debian_pppoe_multicast_pado.patch b/package/ppp/patches/102-debian_pppoe_multicast_pado.patch new file mode 100644 index 0000000000..ea5275c461 --- /dev/null +++ b/package/ppp/patches/102-debian_pppoe_multicast_pado.patch @@ -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/package/ppp/patches/103-debian_pppoe_cleanup.patch b/package/ppp/patches/103-debian_pppoe_cleanup.patch new file mode 100644 index 0000000000..8a97a0b2e5 --- /dev/null +++ b/package/ppp/patches/103-debian_pppoe_cleanup.patch @@ -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/package/ppp/patches/104-debian_fix_linkpidfile.patch b/package/ppp/patches/104-debian_fix_linkpidfile.patch new file mode 100644 index 0000000000..9e32adcae1 --- /dev/null +++ b/package/ppp/patches/104-debian_fix_linkpidfile.patch @@ -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/package/ppp/patches/105-debian_pppoatm_cleanup.patch b/package/ppp/patches/105-debian_pppoatm_cleanup.patch new file mode 100644 index 0000000000..2437a12003 --- /dev/null +++ b/package/ppp/patches/105-debian_pppoatm_cleanup.patch @@ -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/package/ppp/patches/106-debian_pppoatm_fix_mtu.patch b/package/ppp/patches/106-debian_pppoatm_fix_mtu.patch new file mode 100644 index 0000000000..ef28b5cf2b --- /dev/null +++ b/package/ppp/patches/106-debian_pppoatm_fix_mtu.patch @@ -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/package/ppp/patches/107-debian_stripMSdomain.patch b/package/ppp/patches/107-debian_stripMSdomain.patch new file mode 100644 index 0000000000..d52e38645d --- /dev/null +++ b/package/ppp/patches/107-debian_stripMSdomain.patch @@ -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/package/ppp/patches/108-debian_defaultroute.patch b/package/ppp/patches/108-debian_defaultroute.patch new file mode 100644 index 0000000000..76b444e4b2 --- /dev/null +++ b/package/ppp/patches/108-debian_defaultroute.patch @@ -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/package/ppp/patches/109-debian_demand.patch b/package/ppp/patches/109-debian_demand.patch new file mode 100644 index 0000000000..e024696697 --- /dev/null +++ b/package/ppp/patches/109-debian_demand.patch @@ -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/package/ppp/patches/200-makefile.patch b/package/ppp/patches/200-makefile.patch new file mode 100644 index 0000000000..5bbf8602d1 --- /dev/null +++ b/package/ppp/patches/200-makefile.patch @@ -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/package/ppp/patches/201-mppe_mppc_1.1.patch b/package/ppp/patches/201-mppe_mppc_1.1.patch new file mode 100644 index 0000000000..7e09f1a792 --- /dev/null +++ b/package/ppp/patches/201-mppe_mppc_1.1.patch @@ -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/package/ppp/patches/202-atm_fix.patch b/package/ppp/patches/202-atm_fix.patch new file mode 100644 index 0000000000..40d9d595cf --- /dev/null +++ b/package/ppp/patches/202-atm_fix.patch @@ -0,0 +1,11 @@ +--- ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c 2005-08-26 15:18:55.000000000 +0200 ++++ ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c 2005-08-26 15:19:51.000000000 +0200 +@@ -136,8 +136,6 @@ + int fd; + struct atm_qos qos; + +- system ("/sbin/modprobe pppoatm"); +- + if (!device_got_set) + no_device_given_pppoatm(); + fd = socket(AF_ATMPVC, SOCK_DGRAM, 0); diff --git a/package/ppp/patches/203-no_strip.patch b/package/ppp/patches/203-no_strip.patch new file mode 100644 index 0000000000..216973cf59 --- /dev/null +++ b/package/ppp/patches/203-no_strip.patch @@ -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/package/ppp/patches/204-opt_flags.patch b/package/ppp/patches/204-opt_flags.patch new file mode 100644 index 0000000000..200e76b5b5 --- /dev/null +++ b/package/ppp/patches/204-opt_flags.patch @@ -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/package/ppp/patches/205-pppoe_iface_name.patch b/package/ppp/patches/205-pppoe_iface_name.patch new file mode 100644 index 0000000000..0961eca623 --- /dev/null +++ b/package/ppp/patches/205-pppoe_iface_name.patch @@ -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, "ath", 3) + && strncmp(cmd, "tap", 3) && strncmp(cmd, "br", 2))) { + return 0; + } diff --git a/package/ppp/patches/206-radius_config.patch b/package/ppp/patches/206-radius_config.patch new file mode 100644 index 0000000000..90c02af4c1 --- /dev/null +++ b/package/ppp/patches/206-radius_config.patch @@ -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/package/ppp/patches/207-ppp_reconnect.patch b/package/ppp/patches/207-ppp_reconnect.patch new file mode 100644 index 0000000000..9311c9ef4e --- /dev/null +++ b/package/ppp/patches/207-ppp_reconnect.patch @@ -0,0 +1,129 @@ +diff -urN -x'*.swp' ppp.old/pppd/auth.c ppp.dev/pppd/auth.c +--- ppp.old/pppd/auth.c 2004-11-12 11:30:51.000000000 +0100 ++++ ppp.dev/pppd/auth.c 2005-07-13 14:54:23.000000000 +0200 +@@ -532,6 +532,12 @@ + link_required(unit) + int unit; + { ++} ++ ++void ++start_link(unit) ++ int unit; ++{ + new_phase(PHASE_SERIALCONN); + + devfd = the_channel->connect(); +@@ -984,10 +990,12 @@ + int unit, protocol, prot_flavor; + { + int bit; ++ const char *prot = ""; + + switch (protocol) { + case PPP_CHAP: + bit = CHAP_WITHPEER; ++ prot = "CHAP"; + switch (prot_flavor) { + case CHAP_MD5: + bit |= CHAP_MD5_WITHPEER; +@@ -1006,15 +1014,19 @@ + if (passwd_from_file) + BZERO(passwd, MAXSECRETLEN); + bit = PAP_WITHPEER; ++ prot = "PAP"; + break; + case PPP_EAP: + bit = EAP_WITHPEER; ++ prot = "EAP"; + break; + default: + warn("auth_withpeer_success: unknown protocol %x", protocol); + bit = 0; + } + ++ notice("%s authentication succeeded", prot); ++ + /* Save the authentication method for later. */ + auth_done[unit] |= bit; + +@@ -1648,6 +1660,7 @@ + static void + plogout() + { ++ char *tty; + #ifdef USE_PAM + int pam_error; + +@@ -1658,14 +1671,12 @@ + } + /* Apparently the pam stuff does closelog(). */ + reopen_log(); +-#else /* ! USE_PAM */ +- char *tty; ++#endif /* USE_PAM */ + + tty = devnam; + if (strncmp(tty, "/dev/", 5) == 0) + tty += 5; + logwtmp(tty, "", ""); /* Wipe out utmp logout entry */ +-#endif /* ! USE_PAM */ + logged_in = 0; + } + +diff -urN -x'*.swp' ppp.old/pppd/main.c ppp.dev/pppd/main.c +--- ppp.old/pppd/main.c 2005-07-13 11:34:28.000000000 +0200 ++++ ppp.dev/pppd/main.c 2005-07-13 14:49:06.000000000 +0200 +@@ -537,6 +537,7 @@ + script_unsetenv("BYTES_RCVD"); + + lcp_open(0); /* Start protocol */ ++ start_link(0); + while (phase != PHASE_DEAD) { + handle_events(); + get_input(); +diff -urN -x'*.swp' ppp.old/pppd/pppd.h ppp.dev/pppd/pppd.h +--- ppp.old/pppd/pppd.h 2005-07-13 11:34:28.000000000 +0200 ++++ ppp.dev/pppd/pppd.h 2005-07-13 14:48:56.000000000 +0200 +@@ -526,6 +526,7 @@ + + /* Procedures exported from auth.c */ + void link_required __P((int)); /* we are starting to use the link */ ++void start_link __P((int)); /* bring the link up now */ + void link_terminated __P((int)); /* we are finished with the link */ + void link_down __P((int)); /* the LCP layer has left the Opened state */ + void upper_layers_down __P((int));/* take all NCPs down */ +diff -urN -x'*.swp' ppp.old/pppd/tty.c ppp.dev/pppd/tty.c +--- ppp.old/pppd/tty.c 2004-11-13 13:07:29.000000000 +0100 ++++ ppp.dev/pppd/tty.c 2005-07-13 14:46:57.000000000 +0200 +@@ -755,14 +755,6 @@ + close(pty_master); + pty_master = -1; + } +- if (pty_slave >= 0) { +- close(pty_slave); +- pty_slave = -1; +- } +- if (real_ttyfd >= 0) { +- close(real_ttyfd); +- real_ttyfd = -1; +- } + ttyfd = -1; + if (got_sigterm) + asked_to_quit = 1; +@@ -781,6 +773,7 @@ + } else { + info("Serial link disconnected."); + } ++ stop_charshunt(NULL, 0); + } + + void tty_close_fds() +@@ -944,7 +937,6 @@ + exit(0); + } + charshunt_pid = cpid; +- add_notifier(&sigreceived, stop_charshunt, 0); + record_child(cpid, "pppd (charshunt)", charshunt_done, NULL); + return 1; + } diff --git a/package/ppp/patches/208-no_exponential_timeout.patch b/package/ppp/patches/208-no_exponential_timeout.patch new file mode 100644 index 0000000000..d6c986a7ed --- /dev/null +++ b/package/ppp/patches/208-no_exponential_timeout.patch @@ -0,0 +1,28 @@ +diff -urN ppp.old/pppd/plugins/rp-pppoe/discovery.c ppp.dev/pppd/plugins/rp-pppoe/discovery.c +--- ppp.old/pppd/plugins/rp-pppoe/discovery.c 2005-09-05 15:25:35.917232000 +0200 ++++ ppp.dev/pppd/plugins/rp-pppoe/discovery.c 2005-09-05 15:29:17.233586872 +0200 +@@ -593,12 +593,14 @@ + conn->discoveryState = STATE_SENT_PADI; + waitForPADO(conn, timeout); + ++#if 0 + /* If we're just probing for access concentrators, don't do + exponential backoff. This reduces the time for an unsuccessful + probe to 15 seconds. */ + if (!conn->printACNames) { + timeout *= 2; + } ++#endif + if (conn->printACNames && conn->numPADOs) { + break; + } +@@ -621,7 +623,9 @@ + sendPADR(conn); + conn->discoveryState = STATE_SENT_PADR; + waitForPADS(conn, timeout); ++#if 0 + timeout *= 2; ++#endif + } while (conn->discoveryState == STATE_SENT_PADR); + + /* We're done. */ diff --git a/package/ppp/patches/209-compensate_time_change.patch b/package/ppp/patches/209-compensate_time_change.patch new file mode 100644 index 0000000000..f43085ab11 --- /dev/null +++ b/package/ppp/patches/209-compensate_time_change.patch @@ -0,0 +1,82 @@ +diff -urN ppp.old/pppd/main.c ppp.dev/pppd/main.c +--- ppp.old/pppd/main.c 2005-11-11 19:19:28.177790000 +0100 ++++ ppp.dev/pppd/main.c 2005-11-11 20:18:05.957363000 +0100 +@@ -90,6 +90,7 @@ + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> ++#include <sys/sysinfo.h> + + #include "pppd.h" + #include "magic.h" +@@ -227,6 +228,7 @@ + + /* Prototypes for procedures local to this file. */ + ++static void check_time(void); + static void setup_signals __P((void)); + static void create_pidfile __P((int pid)); + static void create_linkpidfile __P((int pid)); +@@ -531,6 +533,7 @@ + info("Starting link"); + } + ++ check_time(); + gettimeofday(&start_time, NULL); + script_unsetenv("CONNECT_TIME"); + script_unsetenv("BYTES_SENT"); +@@ -1195,6 +1198,36 @@ + + static struct callout *callout = NULL; /* Callout list */ + static struct timeval timenow; /* Current time */ ++static long uptime_diff = 0; ++static int uptime_diff_set = 0; ++ ++static void check_time(void) ++{ ++ long new_diff; ++ struct timeval t; ++ struct sysinfo i; ++ struct callout *p; ++ ++ gettimeofday(&t, NULL); ++ sysinfo(&i); ++ new_diff = t.tv_sec - i.uptime; ++ ++ if (!uptime_diff_set) { ++ uptime_diff = new_diff; ++ uptime_diff_set = 1; ++ return; ++ } ++ ++ if ((new_diff - 5 > uptime_diff) || (new_diff + 5 < uptime_diff)) { ++ /* system time has changed, update counters and timeouts */ ++ info("System time change detected."); ++ start_time.tv_sec += new_diff - uptime_diff; ++ ++ for (p = callout; p != NULL; p = p->c_next) ++ p->c_time.tv_sec += new_diff - uptime_diff; ++ } ++ uptime_diff = new_diff; ++} + + /* + * timeout - Schedule a timeout. +@@ -1265,6 +1298,8 @@ + { + struct callout *p; + ++ check_time(); ++ + while (callout != NULL) { + p = callout; + +@@ -1292,6 +1327,8 @@ + { + if (callout == NULL) + return NULL; ++ ++ check_time(); + + gettimeofday(&timenow, NULL); + tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; diff --git a/package/ppp/patches/210-lcp_mtu_max.patch b/package/ppp/patches/210-lcp_mtu_max.patch new file mode 100644 index 0000000000..2056a87325 --- /dev/null +++ b/package/ppp/patches/210-lcp_mtu_max.patch @@ -0,0 +1,17 @@ +--- ppp-2.4.3/pppd/lcp.c.old 2006-10-10 14:19:11.000000000 +0200 ++++ ppp-2.4.3/pppd/lcp.c 2006-10-10 14:19:55.000000000 +0200 +@@ -1891,12 +1891,12 @@ + * the interface MTU is set to the lowest of that, the + * MTU we want to use, and our link MRU. + */ +- mtu = ho->neg_mru? ho->mru: PPP_MRU; ++ mtu = MIN(ho->neg_mru? ho->mru: PPP_MRU, ao->mru); + mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; + #ifdef HAVE_MULTILINK + if (!(multilink && go->neg_mrru && ho->neg_mrru)) + #endif /* HAVE_MULTILINK */ +- netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru)); ++ netif_set_mtu(f->unit, MIN(mtu, mru)); + ppp_send_config(f->unit, mtu, + (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), + ho->neg_pcompression, ho->neg_accompression); diff --git a/package/ppp/patches/300-filter-pcap-includes-lib.patch b/package/ppp/patches/300-filter-pcap-includes-lib.patch new file mode 100644 index 0000000000..3f6247d6ef --- /dev/null +++ b/package/ppp/patches/300-filter-pcap-includes-lib.patch @@ -0,0 +1,14 @@ +diff -urN ppp-2.4.3.orig/pppd/Makefile.linux ppp-2.4.3/pppd/Makefile.linux +--- ppp-2.4.3.orig/pppd/Makefile.linux 2006-02-05 20:13:06.000000000 +0100 ++++ ppp-2.4.3/pppd/Makefile.linux 2006-02-05 20:24:22.000000000 +0100 +@@ -172,8 +172,8 @@ + + ifdef FILTER + ifneq ($(wildcard /usr/include/pcap-bpf.h),) +-LIBS += -lpcap +-CFLAGS += -DPPP_FILTER ++LIBS += -lpcap -L$(STAGING_DIR)/usr/lib ++CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)/usr/include + endif + endif + diff --git a/package/ppp/patches/310-precompiled_filter.patch b/package/ppp/patches/310-precompiled_filter.patch new file mode 100644 index 0000000000..df9452c379 --- /dev/null +++ b/package/ppp/patches/310-precompiled_filter.patch @@ -0,0 +1,231 @@ +diff -urN ppp.old/pppd/Makefile.linux ppp.dev/pppd/Makefile.linux +--- ppp.old/pppd/Makefile.linux 2006-03-18 15:58:00.000000000 +0100 ++++ ppp.dev/pppd/Makefile.linux 2006-03-18 16:52:01.000000000 +0100 +@@ -50,6 +50,9 @@ + # and that the kernel driver support PPP packet filtering. + #FILTER=y + ++# Support for precompiled filters ++PRECOMPILED_FILTER=y ++ + # Uncomment the next line to enable multilink PPP (enabled by default) + # Linux distributions: Please leave multilink ENABLED in your builds + # of pppd! +@@ -177,6 +180,14 @@ + endif + endif + ++ifdef PRECOMPILED_FILTER ++PPPDSRCS += pcap_pcc.c ++HEADERS += pcap_pcc.h ++PPPDOBJS += pcap_pcc.o ++LIBS += $(STAGING_DIR)/usr/lib/libpcap.a ++CFLAGS += -DPPP_FILTER -DPPP_PRECOMPILED_FILTER -I$(STAGING_DIR)/usr/include ++endif ++ + ifdef HAVE_INET6 + PPPDSRCS += ipv6cp.c eui64.c + HEADERS += ipv6cp.h eui64.h +diff -urN ppp.old/pppd/demand.c ppp.dev/pppd/demand.c +--- ppp.old/pppd/demand.c 2006-03-18 15:58:00.000000000 +0100 ++++ ppp.dev/pppd/demand.c 2006-03-18 18:09:16.000000000 +0100 +@@ -438,12 +438,14 @@ + return 0; + proto = PPP_PROTOCOL(p); + #ifdef PPP_FILTER ++ *p = 1; /* set outbound for the filter rule */ + if (pass_filter.bf_len != 0 + && bpf_filter(pass_filter.bf_insns, p, len, len) == 0) + return 0; + if (active_filter.bf_len != 0 + && bpf_filter(active_filter.bf_insns, p, len, len) == 0) + return 0; ++ *p = 0xff; /* restore original ppp header */ + #endif + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { +diff -urN ppp.old/pppd/options.c ppp.dev/pppd/options.c +--- ppp.old/pppd/options.c 2006-03-18 15:58:00.000000000 +0100 ++++ ppp.dev/pppd/options.c 2006-03-18 18:05:58.000000000 +0100 +@@ -57,14 +57,7 @@ + + #ifdef PPP_FILTER + #include <pcap.h> +-/* +- * DLT_PPP_WITH_DIRECTION is in current libpcap cvs, and should be in +- * libpcap-0.8.4. Until that is released, use DLT_PPP - but that means +- * we lose the inbound and outbound qualifiers. +- */ +-#ifndef DLT_PPP_WITH_DIRECTION +-#define DLT_PPP_WITH_DIRECTION DLT_PPP +-#endif ++#include <pcap-bpf.h> + #endif + + #include "pppd.h" +@@ -155,6 +148,13 @@ + static int loadplugin __P((char **)); + #endif + ++#ifdef PPP_PRECOMPILED_FILTER ++#include "pcap_pcc.h" ++static int setprecompiledpassfilter __P((char **)); ++static int setprecompiledactivefilter __P((char **)); ++#undef PPP_FILTER ++#endif ++ + #ifdef PPP_FILTER + static int setpassfilter __P((char **)); + static int setactivefilter __P((char **)); +@@ -312,6 +312,14 @@ + "set filter for active pkts", OPT_PRIO }, + #endif + ++#ifdef PPP_PRECOMPILED_FILTER ++ { "precompiled-pass-filter", 1, setprecompiledpassfilter, ++ "set precompiled filter for packets to pass", OPT_PRIO }, ++ ++ { "precompiled-active-filter", 1, setprecompiledactivefilter, ++ "set precompiled filter for active pkts", OPT_PRIO }, ++#endif ++ + #ifdef MAXOCTETS + { "maxoctets", o_int, &maxoctets, + "Set connection traffic limit", +@@ -1447,6 +1455,29 @@ + return ok; + } + ++#ifdef PPP_PRECOMPILED_FILTER ++/* ++ * setprecompiledpassfilter - Set the pass filter for packets using a ++ * precompiled expression ++ */ ++static int ++setprecompiledpassfilter(argv) ++ char **argv; ++{ ++ return pcap_pre_compiled (*argv, &pass_filter); ++} ++ ++/* ++ * setactivefilter - Set the active filter for packets ++ */ ++static int ++setprecompiledactivefilter(argv) ++ char **argv; ++{ ++ return pcap_pre_compiled (*argv, &active_filter); ++} ++#endif ++ + #ifdef PPP_FILTER + /* + * setpassfilter - Set the pass filter for packets +@@ -1458,7 +1489,7 @@ + pcap_t *pc; + int ret = 0; + +- pc = pcap_open_dead(DLT_PPP_WITH_DIRECTION, 65535); ++ pc = pcap_open_dead(DLT_PPP_PPPD, 65535); + if (pcap_compile(pc, &pass_filter, *argv, 1, netmask) == -1) { + option_error("error in pass-filter expression: %s\n", + pcap_geterr(pc)); +@@ -1479,7 +1510,7 @@ + pcap_t *pc; + int ret = 0; + +- pc = pcap_open_dead(DLT_PPP_WITH_DIRECTION, 65535); ++ pc = pcap_open_dead(DLT_PPP_PPPD, 65535); + if (pcap_compile(pc, &active_filter, *argv, 1, netmask) == -1) { + option_error("error in active-filter expression: %s\n", + pcap_geterr(pc)); +diff -urN ppp.old/pppd/pcap_pcc.c ppp.dev/pppd/pcap_pcc.c +--- ppp.old/pppd/pcap_pcc.c 1970-01-01 01:00:00.000000000 +0100 ++++ ppp.dev/pppd/pcap_pcc.c 2006-03-18 16:51:31.000000000 +0100 +@@ -0,0 +1,74 @@ ++#include <pcap.h> ++#include <pcap-bpf.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <errno.h> ++#include "pppd.h" ++ ++int pcap_pre_compiled (char * fname, struct bpf_program *p) ++{ ++ char buf[128]; ++ int line = 0, size = 0, index=0, ret=1; ++ FILE *f = fopen (fname, "r"); ++ if (!f) ++ { ++ option_error("error opening precompiled active-filter '%s': %s", ++ fname, strerror (errno)); ++ return 0; ++ } ++ while (fgets (buf, 127, f)) ++ { ++ line++; ++ if (*buf == '#') ++ continue; ++ if (size) ++ { ++ /* ++ struct bpf_insn { ++ u_short code; ++ u_char jt; ++ u_char jf; ++ bpf_int32 k; ++ } ++ */ ++ struct bpf_insn * insn = & p->bf_insns[index]; ++ unsigned code, jt, jf, k; ++ if (sscanf (buf, "%u %u %u %u", &code, &jt, &jf, &k) != 4) ++ { ++ goto err; ++ } ++ insn->code = code; ++ insn->jt = jt; ++ insn->jf = jf; ++ insn->k = k; ++ index++; ++ } ++ else ++ { ++ if (sscanf (buf, "%u", &size) != 1) ++ { ++ goto err; ++ } ++ p->bf_len = size; ++ p->bf_insns = (struct bpf_insn *) ++ malloc (size * sizeof (struct bpf_insn)); ++ } ++ } ++ if (size != index) ++ { ++ option_error("error in precompiled active-filter," ++ " expected %d expressions, got %dn", ++ size, index); ++ ret = 0; ++ } ++ fclose(f); ++ return ret; ++ ++err: ++ option_error("error in precompiled active-filter" ++ " expression line %s:%d (wrong size)\n", ++ fname, line); ++ fclose (f); ++ return 0; ++} +diff -urN ppp.old/pppd/pcap_pcc.h ppp.dev/pppd/pcap_pcc.h +--- ppp.old/pppd/pcap_pcc.h 1970-01-01 01:00:00.000000000 +0100 ++++ ppp.dev/pppd/pcap_pcc.h 2006-03-18 15:59:14.000000000 +0100 +@@ -0,0 +1,7 @@ ++#ifndef PCAP_PCC_H ++#define PCAP_PCC_H ++ ++#include <pcap.h> ++ ++int pcap_pre_compiled (char * fname, struct bpf_program *p); ++#endif /* PCAP_PCC_H */ |