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