static void handle_assoc(struct hostapd_data *hapd, const struct ieee80211_mgmt *mgmt, size_t len, int reassoc) { u16 capab_info, listen_interval; u16 resp = WLAN_STATUS_SUCCESS; const u8 *pos; int left, i; struct sta_info *sta; if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : sizeof(mgmt->u.assoc_req))) { printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)" "\n", reassoc, (unsigned long) len); return; } if (reassoc) { capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info); listen_interval = le_to_host16( mgmt->u.reassoc_req.listen_interval); wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR " capab_info=0x%02x listen_interval=%d current_ap=" MACSTR, MAC2STR(mgmt->sa), capab_info, listen_interval, MAC2STR(mgmt->u.reassoc_req.current_ap)); left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); pos = mgmt->u.reassoc_req.variable; } else { capab_info = le_to_host16(mgmt->u.assoc_req.capab_info); listen_interval = le_to_host16( mgmt->u.assoc_req.listen_interval); wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR " capab_info=0x%02x listen_interval=%d", MAC2STR(mgmt->sa), capab_info, listen_interval); left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); pos = mgmt->u.assoc_req.variable; } sta = ap_get_sta(hapd, mgmt->sa); #ifdef CONFIG_IEEE80211R if (sta && sta->auth_alg == WLAN_AUTH_FT && (sta->flags & WLAN_STA_AUTH) == 0) { wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate " "prior to authentication since it is using " "over-the-DS FT", MAC2STR(mgmt->sa)); } else #endif /* CONFIG_IEEE80211R */ if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "Station tried to " "associate before authentication " "(aid=%d flags=0x%x)", sta ? sta->aid : -1, sta ? sta->flags : 0); send_deauth(hapd, mgmt->sa, WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA); return; } if (hapd->tkip_countermeasures) { resp = WLAN_REASON_MICHAEL_MIC_FAILURE; goto fail; } if (listen_interval > hapd->conf->max_listen_interval) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Too large Listen Interval (%d)", listen_interval); resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; goto fail; } /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ resp = check_assoc_ies(hapd, sta, pos, left, reassoc); if (resp != WLAN_STATUS_SUCCESS) goto fail; if (hostapd_get_aid(hapd, sta) < 0) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "No room for more AIDs"); resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; goto fail; } sta->capability = capab_info; sta->listen_interval = listen_interval; if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) sta->flags |= WLAN_STA_NONERP; for (i = 0; i < sta->supported_rates_len; i++) { if ((sta->supported_rates[i] & 0x7f) > 22) { sta->flags &= ~WLAN_STA_NONERP; break; } } if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) { sta->nonerp_set = 1; hapd->iface->num_sta_non_erp++; if (hapd->iface->num_sta_non_erp == 1) ieee802_11_set_beacons(hapd->iface); } if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) && !sta->no_short_slot_time_set) { sta->no_short_slot_time_set = 1; hapd->iface->num_sta_no_short_slot_time++; if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && hapd->iface->num_sta_no_short_slot_time == 1) ieee802_11_set_beacons(hapd->iface); } if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) sta->flags |= WLAN_STA_SHORT_PREAMBLE; else sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && !sta->no_short_preamble_set) { sta->no_short_preamble_set = 1; hapd->iface->num_sta_no_short_preamble++; if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && hapd->iface->num_sta_no_short_preamble == 1) ieee802_11_set_beacons(hapd->iface); } #ifdef CONFIG_IEEE80211N update_ht_state(hapd, sta); #endif /* CONFIG_IEEE80211N */ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "association OK (aid %d)", sta->aid); /* Station will be marked associated, after it acknowledges AssocResp */ #ifdef CONFIG_IEEE80211W if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) { wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out " "SA Query procedure", reassoc ? "re" : ""); /* TODO: Send a protected Disassociate frame to the STA using * the old key and Reason Code "Previous Authentication no * longer valid". Make sure this is only sent protected since * unprotected frame would be received by the STA that is now * trying to associate. */ } #endif /* CONFIG_IEEE80211W */ if (reassoc) { os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap, ETH_ALEN); } if (sta->last_assoc_req) os_free(sta->last_assoc_req); sta->last_assoc_req = os_malloc(len); if (sta->last_assoc_req) os_memcpy(sta->last_assoc_req, mgmt, len); /* Make sure that the previously registered inactivity timer will not * remove the STA immediately. */ sta->timeout_next = STA_NULLFUNC; fail: send_assoc_resp(hapd, sta, resp, reassoc, pos, left); }
static void wpa_driver_privsep_receive(int sock, void *eloop_ctx, void *sock_ctx) { struct wpa_driver_privsep_data *drv = eloop_ctx; u8 *buf, *event_buf; size_t event_len; int res, event; enum privsep_event e; struct sockaddr_un from; socklen_t fromlen = sizeof(from); const size_t buflen = 2000; buf = os_malloc(buflen); if (buf == NULL) return; res = recvfrom(sock, buf, buflen, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(priv_socket)"); os_free(buf); return; } wpa_printf(MSG_DEBUG, "privsep_driver: received %u bytes", res); if (res < (int) sizeof(int)) { wpa_printf(MSG_DEBUG, "Too short event message (len=%d)", res); return; } os_memcpy(&event, buf, sizeof(int)); event_buf = &buf[sizeof(int)]; event_len = res - sizeof(int); wpa_printf(MSG_DEBUG, "privsep: Event %d received (len=%lu)", event, (unsigned long) event_len); e = event; switch (e) { case PRIVSEP_EVENT_SCAN_RESULTS: wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL); break; case PRIVSEP_EVENT_ASSOC: wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOC, event_buf, event_len); break; case PRIVSEP_EVENT_DISASSOC: wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); break; case PRIVSEP_EVENT_ASSOCINFO: wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOCINFO, event_buf, event_len); break; case PRIVSEP_EVENT_MICHAEL_MIC_FAILURE: wpa_driver_privsep_event_michael_mic_failure( drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_INTERFACE_STATUS: wpa_driver_privsep_event_interface_status(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_PMKID_CANDIDATE: wpa_driver_privsep_event_pmkid_candidate(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_STKSTART: wpa_driver_privsep_event_stkstart(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_FT_RESPONSE: wpa_driver_privsep_event_ft_response(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_RX_EAPOL: wpa_driver_privsep_event_rx_eapol(drv->ctx, event_buf, event_len); break; } os_free(buf); }
int main(int argc, char *argv[]) { int warning_displayed = 0; int c; int daemonize = 0; if (os_program_init()) return -1; for (;;) { c = getopt(argc, argv, "a:BhG:i:p:P:s:v"); if (c < 0) break; switch (c) { case 'a': action_file = optarg; break; case 'B': daemonize = 1; break; case 'G': ping_interval = atoi(optarg); break; case 'h': usage(); return 0; case 'v': printf("%s\n", hostapd_cli_version); return 0; case 'i': os_free(ctrl_ifname); ctrl_ifname = os_strdup(optarg); break; case 'p': ctrl_iface_dir = optarg; break; case 'P': pid_file = optarg; break; case 's': client_socket_dir = optarg; break; default: usage(); return -1; } } interactive = (argc == optind) && (action_file == NULL); if (interactive) { printf("%s\n\n%s\n\n", hostapd_cli_version, cli_license); } if (eloop_init()) return -1; for (;;) { if (ctrl_ifname == NULL) { struct dirent *dent; DIR *dir = opendir(ctrl_iface_dir); if (dir) { while ((dent = readdir(dir))) { if (os_strcmp(dent->d_name, ".") == 0 || os_strcmp(dent->d_name, "..") == 0) continue; printf("Selected interface '%s'\n", dent->d_name); ctrl_ifname = os_strdup(dent->d_name); break; } closedir(dir); } } ctrl_conn = hostapd_cli_open_connection(ctrl_ifname); if (ctrl_conn) { if (warning_displayed) printf("Connection established.\n"); break; } if (!interactive) { perror("Failed to connect to hostapd - " "wpa_ctrl_open"); return -1; } if (!warning_displayed) { printf("Could not connect to hostapd - re-trying\n"); warning_displayed = 1; } os_sleep(1, 0); continue; } if (interactive || action_file) { if (wpa_ctrl_attach(ctrl_conn) == 0) { hostapd_cli_attached = 1; register_event_handler(ctrl_conn); } else { printf("Warning: Failed to attach to hostapd.\n"); if (action_file) return -1; } } if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) return -1; if (interactive) hostapd_cli_interactive(); else if (action_file) hostapd_cli_action(ctrl_conn); else wpa_request(ctrl_conn, argc - optind, &argv[optind]); unregister_event_handler(ctrl_conn); os_free(ctrl_ifname); eloop_destroy(); hostapd_cli_cleanup(); return 0; }
static void rx_data_bss_prot(struct wlantest *wt, const struct ieee80211_hdr *hdr, size_t hdrlen, const u8 *qos, const u8 *dst, const u8 *src, const u8 *data, size_t len) { struct wlantest_bss *bss, *bss2; struct wlantest_sta *sta, *sta2; int keyid; u16 fc = le_to_host16(hdr->frame_control); u8 *decrypted; size_t dlen; int tid; u8 pn[6], *rsc; struct wlantest_tdls *tdls = NULL, *found; const u8 *tk = NULL; int ptk_iter_done = 0; int try_ptk_iter = 0; int replay = 0; if (hdr->addr1[0] & 0x01) { rx_data_bss_prot_group(wt, hdr, hdrlen, qos, dst, src, data, len); return; } if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == (WLAN_FC_TODS | WLAN_FC_FROMDS)) { bss = bss_find(wt, hdr->addr1); if (bss) { sta = sta_find(bss, hdr->addr2); if (sta) { sta->counters[ WLANTEST_STA_COUNTER_PROT_DATA_TX]++; } if (!sta || !sta->ptk_set) { bss2 = bss_find(wt, hdr->addr2); if (bss2) { sta2 = sta_find(bss2, hdr->addr1); if (sta2 && (!sta || sta2->ptk_set)) { bss = bss2; sta = sta2; } } } } else { bss = bss_find(wt, hdr->addr2); if (!bss) return; sta = sta_find(bss, hdr->addr1); } } else if (fc & WLAN_FC_TODS) { bss = bss_get(wt, hdr->addr1); if (bss == NULL) return; sta = sta_get(bss, hdr->addr2); if (sta) sta->counters[WLANTEST_STA_COUNTER_PROT_DATA_TX]++; } else if (fc & WLAN_FC_FROMDS) { bss = bss_get(wt, hdr->addr2); if (bss == NULL) return; sta = sta_get(bss, hdr->addr1); } else { bss = bss_get(wt, hdr->addr3); if (bss == NULL) return; sta = sta_find(bss, hdr->addr2); sta2 = sta_find(bss, hdr->addr1); if (sta == NULL || sta2 == NULL) return; found = NULL; dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) { if ((tdls->init == sta && tdls->resp == sta2) || (tdls->init == sta2 && tdls->resp == sta)) { found = tdls; if (tdls->link_up) break; } } if (found) { if (!found->link_up) add_note(wt, MSG_DEBUG, "TDLS: Link not up, but Data " "frame seen"); tk = found->tpk.tk; tdls = found; } } if ((sta == NULL || (!sta->ptk_set && sta->pairwise_cipher != WPA_CIPHER_WEP40)) && tk == NULL) { add_note(wt, MSG_MSGDUMP, "No PTK known to decrypt the frame"); if (dl_list_empty(&wt->ptk)) return; try_ptk_iter = 1; } if (len < 4) { add_note(wt, MSG_INFO, "Too short encrypted data frame"); return; } if (sta == NULL) return; if (sta->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) && !(data[3] & 0x20)) { add_note(wt, MSG_INFO, "Expected TKIP/CCMP frame from " MACSTR " did not have ExtIV bit set to 1", MAC2STR(src)); return; } if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP) { if (data[3] & 0x1f) { add_note(wt, MSG_INFO, "TKIP frame from " MACSTR " used non-zero reserved bit", MAC2STR(hdr->addr2)); } if (data[1] != ((data[0] | 0x20) & 0x7f)) { add_note(wt, MSG_INFO, "TKIP frame from " MACSTR " used incorrect WEPSeed[1] (was 0x%x, " "expected 0x%x)", MAC2STR(hdr->addr2), data[1], (data[0] | 0x20) & 0x7f); } } else if (tk || sta->pairwise_cipher == WPA_CIPHER_CCMP) { if (data[2] != 0 || (data[3] & 0x1f) != 0) { add_note(wt, MSG_INFO, "CCMP frame from " MACSTR " used non-zero reserved bit", MAC2STR(hdr->addr2)); } } keyid = data[3] >> 6; if (keyid != 0) { add_note(wt, MSG_INFO, "Unexpected non-zero KeyID %d in " "individually addressed Data frame from " MACSTR, keyid, MAC2STR(hdr->addr2)); } if (qos) { tid = qos[0] & 0x0f; if (fc & WLAN_FC_TODS) sta->tx_tid[tid]++; else sta->rx_tid[tid]++; } else { tid = 0; if (fc & WLAN_FC_TODS) sta->tx_tid[16]++; else sta->rx_tid[16]++; } if (tk) { if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0) rsc = tdls->rsc_init[tid]; else rsc = tdls->rsc_resp[tid]; } else if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == (WLAN_FC_TODS | WLAN_FC_FROMDS)) { if (os_memcmp(sta->addr, hdr->addr2, ETH_ALEN) == 0) rsc = sta->rsc_tods[tid]; else rsc = sta->rsc_fromds[tid]; } else if (fc & WLAN_FC_TODS) rsc = sta->rsc_tods[tid]; else rsc = sta->rsc_fromds[tid]; if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP) tkip_get_pn(pn, data); else if (sta->pairwise_cipher == WPA_CIPHER_WEP40) goto skip_replay_det; else ccmp_get_pn(pn, data); if (os_memcmp(pn, rsc, 6) <= 0) { u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); add_note(wt, MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u%s", MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3), WLAN_GET_SEQ_SEQ(seq_ctrl), WLAN_GET_SEQ_FRAG(seq_ctrl), (le_to_host16(hdr->frame_control) & WLAN_FC_RETRY) ? " Retry" : ""); wpa_hexdump(MSG_INFO, "RX PN", pn, 6); wpa_hexdump(MSG_INFO, "RSC", rsc, 6); replay = 1; } skip_replay_det: if (tk) { if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256) decrypted = ccmp_256_decrypt(tk, hdr, data, len, &dlen); else if (sta->pairwise_cipher == WPA_CIPHER_GCMP || sta->pairwise_cipher == WPA_CIPHER_GCMP_256) decrypted = gcmp_decrypt(tk, sta->ptk.tk_len, hdr, data, len, &dlen); else decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen); } else if (sta->pairwise_cipher == WPA_CIPHER_TKIP) { decrypted = tkip_decrypt(sta->ptk.tk, hdr, data, len, &dlen); } else if (sta->pairwise_cipher == WPA_CIPHER_WEP40) { decrypted = wep_decrypt(wt, hdr, data, len, &dlen); } else if (sta->ptk_set) { if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256) decrypted = ccmp_256_decrypt(sta->ptk.tk, hdr, data, len, &dlen); else if (sta->pairwise_cipher == WPA_CIPHER_GCMP || sta->pairwise_cipher == WPA_CIPHER_GCMP_256) decrypted = gcmp_decrypt(sta->ptk.tk, sta->ptk.tk_len, hdr, data, len, &dlen); else decrypted = ccmp_decrypt(sta->ptk.tk, hdr, data, len, &dlen); } else { decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data, len, &dlen); ptk_iter_done = 1; } if (!decrypted && !ptk_iter_done) { decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data, len, &dlen); if (decrypted) { add_note(wt, MSG_DEBUG, "Current PTK did not work, but found a match from all known PTKs"); } } if (decrypted) { u16 fc = le_to_host16(hdr->frame_control); const u8 *peer_addr = NULL; if (!(fc & (WLAN_FC_FROMDS | WLAN_FC_TODS))) peer_addr = hdr->addr1; if (!replay) os_memcpy(rsc, pn, 6); rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted, dlen, 1, peer_addr); write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen, decrypted, dlen); } else if (!try_ptk_iter) add_note(wt, MSG_DEBUG, "Failed to decrypt frame"); os_free(decrypted); }
LOCAL ICACHE_FLASH_ATTR void parse_url(char *precv, URL_Frame *purl_frame) { char *str = NULL; uint8 length = 0; char *pbuffer = NULL; char *pbufer = NULL; if (purl_frame == NULL || precv == NULL) { return; } pbuffer = (char *)os_strstr(precv, "Host:"); if (pbuffer != NULL) { length = pbuffer - precv; pbufer = (char *)os_zalloc(length + 1); pbuffer = pbufer; os_memcpy(pbuffer, precv, length); os_memset(purl_frame->pSelect, 0, URLSize); os_memset(purl_frame->pCommand, 0, URLSize); os_memset(purl_frame->pFilename, 0, URLSize); if (os_strncmp(pbuffer, "GET ", 4) == 0) { purl_frame->Type = GET; pbuffer += 4; } else if (os_strncmp(pbuffer, "POST ", 5) == 0) { purl_frame->Type = POST; pbuffer += 5; } pbuffer ++; str = (char *)os_strstr(pbuffer, "?"); if (str != NULL) { length = str - pbuffer; os_memcpy(purl_frame->pSelect, pbuffer, length); str ++; pbuffer = (char *)os_strstr(str, "="); if (pbuffer != NULL) { length = pbuffer - str; os_memcpy(purl_frame->pCommand, str, length); pbuffer ++; str = (char *)os_strstr(pbuffer, "&"); if (str != NULL) { length = str - pbuffer; os_memcpy(purl_frame->pFilename, pbuffer, length); } else { str = (char *)os_strstr(pbuffer, " HTTP"); if (str != NULL) { length = str - pbuffer; os_memcpy(purl_frame->pFilename, pbuffer, length); } } } } os_free(pbufer); } else { return; } }
int main(int argc, char *argv[]) { struct hapd_interfaces interfaces; int ret = 1; size_t i, j; int c, debug = 0, daemonize = 0; char *pid_file = NULL; const char *log_file = NULL; const char *entropy_file = NULL; char **bss_config = NULL, **tmp_bss; size_t num_bss_configs = 0; #ifdef CONFIG_DEBUG_LINUX_TRACING int enable_trace_dbg = 0; #endif /* CONFIG_DEBUG_LINUX_TRACING */ if (os_program_init()) return -1; os_memset(&interfaces, 0, sizeof(interfaces)); interfaces.reload_config = hostapd_reload_config; interfaces.config_read_cb = hostapd_config_read; interfaces.for_each_interface = hostapd_for_each_interface; interfaces.ctrl_iface_init = hostapd_ctrl_iface_init; interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit; interfaces.driver_init = hostapd_driver_init; interfaces.global_iface_path = NULL; interfaces.global_iface_name = NULL; interfaces.global_ctrl_sock = -1; for (;;) { c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:"); if (c < 0) break; switch (c) { case 'h': usage(); break; case 'd': debug++; if (wpa_debug_level > 0) wpa_debug_level--; break; case 'B': daemonize++; break; case 'e': entropy_file = optarg; break; case 'f': log_file = optarg; break; case 'K': wpa_debug_show_keys++; break; case 'P': os_free(pid_file); pid_file = os_rel2abs_path(optarg); break; case 't': wpa_debug_timestamp++; break; #ifdef CONFIG_DEBUG_LINUX_TRACING case 'T': enable_trace_dbg = 1; break; #endif /* CONFIG_DEBUG_LINUX_TRACING */ case 'v': show_version(); exit(1); break; case 'g': if (hostapd_get_global_ctrl_iface(&interfaces, optarg)) return -1; break; case 'G': if (hostapd_get_ctrl_iface_group(&interfaces, optarg)) return -1; break; case 'b': tmp_bss = os_realloc_array(bss_config, num_bss_configs + 1, sizeof(char *)); if (tmp_bss == NULL) goto out; bss_config = tmp_bss; bss_config[num_bss_configs++] = optarg; break; #ifdef CONFIG_WPS case 'u': return gen_uuid(optarg); #endif /* CONFIG_WPS */ default: usage(); break; } } if (optind == argc && interfaces.global_iface_path == NULL && num_bss_configs == 0) usage(); wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb); if (log_file) wpa_debug_open_file(log_file); else wpa_debug_setup_stdout(); #ifdef CONFIG_DEBUG_LINUX_TRACING if (enable_trace_dbg) { int tret = wpa_debug_open_linux_tracing(); if (tret) { wpa_printf(MSG_ERROR, "Failed to enable trace logging"); return -1; } } #endif /* CONFIG_DEBUG_LINUX_TRACING */ interfaces.count = argc - optind; if (interfaces.count || num_bss_configs) { interfaces.iface = os_calloc(interfaces.count + num_bss_configs, sizeof(struct hostapd_iface *)); if (interfaces.iface == NULL) { wpa_printf(MSG_ERROR, "malloc failed"); return -1; } } if (hostapd_global_init(&interfaces, entropy_file)) { wpa_printf(MSG_ERROR, "Failed to initilize global context"); return -1; } /* Allocate and parse configuration for full interface files */ for (i = 0; i < interfaces.count; i++) { interfaces.iface[i] = hostapd_interface_init(&interfaces, argv[optind + i], debug); if (!interfaces.iface[i]) { wpa_printf(MSG_ERROR, "Failed to initialize interface"); goto out; } } /* Allocate and parse configuration for per-BSS files */ for (i = 0; i < num_bss_configs; i++) { struct hostapd_iface *iface; char *fname; wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]); fname = os_strchr(bss_config[i], ':'); if (fname == NULL) { wpa_printf(MSG_ERROR, "Invalid BSS config identifier '%s'", bss_config[i]); goto out; } *fname++ = '\0'; iface = hostapd_interface_init_bss(&interfaces, bss_config[i], fname, debug); if (iface == NULL) goto out; for (j = 0; j < interfaces.count; j++) { if (interfaces.iface[j] == iface) break; } if (j == interfaces.count) { struct hostapd_iface **tmp; tmp = os_realloc_array(interfaces.iface, interfaces.count + 1, sizeof(struct hostapd_iface *)); if (tmp == NULL) { hostapd_interface_deinit_free(iface); goto out; } interfaces.iface = tmp; interfaces.iface[interfaces.count++] = iface; } } /* * Enable configured interfaces. Depending on channel configuration, * this may complete full initialization before returning or use a * callback mechanism to complete setup in case of operations like HT * co-ex scans, ACS, or DFS are needed to determine channel parameters. * In such case, the interface will be enabled from eloop context within * hostapd_global_run(). */ interfaces.terminate_on_error = interfaces.count; for (i = 0; i < interfaces.count; i++) { if (hostapd_driver_init(interfaces.iface[i]) || hostapd_setup_interface(interfaces.iface[i])) goto out; } hostapd_global_ctrl_iface_init(&interfaces); if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); goto out; } ret = 0; out: hostapd_global_ctrl_iface_deinit(&interfaces); /* Deinitialize all interfaces */ for (i = 0; i < interfaces.count; i++) { if (!interfaces.iface[i]) continue; interfaces.iface[i]->driver_ap_teardown = !!(interfaces.iface[i]->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); hostapd_interface_deinit_free(interfaces.iface[i]); } os_free(interfaces.iface); hostapd_global_deinit(pid_file); os_free(pid_file); if (log_file) wpa_debug_close_file(); wpa_debug_close_linux_tracing(); os_free(bss_config); os_program_deinit(); return ret; }
void eloop_run(void) { fd_set *rfds, *wfds, *efds; int res; struct timeval _tv; struct os_time tv, now; rfds = os_malloc(sizeof(*rfds)); wfds = os_malloc(sizeof(*wfds)); efds = os_malloc(sizeof(*efds)); if (rfds == NULL || wfds == NULL || efds == NULL) { printf("eloop_run - malloc failed\n"); goto out; } while (!eloop.terminate && (eloop.timeout || eloop.readers.count > 0 || eloop.writers.count > 0 || eloop.exceptions.count > 0)) { if (eloop.timeout) { os_get_time(&now); if (os_time_before(&now, &eloop.timeout->time)) os_time_sub(&eloop.timeout->time, &now, &tv); else tv.sec = tv.usec = 0; #if 0 printf("next timeout in %lu.%06lu sec\n", tv.sec, tv.usec); #endif _tv.tv_sec = tv.sec; _tv.tv_usec = tv.usec; } eloop_sock_table_set_fds(&eloop.readers, rfds); eloop_sock_table_set_fds(&eloop.writers, wfds); eloop_sock_table_set_fds(&eloop.exceptions, efds); res = select(eloop.max_sock + 1, rfds, wfds, efds, eloop.timeout ? &_tv : NULL); if (res < 0 && errno != EINTR && errno != 0) { perror("select"); goto out; } eloop_process_pending_signals(); /* check if some registered timeouts have occurred */ if (eloop.timeout) { struct eloop_timeout *tmp; os_get_time(&now); if (!os_time_before(&now, &eloop.timeout->time)) { tmp = eloop.timeout; eloop.timeout = eloop.timeout->next; tmp->handler(tmp->eloop_data, tmp->user_data); os_free(tmp); } } if (res <= 0) continue; eloop_sock_table_dispatch(&eloop.readers, rfds); eloop_sock_table_dispatch(&eloop.writers, wfds); eloop_sock_table_dispatch(&eloop.exceptions, efds); } out: os_free(rfds); os_free(wfds); os_free(efds); }
/** * @brief Delete MQTT client and free all memory * @param mqttClient: The mqtt client * @retval None */ void ICACHE_FLASH_ATTR mqtt_client_delete(MQTT_Client *mqttClient) { if (mqttClient == NULL) return; if (mqttClient->pCon != NULL) { mqtt_tcpclient_delete(mqttClient); } if (mqttClient->host != NULL) { os_free(mqttClient->host); mqttClient->host = NULL; } if (mqttClient->user_data != NULL) { os_free(mqttClient->user_data); mqttClient->user_data = NULL; } if (mqttClient->mqtt_state.in_buffer != NULL) { os_free(mqttClient->mqtt_state.in_buffer); mqttClient->mqtt_state.in_buffer = NULL; } if (mqttClient->mqtt_state.out_buffer != NULL) { os_free(mqttClient->mqtt_state.out_buffer); mqttClient->mqtt_state.out_buffer = NULL; } if (mqttClient->mqtt_state.outbound_message != NULL) { if (mqttClient->mqtt_state.outbound_message->data != NULL) { os_free(mqttClient->mqtt_state.outbound_message->data); mqttClient->mqtt_state.outbound_message->data = NULL; } } if (mqttClient->mqtt_state.mqtt_connection.buffer != NULL) { // Already freed but not NULL mqttClient->mqtt_state.mqtt_connection.buffer = NULL; } if (mqttClient->connect_info.client_id != NULL) { #ifdef PROTOCOL_NAMEv311 /* Don't attempt to free if it's the zero_len array */ if ( ((uint8_t*)mqttClient->connect_info.client_id) != zero_len_id ) os_free(mqttClient->connect_info.client_id); #else os_free(mqttClient->connect_info.client_id); #endif mqttClient->connect_info.client_id = NULL; } if (mqttClient->connect_info.username != NULL) { os_free(mqttClient->connect_info.username); mqttClient->connect_info.username = NULL; } if (mqttClient->connect_info.password != NULL) { os_free(mqttClient->connect_info.password); mqttClient->connect_info.password = NULL; } if (mqttClient->connect_info.will_topic != NULL) { os_free(mqttClient->connect_info.will_topic); mqttClient->connect_info.will_topic = NULL; } if (mqttClient->connect_info.will_message != NULL) { os_free(mqttClient->connect_info.will_message); mqttClient->connect_info.will_message = NULL; } if (mqttClient->msgQueue.buf != NULL) { os_free(mqttClient->msgQueue.buf); mqttClient->msgQueue.buf = NULL; } // Initialize state mqttClient->connState = WIFI_INIT; // Clear callback functions to avoid abnormal callback mqttClient->connectedCb = NULL; mqttClient->disconnectedCb = NULL; mqttClient->publishedCb = NULL; mqttClient->timeoutCb = NULL; mqttClient->dataCb = NULL; MQTT_INFO("MQTT: client already deleted\r\n"); }
int main(int argc, char *argv[]) { int c, i; struct wpa_interface *ifaces, *iface; int iface_count, exitcode = -1; struct wpa_params params; struct wpa_global *global; if (os_program_init()) return -1; os_memset(¶ms, 0, sizeof(params)); params.wpa_debug_level = MSG_INFO; iface = ifaces = os_zalloc(sizeof(struct wpa_interface)); if (ifaces == NULL) return -1; iface_count = 1; wpa_supplicant_fd_workaround(1); for (;;) { c = getopt(argc, argv, "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuv::W"); if (c < 0) break; switch (c) { case 'b': iface->bridge_ifname = optarg; break; case 'B': params.daemonize++; break; case 'c': iface->confname = optarg; break; case 'C': iface->ctrl_interface = optarg; break; case 'D': iface->driver = optarg; break; case 'd': #ifdef CONFIG_NO_STDOUT_DEBUG printf("Debugging disabled with " "CONFIG_NO_STDOUT_DEBUG=y build time " "option.\n"); goto out; #else /* CONFIG_NO_STDOUT_DEBUG */ params.wpa_debug_level--; break; #endif /* CONFIG_NO_STDOUT_DEBUG */ case 'e': params.entropy_file = optarg; break; #ifdef CONFIG_DEBUG_FILE case 'f': params.wpa_debug_file_path = optarg; break; #endif /* CONFIG_DEBUG_FILE */ case 'g': params.ctrl_interface = optarg; break; case 'G': params.ctrl_interface_group = optarg; break; case 'h': usage(); exitcode = 0; goto out; case 'H': iface->hostapd_ctrl = optarg; break; case 'i': iface->ifname = optarg; break; case 'I': iface->confanother = optarg; break; case 'K': params.wpa_debug_show_keys++; break; case 'L': license(); exitcode = 0; goto out; case 'o': params.override_driver = optarg; break; case 'O': params.override_ctrl_interface = optarg; break; case 'p': iface->driver_param = optarg; break; case 'P': os_free(params.pid_file); params.pid_file = os_rel2abs_path(optarg); break; case 'q': params.wpa_debug_level++; break; #ifdef CONFIG_DEBUG_SYSLOG case 's': params.wpa_debug_syslog++; break; #endif /* CONFIG_DEBUG_SYSLOG */ #ifdef CONFIG_DEBUG_LINUX_TRACING case 'T': params.wpa_debug_tracing++; break; #endif /* CONFIG_DEBUG_LINUX_TRACING */ case 't': params.wpa_debug_timestamp++; break; #ifdef CONFIG_DBUS case 'u': params.dbus_ctrl_interface = 1; break; #endif /* CONFIG_DBUS */ case 'v': if (optarg) { exitcode = !has_feature(optarg); } else { printf("%s\n", wpa_supplicant_version); exitcode = 0; } goto out; case 'W': params.wait_for_monitor++; break; case 'N': iface_count++; iface = os_realloc_array(ifaces, iface_count, sizeof(struct wpa_interface)); if (iface == NULL) goto out; ifaces = iface; iface = &ifaces[iface_count - 1]; os_memset(iface, 0, sizeof(*iface)); break; default: usage(); exitcode = 0; goto out; } } exitcode = 0; global = wpa_supplicant_init(¶ms); if (global == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant"); exitcode = -1; goto out; } else { wpa_printf(MSG_INFO, "Successfully initialized " "wpa_supplicant"); } for (i = 0; exitcode == 0 && i < iface_count; i++) { struct wpa_supplicant *wpa_s; if ((ifaces[i].confname == NULL && ifaces[i].ctrl_interface == NULL) || ifaces[i].ifname == NULL) { if (iface_count == 1 && (params.ctrl_interface || params.dbus_ctrl_interface)) break; usage(); exitcode = -1; break; } wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]); if (wpa_s == NULL) { exitcode = -1; break; } #ifdef CONFIG_P2P if (wpa_s->global->p2p == NULL && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) && wpas_p2p_add_p2pdev_interface(wpa_s) < 0) exitcode = -1; #endif /* CONFIG_P2P */ } if (exitcode == 0) exitcode = wpa_supplicant_run(global); wpa_supplicant_deinit(global); out: wpa_supplicant_fd_workaround(0); os_free(ifaces); os_free(params.pid_file); os_program_deinit(); return exitcode; }
int MDNSResponder::queryService(char *service, char *proto) { #ifdef MDNS_DEBUG_TX Serial.printf("queryService %s %s\n", service, proto); #endif if (_query != 0) { os_free(_query); _query = 0; } _query = (struct MDNSQuery*)(os_malloc(sizeof(struct MDNSQuery))); os_strcpy(_query->_service, service); os_strcpy(_query->_proto, proto); _newQuery = true; char underscore[] = "_"; // build service name with _ char serviceName[os_strlen(service) + 2]; os_strcpy(serviceName, underscore); os_strcat(serviceName, service); size_t serviceNameLen = os_strlen(serviceName); //build proto name with _ char protoName[5]; os_strcpy(protoName, underscore); os_strcat(protoName, proto); size_t protoNameLen = 4; //local string char localName[] = "local"; size_t localNameLen = 5; //terminator char terminator[] = "\0"; // Only supports sending one PTR query uint8_t questionCount = 1; // Write the header _conn->flush(); uint8_t head[12] = { 0x00, 0x00, //ID = 0 0x00, 0x00, //Flags = response + authoritative answer 0x00, questionCount, //Question count 0x00, 0x00, //Answer count 0x00, 0x00, //Name server records 0x00, 0x00 //Additional records }; _conn->append(reinterpret_cast<const char*>(head), 12); // Only supports sending one PTR query // Send the Name field (eg. "_http._tcp.local") _conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // lenght of "_" + service _conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_" + service _conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // lenght of "_" + proto _conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_" + proto _conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // lenght of "local" _conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local" _conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator //Send the type and class uint8_t ptrAttrs[4] = { 0x00, 0x0c, //PTR record query 0x00, 0x01 //Class IN }; _conn->append(reinterpret_cast<const char*>(ptrAttrs), 4); _waitingForAnswers = true; _conn->send(); #ifdef MDNS_DEBUG_TX Serial.println("Waiting for answers.."); #endif delay(1000); _waitingForAnswers = false; return _getNumAnswers(); }
void MDNSResponder::_parsePacket() { int i; char tmp; bool serviceParsed = false; bool protoParsed = false; bool localParsed = false; char hostName[255]; uint8_t hostNameLen; char serviceName[32]; uint8_t serviceNameLen; uint16_t servicePort = 0; char protoName[32]; protoName[0] = 0; uint8_t protoNameLen = 0; uint16_t packetHeader[6]; for (i = 0; i<6; i++) packetHeader[i] = _conn_read16(); if ((packetHeader[1] & 0x8000) != 0) { // Read answers #ifdef MDNS_DEBUG_RX Serial.printf("Reading answers RX: REQ, ID:%u, Q:%u, A:%u, NS:%u, ADD:%u\n", packetHeader[0], packetHeader[2], packetHeader[3], packetHeader[4], packetHeader[5]); #endif if (!_waitingForAnswers) { #ifdef MDNS_DEBUG_RX Serial.println("Not expecting any answers right now, returning"); #endif _conn->flush(); return; } int numAnswers = packetHeader[3]; // Assume that the PTR answer always comes first and that it is always accompanied by a TXT, SRV, AAAA (optional) and A answer in the same packet. if (numAnswers < 4) { #ifdef MDNS_DEBUG_RX Serial.println("Expected a packet with 4 answers, returning"); #endif _conn->flush(); return; } uint8_t tmp8; uint16_t answerPort = 0; uint8_t answerIp[4] = { 0,0,0,0 }; char answerHostName[255]; bool serviceMatch = false; MDNSAnswer *answer; uint8_t partsCollected = 0; // Clear answer list if (_newQuery) { int numAnswers = _getNumAnswers(); for (int n = numAnswers - 1; n >= 0; n--) { answer = _getAnswerFromIdx(n); os_free(answer->hostname); os_free(answer); answer = 0; } _answers = 0; _newQuery = false; } while (numAnswers--) { // Read name do { tmp8 = _conn_read8(); if (tmp8 & 0xC0) { // Compressed pointer (not supported) tmp8 = _conn_read8(); break; } if (tmp8 == 0x00) { // ?nd of name break; } _conn_readS(serviceName, tmp8); serviceName[tmp8] = '\0'; #ifdef MDNS_DEBUG_RX Serial.printf(" %d ", tmp8); for (int n = 0; n < tmp8; n++) { Serial.printf("%02x ", serviceName[n]); } Serial.println(); #endif if (serviceName[0] == '_') { if (strcmp(&serviceName[1], _query->_service) == 0) { serviceMatch = true; #ifdef MDNS_DEBUG_RX Serial.printf("found matching service: %s\n", _query->_service); #endif } } } while (true); uint16_t answerType = _conn_read16(); // Read type uint16_t answerClass = _conn_read16(); // Read class uint32_t answerTtl = _conn_read32(); // Read ttl uint16_t answerRdlength = _conn_read16(); // Read rdlength #ifdef MDNS_DEBUG_RX Serial.printf("type: %04x rdlength: %d\n", answerType, answerRdlength); #endif if (answerType == MDNS_TYPE_PTR) { partsCollected |= 0x01; _conn_readS(hostName, answerRdlength); // Read rdata #ifdef MDNS_DEBUG_RX for (int n = 0; n < answerRdlength; n++) { Serial.printf("%02x ", hostName[n]); } Serial.println(); #endif } else if (answerType == MDNS_TYPE_TXT) { partsCollected |= 0x02; _conn_readS(hostName, answerRdlength); // Read rdata #ifdef MDNS_DEBUG_RX for (int n = 0; n < answerRdlength; n++) { Serial.printf("%02x ", hostName[n]); } Serial.println(); #endif } else if (answerType == MDNS_TYPE_SRV) { partsCollected |= 0x04; uint16_t answerPrio = _conn_read16(); // Read priority uint16_t answerWeight = _conn_read16(); // Read weight answerPort = _conn_read16(); // Read port // Read hostname tmp8 = _conn_read8(); if (tmp8 & 0xC0) { // Compressed pointer (not supported) Serial.println("Skipping compressed pointer"); tmp8 = _conn_read8(); } else { _conn_readS(answerHostName, tmp8); answerHostName[tmp8] = '\0'; #ifdef MDNS_DEBUG_RX Serial.printf(" %d ", tmp8); for (int n = 0; n < tmp8; n++) { Serial.printf("%02x ", answerHostName[n]); } Serial.printf("\n%s\n", answerHostName); #endif if (answerRdlength - (6 + 1 + tmp8) > 0) { // Skip any remaining rdata _conn_readS(hostName, answerRdlength - (6 + 1 + tmp8)); } } } else if (answerType == MDNS_TYPE_A) { partsCollected |= 0x08; for (int i = 0; i < 4; i++) { answerIp[i] = _conn_read8(); } } else { #ifdef MDNS_DEBUG_RX Serial.printf("Ignoring unsupported type %d\n", tmp8); #endif for (int n = 0; n < answerRdlength; n++) (void)_conn_read8(); } if ((partsCollected == 0x0F) && serviceMatch) { #ifdef MDNS_DEBUG_RX Serial.println("All answers parsed, adding to _answers list.."); #endif // Add new answer to answer list if (_answers == 0) { _answers = (struct MDNSAnswer*)(os_malloc(sizeof(struct MDNSAnswer))); answer = _answers; } else { answer = _answers; while (answer->next != 0) { answer = _answers->next; } answer->next = (struct MDNSAnswer*)(os_malloc(sizeof(struct MDNSAnswer))); answer = answer->next; } answer->next = 0; answer->hostname = 0; // Populate new answer answer->port = answerPort; for (int i = 0; i < 4; i++) { answer->ip[i] = answerIp[i]; } answer->hostname = (char *)os_malloc(strlen(answerHostName) + 1); os_strcpy(answer->hostname, answerHostName); } } _conn->flush(); return; } // PARSE REQUEST NAME hostNameLen = _conn_read8(); _conn_readS(hostName, hostNameLen); hostName[hostNameLen] = '\0'; if (hostName[0] == '_') { serviceParsed = true; memcpy(serviceName, hostName + 1, hostNameLen); serviceNameLen = hostNameLen - 1; hostNameLen = 0; } if (hostNameLen > 0 && !_hostName.equals(hostName) && !_instanceName.equals(hostName)) { #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_NO_HOST: %s\n", hostName); Serial.printf("hostname: %s\n", _hostName.c_str()); Serial.printf("instance: %s\n", _instanceName.c_str()); #endif _conn->flush(); return; } if (!serviceParsed) { serviceNameLen = _conn_read8(); _conn_readS(serviceName, serviceNameLen); serviceName[serviceNameLen] = '\0'; if (serviceName[0] == '_') { memmove(serviceName, serviceName + 1, serviceNameLen); serviceNameLen--; serviceParsed = true; } else if (serviceNameLen == 5 && strcmp("local", serviceName) == 0) { tmp = _conn_read8(); if (tmp == 0) { serviceParsed = true; serviceNameLen = 0; protoParsed = true; protoNameLen = 0; localParsed = true; } else { #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_FQDN: %s\n", serviceName); #endif _conn->flush(); return; } } else { #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_SERVICE: %s\n", serviceName); #endif _conn->flush(); return; } } if (!protoParsed) { protoNameLen = _conn_read8(); _conn_readS(protoName, protoNameLen); protoName[protoNameLen] = '\0'; if (protoNameLen == 4 && protoName[0] == '_') { memmove(protoName, protoName + 1, protoNameLen); protoNameLen--; protoParsed = true; } else if (strcmp("services", serviceName) == 0 && strcmp("_dns-sd", protoName) == 0) { _conn->flush(); advertiseServices(); return; } else { #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_PROTO: %s\n", protoName); #endif _conn->flush(); return; } } if (!localParsed) { char localName[32]; uint8_t localNameLen = _conn_read8(); _conn_readS(localName, localNameLen); localName[localNameLen] = '\0'; tmp = _conn_read8(); if (localNameLen == 5 && strcmp("local", localName) == 0 && tmp == 0) { localParsed = true; } else { #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_FQDN: %s\n", localName); #endif _conn->flush(); return; } } if (serviceNameLen > 0 && protoNameLen > 0) { servicePort = _getServicePort(serviceName, protoName); if (servicePort == 0) { #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_NO_SERVICE: %s\n", serviceName); #endif _conn->flush(); return; } } else if (serviceNameLen > 0 || protoNameLen > 0) { #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_SERVICE_PROTO: %s\n", serviceName); #endif _conn->flush(); return; } // RESPOND #ifdef MDNS_DEBUG_RX Serial.printf("RX: REQ, ID:%u, Q:%u, A:%u, NS:%u, ADD:%u\n", packetHeader[0], packetHeader[2], packetHeader[3], packetHeader[4], packetHeader[5]); #endif uint16_t currentType; uint16_t currentClass; int numQuestions = packetHeader[2]; if (numQuestions > 4) numQuestions = 4; uint16_t questions[4]; int question = 0; while (numQuestions--) { currentType = _conn_read16(); if (currentType & MDNS_NAME_REF) { //new header handle it better! currentType = _conn_read16(); } currentClass = _conn_read16(); if (currentClass & MDNS_CLASS_IN) questions[question++] = currentType; if (numQuestions > 0) { if (_conn_read16() != 0xC00C) {//new question but for another host/service _conn->flush(); numQuestions = 0; } } #ifdef MDNS_DEBUG_RX Serial.printf("REQ: "); if (hostNameLen > 0) Serial.printf("%s.", hostName); if (serviceNameLen > 0) Serial.printf("_%s.", serviceName); if (protoNameLen > 0) Serial.printf("_%s.", protoName); Serial.printf("local. "); if (currentType == MDNS_TYPE_AAAA) Serial.printf(" AAAA "); else if (currentType == MDNS_TYPE_A) Serial.printf(" A "); else if (currentType == MDNS_TYPE_PTR) Serial.printf(" PTR "); else if (currentType == MDNS_TYPE_SRV) Serial.printf(" SRV "); else if (currentType == MDNS_TYPE_TXT) Serial.printf(" TXT "); else Serial.printf(" 0x%04X ", currentType); if (currentClass == MDNS_CLASS_IN) Serial.printf(" IN "); else if (currentClass == MDNS_CLASS_IN_FLUSH_CACHE) Serial.printf(" IN[F] "); else Serial.printf(" 0x%04X ", currentClass); Serial.printf("\n"); #endif } uint8_t responseMask = 0; for (i = 0; i<question; i++) { if (questions[i] == MDNS_TYPE_A) responseMask |= 0x1; else if (questions[i] == MDNS_TYPE_SRV) responseMask |= 0x3; else if (questions[i] == MDNS_TYPE_TXT) responseMask |= 0x4; else if (questions[i] == MDNS_TYPE_PTR) responseMask |= 0xF; } return _reply(responseMask, serviceName, protoName, servicePort); }
static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt) { struct hostapd_iface *iface = hapd->iface; const struct ieee80211_hdr *hdr; const u8 *bssid; struct hostapd_frame_info fi; int ret; #ifdef CONFIG_TESTING_OPTIONS if (hapd->ext_mgmt_frame_handling) { size_t hex_len = 2 * rx_mgmt->frame_len + 1; char *hex = os_malloc(hex_len); if (hex) { wpa_snprintf_hex(hex, hex_len, rx_mgmt->frame, rx_mgmt->frame_len); wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex); os_free(hex); } return 1; } #endif /* CONFIG_TESTING_OPTIONS */ hdr = (const struct ieee80211_hdr *) rx_mgmt->frame; bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len); if (bssid == NULL) return 0; hapd = get_hapd_bssid(iface, bssid); if (hapd == NULL) { u16 fc = le_to_host16(hdr->frame_control); /* * Drop frames to unknown BSSIDs except for Beacon frames which * could be used to update neighbor information. */ if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) hapd = iface->bss[0]; else return 0; } os_memset(&fi, 0, sizeof(fi)); fi.freq = rx_mgmt->freq; fi.datarate = rx_mgmt->datarate; fi.ssi_signal = rx_mgmt->ssi_signal; if (hapd == HAPD_BROADCAST) { size_t i; ret = 0; for (i = 0; i < iface->num_bss; i++) { /* if bss is set, driver will call this function for * each bss individually. */ if (rx_mgmt->drv_priv && (iface->bss[i]->drv_priv != rx_mgmt->drv_priv)) continue; if (ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame, rx_mgmt->frame_len, &fi) > 0) ret = 1; } } else ret = ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi); random_add_randomness(&fi, sizeof(fi)); return ret; }
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, const u8 *req_ies, size_t req_ies_len, int reassoc) { struct sta_info *sta; int new_assoc, res; struct ieee802_11_elems elems; const u8 *ie; size_t ielen; #if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS) || defined(CONFIG_OWE) u8 buf[sizeof(struct ieee80211_mgmt) + 1024]; u8 *p = buf; #endif /* CONFIG_IEEE80211R_AP || CONFIG_IEEE80211W || CONFIG_FILS || CONFIG_OWE */ u16 reason = WLAN_REASON_UNSPECIFIED; u16 status = WLAN_STATUS_SUCCESS; const u8 *p2p_dev_addr = NULL; if (addr == NULL) { /* * This could potentially happen with unexpected event from the * driver wrapper. This was seen at least in one case where the * driver ended up being set to station mode while hostapd was * running, so better make sure we stop processing such an * event here. */ wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with no address"); return -1; } random_add_randomness(addr, ETH_ALEN); hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated"); ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0); if (elems.wps_ie) { ie = elems.wps_ie - 2; ielen = elems.wps_ie_len + 2; wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq"); } else if (elems.rsn_ie) { ie = elems.rsn_ie - 2; ielen = elems.rsn_ie_len + 2; wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq"); } else if (elems.wpa_ie) { ie = elems.wpa_ie - 2; ielen = elems.wpa_ie_len + 2; wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq"); #ifdef CONFIG_HS20 } else if (elems.osen) { ie = elems.osen - 2; ielen = elems.osen_len + 2; wpa_printf(MSG_DEBUG, "STA included OSEN IE in (Re)AssocReq"); #endif /* CONFIG_HS20 */ } else { ie = NULL; ielen = 0; wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in (Re)AssocReq"); } sta = ap_get_sta(hapd, addr); if (sta) { ap_sta_no_session_timeout(hapd, sta); accounting_sta_stop(hapd, sta); /* * Make sure that the previously registered inactivity timer * will not remove the STA immediately. */ sta->timeout_next = STA_NULLFUNC; } else { sta = ap_sta_add(hapd, addr); if (sta == NULL) { hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_AP_BUSY); return -1; } } sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); /* * ACL configurations to the drivers (implementing AP SME and ACL * offload) without hostapd's knowledge, can result in a disconnection * though the driver accepts the connection. Skip the hostapd check for * ACL if the driver supports ACL offload to avoid potentially * conflicting ACL rules. */ if (hapd->iface->drv_max_acl_mac_addrs == 0 && hostapd_check_acl(hapd, addr, NULL) != HOSTAPD_ACL_ACCEPT) { wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect", MAC2STR(addr)); reason = WLAN_REASON_UNSPECIFIED; goto fail; } #ifdef CONFIG_P2P if (elems.p2p) { wpabuf_free(sta->p2p_ie); sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, P2P_IE_VENDOR_TYPE); if (sta->p2p_ie) p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie); } #endif /* CONFIG_P2P */ #ifdef CONFIG_IEEE80211N #ifdef NEED_AP_MLME if (elems.ht_capabilities && (hapd->iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) { struct ieee80211_ht_capabilities *ht_cap = (struct ieee80211_ht_capabilities *) elems.ht_capabilities; if (le_to_host16(ht_cap->ht_capabilities_info) & HT_CAP_INFO_40MHZ_INTOLERANT) ht40_intolerant_add(hapd->iface, sta); } #endif /* NEED_AP_MLME */ #endif /* CONFIG_IEEE80211N */ #ifdef CONFIG_INTERWORKING if (elems.ext_capab && elems.ext_capab_len > 4) { if (elems.ext_capab[4] & 0x01) sta->qos_map_enabled = 1; } #endif /* CONFIG_INTERWORKING */ #ifdef CONFIG_HS20 wpabuf_free(sta->hs20_ie); if (elems.hs20 && elems.hs20_len > 4) { sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4, elems.hs20_len - 4); } else sta->hs20_ie = NULL; wpabuf_free(sta->roaming_consortium); if (elems.roaming_cons_sel) sta->roaming_consortium = wpabuf_alloc_copy( elems.roaming_cons_sel + 4, elems.roaming_cons_sel_len - 4); else sta->roaming_consortium = NULL; #endif /* CONFIG_HS20 */ #ifdef CONFIG_FST wpabuf_free(sta->mb_ies); if (hapd->iface->fst) sta->mb_ies = mb_ies_by_info(&elems.mb_ies); else sta->mb_ies = NULL; #endif /* CONFIG_FST */ mbo_ap_check_sta_assoc(hapd, sta, &elems); ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes, elems.supp_op_classes_len); if (hapd->conf->wpa) { if (ie == NULL || ielen == 0) { #ifdef CONFIG_WPS if (hapd->conf->wps_state) { wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in (Re)Association Request - possible WPS use"); sta->flags |= WLAN_STA_MAYBE_WPS; goto skip_wpa_check; } #endif /* CONFIG_WPS */ wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA"); reason = WLAN_REASON_INVALID_IE; status = WLAN_STATUS_INVALID_IE; goto fail; } #ifdef CONFIG_WPS if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { struct wpabuf *wps; sta->flags |= WLAN_STA_WPS; wps = ieee802_11_vendor_ie_concat(ie, ielen, WPS_IE_VENDOR_TYPE); if (wps) { if (wps_is_20(wps)) { wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0"); sta->flags |= WLAN_STA_WPS2; } wpabuf_free(wps); } goto skip_wpa_check; } #endif /* CONFIG_WPS */ if (sta->wpa_sm == NULL) sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr, p2p_dev_addr); if (sta->wpa_sm == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize WPA state machine"); return -1; } res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, hapd->iface->freq, ie, ielen, elems.mdie, elems.mdie_len, elems.owe_dh, elems.owe_dh_len); if (res != WPA_IE_OK) { wpa_printf(MSG_DEBUG, "WPA/RSN information element rejected? (res %u)", res); wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); if (res == WPA_INVALID_GROUP) { reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID; status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; } else if (res == WPA_INVALID_PAIRWISE) { reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; } else if (res == WPA_INVALID_AKMP) { reason = WLAN_REASON_AKMP_NOT_VALID; status = WLAN_STATUS_AKMP_NOT_VALID; } #ifdef CONFIG_IEEE80211W else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) { reason = WLAN_REASON_INVALID_IE; status = WLAN_STATUS_INVALID_IE; } else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) { reason = WLAN_REASON_CIPHER_SUITE_REJECTED; status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; } #endif /* CONFIG_IEEE80211W */ else { reason = WLAN_REASON_INVALID_IE; status = WLAN_STATUS_INVALID_IE; } goto fail; } #ifdef CONFIG_IEEE80211W if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) == (WLAN_STA_ASSOC | WLAN_STA_MFP) && !sta->sa_query_timed_out && sta->sa_query_count > 0) ap_check_sa_query_timeout(hapd, sta); if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) == (WLAN_STA_ASSOC | WLAN_STA_MFP) && !sta->sa_query_timed_out && (sta->auth_alg != WLAN_AUTH_FT)) { /* * STA has already been associated with MFP and SA * Query timeout has not been reached. Reject the * association attempt temporarily and start SA Query, * if one is not pending. */ if (sta->sa_query_count == 0) ap_sta_start_sa_query(hapd, sta); status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; p = hostapd_eid_assoc_comeback_time(hapd, sta, p); hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); return 0; } if (wpa_auth_uses_mfp(sta->wpa_sm)) sta->flags |= WLAN_STA_MFP; else sta->flags &= ~WLAN_STA_MFP; #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_IEEE80211R_AP if (sta->auth_alg == WLAN_AUTH_FT) { status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies, req_ies_len); if (status != WLAN_STATUS_SUCCESS) { if (status == WLAN_STATUS_INVALID_PMKID) reason = WLAN_REASON_INVALID_IE; if (status == WLAN_STATUS_INVALID_MDIE) reason = WLAN_REASON_INVALID_IE; if (status == WLAN_STATUS_INVALID_FTIE) reason = WLAN_REASON_INVALID_IE; goto fail; } } #endif /* CONFIG_IEEE80211R_AP */ } else if (hapd->conf->wps_state) { #ifdef CONFIG_WPS struct wpabuf *wps; if (req_ies) wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, WPS_IE_VENDOR_TYPE); else wps = NULL; #ifdef CONFIG_WPS_STRICT if (wps && wps_validate_assoc_req(wps) < 0) { reason = WLAN_REASON_INVALID_IE; status = WLAN_STATUS_INVALID_IE; wpabuf_free(wps); goto fail; } #endif /* CONFIG_WPS_STRICT */ if (wps) { sta->flags |= WLAN_STA_WPS; if (wps_is_20(wps)) { wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0"); sta->flags |= WLAN_STA_WPS2; } } else sta->flags |= WLAN_STA_MAYBE_WPS; wpabuf_free(wps); #endif /* CONFIG_WPS */ #ifdef CONFIG_HS20 } else if (hapd->conf->osen) { if (elems.osen == NULL) { hostapd_logger( hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "No HS 2.0 OSEN element in association request"); return WLAN_STATUS_INVALID_IE; } wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association"); if (sta->wpa_sm == NULL) sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr, NULL); if (sta->wpa_sm == NULL) { wpa_printf(MSG_WARNING, "Failed to initialize WPA state machine"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm, elems.osen - 2, elems.osen_len + 2) < 0) return WLAN_STATUS_INVALID_IE; #endif /* CONFIG_HS20 */ } #ifdef CONFIG_MBO if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) && elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) && hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { wpa_printf(MSG_INFO, "MBO: Reject WPA2 association without PMF"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } #endif /* CONFIG_MBO */ #ifdef CONFIG_WPS skip_wpa_check: #endif /* CONFIG_WPS */ #ifdef CONFIG_IEEE80211R_AP p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf), sta->auth_alg, req_ies, req_ies_len); if (!p) { wpa_printf(MSG_DEBUG, "FT: Failed to write AssocResp IEs"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } #endif /* CONFIG_IEEE80211R_AP */ #ifdef CONFIG_FILS if (sta->auth_alg == WLAN_AUTH_FILS_SK || sta->auth_alg == WLAN_AUTH_FILS_SK_PFS || sta->auth_alg == WLAN_AUTH_FILS_PK) { int delay_assoc = 0; if (!req_ies) return WLAN_STATUS_UNSPECIFIED_FAILURE; if (!wpa_fils_validate_fils_session(sta->wpa_sm, req_ies, req_ies_len, sta->fils_session)) { wpa_printf(MSG_DEBUG, "FILS: Session validation failed"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } res = wpa_fils_validate_key_confirm(sta->wpa_sm, req_ies, req_ies_len); if (res < 0) { wpa_printf(MSG_DEBUG, "FILS: Key Confirm validation failed"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } if (fils_process_hlp(hapd, sta, req_ies, req_ies_len) > 0) { wpa_printf(MSG_DEBUG, "FILS: Delaying Assoc Response (HLP)"); delay_assoc = 1; } else { wpa_printf(MSG_DEBUG, "FILS: Going ahead with Assoc Response (no HLP)"); } if (sta) { wpa_printf(MSG_DEBUG, "FILS: HLP callback cleanup"); eloop_cancel_timeout(fils_hlp_timeout, hapd, sta); os_free(sta->fils_pending_assoc_req); sta->fils_pending_assoc_req = NULL; sta->fils_pending_assoc_req_len = 0; wpabuf_free(sta->fils_hlp_resp); sta->fils_hlp_resp = NULL; sta->fils_drv_assoc_finish = 0; } if (sta && delay_assoc && status == WLAN_STATUS_SUCCESS) { u8 *req_tmp; req_tmp = os_malloc(req_ies_len); if (!req_tmp) { wpa_printf(MSG_DEBUG, "FILS: buffer allocation failed for assoc req"); goto fail; } os_memcpy(req_tmp, req_ies, req_ies_len); sta->fils_pending_assoc_req = req_tmp; sta->fils_pending_assoc_req_len = req_ies_len; sta->fils_pending_assoc_is_reassoc = reassoc; sta->fils_drv_assoc_finish = 1; wpa_printf(MSG_DEBUG, "FILS: Waiting for HLP processing before sending (Re)Association Response frame to " MACSTR, MAC2STR(sta->addr)); eloop_register_timeout( 0, hapd->conf->fils_hlp_wait_time * 1024, fils_hlp_timeout, hapd, sta); return 0; } p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p, elems.fils_session, sta->fils_hlp_resp); wpa_hexdump(MSG_DEBUG, "FILS Assoc Resp BUF (IEs)", buf, p - buf); } #endif /* CONFIG_FILS */ #ifdef CONFIG_OWE if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE && elems.owe_dh) { u8 *npos; npos = owe_assoc_req_process(hapd, sta, elems.owe_dh, elems.owe_dh_len, p, sizeof(buf) - (p - buf), &reason); if (npos) p = npos; if (!npos && reason == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) { status = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED; hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); return 0; } if (!npos || reason != WLAN_STATUS_SUCCESS) goto fail; } #endif /* CONFIG_OWE */ #ifdef CONFIG_DPP2 dpp_pfs_free(sta->dpp_pfs); sta->dpp_pfs = NULL; if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) && hapd->conf->dpp_netaccesskey && sta->wpa_sm && wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP && elems.owe_dh) { sta->dpp_pfs = dpp_pfs_init( wpabuf_head(hapd->conf->dpp_netaccesskey), wpabuf_len(hapd->conf->dpp_netaccesskey)); if (!sta->dpp_pfs) { wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS"); /* Try to continue without PFS */ goto pfs_fail; } if (dpp_pfs_process(sta->dpp_pfs, elems.owe_dh, elems.owe_dh_len) < 0) { dpp_pfs_free(sta->dpp_pfs); sta->dpp_pfs = NULL; reason = WLAN_REASON_UNSPECIFIED; goto fail; } } wpa_auth_set_dpp_z(sta->wpa_sm, sta->dpp_pfs ? sta->dpp_pfs->secret : NULL); pfs_fail: #endif /* CONFIG_DPP2 */ #if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_FILS) || defined(CONFIG_OWE) hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); if (sta->auth_alg == WLAN_AUTH_FT || sta->auth_alg == WLAN_AUTH_FILS_SK || sta->auth_alg == WLAN_AUTH_FILS_SK_PFS || sta->auth_alg == WLAN_AUTH_FILS_PK) ap_sta_set_authorized(hapd, sta, 1); #else /* CONFIG_IEEE80211R_AP || CONFIG_FILS */ /* Keep compiler silent about unused variables */ if (status) { } #endif /* CONFIG_IEEE80211R_AP || CONFIG_FILS */ new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE; hostapd_set_sta_flags(hapd, sta); if (reassoc && (sta->auth_alg == WLAN_AUTH_FT)) wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); #ifdef CONFIG_FILS else if (sta->auth_alg == WLAN_AUTH_FILS_SK || sta->auth_alg == WLAN_AUTH_FILS_SK_PFS || sta->auth_alg == WLAN_AUTH_FILS_PK) wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FILS); #endif /* CONFIG_FILS */ else wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); hostapd_new_assoc_sta(hapd, sta, !new_assoc); ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); #ifdef CONFIG_P2P if (req_ies) { p2p_group_notif_assoc(hapd->p2p_group, sta->addr, req_ies, req_ies_len); } #endif /* CONFIG_P2P */ return 0; fail: #ifdef CONFIG_IEEE80211R_AP hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); #endif /* CONFIG_IEEE80211R_AP */ hostapd_drv_sta_disassoc(hapd, sta->addr, reason); ap_free_sta(hapd, sta); return -1; }
int main(int argc, char *argv[]) { int c, i; struct wpa_interface *ifaces, *iface; int iface_count, exitcode = -1; struct wpa_params params; struct wpa_global *global; if (os_program_init()) return -1; os_memset(¶ms, 0, sizeof(params)); params.wpa_debug_level = MSG_INFO; iface = ifaces = os_zalloc(sizeof(struct wpa_interface)); if (ifaces == NULL) return -1; iface_count = 1; wpa_supplicant_fd_workaround(); for (;;) { c = getopt(argc, argv, "b:Bc:C:D:de:f:g:hi:KLNo:O:p:P:qstuvW"); if (c < 0) break; switch (c) { case 'b': iface->bridge_ifname = optarg; break; case 'B': params.daemonize++; break; case 'c': iface->confname = optarg; break; case 'C': iface->ctrl_interface = optarg; break; case 'D': iface->driver = optarg; break; case 'd': #ifdef CONFIG_NO_STDOUT_DEBUG printf("Debugging disabled with " "CONFIG_NO_STDOUT_DEBUG=y build time " "option.\n"); goto out; #else /* CONFIG_NO_STDOUT_DEBUG */ params.wpa_debug_level--; break; #endif /* CONFIG_NO_STDOUT_DEBUG */ case 'e': params.entropy_file = optarg; break; #ifdef CONFIG_DEBUG_FILE case 'f': params.wpa_debug_file_path = optarg; break; #endif /* CONFIG_DEBUG_FILE */ case 'g': params.ctrl_interface = optarg; break; case 'h': usage(); exitcode = 0; goto out; case 'i': iface->ifname = optarg; break; case 'K': params.wpa_debug_show_keys++; break; case 'L': license(); exitcode = 0; goto out; case 'o': params.override_driver = optarg; break; case 'O': params.override_ctrl_interface = optarg; break; case 'p': iface->driver_param = optarg; break; case 'P': os_free(params.pid_file); params.pid_file = os_rel2abs_path(optarg); break; case 'q': params.wpa_debug_level++; break; #ifdef CONFIG_DEBUG_SYSLOG case 's': params.wpa_debug_syslog++; break; #endif /* CONFIG_DEBUG_SYSLOG */ case 't': params.wpa_debug_timestamp++; break; #ifdef CONFIG_DBUS case 'u': params.dbus_ctrl_interface = 1; break; #endif /* CONFIG_DBUS */ case 'v': printf("%s\n", wpa_supplicant_version); exitcode = 0; goto out; case 'W': params.wait_for_monitor++; break; case 'N': iface_count++; iface = os_realloc(ifaces, iface_count * sizeof(struct wpa_interface)); if (iface == NULL) goto out; ifaces = iface; iface = &ifaces[iface_count - 1]; os_memset(iface, 0, sizeof(*iface)); break; default: usage(); exitcode = 0; goto out; } } exitcode = 0; global = wpa_supplicant_init(¶ms); if (global == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant"); exitcode = -1; goto out; } for (i = 0; exitcode == 0 && i < iface_count; i++) { if ((ifaces[i].confname == NULL && ifaces[i].ctrl_interface == NULL) || ifaces[i].ifname == NULL) { if (iface_count == 1 && (params.ctrl_interface || params.dbus_ctrl_interface)) break; usage(); exitcode = -1; break; } if (wpa_supplicant_add_iface(global, &ifaces[i]) == NULL) exitcode = -1; } if (exitcode == 0) exitcode = wpa_supplicant_run(global); wpa_supplicant_deinit(global); out: os_free(ifaces); os_free(params.pid_file); os_program_deinit(); return exitcode; }
/** * hostapd_driver_init - Preparate driver interface */ static int hostapd_driver_init(struct hostapd_iface *iface) { struct wpa_init_params params; size_t i; struct hostapd_data *hapd = iface->bss[0]; struct hostapd_bss_config *conf = hapd->conf; u8 *b = conf->bssid; struct wpa_driver_capa capa; if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) { wpa_printf(MSG_ERROR, "No hostapd driver wrapper available"); return -1; } /* Initialize the driver interface */ if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) b = NULL; os_memset(¶ms, 0, sizeof(params)); for (i = 0; wpa_drivers[i]; i++) { if (wpa_drivers[i] != hapd->driver) continue; if (global.drv_priv[i] == NULL && wpa_drivers[i]->global_init) { global.drv_priv[i] = wpa_drivers[i]->global_init(); if (global.drv_priv[i] == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize " "driver '%s'", wpa_drivers[i]->name); return -1; } } params.global_priv = global.drv_priv[i]; break; } params.bssid = b; params.ifname = hapd->conf->iface; params.driver_params = hapd->iconf->driver_params; params.use_pae_group_addr = hapd->conf->use_pae_group_addr; params.num_bridge = hapd->iface->num_bss; params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *)); if (params.bridge == NULL) return -1; for (i = 0; i < hapd->iface->num_bss; i++) { struct hostapd_data *bss = hapd->iface->bss[i]; if (bss->conf->bridge[0]) params.bridge[i] = bss->conf->bridge; } params.own_addr = hapd->own_addr; hapd->drv_priv = hapd->driver->hapd_init(hapd, ¶ms); os_free(params.bridge); if (hapd->drv_priv == NULL) { wpa_printf(MSG_ERROR, "%s driver initialization failed.", hapd->driver->name); hapd->driver = NULL; return -1; } if (hapd->driver->get_capa && hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) { struct wowlan_triggers *triggs; iface->drv_flags = capa.flags; iface->smps_modes = capa.smps_modes; iface->probe_resp_offloads = capa.probe_resp_offloads; iface->extended_capa = capa.extended_capa; iface->extended_capa_mask = capa.extended_capa_mask; iface->extended_capa_len = capa.extended_capa_len; iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs; triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa); if (triggs && hapd->driver->set_wowlan) { if (hapd->driver->set_wowlan(hapd->drv_priv, triggs)) wpa_printf(MSG_ERROR, "set_wowlan failed"); } os_free(triggs); } return 0; }
static int hostapd_config_read_wpa_psk(const char *fname, struct hostapd_ssid *ssid) { FILE *f; char buf[128], *pos; int line = 0, ret = 0, len, ok; u8 addr[ETH_ALEN]; struct hostapd_wpa_psk *psk; if (!fname) return 0; f = fopen(fname, "r"); if (!f) { wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname); return -1; } while (fgets(buf, sizeof(buf), f)) { line++; if (buf[0] == '#') continue; pos = buf; while (*pos != '\0') { if (*pos == '\n') { *pos = '\0'; break; } pos++; } if (buf[0] == '\0') continue; if (hwaddr_aton(buf, addr)) { wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on " "line %d in '%s'", buf, line, fname); ret = -1; break; } psk = os_zalloc(sizeof(*psk)); if (psk == NULL) { wpa_printf(MSG_ERROR, "WPA PSK allocation failed"); ret = -1; break; } if (is_zero_ether_addr(addr)) psk->group = 1; else os_memcpy(psk->addr, addr, ETH_ALEN); pos = buf + 17; if (*pos == '\0') { wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'", line, fname); os_free(psk); ret = -1; break; } pos++; ok = 0; len = os_strlen(pos); if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0) ok = 1; else if (len >= 8 && len < 64) { pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len, 4096, psk->psk, PMK_LEN); ok = 1; } if (!ok) { wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in " "'%s'", pos, line, fname); os_free(psk); ret = -1; break; } psk->next = ssid->wpa_psk; ssid->wpa_psk = psk; } fclose(f); return ret; }
static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, int level, const char *txt, size_t len) { struct hostapd_data *hapd = ctx; char *format, *module_str; int maxlen; int conf_syslog_level, conf_stdout_level; unsigned int conf_syslog, conf_stdout; maxlen = len + 100; format = os_malloc(maxlen); if (!format) return; if (hapd && hapd->conf) { conf_syslog_level = hapd->conf->logger_syslog_level; conf_stdout_level = hapd->conf->logger_stdout_level; conf_syslog = hapd->conf->logger_syslog; conf_stdout = hapd->conf->logger_stdout; } else { conf_syslog_level = conf_stdout_level = 0; conf_syslog = conf_stdout = (unsigned int) -1; } switch (module) { case HOSTAPD_MODULE_IEEE80211: module_str = "IEEE 802.11"; break; case HOSTAPD_MODULE_IEEE8021X: module_str = "IEEE 802.1X"; break; case HOSTAPD_MODULE_RADIUS: module_str = "RADIUS"; break; case HOSTAPD_MODULE_WPA: module_str = "WPA"; break; case HOSTAPD_MODULE_DRIVER: module_str = "DRIVER"; break; case HOSTAPD_MODULE_IAPP: module_str = "IAPP"; break; case HOSTAPD_MODULE_MLME: module_str = "MLME"; break; default: module_str = NULL; break; } if (hapd && hapd->conf && addr) os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s", hapd->conf->iface, MAC2STR(addr), module_str ? " " : "", module_str ? module_str : "", txt); else if (hapd && hapd->conf) os_snprintf(format, maxlen, "%s:%s%s %s", hapd->conf->iface, module_str ? " " : "", module_str ? module_str : "", txt); else if (addr) os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s", MAC2STR(addr), module_str ? " " : "", module_str ? module_str : "", txt); else os_snprintf(format, maxlen, "%s%s%s", module_str ? module_str : "", module_str ? ": " : "", txt); if ((conf_stdout & module) && level >= conf_stdout_level) { wpa_debug_print_timestamp(); wpa_printf(MSG_INFO, "%s", format); } #ifndef CONFIG_NATIVE_WINDOWS if ((conf_syslog & module) && level >= conf_syslog_level) { int priority; switch (level) { case HOSTAPD_LEVEL_DEBUG_VERBOSE: case HOSTAPD_LEVEL_DEBUG: priority = LOG_DEBUG; break; case HOSTAPD_LEVEL_INFO: priority = LOG_INFO; break; case HOSTAPD_LEVEL_NOTICE: priority = LOG_NOTICE; break; case HOSTAPD_LEVEL_WARNING: priority = LOG_WARNING; break; default: priority = LOG_INFO; break; } syslog(priority, "%s", format); } #endif /* CONFIG_NATIVE_WINDOWS */ os_free(format); }
static void hostapd_config_free_eap_user(struct hostapd_eap_user *user) { os_free(user->identity); os_free(user->password); os_free(user); }
int main(int argc, char *argv[]) { int c, i; int ret = -1; char *pid_file = NULL; int daemonize = 0; char *ctrl_dir = "/var/run/wpa_priv"; struct wpa_priv_interface *interfaces = NULL, *iface; if (os_program_init()) return -1; wpa_priv_fd_workaround(); for (;;) { c = getopt(argc, argv, "Bc:dP:"); if (c < 0) break; switch (c) { case 'B': daemonize++; break; case 'c': ctrl_dir = optarg; break; case 'd': wpa_debug_level--; break; case 'P': pid_file = os_rel2abs_path(optarg); break; default: usage(); goto out; } } if (optind >= argc) { usage(); goto out; } wpa_printf(MSG_DEBUG, "wpa_priv control directory: '%s'", ctrl_dir); if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); goto out; } for (i = optind; i < argc; i++) { wpa_printf(MSG_DEBUG, "Adding driver:interface %s", argv[i]); iface = wpa_priv_interface_init(ctrl_dir, argv[i]); if (iface == NULL) goto out; iface->next = interfaces; interfaces = iface; } if (daemonize && os_daemonize(pid_file)) goto out; eloop_register_signal_terminate(wpa_priv_terminate, NULL); eloop_run(); ret = 0; out: iface = interfaces; while (iface) { struct wpa_priv_interface *prev = iface; iface = iface->next; wpa_priv_interface_deinit(prev); } eloop_destroy(); os_daemonize_terminate(pid_file); os_free(pid_file); os_program_deinit(); return ret; }
static void hostapd_config_free_bss(struct hostapd_bss_config *conf) { struct hostapd_wpa_psk *psk, *prev; struct hostapd_eap_user *user, *prev_user; if (conf == NULL) return; psk = conf->ssid.wpa_psk; while (psk) { prev = psk; psk = psk->next; os_free(prev); } os_free(conf->ssid.wpa_passphrase); os_free(conf->ssid.wpa_psk_file); hostapd_config_free_wep(&conf->ssid.wep); #ifdef CONFIG_FULL_DYNAMIC_VLAN os_free(conf->ssid.vlan_tagged_interface); #endif /* CONFIG_FULL_DYNAMIC_VLAN */ user = conf->eap_user; while (user) { prev_user = user; user = user->next; hostapd_config_free_eap_user(prev_user); } os_free(conf->dump_log_name); os_free(conf->eap_req_id_text); os_free(conf->accept_mac); os_free(conf->deny_mac); os_free(conf->nas_identifier); hostapd_config_free_radius(conf->radius->auth_servers, conf->radius->num_auth_servers); hostapd_config_free_radius(conf->radius->acct_servers, conf->radius->num_acct_servers); os_free(conf->rsn_preauth_interfaces); os_free(conf->ctrl_interface); os_free(conf->ca_cert); os_free(conf->server_cert); os_free(conf->private_key); os_free(conf->private_key_passwd); os_free(conf->dh_file); os_free(conf->pac_opaque_encr_key); os_free(conf->eap_fast_a_id); os_free(conf->eap_fast_a_id_info); os_free(conf->eap_sim_db); os_free(conf->radius_server_clients); os_free(conf->test_socket); os_free(conf->radius); hostapd_config_free_vlan(conf); if (conf->ssid.dyn_vlan_keys) { struct hostapd_ssid *ssid = &conf->ssid; size_t i; for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) { if (ssid->dyn_vlan_keys[i] == NULL) continue; hostapd_config_free_wep(ssid->dyn_vlan_keys[i]); os_free(ssid->dyn_vlan_keys[i]); } os_free(ssid->dyn_vlan_keys); ssid->dyn_vlan_keys = NULL; } #ifdef CONFIG_IEEE80211R { struct ft_remote_r0kh *r0kh, *r0kh_prev; struct ft_remote_r1kh *r1kh, *r1kh_prev; r0kh = conf->r0kh_list; conf->r0kh_list = NULL; while (r0kh) { r0kh_prev = r0kh; r0kh = r0kh->next; os_free(r0kh_prev); } r1kh = conf->r1kh_list; conf->r1kh_list = NULL; while (r1kh) { r1kh_prev = r1kh; r1kh = r1kh->next; os_free(r1kh_prev); } } #endif /* CONFIG_IEEE80211R */ #ifdef CONFIG_WPS os_free(conf->wps_pin_requests); os_free(conf->device_name); os_free(conf->manufacturer); os_free(conf->model_name); os_free(conf->model_number); os_free(conf->serial_number); os_free(conf->device_type); os_free(conf->config_methods); os_free(conf->ap_pin); os_free(conf->extra_cred); os_free(conf->ap_settings); os_free(conf->upnp_iface); os_free(conf->friendly_name); os_free(conf->manufacturer_url); os_free(conf->model_description); os_free(conf->model_url); os_free(conf->upc); #endif /* CONFIG_WPS */ }
static void rx_data_bss_prot_group(struct wlantest *wt, const struct ieee80211_hdr *hdr, size_t hdrlen, const u8 *qos, const u8 *dst, const u8 *src, const u8 *data, size_t len) { struct wlantest_bss *bss; int keyid; u8 *decrypted = NULL; size_t dlen; u8 pn[6]; int replay = 0; bss = bss_get(wt, hdr->addr2); if (bss == NULL) return; if (len < 4) { add_note(wt, MSG_INFO, "Too short group addressed data frame"); return; } if (bss->group_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) && !(data[3] & 0x20)) { add_note(wt, MSG_INFO, "Expected TKIP/CCMP frame from " MACSTR " did not have ExtIV bit set to 1", MAC2STR(bss->bssid)); return; } if (bss->group_cipher == WPA_CIPHER_TKIP) { if (data[3] & 0x1f) { add_note(wt, MSG_INFO, "TKIP frame from " MACSTR " used non-zero reserved bit", MAC2STR(bss->bssid)); } if (data[1] != ((data[0] | 0x20) & 0x7f)) { add_note(wt, MSG_INFO, "TKIP frame from " MACSTR " used incorrect WEPSeed[1] (was 0x%x, " "expected 0x%x)", MAC2STR(bss->bssid), data[1], (data[0] | 0x20) & 0x7f); } } else if (bss->group_cipher == WPA_CIPHER_CCMP) { if (data[2] != 0 || (data[3] & 0x1f) != 0) { add_note(wt, MSG_INFO, "CCMP frame from " MACSTR " used non-zero reserved bit", MAC2STR(bss->bssid)); } } keyid = data[3] >> 6; if (bss->gtk_len[keyid] == 0 && bss->group_cipher != WPA_CIPHER_WEP40) { add_note(wt, MSG_MSGDUMP, "No GTK known to decrypt the frame " "(A2=" MACSTR " KeyID=%d)", MAC2STR(hdr->addr2), keyid); return; } if (bss->group_cipher == WPA_CIPHER_TKIP) tkip_get_pn(pn, data); else if (bss->group_cipher == WPA_CIPHER_WEP40) goto skip_replay_det; else ccmp_get_pn(pn, data); if (os_memcmp(pn, bss->rsc[keyid], 6) <= 0) { u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); add_note(wt, MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u%s", MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3), WLAN_GET_SEQ_SEQ(seq_ctrl), WLAN_GET_SEQ_FRAG(seq_ctrl), (le_to_host16(hdr->frame_control) & WLAN_FC_RETRY) ? " Retry" : ""); wpa_hexdump(MSG_INFO, "RX PN", pn, 6); wpa_hexdump(MSG_INFO, "RSC", bss->rsc[keyid], 6); replay = 1; } skip_replay_det: if (bss->group_cipher == WPA_CIPHER_TKIP) decrypted = tkip_decrypt(bss->gtk[keyid], hdr, data, len, &dlen); else if (bss->group_cipher == WPA_CIPHER_WEP40) decrypted = wep_decrypt(wt, hdr, data, len, &dlen); else if (bss->group_cipher == WPA_CIPHER_CCMP) decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len, &dlen); else if (bss->group_cipher == WPA_CIPHER_CCMP_256) decrypted = ccmp_256_decrypt(bss->gtk[keyid], hdr, data, len, &dlen); else if (bss->group_cipher == WPA_CIPHER_GCMP || bss->group_cipher == WPA_CIPHER_GCMP_256) decrypted = gcmp_decrypt(bss->gtk[keyid], bss->gtk_len[keyid], hdr, data, len, &dlen); if (decrypted) { rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted, dlen, 1, NULL); if (!replay) os_memcpy(bss->rsc[keyid], pn, 6); write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen, decrypted, dlen); } else add_note(wt, MSG_DEBUG, "Failed to decrypt frame"); os_free(decrypted); }
struct hostapd_config * hostapd_config_defaults(void) { #define ecw2cw(ecw) ((1 << (ecw)) - 1) struct hostapd_config *conf; struct hostapd_bss_config *bss; const int aCWmin = 4, aCWmax = 10; const struct hostapd_wmm_ac_params ac_bk = { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */ const struct hostapd_wmm_ac_params ac_be = { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */ const struct hostapd_wmm_ac_params ac_vi = /* video traffic */ { aCWmin - 1, aCWmin, 2, 3000 / 32, 1 }; const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */ { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 1 }; const struct hostapd_tx_queue_params txq_bk = { 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 }; const struct hostapd_tx_queue_params txq_be = { 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0}; const struct hostapd_tx_queue_params txq_vi = { 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30}; const struct hostapd_tx_queue_params txq_vo = { 1, (ecw2cw(aCWmin) + 1) / 4 - 1, (ecw2cw(aCWmin) + 1) / 2 - 1, 15}; #undef ecw2cw conf = os_zalloc(sizeof(*conf)); bss = os_zalloc(sizeof(*bss)); if (conf == NULL || bss == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate memory for " "configuration data."); os_free(conf); os_free(bss); return NULL; } bss->radius = os_zalloc(sizeof(*bss->radius)); if (bss->radius == NULL) { os_free(conf); os_free(bss); return NULL; } hostapd_config_defaults_bss(bss); conf->num_bss = 1; conf->bss = bss; conf->beacon_int = 100; conf->rts_threshold = -1; /* use driver default: 2347 */ conf->fragm_threshold = -1; /* user driver default: 2346 */ conf->send_probe_response = 1; conf->wmm_ac_params[0] = ac_be; conf->wmm_ac_params[1] = ac_bk; conf->wmm_ac_params[2] = ac_vi; conf->wmm_ac_params[3] = ac_vo; conf->tx_queue[0] = txq_vo; conf->tx_queue[1] = txq_vi; conf->tx_queue[2] = txq_be; conf->tx_queue[3] = txq_bk; conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED; return conf; }
/****************************************************************************** * FunctionName : user_platform_timer_first_start * Description : calculate the wait time of each timer * Parameters : count -- The number of timers given by server * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR user_platform_timer_first_start(uint16 count) { int i = 0; struct esp_platform_wait_timer_param timer_wait_param[100] = {0}; ESP_DBG("current timestamp= %ds\n", timestamp); timestamp = timestamp + min_wait_second; for (i = 0 ; i < count ; i++) { char *str = timer_splits[i]; if (indexof(str, "f", 0) == 0) { char *fixed_wait[2]; ESP_DBG("timer is fixed mode\n"); split(str, "=", fixed_wait); os_memcpy(timer_wait_param[i].wait_time_param, fixed_wait[0] + 1, os_strlen(fixed_wait[0]) - 1); os_memcpy(timer_wait_param[i].wait_action, fixed_wait[1], os_strlen(fixed_wait[1])); timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - timestamp; os_free(fixed_wait[0]); os_free(fixed_wait[1]); } else if (indexof(str, "l", 0) == 0) { char *loop_wait[2]; ESP_DBG("timer is loop mode\n"); split(str, "=", loop_wait); os_memcpy(timer_wait_param[i].wait_time_param, loop_wait[0] + 1, os_strlen(loop_wait[0]) - 1); os_memcpy(timer_wait_param[i].wait_action, loop_wait[1], os_strlen(loop_wait[1])); timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - (timestamp % atoi(timer_wait_param[i].wait_time_param)); os_free(loop_wait[0]); os_free(loop_wait[1]); } else if (indexof(str, "w", 0) == 0) { char *week_wait[2]; int monday_wait_time = 0; ESP_DBG("timer is weekend mode\n"); split(str, "=", week_wait); os_memcpy(timer_wait_param[i].wait_time_param, week_wait[0] + 1, os_strlen(week_wait[0]) - 1); os_memcpy(timer_wait_param[i].wait_action, week_wait[1], os_strlen(week_wait[1])); monday_wait_time = (timestamp - 1388937600) % (7 * 24 * 3600); ESP_DBG("monday_wait_time == %d", monday_wait_time); if (atoi(timer_wait_param[i].wait_time_param) > monday_wait_time) { timer_wait_param[i].wait_time_second = atoi(timer_wait_param[i].wait_time_param) - monday_wait_time; } else { timer_wait_param[i].wait_time_second = 7 * 24 * 3600 - monday_wait_time + atoi(timer_wait_param[i].wait_time_param); } os_free(week_wait[0]); os_free(week_wait[1]); } } esp_platform_find_min_time(timer_wait_param, count); if(min_wait_second == 0) { return; } esp_platform_timer_action(timer_wait_param, count); }
static void wps_er_ap_free(struct wps_er_ap *ap) { http_client_free(ap->http); ap->http = NULL; os_free(ap->location); os_free(ap->friendly_name); os_free(ap->manufacturer); os_free(ap->manufacturer_url); os_free(ap->model_description); os_free(ap->model_name); os_free(ap->model_number); os_free(ap->model_url); os_free(ap->serial_number); os_free(ap->udn); os_free(ap->upc); os_free(ap->scpd_url); os_free(ap->control_url); os_free(ap->event_sub_url); os_free(ap->ap_settings); os_free(ap); }
static struct wpa_scan_results * wpa_driver_privsep_get_scan_results2(void *priv) { struct wpa_driver_privsep_data *drv = priv; int res, num; u8 *buf, *pos, *end; size_t reply_len = 60000; struct wpa_scan_results *results; struct wpa_scan_res *r; buf = os_malloc(reply_len); if (buf == NULL) return NULL; res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_SCAN_RESULTS, NULL, 0, buf, &reply_len); if (res < 0) { os_free(buf); return NULL; } wpa_printf(MSG_DEBUG, "privsep: Received %lu bytes of scan results", (unsigned long) reply_len); if (reply_len < sizeof(int)) { wpa_printf(MSG_DEBUG, "privsep: Invalid scan result len %lu", (unsigned long) reply_len); os_free(buf); return NULL; } pos = buf; end = buf + reply_len; os_memcpy(&num, pos, sizeof(int)); if (num < 0 || num > 1000) { os_free(buf); return NULL; } pos += sizeof(int); results = os_zalloc(sizeof(*results)); if (results == NULL) { os_free(buf); return NULL; } results->res = os_zalloc(num * sizeof(struct wpa_scan_res *)); if (results->res == NULL) { os_free(results); os_free(buf); return NULL; } while (results->num < (size_t) num && pos + sizeof(int) < end) { int len; os_memcpy(&len, pos, sizeof(int)); pos += sizeof(int); if (len < 0 || len > 10000 || pos + len > end) break; r = os_malloc(len); if (r == NULL) break; os_memcpy(r, pos, len); pos += len; if (sizeof(*r) + r->ie_len > (size_t) len) { os_free(r); break; } results->res[results->num++] = r; } os_free(buf); return results; }
static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap, const u8 *addr, struct wps_parse_attr *attr, int probe_req) { struct wps_er_sta *sta = wps_er_sta_get(ap, addr, NULL); int new_sta = 0; int m1; m1 = !probe_req && attr->msg_type && *attr->msg_type == WPS_M1; if (sta == NULL) { /* * Only allow new STA entry to be added based on Probe Request * or M1. This will filter out bogus events and anything that * may have been ongoing at the time ER subscribed for events. */ if (!probe_req && !m1) return NULL; sta = os_zalloc(sizeof(*sta)); if (sta == NULL) return NULL; os_memcpy(sta->addr, addr, ETH_ALEN); sta->ap = ap; dl_list_add(&ap->sta, &sta->list); new_sta = 1; } if (m1) sta->m1_received = 1; if (attr->config_methods && (!probe_req || !sta->m1_received)) sta->config_methods = WPA_GET_BE16(attr->config_methods); if (attr->uuid_e && (!probe_req || !sta->m1_received)) os_memcpy(sta->uuid, attr->uuid_e, WPS_UUID_LEN); if (attr->primary_dev_type && (!probe_req || !sta->m1_received)) os_memcpy(sta->pri_dev_type, attr->primary_dev_type, 8); if (attr->dev_password_id && (!probe_req || !sta->m1_received)) sta->dev_passwd_id = WPA_GET_BE16(attr->dev_password_id); if (attr->manufacturer) { os_free(sta->manufacturer); sta->manufacturer = os_malloc(attr->manufacturer_len + 1); if (sta->manufacturer) { os_memcpy(sta->manufacturer, attr->manufacturer, attr->manufacturer_len); sta->manufacturer[attr->manufacturer_len] = '\0'; } } if (attr->model_name) { os_free(sta->model_name); sta->model_name = os_malloc(attr->model_name_len + 1); if (sta->model_name) { os_memcpy(sta->model_name, attr->model_name, attr->model_name_len); sta->model_name[attr->model_name_len] = '\0'; } } if (attr->model_number) { os_free(sta->model_number); sta->model_number = os_malloc(attr->model_number_len + 1); if (sta->model_number) { os_memcpy(sta->model_number, attr->model_number, attr->model_number_len); sta->model_number[attr->model_number_len] = '\0'; } } if (attr->serial_number) { os_free(sta->serial_number); sta->serial_number = os_malloc(attr->serial_number_len + 1); if (sta->serial_number) { os_memcpy(sta->serial_number, attr->serial_number, attr->serial_number_len); sta->serial_number[attr->serial_number_len] = '\0'; } } if (attr->dev_name) { os_free(sta->dev_name); sta->dev_name = os_malloc(attr->dev_name_len + 1); if (sta->dev_name) { os_memcpy(sta->dev_name, attr->dev_name, attr->dev_name_len); sta->dev_name[attr->dev_name_len] = '\0'; } } eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL); eloop_register_timeout(300, 0, wps_er_sta_timeout, sta, NULL); if (m1 || new_sta) wps_er_sta_event(ap->er->wps, sta, WPS_EV_ER_ENROLLEE_ADD); return sta; }
static int wpa_driver_privsep_set_param(void *priv, const char *param) { struct wpa_driver_privsep_data *drv = priv; const char *pos; char *own_dir, *priv_dir; static unsigned int counter = 0; size_t len; struct sockaddr_un addr; wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); if (param == NULL) pos = NULL; else pos = os_strstr(param, "own_dir="); if (pos) { char *end; own_dir = os_strdup(pos + 8); if (own_dir == NULL) return -1; end = os_strchr(own_dir, ' '); if (end) *end = '\0'; } else { own_dir = os_strdup("/tmp"); if (own_dir == NULL) return -1; } if (param == NULL) pos = NULL; else pos = os_strstr(param, "priv_dir="); if (pos) { char *end; priv_dir = os_strdup(pos + 9); if (priv_dir == NULL) { os_free(own_dir); return -1; } end = os_strchr(priv_dir, ' '); if (end) *end = '\0'; } else { priv_dir = os_strdup("/var/run/wpa_priv"); if (priv_dir == NULL) { os_free(own_dir); return -1; } } len = os_strlen(own_dir) + 50; drv->own_socket_path = os_malloc(len); if (drv->own_socket_path == NULL) { os_free(priv_dir); os_free(own_dir); return -1; } os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d", own_dir, getpid(), counter++); len = os_strlen(own_dir) + 50; drv->own_cmd_path = os_malloc(len); if (drv->own_cmd_path == NULL) { os_free(drv->own_socket_path); drv->own_socket_path = NULL; os_free(priv_dir); os_free(own_dir); return -1; } os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d", own_dir, getpid(), counter++); os_free(own_dir); drv->priv_addr.sun_family = AF_UNIX; os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path), "%s/%s", priv_dir, drv->ifname); os_free(priv_dir); drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0); if (drv->priv_socket < 0) { perror("socket(PF_UNIX)"); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path)); if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); close(drv->priv_socket); drv->priv_socket = -1; unlink(drv->own_socket_path); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive, drv, NULL); drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0); if (drv->cmd_socket < 0) { perror("socket(PF_UNIX)"); os_free(drv->own_cmd_path); drv->own_cmd_path = NULL; return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path)); if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); close(drv->cmd_socket); drv->cmd_socket = -1; unlink(drv->own_cmd_path); os_free(drv->own_cmd_path); drv->own_cmd_path = NULL; return -1; } if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) { wpa_printf(MSG_ERROR, "Failed to register with wpa_priv"); return -1; } return 0; }
/** * eap_peer_select_phase2_methods - Select phase 2 EAP method * @config: Pointer to the network configuration * @prefix: 'phase2' configuration prefix, e.g., "auth=" * @types: Buffer for returning allocated list of allowed EAP methods * @num_types: Buffer for returning number of allocated EAP methods * Returns: 0 on success, -1 on failure * * This function is used to parse EAP method list and select allowed methods * for Phase2 authentication. */ int eap_peer_select_phase2_methods(struct eap_peer_config *config, const char *prefix, struct eap_method_type **types, size_t *num_types) { char *start, *pos, *buf; struct eap_method_type *methods = NULL, *_methods; u8 method; size_t num_methods = 0, prefix_len; if (config == NULL || config->phase2 == NULL) goto get_defaults; start = buf = os_strdup(config->phase2); if (buf == NULL) return -1; prefix_len = os_strlen(prefix); while (start && *start != '\0') { int vendor; pos = os_strstr(start, prefix); if (pos == NULL) break; if (start != pos && *(pos - 1) != ' ') { start = pos + prefix_len; continue; } start = pos + prefix_len; pos = os_strchr(start, ' '); if (pos) *pos++ = '\0'; method = eap_get_phase2_type(start, &vendor); if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) { wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP " "method '%s'", start); } else { num_methods++; _methods = os_realloc(methods, num_methods * sizeof(*methods)); if (_methods == NULL) { os_free(methods); os_free(buf); return -1; } methods = _methods; methods[num_methods - 1].vendor = vendor; methods[num_methods - 1].method = method; } start = pos; } os_free(buf); get_defaults: if (methods == NULL) methods = eap_get_phase2_types(config, &num_methods); if (methods == NULL) { wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available"); return -1; } wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types", (u8 *) methods, num_methods * sizeof(struct eap_method_type)); *types = methods; *num_types = num_methods; return 0; }
/* subscr_addr_add_url -- add address(es) for one url to subscription */ static void subscr_addr_add_url(struct subscription *s, const char *url, size_t url_len) { int alloc_len; char *scratch_mem = NULL; char *mem; char *host; char *delim; char *path; int port = 80; /* port to send to (default is port 80) */ struct addrinfo hints; struct addrinfo *result = NULL; struct addrinfo *rp; int rerr; size_t host_len, path_len; /* url MUST begin with http: */ if (url_len < 7 || os_strncasecmp(url, "http://", 7)) goto fail; url += 7; url_len -= 7; /* Make a copy of the string to allow modification during parsing */ scratch_mem = dup_binstr(url, url_len); if (scratch_mem == NULL) goto fail; wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", scratch_mem); host = scratch_mem; path = os_strchr(host, '/'); if (path) *path++ = '\0'; /* null terminate host */ /* Process and remove optional port component */ delim = os_strchr(host, ':'); if (delim) { *delim = '\0'; /* null terminate host name for now */ if (isdigit(delim[1])) port = atol(delim + 1); } /* * getaddrinfo does the right thing with dotted decimal notations, or * will resolve domain names. Resolving domain names will unfortunately * hang the entire program until it is resolved or it times out * internal to getaddrinfo; fortunately we think that the use of actual * domain names (vs. dotted decimal notations) should be uncommon. */ os_memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; /* IPv4 */ hints.ai_socktype = SOCK_STREAM; #if NO_DOMAIN_NAME_RESOLUTION /* Suppress domain name resolutions that would halt * the program for periods of time */ hints.ai_flags = AI_NUMERICHOST; #else /* Allow domain name resolution. */ hints.ai_flags = 0; #endif hints.ai_protocol = 0; /* Any protocol? */ rerr = getaddrinfo(host, NULL /* fill in port ourselves */, &hints, &result); if (rerr) { wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s", rerr, gai_strerror(rerr), host); goto fail; } if (delim) *delim = ':'; /* Restore port */ host_len = os_strlen(host); path_len = path ? os_strlen(path) : 0; alloc_len = host_len + 1 + 1 + path_len + 1; for (rp = result; rp; rp = rp->ai_next) { struct subscr_addr *a; /* Limit no. of address to avoid denial of service attack */ if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) { wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: " "Ignoring excessive addresses"); break; } a = os_zalloc(sizeof(*a) + alloc_len); if (a == NULL) break; mem = (char *) (a + 1); a->domain_and_port = mem; os_memcpy(mem, host, host_len); mem += host_len + 1; a->path = mem; if (path == NULL || path[0] != '/') *mem++ = '/'; if (path) os_memcpy(mem, path, path_len); os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr)); a->saddr.sin_port = htons(port); dl_list_add(&s->addr_list, &a->list); } fail: if (result) freeaddrinfo(result); os_free(scratch_mem); }
static void handle_assoc_cb(struct hostapd_data *hapd, const struct ieee80211_mgmt *mgmt, size_t len, int reassoc, int ok) { u16 status; struct sta_info *sta; int new_assoc = 1; struct ieee80211_ht_capabilities ht_cap; if (!ok) { hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "did not acknowledge association response"); return; } if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) : sizeof(mgmt->u.assoc_resp))) { printf("handle_assoc_cb(reassoc=%d) - too short payload " "(len=%lu)\n", reassoc, (unsigned long) len); return; } if (reassoc) status = le_to_host16(mgmt->u.reassoc_resp.status_code); else status = le_to_host16(mgmt->u.assoc_resp.status_code); sta = ap_get_sta(hapd, mgmt->da); if (!sta) { printf("handle_assoc_cb: STA " MACSTR " not found\n", MAC2STR(mgmt->da)); return; } if (status != WLAN_STATUS_SUCCESS) goto fail; /* Stop previous accounting session, if one is started, and allocate * new session id for the new session. */ accounting_sta_stop(hapd, sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated (aid %d)", sta->aid); if (sta->flags & WLAN_STA_ASSOC) new_assoc = 0; sta->flags |= WLAN_STA_ASSOC; if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || sta->auth_alg == WLAN_AUTH_FT) { /* * Open, static WEP, or FT protocol; no separate authorization * step. */ sta->flags |= WLAN_STA_AUTHORIZED; wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr)); } if (reassoc) mlme_reassociate_indication(hapd, sta); else mlme_associate_indication(hapd, sta); #ifdef CONFIG_IEEE80211W sta->sa_query_timed_out = 0; #endif /* CONFIG_IEEE80211W */ /* * Remove the STA entry in order to make sure the STA PS state gets * cleared and configuration gets updated in case of reassociation back * to the same AP. */ hapd->drv.sta_remove(hapd, sta->addr); #ifdef CONFIG_IEEE80211N if (sta->flags & WLAN_STA_HT) hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap); #endif /* CONFIG_IEEE80211N */ if (hapd->drv.sta_add(hapd, sta->addr, sta->aid, sta->capability, sta->supported_rates, sta->supported_rates_len, sta->listen_interval, sta->flags & WLAN_STA_HT ? &ht_cap : NULL)) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE, "Could not add STA to kernel driver"); } if (sta->eapol_sm == NULL) { /* * This STA does not use RADIUS server for EAP authentication, * so bind it to the selected VLAN interface now, since the * interface selection is not going to change anymore. */ if (ap_sta_bind_vlan(hapd, sta, 0) < 0) goto fail; } else if (sta->vlan_id) { /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */ if (ap_sta_bind_vlan(hapd, sta, 0) < 0) goto fail; } hapd->drv.set_sta_flags(hapd, sta); if (sta->auth_alg == WLAN_AUTH_FT) wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); else wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); hapd->new_assoc_sta_cb(hapd, sta, !new_assoc); ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); fail: /* Copy of the association request is not needed anymore */ if (sta->last_assoc_req) { os_free(sta->last_assoc_req); sta->last_assoc_req = NULL; } }