Add code to simple management IEEE802.11 Association Request/Response packets.
Need more code for complete the management of station association.
This commit is contained in:
parent
bc2a6183ce
commit
547e398924
@ -88,7 +88,7 @@ static int ieee80211_ie_set_dsss(char* buffer, uint8_t channel) {
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ieee80211_ie_set_erp(char* buffer, uint32_t mode) {
|
||||
static int ieee80211_ie_set_erp(char* buffer, uint32_t mode, uint32_t erpmode) {
|
||||
struct ieee80211_ie_erp* ieerp = (struct ieee80211_ie_erp*)buffer;
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
@ -99,7 +99,7 @@ static int ieee80211_ie_set_erp(char* buffer, uint32_t mode) {
|
||||
|
||||
ieerp->id = IEEE80211_IE_ERP;
|
||||
ieerp->len = IEEE80211_IE_ERP_LENGTH;
|
||||
ieerp->params = 0; /* TODO */
|
||||
ieerp->params = erpmode;
|
||||
|
||||
return sizeof(struct ieee80211_ie_erp);
|
||||
}
|
||||
@ -167,7 +167,7 @@ int ieee80211_create_beacon(char* buffer, int length, struct ieee80211_beacon_pa
|
||||
/* TODO */
|
||||
|
||||
/* Information Element: ERP */
|
||||
result = ieee80211_ie_set_erp(pos, params->erpmode);
|
||||
result = ieee80211_ie_set_erp(pos, params->mode, params->erpmode);
|
||||
if (result < 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -250,7 +250,7 @@ int ieee80211_create_probe_response(char* buffer, int length, const struct ieee8
|
||||
/* TODO */
|
||||
|
||||
/* Information Element: ERP */
|
||||
result = ieee80211_ie_set_erp(pos, params->erpmode);
|
||||
result = ieee80211_ie_set_erp(pos, params->mode, params->erpmode);
|
||||
if (result < 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -301,3 +301,52 @@ int ieee80211_create_authentication_response(char* buffer, int length, const str
|
||||
|
||||
return responselength;
|
||||
}
|
||||
|
||||
/* */
|
||||
int ieee80211_create_associationresponse_response(char* buffer, int length, const struct ieee80211_header_mgmt* associationrequestheader, struct ieee80211_associationresponse_params* params) {
|
||||
char* pos;
|
||||
int result;
|
||||
int responselength;
|
||||
struct ieee80211_header_mgmt* header;
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(length == IEEE80211_MTU);
|
||||
|
||||
/* */
|
||||
header = (struct ieee80211_header_mgmt*)buffer;
|
||||
|
||||
/* Management header frame */
|
||||
header->framecontrol = IEEE80211_FRAME_CONTROL(IEEE80211_FRAMECONTROL_TYPE_MGMT, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE);
|
||||
header->durationid = __cpu_to_le16(0);
|
||||
memcpy(header->da, associationrequestheader->sa, ETH_ALEN);
|
||||
memcpy(header->sa, params->bssid, ETH_ALEN);
|
||||
memcpy(header->bssid, params->bssid, ETH_ALEN);
|
||||
header->sequencecontrol = __cpu_to_le16(0);
|
||||
header->associationresponse.capability = __cpu_to_le16(params->capability);
|
||||
header->associationresponse.statuscode = __cpu_to_le16(params->statuscode);
|
||||
header->associationresponse.aid = __cpu_to_le16(params->aid);
|
||||
|
||||
/* Header frame size */
|
||||
responselength = (int)((uint8_t*)&header->associationresponse.ie[0] - (uint8_t*)header);
|
||||
pos = buffer + responselength;
|
||||
|
||||
/* Information Element: Supported Rates */
|
||||
result = ieee80211_ie_set_supportedrates(pos, params->supportedrates, params->supportedratescount);
|
||||
if (result < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos += result;
|
||||
responselength += result;
|
||||
|
||||
/* Information Element: Extended Supported Rates */
|
||||
result = ieee80211_ie_set_extendedsupportedrates(pos, params->supportedrates, params->supportedratescount);
|
||||
if (result < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos += result;
|
||||
responselength += result;
|
||||
|
||||
return responselength;
|
||||
}
|
@ -191,6 +191,9 @@
|
||||
#define IEEE80211_AUTHENTICATION_ALGORITHM_FAST_BSS 2
|
||||
#define IEEE80211_AUTHENTICATION_ALGORITHM_SAE 3
|
||||
|
||||
/* */
|
||||
#define IEEE80211_AID_FIELD 0xC000
|
||||
|
||||
/* 802.11 Packet - IEEE802.11 is a little-endian protocol */
|
||||
struct ieee80211_header {
|
||||
__le16 framecontrol;
|
||||
@ -235,6 +238,19 @@ struct ieee80211_header_mgmt {
|
||||
__le16 statuscode;
|
||||
uint8_t ie[0];
|
||||
} STRUCT_PACKED authetication;
|
||||
|
||||
struct {
|
||||
__le16 capability;
|
||||
__le16 listeninterval;
|
||||
uint8_t ie[0];
|
||||
} STRUCT_PACKED associationrequest;
|
||||
|
||||
struct {
|
||||
__le16 capability;
|
||||
__le16 statuscode;
|
||||
__le16 aid;
|
||||
uint8_t ie[0];
|
||||
} STRUCT_PACKED associationresponse;
|
||||
};
|
||||
} STRUCT_PACKED;
|
||||
|
||||
@ -386,29 +402,25 @@ struct ieee80211_ie_items {
|
||||
|
||||
/* Management Beacon */
|
||||
struct ieee80211_beacon_params {
|
||||
/* Beacon packet */
|
||||
char* headbeacon;
|
||||
int headbeaconlength;
|
||||
char* tailbeacon;
|
||||
int tailbeaconlength;
|
||||
|
||||
/* Header information */
|
||||
uint8_t bssid[ETH_ALEN];
|
||||
|
||||
uint16_t beaconperiod;
|
||||
uint16_t capability;
|
||||
|
||||
/* SSID */
|
||||
const char* ssid;
|
||||
int ssid_hidden;
|
||||
|
||||
/* Supported Rates */
|
||||
int supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
|
||||
/* DSSS */
|
||||
uint8_t channel;
|
||||
|
||||
/* ERP */
|
||||
uint32_t mode;
|
||||
uint32_t erpmode;
|
||||
};
|
||||
|
||||
@ -416,22 +428,19 @@ int ieee80211_create_beacon(char* buffer, int length, struct ieee80211_beacon_pa
|
||||
|
||||
/* Management Probe Response */
|
||||
struct ieee80211_probe_response_params {
|
||||
/* Header information */
|
||||
uint8_t bssid[ETH_ALEN];
|
||||
|
||||
uint16_t beaconperiod;
|
||||
uint16_t capability;
|
||||
|
||||
/* SSID */
|
||||
const char* ssid;
|
||||
|
||||
/* Supported Rates */
|
||||
int supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
|
||||
/* DSSS */
|
||||
uint8_t channel;
|
||||
|
||||
/* ERP */
|
||||
uint32_t mode;
|
||||
uint32_t erpmode;
|
||||
};
|
||||
|
||||
@ -439,8 +448,8 @@ int ieee80211_create_probe_response(char* buffer, int length, const struct ieee8
|
||||
|
||||
/* Management Authentication */
|
||||
struct ieee80211_authentication_params {
|
||||
/* Header information */
|
||||
uint8_t bssid[ETH_ALEN];
|
||||
|
||||
uint16_t algorithm;
|
||||
uint16_t transactionseqnumber;
|
||||
uint16_t statuscode;
|
||||
@ -448,4 +457,18 @@ struct ieee80211_authentication_params {
|
||||
|
||||
int ieee80211_create_authentication_response(char* buffer, int length, const struct ieee80211_header_mgmt* authenticationheader, struct ieee80211_authentication_params* params);
|
||||
|
||||
/* Management Association Response */
|
||||
struct ieee80211_associationresponse_params {
|
||||
uint8_t bssid[ETH_ALEN];
|
||||
|
||||
uint16_t capability;
|
||||
uint16_t statuscode;
|
||||
uint16_t aid;
|
||||
|
||||
int supportedratescount;
|
||||
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
|
||||
};
|
||||
|
||||
int ieee80211_create_associationresponse_response(char* buffer, int length, const struct ieee80211_header_mgmt* associationrequestheader, struct ieee80211_associationresponse_params* params);
|
||||
|
||||
#endif /* __CAPWAP_IEEE802_11_HEADER__ */
|
||||
|
@ -294,8 +294,9 @@ static void nl80211_do_mgmt_probe_request_event(struct nl80211_wlan_handle* wlan
|
||||
ieee80211_params.ssid = wlanhandle->ssid;
|
||||
memcpy(ieee80211_params.supportedrates, wlanhandle->supportedrates, wlanhandle->supportedratescount);
|
||||
ieee80211_params.supportedratescount = wlanhandle->supportedratescount;
|
||||
ieee80211_params.mode = wlanhandle->devicehandle->currentfrequency.mode;
|
||||
ieee80211_params.erpmode = 0; /* TODO */
|
||||
ieee80211_params.channel = wifi_frequency_to_channel(wlanhandle->devicehandle->currentfrequency);
|
||||
ieee80211_params.channel = wlanhandle->devicehandle->currentfrequency.channel;
|
||||
|
||||
responselength = ieee80211_create_probe_response(buffer, IEEE80211_MTU, mgmt, &ieee80211_params);
|
||||
if (responselength < 0) {
|
||||
@ -306,7 +307,7 @@ static void nl80211_do_mgmt_probe_request_event(struct nl80211_wlan_handle* wlan
|
||||
memset(&wlan_params, 0, sizeof(struct wlan_send_frame_params));
|
||||
wlan_params.packet = buffer;
|
||||
wlan_params.length = responselength;
|
||||
wlan_params.frequency = wlanhandle->devicehandle->currentfrequency;
|
||||
wlan_params.frequency = wlanhandle->devicehandle->currentfrequency.frequency;
|
||||
wlan_params.no_wait_ack = ((ssidcheck == WIFI_WILDCARD_SSID) && wifi_is_broadcast_addr(mgmt->da) ? 1 : 0);
|
||||
|
||||
if (nl80211_wlan_send_frame((wifi_wlan_handle)wlanhandle, &wlan_params)) {
|
||||
@ -376,7 +377,7 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla
|
||||
memset(&wlan_params, 0, sizeof(struct wlan_send_frame_params));
|
||||
wlan_params.packet = buffer;
|
||||
wlan_params.length = responselength;
|
||||
wlan_params.frequency = wlanhandle->devicehandle->currentfrequency;
|
||||
wlan_params.frequency = wlanhandle->devicehandle->currentfrequency.frequency;
|
||||
|
||||
if (!nl80211_wlan_send_frame((wifi_wlan_handle)wlanhandle, &wlan_params)) {
|
||||
wlanhandle->last_cookie = wlan_params.cookie;
|
||||
@ -385,12 +386,62 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_do_mgmt_association_request_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
|
||||
int ielength;
|
||||
int responselength;
|
||||
char buffer[IEEE80211_MTU];
|
||||
struct ieee80211_ie_items ieitems;
|
||||
struct ieee80211_associationresponse_params ieee80211_params;
|
||||
struct wlan_send_frame_params wlan_params;
|
||||
|
||||
/* Information Elements packet length */
|
||||
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest));
|
||||
if (ielength < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parsing Information Elements */
|
||||
if (wifi_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get station reference */
|
||||
/* TODO */
|
||||
|
||||
/* Create association response packet */
|
||||
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
|
||||
memcpy(ieee80211_params.bssid, wlanhandle->address, ETH_ALEN);
|
||||
ieee80211_params.capability = wlanhandle->capability;
|
||||
ieee80211_params.statuscode = IEEE80211_STATUS_SUCCESS;
|
||||
ieee80211_params.aid = IEEE80211_AID_FIELD | 1;
|
||||
memcpy(ieee80211_params.supportedrates, wlanhandle->supportedrates, wlanhandle->supportedratescount);
|
||||
ieee80211_params.supportedratescount = wlanhandle->supportedratescount;
|
||||
|
||||
responselength = ieee80211_create_associationresponse_response(buffer, IEEE80211_MTU, mgmt, &ieee80211_params);
|
||||
if (responselength < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send authentication response */
|
||||
memset(&wlan_params, 0, sizeof(struct wlan_send_frame_params));
|
||||
wlan_params.packet = buffer;
|
||||
wlan_params.length = responselength;
|
||||
wlan_params.frequency = wlanhandle->devicehandle->currentfrequency.frequency;
|
||||
|
||||
if (!nl80211_wlan_send_frame((wifi_wlan_handle)wlanhandle, &wlan_params)) {
|
||||
wlanhandle->last_cookie = wlan_params.cookie;
|
||||
} else {
|
||||
capwap_logging_warning("Unable to send IEEE802.11 Association Response");
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_do_mgmt_frame_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint16_t framecontrol_subtype, uint32_t frequency) {
|
||||
int broadcast;
|
||||
|
||||
/* Check frequency */
|
||||
if (frequency && (wlanhandle->devicehandle->currentfrequency != frequency)) {
|
||||
if (frequency && (wlanhandle->devicehandle->currentfrequency.frequency != frequency)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -411,7 +462,7 @@ static void nl80211_do_mgmt_frame_event(struct nl80211_wlan_handle* wlanhandle,
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST: {
|
||||
/* TODO */
|
||||
nl80211_do_mgmt_association_request_event(wlanhandle, mgmt, mgmtlength);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -493,6 +544,26 @@ static void nl80211_do_mgmt_frame_tx_status_authentication_event(struct nl80211_
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void nl80211_do_mgmt_frame_tx_status_association_response_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint64_t cookie, int ack) {
|
||||
uint16_t statuscode;
|
||||
|
||||
/* Accept only acknowledge association response with same cookie */
|
||||
if (!ack || (wlanhandle->last_cookie != cookie)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check packet */
|
||||
if (mgmtlength < (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* */
|
||||
statuscode = __le16_to_cpu(mgmt->associationresponse.statuscode);
|
||||
if (statuscode == IEEE80211_STATUS_SUCCESS) {
|
||||
capwap_logging_debug("Associate station");
|
||||
}
|
||||
}
|
||||
/* */
|
||||
static void nl80211_do_mgmt_frame_tx_status_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint16_t framecontrol_subtype, uint64_t cookie, int ack) {
|
||||
/* Ignore packet if not sent to AP */
|
||||
@ -506,6 +577,11 @@ static void nl80211_do_mgmt_frame_tx_status_event(struct nl80211_wlan_handle* wl
|
||||
nl80211_do_mgmt_frame_tx_status_authentication_event(wlanhandle, mgmt, mgmtlength, cookie, ack);
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE: {
|
||||
nl80211_do_mgmt_frame_tx_status_association_response_event(wlanhandle, mgmt, mgmtlength, cookie, ack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove cookie */
|
||||
@ -562,7 +638,7 @@ static int nl80211_execute_bss_event(struct nl80211_wlan_handle* wlanhandle, str
|
||||
}
|
||||
|
||||
default: {
|
||||
capwap_logging_debug("nl80211_execute_bss_event: %d", (int)gnlh->cmd);
|
||||
capwap_logging_debug("*** nl80211_execute_bss_event: %d", (int)gnlh->cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -628,6 +704,8 @@ static int nl80211_global_valid_handler(struct nl_msg* msg, void* data) {
|
||||
|
||||
devicesearch = devicesearch->next;
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("*** Receive nl80211_global_valid_handler without interface index");
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
@ -1222,7 +1300,7 @@ static int nl80211_device_setfrequency(wifi_device_handle handle, struct wifi_fr
|
||||
/* Set wifi frequency */
|
||||
result = nl80211_send_and_recv_msg(devicehandle->globalhandle, msg, NULL, NULL);
|
||||
if (!result) {
|
||||
devicehandle->currentfrequency = freq->frequency;
|
||||
memcpy(&devicehandle->currentfrequency, freq, sizeof(struct wifi_frequency));
|
||||
} else {
|
||||
capwap_logging_error("Unable retrieve physical device capability, error code: %d", result);
|
||||
}
|
||||
@ -1482,8 +1560,9 @@ static int nl80211_wlan_startap(wifi_wlan_handle handle, struct wlan_startap_par
|
||||
ieee80211_params.ssid_hidden = params->ssid_hidden;
|
||||
memcpy(ieee80211_params.supportedrates, params->supportedrates, params->supportedratescount);
|
||||
ieee80211_params.supportedratescount = params->supportedratescount;
|
||||
ieee80211_params.mode = wlanhandle->devicehandle->currentfrequency.mode;
|
||||
ieee80211_params.erpmode = 0; /* TODO */
|
||||
ieee80211_params.channel = wifi_frequency_to_channel(wlanhandle->devicehandle->currentfrequency);
|
||||
ieee80211_params.channel = wlanhandle->devicehandle->currentfrequency.channel;
|
||||
|
||||
result = ieee80211_create_beacon(buffer, IEEE80211_MTU, &ieee80211_params);
|
||||
if (result < 0) {
|
||||
|
@ -32,7 +32,7 @@ struct nl80211_device_handle {
|
||||
|
||||
struct capwap_list* wlanlist;
|
||||
|
||||
uint32_t currentfrequency;
|
||||
struct wifi_frequency currentfrequency;
|
||||
|
||||
struct wifi_capability* capability; /* Cached capability */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user