aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/dhcp
diff options
context:
space:
mode:
authorThomas Egerer <thomas.egerer@secunet.com>2013-11-18 13:15:02 +0100
committerMartin Willi <martin@revosec.ch>2014-01-20 16:40:34 +0100
commit3711f66e543d55d36eedddc5542ec2257f5d188d (patch)
treeeb3657df07ef2f7e72f616b79c1693475568103c /src/libcharon/plugins/dhcp
parent568e3022607a98394c53bc5a4922d368d19cbe60 (diff)
downloadstrongswan-3711f66e543d55d36eedddc5542ec2257f5d188d.tar.bz2
strongswan-3711f66e543d55d36eedddc5542ec2257f5d188d.tar.xz
dhcp: Allow binding of socket to particular interface
In certain situations it is desirable to bind the send/receive sockets for the DHCP address allocation to a particular interface. With this patch the strongswan.conf option charon.plugins.dhcp.interface can be used to restrict the DHCP communication to a configurable interface. Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
Diffstat (limited to 'src/libcharon/plugins/dhcp')
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index 044c8a819..ac594c8fa 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -643,6 +643,28 @@ METHOD(dhcp_socket_t, destroy, void,
}
/**
+ * Bind a socket to a particular interface name
+ */
+static bool bind_to_device(int fd, char *iface)
+{
+ struct ifreq ifreq;
+
+ if (strlen(iface) > sizeof(ifreq.ifr_name))
+ {
+ DBG1(DBG_CFG, "name for DHCP interface too long: '%s'", iface);
+ return FALSE;
+ }
+ memcpy(ifreq.ifr_name, iface, sizeof(ifreq.ifr_name));
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof(ifreq)))
+ {
+ DBG1(DBG_CFG, "binding DHCP socket to '%s' failed: %s",
+ iface, strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
* See header
*/
dhcp_socket_t *dhcp_socket_create()
@@ -655,6 +677,7 @@ dhcp_socket_t *dhcp_socket_create()
.s_addr = INADDR_ANY,
},
};
+ char *iface;
int on = 1;
struct sock_filter dhcp_filter_code[] = {
BPF_STMT(BPF_LD+BPF_B+BPF_ABS,
@@ -718,6 +741,8 @@ dhcp_socket_t *dhcp_socket_create()
this->dst = host_create_from_string(lib->settings->get_str(lib->settings,
"%s.plugins.dhcp.server", "255.255.255.255",
charon->name), DHCP_SERVER_PORT);
+ iface = lib->settings->get_str(lib->settings, "%s.plugins.dhcp.interface",
+ NULL, charon->name);
if (!this->dst)
{
DBG1(DBG_CFG, "configured DHCP server address invalid");
@@ -766,6 +791,15 @@ dhcp_socket_t *dhcp_socket_create()
destroy(this);
return NULL;
}
+ if (iface)
+ {
+ if (!bind_to_device(this->send, iface) ||
+ !bind_to_device(this->receive, iface))
+ {
+ destroy(this);
+ return NULL;
+ }
+ }
lib->watcher->add(lib->watcher, this->receive, WATCHER_READ,
(watcher_cb_t)receive_dhcp, this);