]> git.ozlabs.org Git - ppp.git/commitdiff
pppd: allow use of arbitrary interface names
authorPaul Mackerras <paulus@samba.org>
Tue, 23 Aug 2016 06:10:21 +0000 (16:10 +1000)
committerPaul Mackerras <paulus@samba.org>
Tue, 23 Aug 2016 06:10:21 +0000 (16:10 +1000)
This is a modified version of a patch from openSUSE that enables PPP interfaces
to be called arbitrary names, rather than simply pppX where X is the unit
number.

The modifications from the stock openSUSE patch are:
- refresh patch on top of 018_ip-up_option.diff
- fix a printf format-string vulnerability in pppd/main.c:set_ifunit()
- clarify the pppd.8 manpage additions
- patch pppstats/pppstats.c to query renamed interfaces without complaint

Origin: SUSE
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=458646
Forwarded: no
Reviewed-by: Chris Boot <bootc@debian.org>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pppd/main.c
pppd/options.c
pppd/pppd.8
pppd/pppd.h
pppd/sys-linux.c
pppstats/pppstats.c

index 6d50d1bac1d998e7ad359a1ec4e35852e3739e1d..f1986ed68d0b7e4d00f81b956e2abbb263b79d7a 100644 (file)
 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 */
index c06a2b4ad8ed4560501dfeb61902946c14ea7d96..177488ca681392c3971e432642c7e97a0638a894 100644 (file)
@@ -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 */
@@ -284,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,
index c508d277df3aa5539dd3c0d94787d97f71709956..06e945fce998080090da52837d1d3b69306c19a7 100644 (file)
@@ -1079,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
index 247fa153739b387d217719e6ac1beb8bf407d708..1a1bf0b99582fa323cb0ee587d79c248642a7896 100644 (file)
 #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 */
index b4a435d2a99368bdb48316c798961f1be8f08147..b832031f7e269648ad6e33207c8855b2da4a8b34 100644 (file)
@@ -643,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;
 }
 
index 6367988eb96bf03c588b6228ee0c0fdf115f0fbb..46cb9c24942b5e6869fef31f463b514daefb99ba 100644 (file)
@@ -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