From: Paul Mackerras Date: Sat, 18 Mar 2017 11:12:36 +0000 (+1100) Subject: Merge https://github.com/yasuoka/ppp X-Git-Tag: ppp-2.4.8~42 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=12fc6939987bc20feff22aadd82dff1a623d892b;hp=f831f27c309fb2f4dfca3336a9f144993e02c225 Merge https://github.com/yasuoka/ppp Signed-off-by: Paul Mackerras --- diff --git a/pppd/ccp.c b/pppd/ccp.c index 5814f35..7d7922a 100644 --- a/pppd/ccp.c +++ b/pppd/ccp.c @@ -676,7 +676,8 @@ ccp_cilen(f) ccp_options *go = &ccp_gotoptions[f->unit]; return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) - + (go->deflate? CILEN_DEFLATE: 0) + + (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0) + + (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0) + (go->predictor_1? CILEN_PREDICTOR_1: 0) + (go->predictor_2? CILEN_PREDICTOR_2: 0) + (go->mppe? CILEN_MPPE: 0); diff --git a/pppd/ccp.h b/pppd/ccp.h index 6f4a2fe..76446db 100644 --- a/pppd/ccp.h +++ b/pppd/ccp.h @@ -37,7 +37,7 @@ typedef struct ccp_options { bool predictor_2; /* do Predictor-2? */ bool deflate_correct; /* use correct code for deflate? */ bool deflate_draft; /* use draft RFC code for deflate? */ - bool mppe; /* do MPPE? */ + u_char mppe; /* MPPE bitfield */ u_short bsd_bits; /* # bits/code for BSD Compress */ u_short deflate_size; /* lg(window size) for Deflate */ short method; /* code for chosen compression method */ diff --git a/pppd/ipxcp.c b/pppd/ipxcp.c index 7b2343e..aaff10f 100644 --- a/pppd/ipxcp.c +++ b/pppd/ipxcp.c @@ -1194,7 +1194,7 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) case IPX_ROUTER_NAME: if (cilen >= CILEN_NAME) { int name_size = cilen - CILEN_NAME; - if (name_size > sizeof (ho->name)) + if (name_size >= sizeof (ho->name)) name_size = sizeof (ho->name) - 1; memset (ho->name, 0, sizeof (ho->name)); memcpy (ho->name, p, name_size); diff --git a/pppd/main.c b/pppd/main.c index 6d50d1b..f1986ed 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -124,7 +124,7 @@ static const char rcsid[] = RCSID; /* interface vars */ -char ifname[32]; /* Interface name */ +char ifname[MAXIFNAMELEN]; /* Interface name */ int ifunit; /* Interface unit number */ struct channel *the_channel; @@ -298,13 +298,6 @@ struct protent *protocols[] = { NULL }; -/* - * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. - */ -#if !defined(PPP_DRV_NAME) -#define PPP_DRV_NAME "ppp" -#endif /* !defined(PPP_DRV_NAME) */ - int main(argc, argv) int argc; @@ -737,8 +730,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 (req_ifname[0] != '\0') + slprintf(ifname, sizeof(ifname), "%s", req_ifname); + else + slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); + info("Using interface %s", ifname); script_setenv("IFNAME", ifname, iskey); if (iskey) { create_pidfile(getpid()); /* write pid to file */ diff --git a/pppd/options.c b/pppd/options.c index f66b765..177488c 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -114,6 +114,7 @@ char linkname[MAXPATHLEN]; /* logical name for 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 */ +char req_ifname[MAXIFNAMELEN]; /* requested interface name */ bool multilink = 0; /* Enable multilink operation */ char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ @@ -121,6 +122,7 @@ 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 */ +int dfl_route_metric = -1; /* metric of the default route to set over the PPP link */ #ifdef MAXOCTETS unsigned int maxoctets = 0; /* default - no limit */ @@ -283,6 +285,10 @@ option_t general_options[] = { "PPP interface unit number to use if possible", OPT_PRIO | OPT_LLIMIT, 0, 0 }, + { "ifname", o_string, req_ifname, + "Set PPP interface name", + OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXIFNAMELEN }, + { "dump", o_bool, &dump_options, "Print out option values after parsing all options", 1 }, { "dryrun", o_bool, &dryrun, @@ -299,6 +305,10 @@ option_t general_options[] = { "Unset user environment variable", OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint }, + { "defaultroute-metric", o_int, &dfl_route_metric, + "Metric to use for the default route (Linux only; -1 for default behavior)", + OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 }, + #ifdef HAVE_MULTILINK { "multilink", o_bool, &multilink, "Enable multilink operation", OPT_PRIO | 1 }, diff --git a/pppd/plugins/Makefile.linux b/pppd/plugins/Makefile.linux index ab8cf50..8a90e39 100644 --- a/pppd/plugins/Makefile.linux +++ b/pppd/plugins/Makefile.linux @@ -27,7 +27,7 @@ include .depend endif all: $(PLUGINS) - for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all; done + for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all || exit $$?; done %.so: %.c $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ @@ -37,12 +37,12 @@ VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../patchlevel.h) install: $(PLUGINS) $(INSTALL) -d $(LIBDIR) $(INSTALL) $? $(LIBDIR) - for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d install; done + for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d install || exit $$?; done clean: rm -f *.o *.so *.a - for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d clean; done + for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d clean || exit $$?; done depend: $(CPP) -M $(CFLAGS) *.c >.depend - for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d depend; done + for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d depend || exit $$?; done diff --git a/pppd/plugins/rp-pppoe/plugin.c b/pppd/plugins/rp-pppoe/plugin.c index a8c2bb4..c89be94 100644 --- a/pppd/plugins/rp-pppoe/plugin.c +++ b/pppd/plugins/rp-pppoe/plugin.c @@ -270,12 +270,13 @@ PPPOEDisconnectDevice(void) 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) + sizeof(struct sockaddr_pppox)) < 0 && errno != EALREADY) error("Failed to disconnect PPPoE socket: %d %m", errno); close(conn->sessionSocket); - /* don't send PADT?? */ - if (conn->discoverySocket >= 0) + if (conn->discoverySocket >= 0) { + sendPADT(conn, NULL); close(conn->discoverySocket); + } } static void diff --git a/pppd/plugins/rp-pppoe/pppoe.h b/pppd/plugins/rp-pppoe/pppoe.h index 9ab2eee..c4aaa6e 100644 --- a/pppd/plugins/rp-pppoe/pppoe.h +++ b/pppd/plugins/rp-pppoe/pppoe.h @@ -47,6 +47,10 @@ #include #endif +/* This has to be included before Linux 4.8's linux/in.h + * gets dragged in. */ +#include + /* Ugly header files on some Linux boxes... */ #if defined(HAVE_LINUX_IF_H) #include @@ -84,8 +88,6 @@ typedef unsigned long UINT32_t; #include #endif -#include - #ifdef HAVE_NETINET_IF_ETHER_H #include @@ -98,7 +100,6 @@ typedef unsigned long UINT32_t; #endif - /* Ethernet frame types according to RFC 2516 */ #define ETH_PPPOE_DISCOVERY 0x8863 #define ETH_PPPOE_SESSION 0x8864 diff --git a/pppd/pppd.8 b/pppd/pppd.8 index e2768b1..06e945f 100644 --- a/pppd/pppd.8 +++ b/pppd/pppd.8 @@ -121,6 +121,12 @@ the gateway, when IPCP negotiation is successfully completed. This entry is removed when the PPP connection is broken. This option is privileged if the \fInodefaultroute\fR option has been specified. .TP +.B defaultroute-metric +Define the metric of the \fIdefaultroute\fR and only add it if there +is no other default route with the same metric. With the default +value of -1, the route is only added if there is no default route at +all. +.TP .B disconnect \fIscript Execute the command specified by \fIscript\fR, by passing it to a shell, after @@ -1073,7 +1079,13 @@ under Linux and FreeBSD 2.2.8 and later. .TP .B unit \fInum Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound -connections. +connections. If the unit is already in use a dynamically allocated number will +be used. +.TP +.B ifname \fIstring +Set the ppp interface name for outbound connections. If the interface name is +already in use, or if the name cannot be used for any other reason, pppd will +terminate. .TP .B unset \fIname Remove a variable from the environment variable for scripts that are diff --git a/pppd/pppd.h b/pppd/pppd.h index 247fa15..1a1bf0b 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -80,6 +80,16 @@ #define MAXARGS 1 /* max # args to a command */ #define MAXNAMELEN 256 /* max length of hostname or name for auth */ #define MAXSECRETLEN 256 /* max length of password or secret */ +#define MAXIFNAMELEN 32 /* max length of interface name; or use IFNAMSIZ, can we + always include net/if.h? */ + +/* + * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. + * Where should PPP_DRV_NAME come from? Do we include it here? + */ +#if !defined(PPP_DRV_NAME) +#define PPP_DRV_NAME "ppp" +#endif /* !defined(PPP_DRV_NAME) */ /* * Option descriptor structure. @@ -318,6 +328,7 @@ 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 */ extern int req_unit; /* interface unit number to use */ +extern char req_ifname[MAXIFNAMELEN]; /* interface name to use */ extern bool multilink; /* enable multilink operation */ extern bool noendpoint; /* don't send or accept endpt. discrim. */ extern char *bundle_name; /* bundle name for multilink */ diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index e5e9baf..b832031 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -233,7 +233,7 @@ static int baud_rate_of (int speed); static void close_route_table (void); static int open_route_table (void); static int read_route_table (struct rtentry *rt); -static int defaultroute_exists (struct rtentry *rt); +static int defaultroute_exists (struct rtentry *rt, int metric); static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, char *name, int namelen); static void decode_version (char *buf, int *version, int *mod, int *patch); @@ -244,6 +244,8 @@ static int setifstate (int u, int state); extern u_char inpacket_buf[]; /* borrowed from main.c */ +extern int dfl_route_metric; + /* * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, * if it exists. @@ -641,6 +643,21 @@ static int make_ppp_unit() } if (x < 0) error("Couldn't create new ppp unit: %m"); + + if (x == 0 && req_ifname[0] != '\0') { + struct ifreq ifr; + char t[MAXIFNAMELEN]; + memset(&ifr, 0, sizeof(struct ifreq)); + slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit); + strncpy(ifr.ifr_name, t, IF_NAMESIZE); + strncpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE); + x = ioctl(sock_fd, SIOCSIFNAME, &ifr); + if (x < 0) + error("Couldn't rename interface %s to %s: %m", t, req_ifname); + else + info("Renamed interface %s to %s", t, req_ifname); + } + return x; } @@ -1447,7 +1464,7 @@ static char *path_to_procfs(const char *tail) FILE *route_fd = (FILE *) 0; static char route_buffer[512]; static int route_dev_col, route_dest_col, route_gw_col; -static int route_flags_col, route_mask_col; +static int route_flags_col, route_metric_col, route_mask_col; static int route_num_cols; static int open_route_table (void); @@ -1490,6 +1507,7 @@ static int open_route_table (void) route_dest_col = 1; route_gw_col = 2; route_flags_col = 3; + route_metric_col = 6; route_mask_col = 7; route_num_cols = 8; @@ -1550,6 +1568,7 @@ static int read_route_table(struct rtentry *rt) SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); + rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10); rt->rt_dev = cols[route_dev_col]; return 1; @@ -1558,9 +1577,10 @@ static int read_route_table(struct rtentry *rt) /******************************************************************** * * defaultroute_exists - determine if there is a default route + * with the given metric (or negative for any) */ -static int defaultroute_exists (struct rtentry *rt) +static int defaultroute_exists (struct rtentry *rt, int metric) { int result = 0; @@ -1573,7 +1593,8 @@ static int defaultroute_exists (struct rtentry *rt) if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) continue; - if (SIN_ADDR(rt->rt_dst) == 0L) { + if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0 + || rt->rt_metric == metric)) { result = 1; break; } @@ -1620,13 +1641,13 @@ 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 (defaultroute_exists(&rt, dfl_route_metric) && 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)); + error("not replacing existing default route via %I with metric %d", + SIN_ADDR(rt.rt_gateway), dfl_route_metric); else - error("not replacing existing default route through %s", - rt.rt_dev); + error("not replacing existing default route through %s with metric %d", + rt.rt_dev, dfl_route_metric); return 0; } @@ -1634,6 +1655,7 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) SET_SA_FAMILY (rt.rt_dst, AF_INET); rt.rt_dev = ifname; + rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); @@ -1668,6 +1690,9 @@ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) rt.rt_dev = ifname; + rt.rt_dev = ifname; + rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ + if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = 0L; diff --git a/pppd/utils.c b/pppd/utils.c index 29bf970..3ac1b60 100644 --- a/pppd/utils.c +++ b/pppd/utils.c @@ -625,7 +625,7 @@ print_string(p, len, printer, arg) printer(arg, "\\t"); break; default: - printer(arg, "\\%.3o", c); + printer(arg, "\\%.3o", (unsigned char) c); } } } diff --git a/pppstats/pppstats.c b/pppstats/pppstats.c index 6367988..46cb9c2 100644 --- a/pppstats/pppstats.c +++ b/pppstats/pppstats.c @@ -88,7 +88,6 @@ int aflag; /* print absolute values, not deltas */ int dflag; /* print data rates, not bytes */ int interval, count; int infinite; -int unit; int s; /* socket or /dev/ppp file descriptor */ int signalled; /* set if alarm goes off "early" */ char *progname; @@ -449,6 +448,7 @@ main(argc, argv) { int c; #ifdef STREAMS + int unit; char *dev; #endif @@ -506,11 +506,6 @@ main(argc, argv) if (argc > 0) interface = argv[0]; - if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { - fprintf(stderr, "%s: invalid interface '%s' specified\n", - progname, interface); - } - #ifndef STREAMS { struct ifreq ifr; @@ -535,6 +530,11 @@ main(argc, argv) } #else /* STREAMS */ + if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { + fprintf(stderr, "%s: invalid interface '%s' specified\n", + progname, interface); + } + #ifdef __osf__ dev = "/dev/streams/ppp"; #else diff --git a/scripts/plog b/scripts/plog index 84d2c73..7cb5334 100644 --- a/scripts/plog +++ b/scripts/plog @@ -3,5 +3,5 @@ if [ -s /var/log/ppp.log ]; then exec tail "$@" /var/log/ppp.log else - exec tail "$@" /var/log/syslog | grep ' \(pppd\|chat\)\[' + exec grep ' \(pppd\|chat\)\[' /var/log/syslog | tail "$@" fi diff --git a/scripts/poff b/scripts/poff index 3f55a7f..5b45d98 100644 --- a/scripts/poff +++ b/scripts/poff @@ -91,7 +91,7 @@ if test "$#" -eq 0 -o "$MODE" = "all" ; then fi # There is an argument, so kill the pppd started on that provider. -PID=`ps axw | grep "[ /]pppd call $1" | awk '{print $1}'` +PID=`ps axw | grep "[ /]pppd call $1" | grep -w "$1" | awk '{print $1}'` if test -n "$PID" ; then $KILL -$SIG $PID || { echo "$0: $KILL failed. None ${DONE}."