Add business logic of Authentication/Association in SplitMAC mode.
This commit is contained in:
		@ -3,9 +3,34 @@
 | 
			
		||||
#include "capwap_array.h"
 | 
			
		||||
#include "ac_session.h"
 | 
			
		||||
#include "ac_json.h"
 | 
			
		||||
#include "ac_wlans.h"
 | 
			
		||||
#include <json/json.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static void ac_dfa_state_configure_set_radio_configuration(struct ac_session_t* session, struct ac_json_ieee80211_wtpradio* wtpradio) {
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < RADIOID_MAX_COUNT; i++) {
 | 
			
		||||
		struct ac_json_ieee80211_item* item = &wtpradio->items[i];
 | 
			
		||||
 | 
			
		||||
		if (item->valid) {
 | 
			
		||||
			struct ac_device* device = &session->wlans->devices[i];
 | 
			
		||||
 | 
			
		||||
			/* Set rates */
 | 
			
		||||
			if (item->rateset || item->supportedrates) {
 | 
			
		||||
				if (item->rateset) {
 | 
			
		||||
					memcpy(device->supportedrates, item->rateset->rateset, item->rateset->ratesetcount);
 | 
			
		||||
					device->supportedratescount = item->rateset->ratesetcount;
 | 
			
		||||
				} else if (item->supportedrates) {
 | 
			
		||||
					memcpy(device->supportedrates, item->supportedrates->supportedrates, item->supportedrates->supportedratescount);
 | 
			
		||||
					device->supportedratescount = item->supportedrates->supportedratescount;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static struct ac_soap_response* ac_dfa_state_configure_parsing_request(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
 | 
			
		||||
	int i;
 | 
			
		||||
@ -690,6 +715,9 @@ static uint32_t ac_dfa_state_configure_create_response(struct ac_session_t* sess
 | 
			
		||||
			if (ac_json_ieee80211_parsingjson(&wtpradio, jsonelement)) {
 | 
			
		||||
				/* Add IEEE802.11 message elements to packet */
 | 
			
		||||
				ac_json_ieee80211_buildpacket(&wtpradio, txmngpacket);
 | 
			
		||||
 | 
			
		||||
				/* Retrieve frequency and rates configuration */
 | 
			
		||||
				ac_dfa_state_configure_set_radio_configuration(session, &wtpradio);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -75,7 +75,7 @@ static void execute_ieee80211_wlan_configuration_addwlan(struct ac_session_t* se
 | 
			
		||||
	/* Get BSSID */
 | 
			
		||||
	assignbssid = (struct capwap_80211_assignbssid_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_ASSIGN_BSSID);
 | 
			
		||||
	if (assignbssid && (assignbssid->radioid == addwlan->radioid) && (assignbssid->wlanid == addwlan->wlanid)) {
 | 
			
		||||
		wlan = ac_wlans_create_bssid(assignbssid->radioid, assignbssid->wlanid, assignbssid->bssid, addwlan);
 | 
			
		||||
		wlan = ac_wlans_create_bssid(&session->wlans->devices[assignbssid->radioid - 1], assignbssid->wlanid, assignbssid->bssid, addwlan);
 | 
			
		||||
 | 
			
		||||
		/* Assign BSSID to session */
 | 
			
		||||
		ac_session_data_send_action(session->sessiondata, AC_SESSION_DATA_ACTION_ASSIGN_BSSID, 0, &wlan, sizeof(struct ac_wlan*));
 | 
			
		||||
 | 
			
		||||
@ -532,6 +532,9 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
 | 
			
		||||
	memcpy(&session->connection.localaddr, acaddress, sizeof(struct sockaddr_storage));
 | 
			
		||||
	memcpy(&session->connection.remoteaddr, wtpaddress, sizeof(struct sockaddr_storage));
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	ac_wlans_init(session);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	session->count = 2;
 | 
			
		||||
	capwap_event_init(&session->changereference);
 | 
			
		||||
@ -618,9 +621,6 @@ static struct ac_session_data_t* ac_create_session_data(struct sockaddr_storage*
 | 
			
		||||
	sessiondata->count = 2;
 | 
			
		||||
	capwap_event_init(&sessiondata->changereference);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	ac_wlans_init(sessiondata);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	sessiondata->timeout = capwap_timeout_init();
 | 
			
		||||
	sessiondata->idtimercontrol = capwap_timeout_createtimer(sessiondata->timeout);
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
		wlan = station->wlan;
 | 
			
		||||
		if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
 | 
			
		||||
			/* TODO */
 | 
			
		||||
		} else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
 | 
			
		||||
		} 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];
 | 
			
		||||
 | 
			
		||||
				/* 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 */
 | 
			
		||||
				ac_stations_authorize_station(sessiondata, 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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
#include "ac.h"
 | 
			
		||||
#include "capwap_dfa.h"
 | 
			
		||||
#include "ac_session.h"
 | 
			
		||||
#include "ac_wlans.h"
 | 
			
		||||
#include "ac_backend.h"
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
 | 
			
		||||
@ -530,6 +531,9 @@ static void ac_session_destroy(struct ac_session_t* session) {
 | 
			
		||||
		capwap_itemlist_free(capwap_itemlist_remove_head(session->packets));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Free WLANS */
 | 
			
		||||
	ac_wlans_destroy(session);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_event_destroy(&session->changereference);
 | 
			
		||||
	capwap_event_destroy(&session->waitpacket);
 | 
			
		||||
 | 
			
		||||
@ -123,9 +123,6 @@ struct ac_session_data_t {
 | 
			
		||||
	long count;
 | 
			
		||||
	capwap_event_t changereference;
 | 
			
		||||
 | 
			
		||||
	/* WLAN Reference */
 | 
			
		||||
	struct ac_wlans* wlans;
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	int enabledtls;
 | 
			
		||||
	unsigned short mtu;
 | 
			
		||||
@ -161,6 +158,9 @@ struct ac_session_t {
 | 
			
		||||
	/* Soap */
 | 
			
		||||
	struct ac_http_soap_request* soaprequest;
 | 
			
		||||
 | 
			
		||||
	/* WLAN Reference */
 | 
			
		||||
	struct ac_wlans* wlans;
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	char* wtpid;
 | 
			
		||||
	unsigned long state;
 | 
			
		||||
@ -208,7 +208,7 @@ void ac_session_data_close(struct ac_session_data_t* sessiondata);
 | 
			
		||||
void ac_session_data_send_action(struct ac_session_data_t* sessiondata, long action, long param, void* data, long length);
 | 
			
		||||
void ac_session_data_release_reference(struct ac_session_data_t* sessiondata);
 | 
			
		||||
 | 
			
		||||
void ac_session_data_send_data_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe);
 | 
			
		||||
int ac_session_data_send_data_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe);
 | 
			
		||||
 | 
			
		||||
/* IEEE802.11 Packet */
 | 
			
		||||
void ac_ieee80211_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, const struct ieee80211_header* header, int length);
 | 
			
		||||
 | 
			
		||||
@ -15,9 +15,9 @@ static int ac_session_data_action_add_station_status(struct ac_session_data_t* s
 | 
			
		||||
	struct ac_wlan* wlan;
 | 
			
		||||
	struct ac_station* station;
 | 
			
		||||
 | 
			
		||||
	wlan = ac_wlans_get_bssid_with_wlanid(sessiondata, notify->radioid, notify->wlanid);
 | 
			
		||||
	wlan = ac_wlans_get_bssid_with_wlanid(sessiondata->session, notify->radioid, notify->wlanid);
 | 
			
		||||
	if (wlan) {
 | 
			
		||||
		station = ac_stations_get_station(sessiondata, notify->radioid, wlan->bssid, notify->address);
 | 
			
		||||
		station = ac_stations_get_station(sessiondata->session, notify->radioid, wlan->address, notify->address);
 | 
			
		||||
		if (station) {
 | 
			
		||||
			if (CAPWAP_RESULTCODE_OK(notify->statuscode)) {
 | 
			
		||||
				capwap_logging_info("Authorized station: %s", station->addrtext);
 | 
			
		||||
@ -27,7 +27,7 @@ static int ac_session_data_action_add_station_status(struct ac_session_data_t* s
 | 
			
		||||
				capwap_timeout_deletetimer(sessiondata->timeout, station->idtimeout);
 | 
			
		||||
				station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
 | 
			
		||||
			} else {
 | 
			
		||||
				ac_stations_delete_station(sessiondata, station);
 | 
			
		||||
				ac_stations_delete_station(sessiondata->session, station);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -39,12 +39,12 @@ static int ac_session_data_action_add_station_status(struct ac_session_data_t* s
 | 
			
		||||
static int ac_session_data_action_delete_station_status(struct ac_session_data_t* sessiondata, struct ac_notify_delete_station_status* notify) {
 | 
			
		||||
	struct ac_station* station;
 | 
			
		||||
 | 
			
		||||
	station = ac_stations_get_station(sessiondata, notify->radioid, NULL, notify->address);
 | 
			
		||||
	station = ac_stations_get_station(sessiondata->session, notify->radioid, NULL, notify->address);
 | 
			
		||||
	if (station) {
 | 
			
		||||
		capwap_logging_info("Deauthorized station: %s with %d result code", station->addrtext, (int)notify->statuscode);
 | 
			
		||||
 | 
			
		||||
		/* */
 | 
			
		||||
		ac_stations_delete_station(sessiondata, station);
 | 
			
		||||
		ac_stations_delete_station(sessiondata->session, station);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return AC_ERROR_ACTION_SESSION;
 | 
			
		||||
@ -59,16 +59,16 @@ static int ac_session_data_action_execute(struct ac_session_data_t* sessiondata,
 | 
			
		||||
			struct ac_station* station;
 | 
			
		||||
 | 
			
		||||
			/* Delete station */
 | 
			
		||||
			station = ac_stations_get_station(sessiondata, RADIOID_ANY, NULL, (uint8_t*)action->data);
 | 
			
		||||
			station = ac_stations_get_station(sessiondata->session, RADIOID_ANY, NULL, (uint8_t*)action->data);
 | 
			
		||||
			if (station) {
 | 
			
		||||
				ac_stations_delete_station(sessiondata, station);
 | 
			
		||||
				ac_stations_delete_station(sessiondata->session, station);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case AC_SESSION_DATA_ACTION_ASSIGN_BSSID: {
 | 
			
		||||
			ac_wlans_assign_bssid(sessiondata, *(struct ac_wlan**)action->data);
 | 
			
		||||
			ac_wlans_assign_bssid(sessiondata->session, *(struct ac_wlan**)action->data);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -312,9 +312,6 @@ static void ac_session_data_destroy(struct ac_session_data_t* sessiondata) {
 | 
			
		||||
	/* Free DTLS */
 | 
			
		||||
	capwap_crypt_freesession(&sessiondata->dtls);
 | 
			
		||||
 | 
			
		||||
	/* Free WLANS */
 | 
			
		||||
	ac_wlans_destroy(sessiondata);
 | 
			
		||||
 | 
			
		||||
	/* Free resource */
 | 
			
		||||
	while (sessiondata->packets->count > 0) {
 | 
			
		||||
		capwap_itemlist_free(capwap_itemlist_remove_head(sessiondata->packets));
 | 
			
		||||
@ -492,7 +489,8 @@ void* ac_session_data_thread(void* param) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_session_data_send_data_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe) {
 | 
			
		||||
int ac_session_data_send_data_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid, const uint8_t* data, int length, int leavenativeframe) {
 | 
			
		||||
	int result = 0;
 | 
			
		||||
	struct capwap_list* txfragpacket;
 | 
			
		||||
	struct capwap_header_data capwapheader;
 | 
			
		||||
	struct capwap_packet_txmng* txmngpacket;
 | 
			
		||||
@ -519,9 +517,11 @@ void ac_session_data_send_data_packet(struct ac_session_data_t* sessiondata, uin
 | 
			
		||||
	/* */
 | 
			
		||||
	if (!capwap_crypt_sendto_fragmentpacket(&sessiondata->dtls, sessiondata->connection.socket.socket[sessiondata->connection.socket.type], txfragpacket, &sessiondata->connection.localaddr, &sessiondata->connection.remoteaddr)) {
 | 
			
		||||
		capwap_logging_debug("Warning: error to send data packet");
 | 
			
		||||
		result = -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Free packets manager */
 | 
			
		||||
	capwap_list_free(txfragpacket);
 | 
			
		||||
	capwap_packet_txmng_free(txmngpacket);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,18 +4,18 @@
 | 
			
		||||
#include "ac_backend.h"
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static void ac_stations_delete_station_from_global_cache(struct ac_session_data_t* sessiondata, uint8_t* address) {
 | 
			
		||||
	struct ac_session_data_t* ownersession;
 | 
			
		||||
static void ac_stations_delete_station_from_global_cache(struct ac_session_t* session, uint8_t* address) {
 | 
			
		||||
	struct ac_session_t* ownersession;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(address != NULL);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_rwlock_wrlock(&g_ac.stationslock);
 | 
			
		||||
 | 
			
		||||
	/* Can delete global reference only if match session handler */
 | 
			
		||||
	ownersession = (struct ac_session_data_t*)capwap_hash_search(g_ac.stations, address);
 | 
			
		||||
	if (ownersession == sessiondata) {
 | 
			
		||||
	ownersession = (struct ac_session_t*)capwap_hash_search(g_ac.stations, address);
 | 
			
		||||
	if (ownersession == session) {
 | 
			
		||||
		capwap_hash_delete(g_ac.stations, address);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -23,18 +23,26 @@ static void ac_stations_delete_station_from_global_cache(struct ac_session_data_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static void ac_stations_reset_station(struct ac_session_data_t* sessiondata, struct ac_station* station, struct ac_wlan* wlan) {
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
static void ac_stations_reset_station(struct ac_session_t* session, struct ac_station* station, struct ac_wlan* wlan) {
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(station != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Remove reference from current WLAN */
 | 
			
		||||
	if (station->wlan) {
 | 
			
		||||
		if (station->aid) {
 | 
			
		||||
			if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
 | 
			
		||||
				ieee80211_aid_free(station->wlan->aidbitfield, station->aid);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			station->aid = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Remove reference from current WLAN */
 | 
			
		||||
		capwap_itemlist_remove(station->wlan->stations, station->wlanitem);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Remove timers */
 | 
			
		||||
	if (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET) {
 | 
			
		||||
		capwap_timeout_deletetimer(sessiondata->timeout, station->idtimeout);
 | 
			
		||||
		capwap_timeout_deletetimer(session->sessiondata->timeout, station->idtimeout);
 | 
			
		||||
		station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -49,21 +57,21 @@ static void ac_stations_reset_station(struct ac_session_data_t* sessiondata, str
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static void ac_stations_destroy_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
static void ac_stations_destroy_station(struct ac_session_t* session, struct ac_station* station) {
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(station != NULL);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_logging_info("Destroy station: %s", station->addrtext);
 | 
			
		||||
 | 
			
		||||
	/* Remove reference from Global Cache Stations List */
 | 
			
		||||
	ac_stations_delete_station_from_global_cache(sessiondata, station->address);
 | 
			
		||||
	ac_stations_delete_station_from_global_cache(session, station->address);
 | 
			
		||||
 | 
			
		||||
	/* Remove reference from WLAN */
 | 
			
		||||
	ac_stations_reset_station(sessiondata, station, NULL);
 | 
			
		||||
	ac_stations_reset_station(session, station, NULL);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_hash_delete(sessiondata->wlans->stations, station->address);
 | 
			
		||||
	capwap_hash_delete(session->wlans->stations, station->address);
 | 
			
		||||
 | 
			
		||||
	/* Free station reference with itemlist */
 | 
			
		||||
	capwap_itemlist_free(station->wlanitem);
 | 
			
		||||
@ -79,33 +87,39 @@ static unsigned long ac_wlans_item_gethash(const void* key, unsigned long keysiz
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_wlans_init(struct ac_session_data_t* sessiondata) {
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
void ac_wlans_init(struct ac_session_t* session) {
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans == NULL);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	sessiondata->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
 | 
			
		||||
	memset(sessiondata->wlans, 0, sizeof(struct ac_wlans));
 | 
			
		||||
	session->wlans = (struct ac_wlans*)capwap_alloc(sizeof(struct ac_wlans));
 | 
			
		||||
	memset(session->wlans, 0, sizeof(struct ac_wlans));
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	sessiondata->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE, AC_WLANS_STATIONS_KEY_SIZE, ac_wlans_item_gethash, NULL, NULL);
 | 
			
		||||
	session->wlans->stations = capwap_hash_create(AC_WLANS_STATIONS_HASH_SIZE, AC_WLANS_STATIONS_KEY_SIZE, ac_wlans_item_gethash, NULL, NULL);
 | 
			
		||||
	for (i = 0; i < RADIOID_MAX_COUNT; i++) {
 | 
			
		||||
		session->wlans->devices[i].radioid = i + 1;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_wlans_destroy(struct ac_session_data_t* sessiondata) {
 | 
			
		||||
void ac_wlans_destroy(struct ac_session_t* session) {
 | 
			
		||||
	int i;
 | 
			
		||||
	struct capwap_list* items;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	for (i = 0; i < RADIOID_MAX_COUNT; i++) {
 | 
			
		||||
		if (sessiondata->wlans->wlans[i]) {
 | 
			
		||||
			items = sessiondata->wlans->wlans[i];
 | 
			
		||||
		if (session->wlans->devices[i].wlans) {
 | 
			
		||||
			items = session->wlans->devices[i].wlans;
 | 
			
		||||
 | 
			
		||||
			/* Delete WLANS */
 | 
			
		||||
			while (items->first) {
 | 
			
		||||
				ac_wlans_delete_bssid(sessiondata, i + 1, ((struct ac_wlan*)items->first->item)->bssid);
 | 
			
		||||
				ac_wlans_delete_bssid(session, i + 1, ((struct ac_wlan*)items->first->item)->address);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* */
 | 
			
		||||
@ -114,51 +128,52 @@ void ac_wlans_destroy(struct ac_session_data_t* sessiondata) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	ASSERT(sessiondata->wlans->stations->count == 0);
 | 
			
		||||
	ASSERT(session->wlans->stations->count == 0);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_hash_free(sessiondata->wlans->stations);
 | 
			
		||||
	capwap_free(sessiondata->wlans);
 | 
			
		||||
	capwap_hash_free(session->wlans->stations);
 | 
			
		||||
	capwap_free(session->wlans);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
int ac_wlans_assign_bssid(struct ac_session_data_t* sessiondata, struct ac_wlan* wlan) {
 | 
			
		||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
 | 
			
		||||
	char buffer[CAPWAP_MACADDRESS_EUI48_BUFFER];
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(wlan != NULL);
 | 
			
		||||
	ASSERT(IS_VALID_RADIOID(wlan->radioid));
 | 
			
		||||
	ASSERT(wlan->device != NULL);
 | 
			
		||||
	ASSERT(IS_VALID_RADIOID(wlan->device->radioid));
 | 
			
		||||
	ASSERT(IS_VALID_WLANID(wlan->wlanid));
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	if (ac_wlans_get_bssid(sessiondata, wlan->radioid, wlan->bssid)) {
 | 
			
		||||
	if (ac_wlans_get_bssid(session, wlan->device->radioid, wlan->address)) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	wlan->session = sessiondata->session;
 | 
			
		||||
	wlan->sessiondata = sessiondata;
 | 
			
		||||
	wlan->session = session;
 | 
			
		||||
	wlan->sessiondata = session->sessiondata;
 | 
			
		||||
 | 
			
		||||
	/* Create WLAN list */
 | 
			
		||||
	if (!sessiondata->wlans->wlans[wlan->radioid - 1]) {
 | 
			
		||||
		sessiondata->wlans->wlans[wlan->radioid - 1] = capwap_list_create();
 | 
			
		||||
	if (!session->wlans->devices[wlan->device->radioid - 1].wlans) {
 | 
			
		||||
		session->wlans->devices[wlan->device->radioid - 1].wlans = capwap_list_create();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Append WLAN to list */
 | 
			
		||||
	capwap_itemlist_insert_after(sessiondata->wlans->wlans[wlan->radioid - 1], NULL, wlan->wlanitem);
 | 
			
		||||
	capwap_itemlist_insert_after(session->wlans->devices[wlan->device->radioid - 1].wlans, NULL, wlan->wlanitem);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->bssid, MACADDRESS_EUI48_LENGTH));
 | 
			
		||||
	capwap_logging_info("Added new wlan with radioid: %d, wlanid: %d, bssid: %s", (int)wlan->device->radioid, (int)wlan->wlanid, capwap_printf_macaddress(buffer, wlan->address, MACADDRESS_EUI48_LENGTH));
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_wlan* ac_wlans_create_bssid(uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan) {
 | 
			
		||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan) {
 | 
			
		||||
	struct ac_wlan* wlan;
 | 
			
		||||
	struct capwap_list_item* wlanitem;
 | 
			
		||||
 | 
			
		||||
	ASSERT(IS_VALID_RADIOID(radioid));
 | 
			
		||||
	ASSERT(device != NULL);
 | 
			
		||||
	ASSERT(IS_VALID_WLANID(wlanid));
 | 
			
		||||
	ASSERT(bssid != NULL);
 | 
			
		||||
 | 
			
		||||
@ -169,8 +184,8 @@ struct ac_wlan* ac_wlans_create_bssid(uint8_t radioid, uint8_t wlanid, const uin
 | 
			
		||||
 | 
			
		||||
	/* Init WLAN */
 | 
			
		||||
	wlan->wlanitem = wlanitem;
 | 
			
		||||
	memcpy(wlan->bssid, bssid, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
	wlan->radioid = radioid;
 | 
			
		||||
	memcpy(wlan->address, bssid, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
	wlan->device = device;
 | 
			
		||||
	wlan->wlanid = wlanid;
 | 
			
		||||
	wlan->stations = capwap_list_create();
 | 
			
		||||
 | 
			
		||||
@ -192,34 +207,30 @@ struct ac_wlan* ac_wlans_create_bssid(uint8_t radioid, uint8_t wlanid, const uin
 | 
			
		||||
	wlan->tunnelmode = addwlan->tunnelmode;
 | 
			
		||||
 | 
			
		||||
	wlan->suppressssid = addwlan->suppressssid;
 | 
			
		||||
	wlan->ssid = (uint8_t*)capwap_duplicate_string((const char*)addwlan->ssid);
 | 
			
		||||
	strcpy(wlan->ssid, (const char*)addwlan->ssid);
 | 
			
		||||
 | 
			
		||||
	return wlan;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid) {
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
 | 
			
		||||
	struct capwap_list_item* search;
 | 
			
		||||
	struct ac_wlan* wlan = NULL;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(IS_VALID_RADIOID(radioid));
 | 
			
		||||
	ASSERT(bssid != NULL);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	if (sessiondata->wlans->wlans[radioid - 1]) {
 | 
			
		||||
		search = sessiondata->wlans->wlans[radioid - 1]->first;
 | 
			
		||||
		while (search) {
 | 
			
		||||
	if (session->wlans->devices[radioid - 1].wlans) {
 | 
			
		||||
		for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
 | 
			
		||||
			struct ac_wlan* item = (struct ac_wlan*)search->item;
 | 
			
		||||
 | 
			
		||||
			if (!memcmp(bssid, item->bssid, MACADDRESS_EUI48_LENGTH)) {
 | 
			
		||||
			if (!memcmp(bssid, item->address, MACADDRESS_EUI48_LENGTH)) {
 | 
			
		||||
				wlan = item;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Next */
 | 
			
		||||
			search = search->next;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -227,28 +238,24 @@ struct ac_wlan* ac_wlans_get_bssid(struct ac_session_data_t* sessiondata, uint8_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid) {
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid) {
 | 
			
		||||
	struct capwap_list_item* search;
 | 
			
		||||
	struct ac_wlan* wlan = NULL;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(IS_VALID_RADIOID(radioid));
 | 
			
		||||
	ASSERT(IS_VALID_WLANID(wlanid));
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	if (sessiondata->wlans->wlans[radioid - 1]) {
 | 
			
		||||
		search = sessiondata->wlans->wlans[radioid - 1]->first;
 | 
			
		||||
		while (search) {
 | 
			
		||||
	if (session->wlans->devices[radioid - 1].wlans) {
 | 
			
		||||
		for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
 | 
			
		||||
			struct ac_wlan* item = (struct ac_wlan*)search->item;
 | 
			
		||||
 | 
			
		||||
			if (wlanid == item->wlanid) {
 | 
			
		||||
				wlan = item;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Next */
 | 
			
		||||
			search = search->next;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -256,19 +263,19 @@ struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_data_t* session
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static void ac_wlans_destroy_bssid(struct ac_session_data_t* sessiondata, struct ac_wlan* wlan) {
 | 
			
		||||
static void ac_wlans_destroy_bssid(struct ac_session_t* session, struct ac_wlan* wlan) {
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(wlan != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Free capability */
 | 
			
		||||
	if (wlan->key) {
 | 
			
		||||
		capwap_free(wlan->key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (wlan->ssid) {
 | 
			
		||||
		capwap_free(wlan->ssid);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Remove stations */
 | 
			
		||||
	while (wlan->stations->first) {
 | 
			
		||||
		ac_stations_destroy_station(sessiondata, (struct ac_station*)wlan->stations->first->item);
 | 
			
		||||
		ac_stations_destroy_station(session, (struct ac_station*)wlan->stations->first->item);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
@ -276,43 +283,39 @@ static void ac_wlans_destroy_bssid(struct ac_session_data_t* sessiondata, struct
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_wlans_delete_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid) {
 | 
			
		||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid) {
 | 
			
		||||
	struct capwap_list_item* search;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(IS_VALID_RADIOID(radioid));
 | 
			
		||||
	ASSERT(bssid != NULL);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	if (sessiondata->wlans->wlans[radioid - 1]) {
 | 
			
		||||
		search = sessiondata->wlans->wlans[radioid - 1]->first;
 | 
			
		||||
		while (search) {
 | 
			
		||||
	if (session->wlans->devices[radioid - 1].wlans) {
 | 
			
		||||
		for (search = session->wlans->devices[radioid - 1].wlans->first; search; search = search->next) {
 | 
			
		||||
			struct ac_wlan* item = (struct ac_wlan*)search->item;
 | 
			
		||||
 | 
			
		||||
			if (!memcmp(bssid, item->bssid, MACADDRESS_EUI48_LENGTH)) {
 | 
			
		||||
				ac_wlans_destroy_bssid(sessiondata, item);
 | 
			
		||||
				capwap_itemlist_free(capwap_itemlist_remove(sessiondata->wlans->wlans[radioid - 1], search));
 | 
			
		||||
			if (!memcmp(bssid, item->address, MACADDRESS_EUI48_LENGTH)) {
 | 
			
		||||
				ac_wlans_destroy_bssid(session, item);
 | 
			
		||||
				capwap_itemlist_free(capwap_itemlist_remove(session->wlans->devices[radioid - 1].wlans, search));
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Next */
 | 
			
		||||
			search = search->next;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_station* ac_stations_get_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
 | 
			
		||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
 | 
			
		||||
	struct ac_station* station;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(address != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Get station */
 | 
			
		||||
	station = (struct ac_station*)capwap_hash_search(sessiondata->wlans->stations, address);
 | 
			
		||||
	if (station && (station->flags & AC_STATION_FLAGS_ENABLED) && ((radioid == RADIOID_ANY) || (radioid == station->wlan->radioid)) && (!bssid || !memcmp(bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH))) {
 | 
			
		||||
	station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
 | 
			
		||||
	if (station && (station->flags & AC_STATION_FLAGS_ENABLED) && ((radioid == RADIOID_ANY) || (radioid == station->wlan->device->radioid)) && (!bssid || !memcmp(bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH))) {
 | 
			
		||||
		return station;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -320,16 +323,16 @@ struct ac_station* ac_stations_get_station(struct ac_session_data_t* sessiondata
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
 | 
			
		||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address) {
 | 
			
		||||
	char buffer1[CAPWAP_MACADDRESS_EUI48_BUFFER];
 | 
			
		||||
	char buffer2[CAPWAP_MACADDRESS_EUI48_BUFFER];
 | 
			
		||||
	struct ac_wlan* wlan;
 | 
			
		||||
	struct ac_session_data_t* ownersession;
 | 
			
		||||
	struct ac_station* station;
 | 
			
		||||
	struct ac_session_t* ownersession;
 | 
			
		||||
	struct capwap_list_item* stationitem;
 | 
			
		||||
	struct ac_station* station = NULL;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(IS_VALID_RADIOID(radioid));
 | 
			
		||||
	ASSERT(bssid != NULL);
 | 
			
		||||
	ASSERT(address != NULL);
 | 
			
		||||
@ -339,27 +342,29 @@ struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiond
 | 
			
		||||
	capwap_printf_macaddress(buffer2, address, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
	capwap_logging_info("Create station to radioid: %d, bssid: %s, station address: %s", (int)radioid, buffer1, buffer2);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	wlan = ac_wlans_get_bssid(session, radioid, bssid);
 | 
			
		||||
	if (wlan) {
 | 
			
		||||
		/* Get session that owns the station */
 | 
			
		||||
		capwap_rwlock_rdlock(&g_ac.stationslock);
 | 
			
		||||
	ownersession = (struct ac_session_data_t*)capwap_hash_search(g_ac.stations, address);
 | 
			
		||||
		ownersession = (struct ac_session_t*)capwap_hash_search(g_ac.stations, address);
 | 
			
		||||
		capwap_rwlock_exit(&g_ac.stationslock);
 | 
			
		||||
 | 
			
		||||
		/* If request change owner of station */
 | 
			
		||||
	if (ownersession != sessiondata) {
 | 
			
		||||
		if (ownersession != session) {
 | 
			
		||||
			/* Release station from old owner */
 | 
			
		||||
			if (ownersession) {
 | 
			
		||||
			ac_session_data_send_action(ownersession, AC_SESSION_DATA_ACTION_ROAMING_STATION, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
				ac_session_data_send_action(ownersession->sessiondata, AC_SESSION_DATA_ACTION_ROAMING_STATION, 0, (void*)address, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Set station into Global Cache Stations List */
 | 
			
		||||
			capwap_rwlock_wrlock(&g_ac.stationslock);
 | 
			
		||||
		capwap_hash_add(g_ac.stations, address, sessiondata);
 | 
			
		||||
			capwap_hash_add(g_ac.stations, address, session);
 | 
			
		||||
			capwap_rwlock_exit(&g_ac.stationslock);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* */
 | 
			
		||||
	wlan = ac_wlans_get_bssid(sessiondata, radioid, bssid);
 | 
			
		||||
	station = (struct ac_station*)capwap_hash_search(sessiondata->wlans->stations, address);
 | 
			
		||||
		station = (struct ac_station*)capwap_hash_search(session->wlans->stations, address);
 | 
			
		||||
		if (!station) {
 | 
			
		||||
			stationitem = capwap_itemlist_create(sizeof(struct ac_station));
 | 
			
		||||
			station = (struct ac_station*)stationitem->item;
 | 
			
		||||
@ -372,41 +377,44 @@ struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiond
 | 
			
		||||
			station->wlanitem = stationitem;
 | 
			
		||||
 | 
			
		||||
			/* */
 | 
			
		||||
		capwap_hash_add(sessiondata->wlans->stations, address, station);
 | 
			
		||||
			capwap_hash_add(session->wlans->stations, address, station);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Set station to WLAN */
 | 
			
		||||
	ac_stations_reset_station(sessiondata, station, wlan);
 | 
			
		||||
		ac_stations_reset_station(session, station, wlan);
 | 
			
		||||
		station->flags |= AC_STATION_FLAGS_ENABLED;
 | 
			
		||||
	} else {
 | 
			
		||||
		capwap_logging_warning("Unable to find radioid: %d, bssid: %s", (int)radioid, buffer1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return station;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_stations_delete_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station) {
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(station != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Deauthorize station */
 | 
			
		||||
	ac_stations_deauthorize_station(sessiondata, station);
 | 
			
		||||
	ac_stations_deauthorize_station(session, station);
 | 
			
		||||
 | 
			
		||||
	/* Destroy station reference */
 | 
			
		||||
	ac_stations_destroy_station(sessiondata, station);
 | 
			
		||||
	ac_stations_destroy_station(session, station);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_stations_authorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
 | 
			
		||||
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station) {
 | 
			
		||||
	struct ac_notify_station_configuration_ieee8011_add_station notify;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(station != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Active Station only if Authenticated, Associated and not Authrizated */
 | 
			
		||||
	if ((station->flags & AC_STATION_FLAGS_AUTHENTICATED) && (station->flags & AC_STATION_FLAGS_ASSOCIATE) && !(station->flags & AC_STATION_FLAGS_AUTHORIZED)) {
 | 
			
		||||
		memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
 | 
			
		||||
		notify.radioid = station->wlan->radioid;
 | 
			
		||||
		notify.radioid = station->wlan->device->radioid;
 | 
			
		||||
		memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
		notify.wlanid = station->wlan->wlanid;
 | 
			
		||||
		notify.associationid = station->aid;
 | 
			
		||||
@ -414,34 +422,34 @@ void ac_stations_authorize_station(struct ac_session_data_t* sessiondata, struct
 | 
			
		||||
		notify.supportedratescount = station->supportedratescount;
 | 
			
		||||
		memcpy(notify.supportedrates, station->supportedrates, station->supportedratescount);
 | 
			
		||||
 | 
			
		||||
		ac_session_send_action(sessiondata->session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
 | 
			
		||||
		ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_add_station));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_stations_deauthorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station) {
 | 
			
		||||
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station) {
 | 
			
		||||
	int responselength;
 | 
			
		||||
	uint8_t buffer[IEEE80211_MTU];
 | 
			
		||||
	struct ieee80211_deauthentication_params ieee80211_params;
 | 
			
		||||
	struct ac_notify_station_configuration_ieee8011_delete_station notify;
 | 
			
		||||
 | 
			
		||||
	ASSERT(sessiondata != NULL);
 | 
			
		||||
	ASSERT(sessiondata->wlans != NULL);
 | 
			
		||||
	ASSERT(session != NULL);
 | 
			
		||||
	ASSERT(session->wlans != NULL);
 | 
			
		||||
	ASSERT(station != NULL);
 | 
			
		||||
 | 
			
		||||
	if (station->flags & AC_STATION_FLAGS_AUTHORIZED) {
 | 
			
		||||
		/* Deauthorize station */
 | 
			
		||||
		memset(¬ify, 0, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
 | 
			
		||||
		notify.radioid = station->wlan->radioid;
 | 
			
		||||
		notify.radioid = station->wlan->device->radioid;
 | 
			
		||||
		memcpy(notify.address, station->address, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
 | 
			
		||||
		/* */
 | 
			
		||||
		station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE | AC_STATION_FLAGS_AUTHORIZED);
 | 
			
		||||
		ac_session_send_action(sessiondata->session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
 | 
			
		||||
		ac_session_send_action(session, AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION, 0, ¬ify, sizeof(struct ac_notify_station_configuration_ieee8011_delete_station));
 | 
			
		||||
	} else if (station->flags & AC_STATION_FLAGS_AUTHENTICATED) {
 | 
			
		||||
		/* Create deauthentication packet */
 | 
			
		||||
		memset(&ieee80211_params, 0, sizeof(struct ieee80211_deauthentication_params));
 | 
			
		||||
		memcpy(ieee80211_params.bssid, station->wlan->bssid, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
		memcpy(ieee80211_params.bssid, station->wlan->address, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
		memcpy(ieee80211_params.station, station->address, MACADDRESS_EUI48_LENGTH);
 | 
			
		||||
		ieee80211_params.reasoncode = IEEE80211_REASON_PREV_AUTH_NOT_VALID;
 | 
			
		||||
 | 
			
		||||
@ -449,7 +457,7 @@ void ac_stations_deauthorize_station(struct ac_session_data_t* sessiondata, stru
 | 
			
		||||
		responselength = ieee80211_create_deauthentication(buffer, IEEE80211_MTU, &ieee80211_params);
 | 
			
		||||
		if (responselength > 0) {
 | 
			
		||||
			station->flags &= ~(AC_STATION_FLAGS_AUTHENTICATED | AC_STATION_FLAGS_ASSOCIATE);
 | 
			
		||||
			ac_session_data_send_data_packet(sessiondata, station->wlan->radioid, station->wlan->wlanid, buffer, responselength, 1);
 | 
			
		||||
			ac_session_data_send_data_packet(session->sessiondata, station->wlan->device->radioid, station->wlan->wlanid, buffer, responselength, 1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -464,7 +472,7 @@ void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, vo
 | 
			
		||||
		switch (station->timeoutaction) {
 | 
			
		||||
			case AC_STATION_TIMEOUT_ACTION_DEAUTHENTICATE: {
 | 
			
		||||
				capwap_logging_warning("The %s station has not completed the association in time", station->addrtext);
 | 
			
		||||
				ac_stations_delete_station((struct ac_session_data_t*)param, station);
 | 
			
		||||
				ac_stations_delete_station((struct ac_session_t*)param, station);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -13,15 +13,17 @@
 | 
			
		||||
/* AC WLAN */
 | 
			
		||||
struct ac_wlan {
 | 
			
		||||
	struct capwap_list_item* wlanitem;
 | 
			
		||||
	struct ac_device* device;
 | 
			
		||||
 | 
			
		||||
	uint8_t bssid[MACADDRESS_EUI48_LENGTH];
 | 
			
		||||
	uint8_t radioid;
 | 
			
		||||
	uint8_t address[MACADDRESS_EUI48_LENGTH];
 | 
			
		||||
	uint8_t wlanid;
 | 
			
		||||
 | 
			
		||||
	/* CAPWAP Session */
 | 
			
		||||
	struct ac_session_t* session;
 | 
			
		||||
	struct ac_session_data_t* sessiondata;
 | 
			
		||||
 | 
			
		||||
	uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
 | 
			
		||||
 | 
			
		||||
	/* Stations reference */
 | 
			
		||||
	struct capwap_list* stations;
 | 
			
		||||
 | 
			
		||||
@ -37,7 +39,25 @@ struct ac_wlan {
 | 
			
		||||
	uint8_t macmode;
 | 
			
		||||
	uint8_t tunnelmode;
 | 
			
		||||
	uint8_t suppressssid;
 | 
			
		||||
	uint8_t* ssid;
 | 
			
		||||
	char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_device {
 | 
			
		||||
	uint8_t radioid;
 | 
			
		||||
	struct capwap_list* wlans;
 | 
			
		||||
 | 
			
		||||
	/* Rates */
 | 
			
		||||
	unsigned long supportedratescount;
 | 
			
		||||
	uint8_t supportedrates[IEEE80211_SUPPORTEDRATE_MAX_COUNT];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_wlans {
 | 
			
		||||
	struct ac_device devices[RADIOID_MAX_COUNT];
 | 
			
		||||
 | 
			
		||||
	/* Stations */
 | 
			
		||||
	struct capwap_hash* stations;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
@ -81,31 +101,23 @@ struct ac_station {
 | 
			
		||||
	uint16_t authalgorithm;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_wlans {
 | 
			
		||||
	struct capwap_list* wlans[RADIOID_MAX_COUNT];
 | 
			
		||||
 | 
			
		||||
	/* Stations */
 | 
			
		||||
	struct capwap_hash* stations;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Management WLANS */
 | 
			
		||||
void ac_wlans_init(struct ac_session_data_t* sessiondata);
 | 
			
		||||
void ac_wlans_destroy(struct ac_session_data_t* sessiondata);
 | 
			
		||||
void ac_wlans_init(struct ac_session_t* session);
 | 
			
		||||
void ac_wlans_destroy(struct ac_session_t* session);
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
struct ac_wlan* ac_wlans_create_bssid(uint8_t radioid, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan);
 | 
			
		||||
int ac_wlans_assign_bssid(struct ac_session_data_t* sessiondata, struct ac_wlan* wlan);
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid);
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_data_t* sessiondata, uint8_t radioid, uint8_t wlanid);
 | 
			
		||||
void ac_wlans_delete_bssid(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid);
 | 
			
		||||
struct ac_wlan* ac_wlans_create_bssid(struct ac_device* device, uint8_t wlanid, const uint8_t* bssid, struct capwap_80211_addwlan_element* addwlan);
 | 
			
		||||
int ac_wlans_assign_bssid(struct ac_session_t* session, struct ac_wlan* wlan);
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
 | 
			
		||||
struct ac_wlan* ac_wlans_get_bssid_with_wlanid(struct ac_session_t* session, uint8_t radioid, uint8_t wlanid);
 | 
			
		||||
void ac_wlans_delete_bssid(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid);
 | 
			
		||||
 | 
			
		||||
/* Management Stations */
 | 
			
		||||
struct ac_station* ac_stations_create_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
 | 
			
		||||
struct ac_station* ac_stations_get_station(struct ac_session_data_t* sessiondata, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
 | 
			
		||||
void ac_stations_delete_station(struct ac_session_data_t* sessiondata, struct ac_station* station);
 | 
			
		||||
void ac_stations_authorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station);
 | 
			
		||||
void ac_stations_deauthorize_station(struct ac_session_data_t* sessiondata, struct ac_station* station);
 | 
			
		||||
struct ac_station* ac_stations_create_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
 | 
			
		||||
struct ac_station* ac_stations_get_station(struct ac_session_t* session, uint8_t radioid, const uint8_t* bssid, const uint8_t* address);
 | 
			
		||||
void ac_stations_delete_station(struct ac_session_t* session, struct ac_station* station);
 | 
			
		||||
void ac_stations_authorize_station(struct ac_session_t* session, struct ac_station* station);
 | 
			
		||||
void ac_stations_deauthorize_station(struct ac_session_t* session, struct ac_station* station);
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void ac_stations_timeout(struct capwap_timeout* timeout, unsigned long index, void* context, void* param);
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,8 @@
 | 
			
		||||
#define IEEE80211_MTU									7981
 | 
			
		||||
#define IEEE80211_SUPPORTEDRATE_MAX_COUNT				16
 | 
			
		||||
#define IEEE80211_MAX_STATIONS							2007
 | 
			
		||||
#define IEEE80211_SSID_MAX_LENGTH						32
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Radio type with value same of IEEE802.11 Radio Information Message Element */
 | 
			
		||||
#define IEEE80211_RADIO_TYPE_80211B			0x00000001
 | 
			
		||||
 | 
			
		||||
@ -180,7 +180,7 @@ static void wifi_station_clean(struct wifi_station* station) {
 | 
			
		||||
			wlan->device->instance->ops->station_deauthorize(wlan, station->address);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (station->aid) {
 | 
			
		||||
		if (station->aid && (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL)) {
 | 
			
		||||
			ieee80211_aid_free(wlan->aidbitfield, station->aid);
 | 
			
		||||
			station->aid = 0;
 | 
			
		||||
		}
 | 
			
		||||
@ -429,35 +429,9 @@ static void wifi_wlan_receive_station_mgmt_probe_request(struct wifi_wlan* wlan,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_set_station_information(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, struct ieee80211_ie_items* ieitems, struct wifi_station* station) {
 | 
			
		||||
static void wifi_wlan_management_legacy_station(struct wifi_wlan* wlan, struct wifi_station* station) {
 | 
			
		||||
	int updatebeacons = 0;
 | 
			
		||||
 | 
			
		||||
	/* Verify SSID */
 | 
			
		||||
	if (ieee80211_is_valid_ssid(wlan->ssid, ieitems->ssid, NULL) != IEEE80211_VALID_SSID) {
 | 
			
		||||
		return IEEE80211_STATUS_UNSPECIFIED_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	station->capability = __le16_to_cpu(frame->associationrequest.capability);
 | 
			
		||||
	station->listeninterval = __le16_to_cpu(frame->associationrequest.listeninterval);
 | 
			
		||||
	if (ieee80211_aid_create(wlan->aidbitfield, &station->aid)) {
 | 
			
		||||
		return IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get supported rates */
 | 
			
		||||
	if (!ieitems->supported_rates) {
 | 
			
		||||
		return IEEE80211_STATUS_UNSPECIFIED_FAILURE;
 | 
			
		||||
	} else if ((ieitems->supported_rates->len + (ieitems->extended_supported_rates ? ieitems->extended_supported_rates->len : 0)) > sizeof(station->supportedrates)) {
 | 
			
		||||
		return IEEE80211_STATUS_UNSPECIFIED_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check NON ERP */
 | 
			
		||||
	if (wlan->device->currentfrequency.mode & IEEE80211_RADIO_TYPE_80211G) {
 | 
			
		||||
		int i;
 | 
			
		||||
@ -501,8 +475,25 @@ static int wifi_wlan_set_station_information(struct wifi_wlan* wlan, const struc
 | 
			
		||||
	if (updatebeacons) {
 | 
			
		||||
		wlan->device->instance->ops->device_updatebeacons(wlan->device);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	return IEEE80211_STATUS_SUCCESS;
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_get_station_rates(struct wifi_station* station, struct ieee80211_ie_items* ieitems) {
 | 
			
		||||
	if (!ieitems->supported_rates) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	} else if ((ieitems->supported_rates->len + (ieitems->extended_supported_rates ? ieitems->extended_supported_rates->len : 0)) > sizeof(station->supportedrates)) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
@ -627,9 +618,6 @@ static void wifi_wlan_receive_station_mgmt_association_request(struct wifi_wlan*
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	;
 | 
			
		||||
 | 
			
		||||
	/* Get station reference */
 | 
			
		||||
	station = wifi_station_get(wlan, frame->sa);
 | 
			
		||||
	if (!station) {
 | 
			
		||||
@ -661,7 +649,24 @@ static void wifi_wlan_receive_station_mgmt_association_request(struct wifi_wlan*
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
 | 
			
		||||
		resultstatuscode = wifi_wlan_set_station_information(wlan, frame, &ieitems, station);
 | 
			
		||||
		/* Verify SSID */
 | 
			
		||||
		if (ieee80211_is_valid_ssid(wlan->ssid, ieitems.ssid, NULL) == IEEE80211_VALID_SSID) {
 | 
			
		||||
			station->capability = __le16_to_cpu(frame->associationrequest.capability);
 | 
			
		||||
			station->listeninterval = __le16_to_cpu(frame->associationrequest.listeninterval);
 | 
			
		||||
			if (!ieee80211_aid_create(wlan->aidbitfield, &station->aid)) {
 | 
			
		||||
				/* Get supported rates */
 | 
			
		||||
				if (!wifi_wlan_get_station_rates(station, &ieitems)) {
 | 
			
		||||
					wifi_wlan_management_legacy_station(wlan, station);
 | 
			
		||||
					resultstatuscode = IEEE80211_STATUS_SUCCESS;
 | 
			
		||||
				} else {
 | 
			
		||||
					resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				resultstatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			resultstatuscode = IEEE80211_STATUS_UNSPECIFIED_FAILURE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Create association response packet */
 | 
			
		||||
		memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params));
 | 
			
		||||
@ -693,6 +698,10 @@ static void wifi_wlan_receive_station_mgmt_association_request(struct wifi_wlan*
 | 
			
		||||
		}
 | 
			
		||||
	} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
 | 
			
		||||
		wlan->send_frame(wlan->send_frame_to_ac_cbparam, frame, length);
 | 
			
		||||
 | 
			
		||||
		/* Station information */
 | 
			
		||||
		station->capability = __le16_to_cpu(frame->associationresponse.capability);
 | 
			
		||||
		station->listeninterval = __le16_to_cpu(frame->associationrequest.listeninterval);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -700,8 +709,6 @@ static void wifi_wlan_receive_station_mgmt_association_request(struct wifi_wlan*
 | 
			
		||||
static void wifi_wlan_receive_station_mgmt_reassociation_request(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length, uint8_t rssi, uint8_t snr, uint16_t rate) {
 | 
			
		||||
	int ielength;
 | 
			
		||||
 | 
			
		||||
	/* TODO */
 | 
			
		||||
 | 
			
		||||
	/* Information Elements packet length */
 | 
			
		||||
	ielength = length - (sizeof(struct ieee80211_header) + sizeof(frame->reassociationrequest));
 | 
			
		||||
	if (ielength < 0) {
 | 
			
		||||
@ -715,8 +722,6 @@ static void wifi_wlan_receive_station_mgmt_reassociation_request(struct wifi_wla
 | 
			
		||||
static void wifi_wlan_receive_station_mgmt_disassociation(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length, uint8_t rssi, uint8_t snr, uint16_t rate) {
 | 
			
		||||
	int ielength;
 | 
			
		||||
 | 
			
		||||
	/* TODO */
 | 
			
		||||
 | 
			
		||||
	/* Information Elements packet length */
 | 
			
		||||
	ielength = length - (sizeof(struct ieee80211_header) + sizeof(frame->disassociation));
 | 
			
		||||
	if (ielength < 0) {
 | 
			
		||||
@ -734,8 +739,6 @@ static void wifi_wlan_receive_station_mgmt_deauthentication(struct wifi_wlan* wl
 | 
			
		||||
	int ielength;
 | 
			
		||||
	struct wifi_station* station;
 | 
			
		||||
 | 
			
		||||
	/* TODO */
 | 
			
		||||
 | 
			
		||||
	/* Information Elements packet length */
 | 
			
		||||
	ielength = length - (sizeof(struct ieee80211_header) + sizeof(frame->deauthetication));
 | 
			
		||||
	if (ielength < 0) {
 | 
			
		||||
@ -831,6 +834,7 @@ static void wifi_wlan_receive_station_mgmt_authentication_ack(struct wifi_wlan*
 | 
			
		||||
 | 
			
		||||
		/* Check if authenticate */
 | 
			
		||||
		if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
 | 
			
		||||
			capwap_logging_info("IEEE802.11 Authentication complete to %s station", station->addrtext);
 | 
			
		||||
			station->flags |= WIFI_STATION_FLAGS_AUTHENTICATED;
 | 
			
		||||
		} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
 | 
			
		||||
			/* TODO */
 | 
			
		||||
@ -857,11 +861,15 @@ static void wifi_wlan_receive_station_mgmt_association_response_ack(struct wifi_
 | 
			
		||||
	/* */
 | 
			
		||||
	statuscode = __le16_to_cpu(frame->associationresponse.statuscode);
 | 
			
		||||
	if (statuscode == IEEE80211_STATUS_SUCCESS) {
 | 
			
		||||
		station->flags |= WIFI_STATION_FLAGS_ASSOCIATE;
 | 
			
		||||
		capwap_logging_info("IEEE802.11 Association complete to %s station", station->addrtext);
 | 
			
		||||
 | 
			
		||||
		/* Apply authorization if Station already authorized */
 | 
			
		||||
		/* */
 | 
			
		||||
		station->flags |= WIFI_STATION_FLAGS_ASSOCIATE;
 | 
			
		||||
		if (station->flags & WIFI_STATION_FLAGS_AUTHORIZED) {
 | 
			
		||||
			wlan->device->instance->ops->station_authorize(wlan, station);
 | 
			
		||||
			/* Apply authorization if Station already authorized */
 | 
			
		||||
			if (wlan->device->instance->ops->station_authorize(wlan, station)) {
 | 
			
		||||
				wifi_wlan_deauthentication_station(wlan, station, IEEE80211_REASON_PREV_AUTH_NOT_VALID, 0);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -893,7 +901,7 @@ static void wifi_wlan_receive_station_mgmt_ackframe(struct wifi_wlan* wlan, cons
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_authentication(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_authentication(struct wifi_wlan* wlan, struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
	int ielength;
 | 
			
		||||
	struct wifi_station* station;
 | 
			
		||||
	int forwardframe = 0;
 | 
			
		||||
@ -904,7 +912,22 @@ static int wifi_wlan_receive_ac_mgmt_authentication(struct wifi_wlan* wlan, cons
 | 
			
		||||
		if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
 | 
			
		||||
			station = wifi_station_get(wlan, frame->da);
 | 
			
		||||
			if (station) {
 | 
			
		||||
				/* TODO */
 | 
			
		||||
				uint16_t statuscode = __le16_to_cpu(frame->authetication.statuscode);
 | 
			
		||||
 | 
			
		||||
				if (statuscode == IEEE80211_STATUS_SUCCESS) {
 | 
			
		||||
					uint16_t algorithm = __le16_to_cpu(frame->authetication.algorithm);
 | 
			
		||||
					uint16_t transactionseqnumber = __le16_to_cpu(frame->authetication.transactionseqnumber);
 | 
			
		||||
 | 
			
		||||
					/* Get authentication algorithm */
 | 
			
		||||
					if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_OPEN) && (transactionseqnumber == 2)) {
 | 
			
		||||
						station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_OPEN;
 | 
			
		||||
					} else if ((algorithm == IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY) && (transactionseqnumber == 4)) {
 | 
			
		||||
						station->authalgorithm = IEEE80211_AUTHENTICATION_ALGORITHM_SHARED_KEY;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* */
 | 
			
		||||
				forwardframe = 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -913,8 +936,9 @@ static int wifi_wlan_receive_ac_mgmt_authentication(struct wifi_wlan* wlan, cons
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_association_response(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_association_response(struct wifi_wlan* wlan, struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
	int ielength;
 | 
			
		||||
	struct ieee80211_ie_items ieitems;
 | 
			
		||||
	struct wifi_station* station;
 | 
			
		||||
	int forwardframe = 0;
 | 
			
		||||
 | 
			
		||||
@ -929,7 +953,24 @@ static int wifi_wlan_receive_ac_mgmt_association_response(struct wifi_wlan* wlan
 | 
			
		||||
					wifi_wlan_deauthentication_station(wlan, station, IEEE80211_REASON_PREV_AUTH_NOT_VALID, 0);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) {
 | 
			
		||||
				/* TODO */
 | 
			
		||||
				uint16_t statuscode = __le16_to_cpu(frame->associationresponse.statuscode);
 | 
			
		||||
 | 
			
		||||
				if ((statuscode == IEEE80211_STATUS_SUCCESS) && !ieee80211_retrieve_information_elements_position(&ieitems, &frame->associationresponse.ie[0], ielength)) {
 | 
			
		||||
					/* Station information */
 | 
			
		||||
					station->aid = (__le16_to_cpu(frame->associationresponse.aid) & ~IEEE80211_AID_FIELD);
 | 
			
		||||
 | 
			
		||||
					/* Get supported rates */
 | 
			
		||||
					wifi_wlan_get_station_rates(station, &ieitems);
 | 
			
		||||
 | 
			
		||||
					/* */
 | 
			
		||||
					wifi_wlan_management_legacy_station(wlan, station);
 | 
			
		||||
 | 
			
		||||
					/* Assign valid WLAN capability */
 | 
			
		||||
					frame->associationresponse.capability = __cpu_to_le16(wifi_wlan_check_capability(wlan, wlan->capability));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* */
 | 
			
		||||
				forwardframe = 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -938,7 +979,7 @@ static int wifi_wlan_receive_ac_mgmt_association_response(struct wifi_wlan* wlan
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_reassociation_response(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_reassociation_response(struct wifi_wlan* wlan, struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
	int ielength;
 | 
			
		||||
	struct wifi_station* station;
 | 
			
		||||
	int forwardframe = 0;
 | 
			
		||||
@ -958,7 +999,7 @@ static int wifi_wlan_receive_ac_mgmt_reassociation_response(struct wifi_wlan* wl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_disassociation(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_disassociation(struct wifi_wlan* wlan, struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
	int ielength;
 | 
			
		||||
	struct wifi_station* station;
 | 
			
		||||
 | 
			
		||||
@ -985,7 +1026,7 @@ static int wifi_wlan_receive_ac_mgmt_disassociation(struct wifi_wlan* wlan, cons
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_deauthentication(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_deauthentication(struct wifi_wlan* wlan, struct ieee80211_header_mgmt* frame, int length) {
 | 
			
		||||
	int ielength;
 | 
			
		||||
	struct wifi_station* station;
 | 
			
		||||
 | 
			
		||||
@ -1005,7 +1046,7 @@ static int wifi_wlan_receive_ac_mgmt_deauthentication(struct wifi_wlan* wlan, co
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_frame(struct wifi_wlan* wlan, const struct ieee80211_header_mgmt* frame, int length, uint16_t framecontrol_subtype) {
 | 
			
		||||
static int wifi_wlan_receive_ac_mgmt_frame(struct wifi_wlan* wlan, struct ieee80211_header_mgmt* frame, int length, uint16_t framecontrol_subtype) {
 | 
			
		||||
	int forwardframe = 0;
 | 
			
		||||
 | 
			
		||||
	switch (framecontrol_subtype) {
 | 
			
		||||
@ -1578,7 +1619,7 @@ void wifi_wlan_receive_station_ackframe(struct wifi_wlan* wlan, const struct iee
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length) {
 | 
			
		||||
void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, struct ieee80211_header* frame, int length) {
 | 
			
		||||
	int forwardframe = 1;
 | 
			
		||||
	uint16_t framecontrol;
 | 
			
		||||
	uint16_t framecontrol_type;
 | 
			
		||||
@ -1596,7 +1637,7 @@ void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, const struct ieee80211_h
 | 
			
		||||
 | 
			
		||||
	/* Parsing frame */
 | 
			
		||||
	if (framecontrol_type == IEEE80211_FRAMECONTROL_TYPE_MGMT) {
 | 
			
		||||
		forwardframe = wifi_wlan_receive_ac_mgmt_frame(wlan, (const struct ieee80211_header_mgmt*)frame, length, framecontrol_subtype);
 | 
			
		||||
		forwardframe = wifi_wlan_receive_ac_mgmt_frame(wlan, (struct ieee80211_header_mgmt*)frame, length, framecontrol_subtype);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Forward frame */
 | 
			
		||||
@ -1608,6 +1649,7 @@ void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, const struct ieee80211_h
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* params) {
 | 
			
		||||
	int result;
 | 
			
		||||
	struct wifi_station* station;
 | 
			
		||||
 | 
			
		||||
	ASSERT(wlan != NULL);
 | 
			
		||||
@ -1622,9 +1664,6 @@ int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* pa
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_logging_info("Authorized station: %s", station->addrtext);
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	capwap_timeout_deletetimer(g_wifiglobal.timeout, station->idtimeout);
 | 
			
		||||
	station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET;
 | 
			
		||||
@ -1636,7 +1675,12 @@ int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* pa
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Station authorized */
 | 
			
		||||
	return wlan->device->instance->ops->station_authorize(wlan, station);
 | 
			
		||||
	result = wlan->device->instance->ops->station_authorize(wlan, station);
 | 
			
		||||
	if (result) {
 | 
			
		||||
		wifi_wlan_deauthentication_station(wlan, station, IEEE80211_REASON_PREV_AUTH_NOT_VALID, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,6 @@
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
#define WIFI_DRIVER_NAME_SIZE								16
 | 
			
		||||
#define WIFI_SSID_MAX_LENGTH								32
 | 
			
		||||
 | 
			
		||||
/* */
 | 
			
		||||
#define WIFI_BAND_UNKNOWN									0
 | 
			
		||||
@ -294,7 +293,7 @@ struct wifi_wlan {
 | 
			
		||||
	void* send_frame_to_ac_cbparam;
 | 
			
		||||
 | 
			
		||||
	/* WLAN information */
 | 
			
		||||
	char ssid[WIFI_SSID_MAX_LENGTH + 1];
 | 
			
		||||
	char ssid[IEEE80211_SSID_MAX_LENGTH + 1];
 | 
			
		||||
	uint8_t ssid_hidden;
 | 
			
		||||
	uint16_t capability;
 | 
			
		||||
 | 
			
		||||
@ -415,7 +414,7 @@ void wifi_wlan_destroy(struct wifi_wlan* wlan);
 | 
			
		||||
/* WLAN packet management */
 | 
			
		||||
void wifi_wlan_receive_station_frame(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, uint32_t frequency, uint8_t rssi, uint8_t snr, uint16_t rate);
 | 
			
		||||
void wifi_wlan_receive_station_ackframe(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length, int ack);
 | 
			
		||||
void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, const struct ieee80211_header* frame, int length);
 | 
			
		||||
void wifi_wlan_receive_ac_frame(struct wifi_wlan* wlan, struct ieee80211_header* frame, int length);
 | 
			
		||||
 | 
			
		||||
/* Station management */
 | 
			
		||||
int wifi_station_authorize(struct wifi_wlan* wlan, struct station_add_params* params);
 | 
			
		||||
 | 
			
		||||
@ -1003,10 +1003,15 @@ int nl80211_station_authorize(struct wifi_wlan* wlan, struct wifi_station* stati
 | 
			
		||||
		if (result == -EEXIST) {
 | 
			
		||||
			result = 0;
 | 
			
		||||
		} else {
 | 
			
		||||
			capwap_logging_error("Unable add station into wireless driver, error code: %d", result);
 | 
			
		||||
			capwap_logging_error("Unable to authorized station, error code: %d", result);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	if (!result) {
 | 
			
		||||
		capwap_logging_info("Authorized station: %s", station->addrtext);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* */
 | 
			
		||||
	nlmsg_free(msg);
 | 
			
		||||
	return result;
 | 
			
		||||
 | 
			
		||||
@ -612,7 +612,7 @@ void wtp_radio_receive_data_packet(uint8_t radioid, unsigned short binding, cons
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((binding == CAPWAP_WIRELESS_BINDING_IEEE80211) && (length >= sizeof(struct ieee80211_header))) {
 | 
			
		||||
		const struct ieee80211_header* header = (const struct ieee80211_header*)frame;
 | 
			
		||||
		struct ieee80211_header* header = (struct ieee80211_header*)frame;
 | 
			
		||||
		const uint8_t* bssid = ieee80211_get_bssid_addr(header);
 | 
			
		||||
 | 
			
		||||
		if (bssid) {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user