diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index 2da58c962..27b828276 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 +/* Port range for multiple wpa_supplicant instances and multiple VIFs */ #define WPA_CTRL_IFACE_PORT 9877 +#define WPA_CTRL_IFACE_PORT_LIMIT 50 /* decremented from start */ #define WPA_GLOBAL_CTRL_IFACE_PORT 9878 +#define WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT 20 /* incremented from start */ #endif /* CONFIG_CTRL_IFACE_UDP */ diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index 27dda29d2..c45a51096 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -1151,6 +1151,11 @@ endif ifeq ($(CONFIG_CTRL_IFACE), named_pipe) L_CFLAGS += -DCONFIG_CTRL_IFACE_NAMED_PIPE endif +ifeq ($(CONFIG_CTRL_IFACE), udp-remote) +CONFIG_CTRL_IFACE=udp +L_CFLAGS += -DCONFIG_CTRL_IFACE_UDP +L_CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE +endif OBJS += ctrl_iface.c ctrl_iface_$(CONFIG_CTRL_IFACE).c endif diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index a7683dd26..4f79f0010 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 c831e6c91..994f9b18c 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 /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 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 ((WPA_CTRL_IFACE_PORT - 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", 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,8 @@ 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 +472,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 +523,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 +545,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 /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 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", 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 e2b6cbe42..711b4073a 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.