I wrote this little patch to add a restrict option to bind only to a
specific network interface.

I'd not deal with --inetd since there are some bugs in xinetd with ipv6
( and no more maintener ) , systemd/upstart are also Linux centric and
subject to controversy...

"listen" option was not more useful in my case because it need ip as
parameter (you need fix ip or custom script for example).

It's not ready for inclusion but ready for discussion.

PROS :
* Do the job

CONS :
* Linux only
* root only

What do you think about such option/implementation ?
-- 
Ronan Bignaux
Entrepreneur indépendant
Consultant informatique

ScourGE SARL
136 rue Branville
14000 CAEN
06.47.75.44.81

>From bfebe7fc838f83065fea04cf27613fe89e962a3a Mon Sep 17 00:00:00 2001
From: Bignaux Ronan <ro...@aimao.org>
Date: Thu, 20 Sep 2012 15:09:31 +0200
Subject: [PATCH] add option to bind to a specific interface


Signed-off-by: Bignaux Ronan <ro...@aimao.org>
---
 daemon.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/daemon.c b/daemon.c
index 4602b46..755fbd3 100644
--- a/daemon.c
+++ b/daemon.c
@@ -5,6 +5,10 @@
 #include "strbuf.h"
 #include "string-list.h"
 
+#ifdef SO_BINDTODEVICE
+#include <net/if.h>
+#endif
+
 #ifndef HOST_NAME_MAX
 #define HOST_NAME_MAX 256
 #endif
@@ -31,7 +35,7 @@ static const char daemon_usage[] =
 "           [--reuseaddr] [--pid-file=<file>]\n"
 "           [--(enable|disable|allow-override|forbid-override)=<service>]\n"
 "           [--access-hook=<path>]\n"
-"           [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>]\n"
+"           [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>] [--bindtodev=<interface>]\n"
 "                      [--detach] [--user=<user> [--group=<group>]]\n"
 "           [<directory>...]";
 
@@ -64,6 +68,7 @@ static char *hostname;
 static char *canon_hostname;
 static char *ip_address;
 static char *tcp_port;
+static struct ifreq ifr;
 
 static void logreport(int priority, const char *err, va_list params)
 {
@@ -875,6 +880,15 @@ static int setup_named_sock(char *listen_addr, int listen_port, struct socketlis
 			continue;
 		}
 
+		if (ifr.ifr_name) {
+			if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (void *) &ifr,
+					sizeof(ifr)) < 0) {
+				logerror("Could not set SO_BINDTODEVICE: %s", strerror(errno));
+				close(sockfd);
+				continue;
+			}
+		}
+
 #ifdef IPV6_V6ONLY
 		if (ai->ai_family == AF_INET6) {
 			int on = 1;
@@ -1194,6 +1208,11 @@ int main(int argc, char **argv)
 				continue;
 			}
 		}
+		if (!prefixcmp(arg, "--bindtodev=")) {
+			memset(&ifr, 0, sizeof(ifr));
+			strncpy (ifr.ifr_name, arg + 12 ,IFNAMSIZ);
+			continue;
+		}
 		if (!strcmp(arg, "--serve")) {
 			serve_mode = 1;
 			continue;
-- 
1.7.12

<<attachment: r_bignaux.vcf>>

Reply via email to