Patchwork [RFC,1/4] wpa_supplicant: remote access for ctrl_iface

login
register
mail settings
Submitter Janusz.Dziedzic@tieto.com
Date Aug. 2, 2012, 11:01 a.m.
Message ID <3078A9B976EF864C8DDD0C499FFD07912150C655E3@EXMB01.eu.tieto.com>
Download mbox | patch
Permalink /patch/174728/
State Accepted
Headers show

Comments

Janusz.Dziedzic@tieto.com - Aug. 2, 2012, 11:01 a.m.
Add new option for ctrl iface:
CONFIG_CTRL_IFACE=udp-remote

This enables remote access to control interface
via udp port. Should be used for tests purpose only.

Signed-hostap: Janusz Dziedzic <janusz.dziedzic@tieto.com>
---
 src/common/wpa_ctrl.h           |    7 +++++--
 wpa_supplicant/Makefile         |    5 +++++
 wpa_supplicant/ctrl_iface_udp.c |   38 ++++++++++++++++++++++++++++++++++++--
 wpa_supplicant/defconfig        |    1 +
 4 files changed, 47 insertions(+), 4 deletions(-)

Patch

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 2da58c9..0f306dd 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -298,8 +298,11 @@  void wpa_ctrl_cleanup(void);
 #endif /* ANDROID */
 
 #ifdef CONFIG_CTRL_IFACE_UDP
-#define WPA_CTRL_IFACE_PORT 9877
-#define WPA_GLOBAL_CTRL_IFACE_PORT 9878
+/* Port range for multiple wpa_supplicant instances and multiple VIFs */
+#define WPA_GLOBAL_CTRL_IFACE_PORT 9871
+#define WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT 20
+#define WPA_CTRL_IFACE_PORT (WPA_GLOBAL_CTRL_IFACE_PORT + WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT)
+#define WPA_CTRL_IFACE_PORT_LIMIT 50
 #endif /* CONFIG_CTRL_IFACE_UDP */
 
 
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index e8fe6f2..55d2d0d 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -1175,6 +1175,11 @@  endif
 ifeq ($(CONFIG_CTRL_IFACE), named_pipe)
 CFLAGS += -DCONFIG_CTRL_IFACE_NAMED_PIPE
 endif
+ifeq ($(CONFIG_CTRL_IFACE), udp-remote)
+CONFIG_CTRL_IFACE=udp
+CFLAGS += -DCONFIG_CTRL_IFACE_UDP
+CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE
+endif
 OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o
 endif
 
diff --git a/wpa_supplicant/ctrl_iface_udp.c b/wpa_supplicant/ctrl_iface_udp.c
index c831e6c..cf6effe 100644
--- a/wpa_supplicant/ctrl_iface_udp.c
+++ b/wpa_supplicant/ctrl_iface_udp.c
@@ -163,6 +163,8 @@  static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
 		perror("recvfrom(ctrl_iface)");
 		return;
 	}
+
+#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
 	if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
 		/*
 		 * The OS networking stack is expected to drop this kind of
@@ -174,6 +176,8 @@  static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
 			   "source %s", inet_ntoa(from.sin_addr));
 		return;
 	}
+#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+
 	buf[res] = '\0';
 
 	if (os_strcmp(buf, "GET_COOKIE") == 0) {
@@ -266,6 +270,7 @@  wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
 {
 	struct ctrl_iface_priv *priv;
 	struct sockaddr_in addr;
+	int port = WPA_CTRL_IFACE_PORT;
 
 	priv = os_zalloc(sizeof(*priv));
 	if (priv == NULL)
@@ -285,13 +290,25 @@  wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
 
 	os_memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
+#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
+	addr.sin_addr.s_addr = INADDR_ANY;
+#else
 	addr.sin_addr.s_addr = htonl((127 << 24) | 1);
-	addr.sin_port = htons(WPA_CTRL_IFACE_PORT);
+#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+try_again:
+	addr.sin_port = htons(port);
 	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		port++;
+		if ((port - WPA_CTRL_IFACE_PORT) < WPA_CTRL_IFACE_PORT_LIMIT)
+			goto try_again;
 		perror("bind(AF_INET)");
 		goto fail;
 	}
 
+#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
+	wpa_msg(wpa_s, MSG_DEBUG, "ctrl_iface_init UDP port: %d\n", port);
+#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+
 	eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
 				 wpa_s, priv);
 	wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
@@ -442,6 +459,7 @@  static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
 		perror("recvfrom(ctrl_iface)");
 		return;
 	}
+#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
 	if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
 		/*
 		 * The OS networking stack is expected to drop this kind of
@@ -453,6 +471,8 @@  static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
 			   "source %s", inet_ntoa(from.sin_addr));
 		return;
 	}
+#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+
 	buf[res] = '\0';
 
 	if (os_strcmp(buf, "GET_COOKIE") == 0) {
@@ -502,6 +522,7 @@  wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
 {
 	struct ctrl_iface_global_priv *priv;
 	struct sockaddr_in addr;
+	int port = WPA_GLOBAL_CTRL_IFACE_PORT;
 
 	priv = os_zalloc(sizeof(*priv));
 	if (priv == NULL)
@@ -523,13 +544,26 @@  wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
 
 	os_memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
+#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
+	addr.sin_addr.s_addr = INADDR_ANY;
+#else
 	addr.sin_addr.s_addr = htonl((127 << 24) | 1);
-	addr.sin_port = htons(WPA_GLOBAL_CTRL_IFACE_PORT);
+#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+try_again:
+	addr.sin_port = htons(port);
 	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		port++;
+		if ((port - WPA_GLOBAL_CTRL_IFACE_PORT) < WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT)
+			goto try_again;
 		perror("bind(AF_INET)");
 		goto fail;
 	}
 
+#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
+	wpa_printf(MSG_DEBUG, "global_ctrl_iface_init UDP port: %d\n",
+		    WPA_GLOBAL_CTRL_IFACE_PORT);
+#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
+
 	eloop_register_read_sock(priv->sock,
 				 wpa_supplicant_global_ctrl_iface_receive,
 				 global, priv);
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index 849f244..4ecc39f 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -232,6 +232,7 @@  CONFIG_SMARTCARD=y
 # unix = UNIX domain sockets (default for Linux/*BSD)
 # udp = UDP sockets using localhost (127.0.0.1)
 # named_pipe = Windows Named Pipe (default for Windows)
+# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
 # y = use default (backwards compatibility)
 # If this option is commented out, control interface is not included in the
 # build.