include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ppp
-PKG_RELEASE:=6
+PKG_VERSION:=2.5.0
+PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=https://github.com/paulusmack/ppp
-PKG_SOURCE_DATE:=2021-01-04
-PKG_SOURCE_VERSION:=4fb319056f168bb8379865b91b4fd3e1ada73f1e
-PKG_MIRROR_HASH:=58b415e17bdcac81bb9594a1b2ba65ec90598817850d22e98c1690e8ed0cd3d8
+PKG_SOURCE_URL:=https://github.com/ppp-project/ppp
+PKG_SOURCE_DATE:=2023-03-18
+PKG_SOURCE_VERSION:=760ce18f82670eb81cc186fb792919339a2e2fbe
+PKG_MIRROR_HASH:=e7fe5947ce9e59d73f6d2fdec5d2e40832e656b9edad288578391f8f169b8b9b
+
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=BSD-4-Clause
PKG_CPE_ID:=cpe:/a:samba:ppp
-PKG_RELEASE_VERSION:=2.4.9
-PKG_VERSION:=$(PKG_RELEASE_VERSION)_git$(subst -,,$(PKG_SOURCE_DATE))
-
-PKG_BUILD_DEPENDS:=libpcap
-
PKG_ASLR_PIE_REGULAR:=1
+PKG_BUILD_DEPENDS:=libpcap
PKG_BUILD_FLAGS:=gc-sections lto
PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
+CONFIGURE_VARS += \
+ enable_eaptls=no \
+ enable_microsoft_extensions=yes \
+ enable_peap=no
+
+CONFIGURE_ARGS += \
+ with_openssl=no \
+ with_pcap=no \
+ with_static_pcap=yes
define Package/ppp/Default
SECTION:=net
endef
MAKE_FLAGS += COPTS="$(TARGET_CFLAGS)" \
- PRECOMPILED_FILTER=1 \
STAGING_DIR="$(STAGING_DIR)"
ifeq ($(BUILD_VARIANT),multilink)
- MAKE_FLAGS += HAVE_MULTILINK=y
-else
- MAKE_FLAGS += HAVE_MULTILINK=
+ CONFIGURE_VARS += \
+ enable_multilink=yes
endif
ifdef CONFIG_USE_MUSL
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
- $(CP) $(PKG_INSTALL_DIR)/include/pppd $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/pppd $(1)/usr/include/
endef
define Package/ppp/script_install
endef
define Package/ppp/install
- $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
$(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/pppd $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/pppd $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc/ppp
$(INSTALL_CONF) ./files/etc/ppp/chap-secrets $(1)/etc/ppp/
$(INSTALL_DATA) ./files/etc/ppp/filter $(1)/etc/ppp/
Package/ppp-multilink/install=$(Package/ppp/install)
define Package/ppp-mod-pppoa/install
- $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_RELEASE_VERSION)/pppoatm.so \
- $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)/
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/pppd/$(PKG_VERSION)/pppoatm.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
endef
define Package/ppp-mod-pppoe/install
- $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_RELEASE_VERSION)/pppoe.so \
- $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)/
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/pppd/$(PKG_VERSION)/pppoe.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
endef
define Package/ppp-mod-radius/install
- $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_RELEASE_VERSION)/radius.so \
- $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)/
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/pppd/$(PKG_VERSION)/radius.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
$(INSTALL_DIR) $(1)/etc/ppp
$(INSTALL_DATA) ./files/etc/ppp/radius.conf $(1)/etc/ppp/
$(INSTALL_DIR) $(1)/etc/ppp/radius
endef
define Package/ppp-mod-pppol2tp/install
- $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_RELEASE_VERSION)/pppol2tp.so \
- $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)/
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/pppd/$(PKG_VERSION)/pppol2tp.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
endef
define Package/ppp-mod-pptp/install
- $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_RELEASE_VERSION)/pptp.so \
- $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)/
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/pppd/$(PKG_VERSION)/pptp.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
$(INSTALL_DIR) $(1)/etc/ppp
$(INSTALL_DATA) ./files/etc/ppp/options.pptp $(1)/etc/ppp/
endef
define Package/ppp-mod-passwordfd/install
- $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/pppd/$(PKG_RELEASE_VERSION)/passwordfd.so \
- $(1)/usr/lib/pppd/$(PKG_RELEASE_VERSION)/
+ $(INSTALL_DIR) $(1)/usr/lib/pppd/$(PKG_VERSION)
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/pppd/$(PKG_VERSION)/passwordfd.so \
+ $(1)/usr/lib/pppd/$(PKG_VERSION)/
endef
define Package/chat/install
$(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/chat $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/chat $(1)/usr/sbin/
endef
define Package/pppdump/install
$(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/pppdump $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/pppdump $(1)/usr/sbin/
endef
define Package/pppstats/install
$(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/pppstats $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/pppstats $(1)/usr/sbin/
endef
define Package/pppoe-discovery/install
$(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/pppoe-discovery $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/pppoe-discovery $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,ppp))
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
---- a/configure
-+++ b/configure
-@@ -10,9 +10,9 @@ CROSS_COMPILE=
- CC=cc
- CFLAGS=
+--- a/configure.ac
++++ b/configure.ac
+@@ -354,7 +354,7 @@ Setting up SunOS kernel module(s)"
+ fi
+ }
--system=`uname -s`
--release=`uname -r`
--arch=`uname -m`
-+system=${UNAME_S:-`uname -s`}
-+release=${UNAME_R:-`uname -r`}
-+arch=${UNAME_M:-`uname -m`}
- state="unknown"
-
- case $system in
+- release=`uname -r`
++ release=${UNAME_R:-`uname -r`}
+ karch=`/usr/bin/isainfo -k`
+ makext="sol2"
+ archvariant=
--- a/pppd/demand.c
+++ b/pppd/demand.c
-@@ -36,6 +36,8 @@
+@@ -40,6 +40,8 @@
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
-@@ -43,6 +45,8 @@
+@@ -47,6 +49,8 @@
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
- #ifdef PPP_FILTER
+ #ifdef PPP_WITH_FILTER
#include <pcap-bpf.h>
#endif
-@@ -218,6 +222,14 @@ loop_chars(unsigned char *p, int n)
+@@ -223,6 +227,14 @@ loop_chars(unsigned char *p, int n)
int c, rv;
rv = 0;
for (; n > 0; --n) {
c = *p++;
if (c == PPP_FLAG) {
-@@ -294,16 +306,100 @@ loop_frame(unsigned char *frame, int len
+@@ -299,16 +311,100 @@ loop_frame(unsigned char *frame, int len
* loopback, now that the real serial link is up.
*/
void
} else {
--- a/pppd/ipcp.c
+++ b/pppd/ipcp.c
-@@ -1850,7 +1850,7 @@ ipcp_up(fsm *f)
+@@ -1911,7 +1911,7 @@ ipcp_up(fsm *f)
proxy_arp_set[f->unit] = 1;
}
} else {
--- a/pppd/ipv6cp.c
+++ b/pppd/ipv6cp.c
-@@ -1253,7 +1253,7 @@ ipv6cp_up(fsm *f)
+@@ -1338,7 +1338,7 @@ ipv6cp_up(fsm *f)
if (sif6defaultroute(f->unit, go->ourid, ho->hisid))
default_route_set[f->unit] = 1;
}
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
} else {
---- a/pppd/pppd.h
-+++ b/pppd/pppd.h
-@@ -598,7 +598,7 @@ void demand_conf(void); /* config interf
+--- a/pppd/pppd-private.h
++++ b/pppd/pppd-private.h
+@@ -362,7 +362,7 @@ void demand_conf(void); /* config interf
void demand_block(void); /* set all NPs to queue up packets */
void demand_unblock(void); /* set all NPs to pass packets */
void demand_discard(void); /* set all NPs to discard packets */
-void demand_rexmit(int); /* retransmit saved frames for an NP */
-+void demand_rexmit(int, u_int32_t); /* retransmit saved frames for an NP*/
++void demand_rexmit(int, u_int32_t); /* retransmit saved frames for an NP */
int loop_chars(unsigned char *, int); /* process chars from loopback */
int loop_frame(unsigned char *, int); /* should we bring link up? */
+++ /dev/null
-pppd: Allow specifying ipv6-up and ipv6-down scripts
-
-This patch implements the "ipv6-up-script" and "ipv6-down-script" options
-which allow to specify the path of the ipv6-up and ipv6-down scripts to call.
-
-These options default to _PATH_IPV6UP and _PATH_IPV6DOWN to retain the
-existing behaviour.
-
-The patch originated from the Debian project.
-
-Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-
---- a/pppd/main.c
-+++ b/pppd/main.c
-@@ -295,6 +295,8 @@ main(int argc, char *argv[])
-
- strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
- strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
-+ strlcpy(path_ipv6up, _PATH_IPV6UP, sizeof(path_ipv6up));
-+ strlcpy(path_ipv6down, _PATH_IPV6DOWN, sizeof(path_ipv6down));
-
- link_stats_valid = 0;
- new_phase(PHASE_INITIALIZE);
---- a/pppd/options.c
-+++ b/pppd/options.c
-@@ -118,6 +118,8 @@ int req_unit = -1; /* requested interfa
- char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
- char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
- char req_ifname[MAXIFNAMELEN]; /* requested interface name */
-+char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
-+char path_ipv6down[MAXPATHLEN];/* pathname of ipv6-down script */
- bool multilink = 0; /* Enable multilink operation */
- char *bundle_name = NULL; /* bundle name for multilink */
- bool dump_options; /* print out option values */
-@@ -324,6 +326,13 @@ option_t general_options[] = {
- "Set pathname of ip-down script",
- OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
-
-+ { "ipv6-up-script", o_string, path_ipv6up,
-+ "Set pathname of ipv6-up script",
-+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
-+ { "ipv6-down-script", o_string, path_ipv6down,
-+ "Set pathname of ipv6-down script",
-+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
-+
- #ifdef HAVE_MULTILINK
- { "multilink", o_bool, &multilink,
- "Enable multilink operation", OPT_PRIO | 1 },
---- a/pppd/ipv6cp.c
-+++ b/pppd/ipv6cp.c
-@@ -1295,7 +1295,7 @@ ipv6cp_up(fsm *f)
- */
- if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) {
- ipv6cp_script_state = s_up;
-- ipv6cp_script(_PATH_IPV6UP);
-+ ipv6cp_script(path_ipv6up);
- }
- }
-
-@@ -1346,7 +1346,7 @@ ipv6cp_down(fsm *f)
- /* Execute the ipv6-down script */
- if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) {
- ipv6cp_script_state = s_down;
-- ipv6cp_script(_PATH_IPV6DOWN);
-+ ipv6cp_script(path_ipv6down);
- }
- }
-
-@@ -1384,13 +1384,13 @@ ipv6cp_script_done(void *arg)
- case s_up:
- if (ipv6cp_fsm[0].state != OPENED) {
- ipv6cp_script_state = s_down;
-- ipv6cp_script(_PATH_IPV6DOWN);
-+ ipv6cp_script(path_ipv6down);
- }
- break;
- case s_down:
- if (ipv6cp_fsm[0].state == OPENED) {
- ipv6cp_script_state = s_up;
-- ipv6cp_script(_PATH_IPV6UP);
-+ ipv6cp_script(path_ipv6up);
- }
- break;
- }
---- a/pppd/pppd.h
-+++ b/pppd/pppd.h
-@@ -328,6 +328,8 @@ extern int req_unit; /* interface unit n
- extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
- extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
- extern char req_ifname[MAXIFNAMELEN]; /* interface name to use */
-+extern char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
-+extern char path_ipv6down[MAXPATHLEN]; /* pathname of ipv6-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 */
+++ /dev/null
---- a/pppd/sha1.c
-+++ b/pppd/sha1.c
-@@ -19,7 +19,7 @@
- #include <string.h>
- #include <time.h>
- #include <netinet/in.h> /* htonl() */
--#include <net/ppp_defs.h>
-+#include "pppd.h"
- #include "sha1.h"
-
- static void
+++ /dev/null
-From 98ec18f098e5ef68e3a8cc6954fcaf5a7fb8b7be Mon Sep 17 00:00:00 2001
-From: pali <7141871+pali@users.noreply.github.com>
-Date: Mon, 15 Feb 2021 07:54:01 +0100
-Subject: [PATCH] pppd: Fix compilation with older glibc or kernel headers
- (#248)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-glibc versions prior to 2.24 do not define SOL_NETLINK and linux kernel
-versions prior to 4.3 do not define NETLINK_CAP_ACK. So add fallback
-definitions for these macros into pppd/sys-linux.c file.
-
-Also extend description why we call SOL_NETLINK/NETLINK_CAP_ACK option.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
----
- pppd/sys-linux.c | 18 +++++++++++++++++-
- 1 file changed, 17 insertions(+), 1 deletion(-)
-
---- a/pppd/sys-linux.c
-+++ b/pppd/sys-linux.c
-@@ -125,6 +125,14 @@
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
- #include <linux/if_addr.h>
-+/* glibc versions prior to 2.24 do not define SOL_NETLINK */
-+#ifndef SOL_NETLINK
-+#define SOL_NETLINK 270
-+#endif
-+/* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
-+#ifndef NETLINK_CAP_ACK
-+#define NETLINK_CAP_ACK 10
-+#endif
- #endif
-
- #include "pppd.h"
-@@ -2843,7 +2851,15 @@ static int append_peer_ipv6_address(unsi
- if (fd < 0)
- return 0;
-
-- /* do not ask for error message content */
-+ /*
-+ * Tell kernel to not send to us payload of acknowledgment error message.
-+ * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
-+ * older kernel versions always send full payload in acknowledgment netlink
-+ * message. We ignore payload of this message as we need only error code,
-+ * to check if our set remote peer address request succeeded or failed.
-+ * So ignore return value from the following setsockopt() call as setting
-+ * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
-+ */
- one = 1;
- setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
-
+++ /dev/null
-From 81ad945630120cc1c27c8bb00503be42b76ff202 Mon Sep 17 00:00:00 2001
-From: Jaco Kroon <jaco@uls.co.za>
-Date: Thu, 13 Jan 2022 08:38:04 +0200
-Subject: [PATCH] Expand byte count statistics to 64 bits (#298)
-
-* Add Gigawords to radius packets where applicable.
-
-IMPORTANT NOTE: The ioctl() only supports 32-bit counters. In order t
-obtain 64-bit counters, these are now pulled in from sysfs (it's assumed
-to be mounted on /sys which I'm assuming is standard).
-
-It is unknown whether sysfs will be available everywhere, as such, keep
-the ioctl() method in place, but attempt to detect wrap-overs.
-
-If the sysfs mechanism fails, fail back to the ioctl().
-
-Given maximum data rates, the intervals between calling this needs to be
-such that no more than 4GB (2^32) bytes are sent or received in any
-given interval. Mostly important for radius plugin where data
-accounting may be in effect.
-
-Towards this, a timer interval on 25 seconds is set to force a ioctl()
-poll irrespective of the rate of stats update calls. This may be
-important for especially radius that needs to provide interim-update
-intervals, if the interim updates is too long and the counters could
-wrap-over twice in a single interval. At 25 seconds we should detect
-all wraps up to an effective data rate of 1.37Gbps, which for my
-purposes is adequate.
-
-Possible downsides, 4 files are opened, read and closed every time
-statistics is requested. This results in 12 system calls every single
-time statistics is required, compared to 1 for the ioctl. Efficiency is
-unknown, but as a rule of thumb fewer system calls are better, this is
-however not a critical path in my opinion, so should not be a problem.
-If required I can run a few benchmarks using gettimeofday() to measure
-actual impact.
-
-Signed-off-by: Jaco Kroon <jaco@uls.co.za>
-
-* Use netlink if possible to obtain 64-bit stats.
-
-This uses two system calls per round.
-
-This should be preferred where available. It seems the RTM_GETSTATS was
-only added from 2016 some point (4.7.0 as per pali), which is in my
-opinion old, but given experience with certain embedded systems does
-need to be supported.
-
-Signed-off-by: Jaco Kroon <jaco@uls.co.za>
-
-Co-authored-by: Jaco Kroon <jaco@iewc.co.za>
----
- pppd/main.c | 5 +-
- pppd/plugins/radius/etc/dictionary | 2 +
- pppd/plugins/radius/radius.c | 28 ++-
- pppd/plugins/radius/radiusclient.h | 2 +
- pppd/pppd.h | 9 +-
- pppd/sys-linux.c | 281 ++++++++++++++++++++++++++++-
- 6 files changed, 313 insertions(+), 14 deletions(-)
-
---- a/pppd/main.c
-+++ b/pppd/main.c
-@@ -87,6 +87,7 @@
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-+#include <inttypes.h>
-
- #include "pppd.h"
- #include "magic.h"
-@@ -1230,9 +1231,9 @@ update_link_stats(int u)
-
- slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time);
- script_setenv("CONNECT_TIME", numbuf, 0);
-- slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out);
-+ snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_out);
- script_setenv("BYTES_SENT", numbuf, 0);
-- slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in);
-+ snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_in);
- script_setenv("BYTES_RCVD", numbuf, 0);
- }
-
---- a/pppd/plugins/radius/etc/dictionary
-+++ b/pppd/plugins/radius/etc/dictionary
-@@ -82,6 +82,8 @@ ATTRIBUTE Acct-Session-Time 46 integer
- ATTRIBUTE Acct-Input-Packets 47 integer
- ATTRIBUTE Acct-Output-Packets 48 integer
- ATTRIBUTE Acct-Terminate-Cause 49 integer
-+ATTRIBUTE Acct-Input-Gigawords 52 integer
-+ATTRIBUTE Acct-Output-Gigawords 53 integer
- ATTRIBUTE Chap-Challenge 60 string
- ATTRIBUTE NAS-Port-Type 61 integer
- ATTRIBUTE Port-Limit 62 integer
---- a/pppd/plugins/radius/radius.c
-+++ b/pppd/plugins/radius/radius.c
-@@ -1020,12 +1020,22 @@ radius_acct_stop(void)
- av_type = link_connect_time;
- rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
-
-- av_type = link_stats.bytes_out;
-+ av_type = link_stats.bytes_out & 0xFFFFFFFF;
- rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
-
-- av_type = link_stats.bytes_in;
-+ if (link_stats.bytes_out > 0xFFFFFFFF) {
-+ av_type = link_stats.bytes_out >> 32;
-+ rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
-+ }
-+
-+ av_type = link_stats.bytes_in & 0xFFFFFFFF;
- rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
-
-+ if (link_stats.bytes_in > 0xFFFFFFFF) {
-+ av_type = link_stats.bytes_in >> 32;
-+ rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
-+ }
-+
- av_type = link_stats.pkts_out;
- rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
-
-@@ -1172,12 +1182,22 @@ radius_acct_interim(void *ignored)
- av_type = link_connect_time;
- rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
-
-- av_type = link_stats.bytes_out;
-+ av_type = link_stats.bytes_out & 0xFFFFFFFF;
- rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
-
-- av_type = link_stats.bytes_in;
-+ if (link_stats.bytes_out > 0xFFFFFFFF) {
-+ av_type = link_stats.bytes_out >> 32;
-+ rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
-+ }
-+
-+ av_type = link_stats.bytes_in & 0xFFFFFFFF;
- rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
-
-+ if (link_stats.bytes_in > 0xFFFFFFFF) {
-+ av_type = link_stats.bytes_in >> 32;
-+ rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
-+ }
-+
- av_type = link_stats.pkts_out;
- rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
-
---- a/pppd/plugins/radius/radiusclient.h
-+++ b/pppd/plugins/radius/radiusclient.h
-@@ -184,6 +184,8 @@ typedef struct pw_auth_hdr
- #define PW_ACCT_LINK_COUNT 51 /* integer */
-
- /* From RFC 2869 */
-+#define PW_ACCT_INPUT_GIGAWORDS 52 /* integer */
-+#define PW_ACCT_OUTPUT_GIGAWORDS 53 /* integer */
- #define PW_ACCT_INTERIM_INTERVAL 85 /* integer */
-
- /* Merit Experimental Extensions */
---- a/pppd/pppd.h
-+++ b/pppd/pppd.h
-@@ -53,6 +53,7 @@
- #include <stdlib.h> /* for encrypt */
- #include <unistd.h> /* for setkey */
- #include <stdarg.h>
-+#include <stdint.h>
- #include <limits.h> /* for NGROUPS_MAX */
- #include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
- #include <sys/types.h> /* for u_int32_t, if defined */
-@@ -173,8 +174,8 @@ struct permitted_ip {
- * pppd needs.
- */
- struct pppd_stats {
-- unsigned int bytes_in;
-- unsigned int bytes_out;
-+ uint64_t bytes_in;
-+ uint64_t bytes_out;
- unsigned int pkts_in;
- unsigned int pkts_out;
- };
-@@ -347,7 +348,7 @@ extern char *max_tls_version;
- extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */
- extern int maxoctets_dir; /* Direction :
- 0 - in+out (default)
-- 1 - in
-+ 1 - in
- 2 - out
- 3 - max(in,out) */
- extern int maxoctets_timeout; /* Timeout for check of octets limit */
-@@ -356,7 +357,7 @@ extern int maxoctets_timeout; /*
- #define PPP_OCTETS_DIRECTION_OUT 2
- #define PPP_OCTETS_DIRECTION_MAXOVERAL 3
- /* same as previos, but little different on RADIUS side */
--#define PPP_OCTETS_DIRECTION_MAXSESSION 4
-+#define PPP_OCTETS_DIRECTION_MAXSESSION 4
- #endif
-
- #ifdef PPP_FILTER
---- a/pppd/sys-linux.c
-+++ b/pppd/sys-linux.c
-@@ -79,6 +79,7 @@
- #include <sys/sysmacros.h>
-
- #include <errno.h>
-+#include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <syslog.h>
-@@ -92,6 +93,7 @@
- #include <ctype.h>
- #include <termios.h>
- #include <unistd.h>
-+#include <limits.h>
-
- /* This is in netdevice.h. However, this compile will fail miserably if
- you attempt to include netdevice.h because it has so many references
-@@ -121,9 +123,19 @@
- #include <linux/ppp_defs.h>
- #include <linux/if_ppp.h>
-
--#ifdef INET6
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
-+#include <linux/if_link.h>
-+/* Attempt at retaining compile-support with older than 4.7 kernels, or kernels
-+ * where RTM_NEWSTATS isn't defined for whatever reason.
-+ */
-+#ifndef RTM_NEWSTATS
-+#define RTM_NEWSTATS 92
-+#define RTM_GETSTATS 94
-+#define IFLA_STATS_LINK_64 1
-+#endif
-+
-+#ifdef INET6
- #include <linux/if_addr.h>
- /* glibc versions prior to 2.24 do not define SOL_NETLINK */
- #ifndef SOL_NETLINK
-@@ -1407,11 +1419,17 @@ get_idle_time(int u, struct ppp_idle *ip
-
- /********************************************************************
- *
-- * get_ppp_stats - return statistics for the link.
-+ * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
-+ * this only supports 32-bit counters, so need to count the wraps.
- */
--int
--get_ppp_stats(int u, struct pppd_stats *stats)
-+static int
-+get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
- {
-+ static u_int32_t previbytes = 0;
-+ static u_int32_t prevobytes = 0;
-+ static u_int32_t iwraps = 0;
-+ static u_int32_t owraps = 0;
-+
- struct ifpppstatsreq req;
-
- memset (&req, 0, sizeof (req));
-@@ -1426,7 +1444,262 @@ get_ppp_stats(int u, struct pppd_stats *
- stats->bytes_out = req.stats.p.ppp_obytes;
- stats->pkts_in = req.stats.p.ppp_ipackets;
- stats->pkts_out = req.stats.p.ppp_opackets;
-+
-+ if (stats->bytes_in < previbytes)
-+ ++iwraps;
-+ if (stats->bytes_out < prevobytes)
-+ ++owraps;
-+
-+ previbytes = stats->bytes_in;
-+ prevobytes = stats->bytes_out;
-+
-+ stats->bytes_in += (uint64_t)iwraps << 32;
-+ stats->bytes_out += (uint64_t)owraps << 32;
-+
-+ return 1;
-+}
-+
-+/********************************************************************
-+ * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
-+ * This provides native 64-bit counters.
-+ */
-+static int
-+get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
-+{
-+ static int rtnl_fd = -1;
-+
-+ struct sockaddr_nl nladdr;
-+ struct {
-+ struct nlmsghdr nlh;
-+ struct if_stats_msg ifsm;
-+ } nlreq;
-+ struct nlresp {
-+ struct nlmsghdr nlh;
-+ union {
-+ struct {
-+ struct nlmsgerr nlerr;
-+ char __end_err[0];
-+ };
-+ struct {
-+ struct rtmsg rth;
-+ struct {
-+ /* We only case about these first fields from rtnl_link_stats64 */
-+ uint64_t rx_packets;
-+ uint64_t tx_packets;
-+ uint64_t rx_bytes;
-+ uint64_t tx_bytes;
-+ } stats;
-+ char __end_stats[0];
-+ };
-+ };
-+ } nlresp;
-+ ssize_t nlresplen;
-+ struct iovec iov;
-+ struct msghdr msg;
-+
-+ memset(&nladdr, 0, sizeof(nladdr));
-+ nladdr.nl_family = AF_NETLINK;
-+
-+ if (rtnl_fd < 0) {
-+ rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-+ if (rtnl_fd < 0) {
-+ error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
-+ error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
-+ goto err;
-+ }
-+ }
-+
-+ memset(&nlreq, 0, sizeof(nlreq));
-+ nlreq.nlh.nlmsg_len = sizeof(nlreq);
-+ nlreq.nlh.nlmsg_type = RTM_GETSTATS;
-+ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
-+
-+ nlreq.ifsm.ifindex = if_nametoindex(ifname);
-+ nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
-+
-+ memset(&iov, 0, sizeof(iov));
-+ iov.iov_base = &nlreq;
-+ iov.iov_len = sizeof(nlreq);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_name = &nladdr;
-+ msg.msg_namelen = sizeof(nladdr);
-+ msg.msg_iov = &iov;
-+ msg.msg_iovlen = 1;
-+
-+ if (sendmsg(rtnl_fd, &msg, 0) < 0) {
-+ error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
-+ goto err;
-+ }
-+
-+ /* We just need to repoint to IOV ... everything else stays the same */
-+ iov.iov_base = &nlresp;
-+ iov.iov_len = sizeof(nlresp);
-+
-+ nlresplen = recvmsg(rtnl_fd, &msg, 0);
-+
-+ if (nlresplen < 0) {
-+ error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
-+ goto err;
-+ }
-+
-+ if (nlresplen < sizeof(nlresp.nlh)) {
-+ error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__);
-+ goto err;
-+ }
-+
-+ if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) {
-+ if (nlresplen < offsetof(struct nlresp, __end_err)) {
-+ if (kernel_version >= KVERSION(4,7,0))
-+ error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
-+ } else {
-+ error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).",
-+ __LINE__);
-+ }
-+ goto err;
-+ }
-+
-+ if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) {
-+ error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)",
-+ nlresp.nlh.nlmsg_type, __LINE__);
-+ goto err;
-+ }
-+
-+ if (nlresplen < offsetof(struct nlresp, __end_stats)) {
-+ error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
-+ goto err;
-+ }
-+
-+ stats->bytes_in = nlresp.stats.rx_bytes;
-+ stats->bytes_out = nlresp.stats.tx_bytes;
-+ stats->pkts_in = nlresp.stats.rx_packets;
-+ stats->pkts_out = nlresp.stats.tx_packets;
-+
- return 1;
-+err:
-+ close(rtnl_fd);
-+ rtnl_fd = -1;
-+ return 0;
-+}
-+
-+/********************************************************************
-+ * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
-+ * this provides native 64-bit counters.
-+ */
-+static int
-+get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
-+{
-+ char fname[PATH_MAX+1];
-+ char buf[21], *err; /* 2^64 < 10^20 */
-+ int blen, fd, rlen;
-+ unsigned long long val;
-+
-+ struct {
-+ const char* fname;
-+ void* ptr;
-+ unsigned size;
-+ } slist[] = {
-+#define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
-+ statfield(rx_bytes, bytes_in),
-+ statfield(tx_bytes, bytes_out),
-+ statfield(rx_packets, pkts_in),
-+ statfield(tx_packets, pkts_out),
-+#undef statfield
-+ };
-+
-+ blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
-+ if (blen >= sizeof(fname))
-+ return 0; /* ifname max 15, so this should be impossible */
-+
-+ for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
-+ if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
-+ fname[blen] = 0;
-+ error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
-+ return 0;
-+ }
-+
-+ fd = open(fname, O_RDONLY);
-+ if (fd < 0) {
-+ error("%s: %m", fname);
-+ return 0;
-+ }
-+
-+ rlen = read(fd, buf, sizeof(buf) - 1);
-+ close(fd);
-+ if (rlen < 0) {
-+ error("%s: %m", fname);
-+ return 0;
-+ }
-+ /* trim trailing \n if present */
-+ while (rlen > 0 && buf[rlen-1] == '\n')
-+ rlen--;
-+ buf[rlen] = 0;
-+
-+ errno = 0;
-+ val = strtoull(buf, &err, 10);
-+ if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
-+ error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
-+ buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
-+ return 0;
-+ }
-+ switch (slist[i].size) {
-+#define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
-+ stattype(uint64_t);
-+ stattype(uint32_t);
-+ stattype(uint16_t);
-+ stattype(uint8_t);
-+#undef stattype
-+ default:
-+ error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
-+ return 0;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+/********************************************************************
-+ * Periodic timer function to be used to keep stats up to date in case of ioctl
-+ * polling.
-+ *
-+ * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
-+ * If you do change the timer, remember to also bring the get_ppp_stats (which
-+ * sets up the initial trigger) as well.
-+ */
-+static void
-+ppp_stats_poller(void* u)
-+{
-+ struct pppd_stats dummy;
-+ get_ppp_stats_ioctl((long)u, &dummy);
-+ TIMEOUT(ppp_stats_poller, u, 25);
-+}
-+
-+/********************************************************************
-+ * get_ppp_stats - return statistics for the link.
-+ */
-+int get_ppp_stats(int u, struct pppd_stats *stats)
-+{
-+ static int (*func)(int, struct pppd_stats*) = NULL;
-+
-+ if (!func) {
-+ if (get_ppp_stats_rtnetlink(u, stats)) {
-+ func = get_ppp_stats_rtnetlink;
-+ return 1;
-+ }
-+ if (get_ppp_stats_sysfs(u, stats)) {
-+ func = get_ppp_stats_sysfs;
-+ return 1;
-+ }
-+ warn("statistics falling back to ioctl which only supports 32-bit counters");
-+ func = get_ppp_stats_ioctl;
-+ TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
-+ }
-+
-+ return func(u, stats);
- }
-
- /********************************************************************
+++ /dev/null
-From 4a54e34cf5629f9fed61f0b7d69ee3ba4d874bc6 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Sat, 9 Jul 2022 13:40:24 +0200
-Subject: [PATCH] pppd: Add support for registering ppp interface via Linux
- rtnetlink API
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-pppd currently creates ppp network interface via PPPIOCNEWUNIT ioctl API.
-This API creates a new ppp network interface named "ppp<unit_id>". If user
-supply option "ifname" with custom network name then pppd calls SIOCSIFNAME
-ioctl to rename "ppp<unit_id>" to custom name immediately after successful
-PPPIOCNEWUNIT ioctl call. If custom name is already registered then
-SIOCSIFNAME ioctl fails and pppd close current channel (which destroy also
-network interface).
-
-This has side effect that in the first few miliseconds interface has
-different name as what user supplied.
-
-Tools like systemd, udev or NetworkManager are trying to query
-interface attributes based on interface name immediately when new
-network interface is created.
-
-But if interface is renamed immediately after creation then these tools
-fails. For example when running pppd with option "ifname ppp-wan" following
-error is reported by systemd / udev into dmesg log:
-
- [ 35.718732] PPP generic driver version 2.4.2
- [ 35.793914] NET: Registered protocol family 24
- [ 35.889924] systemd-udevd[1852]: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.
- [ 35.901450] ppp-wan: renamed from ppp0
- [ 35.930332] systemd-udevd[1852]: link_config: could not get ethtool features for ppp0
- [ 35.939473] systemd-udevd[1852]: Could not set offload features of ppp0: No such device
-
-There is an easy way to fix this issue: Use new rtnetlink API.
-
-Via rtnetlink API it is possible to create ppp network interface with
-custom ifname atomically. Just it is not possible to specify custom ppp
-unit id.
-
-So use new rtnetlink API when user requested custom ifname without custom
-ppp unit id. This will avoid system issues with interface renaming as ppp
-interface is directly registered with specified final name.
-
-This has also advantage that if requested interface name already exists
-then pppd fail during registering of networking interface and not during
-renaming network interface which happens after successful registration.
-
-If user supply custom ppp unit id then it is required to use old ioctl API
-as currently it is the only API which allows specifying ppp unit id.
-
-When user does not specify custom ifname stay also with old ioctl API.
-There is currently a bug in kernel which cause that when empty interface is
-specified in rtnetlink message for creating ppp interface then kernel
-creates ppp interface but with pseudo-random name, not derived from ppp
-unit id. And therefore it is not possible to retrieve what is the name of
-newly created network interface. So when user does not specify interface
-name via "ifname" option (which means that want from kernel to choose some
-"free" interface name) it is needed to use old ioctl API which do it
-correctly for now.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
----
- pppd/sys-linux.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 192 insertions(+), 2 deletions(-)
-
---- a/pppd/sys-linux.c
-+++ b/pppd/sys-linux.c
-@@ -126,6 +126,11 @@
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
- #include <linux/if_link.h>
-+
-+#ifdef INET6
-+#include <linux/if_addr.h>
-+#endif
-+
- /* Attempt at retaining compile-support with older than 4.7 kernels, or kernels
- * where RTM_NEWSTATS isn't defined for whatever reason.
- */
-@@ -135,16 +140,20 @@
- #define IFLA_STATS_LINK_64 1
- #endif
-
--#ifdef INET6
--#include <linux/if_addr.h>
- /* glibc versions prior to 2.24 do not define SOL_NETLINK */
- #ifndef SOL_NETLINK
- #define SOL_NETLINK 270
- #endif
-+
- /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
- #ifndef NETLINK_CAP_ACK
- #define NETLINK_CAP_ACK 10
- #endif
-+
-+/* linux kernel versions prior to 4.7 do not define/support IFLA_PPP_DEV_FD */
-+#ifndef IFLA_PPP_MAX
-+/* IFLA_PPP_DEV_FD is declared as enum when IFLA_PPP_MAX is defined */
-+#define IFLA_PPP_DEV_FD 1
- #endif
-
- #include "pppd.h"
-@@ -657,6 +666,160 @@ void generic_disestablish_ppp(int dev_fd
- }
-
- /*
-+ * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
-+ * with specified req_ifname via rtnetlink. Interface name req_ifname must not
-+ * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
-+ */
-+static int make_ppp_unit_rtnetlink(void)
-+{
-+ struct {
-+ struct nlmsghdr nlh;
-+ struct ifinfomsg ifm;
-+ struct {
-+ struct rtattr rta;
-+ char ifname[IFNAMSIZ];
-+ } ifn;
-+ struct {
-+ struct rtattr rta;
-+ struct {
-+ struct rtattr rta;
-+ char ifkind[sizeof("ppp")];
-+ } ifik;
-+ struct {
-+ struct rtattr rta;
-+ struct {
-+ struct rtattr rta;
-+ union {
-+ int ppp_dev_fd;
-+ } ppp;
-+ } ifdata[1];
-+ } ifid;
-+ } ifli;
-+ } nlreq;
-+ struct {
-+ struct nlmsghdr nlh;
-+ struct nlmsgerr nlerr;
-+ } nlresp;
-+ struct sockaddr_nl nladdr;
-+ struct iovec iov;
-+ struct msghdr msg;
-+ ssize_t nlresplen;
-+ int one;
-+ int fd;
-+
-+ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-+ if (fd < 0) {
-+ error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ /* Tell kernel to not send to us payload of acknowledgment error message. */
-+ one = 1;
-+ setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
-+
-+ memset(&nladdr, 0, sizeof(nladdr));
-+ nladdr.nl_family = AF_NETLINK;
-+
-+ if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
-+ error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
-+ close(fd);
-+ return 0;
-+ }
-+
-+ memset(&nlreq, 0, sizeof(nlreq));
-+ nlreq.nlh.nlmsg_len = sizeof(nlreq);
-+ nlreq.nlh.nlmsg_type = RTM_NEWLINK;
-+ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
-+ nlreq.ifm.ifi_family = AF_UNSPEC;
-+ nlreq.ifm.ifi_type = ARPHRD_NETROM;
-+ nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
-+ nlreq.ifn.rta.rta_type = IFLA_IFNAME;
-+ strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
-+ nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
-+ nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
-+ nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
-+ nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
-+ strcpy(nlreq.ifli.ifik.ifkind, "ppp");
-+ nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
-+ nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
-+ nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
-+ nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
-+ nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
-+
-+ memset(&nladdr, 0, sizeof(nladdr));
-+ nladdr.nl_family = AF_NETLINK;
-+
-+ memset(&iov, 0, sizeof(iov));
-+ iov.iov_base = &nlreq;
-+ iov.iov_len = sizeof(nlreq);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_name = &nladdr;
-+ msg.msg_namelen = sizeof(nladdr);
-+ msg.msg_iov = &iov;
-+ msg.msg_iovlen = 1;
-+
-+ if (sendmsg(fd, &msg, 0) < 0) {
-+ error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__);
-+ close(fd);
-+ return 0;
-+ }
-+
-+ memset(&iov, 0, sizeof(iov));
-+ iov.iov_base = &nlresp;
-+ iov.iov_len = sizeof(nlresp);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_name = &nladdr;
-+ msg.msg_namelen = sizeof(nladdr);
-+ msg.msg_iov = &iov;
-+ msg.msg_iovlen = 1;
-+
-+ nlresplen = recvmsg(fd, &msg, 0);
-+
-+ if (nlresplen < 0) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
-+ close(fd);
-+ return 0;
-+ }
-+
-+ close(fd);
-+
-+ if (nladdr.nl_family != AF_NETLINK) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
-+ if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ /* error == 0 indicates success, negative value is errno code */
-+ if (nlresp.nlerr.error != 0) {
-+ /*
-+ * Linux kernel versions prior to 4.7 do not support creating ppp
-+ * interfaces via rtnetlink API and therefore error response is
-+ * expected. On older kernel versions do not show this error message.
-+ * When error is different than EEXIST then pppd tries to fallback to
-+ * the old ioctl method.
-+ */
-+ errno = (nlresp.nlerr.error < 0) ? -nlresp.nlerr.error : EINVAL;
-+ if (kernel_version >= KVERSION(4,7,0))
-+ error("Couldn't create ppp interface %s: %m", req_ifname);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+/*
- * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
- * Assumes new_style_driver.
- */
-@@ -676,6 +839,33 @@ static int make_ppp_unit(void)
- || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
- warn("Couldn't set /dev/ppp to nonblock: %m");
-
-+ /*
-+ * Via rtnetlink it is possible to create ppp network interface with
-+ * custom ifname atomically. But it is not possible to specify custom
-+ * ppp unit id.
-+ *
-+ * Tools like systemd, udev or NetworkManager are trying to query
-+ * interface attributes based on interface name immediately when new
-+ * network interface is created. And therefore immediate interface
-+ * renaming is causing issues.
-+ *
-+ * So use rtnetlink API only when user requested custom ifname. It will
-+ * avoid system issues with interface renaming.
-+ */
-+ if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
-+ if (make_ppp_unit_rtnetlink()) {
-+ if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
-+ fatal("Couldn't retrieve PPP unit id: %m");
-+ return 0;
-+ }
-+ /*
-+ * If interface with requested name already exist return error
-+ * otherwise fallback to old ioctl method.
-+ */
-+ if (errno == EEXIST)
-+ return -1;
-+ }
-+
- ifunit = req_unit;
- x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
- if (x < 0 && req_unit >= 0 && errno == EEXIST) {
+++ /dev/null
-From 44609bfc974bdafc0316d069aabf5e2903efa805 Mon Sep 17 00:00:00 2001
-From: pali <7141871+pali@users.noreply.github.com>
-Date: Tue, 9 Aug 2022 11:20:15 +0200
-Subject: [PATCH] pppd: Workaround for generating ppp unit id on Linux (#355)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Linux kernel has nasty bug / feature. If PPPIOCNEWUNIT is called with
-negative ppp unit id (which is default option when command line argument
-"unit" is not specified; and tells kernel to choose some free ppp unit id)
-and the lowest unused/free ppp unit id is present in some existing network
-interface name prefixed by "ppp" string then this PPPIOCNEWUNIT ioctl
-fails. In this case kernel is basically unable to create a new ppp
-interface via PPPIOCNEWUNIT ioctl when user does not specify some unused
-and non-conflicted unit id.
-
-Linux kernel should be fixed to choose usable ppp unit id when was
-requested via PPPIOCNEWUNIT parameter -1.
-
-Until this happens, add a workaround for pppd to help choosing some random
-ppp unit id when kernel returns this error.
-
-Simple test case (run on system when there is no ppp interface):
-
- sudo ./pppd ifname ppp1 nodefaultroute noauth nolock local nodetach pty "./pppd nodefaultroute noauth nolock local nodetach notty"
-
-Second pppd process without this patch prints into syslog following error:
-
- pppd 2.4.10-dev started by pali, uid 0
- Couldn't create new ppp unit: File exists
- Exit.
-
-With this patch it falls back to random ppp unit id and succeeds:
-
- pppd 2.4.10-dev started by pali, uid 0
- Using interface ppp1361
- Connect: ppp1361 <--> /dev/pts/14
- ...
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
----
- pppd/sys-linux.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/pppd/sys-linux.c
-+++ b/pppd/sys-linux.c
-@@ -873,6 +873,11 @@ static int make_ppp_unit(void)
- ifunit = -1;
- x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
- }
-+ if (x < 0 && errno == EEXIST) {
-+ srand(time(NULL) * getpid());
-+ ifunit = rand() % 10000;
-+ x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
-+ }
- if (x < 0)
- error("Couldn't create new ppp unit: %m");
-
+++ /dev/null
-From 089687fbcc6524809ae9f4b2f8145fe3c2a91147 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
-Date: Sat, 7 Aug 2021 19:48:01 +0200
-Subject: [PATCH] pppd: Retry registering interface when on rtnetlink -EBUSY
- error
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Due to workaround in kernel module ppp_generic.ko in function
-ppp_nl_newlink(), kernel may return -EBUSY error to prevent possible
-mutex deadlock. In this case userspace needs to retry its request.
-
-Proper way would be to fix kernel module to order requests and mutex
-locking, so prevent deadlock in kernel and so never return this error to
-userspace. Until it happens we need retry code in userspace.
-
-Signed-off-by: Pali Rohár <pali@kernel.org>
-[ backport to ppp 2.4.9 ]
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- pppd/sys-linux.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
---- a/pppd/sys-linux.c
-+++ b/pppd/sys-linux.c
-@@ -707,99 +707,101 @@ static int make_ppp_unit_rtnetlink(void)
- int one;
- int fd;
-
-- fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-- if (fd < 0) {
-- error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
-- return 0;
-- }
--
-- /* Tell kernel to not send to us payload of acknowledgment error message. */
-- one = 1;
-- setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
-+ do {
-+ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-+ if (fd < 0) {
-+ error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ /* Tell kernel to not send to us payload of acknowledgment error message. */
-+ one = 1;
-+ setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
-+
-+ memset(&nladdr, 0, sizeof(nladdr));
-+ nladdr.nl_family = AF_NETLINK;
-+
-+ if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
-+ error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
-+ close(fd);
-+ return 0;
-+ }
-+
-+ memset(&nlreq, 0, sizeof(nlreq));
-+ nlreq.nlh.nlmsg_len = sizeof(nlreq);
-+ nlreq.nlh.nlmsg_type = RTM_NEWLINK;
-+ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
-+ nlreq.ifm.ifi_family = AF_UNSPEC;
-+ nlreq.ifm.ifi_type = ARPHRD_NETROM;
-+ nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
-+ nlreq.ifn.rta.rta_type = IFLA_IFNAME;
-+ strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
-+ nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
-+ nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
-+ nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
-+ nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
-+ strcpy(nlreq.ifli.ifik.ifkind, "ppp");
-+ nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
-+ nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
-+ nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
-+ nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
-+ nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
-+
-+ memset(&nladdr, 0, sizeof(nladdr));
-+ nladdr.nl_family = AF_NETLINK;
-+
-+ memset(&iov, 0, sizeof(iov));
-+ iov.iov_base = &nlreq;
-+ iov.iov_len = sizeof(nlreq);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_name = &nladdr;
-+ msg.msg_namelen = sizeof(nladdr);
-+ msg.msg_iov = &iov;
-+ msg.msg_iovlen = 1;
-+
-+ if (sendmsg(fd, &msg, 0) < 0) {
-+ error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__);
-+ close(fd);
-+ return 0;
-+ }
-+
-+ memset(&iov, 0, sizeof(iov));
-+ iov.iov_base = &nlresp;
-+ iov.iov_len = sizeof(nlresp);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_name = &nladdr;
-+ msg.msg_namelen = sizeof(nladdr);
-+ msg.msg_iov = &iov;
-+ msg.msg_iovlen = 1;
-+
-+ nlresplen = recvmsg(fd, &msg, 0);
-+
-+ if (nlresplen < 0) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
-+ close(fd);
-+ return 0;
-+ }
-
-- memset(&nladdr, 0, sizeof(nladdr));
-- nladdr.nl_family = AF_NETLINK;
--
-- if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
-- error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
- close(fd);
-- return 0;
-- }
--
-- memset(&nlreq, 0, sizeof(nlreq));
-- nlreq.nlh.nlmsg_len = sizeof(nlreq);
-- nlreq.nlh.nlmsg_type = RTM_NEWLINK;
-- nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
-- nlreq.ifm.ifi_family = AF_UNSPEC;
-- nlreq.ifm.ifi_type = ARPHRD_NETROM;
-- nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
-- nlreq.ifn.rta.rta_type = IFLA_IFNAME;
-- strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
-- nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
-- nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
-- nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
-- nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
-- strcpy(nlreq.ifli.ifik.ifkind, "ppp");
-- nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
-- nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
-- nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
-- nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
-- nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
--
-- memset(&nladdr, 0, sizeof(nladdr));
-- nladdr.nl_family = AF_NETLINK;
--
-- memset(&iov, 0, sizeof(iov));
-- iov.iov_base = &nlreq;
-- iov.iov_len = sizeof(nlreq);
--
-- memset(&msg, 0, sizeof(msg));
-- msg.msg_name = &nladdr;
-- msg.msg_namelen = sizeof(nladdr);
-- msg.msg_iov = &iov;
-- msg.msg_iovlen = 1;
--
-- if (sendmsg(fd, &msg, 0) < 0) {
-- error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__);
-- close(fd);
-- return 0;
-- }
--
-- memset(&iov, 0, sizeof(iov));
-- iov.iov_base = &nlresp;
-- iov.iov_len = sizeof(nlresp);
--
-- memset(&msg, 0, sizeof(msg));
-- msg.msg_name = &nladdr;
-- msg.msg_namelen = sizeof(nladdr);
-- msg.msg_iov = &iov;
-- msg.msg_iovlen = 1;
--
-- nlresplen = recvmsg(fd, &msg, 0);
--
-- if (nlresplen < 0) {
-- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
-- close(fd);
-- return 0;
-- }
--
-- close(fd);
-
-- if (nladdr.nl_family != AF_NETLINK) {
-- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
-- return 0;
-- }
--
-- if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
-- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
-- return 0;
-- }
--
-- /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
-- if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
-- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
-- return 0;
-- }
-+ if (nladdr.nl_family != AF_NETLINK) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
-+ return 0;
-+ }
-+
-+ /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
-+ if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
-+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
-+ return 0;
-+ }
-+ } while (nlresp.nlerr.error == -EBUSY);
-
- /* error == 0 indicates success, negative value is errno code */
- if (nlresp.nlerr.error != 0) {
+++ /dev/null
-pppd: tune Linux config defaults for OpenWrt
-
-This patch adjusts a number defaults to properly match the OpenWrt environment.
-It is not intended for upstream.
-
-Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-
---- a/pppd/Makefile.linux
-+++ b/pppd/Makefile.linux
-@@ -49,7 +49,7 @@ MPPE=y
- # 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
-@@ -59,7 +59,7 @@ 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
-
- # Uncomment the next line to enable Type=notify services in systemd
- # If enabled, and the user sets the up_sdnotify option, then
-@@ -85,13 +85,13 @@ USE_LIBUTIL=y
- endif
-
- # Enable EAP-TLS authentication (requires MPPE support, libssl and libcrypto)
--USE_EAPTLS=y
-+#USE_EAPTLS=y
-
- MAXOCTETS=y
-
- INCLUDE_DIRS= -I../include
-
--COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP -pipe
-+COMPILE_FLAGS= -DHAVE_PATHS_H -DHAVE_MMAP -pipe
-
- CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) '-DDESTDIR="@DESTDIR@"'
-
-@@ -143,10 +143,10 @@ CFLAGS += -DHAS_SHADOW
- #LIBS += -lshadow $(LIBS)
- endif
-
--ifeq ($(shell echo '\#include <crypt.h>' | $(CC) -E - >/dev/null 2>&1 && echo yes),yes)
-+#ifeq ($(shell echo '\#include <crypt.h>' | $(CC) -E - >/dev/null 2>&1 && echo yes),yes)
- CFLAGS += -DHAVE_CRYPT_H=1
- LIBS += -lcrypt
--endif
-+#endif
-
- ifdef USE_LIBUTIL
- CFLAGS += -DHAVE_LOGWTMP=1
+++ /dev/null
-pppd: add support for MPPE and MPPC encryption and compression protocols
-
-This is a forward ported version of ppp-2.4.3-mppe-mppc-1.1.patch.gz found on
-http://mppe-mppc.alphacron.de/ .
-
-Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-
---- a/include/linux/ppp-comp.h
-+++ b/include/linux/ppp-comp.h
-@@ -36,7 +36,7 @@
- */
-
- /*
-- * ==FILEVERSION 20020319==
-+ * ==FILEVERSION 20020715==
- *
- * NOTE TO MAINTAINERS:
- * If you modify this file at all, please set the above date.
-@@ -201,6 +201,33 @@ struct compressor {
- #define CI_MPPE 18 /* config option for MPPE */
- #define CILEN_MPPE 6 /* length of config option */
-
-+/* 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.
- */
---- a/include/net/ppp-comp.h
-+++ b/include/net/ppp-comp.h
-@@ -168,6 +168,33 @@ struct compressor {
- #define CI_MPPE 18 /* config option for MPPE */
- #define CILEN_MPPE 6 /* length of config option */
-
-+/* 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.
- */
---- a/pppd/ccp.c
-+++ b/pppd/ccp.c
-@@ -61,12 +61,10 @@ static int setdeflate (char **);
- 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,
-@@ -107,54 +105,36 @@ static option_t ccp_option_list[] = {
- "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 }
-@@ -240,7 +220,7 @@ static fsm_callbacks ccp_callbacks = {
- */
- #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).
-@@ -341,6 +321,100 @@ setdeflate(char **argv)
- 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.
- */
-@@ -374,6 +448,30 @@ ccp_init(int unit)
- 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 */
- }
-
- /*
-@@ -443,11 +541,11 @@ ccp_input(int unit, u_char *p, int len)
- 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 */
- }
-
- /*
-@@ -471,6 +569,15 @@ ccp_extcode(fsm *f, int code, int id, u_
- 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;
-
-@@ -498,12 +605,11 @@ ccp_protrej(int unit)
- 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 */
- }
-
- /*
-@@ -519,7 +625,7 @@ ccp_resetci(fsm *f)
- 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];
- #ifdef USE_EAPTLS
-@@ -536,95 +642,124 @@ ccp_resetci(fsm *f)
- * NB: If MPPE is required, all other compression opts are invalid.
- * So, we return right away if we can't do it.
- */
--
-- /* 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 (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;
-+ }
-
- #ifdef USE_EAPTLS
-- /*
-- * MPPE is also possible in combination with EAP-TLS.
-- * It is not possible to detect if we're doing EAP or EAP-TLS
-- * at this stage, hence we accept all forms of EAP. If TLS is
-- * not used then the MPPE keys will not be derived anyway.
-- */
-- /* Leave only the eap auth bits set */
-- auth_eap_bits &= (EAP_WITHPEER | EAP_PEER );
-+ /*
-+ * MPPE is also possible in combination with EAP-TLS.
-+ * It is not possible to detect if we're doing EAP or EAP-TLS
-+ * at this stage, hence we accept all forms of EAP. If TLS is
-+ * not used then the MPPE keys will not be derived anyway.
-+ */
-+ /* Leave only the eap auth bits set */
-+ auth_eap_bits &= (EAP_WITHPEER | EAP_PEER );
-
-- if ((numbits == 0) && (auth_eap_bits == 0)) {
-- error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed.");
-+ if ((numbits == 0) && (auth_eap_bits == 0)) {
-+ error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed.");
- #else
-- if (!numbits) {
-- error("MPPE required, but MS-CHAP[v2] auth not performed.");
-+ if (!numbits) {
-+ error("MPPE required, but MS-CHAP[v2] auth not performed.");
- #endif
-- lcp_close(f->unit, "MPPE required but not available");
-- return;
-- }
-+ 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 @@ static int
- + (go->deflate && go->deflate_draft? 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);
- }
-
- /*
-@@ -690,6 +826,8 @@ static void
- {
- 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;
-
- /*
-@@ -698,22 +836,43 @@ static void
- * 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;
-@@ -799,30 +958,50 @@ static void
-
- /*
- * 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(fsm *f, u_char *p, 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,6 +1070,8 @@ static int
- ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
- {
- 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 */
-
-@@ -898,28 +1079,100 @@ static int
- 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) {
-@@ -989,14 +1242,50 @@ ccp_rejci(fsm *f, u_char *p, int len)
- 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)
-@@ -1056,14 +1345,15 @@ static int
- ccp_reqci(fsm *f, u_char *p, int *lenp, 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;
-@@ -1086,106 +1376,302 @@ ccp_reqci(fsm *f, u_char *p, int *lenp,
- 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) {
-+ 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_UNSUPPORTED;
-- }
-- if (ho->mppe & MPPE_OPT_UNKNOWN) {
-- newret = CONFNAK;
-- ho->mppe &= ~MPPE_OPT_UNKNOWN;
-- }
--
-- /* 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");
-- newret = CONFREJ;
-- break;
-+ 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;
-+ }
-+
-+ 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;
-+ if (wo->mppe || ao->mppe) {
-+ p[5] &= ~MPPE_MPPC;
-+ newret = CONFNAK;
-+ }
- }
- }
--
-- /* 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. */
-- 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;
-- }
-- } else if (ho->mppe & MPPE_OPT_128) {
-- if (!(ao->mppe & MPPE_OPT_128)) {
-- newret = CONFREJ;
-- break;
-- }
-- } else if (ho->mppe & MPPE_OPT_40) {
-- if (!(ao->mppe & MPPE_OPT_40)) {
-- newret = CONFREJ;
-- break;
-- }
-+ 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;
-+ }
-+ }
-+
-+ if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT|MPPE_128BIT)) {
-+ newret = CONFNAK;
-+ 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;
-+ }
-+ 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;
-+ }
-+ 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. */
-- /* We cannot accept this. */
-- newret = CONFNAK;
-- /* Give the peer our idea of what can be used,
-- so it can choose and confirm */
-- ho->mppe = ao->mppe;
-- }
--
-- /* 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;
-- }
--
-- /*
-- * We have accepted MPPE or are willing to negotiate
-- * MPPE parameters. A CONFREJ is due to subsequent
-- * (non-MPPE) processing.
-- */
-- rej_for_ci_mppe = 0;
-- break;
--#endif /* MPPE */
-+ /* 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;
-+ }
-+
-+ /*
-+ * 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 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;
-+ 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
-@@ -1327,12 +1813,6 @@ ccp_reqci(fsm *f, u_char *p, int *lenp,
- 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;
- }
-
-@@ -1353,24 +1833,35 @@ method_name(ccp_options *opt, ccp_option
- 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)
-@@ -1425,12 +1916,12 @@ ccp_up(fsm *f)
- } 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 */
- }
-
- /*
-@@ -1452,7 +1943,7 @@ ccp_down(fsm *f)
- lcp_close(f->unit, "MPPE disabled");
- }
- }
--#endif
-+#endif /* MPPE */
- }
-
- /*
-@@ -1509,24 +2000,28 @@ ccp_printpkt(u_char *p, int plen,
- #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) {
-@@ -1609,6 +2104,7 @@ ccp_datainput(int unit, u_char *pkt, int
- 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.
- */
-@@ -1616,9 +2112,18 @@ ccp_datainput(int unit, u_char *pkt, int
- 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.
---- a/pppd/ccp.h
-+++ b/pppd/ccp.h
-@@ -37,9 +37,17 @@ typedef struct ccp_options {
- 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? */
- u_char mppe; /* MPPE bitfield */
-+ 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;
-
---- a/pppd/chap_ms.c
-+++ b/pppd/chap_ms.c
-@@ -964,13 +964,17 @@ set_mppe_enc_types(int policy, int types
- /*
- * 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;
+++ /dev/null
-build: Move optimization flags into a separate variable
-
-Isolate optimization related compiler flags from CFLAGS and move them into a
-separate COPTS variable so that it is easier to override optimizations from
-the environment.
-
-Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-
---- a/pppd/plugins/radius/Makefile.linux
-+++ b/pppd/plugins/radius/Makefile.linux
-@@ -47,13 +47,13 @@ install: all
- $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
-
- radius.so: radius.o libradiusclient.a
-- $(CC) $(LDFLAGS) -o radius.so -shared radius.o libradiusclient.a
-+ $(CC) $(LDFLAGS) -fPIC -o radius.so -shared radius.o libradiusclient.a
-
- radattr.so: radattr.o
-- $(CC) $(LDFLAGS) -o radattr.so -shared radattr.o
-+ $(CC) $(LDFLAGS) -fPIC -o radattr.so -shared radattr.o
-
- radrealms.so: radrealms.o
-- $(CC) $(LDFLAGS) -o radrealms.so -shared radrealms.o
-+ $(CC) $(LDFLAGS) -fPIC -o radrealms.so -shared radrealms.o
-
- CLIENTOBJS = avpair.o buildreq.o config.o dict.o ip_util.o \
- clientid.o sendserver.o lock.o util.o md5.o
---- a/pppd/plugins/pppoe/Makefile.linux
-+++ b/pppd/plugins/pppoe/Makefile.linux
-@@ -38,7 +38,7 @@ debug.o: debug.c
- $(CC) $(CFLAGS) -I../../.. -c -o debug.o debug.c
-
- pppoe.so: plugin.o discovery.o if.o common.o
-- $(CC) $(LDFLAGS) -o pppoe.so -shared plugin.o discovery.o if.o common.o
-+ $(CC) $(LDFLAGS) -fPIC -o pppoe.so -shared plugin.o discovery.o if.o common.o
-
- install: all
- $(INSTALL) -d -m 755 $(LIBDIR)
--- a/pppd/plugins/radius/config.c
+++ b/pppd/plugins/radius/config.c
-@@ -371,31 +371,37 @@ static int test_config(char *filename)
+@@ -377,31 +377,37 @@ static int test_config(char *filename)
}
#endif
--- a/pppd/plugins/pppoe/discovery.c
+++ b/pppd/plugins/pppoe/discovery.c
-@@ -632,7 +632,9 @@ discovery(PPPoEConnection *conn)
+@@ -685,7 +685,9 @@ discovery1(PPPoEConnection *conn)
conn->discoveryState = STATE_SENT_PADI;
waitForPADO(conn, timeout);
timeout *= 2;
+#endif
} while (conn->discoveryState == STATE_SENT_PADI);
+ }
- timeout = conn->discoveryTimeout;
-@@ -647,7 +649,9 @@ discovery(PPPoEConnection *conn)
+@@ -715,7 +717,9 @@ discovery2(PPPoEConnection *conn)
sendPADR(conn);
conn->discoveryState = STATE_SENT_PADR;
waitForPADS(conn, timeout);
--- a/pppd/lcp.c
+++ b/pppd/lcp.c
-@@ -1862,12 +1862,12 @@ lcp_up(fsm *f)
+@@ -1868,12 +1868,12 @@ lcp_up(fsm *f)
* 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
+ #ifdef PPP_WITH_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));
+ #endif /* PPP_WITH_MULTILINK */
+- ppp_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
++ ppp_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);
--- a/pppd/main.c
+++ b/pppd/main.c
-@@ -1035,7 +1035,8 @@ get_input(void)
+@@ -1116,7 +1116,8 @@ get_input(void)
}
notice("Modem hangup");
hungup = 1;
-- status = EXIT_HANGUP;
-+ if (status == EXIT_OK)
-+ status = EXIT_HANGUP;
+- code = EXIT_HANGUP;
++ if (code == EXIT_OK)
++ code = EXIT_HANGUP;
lcp_lowerdown(0); /* serial link is no longer available */
link_terminated(0);
return;
+++ /dev/null
-build: Add required CFLAGS for libpcap
-
-This patch adds some flags to required to properly link libpcap within the
-OpenWrt environment.
-
-Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-
---- a/pppd/Makefile.linux
-+++ b/pppd/Makefile.linux
-@@ -210,8 +210,8 @@ LIBS += -ldl
- endif
-
- ifdef FILTER
--LIBS += -lpcap
--CFLAGS += -DPPP_FILTER
-+LIBS += -lpcap -L$(STAGING_DIR)/usr/lib
-+CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)/usr/include
- endif
-
- ifdef HAVE_INET6
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
---- a/pppd/Makefile.linux
-+++ b/pppd/Makefile.linux
-@@ -51,6 +51,9 @@ MPPE=y
- # and that the kernel driver support PPP packet filtering.
- #FILTER=y
+--- a/configure.ac
++++ b/configure.ac
+@@ -296,6 +296,9 @@ AM_CONDITIONAL(PPP_WITH_PAM, test "x${wi
+ # With libpcap support, activate pppd on network activity
+ AX_CHECK_PCAP
-+# Support for precompiled filters
-+PRECOMPILED_FILTER=y
++# internal statically linked pcap
++AM_CONDITIONAL(PPP_WITH_PRECOMPILED_FILTER, test "x${with_static_pcap}" = "xyes")
+
- # Uncomment the next line to enable multilink PPP (enabled by default)
- # Linux distributions: Please leave multilink ENABLED in your builds
- # of pppd!
-@@ -214,6 +217,14 @@ LIBS += -lpcap -L$(STAGING_DIR)/usr/l
- CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)/usr/include
+ #
+ # SunOS provides a version of libpcap that would work, but SunOS has no support for activity filter
+ AM_CONDITIONAL([PPP_WITH_FILTER], [ test "x${with_pcap}" = "xyes" && test "x${build_sunos}" != "xyes" ])
+@@ -417,6 +420,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION
+ With libatm..........: ${with_atm:-no}
+ With libpam..........: ${with_pam:-no}
+ With libpcap.........: ${with_pcap:-no}
++ With static libpcap..: ${with_static_pcap:-no}
+ With libsrp..........: ${with_srp:-no}
+ C Compiler...........: $CC $CFLAGS
+ Linker...............: $LD $LDFLAGS $LIBS
+--- a/pppd/Makefile.am
++++ b/pppd/Makefile.am
+@@ -128,6 +128,12 @@ pppd_LDFLAGS += $(PCAP_LDFLAGS)
+ pppd_LIBS += $(PCAP_LIBS)
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
++if PPP_WITH_PRECOMPILED_FILTER
++pppd_SOURCES += pcap_pcc.c
++pppd_include_HEADERS += pcap_pcc.h
++pppd_LIBS += $(STAGING_DIR)/usr/lib/libpcap.a
+endif
+
- ifdef HAVE_INET6
- PPPDSRCS += ipv6cp.c eui64.c
- HEADERS += ipv6cp.h eui64.h
+ if PPP_WITH_PLUGINS
+ pppd_CPPFLAGS += -DPPPD_PLUGIN_DIR='"@PPPD_PLUGIN_DIR@"'
+ pppd_LIBS += -ldl
--- a/pppd/options.c
+++ b/pppd/options.c
-@@ -56,6 +56,7 @@
+@@ -62,6 +62,7 @@
- #ifdef PPP_FILTER
+ #ifdef PPP_WITH_FILTER
#include <pcap.h>
+#include <pcap-bpf.h>
/*
* There have been 3 or 4 different names for this in libpcap CVS, but
* this seems to be what they have settled on...
-@@ -168,6 +169,13 @@ static int setlogfile(char **);
+@@ -178,6 +179,13 @@ static int setlogfile(char **);
static int loadplugin(char **);
#endif
-+#ifdef PPP_PRECOMPILED_FILTER
++#ifdef PPP_WITH_PRECOMPILED_FILTER
+#include "pcap_pcc.h"
+static int setprecompiledpassfilter(char **);
+static int setprecompiledactivefilter(char **);
-+#undef PPP_FILTER
++#undef PPP_WITH_FILTER
+#endif
+
- #ifdef PPP_FILTER
+ #ifdef PPP_WITH_FILTER
static int setpassfilter(char **);
static int setactivefilter(char **);
-@@ -360,6 +368,14 @@ option_t general_options[] = {
+@@ -374,6 +382,14 @@ struct option general_options[] = {
"set filter for active pkts", OPT_PRIO },
#endif
-+#ifdef PPP_PRECOMPILED_FILTER
++#ifdef PPP_WITH_PRECOMPILED_FILTER
+ { "precompiled-pass-filter", 1, setprecompiledpassfilter,
+ "set precompiled filter for packets to pass", OPT_PRIO },
+
+ "set precompiled filter for active pkts", OPT_PRIO },
+#endif
+
- #ifdef MAXOCTETS
{ "maxoctets", o_int, &maxoctets,
"Set connection traffic limit",
-@@ -1468,6 +1484,27 @@ callfile(char **argv)
+ OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF },
+@@ -1648,6 +1664,27 @@ callfile(char **argv)
return ok;
}
-+#ifdef PPP_PRECOMPILED_FILTER
++#ifdef PPP_WITH_PRECOMPILED_FILTER
+/*
+ * setprecompiledpassfilter - Set the pass filter for packets using a
+ * precompiled expression
+}
+#endif
+
- #ifdef PPP_FILTER
+ #ifdef PPP_WITH_FILTER
/*
* setpassfilter - Set the pass filter for packets
--- /dev/null
+++ b/pppd/pcap_pcc.c
-@@ -0,0 +1,74 @@
+@@ -0,0 +1,75 @@
+#include <pcap.h>
+#include <pcap-bpf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
++#include "options.h"
+#include "pppd.h"
+
+int pcap_pre_compiled (char * fname, struct bpf_program *p)
+ FILE *f = fopen (fname, "r");
+ if (!f)
+ {
-+ option_error("error opening precompiled active-filter '%s': %s",
++ ppp_option_error("error opening precompiled active-filter '%s': %s",
+ fname, strerror (errno));
+ return 0;
+ }
+ }
+ if (size != index)
+ {
-+ option_error("error in precompiled active-filter,"
-+ " expected %d expressions, got %dn",
-+ size, index);
++ ppp_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);
++ ppp_option_error("error in precompiled active-filter"
++ " expression line %s:%d (wrong size)\n",
++ fname, line);
+ fclose (f);
+ return 0;
+}
2 files changed, 53 insertions(+), 14 deletions(-)
--- a/pppd/multilink.c
+++ b/pppd/multilink.c
-@@ -35,6 +35,7 @@
+@@ -40,6 +40,7 @@
#include <signal.h>
#include <netinet/in.h>
#include <unistd.h>
+#include <net/if.h>
- #include "pppd.h"
+ #include "pppd-private.h"
#include "fsm.h"
-@@ -56,7 +57,8 @@ static void iterate_bundle_links(void (*
+@@ -62,7 +63,8 @@ static void iterate_bundle_links(void (*
static int get_default_epdisc(struct epdisc *);
static int parse_num(char *str, const char *key, int *valp);
#define set_ip_epdisc(ep, addr) do { \
ep->length = 4; \
-@@ -197,35 +199,38 @@ mp_join_bundle(void)
+@@ -215,35 +217,38 @@ mp_join_bundle(void)
key.dptr = bundle_id;
key.dsize = p - bundle_id;
pid = tdb_fetch(pppdb, key);
- if (bundle_attach(unit)) {
+ if (unit >= 0 && bundle_attach(unit)) {
set_ifunit(0);
- script_setenv("BUNDLE", bundle_id + 7, 0);
+ ppp_script_setenv("BUNDLE", bundle_id + 7, 0);
make_bundle_links(1);
unlock_db();
- info("Link attached to %s", ifname);
}
/* we have to make a new bundle */
-@@ -405,20 +410,39 @@ parse_num(char *str, const char *key, in
+@@ -423,20 +428,39 @@ parse_num(char *str, const char *key, in
return 0;
}
&& memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
-@@ -923,6 +923,16 @@ void cfg_bundle(int mrru, int mtru, int
+@@ -994,6 +994,16 @@ void cfg_bundle(int mrru, int mtru, int
add_fd(ppp_dev_fd);
}
+#ifdef USE_TDB
+ char tmp[11];
+ slprintf(tmp, sizeof(tmp), "%d", ifunit);
-+ script_setenv("IFUNIT", tmp, 0);
++ ppp_script_setenv("IFUNIT", tmp, 0);
+#endif
+}
+
/*
* make_new_bundle - create a new PPP unit (i.e. a bundle)
* and connect our channel to it. This should only get called
-@@ -941,6 +951,8 @@ void make_new_bundle(int mrru, int mtru,
+@@ -1012,6 +1022,8 @@ void make_new_bundle(int mrru, int mtru,
/* set the mrru and flags */
cfg_bundle(mrru, mtru, rssn, tssn);
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
-@@ -2248,6 +2248,7 @@ int cifdefaultroute (int unit, u_int32_t
+@@ -2293,6 +2293,7 @@ int cifdefaultroute (int unit, u_int32_t
SIN_ADDR(rt.rt_genmask) = 0L;
}
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
-@@ -2198,6 +2198,9 @@ int sifdefaultroute (int unit, u_int32_t
+@@ -2243,6 +2243,9 @@ int sifdefaultroute (int unit, u_int32_t
memset (&rt, 0, sizeof (rt));
SET_SA_FAMILY (rt.rt_dst, AF_INET);
rt.rt_dev = ifname;
rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
-@@ -2206,7 +2209,7 @@ int sifdefaultroute (int unit, u_int32_t
+@@ -2251,7 +2254,7 @@ int sifdefaultroute (int unit, u_int32_t
SIN_ADDR(rt.rt_genmask) = 0L;
}
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
-@@ -235,7 +235,7 @@ static int driver_is_old = 0;
+@@ -241,7 +241,7 @@ static int driver_is_old = 0;
static int restore_term = 0; /* 1 => we've munged the terminal */
static struct termios inittermios; /* Initial TTY termios */
static char loop_name[20];
static unsigned char inbuf[512]; /* buffer for chars read from loopback */
-@@ -254,8 +254,8 @@ static int looped; /* 1 if using loop
+@@ -260,8 +260,8 @@ static int looped; /* 1 if using loop
static int link_mtu; /* mtu for the link (not bundle) */
static struct utsname utsname; /* for the kernel version */
#define MAX_IFS 100
-@@ -1933,11 +1933,12 @@ int ccp_fatal_error (int unit)
+@@ -1978,11 +1978,12 @@ int ccp_fatal_error (int unit)
*
* path_to_procfs - find the path to the proc file system mount point
*/
struct mntent *mntent;
FILE *fp;
-@@ -1959,6 +1960,7 @@ static char *path_to_procfs(const char *
+@@ -2004,6 +2005,7 @@ static char *path_to_procfs(const char *
fclose (fp);
}
}
strlcpy(proc_path + proc_path_len, tail,
sizeof(proc_path) - proc_path_len);
-@@ -2843,15 +2845,19 @@ int ppp_available(void)
+@@ -2888,15 +2890,19 @@ int ppp_check_kernel_support(void)
int my_version, my_modification, my_patch;
int osmaj, osmin, ospatch;
/* XXX should get from driver */
driver_version = 2;
-@@ -2911,6 +2917,7 @@ int ppp_available(void)
+@@ -2956,6 +2962,7 @@ int ppp_check_kernel_support(void)
if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
ok = 0;
/*
* This is the PPP device. Validate the version of the driver at this
-@@ -3592,6 +3599,7 @@ get_pty(int *master_fdp, int *slave_fdp,
+@@ -3570,6 +3577,7 @@ get_pty(int *master_fdp, int *slave_fdp,
}
#endif /* TIOCGPTN */
if (sfd < 0) {
/* the old way - scan through the pty name space */
for (i = 0; i < 64; ++i) {
-@@ -3610,6 +3618,7 @@ get_pty(int *master_fdp, int *slave_fdp,
+@@ -3594,6 +3602,7 @@ get_pty(int *master_fdp, int *slave_fdp,
}
}
}
return 0;
--- a/pppd/plugins/pppoatm/pppoatm.c
+++ b/pppd/plugins/pppoatm/pppoatm.c
-@@ -171,14 +171,6 @@ static void disconnect_pppoatm(void)
+@@ -179,14 +179,6 @@ static void disconnect_pppoatm(void)
void plugin_init(void)
{
-#ifdef linux
- extern int new_style_driver; /* From sys-linux.c */
-- if (!ppp_available() && !new_style_driver)
+- if (!ppp_check_kernel_support() && !new_style_driver)
- fatal("Kernel doesn't support ppp_generic - "
- "needed for PPPoATM");
-#else
- fatal("No PPPoATM support on this OS");
-#endif
- add_options(pppoa_options);
+ ppp_add_options(pppoa_options);
}
--- a/pppd/plugins/pppoe/plugin.c
+++ b/pppd/plugins/pppoe/plugin.c
-@@ -58,9 +58,6 @@ static char const RCSID[] =
+@@ -57,9 +57,6 @@ static char const RCSID[] =
- char pppd_version[] = VERSION;
+ char pppd_version[] = PPPD_VERSION;
-/* From sys-linux.c in pppd -- MUST FIX THIS! */
-extern int new_style_driver;
char *pppd_pppoe_service = NULL;
static char *acName = NULL;
static char *existingSession = NULL;
-@@ -407,10 +404,6 @@ PPPoEDevnameHook(char *cmd, char **argv,
+@@ -416,10 +413,6 @@ PPPoEDevnameHook(char *cmd, char **argv,
void
plugin_init(void)
{
-- if (!ppp_available() && !new_style_driver) {
+- if (!ppp_check_kernel_support() && !new_style_driver) {
- fatal("Linux kernel does not support PPPoE -- are you running 2.4.x?");
- }
-
- add_options(Options);
+ ppp_add_options(Options);
- info("PPPoE plugin from pppd %s", VERSION);
+ info("PPPoE plugin from pppd %s", PPPD_VERSION);
--- a/pppd/plugins/pppol2tp/pppol2tp.c
+++ b/pppd/plugins/pppol2tp/pppol2tp.c
-@@ -490,12 +490,7 @@ static void pppol2tp_cleanup(void)
+@@ -500,12 +500,7 @@ static void pppol2tp_cleanup(void)
void plugin_init(void)
{
-#if defined(__linux__)
- extern int new_style_driver; /* From sys-linux.c */
-- if (!ppp_available() && !new_style_driver)
+- if (!ppp_check_kernel_support() && !new_style_driver)
- fatal("Kernel doesn't support ppp_generic - "
- "needed for PPPoL2TP");
-#else
+#if !defined(__linux__)
fatal("No PPPoL2TP support on this OS");
#endif
- add_options(pppol2tp_options);
+ ppp_add_options(pppol2tp_options);
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
---- a/pppd/pppd.h
-+++ b/pppd/pppd.h
-@@ -318,7 +318,6 @@ extern int holdoff; /* Dead time before
+--- a/pppd/pppd-private.h
++++ b/pppd/pppd-private.h
+@@ -185,7 +185,6 @@ extern int holdoff; /* Dead time before
extern bool holdoff_specified; /* true if user gave a holdoff value */
extern bool notty; /* Stdin/out is not a tty */
extern char *pty_socket; /* Socket to connect to pty */
-extern char *record_file; /* File to record chars sent/received */
- extern bool sync_serial; /* Device is synchronous serial device */
extern int maxfail; /* Max # of unsuccessful connection attempts */
- extern char linkname[MAXPATHLEN]; /* logical name for link */
+ extern char linkname[]; /* logical name for link */
+ extern bool tune_kernel; /* May alter kernel settings as necessary */
--- a/pppd/tty.c
+++ b/pppd/tty.c
-@@ -143,7 +143,7 @@ char *disconnect_script = NULL; /* Scrip
+@@ -150,7 +150,7 @@ char *disconnect_script = NULL; /* Scrip
char *welcomer = NULL; /* Script to run after phys link estab. */
char *ptycommand = NULL; /* Command to run on other side of pty */
bool notty = 0; /* Stdin/out is not a tty */
int max_data_rate; /* max bytes/sec through charshunt */
bool sync_serial = 0; /* Device is synchronous serial device */
char *pty_socket = NULL; /* Socket to connect to pty */
-@@ -199,8 +199,10 @@ option_t tty_options[] = {
+@@ -206,8 +206,10 @@ static struct option tty_options[] = {
"Send and receive over socket, arg is host:port",
OPT_PRIO | OPT_DEVNAM },
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
-@@ -2981,6 +2981,7 @@ int ppp_available(void)
+@@ -3026,6 +3026,7 @@ int ppp_check_kernel_support(void)
void logwtmp (const char *line, const char *name, const char *host)
{
struct utmp ut, *utp;
pid_t mypid = getpid();
#if __GLIBC__ < 2
-@@ -3046,6 +3047,7 @@ void logwtmp (const char *line, const ch
+@@ -3091,6 +3092,7 @@ void logwtmp (const char *line, const ch
close (wtmp);
}
#endif
--- a/pppd/main.c
+++ b/pppd/main.c
-@@ -867,14 +867,17 @@ struct protocol_list {
+@@ -948,14 +948,17 @@ struct protocol_list {
const char *name;
} protocol_list[] = {
{ 0x21, "IP" },
{ 0x33, "Stream Protocol ST-II" },
{ 0x35, "Banyan Vines" },
{ 0x39, "AppleTalk EDDP" },
-@@ -888,8 +891,11 @@ struct protocol_list {
+@@ -969,8 +972,11 @@ struct protocol_list {
{ 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
{ 0x4b, "SNA over 802.2" },
{ 0x4d, "SNA" },
{ 0x53, "Encryption" },
{ 0x55, "Individual Link Encryption" },
{ 0x57, "IPv6" },
-@@ -900,12 +906,15 @@ struct protocol_list {
+@@ -981,12 +987,15 @@ struct protocol_list {
{ 0x65, "RTP IPHC Compressed non-TCP" },
{ 0x67, "RTP IPHC Compressed UDP 8" },
{ 0x69, "RTP IPHC Compressed RTP 8" },
{ 0x0203, "IBM Source Routing BPDU" },
{ 0x0205, "DEC LANBridge100 Spanning Tree" },
{ 0x0207, "Cisco Discovery Protocol" },
-@@ -917,15 +926,19 @@ struct protocol_list {
+@@ -998,15 +1007,19 @@ struct protocol_list {
{ 0x0231, "Luxcom" },
{ 0x0233, "Sigma Network Systems" },
{ 0x0235, "Apple Client Server Protocol" },
{ 0x4001, "Cray Communications Control Protocol" },
{ 0x4003, "CDPD Mobile Network Registration Protocol" },
{ 0x4005, "Expand accelerator protocol" },
-@@ -936,8 +949,10 @@ struct protocol_list {
+@@ -1017,8 +1030,10 @@ struct protocol_list {
{ 0x4023, "RefTek Protocol" },
{ 0x4025, "Fibre Channel" },
{ 0x4027, "EMIT Protocols" },
{ 0x8023, "OSI Network Layer Control Protocol" },
{ 0x8025, "Xerox NS IDP Control Protocol" },
{ 0x8027, "DECnet Phase IV Control Protocol" },
-@@ -946,7 +961,9 @@ struct protocol_list {
+@@ -1027,7 +1042,9 @@ struct protocol_list {
{ 0x8031, "Bridging NCP" },
{ 0x8033, "Stream Protocol Control Protocol" },
{ 0x8035, "Banyan Vines Control Protocol" },
{ 0x803f, "NETBIOS Framing Control Protocol" },
{ 0x8041, "Cisco Systems Control Protocol" },
{ 0x8043, "Ascom Timeplex" },
-@@ -955,18 +972,24 @@ struct protocol_list {
+@@ -1036,18 +1053,24 @@ struct protocol_list {
{ 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
{ 0x804b, "SNA over 802.2 Control Protocol" },
{ 0x804d, "SNA Control Protocol" },
{ 0x8207, "Cisco Discovery Protocol Control" },
{ 0x8209, "Netcs Twin Routing" },
{ 0x820b, "STP - Control Protocol" },
-@@ -975,24 +998,29 @@ struct protocol_list {
+@@ -1056,24 +1079,29 @@ struct protocol_list {
{ 0x8281, "MPLSCP" },
{ 0x8285, "IEEE p1284.4 standard - Protocol Control" },
{ 0x8287, "ETSI TETRA TNP1 Control Protocol" },
--- a/pppd/options.c
+++ b/pppd/options.c
-@@ -348,13 +348,14 @@ option_t general_options[] = {
+@@ -362,13 +362,14 @@ struct option general_options[] = {
"Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 },
{ "nomultilink", o_bool, &multilink,
"Disable multilink operation", OPT_PRIOSUB | 0 },
{ "bundle", o_string, &bundle_name,
"Bundle name for multilink", OPT_PRIO },
- #endif /* HAVE_MULTILINK */
+ #endif /* PPP_WITH_MULTILINK */
+ { "nomp", o_bool, &multilink,
+ "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 },
+
- #ifdef PLUGIN
+ #ifdef PPP_WITH_PLUGINS
{ "plugin", o_special, (void *)loadplugin,
"Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST },
---- a/configure
-+++ b/configure
-@@ -133,7 +133,7 @@ if [ -d "$ksrc" ]; then
- mkmkf $ksrc/Makedefs$compiletype Makedefs.com
- for dir in pppd pppstats chat pppdump pppd/plugins pppd/plugins/pppoe \
- pppd/plugins/radius pppd/plugins/pppoatm \
-- pppd/plugins/pppol2tp; do
-+ pppd/plugins/pppol2tp pppd/plugins/pptp ; do
- mkmkf $dir/Makefile.$makext $dir/Makefile
- done
- if [ -f $ksrc/Makefile.$makext$archvariant ]; then
---- a/pppd/plugins/Makefile.linux
-+++ b/pppd/plugins/Makefile.linux
-@@ -14,7 +14,7 @@ INSTALL = install
- # EAP-TLS
- CFLAGS += -DUSE_EAPTLS=1
+--- a/configure.ac
++++ b/configure.ac
+@@ -336,6 +336,7 @@ AC_CONFIG_FILES([
+ pppd/plugins/pppoatm/Makefile
+ pppd/plugins/pppol2tp/Makefile
+ pppd/plugins/radius/Makefile
++ pppd/plugins/pptp/Makefile
+ pppdump/Makefile
+ pppstats/Makefile
+ scripts/Makefile
+--- a/pppd/plugins/Makefile.am
++++ b/pppd/plugins/Makefile.am
+@@ -21,5 +21,5 @@ winbind_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+ winbind_la_SOURCES = winbind.c
--SUBDIRS := pppoe pppoatm pppol2tp
-+SUBDIRS := pppoe pppoatm pppol2tp pptp
- # Uncomment the next line to include the radius authentication plugin
- SUBDIRS += radius
- PLUGINS := minconn.so passprompt.so passwordfd.so winbind.so
+ if !SUNOS
+-SUBDIRS = pppoe pppoatm pppol2tp radius
++SUBDIRS = pppoe pppoatm pppol2tp radius pptp
+ endif
--- /dev/null
-+++ b/pppd/plugins/pptp/Makefile.linux
-@@ -0,0 +1,31 @@
-+#
-+# This program may be distributed according to the terms of the GNU
-+# General Public License, version 2 or (at your option) any later version.
-+#
-+# $Id: Makefile.linux,v 1.9 2012/05/04 21:48:00 dgolle Exp $
-+#***********************************************************************
-+
-+DESTDIR = $(INSTROOT)@DESTDIR@
-+LIBDIR = $(DESTDIR)/lib/pppd/$(PPPDVERSION)
-+
-+PPPDVERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h)
-+
-+INSTALL = install
-+
-+COPTS=-O2 -g
-+CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC -DPPPD_VERSION=\"$(PPPDVERSION)\"
-+all: pptp.so
-+
-+%.o: %.c
-+ $(CC) $(CFLAGS) -c -o $@ $<
-+
-+pptp.so: dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
-+ $(CC) -o pptp.so -shared dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
-+
-+install: all
-+ $(INSTALL) -d -m 755 $(LIBDIR)
-+ $(INSTALL) -c -m 4550 pptp.so $(LIBDIR)
-+
-+clean:
-+ rm -f *.o *.so
-+
++++ b/pppd/plugins/pptp/Makefile.am
+@@ -0,0 +1,18 @@
++pppd_plugin_LTLIBRARIES = pptp.la
++pppd_plugindir = $(PPPD_PLUGIN_DIR)
++
++noinst_HEADERS = \
++ dirutil.h \
++ orckit_quirks.h \
++ pptp_callmgr.h \
++ pptp_ctrl.h \
++ pptp_msg.h \
++ pptp_options.h \
++ pptp_quirks.h \
++ util.h \
++ vector.h
++
++pptp_la_CPPFLAGS = -I${top_srcdir} -DSYSCONFDIR=\"${sysconfdir}\" -DPLUGIN
++pptp_la_LDFLAGS = -fPIC -module -avoid-version
++pptp_la_SOURCES = dirutil.c orckit_quirks.c pptp.c pptp_callmgr.c pptp_ctrl.c \
++ pptp_quirks.c util.c vector.c
--- /dev/null
+++ b/pppd/plugins/pptp/dirutil.c
@@ -0,0 +1,68 @@
+xeb xeb@mail.ru
--- /dev/null
+++ b/pppd/plugins/pptp/pptp.c
-@@ -0,0 +1,323 @@
+@@ -0,0 +1,325 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Kozlov D. <xeb@mail.ru> *
+ * some cleanup done (C) 2012 by Daniel Golle <dgolle@allnet.de> *
+#include <sys/ioctl.h>
+
+#include "pppd.h"
++#include "pppd-private.h"
++#include "options.h"
+#include "fsm.h"
+#include "lcp.h"
+#include "ipcp.h"
+ check_options: NULL,
+ connect: &pptp_connect,
+ disconnect: &pptp_disconnect,
-+ establish_ppp: &generic_establish_ppp,
-+ disestablish_ppp: &generic_disestablish_ppp,
++ establish_ppp: &ppp_generic_establish,
++ disestablish_ppp: &ppp_generic_disestablish,
+ close: NULL,
+ cleanup: NULL
+};
+static int pptp_start_server(void)
+{
+ pptp_fd=pptp_sock;
-+ sprintf(ppp_devnam,"pptp (%s)",pptp_client);
++ sprintf(ppp_devname,"pptp (%s)",pptp_client);
+
+ return pptp_fd;
+}
+ return -1;
+ }
+
-+ sprintf(ppp_devnam,"pptp (%s)",pptp_server);
++ sprintf(ppp_devname,"pptp (%s)",pptp_server);
+
+ return pptp_fd;
+}
+
+void plugin_init(void)
+{
-+ add_options(Options);
++ ppp_add_options(Options);
+
+ info("PPTP plugin version %s", PPTP_VERSION);
+
--- a/pppd/plugins/pptp/pptp.c
+++ b/pppd/plugins/pptp/pptp.c
-@@ -48,7 +48,7 @@
+@@ -50,7 +50,7 @@
#include "pptp_callmgr.h"
#include <net/if.h>
+++ /dev/null
---- a/pppd/plugins/pptp/Makefile.linux
-+++ b/pppd/plugins/pptp/Makefile.linux
-@@ -20,7 +20,7 @@ all: pptp.so
- $(CC) $(CFLAGS) -c -o $@ $<
-
- pptp.so: dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
-- $(CC) -o pptp.so -shared dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
-+ $(CC) -fPIC -o pptp.so -shared dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
-
- install: all
- $(INSTALL) -d -m 755 $(LIBDIR)
--- /dev/null
+--- a/pppd/ppp-sha1.c
++++ b/pppd/ppp-sha1.c
+@@ -107,6 +107,7 @@ static void sha1_clean(PPP_MD_CTX *ctx)
+ */
+
+ #include <string.h>
++#include <sys/types.h>
+ #include <netinet/in.h> /* htonl() */
+
+ typedef struct {
--- /dev/null
+--- a/pppd/crypto_ms.c
++++ b/pppd/crypto_ms.c
+@@ -122,8 +122,6 @@ MakeKey(const unsigned char *key, unsign
+ DES_set_odd_parity((DES_cblock *)des_key);
+ }
+
+-#include <openssl/evp.h>
+-
+ int
+ DesEncrypt(const unsigned char *clear, const unsigned char *key, unsigned char *cipher)
+ {
+++ /dev/null
-From 831dca008699d485f2c8e91749657ef2d0b06166 Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Thu, 6 Dec 2018 08:43:17 +0100
-Subject: [PATCH] Revert "pppd: Use openssl for the DES instead of the libcrypt
- / glibc"
-
-For musl and glibc2.27 we can keep linking to crypt; however if we
-switch to glibc 2.28 we will have to link to one of the SSL libraries.
-
-This reverts commit 3c7b86229f7bd2600d74db14b1fe5b3896be3875.
----
- pppd/Makefile.linux | 7 +++----
- pppd/pppcrypt.c | 18 +++++++++---------
- 2 files changed, 12 insertions(+), 13 deletions(-)
-
---- a/pppd/Makefile.linux
-+++ b/pppd/Makefile.linux
-@@ -36,10 +36,10 @@ endif
-
- LIBS = -lrt
-
--# Uncomment the next line to include support for Microsoft's
-+# Uncomment the next 2 lines to include support for Microsoft's
- # MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux.
- CHAPMS=y
--#USE_CRYPT=y
-+USE_CRYPT=y
- # Don't use MSLANMAN unless you really know what you're doing.
- #MSLANMAN=y
- # Uncomment the next line to include support for MPPE. CHAPMS (above) must
-@@ -158,8 +158,7 @@ endif
-
- ifdef NEEDDES
- ifndef USE_CRYPT
--CFLAGS += -I$(shell $(CC) --print-sysroot)/usr/include/openssl
--NEEDCRYPTOLIB = y
-+LIBS += -ldes $(LIBS)
- else
- CFLAGS += -DUSE_CRYPT=1
- endif
---- a/pppd/pppcrypt.c
-+++ b/pppd/pppcrypt.c
-@@ -62,7 +62,7 @@ MakeKey(u_char *key, u_char *des_key)
- des_key[7] = Get7Bits(key, 49);
-
- #ifndef USE_CRYPT
-- DES_set_odd_parity((DES_cblock *)des_key);
-+ des_set_odd_parity((des_cblock *)des_key);
- #endif
- }
-
-@@ -147,30 +147,30 @@ DesDecrypt(u_char *cipher, u_char *clear
- }
-
- #else /* USE_CRYPT */
--static DES_key_schedule key_schedule;
-+static des_key_schedule key_schedule;
-
- bool
- DesSetkey(u_char *key)
- {
-- DES_cblock des_key;
-+ des_cblock des_key;
- MakeKey(key, des_key);
-- DES_set_key(&des_key, &key_schedule);
-+ des_set_key(&des_key, key_schedule);
- return (1);
- }
-
- bool
- DesEncrypt(u_char *clear, u_char *cipher)
- {
-- DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher,
-- &key_schedule, 1);
-+ des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher,
-+ key_schedule, 1);
- return (1);
- }
-
- bool
- DesDecrypt(u_char *cipher, u_char *clear)
- {
-- DES_ecb_encrypt((DES_cblock *)cipher, (DES_cblock *)clear,
-- &key_schedule, 0);
-+ des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear,
-+ key_schedule, 0);
- return (1);
- }
-
+++ /dev/null
---- a/pppd/Makefile.linux
-+++ b/pppd/Makefile.linux
-@@ -49,7 +49,8 @@ MPPE=y
- # 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
-+# libpcap statically linked in OpenWRT, hence disabled here.
-+FILTER=
-
- # Support for precompiled filters
- PRECOMPILED_FILTER=y