Add business logic of Authentication/Association in SplitMAC mode.

This commit is contained in:
vemax78
2014-04-25 22:05:36 +02:00
parent d4d7649f3b
commit e1023a388e
14 changed files with 498 additions and 264 deletions

View File

@ -26,6 +26,7 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_data_t* se
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
struct ac_wlan* wlan;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->authetication));
@ -35,24 +36,79 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_data_t* se
/* */
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_create_station(sessiondata, radioid, mgmt->bssid, mgmt->sa);
station = ac_stations_create_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa);
if (!station || !station->wlan) {
return;
}
/* */
capwap_logging_info("Receive IEEE802.11 Authentication Request from %s station", station->addrtext);
/* A station is removed if the association does not complete within a given period of time */
station->timeoutaction = AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE;
station->idtimeout = capwap_timeout_set(sessiondata->timeout, station->idtimeout, AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE, ac_stations_timeout, station, sessiondata);
station->idtimeout = capwap_timeout_set(sessiondata->timeout, station->idtimeout, AC_STATION_TIMEOUT_ASSOCIATION_COMPLETE, ac_stations_timeout, station, sessiondata->session);
/* */
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
wlan = station->wlan;
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} 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 */
if (!ac_session_data_send_data_packet(sessiondata, wlan->device->radioid, wlan->wlanid, buffer, responselength, 1)) {
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);
ac_stations_delete_station(sessiondata->session, station);
}
} else {
capwap_logging_warning("Unable to create IEEE802.11 Authentication Response to %s station", station->addrtext);
ac_stations_delete_station(sessiondata->session, station);
}
}
} else if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(sessiondata, radioid, mgmt->bssid, mgmt->da);
if (station && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->da);
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
uint16_t algorithm;
uint16_t transactionseqnumber;
uint16_t statuscode;
@ -83,6 +139,7 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_data_
int ielength;
struct ieee80211_ie_items ieitems;
struct ac_station* station;
struct ac_wlan* wlan;
/* Parsing Information Elements */
ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationrequest));
@ -92,11 +149,23 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_data_
/* Get station */
if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && !memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(sessiondata, radioid, mgmt->bssid, mgmt->sa);
station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa);
if (!station || !station->wlan) {
return;
}
/* */
capwap_logging_info("Receive IEEE802.11 Association Request from %s station", station->addrtext);
/* */
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);
ac_stations_delete_station(sessiondata->session, station);
return;
}
/* Get Station Info */
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
@ -111,13 +180,76 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_data_
}
/* */
if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* TODO */
} 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];
/* Active Station */
ac_stations_authorize_station(sessiondata, station);
/* 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);
ac_stations_delete_station(sessiondata->session, station);
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;
}
}
}
/* 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 */
if (!ac_session_data_send_data_packet(sessiondata, wlan->device->radioid, wlan->wlanid, buffer, responselength, 1)) {
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;
ac_stations_authorize_station(sessiondata->session, station);
} else {
capwap_logging_warning("Unable to send IEEE802.11 Association Response to %s station", station->addrtext);
ac_stations_delete_station(sessiondata->session, station);
}
} else {
capwap_logging_warning("Unable to create IEEE802.11 Association Response to %s station", station->addrtext);
ac_stations_delete_station(sessiondata->session, station);
}
}
}
}
@ -137,8 +269,8 @@ static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_data
/* Get station */
if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) && memcmp(mgmt->bssid, mgmt->da, MACADDRESS_EUI48_LENGTH)) {
station = ac_stations_get_station(sessiondata, radioid, mgmt->bssid, mgmt->da);
if (station && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->da);
if (station && station->wlan && (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
capwap_logging_info("Receive IEEE802.11 Association Response to %s station with %d status code", station->addrtext, (int)mgmt->associationresponse.statuscode);
if (mgmt->associationresponse.statuscode == IEEE80211_STATUS_SUCCESS) {
@ -157,7 +289,7 @@ static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_data
}
/* Active Station */
ac_stations_authorize_station(sessiondata, station);
ac_stations_authorize_station(sessiondata->session, station);
}
}
}
@ -223,10 +355,10 @@ static void ac_ieee80211_mgmt_deauthentication_packet(struct ac_session_data_t*
stationaddress = (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH) ? mgmt->sa : mgmt->da);
/* Delete station */
station = ac_stations_get_station(sessiondata, radioid, NULL, stationaddress);
station = ac_stations_get_station(sessiondata->session, radioid, NULL, stationaddress);
if (station) {
station->flags &= ~(AC_STATION_FLAGS_AUTHORIZED | AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
ac_stations_delete_station(sessiondata, station);
ac_stations_delete_station(sessiondata->session, station);
}
}