18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / UNIX domain socket -based control interface 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <sys/un.h> 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <sys/stat.h> 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <stddef.h> 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/version.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "drivers/driver.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ap_config.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ieee802_1x.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/wpa_auth.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ieee802_11.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/sta_info.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/wps_hostapd.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ctrl_iface_ap.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ap_drv_ops.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_defs.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_ctrl_dst { 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ctrl_dst *next; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t addrlen; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int debug_level; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int errors; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level, 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *buf, size_t len); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_attach(struct hostapd_data *hapd, 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un *from, 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen) 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ctrl_dst *dst; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = os_zalloc(sizeof(*dst)); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dst == NULL) 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un)); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst->addrlen = fromlen; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst->debug_level = MSG_INFO; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst->next = hapd->ctrl_dst; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->ctrl_dst = dst; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached", 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) from->sun_path, 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen - offsetof(struct sockaddr_un, sun_path)); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_detach(struct hostapd_data *hapd, 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un *from, 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ctrl_dst *dst, *prev = NULL; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = hapd->ctrl_dst; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dst) { 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fromlen == dst->addrlen && 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(from->sun_path, dst->addr.sun_path, 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen - offsetof(struct sockaddr_un, sun_path)) 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev == NULL) 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->ctrl_dst = dst->next; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = dst->next; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dst); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached", 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) from->sun_path, 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen - 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt offsetof(struct sockaddr_un, sun_path)); 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = dst; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = dst->next; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_level(struct hostapd_data *hapd, 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un *from, 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen, 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *level) 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ctrl_dst *dst; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = hapd->ctrl_dst; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dst) { 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fromlen == dst->addrlen && 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(from->sun_path, dst->addr.sun_path, 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen - offsetof(struct sockaddr_un, sun_path)) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor " 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "level", (u8 *) from->sun_path, fromlen - 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt offsetof(struct sockaddr_un, sun_path)); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst->debug_level = atoi(level); 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = dst->next; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd, 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txtaddr) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE NEW_STA %s", txtaddr); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(txtaddr, addr)) 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Add new STA " MACSTR " based on ctrl_iface " 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "notification", MAC2STR(addr)); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_sta_add(hapd, addr); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_new_assoc_sta(hapd, sta, 0); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 minor_reason_code, const u8 *addr) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *mgmt; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->send_frame == NULL) 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt = os_zalloc(sizeof(*mgmt) + 100); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mgmt == NULL) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "P2P: Disconnect STA " MACSTR 1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " with minor reason code %u (stype=%u)", 1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(addr), minor_reason_code, stype); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt->da, addr, ETH_ALEN); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (stype == WLAN_FC_STYPE_DEAUTH) { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.deauth.reason_code = 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) (&mgmt->u.deauth.reason_code + 1); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.disassoc.reason_code = 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) (&mgmt->u.disassoc.reason_code + 1); 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_VENDOR_SPECIFIC; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 4 + 3 + 1; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE24(pos, OUI_WFA); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = P2P_OUI_TYPE; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = P2P_ATTR_MINOR_REASON_CODE; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(pos, 1); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = minor_reason_code; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = hapd->driver->send_frame(hapd->drv_priv, (u8 *) mgmt, 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos - (u8 *) mgmt, 1); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(mgmt); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret < 0 ? -1 : 0; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd, 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txtaddr) 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s", 2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt txtaddr); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(txtaddr, addr)) 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(txtaddr, " test="); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt mgmt; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int encrypt; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->send_frame == NULL) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encrypt = atoi(pos); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&mgmt, 0, sizeof(mgmt)); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_DEAUTH); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt.da, addr, ETH_ALEN); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt.u.deauth.reason_code = 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt, 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE80211_HDRLEN + 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt.u.deauth), 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encrypt) < 0) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(txtaddr, " p2p="); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DEAUTH, 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt atoi(pos + 5), addr); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_deauthenticate(hapd, sta, 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (addr[0] == 0xff) 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_free_stas(hapd); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd, 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txtaddr) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", 2731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt txtaddr); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(txtaddr, addr)) 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(txtaddr, " test="); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt mgmt; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int encrypt; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->send_frame == NULL) 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encrypt = atoi(pos); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&mgmt, 0, sizeof(mgmt)); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_DISASSOC); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt.da, addr, ETH_ALEN); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt.u.disassoc.reason_code = 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt, 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE80211_HDRLEN + 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt.u.deauth), 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encrypt) < 0) 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(txtaddr, " p2p="); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DISASSOC, 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt atoi(pos + 5), addr); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_disassociate(hapd, sta, 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (addr[0] == 0xff) 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_free_stas(hapd); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NEED_AP_MLME 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd, 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txtaddr) 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(txtaddr, addr) || 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_send_sa_query_req(hapd, addr, trans_id); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* NEED_AP_MLME */ 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt) 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pin = os_strchr(txt, ' '); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *timeout_txt; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int timeout; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr_buf[ETH_ALEN], *addr = NULL; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pin == NULL) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pin++ = '\0'; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout_txt = os_strchr(pin, ' '); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout_txt) { 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *timeout_txt++ = '\0'; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = atoi(timeout_txt); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(timeout_txt, ' '); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(pos, addr_buf) == 0) 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr = addr_buf; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = 0; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_wps_add_pin(hapd, addr, txt, pin, timeout); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_wps_check_pin( 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd, char *cmd, char *buf, size_t buflen) 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char pin[9]; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN", 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) cmd, os_strlen(cmd)); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (pos = cmd, len = 0; *pos != '\0'; pos++) { 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos < '0' || *pos > '9') 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pin[len++] = *pos; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == 9) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Too long PIN"); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != 4 && len != 8) { 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len); 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pin[len] = '\0'; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == 8) { 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int pin_val; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pin_val = atoi(pin); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wps_pin_valid(pin_val)) { 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit"); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n"); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen) 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf, buflen, "%s", pin); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= buflen) 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_OOB 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt) 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *path, *method, *name; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt path = os_strchr(txt, ' '); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (path == NULL) 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *path++ = '\0'; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = os_strchr(path, ' '); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (method == NULL) 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *method++ = '\0'; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = os_strchr(method, ' '); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name != NULL) 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *name++ = '\0'; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_wps_start_oob(hapd, txt, path, method, name); 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_OOB */ 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt, 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int timeout = 300; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin_txt; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(txt, ' '); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(txt, "disable") == 0) { 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_wps_ap_pin_disable(hapd); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_snprintf(buf, buflen, "OK\n"); 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(txt, "random") == 0) { 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = atoi(pos); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pin_txt = hostapd_wps_ap_pin_random(hapd, timeout); 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pin_txt == NULL) 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_snprintf(buf, buflen, "%s", pin_txt); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(txt, "get") == 0) { 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pin_txt = hostapd_wps_ap_pin_get(hapd); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pin_txt == NULL) 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_snprintf(buf, buflen, "%s", pin_txt); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(txt, "set") == 0) { 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pin; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pin = pos; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(pos, ' '); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = atoi(pos); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen(pin) > buflen) 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_wps_ap_pin_set(hapd, pin, timeout) < 0) 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_snprintf(buf, buflen, "%s", pin); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_wps_config(struct hostapd_data *hapd, char *txt) 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ssid, *auth, *encr = NULL, *key = NULL; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = txt; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(txt, ' '); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!pos) 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth = pos; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(pos, ' '); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = pos; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(pos, ' '); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = pos; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_wps_config_ap(hapd, ssid, auth, encr, key); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd, 5251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *cmd) 5261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 5271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 addr[ETH_ALEN]; 5281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *url; 5291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 buf[1000], *pos; 5301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct ieee80211_mgmt *mgmt; 5311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t url_len; 5321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hwaddr_aton(cmd, addr)) 5341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 5351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt url = cmd + 17; 5361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (*url != ' ') 5371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 5381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt url++; 5391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt url_len = os_strlen(url); 5401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (url_len > 255) 5411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 5421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(buf, 0, sizeof(buf)); 5441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt = (struct ieee80211_mgmt *) buf; 5451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 5461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WLAN_FC_STYPE_ACTION); 5471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(mgmt->da, addr, ETH_ALEN); 5481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN); 5491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN); 5501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.category = WLAN_ACTION_WNM; 5511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ; 5521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.bss_tm_req.dialog_token = 1; 5531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.bss_tm_req.req_mode = 5541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT; 5551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0); 5561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.bss_tm_req.validity_interval = 0; 5571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos = mgmt->u.action.u.bss_tm_req.variable; 5591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Session Information URL */ 5611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *pos++ = url_len; 5621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(pos, url, url_len); 5631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += url_len; 5641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) { 5661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to send BSS Transition " 5671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "Management Request frame"); 5681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 5691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 5701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 5721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 5731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd, 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos, *end; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n" 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ssid=%s\n", 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(hapd->own_addr), 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.ssid); 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "wps_state=%s\n", 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->wps_state == 0 ? "disabled" : 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (hapd->conf->wps_state == 1 ? "not configured" : 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configured")); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wps_state && hapd->conf->wpa && 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wpa_passphrase) { 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "passphrase=%s\n", 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wpa_passphrase); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wps_state && hapd->conf->wpa && 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wpa_psk && 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wpa_psk->group) { 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char hex[PMK_LEN * 2 + 1]; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(hex, sizeof(hex), 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wpa_psk->psk, PMK_LEN); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "psk=%s\n", hex); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa && hapd->conf->wpa_key_mgmt) { 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "key_mgmt="); 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) { 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "WPA-PSK "); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "WPA-EAP "); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) { 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "FT-PSK "); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "FT-EAP "); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "WPA-PSK-SHA256 "); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "WPA-EAP-SHA256 "); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "\n"); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa && hapd->conf->wpa_group == WPA_CIPHER_CCMP) { 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "group_cipher=CCMP\n"); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->conf->wpa && 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->wpa_group == WPA_CIPHER_TKIP) { 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "group_cipher=TKIP\n"); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->wpa & WPA_PROTO_RSN) && hapd->conf->rsn_pairwise) { 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "rsn_pairwise_cipher="); 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->rsn_pairwise & WPA_CIPHER_CCMP) { 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "CCMP "); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->rsn_pairwise & WPA_CIPHER_TKIP) { 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "TKIP "); 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "\n"); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->wpa & WPA_PROTO_WPA) && hapd->conf->wpa_pairwise) { 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "wpa_pairwise_cipher="); 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_pairwise & WPA_CIPHER_CCMP) { 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "CCMP "); 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa_pairwise & WPA_CIPHER_TKIP) { 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "TKIP "); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "\n"); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *value; 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt value = os_strchr(cmd, ' '); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (value == NULL) 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *value++ = '\0'; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value); 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (0) { 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_TESTING 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcasecmp(cmd, "wps_version_number") == 0) { 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt long int val; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = strtol(value, NULL, 0); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (val < 0 || val > 0xff) { 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Invalid " 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_version_number %ld", val); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_version_number = val; 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS " 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "version %u.%u", 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wps_version_number & 0xf0) >> 4, 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_version_number & 0x0f); 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_wps_update_ie(hapd); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) { 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_testing_dummy_cred = atoi(value); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d", 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_testing_dummy_cred); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_TESTING */ 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd, 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(cmd, "version") == 0) { 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(buf, buflen, "%s", VERSION_STR); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || (unsigned int) res >= buflen) 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *sock_ctx) 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = eloop_ctx; 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un from; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen = sizeof(from); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *reply; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const int reply_size = 4096; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reply_len; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int level = MSG_DEBUG; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) &from, &fromlen); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("recvfrom(ctrl_iface)"); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[res] = '\0'; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(buf, "PING") == 0) 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt level = MSG_EXCESSIVE; 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(level, "RX ctrl_iface", (u8 *) buf, res); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply = os_malloc(reply_size); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reply == NULL) { 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen); 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply, "OK\n", 3); 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = 3; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(buf, "PING") == 0) { 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply, "PONG\n", 5); 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = 5; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "RELOG", 5) == 0) { 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_reopen_file() < 0) 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(buf, "MIB") == 0) { 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = ieee802_11_get_mib(hapd, reply, reply_size); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reply_len >= 0) { 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_get_mib(hapd->wpa_auth, reply + reply_len, 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size - reply_len); 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len += res; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reply_len >= 0) { 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ieee802_1x_get_mib(hapd, reply + reply_len, 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size - reply_len); 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len += res; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reply_len >= 0) { 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = radius_client_get_mib(hapd->radius, 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply + reply_len, 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size - reply_len); 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len += res; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(buf, "STA-FIRST") == 0) { 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = hostapd_ctrl_iface_sta_first(hapd, reply, 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "STA ", 4) == 0) { 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = hostapd_ctrl_iface_sta(hapd, buf + 4, reply, 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size); 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size); 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(buf, "ATTACH") == 0) { 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_attach(hapd, &from, fromlen)) 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(buf, "DETACH") == 0) { 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_detach(hapd, &from, fromlen)) 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "LEVEL ", 6) == 0) { 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_level(hapd, &from, fromlen, 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + 6)) 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "NEW_STA ", 8) == 0) { 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_new_sta(hapd, buf + 8)) 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_deauthenticate(hapd, buf + 15)) 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) { 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_disassociate(hapd, buf + 13)) 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NEED_AP_MLME 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) { 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_sa_query(hapd, buf + 9)) 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* NEED_AP_MLME */ 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8)) 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) { 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = hostapd_ctrl_iface_wps_check_pin( 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, buf + 14, reply, reply_size); 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(buf, "WPS_PBC") == 0) { 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_wps_button_pushed(hapd, NULL)) 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_OOB 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) { 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_wps_oob(hapd, buf + 8)) 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_OOB */ 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) { 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11, 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply, reply_size); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "WPS_CONFIG ", 11) == 0) { 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_wps_config(hapd, buf + 11) < 0) 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 9281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (os_strncmp(buf, "ESS_DISASSOC ", 13) == 0) { 9291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_ctrl_iface_ess_disassoc(hapd, buf + 13)) 9301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt reply_len = -1; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strcmp(buf, "GET_CONFIG") == 0) { 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = hostapd_ctrl_iface_get_config(hapd, reply, 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "SET ", 4) == 0) { 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_ctrl_iface_set(hapd, buf + 4)) 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = -1; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(buf, "GET ", 4) == 0) { 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply, 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_size); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = 16; 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reply_len < 0) { 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply, "FAIL\n", 5); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply_len = 5; 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen); 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(reply); 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * hostapd_ctrl_iface_path(struct hostapd_data *hapd) 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ctrl_interface == NULL) 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(hapd->conf->ctrl_interface) + 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(hapd->conf->iface) + 2; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, len, "%s/%s", 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ctrl_interface, hapd->conf->iface); 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[len - 1] = '\0'; 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_ctrl_iface_msg_cb(void *ctx, int level, 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txt, size_t len) 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd == NULL) 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_ctrl_iface_send(hapd, level, txt, len); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_ctrl_iface_init(struct hostapd_data *hapd) 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int s = -1; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *fname = NULL; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->ctrl_sock = -1; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ctrl_interface == NULL) 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mkdir(hapd->conf->ctrl_interface, S_IRWXU | S_IRWXG) < 0) { 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (errno == EEXIST) { 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Using existing control " 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface directory."); 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("mkdir[ctrl_interface]"); 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ctrl_interface_gid_set && 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chown(hapd->conf->ctrl_interface, 0, 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ctrl_interface_gid) < 0) { 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("chown[ctrl_interface]"); 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen(hapd->conf->ctrl_interface) + 1 + 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path)) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = socket(PF_UNIX, SOCK_DGRAM, 0); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s < 0) { 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("socket(PF_UNIX)"); 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __FreeBSD__ 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_len = sizeof(addr); 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __FreeBSD__ */ 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname = hostapd_ctrl_iface_path(hapd); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fname == NULL) 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path)); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(errno)); 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " allow connections - assuming it was left" 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "over from forced program termination"); 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (unlink(fname) < 0) { 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("unlink[ctrl_iface]"); 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not unlink " 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "existing ctrl_iface socket '%s'", 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname); 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("bind(PF_UNIX)"); 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ctrl_iface socket '%s'", fname); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "be in use - cannot override it"); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not used anymore", fname); 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(fname); 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname = NULL; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ctrl_interface_gid_set && 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chown(fname, 0, hapd->conf->ctrl_interface_gid) < 0) { 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("chown[ctrl_interface/ifname]"); 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("chmod[ctrl_interface/ifname]"); 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(fname); 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->ctrl_sock = s; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd, 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->msg_ctx = hapd; 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s >= 0) 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(s); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fname) { 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(fname); 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(fname); 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_ctrl_iface_deinit(struct hostapd_data *hapd) 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ctrl_dst *dst, *prev; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->ctrl_sock > -1) { 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *fname; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(hapd->ctrl_sock); 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(hapd->ctrl_sock); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->ctrl_sock = -1; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname = hostapd_ctrl_iface_path(hapd); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fname) 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(fname); 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(fname); 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ctrl_interface && 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rmdir(hapd->conf->ctrl_interface) < 0) { 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (errno == ENOTEMPTY) { 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Control interface " 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "directory not empty - leaving it " 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "behind"); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("rmdir[ctrl_interface]"); 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = hapd->ctrl_dst; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dst) { 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = dst; 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = dst->next; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level, 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *buf, size_t len) 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ctrl_dst *dst, *next; 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct msghdr msg; 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int idx; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct iovec io[2]; 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char levelstr[10]; 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = hapd->ctrl_dst; 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->ctrl_sock < 0 || dst == NULL) 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[0].iov_base = levelstr; 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[0].iov_len = os_strlen(levelstr); 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[1].iov_base = (char *) buf; 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt io[1].iov_len = len; 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_iov = io; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_iovlen = 2; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = 0; 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dst) { 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = dst->next; 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (level >= dst->debug_level) { 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send", 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) dst->addr.sun_path, dst->addrlen - 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt offsetof(struct sockaddr_un, sun_path)); 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_name = &dst->addr; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.msg_namelen = dst->addrlen; 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sendmsg(hapd->ctrl_sock, &msg, 0) < 0) { 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _errno = errno; 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: " 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d - %s", 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx, errno, strerror(errno)); 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst->errors++; 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dst->errors > 10 || _errno == ENOENT) { 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_ctrl_iface_detach( 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, &dst->addr, 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst->addrlen); 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst->errors = 0; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx++; 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dst = next; 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1181