Change file position of some ieee80211 functions

This commit is contained in:
vemax78 2014-02-20 21:23:18 +01:00
parent ea02d7379e
commit 2bdcac10ba
6 changed files with 250 additions and 251 deletions

View File

@ -104,6 +104,227 @@ static int ieee80211_ie_set_erp(char* buffer, uint32_t mode, uint8_t erpinfo) {
return sizeof(struct ieee80211_ie_erp);
}
/* */
int ieee80211_retrieve_information_elements_position(struct ieee80211_ie_items* items, const uint8_t* data, int length) {
ASSERT(items != NULL);
ASSERT(data != NULL);
/* */
memset(items, 0, sizeof(struct ieee80211_ie_items));
/* Parsing */
while (length >= 2) {
uint8_t ie_id = data[0];
uint8_t ie_len = data[1];
/* Parsing Information Element */
switch (ie_id) {
case IEEE80211_IE_SSID: {
if (ie_len > IEEE80211_IE_SSID_MAX_LENGTH) {
return -1;
}
items->ssid = (struct ieee80211_ie_ssid*)data;
break;
}
case IEEE80211_IE_SUPPORTED_RATES: {
if ((ie_len < IEEE80211_IE_SUPPORTED_RATES_MIN_LENGTH) || (ie_len > IEEE80211_IE_SUPPORTED_RATES_MAX_LENGTH)) {
return -1;
}
items->supported_rates = (struct ieee80211_ie_supported_rates*)data;
break;
}
case IEEE80211_IE_DSSS: {
if (ie_len != IEEE80211_IE_DSSS_LENGTH) {
return -1;
}
items->dsss = (struct ieee80211_ie_dsss*)data;
break;
}
case IEEE80211_IE_COUNTRY: {
if (ie_len < IEEE80211_IE_COUNTRY_MIN_LENGTH) {
return -1;
}
items->country = (struct ieee80211_ie_country*)data;
break;
}
case IEEE80211_IE_CHALLENGE_TEXT: {
if (ie_len < IEEE80211_IE_CHALLENGE_TEXT_MIN_LENGTH) {
return -1;
}
items->challenge_text = (struct ieee80211_ie_challenge_text*)data;
break;
}
case IEEE80211_IE_ERP: {
if (ie_len != IEEE80211_IE_ERP_LENGTH) {
return -1;
}
items->erp = (struct ieee80211_ie_erp*)data;
break;
}
case IEEE80211_IE_EXTENDED_SUPPORTED_RATES: {
if (ie_len < IEEE80211_IE_EXTENDED_SUPPORTED_MIN_LENGTH) {
return -1;
}
items->extended_supported_rates = (struct ieee80211_ie_extended_supported_rates*)data;
break;
}
case IEEE80211_IE_EDCA_PARAMETER_SET: {
if (ie_len != IEEE80211_IE_EDCA_PARAMETER_SET_LENGTH) {
return -1;
}
items->edca_parameter_set = (struct ieee80211_ie_edca_parameter_set*)data;
break;
}
case IEEE80211_IE_QOS_CAPABILITY: {
if (ie_len != IEEE80211_IE_QOS_CAPABILITY_LENGTH) {
return -1;
}
items->qos_capability = (struct ieee80211_ie_qos_capability*)data;
break;
}
case IEEE80211_IE_POWER_CONSTRAINT: {
if (ie_len != IEEE80211_IE_POWER_CONSTRAINT_LENGTH) {
return -1;
}
items->power_constraint = (struct ieee80211_ie_power_constraint*)data;
break;
}
case IEEE80211_IE_SSID_LIST: {
items->ssid_list = (struct ieee80211_ie_ssid_list*)data;
break;
}
}
/* Next Information Element */
data += sizeof(struct ieee80211_ie) + ie_len;
length -= sizeof(struct ieee80211_ie) + ie_len;
}
return (!length ? 0 : -1);
}
/* */
int ieee80211_aid_create(uint32_t* aidbitfield, uint16_t* aid) {
int i, j;
ASSERT(aidbitfield != NULL);
ASSERT(aid != NULL);
/* Search free aid bitfield */
for (i = 0; i < IEEE80211_AID_BITFIELD_SIZE; i++) {
if (aidbitfield[i] != 0xffffffff) {
uint32_t bitfield = aidbitfield[i];
/* Search free bit */
for (j = 0; j < 32; j++) {
if (!(bitfield & (1 << j))) {
*aid = i * 32 + j + 1;
if (*aid <= IEEE80211_AID_MAX_VALUE) {
aidbitfield[i] |= (1 << j);
return 0;
}
break;
}
}
break;
}
}
*aid = 0;
return -1;
}
/* */
void ieee80211_aid_free(uint32_t* aidbitfield, uint16_t aid) {
ASSERT(aidbitfield != NULL);
ASSERT((aid > 0) && (aid <= IEEE80211_AID_MAX_VALUE));
aidbitfield[(aid - 1) / 32] &= ~(1 << ((aid - 1) % 32));
}
/* */
unsigned long ieee80211_frequency_to_channel(uint32_t freq) {
if ((freq >= 2412) && (freq <= 2472)) {
return (freq - 2407) / 5;
} else if (freq == 2484) {
return 14;
} else if ((freq >= 4915) && (freq <= 4980)) {
return (freq - 4000) / 5;
} else if ((freq >= 5035) && (freq <= 5825)) {
return (freq - 5000) / 5;
}
return 0;
}
/* */
int ieee80211_is_broadcast_addr(const uint8_t* addr) {
return (((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)) ? 1 : 0);
}
/* */
int ieee80211_is_valid_ssid(const char* ssid, struct ieee80211_ie_ssid* iessid, struct ieee80211_ie_ssid_list* isssidlist) {
int ssidlength;
ASSERT(ssid != NULL);
if (!iessid) {
return IEEE80211_WRONG_SSID;
}
/* Check SSID */
ssidlength = strlen((char*)ssid);
if ((ssidlength == iessid->len) && !memcmp(ssid, iessid->ssid, ssidlength)) {
return IEEE80211_VALID_SSID;
}
/* Check SSID list */
if (isssidlist) {
int length = isssidlist->len;
uint8_t* pos = isssidlist->lists;
while (length >= sizeof(struct ieee80211_ie)) {
struct ieee80211_ie_ssid* ssiditem = (struct ieee80211_ie_ssid*)pos;
/* Check buffer */
length -= sizeof(struct ieee80211_ie);
if ((ssiditem->id != IEEE80211_IE_SSID) || !ssiditem->len || (length < ssiditem->len)) {
break;
} else if ((ssidlength == ssiditem->len) && !memcmp(ssid, ssiditem->ssid, ssidlength)) {
return IEEE80211_VALID_SSID;
}
/* Next */
length -= ssiditem->len;
pos += sizeof(struct ieee80211_ie) + ssiditem->len;
}
}
return (!iessid->len ? IEEE80211_WILDCARD_SSID : IEEE80211_WRONG_SSID);
}
/* */
uint8_t ieee80211_get_erpinfo(uint32_t mode, int olbc, unsigned long stationnonerpcount, unsigned long stationnoshortpreamblecount, int shortpreamble) {
uint8_t result = 0;

View File

@ -568,4 +568,20 @@ struct ieee80211_deauthentication_params {
int ieee80211_create_deauthentication(char* buffer, int length, struct ieee80211_deauthentication_params* params);
/* Utils */
int ieee80211_retrieve_information_elements_position(struct ieee80211_ie_items* items, const uint8_t* data, int length);
unsigned long ieee80211_frequency_to_channel(uint32_t freq);
int ieee80211_is_broadcast_addr(const uint8_t* addr);
/* */
#define IEEE80211_VALID_SSID 1
#define IEEE80211_WILDCARD_SSID 0
#define IEEE80211_WRONG_SSID -1
int ieee80211_is_valid_ssid(const char* ssid, struct ieee80211_ie_ssid* iessid, struct ieee80211_ie_ssid_list* isssidlist);
/* IEEE802.11 Aid management */
#define IEEE80211_AID_BITFIELD_SIZE 63
int ieee80211_aid_create(uint32_t* aidbitfield, uint16_t* aid);
void ieee80211_aid_free(uint32_t* aidbitfield, uint16_t aid);
#endif /* __CAPWAP_IEEE802_11_HEADER__ */

View File

@ -572,224 +572,3 @@ int wifi_frequency_to_radiotype(uint32_t freq) {
return -1;
}
/* */
unsigned long wifi_frequency_to_channel(uint32_t freq) {
if ((freq >= 2412) && (freq <= 2472)) {
return (freq - 2407) / 5;
} else if (freq == 2484) {
return 14;
} else if ((freq >= 4915) && (freq <= 4980)) {
return (freq - 4000) / 5;
} else if ((freq >= 5035) && (freq <= 5825)) {
return (freq - 5000) / 5;
}
return 0;
}
/* */
int wifi_is_broadcast_addr(const uint8_t* addr) {
return (((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)) ? 1 : 0);
}
/* */
int wifi_is_valid_ssid(const char* ssid, struct ieee80211_ie_ssid* iessid, struct ieee80211_ie_ssid_list* isssidlist) {
int ssidlength;
ASSERT(ssid != NULL);
if (!iessid) {
return WIFI_WRONG_SSID;
}
/* Check SSID */
ssidlength = strlen((char*)ssid);
if ((ssidlength == iessid->len) && !memcmp(ssid, iessid->ssid, ssidlength)) {
return WIFI_VALID_SSID;
}
/* Check SSID list */
if (isssidlist) {
int length = isssidlist->len;
uint8_t* pos = isssidlist->lists;
while (length >= sizeof(struct ieee80211_ie)) {
struct ieee80211_ie_ssid* ssiditem = (struct ieee80211_ie_ssid*)pos;
/* Check buffer */
length -= sizeof(struct ieee80211_ie);
if ((ssiditem->id != IEEE80211_IE_SSID) || !ssiditem->len || (length < ssiditem->len)) {
break;
} else if ((ssidlength == ssiditem->len) && !memcmp(ssid, ssiditem->ssid, ssidlength)) {
return WIFI_VALID_SSID;
}
/* Next */
length -= ssiditem->len;
pos += sizeof(struct ieee80211_ie) + ssiditem->len;
}
}
return (!iessid->len ? WIFI_WILDCARD_SSID : WIFI_WRONG_SSID);
}
/* */
int wifi_retrieve_information_elements_position(struct ieee80211_ie_items* items, const uint8_t* data, int length) {
ASSERT(items != NULL);
ASSERT(data != NULL);
/* */
memset(items, 0, sizeof(struct ieee80211_ie_items));
/* Parsing */
while (length >= 2) {
uint8_t ie_id = data[0];
uint8_t ie_len = data[1];
/* Parsing Information Element */
switch (ie_id) {
case IEEE80211_IE_SSID: {
if (ie_len > IEEE80211_IE_SSID_MAX_LENGTH) {
return -1;
}
items->ssid = (struct ieee80211_ie_ssid*)data;
break;
}
case IEEE80211_IE_SUPPORTED_RATES: {
if ((ie_len < IEEE80211_IE_SUPPORTED_RATES_MIN_LENGTH) || (ie_len > IEEE80211_IE_SUPPORTED_RATES_MAX_LENGTH)) {
return -1;
}
items->supported_rates = (struct ieee80211_ie_supported_rates*)data;
break;
}
case IEEE80211_IE_DSSS: {
if (ie_len != IEEE80211_IE_DSSS_LENGTH) {
return -1;
}
items->dsss = (struct ieee80211_ie_dsss*)data;
break;
}
case IEEE80211_IE_COUNTRY: {
if (ie_len < IEEE80211_IE_COUNTRY_MIN_LENGTH) {
return -1;
}
items->country = (struct ieee80211_ie_country*)data;
break;
}
case IEEE80211_IE_CHALLENGE_TEXT: {
if (ie_len < IEEE80211_IE_CHALLENGE_TEXT_MIN_LENGTH) {
return -1;
}
items->challenge_text = (struct ieee80211_ie_challenge_text*)data;
break;
}
case IEEE80211_IE_ERP: {
if (ie_len != IEEE80211_IE_ERP_LENGTH) {
return -1;
}
items->erp = (struct ieee80211_ie_erp*)data;
break;
}
case IEEE80211_IE_EXTENDED_SUPPORTED_RATES: {
if (ie_len < IEEE80211_IE_EXTENDED_SUPPORTED_MIN_LENGTH) {
return -1;
}
items->extended_supported_rates = (struct ieee80211_ie_extended_supported_rates*)data;
break;
}
case IEEE80211_IE_EDCA_PARAMETER_SET: {
if (ie_len != IEEE80211_IE_EDCA_PARAMETER_SET_LENGTH) {
return -1;
}
items->edca_parameter_set = (struct ieee80211_ie_edca_parameter_set*)data;
break;
}
case IEEE80211_IE_QOS_CAPABILITY: {
if (ie_len != IEEE80211_IE_QOS_CAPABILITY_LENGTH) {
return -1;
}
items->qos_capability = (struct ieee80211_ie_qos_capability*)data;
break;
}
case IEEE80211_IE_POWER_CONSTRAINT: {
if (ie_len != IEEE80211_IE_POWER_CONSTRAINT_LENGTH) {
return -1;
}
items->power_constraint = (struct ieee80211_ie_power_constraint*)data;
break;
}
case IEEE80211_IE_SSID_LIST: {
items->ssid_list = (struct ieee80211_ie_ssid_list*)data;
break;
}
}
/* Next Information Element */
data += sizeof(struct ieee80211_ie) + ie_len;
length -= sizeof(struct ieee80211_ie) + ie_len;
}
return (!length ? 0 : -1);
}
/* */
int wifi_aid_create(uint32_t* aidbitfield, uint16_t* aid) {
int i, j;
ASSERT(aidbitfield != NULL);
ASSERT(aid != NULL);
/* Search free aid bitfield */
for (i = 0; i < WIFI_AID_BITFIELD_SIZE; i++) {
if (aidbitfield[i] != 0xffffffff) {
uint32_t bitfield = aidbitfield[i];
/* Search free bit */
for (j = 0; j < 32; j++) {
if (!(bitfield & (1 << j))) {
*aid = i * 32 + j + 1;
if (*aid <= IEEE80211_AID_MAX_VALUE) {
aidbitfield[i] |= (1 << j);
return 0;
}
break;
}
}
break;
}
}
*aid = 0;
return -1;
}
/* */
void wifi_aid_free(uint32_t* aidbitfield, uint16_t aid) {
ASSERT(aidbitfield != NULL);
ASSERT((aid > 0) && (aid <= IEEE80211_AID_MAX_VALUE));
aidbitfield[(aid - 1) / 32] &= ~(1 << ((aid - 1) % 32));
}

View File

@ -63,9 +63,6 @@
#define WLAN_INTERFACE_AP 1
/* IEEE802.11 Aid management */
#define WIFI_AID_BITFIELD_SIZE 63
/* */
typedef void* wifi_global_handle;
typedef void* wifi_device_handle;
@ -290,22 +287,8 @@ uint32_t wifi_iface_index(const char* ifname);
int wifi_iface_hwaddr(int sock, const char* ifname, uint8_t* hwaddr);
int wifi_frequency_to_radiotype(uint32_t freq);
unsigned long wifi_frequency_to_channel(uint32_t freq);
int wifi_is_broadcast_addr(const uint8_t* addr);
/* */
#define WIFI_VALID_SSID 1
#define WIFI_WILDCARD_SSID 0
#define WIFI_WRONG_SSID -1
int wifi_is_valid_ssid(const char* ssid, struct ieee80211_ie_ssid* iessid, struct ieee80211_ie_ssid_list* isssidlist);
/* */
int wifi_aid_create(uint32_t* aidbitfield, uint16_t* aid);
void wifi_aid_free(uint32_t* aidbitfield, uint16_t aid);
/* */
int wifi_retrieve_information_elements_position(struct ieee80211_ie_items* items, const uint8_t* data, int length);
int wifi_iface_getstatus(int sock, const char* ifname);
int wifi_iface_updown(int sock, const char* ifname, int up);
#define wifi_iface_up(sock, ifname) wifi_iface_updown(sock, ifname, 1)

View File

@ -510,7 +510,7 @@ static void nl80211_station_clean(struct nl80211_wlan_handle* wlanhandle, struct
ASSERT(station != NULL);
if (station->aid) {
wifi_aid_free(wlanhandle->aidbitfield, station->aid);
ieee80211_aid_free(wlanhandle->aidbitfield, station->aid);
}
if (station->flags & NL80211_STATION_FLAGS_NON_ERP) {
@ -645,7 +645,7 @@ static void nl80211_do_mgmt_probe_request_event(struct nl80211_wlan_handle* wlan
}
/* Parsing Information Elements */
if (wifi_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->proberequest.ie[0], ielength)) {
return;
}
@ -655,8 +655,8 @@ static void nl80211_do_mgmt_probe_request_event(struct nl80211_wlan_handle* wlan
}
/* Verify the SSID */
ssidcheck = wifi_is_valid_ssid(wlanhandle->ssid, ieitems.ssid, ieitems.ssid_list);
if (ssidcheck == WIFI_WRONG_SSID) {
ssidcheck = ieee80211_is_valid_ssid(wlanhandle->ssid, ieitems.ssid, ieitems.ssid_list);
if (ssidcheck == IEEE80211_WRONG_SSID) {
return;
}
@ -683,7 +683,7 @@ static void nl80211_do_mgmt_probe_request_event(struct nl80211_wlan_handle* wlan
wlan_params.packet = g_bufferIEEE80211;
wlan_params.length = responselength;
wlan_params.frequency = wlanhandle->devicehandle->currentfrequency.frequency;
wlan_params.no_wait_ack = ((ssidcheck == WIFI_WILDCARD_SSID) && wifi_is_broadcast_addr(mgmt->da) ? 1 : 0);
wlan_params.no_wait_ack = ((ssidcheck == IEEE80211_WILDCARD_SSID) && ieee80211_is_broadcast_addr(mgmt->da) ? 1 : 0);
if (nl80211_wlan_send_frame((wifi_wlan_handle)wlanhandle, &wlan_params)) {
capwap_logging_warning("Unable to send IEEE802.11 Probe Response");
@ -727,7 +727,7 @@ static void nl80211_do_mgmt_authentication_event(struct nl80211_wlan_handle* wla
}
/* Parsing Information Elements */
if (wifi_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->authetication.ie[0], ielength)) {
return;
}
@ -793,14 +793,14 @@ static int nl80211_set_station_information(struct nl80211_wlan_handle* wlanhandl
int updatebeacons = 0;
/* Verify SSID */
if (wifi_is_valid_ssid(wlanhandle->ssid, ieitems->ssid, NULL) != WIFI_VALID_SSID) {
if (ieee80211_is_valid_ssid(wlanhandle->ssid, ieitems->ssid, NULL) != IEEE80211_VALID_SSID) {
return IEEE80211_STATUS_UNSPECIFIED_FAILURE;
}
/* */
station->capability = __le16_to_cpu(mgmt->associationrequest.capability);
station->listeninterval = __le16_to_cpu(mgmt->associationrequest.listeninterval);
if (wifi_aid_create(wlanhandle->aidbitfield, &station->aid)) {
if (ieee80211_aid_create(wlanhandle->aidbitfield, &station->aid)) {
return IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
}
@ -923,7 +923,7 @@ static void nl80211_do_mgmt_association_request_event(struct nl80211_wlan_handle
}
/* Parsing Information Elements */
if (wifi_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
if (ieee80211_retrieve_information_elements_position(&ieitems, &mgmt->associationrequest.ie[0], ielength)) {
return;
}
@ -932,7 +932,7 @@ static void nl80211_do_mgmt_association_request_event(struct nl80211_wlan_handle
/* */
if (wlanhandle->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
if (resultstatuscode == IEEE80211_STATUS_SUCCESS) {
if (wifi_aid_create(wlanhandle->aidbitfield, &station->aid)) {
if (ieee80211_aid_create(wlanhandle->aidbitfield, &station->aid)) {
resultstatuscode = IEEE80211_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
}
}
@ -1008,7 +1008,7 @@ static void nl80211_do_mgmt_frame_event(struct nl80211_wlan_handle* wlanhandle,
}
/* Check if sent packet to correct AP */
broadcast = wifi_is_broadcast_addr(mgmt->bssid);
broadcast = ieee80211_is_broadcast_addr(mgmt->bssid);
if (!broadcast && memcmp(mgmt->bssid, wlanhandle->address, ETH_ALEN)) {
return;
}
@ -1671,7 +1671,7 @@ static int cb_get_phydevice_capability(struct nl_msg* msg, void* data) {
/* Retrieve frequency and channel */
freq->frequency = frequency;
freq->channel = wifi_frequency_to_channel(frequency);
freq->channel = ieee80211_frequency_to_channel(frequency);
if (!radio80211bg && IS_IEEE80211_FREQ_BG(frequency)) {
radio80211bg = 1;

View File

@ -117,7 +117,7 @@ struct nl80211_wlan_handle {
unsigned long maxstationscount;
struct capwap_hash* stations;
uint32_t aidbitfield[WIFI_AID_BITFIELD_SIZE];
uint32_t aidbitfield[IEEE80211_AID_BITFIELD_SIZE];
};
/* Physical device info */