summaryrefslogtreecommitdiff
path: root/socket.c
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2016-08-17 08:41:52 +0200
committerTobias Klauser <tklauser@distanz.ch>2016-08-17 08:41:52 +0200
commitf46d59e0dc7b54a3f4a7ead2fd2d4258b3f56782 (patch)
tree076ca9422193ee640dc16c69c0923a4c9feeaec1 /socket.c
parentf1081b6b0f47160f83ded689d956bd577819d752 (diff)
llmnrd: Allow to bind to a specific network interface
Add a command line option -i/--interface which allows to bind the llmnrd sockets to a specific interface. If used, requests are only answered on the specified interface. Example: llmnrd -i eth0 Closes #9 Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'socket.c')
-rw-r--r--socket.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/socket.c b/socket.c
index 21e715a..1103779 100644
--- a/socket.c
+++ b/socket.c
@@ -36,7 +36,24 @@
static const int YES = 1;
static const int TTL = 255;
-int socket_open_ipv4(uint16_t port)
+static int socket_bind_to_device(int sock, const char *iface) {
+#ifdef SO_BINDTODEVICE
+ /* bind socket to specific interface */
+ if (iface) {
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
+ if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) {
+ log_err("Failed to bind socket to device %s: %s\n", iface, strerror(errno));
+ return -1;
+ }
+ }
+#endif
+ return 0;
+}
+
+int socket_open_ipv4(uint16_t port, const char *iface)
{
int sock;
struct sockaddr_in sa;
@@ -64,6 +81,9 @@ int socket_open_ipv4(uint16_t port)
goto err;
}
+ if (socket_bind_to_device(sock, iface) < 0)
+ goto err;
+
/* bind the socket */
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
@@ -81,7 +101,7 @@ err:
return -1;
}
-int socket_open_ipv6(uint16_t port)
+int socket_open_ipv6(uint16_t port, const char *iface)
{
int sock, opt_pktinfo;
struct sockaddr_in6 sa;
@@ -120,6 +140,9 @@ int socket_open_ipv6(uint16_t port)
goto err;
}
+ if (socket_bind_to_device(sock, iface) < 0)
+ goto err;
+
/* bind the socket */
memset(&sa, 0, sizeof(sa));
sa.sin6_family = AF_INET6;