Add code to simple management IEEE802.11 Authentication packets

This commit is contained in:
vemax78 2014-01-13 19:00:51 +01:00
parent b4a95beb89
commit bc2a6183ce
4 changed files with 583 additions and 96 deletions

View File

@ -114,15 +114,17 @@ int ieee80211_create_beacon(char* buffer, int length, struct ieee80211_beacon_pa
ASSERT(length == IEEE80211_MTU); ASSERT(length == IEEE80211_MTU);
/* */ /* */
memset(buffer, 0x00, length);
header = (struct ieee80211_header_mgmt*)buffer; header = (struct ieee80211_header_mgmt*)buffer;
params->headbeacon = buffer; params->headbeacon = buffer;
/* Management header frame */ /* Management header frame */
header->framecontrol = IEEE80211_FRAME_CONTROL(IEEE80211_FRAMECONTROL_TYPE_MGMT, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_BEACON); header->framecontrol = IEEE80211_FRAME_CONTROL(IEEE80211_FRAMECONTROL_TYPE_MGMT, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_BEACON);
header->durationid = __cpu_to_le16(0);
memset(header->da, 0xff, ETH_ALEN); memset(header->da, 0xff, ETH_ALEN);
memcpy(header->sa, params->bssid, ETH_ALEN); memcpy(header->sa, params->bssid, ETH_ALEN);
memcpy(header->bssid, params->bssid, ETH_ALEN); memcpy(header->bssid, params->bssid, ETH_ALEN);
header->sequencecontrol = __cpu_to_le16(0);
memset(header->beacon.timestamp, 0, sizeof(header->beacon.timestamp));
header->beacon.beaconinterval = __cpu_to_le16(params->beaconperiod); header->beacon.beaconinterval = __cpu_to_le16(params->beaconperiod);
header->beacon.capability = __cpu_to_le16(params->capability); header->beacon.capability = __cpu_to_le16(params->capability);
@ -196,18 +198,20 @@ int ieee80211_create_probe_response(char* buffer, int length, const struct ieee8
ASSERT(length == IEEE80211_MTU); ASSERT(length == IEEE80211_MTU);
/* */ /* */
memset(buffer, 0x00, length);
header = (struct ieee80211_header_mgmt*)buffer; header = (struct ieee80211_header_mgmt*)buffer;
/* Management header frame */ /* Management header frame */
header->framecontrol = IEEE80211_FRAME_CONTROL(IEEE80211_FRAMECONTROL_TYPE_MGMT, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_RESP); header->framecontrol = IEEE80211_FRAME_CONTROL(IEEE80211_FRAMECONTROL_TYPE_MGMT, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_RESPONSE);
header->durationid = __cpu_to_le16(0);
if (proberequestheader) { if (proberequestheader) {
memcpy(header->da, proberequestheader->sa, ETH_ALEN); memcpy(header->da, proberequestheader->sa, ETH_ALEN);
} else { } else {
memset(header->da, 0x00, ETH_ALEN); memset(header->da, 0, ETH_ALEN);
} }
memcpy(header->sa, params->bssid, ETH_ALEN); memcpy(header->sa, params->bssid, ETH_ALEN);
memcpy(header->bssid, params->bssid, ETH_ALEN); memcpy(header->bssid, params->bssid, ETH_ALEN);
header->sequencecontrol = __cpu_to_le16(0);
memset(header->proberesponse.timestamp, 0, sizeof(header->proberesponse.timestamp));
header->proberesponse.beaconinterval = __cpu_to_le16(params->beaconperiod); header->proberesponse.beaconinterval = __cpu_to_le16(params->beaconperiod);
header->proberesponse.capability = __cpu_to_le16(params->capability); header->proberesponse.capability = __cpu_to_le16(params->capability);
@ -265,3 +269,35 @@ int ieee80211_create_probe_response(char* buffer, int length, const struct ieee8
return responselength; return responselength;
} }
/* */
int ieee80211_create_authentication_response(char* buffer, int length, const struct ieee80211_header_mgmt* authenticationheader, struct ieee80211_authentication_params* params) {
char* pos;
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_AUTHENTICATION);
header->durationid = __cpu_to_le16(0);
memcpy(header->da, authenticationheader->sa, ETH_ALEN);
memcpy(header->sa, params->bssid, ETH_ALEN);
memcpy(header->bssid, params->bssid, ETH_ALEN);
header->sequencecontrol = __cpu_to_le16(0);
header->authetication.algorithm = __cpu_to_le16(params->algorithm);
header->authetication.transactionseqnumber = __cpu_to_le16(params->transactionseqnumber);
header->authetication.statuscode = __cpu_to_le16(params->statuscode);
/* Header frame size */
responselength = (int)((uint8_t*)&header->authetication.ie[0] - (uint8_t*)header);
pos = buffer + responselength;
/* TODO: add custon IE */
return responselength;
}

View File

@ -53,18 +53,18 @@
#define IEEE80211_FRAMECONTROL_TYPE_DATA 2 #define IEEE80211_FRAMECONTROL_TYPE_DATA 2
/* Frame control Management subtype */ /* Frame control Management subtype */
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOC_REQ 0 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST 0
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOC_RESP 1 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE 1
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOC_REQ 2 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST 2
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOC_RESP 3 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_RESPONSE 3
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQ 4 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST 4
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_RESP 5 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_RESPONSE 5
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_TIMING_ADV 6 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_TIMING_ADV 6
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_BEACON 8 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_BEACON 8
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ATIM 9 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ATIM 9
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOC 10 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION 10
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTH 11 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION 11
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTH 12 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION 12
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION 13 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION 13
#define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION_NOACK 14 #define IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION_NOACK 14
@ -101,6 +101,96 @@
#define IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol) (((framecontrol) & 0x000c) >> 2) #define IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol) (((framecontrol) & 0x000c) >> 2)
#define IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol) (((framecontrol) & 0x00f0) >> 4) #define IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol) (((framecontrol) & 0x00f0) >> 4)
/* IEEE802.11 Status Code */
#define IEEE80211_STATUS_SUCCESS 0
#define IEEE80211_STATUS_UNSPECIFIED_FAILURE 1
#define IEEE80211_STATUS_TDLS_WAKEUP_ALTERNATE 2
#define IEEE80211_STATUS_TDLS_WAKEUP_REJECT 3
#define IEEE80211_STATUS_SECURITY_DISABLED 5
#define IEEE80211_STATUS_UNACCEPTABLE_LIFETIME 6
#define IEEE80211_STATUS_NOT_IN_SAME_BSS 7
#define IEEE80211_STATUS_CAPS_UNSUPPORTED 10
#define IEEE80211_STATUS_REASSOCIATION_NO_ASSOCIATE 11
#define IEEE80211_STATUS_ASSOCIATION_DENIED_UNSPEC 12
#define IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM 13
#define IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION 14
#define IEEE80211_STATUS_CHALLENGE_FAIL 15
#define IEEE80211_STATUS_AUTHENTICATION_TIMEOUT 16
#define IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
#define IEEE80211_STATUS_ASSOCIATION_DENIED_RATES 18
#define IEEE80211_STATUS_ASSOCIATION_DENIED_NOSHORT 19
#define IEEE80211_STATUS_ASSOCIATION_DENIED_NOPBCC 20
#define IEEE80211_STATUS_ASSOCIATION_DENIED_NOAGILITY 21
#define IEEE80211_STATUS_SPEC_MGMT_REQUIRED 22
#define IEEE80211_STATUS_PWR_CAPABILITY_NOT_VALID 23
#define IEEE80211_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24
#define IEEE80211_STATUS_ASSOCIATION_DENIED_NO_SHORT_SLOT_TIME 25
#define IEEE80211_STATUS_ASSOCIATION_DENIED_NO_DSSS_OFDM 26
#define IEEE80211_STATUS_ASSOCIATION_DENIED_NO_HT 27
#define IEEE80211_STATUS_R0KH_UNREACHABLE 28
#define IEEE80211_STATUS_ASSOCIATION_DENIED_NO_PCO 29
#define IEEE80211_STATUS_ASSOCIATION_REJECTED_TEMPORARILY 30
#define IEEE80211_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31
#define IEEE80211_STATUS_UNSPECIFIED_QOS_FAILURE 32
#define IEEE80211_STATUS_QOS_INSUFFICIENT_BANDWIDTH 33
#define IEEE80211_STATUS_EXCESSIVE_FRAME_LOST 34
#define IEEE80211_STATUS_STA_NOT_SUPPORT_QOS_FACILITY 35
#define IEEE80211_STATUS_REQUEST_DECLINED 37
#define IEEE80211_STATUS_INVALID_PARAMETERS 38
#define IEEE80211_STATUS_REJECTED_WITH_SUGGESTED_CHANGES 39
#define IEEE80211_STATUS_INVALID_IE 40
#define IEEE80211_STATUS_GROUP_CIPHER_NOT_VALID 41
#define IEEE80211_STATUS_PAIRWISE_CIPHER_NOT_VALID 42
#define IEEE80211_STATUS_AKMP_NOT_VALID 43
#define IEEE80211_STATUS_UNSUPPORTED_RSN_IE_VERSION 44
#define IEEE80211_STATUS_INVALID_RSN_IE_CAPAB 45
#define IEEE80211_STATUS_CIPHER_REJECTED_PER_POLICY 46
#define IEEE80211_STATUS_TS_NOT_CREATED 47
#define IEEE80211_STATUS_DIRECT_LINK_NOT_ALLOWED 48
#define IEEE80211_STATUS_DEST_STA_NOT_PRESENT 49
#define IEEE80211_STATUS_DEST_STA_NOT_QOS_STA 50
#define IEEE80211_STATUS_ASSOCIATION_DENIED_LISTEN_INT_TOO_LARGE 51
#define IEEE80211_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52
#define IEEE80211_STATUS_INVALID_PMKID 53
#define IEEE80211_STATUS_INVALID_MDIE 54
#define IEEE80211_STATUS_INVALID_FTIE 55
#define IEEE80211_STATUS_REQUEST_TCLAS_NOT_SUPPORTED 56
#define IEEE80211_STATUS_INSUFFICIENT_TCLAS 57
#define IEEE80211_STATUS_TS_NOT_BEEN_CREATED 58
#define IEEE80211_STATUS_GAS_ADV_PROTO_NOT_SUPPORTED 59
#define IEEE80211_STATUS_NO_OUTSTANDING_GAS_REQ 60
#define IEEE80211_STATUS_GAS_RESP_NOT_RECEIVED 61
#define IEEE80211_STATUS_STA_TIMED_OUT_WAITING_FOR_GAS_RESP 62
#define IEEE80211_STATUS_GAS_RESP_LARGER_THAN_LIMIT 63
#define IEEE80211_STATUS_REQ_REFUSED_HOME 64
#define IEEE80211_STATUS_ADV_SRV_UNREACHABLE 65
#define IEEE80211_STATUS_REQ_REFUSED_SSPN 67
#define IEEE80211_STATUS_REQ_REFUSED_UNAUTH_ACCESS 68
#define IEEE80211_STATUS_INVALID_RSNIE 72
#define IEEE80211_STATUS_UAPSD_COEXISTENCE_NOT_SUPPORTED 73
#define IEEE80211_STATUS_REQUEST_UAPSD_COEXISTENCE_NOT_SUPPORTED 74
#define IEEE80211_STATUS_REQUEST_INTERVAL_NOT SUPPORTED 75
#define IEEE80211_STATUS_ANTI_CLOGGING_TOKEN_REQ 76
#define IEEE80211_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED 77
#define IEEE80211_STATUS_CANNOT_FIND_ALTERNATIVE_TBTT 78
#define IEEE80211_STATUS_TRANSMISSION_FAILURE 79
#define IEEE80211_STATUS_REQUYESTED_TCLAS_NOT_SUPPORTED 80
#define IEEE80211_STATUS_TCLAS_RESOURCES_EXHAUSTED 81
#define IEEE80211_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION 82
#define IEEE80211_STATUS_REFUSED_EXTERNAL_REASON 92
#define IEEE80211_STATUS_REFUSED_AP_OUT_OF_MEMORY 93
#define IEEE80211_STATUS_REJECTED_EMERGENCY_SERVICES_NOT_SUPPORTED 94
#define IEEE80211_STATUS_QUERY_RESPONSE_OUTSTANDING 95
#define IEEE80211_STATUS_MCCAOP_RESERVATION_CONFLICT 100
#define IEEE80211_STATUS_MAF_LIMIT_EXCEEDED 101
#define IEEE80211_STATUS_MCCA_TRACK_LIMIT_EXCEEDED 102
/* IEEE802.11 Authentication Algorithm */
#define IEEE80211_AUTHENTICATION_ALGORITHM_OPEN 0
#define IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY 1
#define IEEE80211_AUTHENTICATION_ALGORITHM_FAST_BSS 2
#define IEEE80211_AUTHENTICATION_ALGORITHM_SAE 3
/* 802.11 Packet - IEEE802.11 is a little-endian protocol */ /* 802.11 Packet - IEEE802.11 is a little-endian protocol */
struct ieee80211_header { struct ieee80211_header {
__le16 framecontrol; __le16 framecontrol;
@ -140,9 +230,9 @@ struct ieee80211_header_mgmt {
} STRUCT_PACKED proberesponse; } STRUCT_PACKED proberesponse;
struct { struct {
__le16 auth_alg; __le16 algorithm;
__le16 auth_transaction; __le16 transactionseqnumber;
__le16 status_code; __le16 statuscode;
uint8_t ie[0]; uint8_t ie[0];
} STRUCT_PACKED authetication; } STRUCT_PACKED authetication;
}; };
@ -347,4 +437,15 @@ struct ieee80211_probe_response_params {
int ieee80211_create_probe_response(char* buffer, int length, const struct ieee80211_header_mgmt* proberequestheader, struct ieee80211_probe_response_params* params); int ieee80211_create_probe_response(char* buffer, int length, const struct ieee80211_header_mgmt* proberequestheader, struct ieee80211_probe_response_params* params);
/* Management Authentication */
struct ieee80211_authentication_params {
/* Header information */
uint8_t bssid[ETH_ALEN];
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t statuscode;
};
int ieee80211_create_authentication_response(char* buffer, int length, const struct ieee80211_header_mgmt* authenticationheader, struct ieee80211_authentication_params* params);
#endif /* __CAPWAP_IEEE802_11_HEADER__ */ #endif /* __CAPWAP_IEEE802_11_HEADER__ */

View File

@ -12,6 +12,12 @@
#include "wifi_drivers.h" #include "wifi_drivers.h"
#include "wifi_nl80211.h" #include "wifi_nl80211.h"
/* */
struct family_data {
int id;
const char* group;
};
/* Compatibility functions */ /* Compatibility functions */
#if !defined(HAVE_LIBNL20) && !defined(HAVE_LIBNL30) #if !defined(HAVE_LIBNL20) && !defined(HAVE_LIBNL30)
static uint32_t port_bitmap[32] = { 0 }; static uint32_t port_bitmap[32] = { 0 };
@ -141,6 +147,64 @@ static int nl80211_send_and_recv_msg(struct nl80211_global_handle* globalhandle,
return nl80211_send_and_recv(globalhandle->nl, globalhandle->nl_cb, msg, valid_cb, data); return nl80211_send_and_recv(globalhandle->nl, globalhandle->nl_cb, msg, valid_cb, data);
} }
/* */
static int cb_family_handler(struct nl_msg* msg, void* data) {
int i;
struct nlattr* mcast_group;
struct nlattr* tb_msg[CTRL_ATTR_MAX + 1];
struct nlattr* tb_msg_mcast_group[CTRL_ATTR_MCAST_GRP_MAX + 1];
struct genlmsghdr* gnlh = nlmsg_data(nlmsg_hdr(msg));
struct family_data* resource = (struct family_data*)data;
nla_parse(tb_msg, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
if (tb_msg[CTRL_ATTR_MCAST_GROUPS]) {
nla_for_each_nested(mcast_group, tb_msg[CTRL_ATTR_MCAST_GROUPS], i) {
nla_parse(tb_msg_mcast_group, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcast_group), nla_len(mcast_group), NULL);
if (tb_msg_mcast_group[CTRL_ATTR_MCAST_GRP_NAME] && tb_msg_mcast_group[CTRL_ATTR_MCAST_GRP_ID]) {
if (!strncmp(nla_data(tb_msg_mcast_group[CTRL_ATTR_MCAST_GRP_NAME]), resource->group, nla_len(tb_msg_mcast_group[CTRL_ATTR_MCAST_GRP_NAME]))) {
resource->id = nla_get_u32(tb_msg_mcast_group[CTRL_ATTR_MCAST_GRP_ID]);
break;
}
}
}
}
return NL_SKIP;
}
/* */
static int nl80211_get_multicast_id(struct nl80211_global_handle* globalhandle, const char* family, const char* group) {
int result;
struct nl_msg* msg;
struct family_data resource = { -1, group };
ASSERT(globalhandle != NULL);
ASSERT(family != NULL);
ASSERT(group != NULL);
/* */
msg = nlmsg_alloc();
if (!msg) {
return -1;
}
/* */
genlmsg_put(msg, 0, 0, genl_ctrl_resolve(globalhandle->nl, "nlctrl"), 0, 0, CTRL_CMD_GETFAMILY, 0);
nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family);
/* */
result = nl80211_send_and_recv_msg(globalhandle, msg, cb_family_handler, &resource);
if (!result) {
result = resource.id;
}
/* */
nlmsg_free(msg);
return result;
}
/* */ /* */
static int nl80211_wlan_send_frame(wifi_wlan_handle handle, struct wlan_send_frame_params* params) { static int nl80211_wlan_send_frame(wifi_wlan_handle handle, struct wlan_send_frame_params* params) {
int result; int result;
@ -251,7 +315,78 @@ static void nl80211_do_mgmt_probe_request_event(struct nl80211_wlan_handle* wlan
} }
/* */ /* */
static void nl80211_do_mgmt_frame_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, uint16_t framecontrol_subtype, int mgmtlength, uint32_t frequency) { static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) {
int ielength;
struct ieee80211_ie_items ieitems;
int responselength;
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t responsestatuscode;
char buffer[IEEE80211_MTU];
struct ieee80211_authentication_params ieee80211_params;
struct wlan_send_frame_params wlan_params;
/* Information Elements packet length */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
if (ielength < 0) {
return;
}
/* Parsing Information Elements */
if (wifi_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
return;
}
/* Ignore authentication packet from same AP */
if (!memcmp(mgmt->sa, wlanhandle->address, ETH_ALEN)) {
return;
}
/* ACL Station */
/* TODO */
/* Create station reference */
/* TODO */
/* */
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* Check authentication algorithm */
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM;
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlanhandle->authenticationtype == CAPWAP_ADD_WLAN_AUTHTYPE_OPEN)) {
responsestatuscode = ((transactionseqnumber == 1) ? IEEE80211_STATUS_SUCCESS : IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION);
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (wlanhandle->authenticationtype == CAPWAP_ADD_WLAN_AUTHTYPE_WEP)) {
/* TODO */
}
/* Create authentication packet */
memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
memcpy(ieee80211_params.bssid, wlanhandle->address, ETH_ALEN);
ieee80211_params.algorithm = algorithm;
ieee80211_params.transactionseqnumber = transactionseqnumber + 1;
ieee80211_params.statuscode = responsestatuscode;
responselength = ieee80211_create_authentication_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;
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 Authentication 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; int broadcast;
/* Check frequency */ /* Check frequency */
@ -259,38 +394,38 @@ static void nl80211_do_mgmt_frame_event(struct nl80211_wlan_handle* wlanhandle,
return; return;
} }
/* Check if sent packet to correct virtual ap */ /* Check if sent packet to correct AP */
broadcast = wifi_is_broadcast_addr(mgmt->bssid); broadcast = wifi_is_broadcast_addr(mgmt->bssid);
if (!broadcast && memcmp(mgmt->bssid, wlanhandle->address, ETH_ALEN)) { if (!broadcast && memcmp(mgmt->bssid, wlanhandle->address, ETH_ALEN)) {
return; return;
} }
/* */ /* */
if (framecontrol_subtype == IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQ) { if (framecontrol_subtype == IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST) {
nl80211_do_mgmt_probe_request_event(wlanhandle, mgmt, mgmtlength); nl80211_do_mgmt_probe_request_event(wlanhandle, mgmt, mgmtlength);
} else if (!memcmp(mgmt->da, wlanhandle->address, ETH_ALEN)) { } else if (!memcmp(mgmt->da, wlanhandle->address, ETH_ALEN)) {
switch (framecontrol_subtype) { switch (framecontrol_subtype) {
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTH: { case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION: {
nl80211_do_mgmt_authentication_event(wlanhandle, mgmt, mgmtlength);
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST: {
/* TODO */ /* TODO */
break; break;
} }
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOC_REQ: { case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST: {
/* TODO */ /* TODO */
break; break;
} }
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOC_REQ: { case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION: {
/* TODO */ /* TODO */
break; break;
} }
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOC: { case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION: {
/* TODO */
break;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTH: {
/* TODO */ /* TODO */
break; break;
} }
@ -304,23 +439,14 @@ static void nl80211_do_mgmt_frame_event(struct nl80211_wlan_handle* wlanhandle,
} }
/* */ /* */
static void nl80211_do_frame_event(struct nl80211_wlan_handle* wlanhandle, struct nlattr* frame, uint32_t frequency) { static void nl80211_do_frame_event(struct nl80211_wlan_handle* wlanhandle, const uint8_t* framedata, int framelength, uint32_t frequency) {
const uint8_t* framedata;
const struct ieee80211_header* header; const struct ieee80211_header* header;
int framelength;
uint16_t framecontrol; uint16_t framecontrol;
uint16_t framecontrol_type; uint16_t framecontrol_type;
uint16_t framecontrol_subtype; uint16_t framecontrol_subtype;
/* */ /* Check frame */
if (!frame) { if (!framedata || (framelength < sizeof(struct ieee80211_header))) {
return;
}
/* Get frame data */
framedata = nla_data(frame);
framelength = nla_len(frame);
if (framelength < sizeof(struct ieee80211_header)) {
return; return;
} }
@ -332,10 +458,118 @@ static void nl80211_do_frame_event(struct nl80211_wlan_handle* wlanhandle, struc
/* Parsing frame */ /* Parsing frame */
if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) { if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
nl80211_do_mgmt_frame_event(wlanhandle, (const struct ieee80211_header_mgmt*)framedata, framecontrol_subtype, framelength, frequency); nl80211_do_mgmt_frame_event(wlanhandle, (const struct ieee80211_header_mgmt*)framedata, framelength, framecontrol_subtype, frequency);
} }
} }
/* */
static void nl80211_do_mgmt_frame_tx_status_authentication_event(struct nl80211_wlan_handle* wlanhandle, const struct ieee80211_header_mgmt* mgmt, int mgmtlength, uint64_t cookie, int ack) {
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t statuscode;
/* Accept only acknowledge authentication response with same cookie */
if (!ack || (wlanhandle->last_cookie != cookie)) {
return;
}
/* Check packet */
if (mgmtlength < (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication))) {
return;
}
/* */
statuscode = __le16_to_cpu(mgmt->authetication.statuscode);
if (statuscode == IEEE80211_STATUS_SUCCESS) {
algorithm = __le16_to_cpu(mgmt->authetication.algorithm);
transactionseqnumber = __le16_to_cpu(mgmt->authetication.transactionseqnumber);
/* Check if authenticate */
if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
capwap_logging_debug("Authenticate station");
} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
/* TODO */
}
}
}
/* */
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 */
if (memcmp(mgmt->bssid, wlanhandle->address, ETH_ALEN)) {
return;
}
/* */
switch (framecontrol_subtype) {
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION: {
nl80211_do_mgmt_frame_tx_status_authentication_event(wlanhandle, mgmt, mgmtlength, cookie, ack);
break;
}
}
/* Remove cookie */
wlanhandle->last_cookie = 0;
}
/* */
static void nl80211_do_frame_tx_status_event(struct nl80211_wlan_handle* wlanhandle, const uint8_t* framedata, int framelength, uint64_t cookie, int ack) {
const struct ieee80211_header* header;
uint16_t framecontrol;
uint16_t framecontrol_type;
uint16_t framecontrol_subtype;
/* Check frame */
if (!framedata || (framelength < sizeof(struct ieee80211_header))) {
return;
}
/* Get type frame */
header = (const struct ieee80211_header*)framedata;
framecontrol = __le16_to_cpu(header->framecontrol);
framecontrol_type = IEEE80211_FRAME_CONTROL_GET_TYPE(framecontrol);
framecontrol_subtype = IEEE80211_FRAME_CONTROL_GET_SUBTYPE(framecontrol);
/* Parsing frame */
if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
nl80211_do_mgmt_frame_tx_status_event(wlanhandle, (const struct ieee80211_header_mgmt*)framedata, framelength, framecontrol_subtype, cookie, ack);
}
}
/* */
static int nl80211_execute_bss_event(struct nl80211_wlan_handle* wlanhandle, struct genlmsghdr* gnlh, struct nlattr** tb_msg) {
switch (gnlh->cmd) {
case NL80211_CMD_FRAME: {
if (tb_msg[NL80211_ATTR_FRAME]) {
uint32_t frequency = 0;
if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
frequency = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);
}
nl80211_do_frame_event(wlanhandle, nla_data(tb_msg[NL80211_ATTR_FRAME]), nla_len(tb_msg[NL80211_ATTR_FRAME]), frequency);
}
break;
}
case NL80211_CMD_FRAME_TX_STATUS: {
if (tb_msg[NL80211_ATTR_FRAME] && tb_msg[NL80211_ATTR_COOKIE]) {
nl80211_do_frame_tx_status_event(wlanhandle, nla_data(tb_msg[NL80211_ATTR_FRAME]), nla_len(tb_msg[NL80211_ATTR_FRAME]), nla_get_u64(tb_msg[NL80211_ATTR_COOKIE]), (tb_msg[NL80211_ATTR_ACK] ? 1 : 0));
}
break;
}
default: {
capwap_logging_debug("nl80211_execute_bss_event: %d", (int)gnlh->cmd);
break;
}
}
return NL_SKIP;
}
/* */ /* */
static int nl80211_process_bss_event(struct nl_msg* msg, void* arg) { static int nl80211_process_bss_event(struct nl_msg* msg, void* arg) {
struct nlattr* tb_msg[NL80211_ATTR_MAX + 1]; struct nlattr* tb_msg[NL80211_ATTR_MAX + 1];
@ -344,20 +578,7 @@ static int nl80211_process_bss_event(struct nl_msg* msg, void* arg) {
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
switch (gnlh->cmd) { return nl80211_execute_bss_event(wlanhandle, gnlh, tb_msg);
case NL80211_CMD_FRAME: {
uint32_t frequency = 0;
if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
frequency = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);
}
nl80211_do_frame_event(wlanhandle, tb_msg[NL80211_ATTR_FRAME], frequency);
break;
}
}
return NL_SKIP;
} }
/* */ /* */
@ -374,10 +595,40 @@ static void nl80211_event_receive(int fd, void* param1, void* param2) {
} }
/* */ /* */
static int nl80211_global_valid_handler(struct nl_msg* msg, void* arg) { static int nl80211_global_valid_handler(struct nl_msg* msg, void* data) {
/* TODO */ uint32_t ifindex;
capwap_logging_debug("nl80211_global_valid_handler"); struct nl80211_device_handle* devicehandle;
/* TODO */ struct nl80211_wlan_handle* wlanhandle;
struct capwap_list_item* devicesearch;
struct capwap_list_item* wlansearch;
struct nlattr* tb_msg[NL80211_ATTR_MAX + 1];
struct genlmsghdr* gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nl80211_global_handle* globalhandle = (struct nl80211_global_handle*)data;
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
if (tb_msg[NL80211_ATTR_IFINDEX]) {
ifindex = (int)nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]);
/* Search device */
devicesearch = globalhandle->devicelist->first;
while (devicesearch) {
devicehandle = (struct nl80211_device_handle*)devicesearch->item;
/* Search wlan */
wlansearch = devicehandle->wlanlist->first;
while (wlansearch) {
wlanhandle = (struct nl80211_wlan_handle*)wlansearch->item;
if (wlanhandle->virtindex == ifindex) {
return nl80211_execute_bss_event(wlanhandle, gnlh, tb_msg);
}
wlansearch = wlansearch->next;
}
devicesearch = devicesearch->next;
}
}
return NL_SKIP; return NL_SKIP;
} }
@ -934,6 +1185,9 @@ static wifi_device_handle nl80211_device_init(wifi_global_handle handle, struct
/* Remove all virtual adapter from wifi device */ /* Remove all virtual adapter from wifi device */
nl80211_destroy_all_virtdevice(globalhandle, devicehandle->phyindex); nl80211_destroy_all_virtdevice(globalhandle, devicehandle->phyindex);
/* AP list */
devicehandle->wlanlist = capwap_list_create();
/* Save device handle into global handle */ /* Save device handle into global handle */
item = capwap_itemlist_create_with_item(devicehandle, sizeof(struct nl80211_device_handle)); item = capwap_itemlist_create_with_item(devicehandle, sizeof(struct nl80211_device_handle));
item->autodelete = 0; item->autodelete = 0;
@ -978,6 +1232,43 @@ static int nl80211_device_setfrequency(wifi_device_handle handle, struct wifi_fr
return result; return result;
} }
/* */
static void nl80211_wlan_delete(wifi_wlan_handle handle) {
struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)handle;
if (wlanhandle) {
if (wlanhandle->devicehandle) {
struct capwap_list_item* search;
/* Remove wlan handle from device handle */
search = wlanhandle->devicehandle->wlanlist->first;
while (search) {
if ((struct nl80211_wlan_handle*)search->item == wlanhandle) {
/* Remove item from list */
capwap_itemlist_free(capwap_itemlist_remove(wlanhandle->devicehandle->wlanlist, search));
break;
}
search = search->next;
}
}
if (wlanhandle->virtindex) {
nl80211_destroy_virtdevice(wlanhandle->devicehandle->globalhandle, wlanhandle->virtindex);
}
if (wlanhandle->nl) {
nl_socket_free(wlanhandle->nl);
}
if (wlanhandle->nl_cb) {
nl_cb_put(wlanhandle->nl_cb);
}
capwap_free(wlanhandle);
}
}
/* */ /* */
static void nl80211_device_deinit(wifi_device_handle handle) { static void nl80211_device_deinit(wifi_device_handle handle) {
int i; int i;
@ -986,13 +1277,15 @@ static void nl80211_device_deinit(wifi_device_handle handle) {
if (devicehandle) { if (devicehandle) {
struct capwap_list_item* search; struct capwap_list_item* search;
/* Destroy AP */
while (devicehandle->wlanlist->first) {
nl80211_wlan_delete((wifi_wlan_handle)devicehandle->wlanlist->first->item);
}
/* Remove device handle from global handle */ /* Remove device handle from global handle */
search = devicehandle->globalhandle->devicelist->first; search = devicehandle->globalhandle->devicelist->first;
while (search) { while (search) {
if ((struct nl80211_device_handle*)search->item == devicehandle) { if ((struct nl80211_device_handle*)search->item == devicehandle) {
/* Remove all virtual adapter from wifi device */
nl80211_destroy_all_virtdevice(devicehandle->globalhandle, devicehandle->phyindex);
/* Remove item from list */ /* Remove item from list */
capwap_itemlist_free(capwap_itemlist_remove(devicehandle->globalhandle->devicelist, search)); capwap_itemlist_free(capwap_itemlist_remove(devicehandle->globalhandle->devicelist, search));
break; break;
@ -1026,37 +1319,22 @@ static void nl80211_device_deinit(wifi_device_handle handle) {
capwap_free(devicehandle->capability); capwap_free(devicehandle->capability);
} }
if (devicehandle->wlanlist) {
ASSERT(devicehandle->wlanlist->count == 0);
capwap_list_free(devicehandle->wlanlist);
}
/* */ /* */
capwap_free(devicehandle); capwap_free(devicehandle);
} }
} }
/* */
static void nl80211_wlan_delete(wifi_wlan_handle handle) {
struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)handle;
ASSERT(handle != NULL);
if (wlanhandle->virtindex) {
nl80211_destroy_virtdevice(wlanhandle->devicehandle->globalhandle, wlanhandle->virtindex);
}
if (wlanhandle->nl) {
nl_socket_free(wlanhandle->nl);
}
if (wlanhandle->nl_cb) {
nl_cb_put(wlanhandle->nl_cb);
}
capwap_free(wlanhandle);
}
/* */ /* */
static wifi_wlan_handle nl80211_wlan_create(wifi_device_handle handle, struct wlan_init_params* params) { static wifi_wlan_handle nl80211_wlan_create(wifi_device_handle handle, struct wlan_init_params* params) {
int result; int result;
uint32_t ifindex; uint32_t ifindex;
struct nl_msg* msg; struct nl_msg* msg;
struct capwap_list_item* item;
struct nl80211_wlan_handle* wlanhandle = NULL; struct nl80211_wlan_handle* wlanhandle = NULL;
struct nl80211_device_handle* devicehandle = (struct nl80211_device_handle*)handle; struct nl80211_device_handle* devicehandle = (struct nl80211_device_handle*)handle;
@ -1104,6 +1382,11 @@ static wifi_wlan_handle nl80211_wlan_create(wifi_device_handle handle, struct wl
wlanhandle->virtindex = ifindex; wlanhandle->virtindex = ifindex;
strcpy(wlanhandle->virtname, params->ifname); strcpy(wlanhandle->virtname, params->ifname);
/* Save AP handle into device handle */
item = capwap_itemlist_create_with_item(wlanhandle, sizeof(struct nl80211_wlan_handle));
item->autodelete = 0;
capwap_itemlist_insert_after(devicehandle->wlanlist, NULL, item);
/* Mac address */ /* Mac address */
if (wifi_iface_hwaddr(devicehandle->globalhandle->sock_util, wlanhandle->virtname, wlanhandle->address)) { if (wifi_iface_hwaddr(devicehandle->globalhandle->sock_util, wlanhandle->virtname, wlanhandle->address)) {
nl80211_wlan_delete((wifi_wlan_handle)wlanhandle); nl80211_wlan_delete((wifi_wlan_handle)wlanhandle);
@ -1156,12 +1439,12 @@ static int nl80211_wlan_setupap(wifi_wlan_handle handle) {
int i; int i;
struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)handle; struct nl80211_wlan_handle* wlanhandle = (struct nl80211_wlan_handle*)handle;
static const int stypes[] = { static const int stypes[] = {
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOC_REQ, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST,
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOC_REQ, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST,
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQ, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST,
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOC, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION,
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTH, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION,
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTH, IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION,
IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION
}; };
@ -1213,6 +1496,7 @@ static int nl80211_wlan_startap(wifi_wlan_handle handle, struct wlan_startap_par
wlanhandle->capability = params->capability; wlanhandle->capability = params->capability;
memcpy(wlanhandle->supportedrates, params->supportedrates, params->supportedratescount); memcpy(wlanhandle->supportedrates, params->supportedrates, params->supportedratescount);
wlanhandle->supportedratescount = params->supportedratescount; wlanhandle->supportedratescount = params->supportedratescount;
wlanhandle->authenticationtype = params->authenticationtype;
/* */ /* */
msg = nlmsg_alloc(); msg = nlmsg_alloc();
@ -1288,6 +1572,10 @@ static void nl80211_global_deinit(wifi_global_handle handle) {
nl_socket_free(globalhandle->nl); nl_socket_free(globalhandle->nl);
} }
if (globalhandle->nl_event) {
nl_socket_free(globalhandle->nl_event);
}
if (globalhandle->nl_cb) { if (globalhandle->nl_cb) {
nl_cb_put(globalhandle->nl_cb); nl_cb_put(globalhandle->nl_cb);
} }
@ -1307,6 +1595,7 @@ static void nl80211_global_deinit(wifi_global_handle handle) {
/* */ /* */
static wifi_global_handle nl80211_global_init(void) { static wifi_global_handle nl80211_global_init(void) {
int result;
struct nl80211_global_handle* globalhandle; struct nl80211_global_handle* globalhandle;
/* */ /* */
@ -1328,6 +1617,43 @@ static wifi_global_handle nl80211_global_init(void) {
return NULL; return NULL;
} }
/* Create netlink socket for event */
globalhandle->nl_event = nl_create_handle(globalhandle->nl_cb);
if (globalhandle->nl_event) {
globalhandle->nl_event_fd = nl_socket_get_fd(globalhandle->nl_event);
} else {
nl80211_global_deinit((wifi_global_handle)globalhandle);
return NULL;
}
/* Add membership scan events */
result = nl80211_get_multicast_id(globalhandle, "nl80211", "scan");
if (result >= 0) {
result = nl_socket_add_membership(globalhandle->nl_event, result);
}
if (result < 0) {
nl80211_global_deinit((wifi_global_handle)globalhandle);
return NULL;
}
/* Add membership mlme events */
result = nl80211_get_multicast_id(globalhandle, "nl80211", "mlme");
if (result >= 0) {
result = nl_socket_add_membership(globalhandle->nl_event, result);
}
if (result < 0) {
nl80211_global_deinit((wifi_global_handle)globalhandle);
return NULL;
}
/* Add membership regulatory events */
result = nl80211_get_multicast_id(globalhandle, "nl80211", "regulatory");
if (result >= 0) {
result = nl_socket_add_membership(globalhandle->nl_event, result);
}
/* Get nl80211 netlink family */ /* Get nl80211 netlink family */
globalhandle->nl80211_id = genl_ctrl_resolve(globalhandle->nl, "nl80211"); globalhandle->nl80211_id = genl_ctrl_resolve(globalhandle->nl, "nl80211");
if (globalhandle->nl80211_id < 0) { if (globalhandle->nl80211_id < 0) {
@ -1355,7 +1681,22 @@ static wifi_global_handle nl80211_global_init(void) {
/* */ /* */
static int nl80211_global_getfdevent(wifi_global_handle handle, struct pollfd* fds, struct wifi_event* events) { static int nl80211_global_getfdevent(wifi_global_handle handle, struct pollfd* fds, struct wifi_event* events) {
return 0; struct nl80211_global_handle* globalhandle = (struct nl80211_global_handle*)handle;
ASSERT(handle != NULL);
if (fds) {
fds[0].fd = globalhandle->nl_event_fd;
fds[0].events = POLLIN | POLLERR | POLLHUP;
}
if (events) {
events[0].event_handler = nl80211_event_receive;
events[0].param1 = (void*)globalhandle->nl_event;
events[0].param2 = (void*)globalhandle->nl_cb;
}
return 1;
} }
/* Driver function */ /* Driver function */

View File

@ -15,6 +15,9 @@ struct nl80211_global_handle {
struct nl_cb* nl_cb; struct nl_cb* nl_cb;
int nl80211_id; int nl80211_id;
struct nl_sock* nl_event;
int nl_event_fd;
int sock_util; int sock_util;
struct capwap_list* devicelist; struct capwap_list* devicelist;
@ -27,6 +30,8 @@ struct nl80211_device_handle {
uint32_t phyindex; uint32_t phyindex;
char phyname[IFNAMSIZ]; char phyname[IFNAMSIZ];
struct capwap_list* wlanlist;
uint32_t currentfrequency; uint32_t currentfrequency;
struct wifi_capability* capability; /* Cached capability */ struct wifi_capability* capability; /* Cached capability */
@ -45,6 +50,8 @@ struct nl80211_wlan_handle {
uint8_t address[ETH_ALEN]; uint8_t address[ETH_ALEN];
uint64_t last_cookie;
/* WLAN information */ /* WLAN information */
char ssid[WIFI_SSID_MAX_LENGTH + 1]; char ssid[WIFI_SSID_MAX_LENGTH + 1];
@ -53,6 +60,8 @@ struct nl80211_wlan_handle {
int supportedratescount; int supportedratescount;
uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT]; uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
uint8_t authenticationtype;
}; };
/* Physical device info */ /* Physical device info */