diff --git a/src/ac/ac_backend.h b/src/ac/ac_backend.h index 68647da..f5027c6 100644 --- a/src/ac/ac_backend.h +++ b/src/ac/ac_backend.h @@ -29,6 +29,19 @@ struct ac_notify_addwlan_t { char ssid[CAPWAP_ADD_WLAN_SSID_LENGTH + 1]; }; +/* Station Configuration IEEE802.11 add station notification */ +struct ac_notify_station_configuration_ieee8011_add_station { + uint8_t radioid; + uint8_t address[MACADDRESS_EUI48_LENGTH]; + uint8_t vlan[CAPWAP_ADDSTATION_VLAN_MAX_LENGTH]; + + uint8_t wlanid; + uint16_t associationid; + uint16_t capabilities; + uint8_t supportedratescount; + uint8_t supportedrates[CAPWAP_STATION_RATES_MAXLENGTH]; +}; + /* */ int ac_backend_start(void); void ac_backend_stop(void); diff --git a/src/ac/ac_ieee80211_data.c b/src/ac/ac_ieee80211_data.c index 62707e9..813d802 100644 --- a/src/ac/ac_ieee80211_data.c +++ b/src/ac/ac_ieee80211_data.c @@ -7,6 +7,11 @@ static void ac_ieee80211_mgmt_probe_request_packet(struct ac_session_data_t* ses int ielength; struct ieee80211_ie_items ieitems; + /* Accept probe request only if not sent by WTP */ + if (!memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) { + return; + } + /* Parsing Information Elements */ ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->proberequest)); if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) { @@ -28,14 +33,25 @@ static void ac_ieee80211_mgmt_authentication_packet(struct ac_session_data_t* se return; } - /* Create station */ - station = ac_stations_create_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa); + /* Create station if sent by station */ + if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) { + station = ac_stations_create_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa); - /* */ - if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) { - /* TODO */ - } else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) { - /* TODO */ + /* */ + if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) { + /* TODO */ + } else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) { + /* TODO */ + } + } else { + station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->da); + if (station) { + if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) { + /* TODO */ + } else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) { + /* TODO */ + } + } } } @@ -51,6 +67,40 @@ static void ac_ieee80211_mgmt_association_request_packet(struct ac_session_data_ return; } + /* Get station */ + if (memcmp(mgmt->bssid, mgmt->sa, MACADDRESS_EUI48_LENGTH)) { + station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa); + + /* */ + if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) { + /* TODO */ + } else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) { + /* TODO */ + } + } else { + station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->da); + if (station) { + if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) { + /* TODO */ + } else if (station->wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_SPLIT) { + /* TODO */ + } + } + } +} + +/* */ +static void ac_ieee80211_mgmt_association_response_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) { + int ielength; + struct ieee80211_ie_items ieitems; + struct ac_station* station; + + /* Parsing Information Elements */ + ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse)); + if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationresponse.ie[0], ielength)) { + return; + } + /* Get station */ station = ac_stations_get_station(sessiondata->session, radioid, mgmt->bssid, mgmt->sa); @@ -76,6 +126,20 @@ static void ac_ieee80211_mgmt_reassociation_request_packet(struct ac_session_dat /* TODO */ } +/* */ +static void ac_ieee80211_mgmt_reassociation_response_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) { + int ielength; + struct ieee80211_ie_items ieitems; + + /* Parsing Information Elements */ + ielength = mgmtlength - (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse)); + if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->reassociationresponse.ie[0], ielength)) { + return; + } + + /* TODO */ +} + /* */ static void ac_ieee80211_mgmt_disassociation_packet(struct ac_session_data_t* sessiondata, uint8_t radioid, const struct ieee80211_header_mgmt* mgmt, int mgmtlength) { int ielength; @@ -136,6 +200,14 @@ static void ac_ieee80211_mgmt_packet(struct ac_session_data_t* sessiondata, uint break; } + case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_ASSOCIATION_RESPONSE: { + if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->associationresponse))) { + ac_ieee80211_mgmt_association_response_packet(sessiondata, radioid, mgmt, mgmtlength); + } + + break; + } + case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_REQUEST: { if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationrequest))) { ac_ieee80211_mgmt_reassociation_request_packet(sessiondata, radioid, mgmt, mgmtlength); @@ -144,6 +216,14 @@ static void ac_ieee80211_mgmt_packet(struct ac_session_data_t* sessiondata, uint break; } + case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_REASSOCIATION_RESPONSE: { + if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->reassociationresponse))) { + ac_ieee80211_mgmt_reassociation_response_packet(sessiondata, radioid, mgmt, mgmtlength); + } + + break; + } + case IEEE80211_FRAMECONTROL_MGMT_SUBTYPE_DISASSOCIATION: { if (mgmtlength >= (sizeof(struct ieee80211_header) + sizeof(mgmt->disassociation))) { ac_ieee80211_mgmt_disassociation_packet(sessiondata, radioid, mgmt, mgmtlength); diff --git a/src/ac/ac_session.c b/src/ac/ac_session.c index e9ad270..d6835c2 100644 --- a/src/ac/ac_session.c +++ b/src/ac/ac_session.c @@ -112,6 +112,13 @@ static int ac_session_action_addwlan(struct ac_session_t* session, struct ac_not return AC_ERROR_ACTION_SESSION; } +/* */ +static int ac_session_action_station_configuration_ieee8011_add_station(struct ac_session_t* session, struct ac_notify_station_configuration_ieee8011_add_station* notify) { + ASSERT(session->requestfragmentpacket->count == 0); + + return AC_ERROR_ACTION_SESSION; +} + /* */ static int ac_session_action_execute(struct ac_session_t* session, struct ac_session_action* action) { int result = AC_ERROR_ACTION_SESSION; @@ -164,6 +171,15 @@ static int ac_session_action_execute(struct ac_session_t* session, struct ac_ses break; } + case AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION: { + result = ac_session_action_station_configuration_ieee8011_add_station(session, (struct ac_notify_station_configuration_ieee8011_add_station*)action->data); + break; + } + + case AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION: { + break; + } + case AC_SESSION_ACTION_ROAMING_STATION: { /* Delete station */ ac_stations_delete_station(session, (uint8_t*)action->data); diff --git a/src/ac/ac_session.h b/src/ac/ac_session.h index 3354a4d..12cc00f 100644 --- a/src/ac/ac_session.h +++ b/src/ac/ac_session.h @@ -19,11 +19,13 @@ struct ac_session_control { }; /* */ -#define AC_SESSION_ACTION_CLOSE 0 -#define AC_SESSION_ACTION_RESET_WTP 1 -#define AC_SESSION_ACTION_ESTABLISHED_SESSION_DATA 2 -#define AC_SESSION_ACTION_NOTIFY_EVENT 3 -#define AC_SESSION_ACTION_ADDWLAN 4 +#define AC_SESSION_ACTION_CLOSE 0 +#define AC_SESSION_ACTION_RESET_WTP 1 +#define AC_SESSION_ACTION_ESTABLISHED_SESSION_DATA 2 +#define AC_SESSION_ACTION_NOTIFY_EVENT 3 +#define AC_SESSION_ACTION_ADDWLAN 4 +#define AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_ADD_STATION 5 +#define AC_SESSION_ACTION_STATION_CONFIGURATION_IEEE80211_DELETE_STATION 6 #define AC_SESSION_ACTION_ROAMING_STATION 10 diff --git a/src/binding/ieee80211/wifi_nl80211.c b/src/binding/ieee80211/wifi_nl80211.c index 405dea3..ddbe5ae 100644 --- a/src/binding/ieee80211/wifi_nl80211.c +++ b/src/binding/ieee80211/wifi_nl80211.c @@ -650,7 +650,7 @@ static void nl80211_station_clean(struct nl80211_station* station) { station->wlanhandle = NULL; } - /* Remove timers */ + /* Remove timers */ if (station->globalhandle && (station->idtimeout != CAPWAP_TIMEOUT_INDEX_NO_SET)) { capwap_timeout_deletetimer(station->globalhandle->timeout, station->idtimeout); station->idtimeout = CAPWAP_TIMEOUT_INDEX_NO_SET; @@ -978,8 +978,11 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla station->timeoutaction = NL80211_STATION_TIMEOUT_ACTION_DEAUTHENTICATE; station->idtimeout = capwap_timeout_set(station->globalhandle->timeout, station->idtimeout, NL80211_STATION_TIMEOUT_ASSOCIATION_COMPLETE, nl80211_station_timeout, station, wlanhandle); - /* Notify authentication message also to AC */ + /* Notify authentication request message also to AC */ wlanhandle->send_mgmtframe(wlanhandle->send_mgmtframe_to_ac_cbparam, mgmt, mgmtlength); + + /* Forwards the authentication response message also to AC */ + wlanhandle->send_mgmtframe(wlanhandle->send_mgmtframe_to_ac_cbparam, (struct ieee80211_header_mgmt*)g_bufferIEEE80211, responselength); } else { capwap_logging_warning("Unable to send IEEE802.11 Authentication Response to %s station", stationaddress); nl80211_station_delete(station); @@ -1147,11 +1150,10 @@ static void nl80211_do_mgmt_association_request_event(struct nl80211_wlan_handle /* */ capwap_logging_info("Receive IEEE802.11 Association Request from %s station", stationaddress); - /* */ - resultstatuscode = nl80211_set_station_information(wlanhandle, mgmt, &ieitems, station); - /* */ if (wlanhandle->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) { + resultstatuscode = nl80211_set_station_information(wlanhandle, mgmt, &ieitems, station); + /* Create association response packet */ memset(&ieee80211_params, 0, sizeof(struct ieee80211_authentication_params)); memcpy(ieee80211_params.bssid, wlanhandle->address, ETH_ALEN); @@ -1176,6 +1178,9 @@ static void nl80211_do_mgmt_association_request_event(struct nl80211_wlan_handle /* Notify association request message also to AC */ wlanhandle->send_mgmtframe(wlanhandle->send_mgmtframe_to_ac_cbparam, mgmt, mgmtlength); + + /* Forwards the association response message also to AC */ + wlanhandle->send_mgmtframe(wlanhandle->send_mgmtframe_to_ac_cbparam, (struct ieee80211_header_mgmt*)g_bufferIEEE80211, responselength); } else { capwap_logging_warning("Unable to send IEEE802.11 Association Response to %s station", stationaddress); nl80211_wlan_deauthentication_station(wlanhandle, mgmt->sa, IEEE80211_REASON_PREV_AUTH_NOT_VALID, 0);