Add listening on interface groups for dhcpd, from gilles@' smtpd. Add static to is_if_in_group in smtpd and relayd. Fix whitespaces in is_if_in_group in smtpd and relayd.
I didn't write a diff for dhcpd's manpage. Index: dhcpd/dispatch.c =================================================================== RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v retrieving revision 1.28 diff -u -r1.28 dispatch.c --- dhcpd/dispatch.c 19 Nov 2010 08:00:56 -0000 1.28 +++ dhcpd/dispatch.c 27 May 2011 09:06:32 -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); } Index: relayd/parse.y =================================================================== RCS file: /cvs/src/usr.sbin/relayd/parse.y,v retrieving revision 1.158 diff -u -r1.158 parse.y --- relayd/parse.y 26 May 2011 14:48:20 -0000 1.158 +++ relayd/parse.y 27 May 2011 09:06:43 -0000 @@ -122,7 +122,7 @@ struct table *table_inherit(struct table *); struct relay *relay_inherit(struct relay *, struct relay *); int getservice(char *); -int is_if_in_group(const char *, const char *); +static int is_if_in_group(const char *, const char *); typedef struct { union { @@ -2570,7 +2570,7 @@ nextaf: for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) { if (p->ifa_addr->sa_family != af || - (strcmp(s, p->ifa_name) != 0 && + (strcmp(p->ifa_name, s) != 0 && !is_if_in_group(p->ifa_name, s))) continue; if ((h = calloc(1, sizeof(*h))) == NULL) @@ -2807,44 +2807,44 @@ return (htons((u_short)llval)); } -int +static int is_if_in_group(const char *ifname, const char *groupname) { - unsigned int len; - struct ifgroupreq ifgr; - struct ifg_req *ifg; + 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) + 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), + 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 (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); + } + free(ifgr.ifgr_groups); end: close(s); Index: smtpd/parse.y =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v retrieving revision 1.75 diff -u -r1.75 parse.y --- smtpd/parse.y 22 May 2011 21:03:14 -0000 1.75 +++ smtpd/parse.y 27 May 2011 09:06:45 -0000 @@ -101,7 +101,7 @@ struct listenerlist *, int, in_port_t, u_int8_t); void set_localaddrs(void); int delaytonum(char *); -int is_if_in_group(const char *, const char *); +static int is_if_in_group(const char *, const char *); typedef struct { union { @@ -1963,44 +1963,44 @@ return (-1); } -int +static int is_if_in_group(const char *ifname, const char *groupname) { - unsigned int len; - struct ifgroupreq ifgr; - struct ifg_req *ifg; + 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) + 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), + 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"); + 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); + 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); + } + free(ifgr.ifgr_groups); end: close(s); -- Michal Mazurek