On Fri, May 27, 2011 at 01:22:24PM +0200, Reyk Floeter wrote:
> > I didn't write a diff for dhcpd's manpage.
> > 
> 
> you should write a new diff for dhcpd only that also includes the
> manpage bits. 

Thanks for the comments.

I hope it's legal to say "listen on an interface group".

Index: dhcpd.8
===================================================================
RCS file: /cvs/src/usr.sbin/dhcpd/dhcpd.8,v
retrieving revision 1.18
diff -u -r1.18 dhcpd.8
--- dhcpd.8     8 Oct 2010 15:43:45 -0000       1.18
+++ dhcpd.8     27 May 2011 14:36:44 -0000
@@ -142,7 +142,7 @@
 client and sends replies over that,
 which a newly booted client would not be able to grasp.
 .Sh COMMAND LINE
-The names of the network interfaces on which
+The names of the network interfaces or interface groups on which
 .Nm
 should listen for broadcasts may be specified on the command line.
 This should be done on systems where
Index: dispatch.c
===================================================================
RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v
retrieving revision 1.28
diff -u -r1.28 dispatch.c
--- dispatch.c  19 Nov 2010 08:00:56 -0000      1.28
+++ dispatch.c  27 May 2011 14:36:44 -0000
@@ -40,6 +40,7 @@
 
 #include "dhcpd.h"
 #include "sync.h"
+#include <err.h>
 #include <ifaddrs.h>
 #include <sys/ioctl.h>
 #include <poll.h>
@@ -57,6 +58,7 @@
 
 static int interface_status(struct interface_info *ifinfo);
 int get_rdomain(char *);
+static int is_if_in_group(const char *, const char *);
 
 /* Use getifaddrs() to get a list of all the attached interfaces.
    For each interface that's of type INET and not the loopback interface,
@@ -104,7 +106,8 @@
 
                /* See if we've seen an interface that matches this one. */
                for (tmp = interfaces; tmp; tmp = tmp->next)
-                       if (!strcmp(tmp->name, ifa->ifa_name))
+                       if (!strcmp(ifa->ifa_name, tmp->name)
+                           || is_if_in_group(ifa->ifa_name, tmp->name))
                                break;
 
                /* If we are looking for specific interfaces, ignore others. */
@@ -639,4 +642,48 @@
 
        close(s);
        return rv;
+}
+
+static int
+is_if_in_group(const char *ifname, const char *groupname)
+{
+       unsigned int             len;
+       struct ifgroupreq        ifgr;
+       struct ifg_req          *ifg;
+       int                      s;
+       int                      ret = 0;
+
+       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+               err(1, "socket");
+
+       memset(&ifgr, 0, sizeof(ifgr));
+       strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ);
+       if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
+               if (errno == EINVAL || errno == ENOTTY)
+                       goto end;
+               err(1, "SIOCGIFGROUP");
+       }
+
+       len = ifgr.ifgr_len;
+       ifgr.ifgr_groups =
+           (struct ifg_req *)calloc(len / sizeof(struct ifg_req),
+               sizeof(struct ifg_req));
+       if (ifgr.ifgr_groups == NULL)
+               err(1, "getifgroups");
+       if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
+               err(1, "SIOCGIFGROUP");
+
+       ifg = ifgr.ifgr_groups;
+       for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
+               len -= sizeof(struct ifg_req);
+               if (strcmp(ifg->ifgrq_group, groupname) == 0) {
+                       ret = 1;
+                       break;
+               }
+       }
+       free(ifgr.ifgr_groups);
+
+end:
+       close(s);
+       return (ret);
 }

-- 
Michal Mazurek

Reply via email to