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.
1270 lines
40 KiB
1270 lines
40 KiB
# --- 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 |
|
|
|
|