X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fctrl_iface_udp.c;h=0dc0937ff0aa60d32758a2971681fd35a4968f2b;hb=fc1e2c0d91a15a13d30219a5f5d2878197368902;hp=4dd6ae3df11a69823a58bb2c038643df108e2681;hpb=f0e5d3b5c6c708f5c12ee8f87b4922ae272a7c72;p=mech_eap.git diff --git a/wpa_supplicant/ctrl_iface_udp.c b/wpa_supplicant/ctrl_iface_udp.c index 4dd6ae3..0dc0937 100644 --- a/wpa_supplicant/ctrl_iface_udp.c +++ b/wpa_supplicant/ctrl_iface_udp.c @@ -1,6 +1,6 @@ /* * WPA Supplicant / UDP socket -based control interface - * Copyright (c) 2004-2005, Jouni Malinen + * Copyright (c) 2004-2016, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -48,6 +48,12 @@ struct ctrl_iface_priv { u8 cookie[COOKIE_LEN]; }; +struct ctrl_iface_global_priv { + int sock; + struct wpa_ctrl_dst *ctrl_dst; + u8 cookie[COOKIE_LEN]; +}; + static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s, const char *ifname, int sock, @@ -56,6 +62,18 @@ static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s, size_t len); +static void wpas_ctrl_iface_free_dst(struct wpa_ctrl_dst *dst) +{ + struct wpa_ctrl_dst *prev; + + while (dst) { + prev = dst; + dst = dst->next; + os_free(prev); + } +} + + static int wpa_supplicant_ctrl_iface_attach(struct wpa_ctrl_dst **head, #ifdef CONFIG_CTRL_IFACE_UDP_IPV6 struct sockaddr_in6 *from, @@ -331,8 +349,25 @@ static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, const char *txt, size_t len) { struct wpa_supplicant *wpa_s = ctx; - if (wpa_s == NULL || wpa_s->ctrl_iface == NULL) + + if (!wpa_s) return; + + if (type != WPA_MSG_NO_GLOBAL && wpa_s->global->ctrl_iface) { + struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface; + + if (priv->ctrl_dst) { + wpa_supplicant_ctrl_iface_send( + wpa_s, + type != WPA_MSG_PER_INTERFACE ? + NULL : wpa_s->ifname, + priv->sock, &priv->ctrl_dst, level, txt, len); + } + } + + if (type == WPA_MSG_ONLY_GLOBAL || !wpa_s->ctrl_iface) + return; + wpa_supplicant_ctrl_iface_send(wpa_s, NULL, wpa_s->ctrl_iface->sock, &wpa_s->ctrl_iface->ctrl_dst, level, txt, len); @@ -343,6 +378,7 @@ struct ctrl_iface_priv * wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) { struct ctrl_iface_priv *priv; + char port_str[40]; int port = WPA_CTRL_IFACE_PORT; char *pos; #ifdef CONFIG_CTRL_IFACE_UDP_IPV6 @@ -404,13 +440,21 @@ try_again: #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { port--; - if ((WPA_CTRL_IFACE_PORT - port) < WPA_CTRL_IFACE_PORT_LIMIT && - !pos) + if ((WPA_CTRL_IFACE_PORT - port) < WPA_CTRL_IFACE_PORT_LIMIT) goto try_again; wpa_printf(MSG_ERROR, "bind(AF_INET): %s", strerror(errno)); goto fail; } + /* Update the ctrl_interface value to match the selected port */ + os_snprintf(port_str, sizeof(port_str), "udp:%d", port); + os_free(wpa_s->conf->ctrl_interface); + wpa_s->conf->ctrl_interface = os_strdup(port_str); + if (!wpa_s->conf->ctrl_interface) { + wpa_msg(wpa_s, MSG_ERROR, "Failed to malloc ctrl_interface"); + 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 */ @@ -431,8 +475,6 @@ fail: void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) { - struct wpa_ctrl_dst *dst, *prev; - if (priv->sock > -1) { eloop_unregister_read_sock(priv->sock); if (priv->ctrl_dst) { @@ -449,12 +491,7 @@ void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) priv->sock = -1; } - dst = priv->ctrl_dst; - while (dst) { - prev = dst; - dst = dst->next; - os_free(prev); - } + wpas_ctrl_iface_free_dst(priv->ctrl_dst); os_free(priv); } @@ -538,12 +575,6 @@ void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) /* Global ctrl_iface */ -struct ctrl_iface_global_priv { - int sock; - u8 cookie[COOKIE_LEN]; -}; - - static char * wpa_supplicant_global_get_cookie(struct ctrl_iface_global_priv *priv, size_t *reply_len) @@ -571,9 +602,13 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, struct ctrl_iface_global_priv *priv = sock_ctx; char buf[256], *pos; int res; +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + struct sockaddr_in6 from; +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ struct sockaddr_in from; +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ socklen_t fromlen = sizeof(from); - char *reply; + char *reply = NULL; size_t reply_len; u8 cookie[COOKIE_LEN]; @@ -586,6 +621,7 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, } #ifndef CONFIG_CTRL_IFACE_UDP_REMOTE +#ifndef CONFIG_CTRL_IFACE_UDP_IPV6 if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) { /* * The OS networking stack is expected to drop this kind of @@ -597,6 +633,7 @@ 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_IPV6 */ #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ buf[res] = '\0'; @@ -628,17 +665,34 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, while (*pos == ' ') pos++; - reply = wpa_supplicant_global_ctrl_iface_process(global, pos, - &reply_len); + if (os_strcmp(pos, "ATTACH") == 0) { + if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, + &from, fromlen)) + reply_len = 1; + else + reply_len = 2; + } else if (os_strcmp(pos, "DETACH") == 0) { + if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, + &from, fromlen)) + reply_len = 1; + else + reply_len = 2; + } else { + reply = wpa_supplicant_global_ctrl_iface_process(global, pos, + &reply_len); + } done: if (reply) { sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen); os_free(reply); - } else if (reply_len) { + } else if (reply_len == 1) { sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, fromlen); + } else if (reply_len == 2) { + sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from, + fromlen); } } @@ -705,6 +759,7 @@ try_again: eloop_register_read_sock(priv->sock, wpa_supplicant_global_ctrl_iface_receive, global, priv); + wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); return priv; @@ -723,5 +778,7 @@ wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv) eloop_unregister_read_sock(priv->sock); close(priv->sock); } + + wpas_ctrl_iface_free_dst(priv->ctrl_dst); os_free(priv); }