diff options
author | Tobias Klauser <tklauser@distanz.ch> | 2016-08-17 08:41:52 +0200 |
---|---|---|
committer | Tobias Klauser <tklauser@distanz.ch> | 2016-08-17 08:41:52 +0200 |
commit | f46d59e0dc7b54a3f4a7ead2fd2d4258b3f56782 (patch) | |
tree | 076ca9422193ee640dc16c69c0923a4c9feeaec1 /socket.c | |
parent | f1081b6b0f47160f83ded689d956bd577819d752 (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.c | 27 |
1 files changed, 25 insertions, 2 deletions
@@ -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; |