summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2011-05-22 21:03:15 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2011-05-22 21:03:15 +0000
commit45c76bbeb07dca62213877d707ba5686582dc061 (patch)
tree588400ea2a4fb661eba5c03e7064d110e794baf7 /usr.sbin/smtpd
parent44ada67f788d5025a7d4dd7b214bafc618c7f982 (diff)
teach smtpd how to listen on an interface group so that we can do:
listen on egress listen on wlan idea unvoluntarily suggested by Mikolaj Kucharski a few weeks ago, unslacked after theo suggested it again.
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/parse.y52
-rw-r--r--usr.sbin/smtpd/smtpd.conf.55
2 files changed, 53 insertions, 4 deletions
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index 450476bbe61..57ac7287132 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.74 2011/05/21 16:58:04 gilles Exp $ */
+/* $OpenBSD: parse.y,v 1.75 2011/05/22 21:03:14 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -28,7 +28,9 @@
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -99,6 +101,7 @@ int interface(const char *, const char *, const char *,
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 *);
typedef struct {
union {
@@ -1820,7 +1823,8 @@ interface(const char *s, const char *tag, const char *cert,
fatal("getifaddrs");
for (p = ifap; p != NULL; p = p->ifa_next) {
- if (strcmp(s, p->ifa_name) != 0)
+ if (strcmp(p->ifa_name, s) != 0 &&
+ ! is_if_in_group(p->ifa_name, s))
continue;
if ((h = calloc(1, sizeof(*h))) == NULL)
@@ -1958,3 +1962,47 @@ delaytonum(char *str)
bad:
return (-1);
}
+
+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;
+}
diff --git a/usr.sbin/smtpd/smtpd.conf.5 b/usr.sbin/smtpd/smtpd.conf.5
index e85d9b0cdef..812561037ca 100644
--- a/usr.sbin/smtpd/smtpd.conf.5
+++ b/usr.sbin/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.39 2011/05/22 13:38:31 gilles Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.40 2011/05/22 21:03:14 gilles Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -101,7 +101,8 @@ Specify an
and
.Ar port
to listen on.
-An IP address or domain name may be used in place of
+An interface group, an IP address or adomain name may
+be used in place of
.Ar interface .
.Pp
Secured connections are provided either using STARTTLS