2014-03-26 21:35:52 +01:00
# include "ac.h"
# include "ac_session.h"
2014-04-06 17:02:31 +02:00
# include "ac_wlans.h"
2014-03-26 21:35:52 +01:00
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_probe_request_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-02 22:40:04 +02:00
int ielength ;
struct ieee80211_ie_items ieitems ;
2014-04-09 19:25:08 +02:00
/* Accept probe request only if not sent by WTP */
if ( ! memcmp ( mgmt - > bssid , mgmt - > sa , MACADDRESS_EUI48_LENGTH ) ) {
return ;
}
2014-04-02 22:40:04 +02:00
/* Parsing Information Elements */
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > proberequest ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > proberequest . ie [ 0 ] , ielength ) ) {
return ;
}
/* TODO */
}
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_authentication_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-02 22:40:04 +02:00
int ielength ;
struct ieee80211_ie_items ieitems ;
2014-04-06 17:02:31 +02:00
struct ac_station * station ;
2014-04-25 22:05:36 +02:00
struct ac_wlan * wlan ;
2014-04-02 22:40:04 +02:00
/* Parsing Information Elements */
2014-04-06 17:02:31 +02:00
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > authetication ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > authetication . ie [ 0 ] , ielength ) ) {
2014-04-02 22:40:04 +02:00
return ;
}
2014-04-14 22:33:12 +02:00
/* */
if ( memcmp ( mgmt - > bssid , mgmt - > sa , MACADDRESS_EUI48_LENGTH ) & & ! memcmp ( mgmt - > bssid , mgmt - > da , MACADDRESS_EUI48_LENGTH ) ) {
2014-09-10 21:58:23 +02:00
station = ac_stations_create_station ( session , radioid , mgmt - > bssid , mgmt - > sa ) ;
2014-04-25 22:05:36 +02:00
if ( ! station | | ! station - > wlan ) {
return ;
}
2014-04-14 22:33:12 +02:00
/* */
2014-04-23 22:39:19 +02:00
capwap_logging_info ( " Receive IEEE802.11 Authentication Request from %s station " , station - > addrtext ) ;
2014-04-06 17:02:31 +02:00
2014-04-15 21:59:35 +02:00
/* A station is removed if the association does not complete within a given period of time */
station - > timeoutaction = AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE ;
2014-09-10 21:58:23 +02:00
station - > idtimeout = capwap_timeout_set ( session - > timeout , station - > idtimeout , AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE , ac_stations_timeout , station , session ) ;
2014-04-15 21:59:35 +02:00
2014-04-09 19:25:08 +02:00
/* */
2014-04-25 22:05:36 +02:00
wlan = station - > wlan ;
if ( wlan - > macmode = = CAPWAP_ADD_WLAN_MACMODE_LOCAL ) {
2014-04-09 19:25:08 +02:00
/* TODO */
2014-04-25 22:05:36 +02:00
} else if ( wlan - > macmode = = CAPWAP_ADD_WLAN_MACMODE_SPLIT ) {
uint16_t algorithm ;
uint16_t transactionseqnumber ;
uint16_t responsestatuscode ;
uint8_t buffer [ IEEE80211_MTU ] ;
struct ieee80211_authentication_params ieee80211_params ;
int responselength ;
/* Parsing Information Elements */
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > authetication . ie [ 0 ] , ielength ) ) {
capwap_logging_info ( " Invalid IEEE802.11 Authentication Request from %s station " , station - > addrtext ) ;
return ;
}
/* */
algorithm = __le16_to_cpu ( mgmt - > authetication . algorithm ) ;
transactionseqnumber = __le16_to_cpu ( mgmt - > authetication . transactionseqnumber ) ;
/* */
responsestatuscode = IEEE80211_STATUS_NOT_SUPPORTED_AUTHENTICATION_ALGORITHM ;
if ( ( algorithm = = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN ) & & ( wlan - > authmode = = CAPWAP_ADD_WLAN_AUTHTYPE_OPEN ) ) {
if ( transactionseqnumber = = 1 ) {
responsestatuscode = IEEE80211_STATUS_SUCCESS ;
station - > authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN ;
} else {
responsestatuscode = IEEE80211_STATUS_UNKNOWN_AUTHENTICATION_TRANSACTION ;
}
} else if ( ( algorithm = = IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY ) & & ( wlan - > authmode = = CAPWAP_ADD_WLAN_AUTHTYPE_WEP ) ) {
/* TODO */
}
/* Create authentication packet */
memset ( & ieee80211_params , 0 , sizeof ( struct ieee80211_authentication_params ) ) ;
memcpy ( ieee80211_params . bssid , wlan - > address , MACADDRESS_EUI48_LENGTH ) ;
memcpy ( ieee80211_params . station , mgmt - > sa , MACADDRESS_EUI48_LENGTH ) ;
ieee80211_params . algorithm = algorithm ;
ieee80211_params . transactionseqnumber = transactionseqnumber + 1 ;
ieee80211_params . statuscode = responsestatuscode ;
responselength = ieee80211_create_authentication_response ( buffer , sizeof ( buffer ) , & ieee80211_params ) ;
if ( responselength > 0 ) {
/* Send authentication response */
2014-09-10 21:58:23 +02:00
if ( ! ac_kmod_send_data ( & session - > sockaddrdata . ss , wlan - > device - > radioid , session - > binding , buffer , responselength ) ) {
2014-04-25 22:05:36 +02:00
capwap_logging_info ( " Sent IEEE802.11 Authentication Response to %s station with %d status code " , station - > addrtext , ( int ) responsestatuscode ) ;
station - > flags | = AC_STATION_FLAGS_AUTHENTICATED ;
} else {
capwap_logging_warning ( " Unable to send IEEE802.11 Authentication Response to %s station " , station - > addrtext ) ;
2014-09-10 21:58:23 +02:00
ac_stations_delete_station ( session , station ) ;
2014-04-25 22:05:36 +02:00
}
} else {
capwap_logging_warning ( " Unable to create IEEE802.11 Authentication Response to %s station " , station - > addrtext ) ;
2014-09-10 21:58:23 +02:00
ac_stations_delete_station ( session , station ) ;
2014-04-25 22:05:36 +02:00
}
2014-04-09 19:25:08 +02:00
}
2014-04-14 22:33:12 +02:00
} else if ( ! memcmp ( mgmt - > bssid , mgmt - > sa , MACADDRESS_EUI48_LENGTH ) & & memcmp ( mgmt - > bssid , mgmt - > da , MACADDRESS_EUI48_LENGTH ) ) {
2014-09-10 21:58:23 +02:00
station = ac_stations_get_station ( session , radioid , mgmt - > bssid , mgmt - > da ) ;
2014-04-25 22:05:36 +02:00
if ( station & & station - > wlan & & ( station - > wlan - > macmode = = CAPWAP_ADD_WLAN_MACMODE_LOCAL ) ) {
2014-04-14 22:33:12 +02:00
uint16_t algorithm ;
uint16_t transactionseqnumber ;
uint16_t statuscode ;
/* */
statuscode = __le16_to_cpu ( mgmt - > authetication . statuscode ) ;
/* */
2014-04-23 22:39:19 +02:00
capwap_logging_info ( " Receive IEEE802.11 Authentication Response to %s station with %d status code " , station - > addrtext , ( int ) statuscode ) ;
2014-04-14 22:33:12 +02:00
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 ) ) {
station - > flags | = AC_STATION_FLAGS_AUTHENTICATED ;
} else if ( ( algorithm = = IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY ) & & ( transactionseqnumber = = 4 ) ) {
/* TODO */
}
2014-04-09 19:25:08 +02:00
}
}
2014-04-06 17:02:31 +02:00
}
2014-04-02 22:40:04 +02:00
}
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_association_request_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-02 22:40:04 +02:00
int ielength ;
struct ieee80211_ie_items ieitems ;
2014-04-06 17:02:31 +02:00
struct ac_station * station ;
2014-04-25 22:05:36 +02:00
struct ac_wlan * wlan ;
2014-04-02 22:40:04 +02:00
/* Parsing Information Elements */
2014-04-06 17:02:31 +02:00
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > associationrequest ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > associationrequest . ie [ 0 ] , ielength ) ) {
2014-04-02 22:40:04 +02:00
return ;
}
2014-04-09 19:25:08 +02:00
/* Get station */
2014-04-14 22:33:12 +02:00
if ( memcmp ( mgmt - > bssid , mgmt - > sa , MACADDRESS_EUI48_LENGTH ) & & ! memcmp ( mgmt - > bssid , mgmt - > da , MACADDRESS_EUI48_LENGTH ) ) {
2014-09-10 21:58:23 +02:00
station = ac_stations_get_station ( session , radioid , mgmt - > bssid , mgmt - > sa ) ;
2014-04-25 22:05:36 +02:00
if ( ! station | | ! station - > wlan ) {
return ;
}
2014-04-09 19:25:08 +02:00
/* */
2014-04-23 22:39:19 +02:00
capwap_logging_info ( " Receive IEEE802.11 Association Request from %s station " , station - > addrtext ) ;
2014-04-14 22:33:12 +02:00
2014-04-25 22:05:36 +02:00
/* */
wlan = station - > wlan ;
if ( ! ( station - > flags & AC_STATION_FLAGS_AUTHENTICATED ) ) {
/* Invalid station, delete station */
capwap_logging_info ( " Receive IEEE802.11 Association Request from %s unauthorized station " , station - > addrtext ) ;
2014-09-10 21:58:23 +02:00
ac_stations_delete_station ( session , station ) ;
2014-04-25 22:05:36 +02:00
return ;
}
2014-04-14 22:33:12 +02:00
/* Get Station Info */
station - > capability = __le16_to_cpu ( mgmt - > associationrequest . capability ) ;
station - > listeninterval = __le16_to_cpu ( mgmt - > associationrequest . listeninterval ) ;
/* Get supported rates */
if ( ieitems . supported_rates & & ( ( ieitems . supported_rates - > len + ( ieitems . extended_supported_rates ? ieitems . extended_supported_rates - > len : 0 ) ) < = sizeof ( station - > supportedrates ) ) ) {
station - > supportedratescount = ieitems . supported_rates - > len ;
memcpy ( station - > supportedrates , ieitems . supported_rates - > rates , ieitems . supported_rates - > len ) ;
if ( ieitems . extended_supported_rates ) {
station - > supportedratescount + = ieitems . extended_supported_rates - > len ;
memcpy ( & station - > supportedrates [ ieitems . supported_rates - > len ] , ieitems . extended_supported_rates - > rates , ieitems . extended_supported_rates - > len ) ;
}
/* */
2014-04-25 22:05:36 +02:00
if ( wlan - > macmode = = CAPWAP_ADD_WLAN_MACMODE_LOCAL ) {
2014-04-09 19:25:08 +02:00
/* TODO */
2014-04-25 22:05:36 +02:00
} else if ( wlan - > macmode = = CAPWAP_ADD_WLAN_MACMODE_SPLIT ) {
int responselength ;
struct ieee80211_ie_items ieitems ;
struct ieee80211_associationresponse_params ieee80211_params ;
uint16_t resultstatuscode ;
uint8_t buffer [ IEEE80211_MTU ] ;
/* Parsing Information Elements */
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > associationrequest . ie [ 0 ] , ielength ) ) {
capwap_logging_info ( " Invalid IEEE802.11 Association Request from %s station " , station - > addrtext ) ;
2014-09-10 21:58:23 +02:00
ac_stations_delete_station ( session , station ) ;
2014-04-25 22:05:36 +02:00
return ;
}
/* Verify SSID */
if ( ieee80211_is_valid_ssid ( wlan - > ssid , ieitems . ssid , NULL ) ! = IEEE80211_VALID_SSID ) {
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE ;
} else {
/* Check supported rates */
if ( ! ieitems . supported_rates | | ( ( ieitems . supported_rates - > len + ( ieitems . extended_supported_rates ? ieitems . extended_supported_rates - > len : 0 ) ) > sizeof ( station - > supportedrates ) ) ) {
resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE ;
} else {
station - > capability = __le16_to_cpu ( mgmt - > associationrequest . capability ) ;
station - > listeninterval = __le16_to_cpu ( mgmt - > associationrequest . listeninterval ) ;
if ( ieee80211_aid_create ( wlan - > aidbitfield , & station - > aid ) ) {
resultstatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA ;
} else {
/* Get supported rates */
station - > supportedratescount = ieitems . supported_rates - > len ;
memcpy ( station - > supportedrates , ieitems . supported_rates - > rates , ieitems . supported_rates - > len ) ;
if ( ieitems . extended_supported_rates ) {
station - > supportedratescount + = ieitems . extended_supported_rates - > len ;
memcpy ( & station - > supportedrates [ ieitems . supported_rates - > len ] , ieitems . extended_supported_rates - > rates , ieitems . extended_supported_rates - > len ) ;
}
/* */
resultstatuscode = IEEE80211_STATUS_SUCCESS ;
}
}
}
2014-04-14 22:33:12 +02:00
2014-04-25 22:05:36 +02:00
/* Create association response packet */
memset ( & ieee80211_params , 0 , sizeof ( struct ieee80211_authentication_params ) ) ;
memcpy ( ieee80211_params . bssid , wlan - > address , ETH_ALEN ) ;
memcpy ( ieee80211_params . station , mgmt - > sa , ETH_ALEN ) ;
ieee80211_params . capability = wlan - > capability ;
ieee80211_params . statuscode = resultstatuscode ;
ieee80211_params . aid = IEEE80211_AID_FIELD | station - > aid ;
memcpy ( ieee80211_params . supportedrates , wlan - > device - > supportedrates , wlan - > device - > supportedratescount ) ;
ieee80211_params . supportedratescount = wlan - > device - > supportedratescount ;
responselength = ieee80211_create_associationresponse_response ( buffer , sizeof ( buffer ) , & ieee80211_params ) ;
if ( responselength > 0 ) {
/* Send association response */
2014-09-10 21:58:23 +02:00
if ( ! ac_kmod_send_data ( & session - > sockaddrdata . ss , wlan - > device - > radioid , session - > binding , buffer , responselength ) ) {
2014-04-25 22:05:36 +02:00
capwap_logging_info ( " Sent IEEE802.11 Association Response to %s station with %d status code " , station - > addrtext , ( int ) resultstatuscode ) ;
/* Active Station */
station - > flags | = AC_STATION_FLAGS_ASSOCIATE ;
2014-09-10 21:58:23 +02:00
ac_stations_authorize_station ( session , station ) ;
2014-04-25 22:05:36 +02:00
} else {
capwap_logging_warning ( " Unable to send IEEE802.11 Association Response to %s station " , station - > addrtext ) ;
2014-09-10 21:58:23 +02:00
ac_stations_delete_station ( session , station ) ;
2014-04-25 22:05:36 +02:00
}
} else {
capwap_logging_warning ( " Unable to create IEEE802.11 Association Response to %s station " , station - > addrtext ) ;
2014-09-10 21:58:23 +02:00
ac_stations_delete_station ( session , station ) ;
2014-04-25 22:05:36 +02:00
}
2014-04-09 19:25:08 +02:00
}
}
}
}
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_association_response_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-09 19:25:08 +02:00
int ielength ;
struct ieee80211_ie_items ieitems ;
struct ac_station * station ;
/* Parsing Information Elements */
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > associationresponse ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > associationresponse . ie [ 0 ] , ielength ) ) {
return ;
}
2014-04-06 17:02:31 +02:00
/* Get station */
2014-04-14 22:33:12 +02:00
if ( ! memcmp ( mgmt - > bssid , mgmt - > sa , MACADDRESS_EUI48_LENGTH ) & & memcmp ( mgmt - > bssid , mgmt - > da , MACADDRESS_EUI48_LENGTH ) ) {
2014-09-10 21:58:23 +02:00
station = ac_stations_get_station ( session , radioid , mgmt - > bssid , mgmt - > da ) ;
2014-04-25 22:05:36 +02:00
if ( station & & station - > wlan & & ( station - > wlan - > macmode = = CAPWAP_ADD_WLAN_MACMODE_LOCAL ) ) {
2014-04-23 22:39:19 +02:00
capwap_logging_info ( " Receive IEEE802.11 Association Response to %s station with %d status code " , station - > addrtext , ( int ) mgmt - > associationresponse . statuscode ) ;
2014-04-14 22:33:12 +02:00
if ( mgmt - > associationresponse . statuscode = = IEEE80211_STATUS_SUCCESS ) {
/* Get Station Info */
station - > capability = __le16_to_cpu ( mgmt - > associationresponse . capability ) ;
station - > aid = __le16_to_cpu ( mgmt - > associationresponse . aid ) ;
station - > flags | = AC_STATION_FLAGS_ASSOCIATE ;
/* Get supported rates */
if ( ieitems . supported_rates & & ( ( ieitems . supported_rates - > len + ( ieitems . extended_supported_rates ? ieitems . extended_supported_rates - > len : 0 ) ) < = sizeof ( station - > supportedrates ) ) ) {
station - > supportedratescount = ieitems . supported_rates - > len ;
memcpy ( station - > supportedrates , ieitems . supported_rates - > rates , ieitems . supported_rates - > len ) ;
if ( ieitems . extended_supported_rates ) {
station - > supportedratescount + = ieitems . extended_supported_rates - > len ;
memcpy ( & station - > supportedrates [ ieitems . supported_rates - > len ] , ieitems . extended_supported_rates - > rates , ieitems . extended_supported_rates - > len ) ;
}
/* Active Station */
2014-09-10 21:58:23 +02:00
ac_stations_authorize_station ( session , station ) ;
2014-04-14 22:33:12 +02:00
}
}
}
2014-04-06 17:02:31 +02:00
}
2014-04-02 22:40:04 +02:00
}
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_reassociation_request_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-02 22:40:04 +02:00
int ielength ;
struct ieee80211_ie_items ieitems ;
/* Parsing Information Elements */
2014-04-06 17:02:31 +02:00
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > reassociationrequest ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > reassociationrequest . ie [ 0 ] , ielength ) ) {
2014-04-02 22:40:04 +02:00
return ;
}
/* TODO */
}
2014-04-09 19:25:08 +02:00
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_reassociation_response_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-09 19:25:08 +02:00
int ielength ;
struct ieee80211_ie_items ieitems ;
/* Parsing Information Elements */
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > reassociationresponse ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > reassociationresponse . ie [ 0 ] , ielength ) ) {
return ;
}
/* TODO */
}
2014-04-02 22:40:04 +02:00
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_disassociation_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-02 22:40:04 +02:00
int ielength ;
struct ieee80211_ie_items ieitems ;
/* Parsing Information Elements */
2014-04-06 17:02:31 +02:00
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > disassociation ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > disassociation . ie [ 0 ] , ielength ) ) {
2014-04-02 22:40:04 +02:00
return ;
}
/* TODO */
}
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_deauthentication_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength ) {
2014-04-02 22:40:04 +02:00
int ielength ;
2014-04-06 17:02:31 +02:00
const uint8_t * stationaddress ;
2014-04-14 22:33:12 +02:00
struct ac_station * station ;
2014-04-02 22:40:04 +02:00
struct ieee80211_ie_items ieitems ;
/* Parsing Information Elements */
2014-04-06 17:02:31 +02:00
ielength = mgmtlength - ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > deauthetication ) ) ;
if ( ieee80211_retrieve_information_elements_position ( & ieitems , & mgmt - > deauthetication . ie [ 0 ] , ielength ) ) {
2014-04-02 22:40:04 +02:00
return ;
}
2014-04-06 17:02:31 +02:00
/* Get station address */
stationaddress = ( memcmp ( mgmt - > bssid , mgmt - > sa , MACADDRESS_EUI48_LENGTH ) ? mgmt - > sa : mgmt - > da ) ;
/* Delete station */
2014-09-10 21:58:23 +02:00
station = ac_stations_get_station ( session , radioid , NULL , stationaddress ) ;
2014-04-14 22:33:12 +02:00
if ( station ) {
2014-09-10 21:58:23 +02:00
/* Delete station without forward another IEEE802.11 deauthentication message */
station - > flags & = ~ ( AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE ) ;
ac_stations_delete_station ( session , station ) ;
2014-04-14 22:33:12 +02:00
}
2014-04-02 22:40:04 +02:00
}
/* */
2014-09-10 21:58:23 +02:00
static void ac_ieee80211_mgmt_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header_mgmt * mgmt , int mgmtlength , uint16_t framecontrol_subtype ) {
2014-04-02 22:40:04 +02:00
switch ( framecontrol_subtype ) {
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_PROBE_REQUEST : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > proberequest ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_probe_request_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-02 22:40:04 +02:00
}
break ;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_AUTHENTICATION : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > authetication ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_authentication_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-02 22:40:04 +02:00
}
break ;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_REQUEST : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > associationrequest ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_association_request_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-02 22:40:04 +02:00
}
break ;
}
2014-04-09 19:25:08 +02:00
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > associationresponse ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_association_response_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-09 19:25:08 +02:00
}
break ;
}
2014-04-02 22:40:04 +02:00
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > reassociationrequest ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_reassociation_request_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-02 22:40:04 +02:00
}
break ;
}
2014-04-09 19:25:08 +02:00
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_RESPONSE : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > reassociationresponse ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_reassociation_response_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-09 19:25:08 +02:00
}
break ;
}
2014-04-02 22:40:04 +02:00
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > disassociation ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_disassociation_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-02 22:40:04 +02:00
}
break ;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DEAUTHENTICATION : {
if ( mgmtlength > = ( sizeof ( struct ieee80211_header ) + sizeof ( mgmt - > deauthetication ) ) ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_deauthentication_packet ( session , radioid , mgmt , mgmtlength ) ;
2014-04-02 22:40:04 +02:00
}
break ;
}
case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ACTION : {
break ;
}
}
}
/* */
2014-09-10 21:58:23 +02:00
void ac_ieee80211_packet ( struct ac_session_t * session , uint8_t radioid , const struct ieee80211_header * header , int length ) {
2014-04-02 22:40:04 +02:00
uint16_t framecontrol ;
uint16_t framecontrol_type ;
uint16_t framecontrol_subtype ;
2014-09-10 21:58:23 +02:00
ASSERT ( session ! = NULL ) ;
2014-04-06 17:02:31 +02:00
ASSERT ( IS_VALID_RADIOID ( radioid ) ) ;
2014-04-21 23:16:56 +02:00
ASSERT ( header ! = NULL ) ;
2014-04-02 22:40:04 +02:00
ASSERT ( length > = sizeof ( struct ieee80211_header ) ) ;
/* Get type frame */
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 ) {
2014-09-10 21:58:23 +02:00
ac_ieee80211_mgmt_packet ( session , radioid , ( const struct ieee80211_header_mgmt * ) header , length , framecontrol_subtype ) ;
2014-04-02 22:40:04 +02:00
}
2014-03-26 21:35:52 +01:00
}