]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add allowinterfaces and denyinterfaces options to dhcpcd.conf for better multiple...
authorRoy Marples <roy@marples.name>
Thu, 11 Sep 2008 09:38:02 +0000 (09:38 +0000)
committerRoy Marples <roy@marples.name>
Thu, 11 Sep 2008 09:38:02 +0000 (09:38 +0000)
dhcpcd.8.in
dhcpcd.c
dhcpcd.conf.5.in
dhcpcd.h
if-linux.c
if-options.c
if-options.h
net.c

index aba3b86644ae9503d317f416f169f3cd510f9698..f0ae80a5a83df276cc27de4465facf0d09297d8b 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd September 3, 2008
+.Dd September 11, 2008
 .Dt DHCPCD 8 SMM
 .Sh NAME
 .Nm dhcpcd
 .Op Fl t , -timeout Ar seconds
 .Op Fl u , -userclass Ar class
 .Op Fl v , -vendor Ar code , Ar value
+.Op Fl z , -allowinterfaces Ar pattern
 .Op Fl C , -nohook Ar hook
 .Op Fl F , -fqdn Ar FQDN
 .Op Fl I , -clientid Ar clientid
 .Op Fl O , -nooption Ar option
 .Op Fl Q , -require Ar option
 .Op Fl X , -blacklist Ar address
+.Op Fl Z , -denyinterfaces Ar pattern
 .Op interface
 .Op ...
 .Nm
@@ -104,8 +106,10 @@ can be run per interface or as a single instance to manage all interfaces.
 If a list of interfaces are given on the command line, then
 .Nm
 only works with those interfaces.
-If no interfaces are given then we detect all available interfaces and
+If no interfaces are given then we discover available interfaces and
 attempt to configure all of them.
+See options below for controlling what interfaces we allow and deny through
+the use of patterns.
 .Ss Hooking into DHCP events
 .Nm
 runs
@@ -349,6 +353,14 @@ Quiet
 .Nm
 on the command line, only warnings and errors will be displayed.
 The messages are still logged though.
+.It Fl z , -allowinterfaces Ar pattern
+When discovering interfaces, the interface name must match
+.Ar pattern
+which is a space or comma separated list of patterns passed to
+.Xr fnmatch 3 .
+If the same interface is matched in
+.Fl Z , -denyinterfaces
+then it is still denied.
 .It Fl A , -noarp
 Don't request or claim the address by ARP.
 This also disables IPv4LL.
@@ -397,6 +409,11 @@ as the server ID.
 This may be expanded in future releases to ignore all packets
 matching either the IP or hardware
 .Ar address .
+.It Fl Z , -denyinterfaces Ar pattern
+When discovering interfaces, the interface name must not match
+.Ar pattern
+which is a space or comma separated list of patterns passed to
+.Xr fnmatch 3 .
 .El
 .Sh NOTES
 .Nm
@@ -430,6 +447,7 @@ running on the
 .Xr dhcpcd-run-hooks 8 ,
 .Xr resolv.conf 5 ,
 .Xr resolvconf 8 ,
+.Xr fnmatch 3
 .Sh STANDARDS
 RFC 2131, RFC 2132, RFC 2855, RFC 3004, RFC 3361, RFC 3396, RFC 3397,
 RFC 3442, RFC 3927, RFC 4361, RFC 4390, RFC 4702.
index 9992b41e42a8089071695fcdf3df2751426dede9..d7111117cd54178b6451c723eb0041ff2c475133 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -68,6 +68,10 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples";
 int options = 0;
 int pidfd = -1;
 struct interface *ifaces = NULL;
+int ifac = 0;
+char **ifav = NULL;
+int ifdc = 0;
+char **ifdv = NULL;
 
 static char **ifv = NULL;
 static int ifc = 0;
@@ -134,12 +138,20 @@ cleanup(void)
 {
 #ifdef DEBUG_MEMORY
        struct interface *iface;
+       int i;
 
        while (ifaces) {
                iface = ifaces;
                ifaces = iface->next;
                free_interface(iface);
        }
+
+       for (i = 0; i < ifac; i++)
+               free(ifav[i]);
+       free(ifav);
+       for (i = 0; i < ifdc; i++)
+               free(ifdv[i]);
+       free(ifdv);
 #endif
 
        if (linkfd != -1)
@@ -986,7 +998,6 @@ main(int argc, char **argv)
        closefrom(3);
        openlog(PACKAGE, LOG_PERROR, LOG_DAEMON);
        setlogmask(LOG_UPTO(LOG_INFO));
-       options = DHCPCD_DAEMONISE;
 
        /* Test for --help and --version */
        if (argc > 1) {
@@ -999,6 +1010,7 @@ main(int argc, char **argv)
                }
        }
 
+       i = 0;
        while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
        {
                switch (opt) {
@@ -1018,7 +1030,7 @@ main(int argc, char **argv)
                        sig = SIGTERM;
                        break;
                case 'T':
-                       options |= DHCPCD_TEST | DHCPCD_PERSISTENT;
+                       i = 1;
                        break;
                case 'V':
                        print_options();
@@ -1036,12 +1048,15 @@ main(int argc, char **argv)
                        usage();
                exit(EXIT_FAILURE);
        }
+       options = ifo->options;
+       if (i)
+               options |= DHCPCD_TEST | DHCPCD_PERSISTENT;
 
 #ifdef THERE_IS_NO_FORK
        options &= ~DHCPCD_DAEMONISE;
 #endif
 
-       if (ifo->options & DHCPCD_QUIET)
+       if (options & DHCPCD_QUIET)
                setlogmask(LOG_UPTO(LOG_WARNING));
 
        /* If we have any other args, we should run as a single dhcpcd instance
index 899aea35c8770bb20fc04c73e6a7d5da8432cb4b..a492855d15c27c699b6cfd654e93a6859d644e50 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd August 18, 2008
+.Dd September 11, 2008
 .Dt DHCPCD.CONF 5 SMM
 .Sh NAME
 .Nm dhcpcd.conf
@@ -43,6 +43,19 @@ Blank lines and lines starting with # are ignored.
 .Pp
 Here's a list of available options:
 .Bl -tag -width indent
+.It Ic allowinterfaces Ar pattern
+When discovering interfaces, the interface name must match
+.Ar pattern
+which is a space or comma separated list of patterns passed to
+.Xr fnmatch 3 .
+If the same interface is matched in
+.Ic denyinterfaces
+then it is still denied.
+.It Ic denyinterfaces Ar pattern
+When discovering interfaces, the interface name must not match
+.Ar pattern
+which is a space or comma separated list of patterns passed to
+.Xr fnmatch 3 .
 .It Ic background
 Background immediately.
 This is useful for startup scripts which don't disable link messages for
@@ -148,7 +161,8 @@ If not set then none is sent.
 .El
 .Sh SEE ALSO
 .Xr dhcpcd-run-hooks 8 ,
-.Xr dhcpcd 8
+.Xr dhcpcd 8 ,
+.Xr fnmatch 3
 .Sh AUTHORS
 .An Roy Marples <roy@marples.name>
 .Sh BUGS
index 2251febd8faac3c19e8004d004a83eeb9f13f45d..19ca613f78d33eee7892f555e30e7b905871c4dd 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -106,6 +106,10 @@ struct interface
 
 extern int pidfd;
 extern int options;
+extern int ifac;
+extern char **ifav;
+extern int ifdc;
+extern char **ifdv;
 extern struct interface *ifaces;
 
 int handle_args(int, char **);
index 9a20abc26e9cfaef3c255895c5982f2392c68825..8419b5ec1ba9d8e30510dae58bd533d8d62ab372 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <errno.h>
 #include <ctype.h>
+#include <fnmatch.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -397,7 +398,6 @@ discover_interfaces(int argc, char * const *argv)
        FILE *f;
        char *buffer = NULL, *p;
        size_t len = 0, ln = 0, n;
-       int i;
        struct interface *ifs = NULL, *ifp, *ifl;
 
        if ((f = fopen("/proc/net/dev", "r"))) {
@@ -418,10 +418,21 @@ discover_interfaces(int argc, char * const *argv)
                        if (ifp)
                                continue;
                        if (argc > 0) {
-                               for (i = 0; i < argc; i++)
-                                       if (strcmp(argv[i], p) == 0)
+                               for (n = 0; n < argc; n++)
+                                       if (strcmp(argv[n], p) == 0)
                                                break;
-                               if (i == argc)
+                               if (n == argc)
+                                       continue;
+                       } else {
+                               for (n = 0; n < ifdc; n++)
+                                       if (!fnmatch(ifdv[n], ifr->ifr_name, 0))
+                                               break;
+                               if (n < ifdc)
+                                       continue;
+                               for (n = 0; n < ifac; n++)
+                                       if (!fnmatch(ifav[n], ifr->ifr_name, 0))
+                                               break;
+                               if (ifac && n == ifac)
                                        continue;
                        }
                        if ((ifp = init_interface(p))) {
index 3c45b0de0aceb0cc75e108386b2dde79cc8f6a19..e51a09f6757fbe38ccf01887e619afd75e5429dd 100644 (file)
 #define OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:Q:TVX:"
 
 const struct option cf_options[] = {
-       {"background",    no_argument,        NULL, 'b'},
-       {"script",        required_argument,  NULL, 'c'},
-       {"debug",         no_argument,        NULL, 'd'},
-       {"config",        required_argument,  NULL, 'f'},
-       {"hostname",      optional_argument,  NULL, 'h'},
-       {"vendorclassid", optional_argument,  NULL, 'i'},
-       {"release",       no_argument,        NULL, 'k'},
-       {"leasetime",     required_argument,  NULL, 'l'},
-       {"metric",        required_argument,  NULL, 'm'},
-       {"rebind",        no_argument,        NULL, 'n'},
-       {"option",        required_argument,  NULL, 'o'},
-       {"persistent",    no_argument,        NULL, 'p'},
-       {"quiet",         no_argument,        NULL, 'q'},
-       {"request",       optional_argument,  NULL, 'r'},
-       {"inform",        optional_argument,  NULL, 's'},
-       {"timeout",       required_argument,  NULL, 't'},
-       {"userclass",     required_argument,  NULL, 'u'},
-       {"vendor",        required_argument,  NULL, 'v'},
-       {"exit",          no_argument,        NULL, 'x'},
-       {"noarp",         no_argument,        NULL, 'A'},
-       {"nobackground",  no_argument,        NULL, 'B'},
-       {"nohook",        required_argument,  NULL, 'C'},
-       {"duid",          no_argument,        NULL, 'D'},
-       {"lastlease",     no_argument,        NULL, 'E'},
-       {"fqdn",          optional_argument,  NULL, 'F'},
-       {"nogateway",     no_argument,        NULL, 'G'},
-       {"clientid",      optional_argument,  NULL, 'I'},
-       {"nolink",        no_argument,        NULL, 'K'},
-       {"noipv4ll",      no_argument,        NULL, 'L'},
-       {"nooption",      optional_argument,  NULL, 'O'},
-       {"require",       required_argument,  NULL, 'Q'},
-       {"test",          no_argument,        NULL, 'T'},
-       {"variables",     no_argument,        NULL, 'V'},
-       {"blacklist",     required_argument,  NULL, 'X'},
-       {NULL,            0,                  NULL, '\0'}
+       {"background",      no_argument,       NULL, 'b'},
+       {"script",          required_argument, NULL, 'c'},
+       {"debug",           no_argument,       NULL, 'd'},
+       {"config",          required_argument, NULL, 'f'},
+       {"hostname",        optional_argument, NULL, 'h'},
+       {"vendorclassid",   optional_argument, NULL, 'i'},
+       {"release",         no_argument,       NULL, 'k'},
+       {"leasetime",       required_argument, NULL, 'l'},
+       {"metric",          required_argument, NULL, 'm'},
+       {"rebind",          no_argument,       NULL, 'n'},
+       {"option",          required_argument, NULL, 'o'},
+       {"persistent",      no_argument,       NULL, 'p'},
+       {"quiet",           no_argument,       NULL, 'q'},
+       {"request",         optional_argument, NULL, 'r'},
+       {"inform",          optional_argument, NULL, 's'},
+       {"timeout",         required_argument, NULL, 't'},
+       {"userclass",       required_argument, NULL, 'u'},
+       {"vendor",          required_argument, NULL, 'v'},
+       {"exit",            no_argument,       NULL, 'x'},
+       {"allowinterfaces", required_argument, NULL, 'z'},
+       {"noarp",           no_argument,       NULL, 'A'},
+       {"nobackground",    no_argument,       NULL, 'B'},
+       {"nohook",          required_argument, NULL, 'C'},
+       {"duid",            no_argument,       NULL, 'D'},
+       {"lastlease",       no_argument,       NULL, 'E'},
+       {"fqdn",            optional_argument, NULL, 'F'},
+       {"nogateway",       no_argument,       NULL, 'G'},
+       {"clientid",        optional_argument, NULL, 'I'},
+       {"nolink",          no_argument,       NULL, 'K'},
+       {"noipv4ll",        no_argument,       NULL, 'L'},
+       {"nooption",        optional_argument, NULL, 'O'},
+       {"require",         required_argument, NULL, 'Q'},
+       {"test",            no_argument,       NULL, 'T'},
+       {"variables",       no_argument,       NULL, 'V'},
+       {"blacklist",       required_argument, NULL, 'X'},
+       {"denyinterfaces",  required_argument, NULL, 'Z'},
+       {NULL,              0,                 NULL, '\0'}
 };
 
 static int
@@ -248,6 +250,22 @@ parse_string_hwaddr(char *sbuf, ssize_t slen, const char *str, int clid)
        return l;
 }
 
+static char **
+splitv(int *argc, char **argv, const char *arg)
+{
+       char **v = argv;
+       char *o = xstrdup(arg), *p, *t;
+
+       p = o;
+       while ((t = strsep(&p, ", "))) {
+               (*argc)++;
+               v = xrealloc(v, *argc);
+               v[(*argc) - 1] = xstrdup(t);
+       }
+       free(o);
+       return v;       
+}
+
 static int
 parse_option(struct if_options *ifo, int opt, const char *arg)
 {
@@ -417,6 +435,11 @@ parse_option(struct if_options *ifo, int opt, const char *arg)
                        ifo->vendor[0] += s + 2;
                }
                break;
+       case 'z':
+               /* We only set this if we haven't got any interfaces */
+               if (!ifaces)
+                       ifav = splitv(&ifac, ifav, arg);
+               break;
        case 'A':
                ifo->options &= ~DHCPCD_ARP;
                /* IPv4LL requires ARP */
@@ -514,6 +537,11 @@ parse_option(struct if_options *ifo, int opt, const char *arg)
                ifo->blacklist[ifo->blacklist_len] = addr.s_addr;
                ifo->blacklist_len++;
                break;
+       case 'Z':
+               /* We only set this if we haven't got any interfaces */
+               if (!ifaces)
+                       ifdv = splitv(&ifdc, ifdv, arg);
+               break;
        default:
                return 0;
        }
index 7358bd64c25a30f0509584dc0295a31559f6d2c8..0559eec0158390786ca354c7c954c2ee528c4593 100644 (file)
@@ -36,8 +36,8 @@
 #include <limits.h>
 
 /* Don't set any optional arguments here so we retain POSIX
- *  * compatibility with getopt */
-#define IF_OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:Q:TVX:"
+ * compatibility with getopt */
+#define IF_OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xz:ABC:DEF:GI:KLO:Q:TVX:Z:"
 
 #define DEFAULT_TIMEOUT                30
 #define DEFAULT_LEASETIME      3600    /* 1 hour */
diff --git a/net.c b/net.c
index 1f015be7bfe91852afdacc8efbf1220c139c36a2..15b80075fc524d59be1f6c91d73d600ffc2dd506 100644 (file)
--- a/net.c
+++ b/net.c
@@ -61,6 +61,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <fnmatch.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -398,6 +399,17 @@ do_interface(const char *ifname,
                                                break;
                                if (n == argc)
                                        continue;
+                       } else {
+                               for (n = 0; n < ifdc; n++)
+                                       if (!fnmatch(ifdv[n], ifr->ifr_name, 0))
+                                               break;
+                               if (n < ifdc)
+                                       continue;
+                               for (n = 0; n < ifac; n++)
+                                       if (!fnmatch(ifav[n], ifr->ifr_name, 0))
+                                               break;
+                               if (ifac && n == ifac)
+                                       continue;
                        }
                        ifn = init_interface(ifr->ifr_name);
                        if (!ifn)