📄 mlme.c
字号:
/* * WPA Supplicant - Client mode MLME * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> * Copyright (c) 2004, Instant802 Networks, Inc. * Copyright (c) 2005-2006, Devicescape Software, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include "common.h"#include "eloop.h"#include "config.h"#include "wpa_supplicant.h"#include "wpa_supplicant_i.h"#include "wpa.h"#include "os.h"#include "l2_packet.h"#include "driver.h"#include "mlme.h"/* Timeouts and intervals in milliseconds */#define IEEE80211_AUTH_TIMEOUT (200)#define IEEE80211_AUTH_MAX_TRIES 3#define IEEE80211_ASSOC_TIMEOUT (200)#define IEEE80211_ASSOC_MAX_TRIES 3#define IEEE80211_MONITORING_INTERVAL (2000)#define IEEE80211_PROBE_INTERVAL (60000)#define IEEE80211_RETRY_AUTH_INTERVAL (1000)#define IEEE80211_SCAN_INTERVAL (2000)#define IEEE80211_SCAN_INTERVAL_SLOW (15000)#define IEEE80211_IBSS_JOIN_TIMEOUT (20000)#define IEEE80211_PROBE_DELAY (33)#define IEEE80211_CHANNEL_TIME (33)#define IEEE80211_PASSIVE_CHANNEL_TIME (200)#define IEEE80211_SCAN_RESULT_EXPIRE (10000)#define IEEE80211_IBSS_MERGE_INTERVAL (30000)#define IEEE80211_IBSS_INACTIVITY_LIMIT (60000)#define IEEE80211_IBSS_MAX_STA_ENTRIES 128/* Information Element IDs */#define WLAN_EID_SSID 0#define WLAN_EID_SUPP_RATES 1#define WLAN_EID_FH_PARAMS 2#define WLAN_EID_DS_PARAMS 3#define WLAN_EID_CF_PARAMS 4#define WLAN_EID_TIM 5#define WLAN_EID_IBSS_PARAMS 6#define WLAN_EID_COUNTRY 7#define WLAN_EID_CHALLENGE 16/* EIDs defined as part fo 11h - starts */#define WLAN_EID_PWR_CONSTRAINT 32#define WLAN_EID_PWR_CAPABILITY 33#define WLAN_EID_TPC_REQUEST 34#define WLAN_EID_TPC_REPORT 35#define WLAN_EID_SUPPORTED_CHANNELS 36#define WLAN_EID_CHANNEL_SWITCH 37#define WLAN_EID_MEASURE_REQUEST 38#define WLAN_EID_MEASURE_REPORT 39#define WLAN_EID_QUITE 40#define WLAN_EID_IBSS_DFS 41/* EIDs defined as part fo 11h - ends */#define WLAN_EID_ERP_INFO 42#define WLAN_EID_RSN 48#define WLAN_EID_EXT_SUPP_RATES 50#define WLAN_EID_VENDOR_SPECIFIC 221#ifdef _MSC_VER#pragma pack(push, 1)#endif /* _MSC_VER */struct ieee80211_mgmt { u16 frame_control; u16 duration; u8 da[6]; u8 sa[6]; u8 bssid[6]; u16 seq_ctrl; union { struct { u16 auth_alg; u16 auth_transaction; u16 status_code; /* possibly followed by Challenge text */ u8 variable[0]; } STRUCT_PACKED auth; struct { u16 reason_code; } STRUCT_PACKED deauth; struct { u16 capab_info; u16 listen_interval; /* followed by SSID and Supported rates */ u8 variable[0]; } STRUCT_PACKED assoc_req; struct { u16 capab_info; u16 status_code; u16 aid; /* followed by Supported rates */ u8 variable[0]; } STRUCT_PACKED assoc_resp, reassoc_resp; struct { u16 capab_info; u16 listen_interval; u8 current_ap[6]; /* followed by SSID and Supported rates */ u8 variable[0]; } STRUCT_PACKED reassoc_req; struct { u16 reason_code; } STRUCT_PACKED disassoc; struct { u8 timestamp[8]; u16 beacon_int; u16 capab_info; /* followed by some of SSID, Supported rates, * FH Params, DS Params, CF Params, IBSS Params, TIM */ u8 variable[0]; } STRUCT_PACKED beacon; struct { /* only variable items: SSID, Supported rates */ u8 variable[0]; } STRUCT_PACKED probe_req; struct { u8 timestamp[8]; u16 beacon_int; u16 capab_info; /* followed by some of SSID, Supported rates, * FH Params, DS Params, CF Params, IBSS Params */ u8 variable[0]; } STRUCT_PACKED probe_resp; struct { u8 category; union { struct { u8 action_code; u8 dialog_token; u8 status_code; u8 variable[0]; } STRUCT_PACKED wme_action; struct{ u8 action_code; u8 element_id; u8 length; u8 switch_mode; u8 new_chan; u8 switch_count; } __attribute__((packed)) chan_switch; } u; } STRUCT_PACKED action; } u;} STRUCT_PACKED;#ifdef _MSC_VER#pragma pack(pop)#endif /* _MSC_VER *//* Authentication algorithms */#define WLAN_AUTH_OPEN 0#define WLAN_AUTH_SHARED_KEY 1#define WLAN_AUTH_LEAP 128#define WLAN_AUTH_CHALLENGE_LEN 128#define WLAN_CAPABILITY_ESS BIT(0)#define WLAN_CAPABILITY_IBSS BIT(1)#define WLAN_CAPABILITY_CF_POLLABLE BIT(2)#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3)#define WLAN_CAPABILITY_PRIVACY BIT(4)#define WLAN_CAPABILITY_SHORT_PREAMBLE BIT(5)#define WLAN_CAPABILITY_PBCC BIT(6)#define WLAN_CAPABILITY_CHANNEL_AGILITY BIT(7)/* 802.11h */#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8)#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10)#define WLAN_CAPABILITY_DSSS_OFDM BIT(13)/* Status codes */#define WLAN_STATUS_SUCCESS 0#define WLAN_STATUS_UNSPECIFIED_FAILURE 1#define WLAN_STATUS_CAPS_UNSUPPORTED 10#define WLAN_STATUS_REASSOC_NO_ASSOC 11#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14#define WLAN_STATUS_CHALLENGE_FAIL 15#define WLAN_STATUS_AUTH_TIMEOUT 16#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17#define WLAN_STATUS_ASSOC_DENIED_RATES 18/* 802.11b */#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21/* 802.11h */#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24/* 802.11g */#define WLAN_STATUS_ASSOC_DENOED_NO_SHORT_SLOT_TIME 25#define WLAN_STATUS_ASSOC_DENOED_NO_ER_PBCC 26#define WLAN_STATUS_ASSOC_DENOED_NO_DSSS_OFDM 27/* Reason codes */#define WLAN_REASON_UNSPECIFIED 1#define WLAN_REASON_PREV_AUTH_NOT_VALID 2#define WLAN_REASON_DEAUTH_LEAVING 3#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4#define WLAN_REASON_DISASSOC_AP_BUSY 5#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9/* 802.11h */#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11#define WLAN_REASON_MIC_FAILURE 14#define WLAN_FC_PVER 0x0003#define WLAN_FC_TODS 0x0100#define WLAN_FC_FROMDS 0x0200#define WLAN_FC_MOREFRAG 0x0400#define WLAN_FC_RETRY 0x0800#define WLAN_FC_PWRMGT 0x1000#define WLAN_FC_MOREDATA 0x2000#define WLAN_FC_ISWEP 0x4000#define WLAN_FC_ORDER 0x8000#define WLAN_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2)#define WLAN_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4)#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4))#define WLAN_FC_TYPE_MGMT 0#define WLAN_FC_TYPE_CTRL 1#define WLAN_FC_TYPE_DATA 2/* management */#define WLAN_FC_STYPE_ASSOC_REQ 0#define WLAN_FC_STYPE_ASSOC_RESP 1#define WLAN_FC_STYPE_REASSOC_REQ 2#define WLAN_FC_STYPE_REASSOC_RESP 3#define WLAN_FC_STYPE_PROBE_REQ 4#define WLAN_FC_STYPE_PROBE_RESP 5#define WLAN_FC_STYPE_BEACON 8#define WLAN_FC_STYPE_ATIM 9#define WLAN_FC_STYPE_DISASSOC 10#define WLAN_FC_STYPE_AUTH 11#define WLAN_FC_STYPE_DEAUTH 12#define WLAN_FC_STYPE_ACTION 13#define ERP_INFO_USE_PROTECTION BIT(1)struct ieee80211_sta_bss { struct ieee80211_sta_bss *next; struct ieee80211_sta_bss *hnext; u8 bssid[ETH_ALEN]; u8 ssid[MAX_SSID_LEN]; size_t ssid_len; u16 capability; /* host byte order */ int hw_mode; int channel; int freq; int rssi; u8 *wpa_ie; size_t wpa_ie_len; u8 *rsn_ie; size_t rsn_ie_len; u8 *wmm_ie; size_t wmm_ie_len;#define IEEE80211_MAX_SUPP_RATES 32 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; size_t supp_rates_len; int beacon_int; u64 timestamp; int probe_resp; struct os_time last_update;};static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s, const u8 *dst, const u8 *ssid, size_t ssid_len);static struct ieee80211_sta_bss *ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid);static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s);static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s);static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx);static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx);/* Parsed Information Elements */struct ieee802_11_elems { u8 *ssid; u8 ssid_len; u8 *supp_rates; u8 supp_rates_len; u8 *fh_params; u8 fh_params_len; u8 *ds_params; u8 ds_params_len; u8 *cf_params; u8 cf_params_len; u8 *tim; u8 tim_len; u8 *ibss_params; u8 ibss_params_len; u8 *challenge; u8 challenge_len; u8 *wpa; u8 wpa_len; u8 *rsn; u8 rsn_len; u8 *erp_info; u8 erp_info_len; u8 *ext_supp_rates; u8 ext_supp_rates_len; u8 *wmm_info; u8 wmm_info_len; u8 *wmm_param; u8 wmm_param_len;};typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, struct ieee802_11_elems *elems){ size_t left = len; u8 *pos = start; int unknown = 0; os_memset(elems, 0, sizeof(*elems)); while (left >= 2) { u8 id, elen; id = *pos++; elen = *pos++; left -= 2; if (elen > left) {#if 0 wpa_printf(MSG_MSGDUMP, "MLME: IEEE 802.11 element " "parse failed (id=%d elen=%d left=%d)", id, elen, left);#endif return ParseFailed; } switch (id) { case WLAN_EID_SSID: elems->ssid = pos; elems->ssid_len = elen; break; case WLAN_EID_SUPP_RATES: elems->supp_rates = pos; elems->supp_rates_len = elen; break; case WLAN_EID_FH_PARAMS: elems->fh_params = pos; elems->fh_params_len = elen; break; case WLAN_EID_DS_PARAMS: elems->ds_params = pos; elems->ds_params_len = elen; break; case WLAN_EID_CF_PARAMS: elems->cf_params = pos; elems->cf_params_len = elen; break; case WLAN_EID_TIM: elems->tim = pos; elems->tim_len = elen; break; case WLAN_EID_IBSS_PARAMS: elems->ibss_params = pos; elems->ibss_params_len = elen; break; case WLAN_EID_CHALLENGE: elems->challenge = pos; elems->challenge_len = elen; break; case WLAN_EID_VENDOR_SPECIFIC: if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && pos[2] == 0xf2) { /* Microsoft OUI (00:50:F2) */ if (pos[3] == 1) { /* OUI Type 1 - WPA IE */ elems->wpa = pos; elems->wpa_len = elen; } else if (elen >= 5 && pos[3] == 2) { if (pos[4] == 0) { elems->wmm_info = pos; elems->wmm_info_len = elen; } else if (pos[4] == 1) { elems->wmm_param = pos; elems->wmm_param_len = elen; } } } break; case WLAN_EID_RSN: elems->rsn = pos; elems->rsn_len = elen; break; case WLAN_EID_ERP_INFO: elems->erp_info = pos; elems->erp_info_len = elen; break; case WLAN_EID_EXT_SUPP_RATES: elems->ext_supp_rates = pos; elems->ext_supp_rates_len = elen; break; default:#if 0 wpa_printf(MSG_MSGDUMP "MLME: IEEE 802.11 element " "parse ignored unknown element (id=%d " "elen=%d)", id, elen);#endif unknown++; break; } left -= elen; pos += elen; } if (left) return ParseFailed; return unknown ? ParseUnknown : ParseOK;}static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s, wpa_hw_mode phymode, int chan, int freq){ size_t i; struct wpa_hw_modes *mode; for (i = 0; i < wpa_s->mlme.num_modes; i++) { mode = &wpa_s->mlme.modes[i]; if (mode->mode == phymode) { wpa_s->mlme.curr_rates = mode->rates; wpa_s->mlme.num_curr_rates = mode->num_rates; break; } } return wpa_drv_set_channel(wpa_s, phymode, chan, freq);}#if 0 /* FIX */static int ecw2cw(int ecw){ int cw = 1; while (ecw > 0) { cw <<= 1; ecw--; } return cw - 1;}#endifstatic void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s, u8 *wmm_param, size_t wmm_param_len){ size_t left;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -