Initial commit

This commit is contained in:
domenico
2025-06-24 15:51:28 +02:00
commit 22031d9dab
6862 changed files with 1462554 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
--- a/pppd/plugins/radius/Makefile.linux
+++ b/pppd/plugins/radius/Makefile.linux
@@ -43,13 +43,13 @@ install: all
$(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
radius.so: radius.o libradiusclient.a
- $(CC) -o radius.so -shared radius.o libradiusclient.a
+ $(CC) $(COPTS) -o radius.so -shared radius.o libradiusclient.a
radattr.so: radattr.o
- $(CC) -o radattr.so -shared radattr.o
+ $(CC) $(COPTS) -o radattr.so -shared radattr.o
radrealms.so: radrealms.o
- $(CC) -o radrealms.so -shared radrealms.o
+ $(CC) $(COPTS) -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/rp-pppoe/Makefile.linux
+++ b/pppd/plugins/rp-pppoe/Makefile.linux
@@ -30,7 +30,7 @@ CFLAGS=$(COPTS) -I../../../include '-DRP
all: rp-pppoe.so pppoe-discovery
pppoe-discovery: pppoe-discovery.o debug.o
- $(CC) -o pppoe-discovery pppoe-discovery.o debug.o
+ $(CC) $(CFLAGS) -o pppoe-discovery pppoe-discovery.o debug.o
pppoe-discovery.o: pppoe-discovery.c
$(CC) $(CFLAGS) -c -o pppoe-discovery.o pppoe-discovery.c
@@ -39,7 +39,7 @@ debug.o: debug.c
$(CC) $(CFLAGS) -c -o debug.o debug.c
rp-pppoe.so: plugin.o discovery.o if.o common.o
- $(CC) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o
+ $(CC) $(CFLAGS) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o
install: all
$(INSTALL) -d -m 755 $(LIBDIR)

View File

@@ -0,0 +1,24 @@
configure: Allow overriding uname results
In a cross compile setting it makes no sense to rely on the "uname" values
reported by the build host system. This patch allows overriding the
"uname -r", "uname -s" and "uname -m" results with the "UNAME_R", "UNAME_S"
and "UNAME_M" environment variables.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/configure
+++ b/configure
@@ -8,9 +8,9 @@ SYSCONF=/etc
# if [ -d /NextApps ]; then
# system="NeXTStep"
# else
- system=`uname -s`
- release=`uname -r`
- arch=`uname -m`
+ system=${UNAME_S:-`uname -s`}
+ release=${UNAME_R:-`uname -r`}
+ arch=${UNAME_M:-`uname -m`}
# fi
state="unknown"

View File

@@ -0,0 +1,96 @@
pppd: Allow specifying ip-up and ip-down scripts
This patch implements the "ip-up-script" and "ip-down-script" options which
allow to specify the path of the ip-up and ip-down scripts to call.
These options default to _PATH_IPUP and _PATH_IPDOWN to retain the
existing behaviour.
The patch originated from the Debian project.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/ipcp.c
+++ b/pppd/ipcp.c
@@ -1958,7 +1958,7 @@ ipcp_up(f)
*/
if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
ipcp_script_state = s_up;
- ipcp_script(_PATH_IPUP, 0);
+ ipcp_script(path_ipup, 0);
}
}
@@ -2008,7 +2008,7 @@ ipcp_down(f)
/* Execute the ip-down script */
if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
ipcp_script_state = s_down;
- ipcp_script(_PATH_IPDOWN, 0);
+ ipcp_script(path_ipdown, 0);
}
}
@@ -2062,13 +2062,13 @@ ipcp_script_done(arg)
case s_up:
if (ipcp_fsm[0].state != OPENED) {
ipcp_script_state = s_down;
- ipcp_script(_PATH_IPDOWN, 0);
+ ipcp_script(path_ipdown, 0);
}
break;
case s_down:
if (ipcp_fsm[0].state == OPENED) {
ipcp_script_state = s_up;
- ipcp_script(_PATH_IPUP, 0);
+ ipcp_script(path_ipup, 0);
}
break;
}
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -316,6 +316,9 @@ main(argc, argv)
struct protent *protp;
char numbuf[16];
+ strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
+ strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
+
link_stats_valid = 0;
new_phase(PHASE_INITIALIZE);
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -114,6 +114,8 @@ char linkname[MAXPATHLEN]; /* logical na
bool tune_kernel; /* may alter kernel settings */
int connect_delay = 1000; /* wait this many ms after connect script */
int req_unit = -1; /* requested interface unit */
+char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
bool multilink = 0; /* Enable multilink operation */
char *bundle_name = NULL; /* bundle name for multilink */
bool dump_options; /* print out option values */
@@ -299,6 +301,13 @@ option_t general_options[] = {
"Unset user environment variable",
OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint },
+ { "ip-up-script", o_string, path_ipup,
+ "Set pathname of ip-up script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "ip-down-script", o_string, path_ipdown,
+ "Set pathname of ip-down script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+
#ifdef HAVE_MULTILINK
{ "multilink", o_bool, &multilink,
"Enable multilink operation", OPT_PRIO | 1 },
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -318,6 +318,8 @@ extern bool tune_kernel; /* May alter ke
extern int connect_delay; /* Time to delay after connect script */
extern int max_data_rate; /* max bytes/sec through charshunt */
extern int req_unit; /* interface unit number to use */
+extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
extern bool multilink; /* enable multilink operation */
extern bool noendpoint; /* don't send or accept endpt. discrim. */
extern char *bundle_name; /* bundle name for multilink */

View File

@@ -0,0 +1,28 @@
pppd: Close already open ppp descriptors
When using the kernel PPPoE driver in conjunction with the "persist" option,
the already open descriptor to /dev/ppp is not closed when the link is
reestablished. This eventually leads to high CPU load because the stray
descriptors are always reported as ready by select().
This patch closes the descriptor if it is already open when establishing a
new connection. It originated from the Debian project.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -458,6 +458,13 @@ int generic_establish_ppp (int fd)
if (new_style_driver) {
int flags;
+ /* if a ppp_fd is already open, close it first */
+ if(ppp_fd > 0) {
+ close(ppp_fd);
+ remove_fd(ppp_fd);
+ ppp_fd = -1;
+ }
+
/* Open an instance of /dev/ppp and connect the channel to it */
if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
error("Couldn't get channel number: %m");

View File

@@ -0,0 +1,23 @@
pppd: Fix creation of linkpidfile
When pppd is run without "nodetach" or with "updetach", the linkpidfile is
never created. The call to create_linkpidfile() is protected by a check for
linkpidfile[0] but this is only filled in when create_linkpidfile() is called.
This patch changes to code to allways uncondiationally call
create_linkpidfile(), it originated from the Debian project.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -773,8 +773,7 @@ detach()
/* update pid files if they have been written already */
if (pidfilename[0])
create_pidfile(pid);
- if (linkpidfile[0])
- create_linkpidfile(pid);
+ create_linkpidfile(pid);
exit(0); /* parent dies */
}
setsid();

View File

@@ -0,0 +1,172 @@
--- a/pppd/demand.c
+++ b/pppd/demand.c
@@ -36,6 +36,8 @@
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
+#include <unistd.h>
+#include <syslog.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -43,6 +45,8 @@
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#ifdef PPP_FILTER
#include <pcap-bpf.h>
#endif
@@ -221,6 +225,14 @@ loop_chars(p, n)
int c, rv;
rv = 0;
+
+/* check for synchronous connection... */
+
+ if ( (p[0] == 0xFF) && (p[1] == 0x03) ) {
+ rv = loop_frame(p,n);
+ return rv;
+ }
+
for (; n > 0; --n) {
c = *p++;
if (c == PPP_FLAG) {
@@ -299,17 +311,102 @@ loop_frame(frame, len)
* loopback, now that the real serial link is up.
*/
void
-demand_rexmit(proto)
+demand_rexmit(proto, newip)
int proto;
+ u_int32_t newip;
{
struct packet *pkt, *prev, *nextpkt;
+ unsigned short checksum;
+ unsigned short pkt_checksum = 0;
+ unsigned iphdr;
+ struct timeval tv;
+ char cv = 0;
+ char ipstr[16];
prev = NULL;
pkt = pend_q;
pend_q = NULL;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */
for (; pkt != NULL; pkt = nextpkt) {
nextpkt = pkt->next;
if (PPP_PROTOCOL(pkt->data) == proto) {
+ if ( (proto == PPP_IP) && newip ) {
+ /* Get old checksum */
+
+ iphdr = (pkt->data[4] & 15) << 2;
+ checksum = *((unsigned short *) (pkt->data+14));
+ if (checksum == 0xFFFF) {
+ checksum = 0;
+ }
+
+
+ if (pkt->data[13] == 17) {
+ pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr));
+ if (pkt_checksum) {
+ cv = 1;
+ if (pkt_checksum == 0xFFFF) {
+ pkt_checksum = 0;
+ }
+ }
+ else {
+ cv = 0;
+ }
+ }
+
+ if (pkt->data[13] == 6) {
+ pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr));
+ cv = 1;
+ if (pkt_checksum == 0xFFFF) {
+ pkt_checksum = 0;
+ }
+ }
+
+ /* Delete old Source-IP-Address */
+ checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ /* Change Source-IP-Address */
+ * ((u_int32_t *) (pkt->data + 16)) = newip;
+
+ /* Add new Source-IP-Address */
+ checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ /* Write new checksum */
+ if (!checksum) {
+ checksum = 0xFFFF;
+ }
+ *((unsigned short *) (pkt->data+14)) = checksum;
+ if (pkt->data[13] == 6) {
+ *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum;
+ }
+ if (cv && (pkt->data[13] == 17) ) {
+ *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum;
+ }
+
+ /* Log Packet */
+ strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16))));
+ if (pkt->data[13] == 1) {
+ syslog(LOG_INFO,"Open ICMP %s -> %s\n",
+ ipstr,
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20))));
+ } else {
+ syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n",
+ pkt->data[13] == 6 ? "TCP" : "UDP",
+ ipstr,
+ ntohs(*( (short *) (pkt->data+iphdr+4))),
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20))),
+ ntohs(*( (short *) (pkt->data+iphdr+6))));
+ }
+ }
output(0, pkt->data, pkt->length);
free(pkt);
} else {
--- a/pppd/ipcp.c
+++ b/pppd/ipcp.c
@@ -1883,7 +1883,7 @@ ipcp_up(f)
proxy_arp_set[f->unit] = 1;
}
- demand_rexmit(PPP_IP);
+ demand_rexmit(PPP_IP,go->ouraddr);
sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
} else {
--- a/pppd/ipv6cp.c
+++ b/pppd/ipv6cp.c
@@ -1232,7 +1232,7 @@ ipv6cp_up(f)
}
}
- demand_rexmit(PPP_IPV6);
+ demand_rexmit(PPP_IPV6,0);
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
} else {
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -585,7 +585,7 @@ void demand_conf __P((void)); /* config
void demand_block __P((void)); /* set all NPs to queue up packets */
void demand_unblock __P((void)); /* set all NPs to pass packets */
void demand_discard __P((void)); /* set all NPs to discard packets */
-void demand_rexmit __P((int)); /* retransmit saved frames for an NP */
+void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/
int loop_chars __P((unsigned char *, int)); /* process chars from loopback */
int loop_frame __P((unsigned char *, int)); /* should we bring link up? */

View File

@@ -0,0 +1,47 @@
pppd: Implement option to strip domain part from MS CHAP response
This patch implements a new boolean option "chapms-strip-domain" which
strips the leading domain part of the username in a received MS Chap
response.
When the option is set, all leading chars up to and including the last
backslash in the username are stripped. The option defaults to false.
The patch originated from the Debian project.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/chap-new.c
+++ b/pppd/chap-new.c
@@ -58,6 +58,7 @@ int (*chap_verify_hook)(char *name, char
int chap_timeout_time = 3;
int chap_max_transmits = 10;
int chap_rechallenge_time = 0;
+int chapms_strip_domain = 0;
/*
* Command-line options.
@@ -69,6 +70,8 @@ static option_t chap_option_list[] = {
"Set max #xmits for challenge", OPT_PRIO },
{ "chap-interval", o_int, &chap_rechallenge_time,
"Set interval for rechallenge", OPT_PRIO },
+ { "chapms-strip-domain", o_bool, &chapms_strip_domain,
+ "Strip the domain prefix before the Username", 1 },
{ NULL }
};
@@ -336,6 +339,14 @@ chap_handle_response(struct chap_server_
/* Null terminate and clean remote name. */
slprintf(rname, sizeof(rname), "%.*v", len, name);
name = rname;
+
+ /* strip the MS domain name */
+ if (chapms_strip_domain && strrchr(rname, '\\')) {
+ char tmp[MAXNAMELEN+1];
+
+ strcpy(tmp, strrchr(rname, '\\') + 1);
+ strcpy(rname, tmp);
+ }
}
if (chap_verify_hook)

View File

@@ -0,0 +1,25 @@
pppoatm: Allow wildcard ATM devices
When operating pppd's pppoatm plugin with an USB ADSL modem, e.g. an
Alcatel Speedtouch, the ATM device number might change when the modem is
reconnected to the USB port or when the host controller resets the USB
device.
This patch allows to specify the ATM device as wildcard which gives
enough flexibility to cope with changing device names.
The patch originated from the Debain project.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/plugins/pppoatm/pppoatm.c
+++ b/pppd/plugins/pppoatm/pppoatm.c
@@ -75,7 +75,7 @@ static int setdevname_pppoatm(const char
//info("PPPoATM setdevname_pppoatm: '%s'", cp);
memset(&addr, 0, sizeof addr);
if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr),
- T2A_PVC | T2A_NAME) < 0) {
+ T2A_PVC | T2A_NAME | T2A_WILDCARD) < 0) {
if(doit)
info("atm does not recognize: %s", cp);
return 0;

View File

@@ -0,0 +1,313 @@
pppd: Add "replacedefaultroute" and "noreplacedefaultroute" options
This patch implements two new options, "replacedefaultroute" to replace any
existing system default route when specified and "noreplacedefaultroute" to
disable the "replacedefaultroute" option, which is useful in multi user
environments where the administrator wants to allow users to dial pppd
connections but not allow them to change the system default route.
The patch originated from the Debian project.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/ipcp.c
+++ b/pppd/ipcp.c
@@ -198,6 +198,14 @@ static option_t ipcp_option_list[] = {
"disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
&ipcp_wantoptions[0].default_route },
+ { "replacedefaultroute", o_bool,
+ &ipcp_wantoptions[0].replace_default_route,
+ "Replace default route", 1
+ },
+ { "noreplacedefaultroute", o_bool,
+ &ipcp_allowoptions[0].replace_default_route,
+ "Never replace default route", OPT_A2COPY,
+ &ipcp_wantoptions[0].replace_default_route },
{ "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
"Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
{ "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
@@ -271,7 +279,7 @@ struct protent ipcp_protent = {
ip_active_pkt
};
-static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
+static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool));
static void ipcp_script __P((char *, int)); /* Run an up/down script */
static void ipcp_script_done __P((void *));
@@ -1761,7 +1769,8 @@ ip_demand_conf(u)
if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
return 0;
if (wo->default_route)
- if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
+ if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
+ wo->replace_default_route))
default_route_set[u] = 1;
if (wo->proxy_arp)
if (sifproxyarp(u, wo->hisaddr))
@@ -1849,7 +1858,8 @@ ipcp_up(f)
*/
if (demand) {
if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
- ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
+ ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
+ wo->replace_default_route);
if (go->ouraddr != wo->ouraddr) {
warn("Local IP address changed to %I", go->ouraddr);
script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
@@ -1874,7 +1884,8 @@ ipcp_up(f)
/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
- if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
+ wo->replace_default_route))
default_route_set[f->unit] = 1;
/* Make a proxy ARP entry if requested. */
@@ -1924,7 +1935,8 @@ ipcp_up(f)
/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
- if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
+ wo->replace_default_route))
default_route_set[f->unit] = 1;
/* Make a proxy ARP entry if requested. */
@@ -2002,7 +2014,7 @@ ipcp_down(f)
sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
sifdown(f->unit);
ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
- ipcp_hisoptions[f->unit].hisaddr);
+ ipcp_hisoptions[f->unit].hisaddr, 0);
}
/* Execute the ip-down script */
@@ -2018,16 +2030,25 @@ ipcp_down(f)
* proxy arp entries, etc.
*/
static void
-ipcp_clear_addrs(unit, ouraddr, hisaddr)
+ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute)
int unit;
u_int32_t ouraddr; /* local address */
u_int32_t hisaddr; /* remote address */
+ bool replacedefaultroute;
{
if (proxy_arp_set[unit]) {
cifproxyarp(unit, hisaddr);
proxy_arp_set[unit] = 0;
}
- if (default_route_set[unit]) {
+ /* If replacedefaultroute, sifdefaultroute will be called soon
+ * with replacedefaultroute set and that will overwrite the current
+ * default route. This is the case only when doing demand, otherwise
+ * during demand, this cifdefaultroute would restore the old default
+ * route which is not what we want in this case. In the non-demand
+ * case, we'll delete the default route and restore the old if there
+ * is one saved by an sifdefaultroute with replacedefaultroute.
+ */
+ if (!replacedefaultroute && default_route_set[unit]) {
cifdefaultroute(unit, ouraddr, hisaddr);
default_route_set[unit] = 0;
}
--- a/pppd/ipcp.h
+++ b/pppd/ipcp.h
@@ -70,6 +70,7 @@ typedef struct ipcp_options {
bool old_addrs; /* Use old (IP-Addresses) option? */
bool req_addr; /* Ask peer to send IP address? */
bool default_route; /* Assign default route through interface? */
+ bool replace_default_route; /* Replace default route through interface? */
bool proxy_arp; /* Make proxy ARP entry for peer? */
bool neg_vj; /* Van Jacobson Compression? */
bool old_vj; /* use old (short) form of VJ option? */
--- a/pppd/pppd.8
+++ b/pppd/pppd.8
@@ -121,6 +121,11 @@ the gateway, when IPCP negotiation is su
This entry is removed when the PPP connection is broken. This option
is privileged if the \fInodefaultroute\fR option has been specified.
.TP
+.B replacedefaultroute
+This option is a flag to the defaultroute option. If defaultroute is
+set and this flag is also set, pppd replaces an existing default route
+with the new default route.
+.TP
.B disconnect \fIscript
Execute the command specified by \fIscript\fR, by passing it to a
shell, after
@@ -734,7 +739,12 @@ disable both forms of hardware flow cont
.TP
.B nodefaultroute
Disable the \fIdefaultroute\fR option. The system administrator who
-wishes to prevent users from creating default routes with pppd
+wishes to prevent users from adding a default route with pppd
+can do so by placing this option in the /etc/ppp/options file.
+.TP
+.B noreplacedefaultroute
+Disable the \fIreplacedefaultroute\fR option. The system administrator who
+wishes to prevent users from replacing a default route with pppd
can do so by placing this option in the /etc/ppp/options file.
.TP
.B nodeflate
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -667,7 +667,7 @@ int sif6addr __P((int, eui64_t, eui64_t
int cif6addr __P((int, eui64_t, eui64_t));
/* Remove an IPv6 address from i/f */
#endif
-int sifdefaultroute __P((int, u_int32_t, u_int32_t));
+int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt));
/* Create default route through i/f */
int cifdefaultroute __P((int, u_int32_t, u_int32_t));
/* Delete default route through i/f */
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -207,6 +207,8 @@ static unsigned char inbuf[512]; /* buff
static int if_is_up; /* Interface has been marked up */
static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
static int have_default_route; /* Gateway for default route added */
+static struct rtentry old_def_rt; /* Old default route */
+static int default_rt_repl_rest; /* replace and restore old default rt */
static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
static char proxy_arp_dev[16]; /* Device for proxy arp entry */
static u_int32_t our_old_addr; /* for detecting address changes */
@@ -1552,6 +1554,9 @@ static int read_route_table(struct rtent
p = NULL;
}
+ SET_SA_FAMILY (rt->rt_dst, AF_INET);
+ SET_SA_FAMILY (rt->rt_gateway, AF_INET);
+
SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
@@ -1621,20 +1626,51 @@ int have_route_to(u_int32_t addr)
/********************************************************************
*
* sifdefaultroute - assign a default route through the address given.
- */
-
-int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
-{
- struct rtentry rt;
-
- if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
- if (rt.rt_flags & RTF_GATEWAY)
- error("not replacing existing default route via %I",
- SIN_ADDR(rt.rt_gateway));
- else
+ *
+ * If the global default_rt_repl_rest flag is set, then this function
+ * already replaced the original system defaultroute with some other
+ * route and it should just replace the current defaultroute with
+ * another one, without saving the current route. Use: demand mode,
+ * when pppd sets first a defaultroute it it's temporary ppp0 addresses
+ * and then changes the temporary addresses to the addresses for the real
+ * ppp connection when it has come up.
+ */
+
+int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
+{
+ struct rtentry rt, tmp_rt;
+ struct rtentry *del_rt = NULL;
+
+ if (default_rt_repl_rest) {
+ /* We have already reclaced the original defaultroute, if we
+ are called again, we will delete the current default route
+ and set the new default route in this function.
+ - this is normally only the case the doing demand: */
+ if (defaultroute_exists(&tmp_rt))
+ del_rt = &tmp_rt;
+ } else if (defaultroute_exists(&old_def_rt) &&
+ strcmp(old_def_rt.rt_dev, ifname) != 0) {
+ /* We did not yet replace an existing default route, let's
+ check if we should save and replace a default route: */
+ if (old_def_rt.rt_flags & RTF_GATEWAY) {
+ if (!replace) {
+ error("not replacing existing default route via %I",
+ SIN_ADDR(old_def_rt.rt_gateway));
+ return 0;
+ } else {
+ /* we need to copy rt_dev because we need it permanent too: */
+ char *tmp_dev = malloc(strlen(old_def_rt.rt_dev) + 1);
+ strcpy(tmp_dev, old_def_rt.rt_dev);
+ old_def_rt.rt_dev = tmp_dev;
+
+ notice("replacing old default route to %s [%I]",
+ old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
+ default_rt_repl_rest = 1;
+ del_rt = &old_def_rt;
+ }
+ } else
error("not replacing existing default route through %s",
- rt.rt_dev);
- return 0;
+ old_def_rt.rt_dev);
}
memset (&rt, 0, sizeof (rt));
@@ -1649,10 +1685,16 @@ int sifdefaultroute (int unit, u_int32_t
rt.rt_flags = RTF_UP;
if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
- if ( ! ok_error ( errno ))
+ if (!ok_error(errno))
error("default route ioctl(SIOCADDRT): %m");
return 0;
}
+ if (default_rt_repl_rest && del_rt)
+ if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
+ if (!ok_error(errno))
+ error("del old default route ioctl(SIOCDELRT): %m");
+ return 0;
+ }
have_default_route = 1;
return 1;
@@ -1683,11 +1725,21 @@ int cifdefaultroute (int unit, u_int32_t
rt.rt_flags = RTF_UP;
if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
if (still_ppp()) {
- if ( ! ok_error ( errno ))
+ if (!ok_error(errno))
error("default route ioctl(SIOCDELRT): %m");
return 0;
}
}
+ if (default_rt_repl_rest) {
+ notice("restoring old default route to %s [%I]",
+ old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
+ if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
+ if (!ok_error(errno))
+ error("restore default route ioctl(SIOCADDRT): %m");
+ return 0;
+ }
+ default_rt_repl_rest = 0;
+ }
return 1;
}
--- a/pppd/sys-solaris.c
+++ b/pppd/sys-solaris.c
@@ -2039,12 +2039,18 @@ cifaddr(u, o, h)
* sifdefaultroute - assign a default route through the address given.
*/
int
-sifdefaultroute(u, l, g)
+sifdefaultroute(u, l, g, replace)
int u;
u_int32_t l, g;
+ bool replace;
{
struct rtentry rt;
+ if (replace) {
+ error("replacedefaultroute not supported on this platform");
+ return 0;
+ }
+
#if defined(__USLC__)
g = l; /* use the local address as gateway */
#endif

View File

@@ -0,0 +1,95 @@
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
@@ -318,6 +318,8 @@ main(argc, 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
@@ -116,6 +116,8 @@ int connect_delay = 1000; /* wait this m
int req_unit = -1; /* requested interface unit */
char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
+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 */
@@ -308,6 +310,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
@@ -1269,7 +1269,7 @@ ipv6cp_up(f)
*/
if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) {
ipv6cp_script_state = s_up;
- ipv6cp_script(_PATH_IPV6UP);
+ ipv6cp_script(path_ipv6up);
}
}
@@ -1321,7 +1321,7 @@ ipv6cp_down(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);
}
}
@@ -1364,13 +1364,13 @@ ipv6cp_script_done(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
@@ -320,6 +320,8 @@ extern int max_data_rate; /* max bytes/s
extern int req_unit; /* interface unit number to use */
extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
+extern 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 */

View File

@@ -0,0 +1,56 @@
--- a/pppd/lcp.c
+++ b/pppd/lcp.c
@@ -73,6 +73,7 @@ static void lcp_delayed_up __P((void *))
*/
int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
+bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */
bool lax_recv = 0; /* accept control chars in asyncmap */
bool noendpoint = 0; /* don't send/accept endpoint discriminator */
@@ -151,6 +152,8 @@ static option_t lcp_option_list[] = {
OPT_PRIO },
{ "lcp-echo-interval", o_int, &lcp_echo_interval,
"Set time in seconds between LCP echo requests", OPT_PRIO },
+ { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive,
+ "Suppress LCP echo requests if traffic was received", 1 },
{ "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
"Set time in seconds between LCP retransmissions", OPT_PRIO },
{ "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
@@ -2331,6 +2334,22 @@ LcpSendEchoRequest (f)
}
}
+ /*
+ * If adaptive echos have been enabled, only send the echo request if
+ * no traffic was received since the last one.
+ */
+ if (lcp_echo_adaptive) {
+ static unsigned int last_pkts_in = 0;
+
+ update_link_stats(f->unit);
+ link_stats_valid = 0;
+
+ if (link_stats.pkts_in != last_pkts_in) {
+ last_pkts_in = link_stats.pkts_in;
+ return;
+ }
+ }
+
/*
* Make and send the echo request frame.
*/
--- a/pppd/pppd.8
+++ b/pppd/pppd.8
@@ -563,6 +563,11 @@ to 1) if the \fIproxyarp\fR option is us
dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to
1) in demand mode if the local address changes.
.TP
+.B lcp\-echo\-adaptive
+If this option is used with the \fIlcp\-echo\-failure\fR option then
+pppd will send LCP echo\-request frames only if no traffic was received
+from the peer since the last echo\-request was sent.
+.TP
.B lcp\-echo\-failure \fIn
If this option is given, pppd will presume the peer to be dead
if \fIn\fR LCP echo\-requests are sent without receiving a valid LCP

View File

@@ -0,0 +1,11 @@
--- a/pppd/plugins/rp-pppoe/config.h
+++ b/pppd/plugins/rp-pppoe/config.h
@@ -102,7 +102,7 @@
#define HAVE_NETPACKET_PACKET_H 1
/* Define if you have the <sys/cdefs.h> header file. */
-#define HAVE_SYS_CDEFS_H 1
+/* #undef HAVE_SYS_CDEFS_H */
/* Define if you have the <sys/dlpi.h> header file. */
/* #undef HAVE_SYS_DLPI_H */

View File

@@ -0,0 +1,23 @@
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -67,6 +67,9 @@
#define volatile
#endif
+#undef __P
+#define __P(args) args
+
#ifdef INET6
#include "eui64.h"
#endif
--- a/pppd/magic.h
+++ b/pppd/magic.h
@@ -42,6 +42,8 @@
* $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $
*/
+#include "pppd.h"
+
void magic_init __P((void)); /* Initialize the magic number generator */
u_int32_t magic __P((void)); /* Returns the next magic number */

View File

@@ -0,0 +1,40 @@
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -73,12 +73,12 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
-#include <sys/errno.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/sysmacros.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
@@ -102,22 +102,15 @@
#define MAX_ADDR_LEN 7
#endif
-#if __GLIBC__ >= 2
#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>
#include <netinet/if_ether.h>
-#else
-#include <linux/types.h>
-#include <linux/if.h>
-#include <linux/if_arp.h>
-#include <linux/route.h>
-#include <linux/if_ether.h>
-#endif
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <linux/sockios.h>
#include <linux/ppp_defs.h>
#include <linux/if_ppp.h>

View File

@@ -0,0 +1,11 @@
--- a/pppd/sha1.c
+++ b/pppd/sha1.c
@@ -18,7 +18,7 @@
#include <string.h>
#include <netinet/in.h> /* htonl() */
-#include <net/ppp_defs.h>
+#include "pppd.h"
#include "sha1.h"
static void

View File

@@ -0,0 +1,83 @@
--- a/pppd/plugins/rp-pppoe/pppoe.h
+++ b/pppd/plugins/rp-pppoe/pppoe.h
@@ -48,11 +48,7 @@
#endif
/* Ugly header files on some Linux boxes... */
-#if defined(HAVE_LINUX_IF_H)
-#include <linux/if.h>
-#elif defined(HAVE_NET_IF_H)
#include <net/if.h>
-#endif
#ifdef HAVE_NET_IF_TYPES_H
#include <net/if_types.h>
@@ -80,22 +76,8 @@ typedef unsigned long UINT32_t;
#error Could not find a 32-bit integer type
#endif
-#ifdef HAVE_LINUX_IF_ETHER_H
-#include <linux/if_ether.h>
-#endif
-
#include <netinet/in.h>
-
-#ifdef HAVE_NETINET_IF_ETHER_H
-#include <sys/types.h>
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifndef HAVE_SYS_DLPI_H
-#include <netinet/if_ether.h>
-#endif
-#endif
+#include <net/ethernet.h>
--- a/pppd/plugins/rp-pppoe/pppoe-discovery.c
+++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c
@@ -16,6 +16,7 @@
#include <string.h>
#include "pppoe.h"
+#include "pppd/pppd.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -717,6 +718,23 @@ char *xstrdup(const char *s)
return ret;
}
+void
+error(char *fmt, ...)
+{
+ va_list pvar;
+
+#if defined(__STDC__)
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ fprintf(stderr, fmt, pvar);
+ va_end(pvar);
+}
+
void usage(void)
{
fprintf(stderr, "Usage: pppoe-discovery [options]\n");
--- a/pppd/plugins/rp-pppoe/Makefile.linux
+++ b/pppd/plugins/rp-pppoe/Makefile.linux
@@ -33,7 +33,7 @@ pppoe-discovery: pppoe-discovery.o debug
$(CC) $(CFLAGS) -o pppoe-discovery pppoe-discovery.o debug.o
pppoe-discovery.o: pppoe-discovery.c
- $(CC) $(CFLAGS) -c -o pppoe-discovery.o pppoe-discovery.c
+ $(CC) $(CFLAGS) -I../../.. -c -o pppoe-discovery.o pppoe-discovery.c
debug.o: debug.c
$(CC) $(CFLAGS) -c -o debug.o debug.c

View File

@@ -0,0 +1,49 @@
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
@@ -48,7 +48,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
@@ -58,7 +58,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
HAS_SHADOW=y
#USE_PAM=y
@@ -80,7 +80,7 @@ MAXOCTETS=y
INCLUDE_DIRS= -I../include
-COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP
+COMPILE_FLAGS= -DHAVE_PATHS_H -DHAVE_MMAP
CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) '-DDESTDIR="@DESTDIR@"'
@@ -120,10 +120,10 @@ CFLAGS += -DHAS_SHADOW
#LIBS += -lshadow $(LIBS)
endif
-ifneq ($(wildcard /usr/include/crypt.h),)
+#ifneq ($(wildcard /usr/include/crypt.h),)
CFLAGS += -DHAVE_CRYPT_H=1
LIBS += -lcrypt
-endif
+#endif
ifdef USE_LIBUTIL
CFLAGS += -DHAVE_LOGWTMP=1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
build: Do not strip binaries on install
Strippign executables should be handled by the distro packaging, not by ppp
itself. This patch removes the "-s" (strip) switch from all "install" commands
in order to install unstripped binaries into the destination prefix.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/chat/Makefile.linux
+++ b/chat/Makefile.linux
@@ -25,7 +25,7 @@ chat.o: chat.c
install: chat
mkdir -p $(BINDIR) $(MANDIR)
- $(INSTALL) -s -c chat $(BINDIR)
+ $(INSTALL) -c chat $(BINDIR)
$(INSTALL) -c -m 644 chat.8 $(MANDIR)
clean:
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -102,7 +102,7 @@ ifdef USE_SRP
CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
LIBS += -lsrp -L/usr/local/ssl/lib -lcrypto
TARGETS += srp-entry
-EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
+EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry
MANPAGES += srp-entry.8
EXTRACLEAN += srp-entry.o
NEEDDES=y
@@ -208,7 +208,7 @@ all: $(TARGETS)
install: pppd
mkdir -p $(BINDIR) $(MANDIR)
$(EXTRAINSTALL)
- $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd
+ $(INSTALL) -c -m 555 pppd $(BINDIR)/pppd
if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \
chmod o-rx,u+s $(BINDIR)/pppd; fi
$(INSTALL) -c -m 444 pppd.8 $(MANDIR)
--- a/pppd/plugins/radius/Makefile.linux
+++ b/pppd/plugins/radius/Makefile.linux
@@ -36,9 +36,9 @@ all: $(PLUGIN)
install: all
$(INSTALL) -d -m 755 $(LIBDIR)
- $(INSTALL) -s -c -m 755 radius.so $(LIBDIR)
- $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR)
- $(INSTALL) -s -c -m 755 radrealms.so $(LIBDIR)
+ $(INSTALL) -c -m 755 radius.so $(LIBDIR)
+ $(INSTALL) -c -m 755 radattr.so $(LIBDIR)
+ $(INSTALL) -c -m 755 radrealms.so $(LIBDIR)
$(INSTALL) -c -m 444 pppd-radius.8 $(MANDIR)
$(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
--- a/pppd/plugins/rp-pppoe/Makefile.linux
+++ b/pppd/plugins/rp-pppoe/Makefile.linux
@@ -43,9 +43,9 @@ rp-pppoe.so: plugin.o discovery.o if.o c
install: all
$(INSTALL) -d -m 755 $(LIBDIR)
- $(INSTALL) -s -c -m 4550 rp-pppoe.so $(LIBDIR)
+ $(INSTALL) -c -m 4550 rp-pppoe.so $(LIBDIR)
$(INSTALL) -d -m 755 $(BINDIR)
- $(INSTALL) -s -c -m 555 pppoe-discovery $(BINDIR)
+ $(INSTALL) -c -m 555 pppoe-discovery $(BINDIR)
clean:
rm -f *.o *.so pppoe-discovery
--- a/pppdump/Makefile.linux
+++ b/pppdump/Makefile.linux
@@ -17,5 +17,5 @@ clean:
install:
mkdir -p $(BINDIR) $(MANDIR)
- $(INSTALL) -s -c pppdump $(BINDIR)
+ $(INSTALL) -c pppdump $(BINDIR)
$(INSTALL) -c -m 444 pppdump.8 $(MANDIR)
--- a/pppstats/Makefile.linux
+++ b/pppstats/Makefile.linux
@@ -22,7 +22,7 @@ all: pppstats
install: pppstats
-mkdir -p $(MANDIR)
- $(INSTALL) -s -c pppstats $(BINDIR)
+ $(INSTALL) -c pppstats $(BINDIR)
$(INSTALL) -c -m 444 pppstats.8 $(MANDIR)
pppstats: $(PPPSTATSRCS)

View File

@@ -0,0 +1,32 @@
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
@@ -12,7 +12,8 @@ VERSION = $(shell awk -F '"' '/VERSION/
INSTALL = install
PLUGIN=radius.so radattr.so radrealms.so
-CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
+COPTS = -O2
+CFLAGS=-I. -I../.. -I../../../include $(COPTS) -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
# Uncomment the next line to include support for Microsoft's
# MS-CHAP authentication protocol.
--- a/pppdump/Makefile.linux
+++ b/pppdump/Makefile.linux
@@ -2,7 +2,8 @@ DESTDIR = $(INSTROOT)@DESTDIR@
BINDIR = $(DESTDIR)/sbin
MANDIR = $(DESTDIR)/share/man/man8
-CFLAGS= -O -I../include/net
+COPTS = -O
+CFLAGS= $(COPTS) -I../include/net
OBJS = pppdump.o bsd-comp.o deflate.o zlib.o
INSTALL= install

View File

@@ -0,0 +1,72 @@
--- a/pppd/plugins/radius/config.c
+++ b/pppd/plugins/radius/config.c
@@ -369,31 +369,37 @@ static int test_config(char *filename)
}
#endif
+#if 0
if (rc_conf_int("login_tries") <= 0)
{
error("%s: login_tries <= 0 is illegal", filename);
return (-1);
}
+#endif
if (rc_conf_str("seqfile") == NULL)
{
error("%s: seqfile not specified", filename);
return (-1);
}
+#if 0
if (rc_conf_int("login_timeout") <= 0)
{
error("%s: login_timeout <= 0 is illegal", filename);
return (-1);
}
+#endif
if (rc_conf_str("mapfile") == NULL)
{
error("%s: mapfile not specified", filename);
return (-1);
}
+#if 0
if (rc_conf_str("nologin") == NULL)
{
error("%s: nologin not specified", filename);
return (-1);
}
+#endif
return 0;
}
--- a/pppd/plugins/radius/options.h
+++ b/pppd/plugins/radius/options.h
@@ -31,24 +31,21 @@ typedef struct _option {
static SERVER acctserver = {0};
static SERVER authserver = {0};
-int default_tries = 4;
-int default_timeout = 60;
-
static OPTION config_options[] = {
/* internally used options */
{"config_file", OT_STR, ST_UNDEF, NULL},
/* General options */
{"auth_order", OT_AUO, ST_UNDEF, NULL},
-{"login_tries", OT_INT, ST_UNDEF, &default_tries},
-{"login_timeout", OT_INT, ST_UNDEF, &default_timeout},
-{"nologin", OT_STR, ST_UNDEF, "/etc/nologin"},
-{"issue", OT_STR, ST_UNDEF, "/etc/radiusclient/issue"},
+{"login_tries", OT_INT, ST_UNDEF, NULL},
+{"login_timeout", OT_INT, ST_UNDEF, NULL},
+{"nologin", OT_STR, ST_UNDEF, NULL},
+{"issue", OT_STR, ST_UNDEF, NULL},
/* RADIUS specific options */
{"authserver", OT_SRV, ST_UNDEF, &authserver},
{"acctserver", OT_SRV, ST_UNDEF, &acctserver},
{"servers", OT_STR, ST_UNDEF, NULL},
{"dictionary", OT_STR, ST_UNDEF, NULL},
-{"login_radius", OT_STR, ST_UNDEF, "/usr/sbin/login.radius"},
+{"login_radius", OT_STR, ST_UNDEF, NULL},
{"seqfile", OT_STR, ST_UNDEF, NULL},
{"mapfile", OT_STR, ST_UNDEF, NULL},
{"default_realm", OT_STR, ST_UNDEF, NULL},

View File

@@ -0,0 +1,29 @@
pppd: Don't use exponential timeout in discovery phase
This patch removes the exponential timeout increase between PADO or PADS
discovery attempts.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/plugins/rp-pppoe/discovery.c
+++ b/pppd/plugins/rp-pppoe/discovery.c
@@ -644,7 +644,9 @@ discovery(PPPoEConnection *conn)
conn->discoveryState = STATE_SENT_PADI;
waitForPADO(conn, timeout);
+#if 0
timeout *= 2;
+#endif
} while (conn->discoveryState == STATE_SENT_PADI);
timeout = conn->discoveryTimeout;
@@ -659,7 +661,9 @@ discovery(PPPoEConnection *conn)
sendPADR(conn);
conn->discoveryState = STATE_SENT_PADR;
waitForPADS(conn, timeout);
+#if 0
timeout *= 2;
+#endif
} while (conn->discoveryState == STATE_SENT_PADR);
if (!conn->seenMaxPayload) {

View File

@@ -0,0 +1,94 @@
pppd: Watch out for time warps
On many embedded systems there is no battery backed RTC and a proper system
time only becomes available through NTP after establishing a connection.
When the clock suddenly jumps forward, the internal accounting (connect time)
is confused resulting in unreliable data.
This patch implements periodic clock checking to look for time warps, if one
is detected, the internal counters are adjusted accordingly.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -90,6 +90,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <sys/sysinfo.h>
#include "pppd.h"
#include "magic.h"
@@ -228,6 +229,7 @@ static struct subprocess *children;
/* Prototypes for procedures local to this file. */
+static void check_time(void);
static void setup_signals __P((void));
static void create_pidfile __P((int pid));
static void create_linkpidfile __P((int pid));
@@ -535,6 +537,7 @@ main(argc, argv)
info("Starting link");
}
+ check_time();
gettimeofday(&start_time, NULL);
script_unsetenv("CONNECT_TIME");
script_unsetenv("BYTES_SENT");
@@ -1267,6 +1270,36 @@ struct callout {
static struct callout *callout = NULL; /* Callout list */
static struct timeval timenow; /* Current time */
+static long uptime_diff = 0;
+static int uptime_diff_set = 0;
+
+static void check_time(void)
+{
+ long new_diff;
+ struct timeval t;
+ struct sysinfo i;
+ struct callout *p;
+
+ gettimeofday(&t, NULL);
+ sysinfo(&i);
+ new_diff = t.tv_sec - i.uptime;
+
+ if (!uptime_diff_set) {
+ uptime_diff = new_diff;
+ uptime_diff_set = 1;
+ return;
+ }
+
+ if ((new_diff - 5 > uptime_diff) || (new_diff + 5 < uptime_diff)) {
+ /* system time has changed, update counters and timeouts */
+ info("System time change detected.");
+ start_time.tv_sec += new_diff - uptime_diff;
+
+ for (p = callout; p != NULL; p = p->c_next)
+ p->c_time.tv_sec += new_diff - uptime_diff;
+ }
+ uptime_diff = new_diff;
+}
/*
* timeout - Schedule a timeout.
@@ -1337,6 +1370,8 @@ calltimeout()
{
struct callout *p;
+ check_time();
+
while (callout != NULL) {
p = callout;
@@ -1364,6 +1399,8 @@ timeleft(tvp)
{
if (callout == NULL)
return NULL;
+
+ check_time();
gettimeofday(&timenow, NULL);
tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;

View File

@@ -0,0 +1,25 @@
pppd: Cap MTU to the user configured value
This patchs caps the calculated MTU value in lcp.c to the user specified "mru"
option value. Without this patch pppd would advertise a different MTU value
compared to what is set on the local interface in some cases.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/lcp.c
+++ b/pppd/lcp.c
@@ -1917,12 +1917,12 @@ lcp_up(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
if (!(multilink && go->neg_mrru && ho->neg_mrru))
#endif /* HAVE_MULTILINK */
- netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
+ netif_set_mtu(f->unit, MIN(mtu, mru));
ppp_send_config(f->unit, mtu,
(ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
ho->neg_pcompression, ho->neg_accompression);

View File

@@ -0,0 +1,24 @@
pppd: Do not clobber exit codes on hangup
When a modem hangup occurs, pppd unconditionally sets the exit status code
to EXIT_HANGUP. This patch only sets EXIT_HANGUP if the exit status code is
not already set to an error value.
The motiviation of this patch is to allow applications which remote control
pppd to react properly on errors, e.g. only redial (relaunch pppd) if there
was a hangup, but not if the CHAP authentication failed.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -1048,7 +1048,8 @@ get_input()
}
notice("Modem hangup");
hungup = 1;
- status = EXIT_HANGUP;
+ if (status == EXIT_OK)
+ status = EXIT_HANGUP;
lcp_lowerdown(0); /* serial link is no longer available */
link_terminated(0);
return;

View File

@@ -0,0 +1,20 @@
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
@@ -178,8 +178,8 @@ endif
ifdef FILTER
ifneq ($(wildcard /usr/include/pcap-bpf.h),)
-LIBS += -lpcap
-CFLAGS += -DPPP_FILTER
+LIBS += -lpcap -L$(STAGING_DIR)/usr/lib
+CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)/usr/include
endif
endif

View File

@@ -0,0 +1,196 @@
pppd: Implement support for precompiled pcap filters
This patch implements support for precompiled pcap filters which is useful to
support dial-on-demand on memory constrained embedded devices without having
to link the full libpcap into pppd to generate the filters during runtime.
Two new options are introduced; "precompiled-pass-filter" specifies a pre-
compiled filter file containing rules to match packets which should be passed,
"precompiled-active-filter" specifies a filter file containing rules to match
packets which are treated as active.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -50,6 +50,9 @@ MPPE=y
# and that the kernel driver support PPP packet filtering.
#FILTER=y
+# Support for precompiled filters
+PRECOMPILED_FILTER=y
+
# Uncomment the next line to enable multilink PPP (enabled by default)
# Linux distributions: Please leave multilink ENABLED in your builds
# of pppd!
@@ -183,6 +186,14 @@ CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)
endif
endif
+ifdef PRECOMPILED_FILTER
+PPPDSRCS += pcap_pcc.c
+HEADERS += pcap_pcc.h
+PPPDOBJS += pcap_pcc.o
+LIBS += $(STAGING_DIR)/usr/lib/libpcap.a
+CFLAGS += -DPPP_FILTER -DPPP_PRECOMPILED_FILTER -I$(STAGING_DIR)/usr/include
+endif
+
ifdef HAVE_INET6
PPPDSRCS += ipv6cp.c eui64.c
HEADERS += ipv6cp.h eui64.h
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -57,6 +57,7 @@
#ifdef PPP_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...
@@ -165,6 +166,13 @@ static int setlogfile __P((char **));
static int loadplugin __P((char **));
#endif
+#ifdef PPP_PRECOMPILED_FILTER
+#include "pcap_pcc.h"
+static int setprecompiledpassfilter __P((char **));
+static int setprecompiledactivefilter __P((char **));
+#undef PPP_FILTER
+#endif
+
#ifdef PPP_FILTER
static int setpassfilter __P((char **));
static int setactivefilter __P((char **));
@@ -344,6 +352,14 @@ option_t general_options[] = {
"set filter for active pkts", OPT_PRIO },
#endif
+#ifdef PPP_PRECOMPILED_FILTER
+ { "precompiled-pass-filter", 1, setprecompiledpassfilter,
+ "set precompiled filter for packets to pass", OPT_PRIO },
+
+ { "precompiled-active-filter", 1, setprecompiledactivefilter,
+ "set precompiled filter for active pkts", OPT_PRIO },
+#endif
+
#ifdef MAXOCTETS
{ "maxoctets", o_int, &maxoctets,
"Set connection traffic limit",
@@ -1493,6 +1509,29 @@ callfile(argv)
return ok;
}
+#ifdef PPP_PRECOMPILED_FILTER
+/*
+ * setprecompiledpassfilter - Set the pass filter for packets using a
+ * precompiled expression
+ */
+static int
+setprecompiledpassfilter(argv)
+ char **argv;
+{
+ return pcap_pre_compiled (*argv, &pass_filter);
+}
+
+/*
+ * setactivefilter - Set the active filter for packets
+ */
+static int
+setprecompiledactivefilter(argv)
+ char **argv;
+{
+ return pcap_pre_compiled (*argv, &active_filter);
+}
+#endif
+
#ifdef PPP_FILTER
/*
* setpassfilter - Set the pass filter for packets
--- /dev/null
+++ b/pppd/pcap_pcc.c
@@ -0,0 +1,74 @@
+#include <pcap.h>
+#include <pcap-bpf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "pppd.h"
+
+int pcap_pre_compiled (char * fname, struct bpf_program *p)
+{
+ char buf[128];
+ int line = 0, size = 0, index=0, ret=1;
+ FILE *f = fopen (fname, "r");
+ if (!f)
+ {
+ option_error("error opening precompiled active-filter '%s': %s",
+ fname, strerror (errno));
+ return 0;
+ }
+ while (fgets (buf, 127, f))
+ {
+ line++;
+ if (*buf == '#')
+ continue;
+ if (size)
+ {
+ /*
+ struct bpf_insn {
+ u_short code;
+ u_char jt;
+ u_char jf;
+ bpf_int32 k;
+ }
+ */
+ struct bpf_insn * insn = & p->bf_insns[index];
+ unsigned code, jt, jf, k;
+ if (sscanf (buf, "%u %u %u %u", &code, &jt, &jf, &k) != 4)
+ {
+ goto err;
+ }
+ insn->code = code;
+ insn->jt = jt;
+ insn->jf = jf;
+ insn->k = k;
+ index++;
+ }
+ else
+ {
+ if (sscanf (buf, "%u", &size) != 1)
+ {
+ goto err;
+ }
+ p->bf_len = size;
+ p->bf_insns = (struct bpf_insn *)
+ malloc (size * sizeof (struct bpf_insn));
+ }
+ }
+ if (size != index)
+ {
+ option_error("error in precompiled active-filter,"
+ " expected %d expressions, got %dn",
+ size, index);
+ ret = 0;
+ }
+ fclose(f);
+ return ret;
+
+err:
+ option_error("error in precompiled active-filter"
+ " expression line %s:%d (wrong size)\n",
+ fname, line);
+ fclose (f);
+ return 0;
+}
--- /dev/null
+++ b/pppd/pcap_pcc.h
@@ -0,0 +1,7 @@
+#ifndef PCAP_PCC_H
+#define PCAP_PCC_H
+
+#include <pcap.h>
+
+int pcap_pre_compiled (char * fname, struct bpf_program *p);
+#endif /* PCAP_PCC_H */

View File

@@ -0,0 +1,135 @@
pppd: Support arbitrary interface names
This patch implements a new string option "ifname" which allows to specify
fully custom PPP interface names on Linux. It does so by renaming the
allocated pppX device immediately after it has been created to the requested
interface name.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -745,8 +745,11 @@ void
set_ifunit(iskey)
int iskey;
{
- info("Using interface %s%d", PPP_DRV_NAME, ifunit);
- slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
+ if (use_ifname[0] == 0)
+ slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
+ else
+ slprintf(ifname, sizeof(ifname), "%s", use_ifname);
+ info("Using interface %s", ifname);
script_setenv("IFNAME", ifname, iskey);
if (iskey) {
create_pidfile(getpid()); /* write pid to file */
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -112,6 +112,7 @@ int log_to_fd = 1; /* send log messages
bool log_default = 1; /* log_to_fd is default (stdout) */
int maxfail = 10; /* max # of unsuccessful connection attempts */
char linkname[MAXPATHLEN]; /* logical name for link */
+char use_ifname[IFNAMSIZ]; /* physical name for PPP link */
bool tune_kernel; /* may alter kernel settings */
int connect_delay = 1000; /* wait this many ms after connect script */
int req_unit = -1; /* requested interface unit */
@@ -277,6 +278,9 @@ option_t general_options[] = {
{ "linkname", o_string, linkname,
"Set logical name for link",
OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXPATHLEN },
+ { "ifname", o_string, use_ifname,
+ "Set physical name for PPP interface",
+ OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, IFNAMSIZ },
{ "maxfail", o_int, &maxfail,
"Maximum number of unsuccessful connection attempts to allow",
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -74,6 +74,10 @@
#include "eui64.h"
#endif
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
/*
* Limits.
*/
@@ -317,6 +321,7 @@ extern char *record_file; /* File to rec
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 use_ifname[IFNAMSIZ]; /* physical name for PPP interface */
extern bool tune_kernel; /* May alter kernel settings as necessary */
extern int connect_delay; /* Time to delay after connect script */
extern int max_data_rate; /* max bytes/sec through charshunt */
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -161,6 +161,10 @@ struct in6_ifreq {
/* We can get an EIO error on an ioctl if the modem has hung up */
#define ok_error(num) ((num)==EIO)
+#if !defined(PPP_DRV_NAME)
+#define PPP_DRV_NAME "ppp"
+#endif /* !defined(PPP_DRV_NAME) */
+
static int tty_disc = N_TTY; /* The TTY discipline */
static int ppp_disc = N_PPP; /* The PPP discpline */
static int initfdflags = -1; /* Initial file descriptor flags for fd */
@@ -620,7 +624,8 @@ void generic_disestablish_ppp(int dev_fd
*/
static int make_ppp_unit()
{
- int x, flags;
+ struct ifreq ifr;
+ int x, flags, s;
if (ppp_dev_fd >= 0) {
dbglog("in make_ppp_unit, already had /dev/ppp open?");
@@ -643,6 +648,30 @@ static int make_ppp_unit()
}
if (x < 0)
error("Couldn't create new ppp unit: %m");
+
+ if (use_ifname[0] != 0) {
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ s = socket(PF_PACKET, SOCK_DGRAM, 0);
+ if (s < 0)
+ s = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (s < 0)
+ s = socket(PF_UNIX, SOCK_DGRAM, 0);
+ if (s >= 0) {
+ slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", PPP_DRV_NAME, ifunit);
+ slprintf(ifr.ifr_newname, sizeof(ifr.ifr_newname), "%s", use_ifname);
+ x = ioctl(s, SIOCSIFNAME, &ifr);
+ close(s);
+ } else {
+ x = s;
+ }
+ if (x < 0) {
+ error("Couldn't rename %s to %s", ifr.ifr_name, ifr.ifr_newname);
+ close(ppp_dev_fd);
+ ppp_dev_fd = -1;
+ }
+ }
+
return x;
}
--- a/pppstats/pppstats.c
+++ b/pppstats/pppstats.c
@@ -506,10 +506,12 @@ main(argc, argv)
if (argc > 0)
interface = argv[0];
+#if 0
if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) {
fprintf(stderr, "%s: invalid interface '%s' specified\n",
progname, interface);
}
+#endif
#ifndef STREAMS
{

View File

@@ -0,0 +1,146 @@
From: George Kashperko <george@znau.edu.ua>
Make mlppp support more generic interface naming other than pppX
Signed-off-by: George Kashperko <george@znau.edu.ua>
---
pppd/multilink.c | 55 +++++++++++++++++++++++++++++++++------------
pppd/sys-linux.c | 12 +++++++++
2 files changed, 53 insertions(+), 14 deletions(-)
--- a/pppd/multilink.c
+++ b/pppd/multilink.c
@@ -56,7 +56,8 @@ static void iterate_bundle_links __P((vo
static int get_default_epdisc __P((struct epdisc *));
static int parse_num __P((char *str, const char *key, int *valp));
-static int owns_unit __P((TDB_DATA pid, int unit));
+static int parse_str __P((char *str, const char *key, char *buf, int buflen));
+static int owns_link __P((TDB_DATA pid, char *ifname));
#define set_ip_epdisc(ep, addr) do { \
ep->length = 4; \
@@ -197,35 +198,38 @@ mp_join_bundle()
key.dptr = bundle_id;
key.dsize = p - bundle_id;
pid = tdb_fetch(pppdb, key);
+
if (pid.dptr != NULL) {
+ char tmp[IFNAMSIZ];
+
/* bundle ID exists, see if the pppd record exists */
rec = tdb_fetch(pppdb, pid);
+
if (rec.dptr != NULL && rec.dsize > 0) {
/* make sure the string is null-terminated */
rec.dptr[rec.dsize-1] = 0;
- /* parse the interface number */
- parse_num(rec.dptr, "IFNAME=ppp", &unit);
+
/* check the pid value */
if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
+ || !parse_str(rec.dptr, "IFNAME=", tmp, sizeof(tmp))
+ || !parse_num(rec.dptr, "IFUNIT=", &unit)
|| !process_exists(pppd_pid)
- || !owns_unit(pid, unit))
+ || !owns_link(pid, tmp))
unit = -1;
free(rec.dptr);
}
free(pid.dptr);
- }
- if (unit >= 0) {
/* attach to existing unit */
- if (bundle_attach(unit)) {
+ if (unit >= 0 && bundle_attach(unit)) {
set_ifunit(0);
script_setenv("BUNDLE", bundle_id + 7, 0);
make_bundle_links(1);
unlock_db();
- info("Link attached to %s", ifname);
+ info("Link attached to %s", tmp);
return 1;
+ /* attach failed because bundle doesn't exist */
}
- /* attach failed because bundle doesn't exist */
}
/* we have to make a new bundle */
@@ -408,22 +412,45 @@ parse_num(str, key, valp)
return 0;
}
+static int
+parse_str(str, key, buf, buflen)
+ char *str;
+ const char *key;
+ char *buf;
+ int buflen;
+{
+ char *p, *endp;
+ int i;
+
+ p = strstr(str, key);
+ if (p) {
+ p += strlen(key);
+ while (--buflen && *p != 0 && *p != ';')
+ *(buf++) = *(p++);
+ *buf = 0;
+ return 1;
+ }
+ return 0;
+}
+
/*
- * Check whether the pppd identified by `key' still owns ppp unit `unit'.
+ * Check whether the pppd identified by `key' still owns ppp link `ifname'.
*/
static int
-owns_unit(key, unit)
+owns_link(key, ifname)
TDB_DATA key;
- int unit;
+ char *ifname;
{
- char ifkey[32];
+ char ifkey[7 + IFNAMSIZ];
TDB_DATA kd, vd;
int ret = 0;
- slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit);
+ slprintf(ifkey, sizeof(ifkey), "IFNAME=%s", ifname);
+
kd.dptr = ifkey;
kd.dsize = strlen(ifkey);
vd = tdb_fetch(pppdb, kd);
+
if (vd.dptr != NULL) {
ret = vd.dsize == key.dsize
&& memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -698,6 +698,16 @@ void cfg_bundle(int mrru, int mtru, int
add_fd(ppp_dev_fd);
}
+static void
+setenv_ifunit(void)
+{
+#ifdef USE_TDB
+ char tmp[11];
+ slprintf(tmp, sizeof(tmp), "%d", ifunit);
+ 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
@@ -716,6 +726,8 @@ void make_new_bundle(int mrru, int mtru,
/* set the mrru and flags */
cfg_bundle(mrru, mtru, rssn, tssn);
+
+ setenv_ifunit();
}
/*

View File

@@ -0,0 +1,22 @@
pppd: Retain foreign default routes on Linux
On Linux, when pppd attempts to delete its default route it does not fill
the rt_dev field of the struct rtentry used to match the system default route.
As a consequence, pppd happily deletes any default route even if it belongs
to another interface.
This patch makes pppd fill out the rt_dev field so that only own default
routes are ever matched.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -1756,6 +1756,7 @@ int cifdefaultroute (int unit, u_int32_t
SIN_ADDR(rt.rt_genmask) = 0L;
}
+ rt.rt_dev = ifname;
rt.rt_flags = RTF_UP;
if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
if (still_ppp()) {

View File

@@ -0,0 +1,34 @@
pppd: Fill in default gateway on Linux
On Linux, when pppd creates the default route, it does not set the peer
address as gateway, leading to a default route without gateway address.
This behaviour breaks various downstream programs which attempt to infer
the default gateway IP address from the system default route entry.
This patch addresses the issue by filling in the peer address as gateway
when generating the default route entry.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -1710,6 +1710,9 @@ int sifdefaultroute (int unit, u_int32_t
memset (&rt, 0, sizeof (rt));
SET_SA_FAMILY (rt.rt_dst, AF_INET);
+ SET_SA_FAMILY(rt.rt_gateway, AF_INET);
+ SIN_ADDR(rt.rt_gateway) = gateway;
+
rt.rt_dev = ifname;
if (kernel_version > KVERSION(2,1,0)) {
@@ -1717,7 +1720,7 @@ int sifdefaultroute (int unit, u_int32_t
SIN_ADDR(rt.rt_genmask) = 0L;
}
- rt.rt_flags = RTF_UP;
+ rt.rt_flags = RTF_UP | RTF_GATEWAY;
if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
if (!ok_error(errno))
error("default route ioctl(SIOCADDRT): %m");

View File

@@ -0,0 +1,154 @@
pppd: Remove runtime kernel checks
On embedded system distributions the required kernel features for pppd are
more or less guaranteed to be present, so there is not much point in
performing runtime checks, it just increases the binary size.
This patch removes the runtime kernel feature checks.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -196,7 +196,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 */
-int new_style_driver = 0;
+static const int new_style_driver = 1;
static char loop_name[20];
static unsigned char inbuf[512]; /* buffer for chars read from loopback */
@@ -214,8 +214,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 */
-static int kernel_version;
#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
+static const int kernel_version = KVERSION(2,6,37);
#define MAX_IFS 100
@@ -1451,11 +1451,12 @@ int ccp_fatal_error (int unit)
*
* path_to_procfs - find the path to the proc file system mount point
*/
-static char proc_path[MAXPATHLEN];
-static int proc_path_len;
+static char proc_path[MAXPATHLEN] = "/proc";
+static int proc_path_len = 5;
static char *path_to_procfs(const char *tail)
{
+#if 0
struct mntent *mntent;
FILE *fp;
@@ -1477,6 +1478,7 @@ static char *path_to_procfs(const char *
fclose (fp);
}
}
+#endif
strlcpy(proc_path + proc_path_len, tail,
sizeof(proc_path) - proc_path_len);
@@ -2129,15 +2131,19 @@ int ppp_available(void)
int my_version, my_modification, my_patch;
int osmaj, osmin, ospatch;
+#if 0
/* get the kernel version now, since we are called before sys_init */
uname(&utsname);
osmaj = osmin = ospatch = 0;
sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
kernel_version = KVERSION(osmaj, osmin, ospatch);
+#endif
fd = open("/dev/ppp", O_RDWR);
if (fd >= 0) {
+#if 0
new_style_driver = 1;
+#endif
/* XXX should get from driver */
driver_version = 2;
@@ -2197,6 +2203,7 @@ int ppp_available(void)
if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
ok = 0;
+ return ok;
/*
* This is the PPP device. Validate the version of the driver at this
@@ -2730,6 +2737,7 @@ get_pty(master_fdp, slave_fdp, slave_nam
}
#endif /* TIOCGPTN */
+#if 0
if (sfd < 0) {
/* the old way - scan through the pty name space */
for (i = 0; i < 64; ++i) {
@@ -2748,6 +2756,7 @@ get_pty(master_fdp, slave_fdp, slave_nam
}
}
}
+#endif
if (sfd < 0)
return 0;
--- a/pppd/plugins/pppoatm/pppoatm.c
+++ b/pppd/plugins/pppoatm/pppoatm.c
@@ -168,14 +168,6 @@ static void disconnect_pppoatm(void)
void plugin_init(void)
{
-#if defined(__linux__)
- extern int new_style_driver; /* From sys-linux.c */
- if (!ppp_available() && !new_style_driver)
- fatal("Kernel doesn't support ppp_generic - "
- "needed for PPPoATM");
-#else
- fatal("No PPPoATM support on this OS");
-#endif
info("PPPoATM plugin_init");
add_options(pppoa_options);
}
--- a/pppd/plugins/rp-pppoe/plugin.c
+++ b/pppd/plugins/rp-pppoe/plugin.c
@@ -59,9 +59,6 @@ static char const RCSID[] =
char pppd_version[] = 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;
@@ -371,10 +368,6 @@ PPPoEDevnameHook(char *cmd, char **argv,
void
plugin_init(void)
{
- if (!ppp_available() && !new_style_driver) {
- fatal("Linux kernel does not support PPPoE -- are you running 2.4.x?");
- }
-
add_options(Options);
info("RP-PPPoE plugin version %s compiled against pppd %s",
--- a/pppd/plugins/pppol2tp/pppol2tp.c
+++ b/pppd/plugins/pppol2tp/pppol2tp.c
@@ -486,12 +486,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)
- 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);

View File

@@ -0,0 +1,39 @@
pppd: Remove the "record" option
On many embedded systems there is not enough space to record PPP session
information to the permanent storage, therfore remove this option.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -317,7 +317,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 */
--- a/pppd/tty.c
+++ b/pppd/tty.c
@@ -146,7 +146,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 */
-char *record_file = NULL; /* File to record chars sent/received */
+static char *const record_file = NULL; /* File to record chars sent/received */
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 */
@@ -202,8 +202,10 @@ option_t tty_options[] = {
"Send and receive over socket, arg is host:port",
OPT_PRIO | OPT_DEVNAM },
+#if 0
{ "record", o_string, &record_file,
"Record characters sent/received to file", OPT_PRIO },
+#endif
{ "crtscts", o_int, &crtscts,
"Set hardware (RTS/CTS) flow control",

View File

@@ -0,0 +1,25 @@
pppd: Disable wtmp support
Many uClibc based environments lack wtmp and utmp support, therfore remove
the code updating the wtmp information.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -2267,6 +2267,7 @@ int ppp_available(void)
void logwtmp (const char *line, const char *name, const char *host)
{
+#if 0
struct utmp ut, *utp;
pid_t mypid = getpid();
#if __GLIBC__ < 2
@@ -2332,6 +2333,7 @@ void logwtmp (const char *line, const ch
close (wtmp);
}
#endif
+#endif
}
#endif /* HAVE_LOGWTMP */

View File

@@ -0,0 +1,151 @@
pppd: Remove historical protocol names
Remove a number of historical protocol entries from pppd's builtin list, this
reduced the binary size without loss of features.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -882,14 +882,17 @@ struct protocol_list {
const char *name;
} protocol_list[] = {
{ 0x21, "IP" },
+#if 0
{ 0x23, "OSI Network Layer" },
{ 0x25, "Xerox NS IDP" },
{ 0x27, "DECnet Phase IV" },
{ 0x29, "Appletalk" },
{ 0x2b, "Novell IPX" },
+#endif
{ 0x2d, "VJ compressed TCP/IP" },
{ 0x2f, "VJ uncompressed TCP/IP" },
{ 0x31, "Bridging PDU" },
+#if 0
{ 0x33, "Stream Protocol ST-II" },
{ 0x35, "Banyan Vines" },
{ 0x39, "AppleTalk EDDP" },
@@ -903,8 +906,11 @@ struct protocol_list {
{ 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
{ 0x4b, "SNA over 802.2" },
{ 0x4d, "SNA" },
+#endif
{ 0x4f, "IP6 Header Compression" },
+#if 0
{ 0x51, "KNX Bridging Data" },
+#endif
{ 0x53, "Encryption" },
{ 0x55, "Individual Link Encryption" },
{ 0x57, "IPv6" },
@@ -915,12 +921,15 @@ struct protocol_list {
{ 0x65, "RTP IPHC Compressed non-TCP" },
{ 0x67, "RTP IPHC Compressed UDP 8" },
{ 0x69, "RTP IPHC Compressed RTP 8" },
+#if 0
{ 0x6f, "Stampede Bridging" },
{ 0x73, "MP+" },
{ 0xc1, "NTCITS IPI" },
+#endif
{ 0xfb, "single-link compression" },
{ 0xfd, "Compressed Datagram" },
{ 0x0201, "802.1d Hello Packets" },
+#if 0
{ 0x0203, "IBM Source Routing BPDU" },
{ 0x0205, "DEC LANBridge100 Spanning Tree" },
{ 0x0207, "Cisco Discovery Protocol" },
@@ -932,15 +941,19 @@ struct protocol_list {
{ 0x0231, "Luxcom" },
{ 0x0233, "Sigma Network Systems" },
{ 0x0235, "Apple Client Server Protocol" },
+#endif
{ 0x0281, "MPLS Unicast" },
{ 0x0283, "MPLS Multicast" },
+#if 0
{ 0x0285, "IEEE p1284.4 standard - data packets" },
{ 0x0287, "ETSI TETRA Network Protocol Type 1" },
+#endif
{ 0x0289, "Multichannel Flow Treatment Protocol" },
{ 0x2063, "RTP IPHC Compressed TCP No Delta" },
{ 0x2065, "RTP IPHC Context State" },
{ 0x2067, "RTP IPHC Compressed UDP 16" },
{ 0x2069, "RTP IPHC Compressed RTP 16" },
+#if 0
{ 0x4001, "Cray Communications Control Protocol" },
{ 0x4003, "CDPD Mobile Network Registration Protocol" },
{ 0x4005, "Expand accelerator protocol" },
@@ -951,8 +964,10 @@ struct protocol_list {
{ 0x4023, "RefTek Protocol" },
{ 0x4025, "Fibre Channel" },
{ 0x4027, "EMIT Protocols" },
+#endif
{ 0x405b, "Vendor-Specific Protocol (VSP)" },
{ 0x8021, "Internet Protocol Control Protocol" },
+#if 0
{ 0x8023, "OSI Network Layer Control Protocol" },
{ 0x8025, "Xerox NS IDP Control Protocol" },
{ 0x8027, "DECnet Phase IV Control Protocol" },
@@ -961,7 +976,9 @@ struct protocol_list {
{ 0x8031, "Bridging NCP" },
{ 0x8033, "Stream Protocol Control Protocol" },
{ 0x8035, "Banyan Vines Control Protocol" },
+#endif
{ 0x803d, "Multi-Link Control Protocol" },
+#if 0
{ 0x803f, "NETBIOS Framing Control Protocol" },
{ 0x8041, "Cisco Systems Control Protocol" },
{ 0x8043, "Ascom Timeplex" },
@@ -970,18 +987,24 @@ struct protocol_list {
{ 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
{ 0x804b, "SNA over 802.2 Control Protocol" },
{ 0x804d, "SNA Control Protocol" },
+#endif
{ 0x804f, "IP6 Header Compression Control Protocol" },
+#if 0
{ 0x8051, "KNX Bridging Control Protocol" },
+#endif
{ 0x8053, "Encryption Control Protocol" },
{ 0x8055, "Individual Link Encryption Control Protocol" },
{ 0x8057, "IPv6 Control Protocol" },
{ 0x8059, "PPP Muxing Control Protocol" },
{ 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" },
+#if 0
{ 0x806f, "Stampede Bridging Control Protocol" },
{ 0x8073, "MP+ Control Protocol" },
{ 0x80c1, "NTCITS IPI Control Protocol" },
+#endif
{ 0x80fb, "Single Link Compression Control Protocol" },
{ 0x80fd, "Compression Control Protocol" },
+#if 0
{ 0x8207, "Cisco Discovery Protocol Control" },
{ 0x8209, "Netcs Twin Routing" },
{ 0x820b, "STP - Control Protocol" },
@@ -990,24 +1013,29 @@ struct protocol_list {
{ 0x8281, "MPLSCP" },
{ 0x8285, "IEEE p1284.4 standard - Protocol Control" },
{ 0x8287, "ETSI TETRA TNP1 Control Protocol" },
+#endif
{ 0x8289, "Multichannel Flow Treatment Protocol" },
{ 0xc021, "Link Control Protocol" },
{ 0xc023, "Password Authentication Protocol" },
{ 0xc025, "Link Quality Report" },
+#if 0
{ 0xc027, "Shiva Password Authentication Protocol" },
{ 0xc029, "CallBack Control Protocol (CBCP)" },
{ 0xc02b, "BACP Bandwidth Allocation Control Protocol" },
{ 0xc02d, "BAP" },
+#endif
{ 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" },
{ 0xc081, "Container Control Protocol" },
{ 0xc223, "Challenge Handshake Authentication Protocol" },
{ 0xc225, "RSA Authentication Protocol" },
{ 0xc227, "Extensible Authentication Protocol" },
+#if 0
{ 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" },
{ 0xc26f, "Stampede Bridging Authorization Protocol" },
{ 0xc281, "Proprietary Authentication Protocol" },
{ 0xc283, "Proprietary Authentication Protocol" },
{ 0xc481, "Proprietary Node ID Authentication Protocol" },
+#endif
{ 0, NULL },
};

View File

@@ -0,0 +1,28 @@
pppd: Support "nomp" option even if multilink support is off
This patch moves the "nomp" option entry outside of the defines protecting
the multilink specific code. The motivation is to allow "nomp" even if pppd
does not support multilink, so that controlling programs can unconditionally
pass it to pppd regardless of the compile time features.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -336,13 +336,14 @@ option_t general_options[] = {
"Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 },
{ "nomultilink", o_bool, &multilink,
"Disable multilink operation", OPT_PRIOSUB | 0 },
- { "nomp", o_bool, &multilink,
- "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 },
{ "bundle", o_string, &bundle_name,
"Bundle name for multilink", OPT_PRIO },
#endif /* HAVE_MULTILINK */
+ { "nomp", o_bool, &multilink,
+ "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 },
+
#ifdef PLUGIN
{ "plugin", o_special, (void *)loadplugin,
"Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST },

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
--- a/pppd/plugins/pptp/pptp.c
+++ b/pppd/plugins/pptp/pptp.c
@@ -48,7 +48,7 @@
#include "pptp_callmgr.h"
#include <net/if.h>
-#include <net/ethernet.h>
+#include <linux/if_ether.h>
#include <linux/if_pppox.h>
#include <stdio.h>

View File

@@ -0,0 +1,269 @@
--- a/pppd/plugins/rp-pppoe/common.c
+++ b/pppd/plugins/rp-pppoe/common.c
@@ -119,15 +119,11 @@ sendPADT(PPPoEConnection *conn, char con
conn->session = 0;
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
/* Copy error message */
--- a/pppd/plugins/rp-pppoe/discovery.c
+++ b/pppd/plugins/rp-pppoe/discovery.c
@@ -80,13 +80,10 @@ static void
parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
void *extra)
{
- int *val = (int *) extra;
- if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {
- pid_t tmp;
- memcpy(&tmp, data, len);
- if (tmp == getpid()) {
- *val = 1;
- }
+ PPPoETag *tag = extra;
+
+ if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) {
+ tag->length = memcmp(data, tag->payload, len);
}
}
@@ -104,16 +101,16 @@ parseForHostUniq(UINT16_t type, UINT16_t
static int
packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
{
- int forMe = 0;
+ PPPoETag hostUniq = conn->hostUniq;
/* If packet is not directed to our MAC address, forget it */
if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
/* If we're not using the Host-Unique tag, then accept the packet */
- if (!conn->useHostUniq) return 1;
+ if (!conn->hostUniq.length) return 1;
- parsePacket(packet, parseForHostUniq, &forMe);
- return forMe;
+ parsePacket(packet, parseForHostUniq, &hostUniq);
+ return (hostUniq.length == 0);
}
/**********************************************************************
@@ -301,16 +298,12 @@ sendPADI(PPPoEConnection *conn)
}
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
/* Add our maximum MTU/MRU */
@@ -478,16 +471,12 @@ sendPADR(PPPoEConnection *conn)
cursor += namelen + TAG_HDR_SIZE;
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE);
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
/* Add our maximum MTU/MRU */
--- a/pppd/plugins/rp-pppoe/plugin.c
+++ b/pppd/plugins/rp-pppoe/plugin.c
@@ -65,6 +65,7 @@ static char *existingSession = NULL;
static int printACNames = 0;
static char *pppoe_reqd_mac = NULL;
unsigned char pppoe_reqd_mac_addr[6];
+static char *host_uniq = NULL;
static int PPPoEDevnameHook(char *cmd, char **argv, int doit);
static option_t Options[] = {
@@ -82,6 +83,8 @@ static option_t Options[] = {
"Be verbose about discovered access concentrators"},
{ "pppoe-mac", o_string, &pppoe_reqd_mac,
"Only connect to specified MAC address" },
+ { "host-uniq", o_string, &host_uniq,
+ "Specify custom Host-Uniq" },
{ NULL }
};
int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL;
@@ -107,7 +110,6 @@ PPPOEInitDevice(void)
conn->ifName = devnam;
conn->discoverySocket = -1;
conn->sessionSocket = -1;
- conn->useHostUniq = 1;
conn->printACNames = printACNames;
conn->discoveryTimeout = PADI_TIMEOUT;
return 1;
@@ -163,6 +165,9 @@ PPPOEConnectDevice(void)
if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
+ if (host_uniq && !parseHostUniq(host_uniq, &conn->hostUniq))
+ fatal("Illegal value for host-uniq option");
+
conn->acName = acName;
conn->serviceName = pppd_pppoe_service;
strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
--- a/pppd/plugins/rp-pppoe/pppoe-discovery.c
+++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c
@@ -348,7 +348,7 @@ packetIsForMe(PPPoEConnection *conn, PPP
if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
/* If we're not using the Host-Unique tag, then accept the packet */
- if (!conn->useHostUniq) return 1;
+ if (!conn->hostUniq.length) return 1;
parsePacket(packet, parseForHostUniq, &forMe);
return forMe;
@@ -474,16 +474,12 @@ sendPADI(PPPoEConnection *conn)
cursor += namelen + TAG_HDR_SIZE;
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
packet.length = htons(plen);
@@ -645,7 +641,7 @@ int main(int argc, char *argv[])
memset(conn, 0, sizeof(PPPoEConnection));
- while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) {
+ while ((opt = getopt(argc, argv, "I:D:VUW:AS:C:h")) > 0) {
switch(opt) {
case 'S':
conn->serviceName = xstrdup(optarg);
@@ -654,7 +650,23 @@ int main(int argc, char *argv[])
conn->acName = xstrdup(optarg);
break;
case 'U':
- conn->useHostUniq = 1;
+ if(conn->hostUniq.length) {
+ fprintf(stderr, "-U and -W are mutually exclusive\n");
+ exit(EXIT_FAILURE);
+ }
+ char pidbuf[5];
+ snprintf(pidbuf, sizeof(pidbuf), "%04x", getpid());
+ parseHostUniq(pidbuf, &conn->hostUniq);
+ break;
+ case 'W':
+ if(conn->hostUniq.length) {
+ fprintf(stderr, "-U and -W are mutually exclusive\n");
+ exit(EXIT_FAILURE);
+ }
+ if (!parseHostUniq(optarg, &conn->hostUniq)) {
+ fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
break;
case 'D':
conn->debugFile = fopen(optarg, "w");
--- a/pppd/plugins/rp-pppoe/pppoe.h
+++ b/pppd/plugins/rp-pppoe/pppoe.h
@@ -21,6 +21,8 @@
#include <stdio.h> /* For FILE */
#include <sys/types.h> /* For pid_t */
+#include <ctype.h>
+#include <string.h>
/* How do we access raw Ethernet devices? */
#undef USE_LINUX_PACKET
@@ -217,7 +219,7 @@ typedef struct PPPoEConnectionStruct {
char *serviceName; /* Desired service name, if any */
char *acName; /* Desired AC name, if any */
int synchronous; /* Use synchronous PPP */
- int useHostUniq; /* Use Host-Uniq tag */
+ PPPoETag hostUniq; /* Use Host-Uniq tag */
int printACNames; /* Just print AC names */
FILE *debugFile; /* Debug file for dumping packets */
int numPADOs; /* Number of PADO packets received */
@@ -273,6 +275,33 @@ void pppoe_printpkt(PPPoEPacket *packet,
void (*printer)(void *, char *, ...), void *arg);
void pppoe_log_packet(const char *prefix, PPPoEPacket *packet);
+static inline int parseHostUniq(const char *uniq, PPPoETag *tag)
+{
+ int i, len = strlen(uniq);
+
+#define hex(x) \
+ (((x) <= '9') ? ((x) - '0') : \
+ (((x) <= 'F') ? ((x) - 'A' + 10) : \
+ ((x) - 'a' + 10)))
+
+ if (len % 2)
+ return 0;
+
+ for (i = 0; i < len; i += 2)
+ {
+ if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1]))
+ return 0;
+
+ tag->payload[i / 2] = (char)(16 * hex(uniq[i]) + hex(uniq[i+1]));
+ }
+
+#undef hex
+
+ tag->type = htons(TAG_HOST_UNIQ);
+ tag->length = htons(len / 2);
+ return 1;
+}
+
#define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
#define CHECK_ROOM(cursor, start, len) \

View File

@@ -0,0 +1,11 @@
--- a/pppd/plugins/rp-pppoe/plugin.c
+++ b/pppd/plugins/rp-pppoe/plugin.c
@@ -275,7 +275,7 @@ PPPOEDisconnectDevice(void)
sizeof(struct sockaddr_pppox)) < 0)
error("Failed to disconnect PPPoE socket: %d %m", errno);
close(conn->sessionSocket);
- /* don't send PADT?? */
+ sendPADT(conn, NULL);
if (conn->discoverySocket >= 0)
close(conn->discoverySocket);
}

View File

@@ -0,0 +1,14 @@
--- a/pppd/plugins/rp-pppoe/plugin.c
+++ b/pppd/plugins/rp-pppoe/plugin.c
@@ -271,9 +271,8 @@ PPPOEDisconnectDevice(void)
sp.sa_addr.pppoe.sid = 0;
memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ);
memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN);
- if (connect(conn->sessionSocket, (struct sockaddr *) &sp,
- sizeof(struct sockaddr_pppox)) < 0)
- error("Failed to disconnect PPPoE socket: %d %m", errno);
+ connect(conn->sessionSocket, (struct sockaddr *) &sp,
+ sizeof(struct sockaddr_pppox));
close(conn->sessionSocket);
sendPADT(conn, NULL);
if (conn->discoverySocket >= 0)

View File

@@ -0,0 +1,13 @@
--- a/pppd/plugins/pppol2tp/pppol2tp.c
+++ b/pppd/plugins/pppol2tp/pppol2tp.c
@@ -148,6 +148,10 @@ static int setdevname_pppol2tp(char **ar
fatal("PPPoL2TP kernel driver not installed");
}
+ pppol2tp_fd_str = strdup(*argv);
+ if (pppol2tp_fd_str == NULL)
+ novm("PPPoL2TP FD");
+
/* Setup option defaults. Compression options are disabled! */
modem = 0;

View File

@@ -0,0 +1,11 @@
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -1013,7 +1013,7 @@ print_option(opt, mainopt, printer, arg)
p = (char *) opt->addr2;
if ((opt->flags & OPT_STATIC) == 0)
p = *(char **)p;
- printer("%q", p);
+ printer(arg, "%q", p);
} else if (opt->flags & OPT_A2LIST) {
struct option_value *ovp;

View File

@@ -0,0 +1,30 @@
From 858976b1fc3107f1261aae337831959b511b83c2 Mon Sep 17 00:00:00 2001
From: Paul Mackerras <paulus@ozlabs.org>
Date: Sat, 4 Jan 2020 12:01:32 +1100
Subject: [PATCH] radius: Prevent buffer overflow in rc_mksid()
On some systems getpid() can return a value greater than 65535.
Increase the size of buf[] to allow for this, and use slprintf()
to make sure we never overflow it.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
pppd/plugins/radius/util.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pppd/plugins/radius/util.c b/pppd/plugins/radius/util.c
index 6f976a712951..740131e8377c 100644
--- a/pppd/plugins/radius/util.c
+++ b/pppd/plugins/radius/util.c
@@ -73,9 +73,9 @@ void rc_mdelay(int msecs)
char *
rc_mksid (void)
{
- static char buf[15];
+ static char buf[32];
static unsigned short int cnt = 0;
- sprintf (buf, "%08lX%04X%02hX",
+ slprintf(buf, sizeof(buf), "%08lX%04X%02hX",
(unsigned long int) time (NULL),
(unsigned int) getpid (),
cnt & 0xFF);

View File

@@ -0,0 +1,37 @@
From 8d7970b8f3db727fe798b65f3377fe6787575426 Mon Sep 17 00:00:00 2001
From: Paul Mackerras <paulus@ozlabs.org>
Date: Mon, 3 Feb 2020 15:53:28 +1100
Subject: [PATCH] pppd: Fix bounds check in EAP code
Given that we have just checked vallen < len, it can never be the case
that vallen >= len + sizeof(rhostname). This fixes the check so we
actually avoid overflowing the rhostname array.
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
pppd/eap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pppd/eap.c b/pppd/eap.c
index 94407f56a336..1b93db01aebd 100644
--- a/pppd/eap.c
+++ b/pppd/eap.c
@@ -1420,7 +1420,7 @@ int len;
}
/* Not so likely to happen. */
- if (vallen >= len + sizeof (rhostname)) {
+ if (len - vallen >= sizeof (rhostname)) {
dbglog("EAP: trimming really long peer name down");
BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
rhostname[sizeof (rhostname) - 1] = '\0';
@@ -1846,7 +1846,7 @@ int len;
}
/* Not so likely to happen. */
- if (vallen >= len + sizeof (rhostname)) {
+ if (len - vallen >= sizeof (rhostname)) {
dbglog("EAP: trimming really long peer name down");
BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
rhostname[sizeof (rhostname) - 1] = '\0';

View File

@@ -0,0 +1,61 @@
From 8d45443bb5c9372b4c6a362ba2f443d41c5636af Mon Sep 17 00:00:00 2001
From: Paul Mackerras <paulus@ozlabs.org>
Date: Mon, 3 Feb 2020 16:31:42 +1100
Subject: [PATCH] pppd: Ignore received EAP messages when not doing EAP
This adds some basic checks to the subroutines of eap_input to check
that we have requested or agreed to doing EAP authentication before
doing any processing on the received packet. The motivation is to
make it harder for a malicious peer to disrupt the operation of pppd
by sending unsolicited EAP packets. Note that eap_success() already
has a check that the EAP client state is reasonable, and does nothing
(apart from possibly printing a debug message) if not.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
pppd/eap.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/pppd/eap.c b/pppd/eap.c
index 1b93db01aebd..082e95343120 100644
--- a/pppd/eap.c
+++ b/pppd/eap.c
@@ -1328,6 +1328,12 @@ int len;
int fd;
#endif /* USE_SRP */
+ /*
+ * Ignore requests if we're not open
+ */
+ if (esp->es_client.ea_state <= eapClosed)
+ return;
+
/*
* Note: we update es_client.ea_id *only if* a Response
* message is being generated. Otherwise, we leave it the
@@ -1736,6 +1742,12 @@ int len;
u_char dig[SHA_DIGESTSIZE];
#endif /* USE_SRP */
+ /*
+ * Ignore responses if we're not open
+ */
+ if (esp->es_server.ea_state <= eapClosed)
+ return;
+
if (esp->es_server.ea_id != id) {
dbglog("EAP: discarding Response %d; expected ID %d", id,
esp->es_server.ea_id);
@@ -2047,6 +2059,12 @@ u_char *inp;
int id;
int len;
{
+ /*
+ * Ignore failure messages if we're not open
+ */
+ if (esp->es_client.ea_state <= eapClosed)
+ return;
+
if (!eap_client_active(esp)) {
dbglog("EAP unexpected failure message in state %s (%d)",
eap_state_name(esp->es_client.ea_state),