You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1271 lines
40 KiB
1271 lines
40 KiB
13 years ago
|
# --- SDE-COPYRIGHT-NOTE-BEGIN ---
|
||
|
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
|
||
|
#
|
||
|
# Filename: package/.../ppp/ppp-2.4.5-upstream-git-fixes-20110911.patch
|
||
|
# Copyright (C) 2011 The OpenSDE Project
|
||
|
#
|
||
|
# More information can be found in the files COPYING and README.
|
||
|
#
|
||
|
# This patch file is dual-licensed. It is available under the license the
|
||
|
# patched project is licensed under, as long as it is an OpenSource license
|
||
|
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
|
||
|
# of the GNU General Public License as published by the Free Software
|
||
|
# Foundation; either version 2 of the License, or (at your option) any later
|
||
|
# version.
|
||
|
# --- SDE-COPYRIGHT-NOTE-END ---
|
||
|
|
||
|
From e7537958aee79b3f653c601e903cb31d78fb7dcc Mon Sep 17 00:00:00 2001
|
||
|
From: Ludwig Nussel <ludwig.nussel@suse.de>
|
||
|
Date: Tue, 9 Feb 2010 17:32:15 +0100
|
||
|
Subject: [PATCH 1/9] Document +ipv6 and ipv6cp-accept-local
|
||
|
|
||
|
Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de>
|
||
|
Signed-off-by: Paul Mackerras <paulus@samba.org>
|
||
|
---
|
||
|
pppd/pppd.8 | 8 ++++++++
|
||
|
1 files changed, 8 insertions(+), 0 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/pppd.8 ppp-2.4.5/pppd/pppd.8
|
||
|
index 8ea8200..b7adc77 100644
|
||
|
--- ppp-2.4.5-release/pppd/pppd.8
|
||
|
+++ ppp-2.4.5/pppd/pppd.8
|
||
|
@@ -193,6 +193,9 @@ will not accept a different value from the peer in the IPCP
|
||
|
negotiation, unless the \fIipcp\-accept\-local\fR and/or
|
||
|
\fIipcp\-accept\-remote\fR options are given, respectively.
|
||
|
.TP
|
||
|
+.B +ipv6
|
||
|
+Enable the IPv6CP and IPv6 protocols.
|
||
|
+.TP
|
||
|
.B ipv6 \fI<local_interface_identifier>\fR,\fI<remote_interface_identifier>
|
||
|
Set the local and/or remote 64-bit interface identifier. Either one may be
|
||
|
omitted. The identifier must be specified in standard ascii notation of
|
||
|
@@ -449,6 +452,11 @@ scripts. If this
|
||
|
option is given, the \fIstring\fR supplied is given as the 6th
|
||
|
parameter to those scripts.
|
||
|
.TP
|
||
|
+.B ipv6cp\-accept\-local
|
||
|
+With this option, pppd will accept the peer's idea of our local IPv6
|
||
|
+interface identifier, even if the local IPv6 interface identifier
|
||
|
+was specified in an option.
|
||
|
+.TP
|
||
|
.B ipv6cp\-max\-configure \fIn
|
||
|
Set the maximum number of IPv6CP configure-request transmissions to
|
||
|
\fIn\fR (default 10).
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From 406215672cfadc03017341fe03802d1c7294b903 Mon Sep 17 00:00:00 2001
|
||
|
From: Ludwig Nussel <ludwig.nussel@suse.de>
|
||
|
Date: Tue, 9 Feb 2010 17:32:16 +0100
|
||
|
Subject: [PATCH 2/9] Install pppol2tp plugins with sane permissions
|
||
|
|
||
|
Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de>
|
||
|
Signed-off-by: Paul Mackerras <paulus@samba.org>
|
||
|
---
|
||
|
pppd/plugins/pppol2tp/Makefile.linux | 2 +-
|
||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/plugins/pppol2tp/Makefile.linux ppp-2.4.5/pppd/plugins/pppol2tp/Makefile.linux
|
||
|
index 19eff67..ea3538e 100644
|
||
|
--- ppp-2.4.5-release/pppd/plugins/pppol2tp/Makefile.linux
|
||
|
+++ ppp-2.4.5/pppd/plugins/pppol2tp/Makefile.linux
|
||
|
@@ -20,7 +20,7 @@ all: $(PLUGINS)
|
||
|
|
||
|
install: all
|
||
|
$(INSTALL) -d -m 755 $(LIBDIR)
|
||
|
- $(INSTALL) -c -m 4550 $(PLUGINS) $(LIBDIR)
|
||
|
+ $(INSTALL) -c -m 755 $(PLUGINS) $(LIBDIR)
|
||
|
|
||
|
clean:
|
||
|
rm -f *.o *.so
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From 3eb9e810cfa515543655659b72dde30c54fea0a5 Mon Sep 17 00:00:00 2001
|
||
|
From: Paul Mackerras <paulus@samba.org>
|
||
|
Date: Sun, 7 Mar 2010 15:21:38 +1100
|
||
|
Subject: [PATCH 3/9] pppd: Terminate correctly if lcp_lowerup delayed calling fsm_lowerup
|
||
|
|
||
|
Cameron Hutchison noticed that if pppd gets asked to terminate the
|
||
|
link in the period between when lcp_lowerup() is called and when
|
||
|
fsm_lowerup() is called from lcp_delayed_up() (i.e. when listen_time
|
||
|
is non-zero), pppd never exits.
|
||
|
|
||
|
The reason is that lcp_close() doesn't handle the delayed-up case
|
||
|
properly. Since the FSM is still in STOPPED state, we don't call
|
||
|
lcp_finished() and therefore never exit the main event loop.
|
||
|
|
||
|
This fixes it by handling the delayed-up case in lcp_close() as if
|
||
|
we had done the lowerup but the OPT_SILENT bit was set. We use the
|
||
|
silent case because we don't want to actually send a configure-request
|
||
|
at this point.
|
||
|
|
||
|
Signed-off-by: Paul Mackerras <paulus@samba.org>
|
||
|
---
|
||
|
pppd/lcp.c | 28 +++++++++++++++++++---------
|
||
|
1 files changed, 19 insertions(+), 9 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/lcp.c ppp-2.4.5/pppd/lcp.c
|
||
|
index 5c77490..8ed2778 100644
|
||
|
--- ppp-2.4.5-release/pppd/lcp.c
|
||
|
+++ ppp-2.4.5/pppd/lcp.c
|
||
|
@@ -397,21 +397,29 @@ lcp_close(unit, reason)
|
||
|
char *reason;
|
||
|
{
|
||
|
fsm *f = &lcp_fsm[unit];
|
||
|
+ int oldstate;
|
||
|
|
||
|
if (phase != PHASE_DEAD && phase != PHASE_MASTER)
|
||
|
new_phase(PHASE_TERMINATE);
|
||
|
- if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
|
||
|
+
|
||
|
+ if (f->flags & DELAYED_UP) {
|
||
|
+ untimeout(lcp_delayed_up, f);
|
||
|
+ f->state = STOPPED;
|
||
|
+ }
|
||
|
+ oldstate = f->state;
|
||
|
+
|
||
|
+ fsm_close(f, reason);
|
||
|
+ if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) {
|
||
|
/*
|
||
|
* This action is not strictly according to the FSM in RFC1548,
|
||
|
* but it does mean that the program terminates if you do a
|
||
|
- * lcp_close() in passive/silent mode when a connection hasn't
|
||
|
- * been established.
|
||
|
+ * lcp_close() when a connection hasn't been established
|
||
|
+ * because we are in passive/silent mode or because we have
|
||
|
+ * delayed the fsm_lowerup() call and it hasn't happened yet.
|
||
|
*/
|
||
|
- f->state = CLOSED;
|
||
|
+ f->flags &= ~DELAYED_UP;
|
||
|
lcp_finished(f);
|
||
|
-
|
||
|
- } else
|
||
|
- fsm_close(f, reason);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -453,9 +461,10 @@ lcp_lowerdown(unit)
|
||
|
{
|
||
|
fsm *f = &lcp_fsm[unit];
|
||
|
|
||
|
- if (f->flags & DELAYED_UP)
|
||
|
+ if (f->flags & DELAYED_UP) {
|
||
|
f->flags &= ~DELAYED_UP;
|
||
|
- else
|
||
|
+ untimeout(lcp_delayed_up, f);
|
||
|
+ } else
|
||
|
fsm_lowerdown(&lcp_fsm[unit]);
|
||
|
}
|
||
|
|
||
|
@@ -489,6 +498,7 @@ lcp_input(unit, p, len)
|
||
|
|
||
|
if (f->flags & DELAYED_UP) {
|
||
|
f->flags &= ~DELAYED_UP;
|
||
|
+ untimeout(lcp_delayed_up, f);
|
||
|
fsm_lowerup(f);
|
||
|
}
|
||
|
fsm_input(f, p, len);
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From cab58617fd9d328029fffabc788020264b4fa91f Mon Sep 17 00:00:00 2001
|
||
|
From: Paul Mackerras <paulus@samba.org>
|
||
|
Date: Sun, 7 Mar 2010 16:54:00 +1100
|
||
|
Subject: [PATCH 4/9] rp_pppoe: Copy acName and pppd_pppoe_service after option parsing
|
||
|
|
||
|
At present, the access concentrator name (acName) and service name
|
||
|
(pppd_pppoe_service) are set by option parsing, but are used at the
|
||
|
point of PPPOEInitDevice(), which gets called when the ethernet
|
||
|
device name is seen. So if the rp_pppoe_service or rp_pppoe_ac
|
||
|
options appear after the device name, they are ignored.
|
||
|
|
||
|
This fixes it by using acName and pppd_pppoe_service in
|
||
|
PPPOEConnectDevice, which gets called after all options have been
|
||
|
parsed.
|
||
|
|
||
|
Signed-off-by: Paul Mackerras <paulus@samba.org>
|
||
|
---
|
||
|
pppd/plugins/rp-pppoe/plugin.c | 4 ++--
|
||
|
1 files changed, 2 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
|
||
|
index e94494b..9bd6643 100644
|
||
|
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c
|
||
|
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
|
||
|
@@ -108,8 +108,6 @@ PPPOEInitDevice(void)
|
||
|
novm("PPPoE session data");
|
||
|
}
|
||
|
memset(conn, 0, sizeof(PPPoEConnection));
|
||
|
- conn->acName = acName;
|
||
|
- conn->serviceName = pppd_pppoe_service;
|
||
|
conn->ifName = devnam;
|
||
|
conn->discoverySocket = -1;
|
||
|
conn->sessionSocket = -1;
|
||
|
@@ -133,6 +131,8 @@ PPPOEConnectDevice(void)
|
||
|
{
|
||
|
struct sockaddr_pppox sp;
|
||
|
|
||
|
+ conn->acName = acName;
|
||
|
+ conn->serviceName = pppd_pppoe_service;
|
||
|
strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
|
||
|
if (existingSession) {
|
||
|
unsigned int mac[ETH_ALEN];
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From 2b6310fd24dba8e0fca8999916a162f0a1842a84 Mon Sep 17 00:00:00 2001
|
||
|
From: James Carlson <carlsonj@workingcode.com>
|
||
|
Date: Mon, 23 Aug 2010 09:59:56 -0400
|
||
|
Subject: [PATCH 5/9] Add set and reset options to control environment variables for scripts.
|
||
|
|
||
|
---
|
||
|
pppd/main.c | 111 +++++++++++++++++++++++++++++------
|
||
|
pppd/options.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||
|
pppd/pppd.8 | 14 +++++
|
||
|
pppd/pppd.h | 27 +++++++--
|
||
|
pppd/utils.c | 7 +-
|
||
|
5 files changed, 302 insertions(+), 36 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/main.c ppp-2.4.5/pppd/main.c
|
||
|
index 014d614..1b513ca 100644
|
||
|
--- ppp-2.4.5-release/pppd/main.c
|
||
|
+++ ppp-2.4.5/pppd/main.c
|
||
|
@@ -1615,6 +1615,52 @@ safe_fork(int infd, int outfd, int errfd)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static bool
|
||
|
+add_script_env(pos, newstring)
|
||
|
+ int pos;
|
||
|
+ char *newstring;
|
||
|
+{
|
||
|
+ if (pos + 1 >= s_env_nalloc) {
|
||
|
+ int new_n = pos + 17;
|
||
|
+ char **newenv = realloc(script_env, new_n * sizeof(char *));
|
||
|
+ if (newenv == NULL) {
|
||
|
+ free(newstring - 1);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ script_env = newenv;
|
||
|
+ s_env_nalloc = new_n;
|
||
|
+ }
|
||
|
+ script_env[pos] = newstring;
|
||
|
+ script_env[pos + 1] = NULL;
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+remove_script_env(pos)
|
||
|
+ int pos;
|
||
|
+{
|
||
|
+ free(script_env[pos] - 1);
|
||
|
+ while ((script_env[pos] = script_env[pos + 1]) != NULL)
|
||
|
+ pos++;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * update_system_environment - process the list of set/unset options
|
||
|
+ * and update the system environment.
|
||
|
+ */
|
||
|
+static void
|
||
|
+update_system_environment()
|
||
|
+{
|
||
|
+ struct userenv *uep;
|
||
|
+
|
||
|
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
|
||
|
+ if (uep->ue_isset)
|
||
|
+ setenv(uep->ue_name, uep->ue_value, 1);
|
||
|
+ else
|
||
|
+ unsetenv(uep->ue_name);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* device_script - run a program to talk to the specified fds
|
||
|
* (e.g. to run the connector or disconnector script).
|
||
|
@@ -1670,6 +1716,7 @@ device_script(program, in, out, dont_wait)
|
||
|
fprintf(stderr, "pppd: setuid failed\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
+ update_system_environment();
|
||
|
execl("/bin/sh", "sh", "-c", program, (char *)0);
|
||
|
perror("pppd: could not exec /bin/sh");
|
||
|
exit(99);
|
||
|
@@ -1678,6 +1725,44 @@ device_script(program, in, out, dont_wait)
|
||
|
|
||
|
|
||
|
/*
|
||
|
+ * update_script_environment - process the list of set/unset options
|
||
|
+ * and update the script environment. Note that we intentionally do
|
||
|
+ * not update the TDB. These changes are layered on top right before
|
||
|
+ * exec. It is not possible to use script_setenv() or
|
||
|
+ * script_unsetenv() safely after this routine is run.
|
||
|
+ */
|
||
|
+static void
|
||
|
+update_script_environment()
|
||
|
+{
|
||
|
+ struct userenv *uep;
|
||
|
+
|
||
|
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
|
||
|
+ int i;
|
||
|
+ char *p, *newstring;
|
||
|
+ int nlen = strlen(uep->ue_name);
|
||
|
+
|
||
|
+ for (i = 0; (p = script_env[i]) != NULL; i++) {
|
||
|
+ if (strncmp(p, uep->ue_name, nlen) == 0 && p[nlen] == '=')
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if (uep->ue_isset) {
|
||
|
+ nlen += strlen(uep->ue_value) + 2;
|
||
|
+ newstring = malloc(nlen + 1);
|
||
|
+ if (newstring == NULL)
|
||
|
+ continue;
|
||
|
+ *newstring++ = 0;
|
||
|
+ slprintf(newstring, nlen, "%s=%s", uep->ue_name, uep->ue_value);
|
||
|
+ if (p != NULL)
|
||
|
+ script_env[i] = newstring;
|
||
|
+ else
|
||
|
+ add_script_env(i, newstring);
|
||
|
+ } else {
|
||
|
+ remove_script_env(i);
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
* run_program - execute a program with given arguments,
|
||
|
* but don't wait for it unless wait is non-zero.
|
||
|
* If the program can't be executed, logs an error unless
|
||
|
@@ -1747,6 +1832,7 @@ run_program(prog, args, must_exist, done, arg, wait)
|
||
|
#endif
|
||
|
|
||
|
/* run the program */
|
||
|
+ update_script_environment();
|
||
|
execve(prog, args, script_env);
|
||
|
if (must_exist || errno != ENOENT) {
|
||
|
/* have to reopen the log, there's nowhere else
|
||
|
@@ -1967,25 +2053,16 @@ script_setenv(var, value, iskey)
|
||
|
} else {
|
||
|
/* no space allocated for script env. ptrs. yet */
|
||
|
i = 0;
|
||
|
- script_env = (char **) malloc(16 * sizeof(char *));
|
||
|
- if (script_env == 0)
|
||
|
+ script_env = malloc(16 * sizeof(char *));
|
||
|
+ if (script_env == 0) {
|
||
|
+ free(newstring - 1);
|
||
|
return;
|
||
|
+ }
|
||
|
s_env_nalloc = 16;
|
||
|
}
|
||
|
|
||
|
- /* reallocate script_env with more space if needed */
|
||
|
- if (i + 1 >= s_env_nalloc) {
|
||
|
- int new_n = i + 17;
|
||
|
- char **newenv = (char **) realloc((void *)script_env,
|
||
|
- new_n * sizeof(char *));
|
||
|
- if (newenv == 0)
|
||
|
- return;
|
||
|
- script_env = newenv;
|
||
|
- s_env_nalloc = new_n;
|
||
|
- }
|
||
|
-
|
||
|
- script_env[i] = newstring;
|
||
|
- script_env[i+1] = 0;
|
||
|
+ if (!add_script_env(i, newstring))
|
||
|
+ return;
|
||
|
|
||
|
#ifdef USE_TDB
|
||
|
if (pppdb != NULL) {
|
||
|
@@ -2016,9 +2093,7 @@ script_unsetenv(var)
|
||
|
if (p[-1] && pppdb != NULL)
|
||
|
delete_db_key(p);
|
||
|
#endif
|
||
|
- free(p-1);
|
||
|
- while ((script_env[i] = script_env[i+1]) != 0)
|
||
|
- ++i;
|
||
|
+ remove_script_env(i);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
diff --git ppp-2.4.5-release/pppd/options.c ppp-2.4.5/pppd/options.c
|
||
|
index 482eab9..434ab95 100644
|
||
|
--- ppp-2.4.5-release/pppd/options.c
|
||
|
+++ ppp-2.4.5/pppd/options.c
|
||
|
@@ -119,6 +119,7 @@ bool dump_options; /* print out option values */
|
||
|
bool dryrun; /* print out option values and exit */
|
||
|
char *domain; /* domain name set by domain option */
|
||
|
int child_wait = 5; /* # seconds to wait for children at exit */
|
||
|
+struct userenv *userenv_list; /* user environment variables */
|
||
|
|
||
|
#ifdef MAXOCTETS
|
||
|
unsigned int maxoctets = 0; /* default - no limit */
|
||
|
@@ -135,6 +136,7 @@ struct bpf_program pass_filter;/* Filter program for packets to pass */
|
||
|
struct bpf_program active_filter; /* Filter program for link-active pkts */
|
||
|
#endif
|
||
|
|
||
|
+static option_t *curopt; /* pointer to option being processed */
|
||
|
char *current_option; /* the name of the option being parsed */
|
||
|
int privileged_option; /* set iff the current option came from root */
|
||
|
char *option_source; /* string saying where the option came from */
|
||
|
@@ -167,6 +169,11 @@ static int setactivefilter __P((char **));
|
||
|
static int setmodir __P((char **));
|
||
|
#endif
|
||
|
|
||
|
+static int user_setenv __P((char **));
|
||
|
+static void user_setprint __P((option_t *, printer_func, void *));
|
||
|
+static int user_unsetenv __P((char **));
|
||
|
+static void user_unsetprint __P((option_t *, printer_func, void *));
|
||
|
+
|
||
|
static option_t *find_option __P((const char *name));
|
||
|
static int process_option __P((option_t *, char *, char **));
|
||
|
static int n_arguments __P((option_t *));
|
||
|
@@ -281,6 +288,13 @@ option_t general_options[] = {
|
||
|
"Number of seconds to wait for child processes at exit",
|
||
|
OPT_PRIO },
|
||
|
|
||
|
+ { "set", o_special, (void *)user_setenv,
|
||
|
+ "Set user environment variable",
|
||
|
+ OPT_A2PRINTER | OPT_NOPRINT, (void *)user_setprint },
|
||
|
+ { "unset", o_special, (void *)user_unsetenv,
|
||
|
+ "Unset user environment variable",
|
||
|
+ OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint },
|
||
|
+
|
||
|
#ifdef HAVE_MULTILINK
|
||
|
{ "multilink", o_bool, &multilink,
|
||
|
"Enable multilink operation", OPT_PRIO | 1 },
|
||
|
@@ -768,6 +782,7 @@ process_option(opt, cmd, argv)
|
||
|
case o_special_noarg:
|
||
|
case o_special:
|
||
|
parser = (int (*) __P((char **))) opt->addr;
|
||
|
+ curopt = opt;
|
||
|
if (!(*parser)(argv))
|
||
|
return 0;
|
||
|
if (opt->flags & OPT_A2LIST) {
|
||
|
@@ -881,7 +896,7 @@ check_options()
|
||
|
static void
|
||
|
print_option(opt, mainopt, printer, arg)
|
||
|
option_t *opt, *mainopt;
|
||
|
- void (*printer) __P((void *, char *, ...));
|
||
|
+ printer_func printer;
|
||
|
void *arg;
|
||
|
{
|
||
|
int i, v;
|
||
|
@@ -944,11 +959,8 @@ print_option(opt, mainopt, printer, arg)
|
||
|
printer(arg, " ");
|
||
|
}
|
||
|
if (opt->flags & OPT_A2PRINTER) {
|
||
|
- void (*oprt) __P((option_t *,
|
||
|
- void ((*)__P((void *, char *, ...))),
|
||
|
- void *));
|
||
|
- oprt = (void (*) __P((option_t *,
|
||
|
- void ((*)__P((void *, char *, ...))),
|
||
|
+ void (*oprt) __P((option_t *, printer_func, void *));
|
||
|
+ oprt = (void (*) __P((option_t *, printer_func,
|
||
|
void *)))opt->addr2;
|
||
|
(*oprt)(opt, printer, arg);
|
||
|
} else if (opt->flags & OPT_A2STRVAL) {
|
||
|
@@ -986,7 +998,7 @@ print_option(opt, mainopt, printer, arg)
|
||
|
static void
|
||
|
print_option_list(opt, printer, arg)
|
||
|
option_t *opt;
|
||
|
- void (*printer) __P((void *, char *, ...));
|
||
|
+ printer_func printer;
|
||
|
void *arg;
|
||
|
{
|
||
|
while (opt->name != NULL) {
|
||
|
@@ -1004,7 +1016,7 @@ print_option_list(opt, printer, arg)
|
||
|
*/
|
||
|
void
|
||
|
print_options(printer, arg)
|
||
|
- void (*printer) __P((void *, char *, ...));
|
||
|
+ printer_func printer;
|
||
|
void *arg;
|
||
|
{
|
||
|
struct option_list *list;
|
||
|
@@ -1623,3 +1635,154 @@ loadplugin(argv)
|
||
|
return 0;
|
||
|
}
|
||
|
#endif /* PLUGIN */
|
||
|
+
|
||
|
+/*
|
||
|
+ * Set an environment variable specified by the user.
|
||
|
+ */
|
||
|
+static int
|
||
|
+user_setenv(argv)
|
||
|
+ char **argv;
|
||
|
+{
|
||
|
+ char *arg = argv[0];
|
||
|
+ char *eqp;
|
||
|
+ struct userenv *uep, **insp;
|
||
|
+
|
||
|
+ if ((eqp = strchr(arg, '=')) == NULL) {
|
||
|
+ option_error("missing = in name=value: %s", arg);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ if (eqp == arg) {
|
||
|
+ option_error("missing variable name: %s", arg);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
|
||
|
+ int nlen = strlen(uep->ue_name);
|
||
|
+ if (nlen == (eqp - arg) &&
|
||
|
+ strncmp(arg, uep->ue_name, nlen) == 0)
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ /* Ignore attempts by unprivileged users to override privileged sources */
|
||
|
+ if (uep != NULL && !privileged_option && uep->ue_priv)
|
||
|
+ return 1;
|
||
|
+ /* The name never changes, so allocate it with the structure */
|
||
|
+ if (uep == NULL) {
|
||
|
+ uep = malloc(sizeof (*uep) + (eqp-arg));
|
||
|
+ strncpy(uep->ue_name, arg, eqp-arg);
|
||
|
+ uep->ue_name[eqp-arg] = '\0';
|
||
|
+ uep->ue_next = NULL;
|
||
|
+ insp = &userenv_list;
|
||
|
+ while (*insp != NULL)
|
||
|
+ insp = &(*insp)->ue_next;
|
||
|
+ *insp = uep;
|
||
|
+ } else {
|
||
|
+ struct userenv *uep2;
|
||
|
+ for (uep2 = userenv_list; uep2 != NULL; uep2 = uep2->ue_next) {
|
||
|
+ if (uep2 != uep && !uep2->ue_isset)
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if (uep2 == NULL && !uep->ue_isset)
|
||
|
+ find_option("unset")->flags |= OPT_NOPRINT;
|
||
|
+ free(uep->ue_value);
|
||
|
+ }
|
||
|
+ uep->ue_isset = 1;
|
||
|
+ uep->ue_priv = privileged_option;
|
||
|
+ uep->ue_source = option_source;
|
||
|
+ uep->ue_value = strdup(eqp + 1);
|
||
|
+ curopt->flags &= ~OPT_NOPRINT;
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+user_setprint(opt, printer, arg)
|
||
|
+ option_t *opt;
|
||
|
+ printer_func printer;
|
||
|
+ void *arg;
|
||
|
+{
|
||
|
+ struct userenv *uep, *uepnext;
|
||
|
+
|
||
|
+ uepnext = userenv_list;
|
||
|
+ while (uepnext != NULL && !uepnext->ue_isset)
|
||
|
+ uepnext = uepnext->ue_next;
|
||
|
+ while ((uep = uepnext) != NULL) {
|
||
|
+ uepnext = uep->ue_next;
|
||
|
+ while (uepnext != NULL && !uepnext->ue_isset)
|
||
|
+ uepnext = uepnext->ue_next;
|
||
|
+ (*printer)(arg, "%s=%s", uep->ue_name, uep->ue_value);
|
||
|
+ if (uepnext != NULL)
|
||
|
+ (*printer)(arg, "\t\t# (from %s)\n%s ", uep->ue_source, opt->name);
|
||
|
+ else
|
||
|
+ opt->source = uep->ue_source;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+user_unsetenv(argv)
|
||
|
+ char **argv;
|
||
|
+{
|
||
|
+ struct userenv *uep, **insp;
|
||
|
+ char *arg = argv[0];
|
||
|
+
|
||
|
+ if (strchr(arg, '=') != NULL) {
|
||
|
+ option_error("unexpected = in name: %s", arg);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ if (arg == '\0') {
|
||
|
+ option_error("missing variable name for unset");
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
|
||
|
+ if (strcmp(arg, uep->ue_name) == 0)
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ /* Ignore attempts by unprivileged users to override privileged sources */
|
||
|
+ if (uep != NULL && !privileged_option && uep->ue_priv)
|
||
|
+ return 1;
|
||
|
+ /* The name never changes, so allocate it with the structure */
|
||
|
+ if (uep == NULL) {
|
||
|
+ uep = malloc(sizeof (*uep) + strlen(arg));
|
||
|
+ strcpy(uep->ue_name, arg);
|
||
|
+ uep->ue_next = NULL;
|
||
|
+ insp = &userenv_list;
|
||
|
+ while (*insp != NULL)
|
||
|
+ insp = &(*insp)->ue_next;
|
||
|
+ *insp = uep;
|
||
|
+ } else {
|
||
|
+ struct userenv *uep2;
|
||
|
+ for (uep2 = userenv_list; uep2 != NULL; uep2 = uep2->ue_next) {
|
||
|
+ if (uep2 != uep && uep2->ue_isset)
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if (uep2 == NULL && uep->ue_isset)
|
||
|
+ find_option("set")->flags |= OPT_NOPRINT;
|
||
|
+ free(uep->ue_value);
|
||
|
+ }
|
||
|
+ uep->ue_isset = 0;
|
||
|
+ uep->ue_priv = privileged_option;
|
||
|
+ uep->ue_source = option_source;
|
||
|
+ uep->ue_value = NULL;
|
||
|
+ curopt->flags &= ~OPT_NOPRINT;
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+user_unsetprint(opt, printer, arg)
|
||
|
+ option_t *opt;
|
||
|
+ printer_func printer;
|
||
|
+ void *arg;
|
||
|
+{
|
||
|
+ struct userenv *uep, *uepnext;
|
||
|
+
|
||
|
+ uepnext = userenv_list;
|
||
|
+ while (uepnext != NULL && uepnext->ue_isset)
|
||
|
+ uepnext = uepnext->ue_next;
|
||
|
+ while ((uep = uepnext) != NULL) {
|
||
|
+ uepnext = uep->ue_next;
|
||
|
+ while (uepnext != NULL && uepnext->ue_isset)
|
||
|
+ uepnext = uepnext->ue_next;
|
||
|
+ (*printer)(arg, "%s", uep->ue_name);
|
||
|
+ if (uepnext != NULL)
|
||
|
+ (*printer)(arg, "\t\t# (from %s)\n%s ", uep->ue_source, opt->name);
|
||
|
+ else
|
||
|
+ opt->source = uep->ue_source;
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git ppp-2.4.5-release/pppd/pppd.8 ppp-2.4.5/pppd/pppd.8
|
||
|
index b7adc77..7ad24c5 100644
|
||
|
--- ppp-2.4.5-release/pppd/pppd.8
|
||
|
+++ ppp-2.4.5/pppd/pppd.8
|
||
|
@@ -1018,6 +1018,13 @@ Authentication Protocol] authentication.
|
||
|
Require the peer to authenticate itself using PAP [Password
|
||
|
Authentication Protocol] authentication.
|
||
|
.TP
|
||
|
+.B set \fIname\fR=\fIvalue
|
||
|
+Set an environment variable for scripts that are invoked by pppd.
|
||
|
+When set by a privileged source, the variable specified by \fIname\fR
|
||
|
+cannot be changed by options contained in an unprivileged source. See
|
||
|
+also the \fIunset\fR option and the environment described in
|
||
|
+\fISCRIPTS\fR.
|
||
|
+.TP
|
||
|
.B show\-password
|
||
|
When logging the contents of PAP packets, this option causes pppd to
|
||
|
show the password string in the log message.
|
||
|
@@ -1058,6 +1065,13 @@ under Linux and FreeBSD 2.2.8 and later.
|
||
|
Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound
|
||
|
connections.
|
||
|
.TP
|
||
|
+.B unset \fIname
|
||
|
+Remove a variable from the environment variable for scripts that are
|
||
|
+invoked by pppd. When specified by a privileged source, the variable
|
||
|
+\fIname\fR cannot be set by options contained in an unprivileged
|
||
|
+source. See also the \fIset\fR option and the environment described
|
||
|
+in \fISCRIPTS\fR.
|
||
|
+.TP
|
||
|
.B updetach
|
||
|
With this option, pppd will detach from its controlling terminal once
|
||
|
it has successfully established the ppp connection (to the point where
|
||
|
diff --git ppp-2.4.5-release/pppd/pppd.h ppp-2.4.5/pppd/pppd.h
|
||
|
index cf9840a..936cc60 100644
|
||
|
--- ppp-2.4.5-release/pppd/pppd.h
|
||
|
+++ ppp-2.4.5/pppd/pppd.h
|
||
|
@@ -139,7 +139,7 @@ typedef struct {
|
||
|
#define OPT_INITONLY 0x4000000 /* option can only be set in init phase */
|
||
|
#define OPT_DEVEQUIV 0x8000000 /* equiv to device name */
|
||
|
#define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV)
|
||
|
-#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */
|
||
|
+#define OPT_A2PRINTER 0x10000000 /* *addr2 printer_func to print option */
|
||
|
#define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */
|
||
|
#define OPT_NOPRINT 0x40000000 /* don't print this option at all */
|
||
|
|
||
|
@@ -199,6 +199,7 @@ struct epdisc {
|
||
|
#define EPD_PHONENUM 5
|
||
|
|
||
|
typedef void (*notify_func) __P((void *, int));
|
||
|
+typedef void (*printer_func) __P((void *, char *, ...));
|
||
|
|
||
|
struct notifier {
|
||
|
struct notifier *next;
|
||
|
@@ -406,8 +407,7 @@ struct protent {
|
||
|
/* Close the protocol */
|
||
|
void (*close) __P((int unit, char *reason));
|
||
|
/* Print a packet in readable form */
|
||
|
- int (*printpkt) __P((u_char *pkt, int len,
|
||
|
- void (*printer) __P((void *, char *, ...)),
|
||
|
+ int (*printpkt) __P((u_char *pkt, int len, printer_func printer,
|
||
|
void *arg));
|
||
|
/* Process a received data packet */
|
||
|
void (*datainput) __P((int unit, u_char *pkt, int len));
|
||
|
@@ -461,6 +461,21 @@ struct channel {
|
||
|
extern struct channel *the_channel;
|
||
|
|
||
|
/*
|
||
|
+ * This structure contains environment variables that are set or unset
|
||
|
+ * by the user.
|
||
|
+ */
|
||
|
+struct userenv {
|
||
|
+ struct userenv *ue_next;
|
||
|
+ char *ue_value; /* value (set only) */
|
||
|
+ bool ue_isset; /* 1 for set, 0 for unset */
|
||
|
+ bool ue_priv; /* from privileged source */
|
||
|
+ const char *ue_source; /* source name */
|
||
|
+ char ue_name[1]; /* variable name */
|
||
|
+};
|
||
|
+
|
||
|
+extern struct userenv *userenv_list;
|
||
|
+
|
||
|
+/*
|
||
|
* Prototypes.
|
||
|
*/
|
||
|
|
||
|
@@ -504,8 +519,8 @@ void tty_init __P((void));
|
||
|
/* Procedures exported from utils.c. */
|
||
|
void log_packet __P((u_char *, int, char *, int));
|
||
|
/* Format a packet and log it with syslog */
|
||
|
-void print_string __P((char *, int, void (*) (void *, char *, ...),
|
||
|
- void *)); /* Format a string for output */
|
||
|
+void print_string __P((char *, int, printer_func, void *));
|
||
|
+ /* Format a string for output */
|
||
|
int slprintf __P((char *, int, char *, ...)); /* sprintf++ */
|
||
|
int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */
|
||
|
size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */
|
||
|
@@ -691,7 +706,7 @@ void add_options __P((option_t *)); /* Add extra options */
|
||
|
void check_options __P((void)); /* check values after all options parsed */
|
||
|
int override_value __P((const char *, int, const char *));
|
||
|
/* override value if permitted by priority */
|
||
|
-void print_options __P((void (*) __P((void *, char *, ...)), void *));
|
||
|
+void print_options __P((printer_func, void *));
|
||
|
/* print out values of all options */
|
||
|
|
||
|
int parse_dotted_ip __P((char *, u_int32_t *));
|
||
|
diff --git ppp-2.4.5-release/pppd/utils.c ppp-2.4.5/pppd/utils.c
|
||
|
index 062b17e..5c9ba64 100644
|
||
|
--- ppp-2.4.5-release/pppd/utils.c
|
||
|
+++ ppp-2.4.5/pppd/utils.c
|
||
|
@@ -68,8 +68,7 @@ extern char *strerror();
|
||
|
static void logit __P((int, char *, va_list));
|
||
|
static void log_write __P((int, char *));
|
||
|
static void vslp_printer __P((void *, char *, ...));
|
||
|
-static void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
|
||
|
- void *));
|
||
|
+static void format_packet __P((u_char *, int, printer_func, void *));
|
||
|
|
||
|
struct buffer_info {
|
||
|
char *ptr;
|
||
|
@@ -475,7 +474,7 @@ static void
|
||
|
format_packet(p, len, printer, arg)
|
||
|
u_char *p;
|
||
|
int len;
|
||
|
- void (*printer) __P((void *, char *, ...));
|
||
|
+ printer_func printer;
|
||
|
void *arg;
|
||
|
{
|
||
|
int i, n;
|
||
|
@@ -613,7 +612,7 @@ void
|
||
|
print_string(p, len, printer, arg)
|
||
|
char *p;
|
||
|
int len;
|
||
|
- void (*printer) __P((void *, char *, ...));
|
||
|
+ printer_func printer;
|
||
|
void *arg;
|
||
|
{
|
||
|
int c;
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From 2b4ea140432eeba5a007c0d4e6236bd0e0c12ba4 Mon Sep 17 00:00:00 2001
|
||
|
From: James Carlson <carlsonj@workingcode.com>
|
||
|
Date: Mon, 23 Aug 2010 10:01:48 -0400
|
||
|
Subject: [PATCH 6/9] Nit: use _exit when exec fails and restrict values to 0-255 per POSIX.
|
||
|
|
||
|
---
|
||
|
pppd/main.c | 4 ++--
|
||
|
1 files changed, 2 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/main.c ppp-2.4.5/pppd/main.c
|
||
|
index 1b513ca..6e7378b 100644
|
||
|
--- ppp-2.4.5-release/pppd/main.c
|
||
|
+++ ppp-2.4.5/pppd/main.c
|
||
|
@@ -1719,7 +1719,7 @@ device_script(program, in, out, dont_wait)
|
||
|
update_system_environment();
|
||
|
execl("/bin/sh", "sh", "-c", program, (char *)0);
|
||
|
perror("pppd: could not exec /bin/sh");
|
||
|
- exit(99);
|
||
|
+ _exit(99);
|
||
|
/* NOTREACHED */
|
||
|
}
|
||
|
|
||
|
@@ -1841,7 +1841,7 @@ run_program(prog, args, must_exist, done, arg, wait)
|
||
|
syslog(LOG_ERR, "Can't execute %s: %m", prog);
|
||
|
closelog();
|
||
|
}
|
||
|
- _exit(-1);
|
||
|
+ _exit(99);
|
||
|
}
|
||
|
|
||
|
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From 3089132cdf5b58dbdfc2daf08ec5c08eb47f8aca Mon Sep 17 00:00:00 2001
|
||
|
From: James Carlson <carlsonj@workingcode.com>
|
||
|
Date: Mon, 23 Aug 2010 10:03:07 -0400
|
||
|
Subject: [PATCH 7/9] Fix quote handling in configuration files to be more like shell quoting.
|
||
|
|
||
|
The specific case that confused a user was:
|
||
|
ROUTES="216.220.192.0/20 10.0.100.0/24"
|
||
|
which was interpreted as two separate words, merely because the first quote
|
||
|
mark was in the middle of a word.
|
||
|
---
|
||
|
pppd/options.c | 44 ++++++++++++++++++++++----------------------
|
||
|
1 files changed, 22 insertions(+), 22 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/options.c ppp-2.4.5/pppd/options.c
|
||
|
index 434ab95..008b482 100644
|
||
|
--- ppp-2.4.5-release/pppd/options.c
|
||
|
+++ ppp-2.4.5/pppd/options.c
|
||
|
@@ -1146,6 +1146,7 @@ getword(f, word, newlinep, filename)
|
||
|
len = 0;
|
||
|
escape = 0;
|
||
|
comment = 0;
|
||
|
+ quoted = 0;
|
||
|
|
||
|
/*
|
||
|
* First skip white-space and comments.
|
||
|
@@ -1204,15 +1205,6 @@ getword(f, word, newlinep, filename)
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * Save the delimiter for quoted strings.
|
||
|
- */
|
||
|
- if (!escape && (c == '"' || c == '\'')) {
|
||
|
- quoted = c;
|
||
|
- c = getc(f);
|
||
|
- } else
|
||
|
- quoted = 0;
|
||
|
-
|
||
|
- /*
|
||
|
* Process characters until the end of the word.
|
||
|
*/
|
||
|
while (c != EOF) {
|
||
|
@@ -1300,29 +1292,34 @@ getword(f, word, newlinep, filename)
|
||
|
if (!got)
|
||
|
c = getc(f);
|
||
|
continue;
|
||
|
-
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * Not escaped: see if we've reached the end of the word.
|
||
|
+ * Backslash starts a new escape sequence.
|
||
|
*/
|
||
|
- if (quoted) {
|
||
|
- if (c == quoted)
|
||
|
- break;
|
||
|
- } else {
|
||
|
- if (isspace(c) || c == '#') {
|
||
|
- ungetc (c, f);
|
||
|
- break;
|
||
|
- }
|
||
|
+ if (c == '\\') {
|
||
|
+ escape = 1;
|
||
|
+ c = getc(f);
|
||
|
+ continue;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * Backslash starts an escape sequence.
|
||
|
+ * Not escaped: check for the start or end of a quoted
|
||
|
+ * section and see if we've reached the end of the word.
|
||
|
*/
|
||
|
- if (c == '\\') {
|
||
|
- escape = 1;
|
||
|
+ if (quoted) {
|
||
|
+ if (c == quoted) {
|
||
|
+ quoted = 0;
|
||
|
+ c = getc(f);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ } else if (c == '"' || c == '\'') {
|
||
|
+ quoted = c;
|
||
|
c = getc(f);
|
||
|
continue;
|
||
|
+ } else if (isspace(c) || c == '#') {
|
||
|
+ ungetc (c, f);
|
||
|
+ break;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
@@ -1351,6 +1348,9 @@ getword(f, word, newlinep, filename)
|
||
|
*/
|
||
|
if (len == 0)
|
||
|
return 0;
|
||
|
+ if (quoted)
|
||
|
+ option_error("warning: quoted word runs to end of file (%.20s...)",
|
||
|
+ filename, word);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From fd1dcdf758418f040da3ed801ab001b5e46854e7 Mon Sep 17 00:00:00 2001
|
||
|
From: Simon Arlott <simon.arlott.org.uk>
|
||
|
Date: Tue, 4 May 2010 20:06:06 +0100
|
||
|
Subject: [PATCH 8/9] rp-pppoe: allow MTU to be increased up to 1500
|
||
|
|
||
|
The ethernet data limit on rp-pppoe has been increased to 1508 to
|
||
|
allow an MTU of 1500 to be used. To prevent problems the interface
|
||
|
MTU is checked and used to lower the configured MTU/MRU.
|
||
|
|
||
|
If MIN(MTU/MRU) is > 1492, PPP-Max-Payload is added to PADI and
|
||
|
PADR. If PPP-Max-Payload is received in PADO or PADS, it will be
|
||
|
used to lower the configured MTU/MRU as required.
|
||
|
|
||
|
The MTU/MRU settings are stored and reloaded whenever a connection
|
||
|
is made, to allow for the peer or interface MTU/MRU to increase if
|
||
|
used with persist option.
|
||
|
|
||
|
Conforming to RFC4638, if no PPP-Max-Payload is received, the
|
||
|
negotiated MRU will be limited to 1492.
|
||
|
---
|
||
|
pppd/plugins/rp-pppoe/common.c | 5 ++-
|
||
|
pppd/plugins/rp-pppoe/discovery.c | 65 +++++++++++++++++++++++++++++++
|
||
|
pppd/plugins/rp-pppoe/plugin.c | 30 ++++++++++++++
|
||
|
pppd/plugins/rp-pppoe/pppoe-discovery.c | 2 +-
|
||
|
pppd/plugins/rp-pppoe/pppoe.h | 22 ++++++++--
|
||
|
5 files changed, 118 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/common.c ppp-2.4.5/pppd/plugins/rp-pppoe/common.c
|
||
|
index a49efe7..3b8e014 100644
|
||
|
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/common.c
|
||
|
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/common.c
|
||
|
@@ -58,7 +58,7 @@ parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra)
|
||
|
}
|
||
|
|
||
|
/* Do some sanity checks on packet */
|
||
|
- if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */
|
||
|
+ if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */
|
||
|
error("Invalid PPPoE packet length (%u)", len);
|
||
|
return -1;
|
||
|
}
|
||
|
@@ -246,6 +246,9 @@ void pppoe_printpkt(PPPoEPacket *packet,
|
||
|
case TAG_RELAY_SESSION_ID:
|
||
|
printer(arg, "relay-session-id");
|
||
|
break;
|
||
|
+ case TAG_PPP_MAX_PAYLOAD:
|
||
|
+ printer(arg, "PPP-max-payload");
|
||
|
+ break;
|
||
|
case TAG_SERVICE_NAME_ERROR:
|
||
|
printer(arg, "service-name-error");
|
||
|
text = 1;
|
||
|
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/discovery.c ppp-2.4.5/pppd/plugins/rp-pppoe/discovery.c
|
||
|
index 6e25ae7..a856490 100644
|
||
|
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/discovery.c
|
||
|
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/discovery.c
|
||
|
@@ -14,6 +14,8 @@ static char const RCSID[] =
|
||
|
#define _GNU_SOURCE 1
|
||
|
#include "pppoe.h"
|
||
|
#include "pppd/pppd.h"
|
||
|
+#include "pppd/fsm.h"
|
||
|
+#include "pppd/lcp.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
@@ -110,6 +112,7 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data,
|
||
|
{
|
||
|
struct PacketCriteria *pc = (struct PacketCriteria *) extra;
|
||
|
PPPoEConnection *conn = pc->conn;
|
||
|
+ UINT16_t mru;
|
||
|
int i;
|
||
|
|
||
|
switch(type) {
|
||
|
@@ -140,6 +143,19 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data,
|
||
|
conn->relayId.length = htons(len);
|
||
|
memcpy(conn->relayId.payload, data, len);
|
||
|
break;
|
||
|
+ case TAG_PPP_MAX_PAYLOAD:
|
||
|
+ if (len == sizeof(mru)) {
|
||
|
+ memcpy(&mru, data, sizeof(mru));
|
||
|
+ mru = ntohs(mru);
|
||
|
+ if (mru >= ETH_PPPOE_MTU) {
|
||
|
+ if (lcp_allowoptions[0].mru > mru)
|
||
|
+ lcp_allowoptions[0].mru = mru;
|
||
|
+ if (lcp_wantoptions[0].mru > mru)
|
||
|
+ lcp_wantoptions[0].mru = mru;
|
||
|
+ conn->seenMaxPayload = 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ break;
|
||
|
case TAG_SERVICE_NAME_ERROR:
|
||
|
error("PADO: Service-Name-Error: %.*s", (int) len, data);
|
||
|
conn->error = 1;
|
||
|
@@ -172,10 +188,24 @@ parsePADSTags(UINT16_t type, UINT16_t len, unsigned char *data,
|
||
|
void *extra)
|
||
|
{
|
||
|
PPPoEConnection *conn = (PPPoEConnection *) extra;
|
||
|
+ UINT16_t mru;
|
||
|
switch(type) {
|
||
|
case TAG_SERVICE_NAME:
|
||
|
dbglog("PADS: Service-Name: '%.*s'", (int) len, data);
|
||
|
break;
|
||
|
+ case TAG_PPP_MAX_PAYLOAD:
|
||
|
+ if (len == sizeof(mru)) {
|
||
|
+ memcpy(&mru, data, sizeof(mru));
|
||
|
+ mru = ntohs(mru);
|
||
|
+ if (mru >= ETH_PPPOE_MTU) {
|
||
|
+ if (lcp_allowoptions[0].mru > mru)
|
||
|
+ lcp_allowoptions[0].mru = mru;
|
||
|
+ if (lcp_wantoptions[0].mru > mru)
|
||
|
+ lcp_wantoptions[0].mru = mru;
|
||
|
+ conn->seenMaxPayload = 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ break;
|
||
|
case TAG_SERVICE_NAME_ERROR:
|
||
|
error("PADS: Service-Name-Error: %.*s", (int) len, data);
|
||
|
conn->error = 1;
|
||
|
@@ -259,6 +289,19 @@ sendPADI(PPPoEConnection *conn)
|
||
|
plen += sizeof(pid) + TAG_HDR_SIZE;
|
||
|
}
|
||
|
|
||
|
+ /* Add our maximum MTU/MRU */
|
||
|
+ if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) {
|
||
|
+ PPPoETag maxPayload;
|
||
|
+ UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru));
|
||
|
+ maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD);
|
||
|
+ maxPayload.length = htons(sizeof(mru));
|
||
|
+ memcpy(maxPayload.payload, &mru, sizeof(mru));
|
||
|
+ CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE);
|
||
|
+ memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE);
|
||
|
+ cursor += sizeof(mru) + TAG_HDR_SIZE;
|
||
|
+ plen += sizeof(mru) + TAG_HDR_SIZE;
|
||
|
+ }
|
||
|
+
|
||
|
packet.length = htons(plen);
|
||
|
|
||
|
sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE));
|
||
|
@@ -289,6 +332,7 @@ waitForPADO(PPPoEConnection *conn, int timeout)
|
||
|
pc.serviceNameOK = (conn->serviceName) ? 0 : 1;
|
||
|
pc.seenACName = 0;
|
||
|
pc.seenServiceName = 0;
|
||
|
+ conn->seenMaxPayload = 0;
|
||
|
conn->error = 0;
|
||
|
|
||
|
do {
|
||
|
@@ -413,6 +457,19 @@ sendPADR(PPPoEConnection *conn)
|
||
|
plen += sizeof(pid) + TAG_HDR_SIZE;
|
||
|
}
|
||
|
|
||
|
+ /* Add our maximum MTU/MRU */
|
||
|
+ if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) {
|
||
|
+ PPPoETag maxPayload;
|
||
|
+ UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru));
|
||
|
+ maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD);
|
||
|
+ maxPayload.length = htons(sizeof(mru));
|
||
|
+ memcpy(maxPayload.payload, &mru, sizeof(mru));
|
||
|
+ CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE);
|
||
|
+ memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE);
|
||
|
+ cursor += sizeof(mru) + TAG_HDR_SIZE;
|
||
|
+ plen += sizeof(mru) + TAG_HDR_SIZE;
|
||
|
+ }
|
||
|
+
|
||
|
/* Copy cookie and relay-ID if needed */
|
||
|
if (conn->cookie.type) {
|
||
|
CHECK_ROOM(cursor, packet.payload,
|
||
|
@@ -566,6 +623,14 @@ discovery(PPPoEConnection *conn)
|
||
|
timeout *= 2;
|
||
|
} while (conn->discoveryState == STATE_SENT_PADR);
|
||
|
|
||
|
+ if (!conn->seenMaxPayload) {
|
||
|
+ /* RFC 4638: MUST limit MTU/MRU to 1492 */
|
||
|
+ if (lcp_allowoptions[0].mru > ETH_PPPOE_MTU)
|
||
|
+ lcp_allowoptions[0].mru = ETH_PPPOE_MTU;
|
||
|
+ if (lcp_wantoptions[0].mru > ETH_PPPOE_MTU)
|
||
|
+ lcp_wantoptions[0].mru = ETH_PPPOE_MTU;
|
||
|
+ }
|
||
|
+
|
||
|
/* We're done. */
|
||
|
conn->discoveryState = STATE_SESSION;
|
||
|
return;
|
||
|
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
|
||
|
index 9bd6643..97011aa 100644
|
||
|
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c
|
||
|
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
|
||
|
@@ -130,6 +130,31 @@ static int
|
||
|
PPPOEConnectDevice(void)
|
||
|
{
|
||
|
struct sockaddr_pppox sp;
|
||
|
+ struct ifreq ifr;
|
||
|
+ int s;
|
||
|
+
|
||
|
+ /* Restore configuration */
|
||
|
+ lcp_allowoptions[0].mru = conn->mtu;
|
||
|
+ lcp_wantoptions[0].mru = conn->mru;
|
||
|
+
|
||
|
+ /* Update maximum MRU */
|
||
|
+ s = socket(AF_INET, SOCK_DGRAM, 0);
|
||
|
+ if (s < 0) {
|
||
|
+ error("Can't get MTU for %s: %m", conn->ifName);
|
||
|
+ goto errout;
|
||
|
+ }
|
||
|
+ strncpy(ifr.ifr_name, conn->ifName, sizeof(ifr.ifr_name));
|
||
|
+ if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
|
||
|
+ error("Can't get MTU for %s: %m", conn->ifName);
|
||
|
+ close(s);
|
||
|
+ goto errout;
|
||
|
+ }
|
||
|
+ close(s);
|
||
|
+
|
||
|
+ if (lcp_allowoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
|
||
|
+ lcp_allowoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
|
||
|
+ if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
|
||
|
+ lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
|
||
|
|
||
|
conn->acName = acName;
|
||
|
conn->serviceName = pppd_pppoe_service;
|
||
|
@@ -163,6 +188,7 @@ PPPOEConnectDevice(void)
|
||
|
error("Failed to create PPPoE socket: %m");
|
||
|
goto errout;
|
||
|
}
|
||
|
+
|
||
|
sp.sa_family = AF_PPPOX;
|
||
|
sp.sa_protocol = PX_PROTO_OE;
|
||
|
sp.sa_addr.pppoe.sid = conn->session;
|
||
|
@@ -381,6 +407,10 @@ void pppoe_check_options(void)
|
||
|
if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU)
|
||
|
lcp_wantoptions[0].mru = MAX_PPPOE_MTU;
|
||
|
|
||
|
+ /* Save configuration */
|
||
|
+ conn->mtu = lcp_allowoptions[0].mru;
|
||
|
+ conn->mru = lcp_wantoptions[0].mru;
|
||
|
+
|
||
|
ccp_allowoptions[0].deflate = 0;
|
||
|
ccp_wantoptions[0].deflate = 0;
|
||
|
|
||
|
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe-discovery.c ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c
|
||
|
index 318f858..3d3bf4e 100644
|
||
|
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe-discovery.c
|
||
|
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c
|
||
|
@@ -277,7 +277,7 @@ parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra)
|
||
|
}
|
||
|
|
||
|
/* Do some sanity checks on packet */
|
||
|
- if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */
|
||
|
+ if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */
|
||
|
fprintf(stderr, "Invalid PPPoE packet length (%u)\n", len);
|
||
|
return -1;
|
||
|
}
|
||
|
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe.h ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe.h
|
||
|
index 3dba439..9ab2eee 100644
|
||
|
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe.h
|
||
|
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe.h
|
||
|
@@ -129,6 +129,7 @@ extern UINT16_t Eth_PPPOE_Session;
|
||
|
#define TAG_AC_COOKIE 0x0104
|
||
|
#define TAG_VENDOR_SPECIFIC 0x0105
|
||
|
#define TAG_RELAY_SESSION_ID 0x0110
|
||
|
+#define TAG_PPP_MAX_PAYLOAD 0x0120
|
||
|
#define TAG_SERVICE_NAME_ERROR 0x0201
|
||
|
#define TAG_AC_SYSTEM_ERROR 0x0202
|
||
|
#define TAG_GENERIC_ERROR 0x0203
|
||
|
@@ -167,6 +168,13 @@ extern UINT16_t Eth_PPPOE_Session;
|
||
|
#define IPV4ALEN 4
|
||
|
#define SMALLBUF 256
|
||
|
|
||
|
+/* There are other fixed-size buffers preventing
|
||
|
+ this from being increased to 16110. The buffer
|
||
|
+ sizes would need to be properly de-coupled from
|
||
|
+ the default MRU. For now, getting up to 1500 is
|
||
|
+ enough. */
|
||
|
+#define ETH_JUMBO_LEN 1508
|
||
|
+
|
||
|
/* A PPPoE Packet, including Ethernet headers */
|
||
|
typedef struct PPPoEPacketStruct {
|
||
|
struct ethhdr ethHdr; /* Ethernet header */
|
||
|
@@ -174,7 +182,7 @@ typedef struct PPPoEPacketStruct {
|
||
|
unsigned int code:8; /* PPPoE code */
|
||
|
unsigned int session:16; /* PPPoE session */
|
||
|
unsigned int length:16; /* Payload length */
|
||
|
- unsigned char payload[ETH_DATA_LEN]; /* A bit of room to spare */
|
||
|
+ unsigned char payload[ETH_JUMBO_LEN]; /* A bit of room to spare */
|
||
|
} PPPoEPacket;
|
||
|
|
||
|
#define PPPOE_VER(vt) ((vt) >> 4)
|
||
|
@@ -184,15 +192,18 @@ typedef struct PPPoEPacketStruct {
|
||
|
/* Header size of a PPPoE packet */
|
||
|
#define PPPOE_OVERHEAD 6 /* type, code, session, length */
|
||
|
#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD)
|
||
|
-#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD)
|
||
|
-#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - 2)
|
||
|
+#define MAX_PPPOE_PAYLOAD (ETH_JUMBO_LEN - PPPOE_OVERHEAD)
|
||
|
+#define PPP_OVERHEAD 2 /* protocol */
|
||
|
+#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - PPP_OVERHEAD)
|
||
|
+#define TOTAL_OVERHEAD (PPPOE_OVERHEAD + PPP_OVERHEAD)
|
||
|
+#define ETH_PPPOE_MTU (ETH_DATA_LEN - TOTAL_OVERHEAD)
|
||
|
|
||
|
/* PPPoE Tag */
|
||
|
|
||
|
typedef struct PPPoETagStruct {
|
||
|
unsigned int type:16; /* tag type */
|
||
|
unsigned int length:16; /* Length of payload */
|
||
|
- unsigned char payload[ETH_DATA_LEN]; /* A LOT of room to spare */
|
||
|
+ unsigned char payload[ETH_JUMBO_LEN]; /* A LOT of room to spare */
|
||
|
} PPPoETag;
|
||
|
/* Header size of a PPPoE tag */
|
||
|
#define TAG_HDR_SIZE 4
|
||
|
@@ -233,6 +244,9 @@ typedef struct PPPoEConnectionStruct {
|
||
|
int error; /* Error packet received */
|
||
|
int debug; /* Set to log packets sent and received */
|
||
|
int discoveryTimeout; /* Timeout for discovery packets */
|
||
|
+ int seenMaxPayload;
|
||
|
+ int mtu; /* Stored MTU */
|
||
|
+ int mru; /* Stored MRU */
|
||
|
} PPPoEConnection;
|
||
|
|
||
|
/* Structure used to determine acceptable PADO or PADS packet */
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|
||
|
|
||
|
From ae80bf833e48a6202f44a935a68083ae52ad3824 Mon Sep 17 00:00:00 2001
|
||
|
From: Ashok Rao <greatarbor@gmail.com>
|
||
|
Date: Sat, 11 Sep 2010 22:14:48 +1000
|
||
|
Subject: [PATCH 9/9] chat: Allow TIMEOUT value to come from environment variable
|
||
|
|
||
|
This allows the TIMEOUT value to be obtained from the environment
|
||
|
using the $ENVVAR syntax.
|
||
|
|
||
|
Signed-off-by: Paul Mackerras <paulus@samba.org>
|
||
|
---
|
||
|
chat/chat.c | 1 +
|
||
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
||
|
|
||
|
diff --git ppp-2.4.5-release/chat/chat.c ppp-2.4.5/chat/chat.c
|
||
|
index 0b88c27..710dba9 100644
|
||
|
--- ppp-2.4.5-release/chat/chat.c
|
||
|
+++ ppp-2.4.5/chat/chat.c
|
||
|
@@ -1167,6 +1167,7 @@ register char *s;
|
||
|
|
||
|
if (timeout_next) {
|
||
|
timeout_next = 0;
|
||
|
+ s = clean(s, 0);
|
||
|
timeout = atoi(s);
|
||
|
|
||
|
if (timeout <= 0)
|
||
|
--
|
||
|
1.6.6.2
|
||
|
|