diff --git a/src/mpdu.c b/src/mpdu.c index 52898bcf..3ee5be5c 100644 --- a/src/mpdu.c +++ b/src/mpdu.c @@ -24,11 +24,274 @@ #include #endif +#include +#include + #include #include "src/ie.h" #include "src/mpdu.h" +/* 802.11-2020 section 9.3.3.5 */ +static const enum ie_type association_request_ie_order[] = { + IE_TYPE_SSID, + IE_TYPE_SUPPORTED_RATES, + IE_TYPE_EXTENDED_SUPPORTED_RATES, + IE_TYPE_POWER_CAPABILITY, + IE_TYPE_SUPPORTED_CHANNELS, + IE_TYPE_RSN, + IE_TYPE_QOS_CAPABILITY, + IE_TYPE_RM_ENABLED_CAPABILITIES, + IE_TYPE_MOBILITY_DOMAIN, + IE_TYPE_SUPPORTED_OPERATING_CLASSES, + IE_TYPE_HT_CAPABILITIES, + IE_TYPE_BSS_COEXISTENCE, + IE_TYPE_EXTENDED_CAPABILITIES, + IE_TYPE_QOS_TRAFFIC_CAPABILITY, + IE_TYPE_TIM_BROADCAST_REQUEST, + IE_TYPE_INTERWORKING, + IE_TYPE_MULTIBAND, + IE_TYPE_DMG_CAPABILITIES, + IE_TYPE_MULTIPLE_MAC_SUBLAYERS, + IE_TYPE_VHT_CAPABILITIES, + IE_TYPE_OPERATING_MODE_NOTIFICATION, + IE_TYPE_FILS_SESSION, + IE_TYPE_FILS_PUBLIC_KEY, + IE_TYPE_FILS_KEY_CONFIRMATION, + IE_TYPE_FILS_HLP_CONTAINER, + IE_TYPE_FILS_IP_ADDRESS, + IE_TYPE_TWT, + IE_TYPE_AID_REQUEST, + IE_TYPE_S1G_CAPABILITIES, + IE_TYPE_EL_OPERATION, + IE_TYPE_S1G_RELAY, + IE_TYPE_BSS_MAX_IDLE_PERIOD, + IE_TYPE_HEADER_COMPRESSION, + IE_TYPE_MAD, + IE_TYPE_REACHABLE_ADDRESS, + IE_TYPE_S1G_RELAY_ACTIVATION, + IE_TYPE_CDMG_CAPABILITIES, + IE_TYPE_CMMG_CAPABILITIES, + IE_TYPE_GLK_GCR_PARAMETER_SET, + IE_TYPE_FAST_BSS_TRANSITION, + IE_TYPE_RSNX, + IE_TYPE_SUPPLEMENTAL_CLASS_2_CAPABILITIES, + IE_TYPE_MSCS_DESCRIPTOR, + IE_TYPE_VENDOR_SPECIFIC, +}; + +/* 802.11-2020 section 9.3.3.6 */ +static const enum ie_type association_response_ie_order[] = { + IE_TYPE_AID, + IE_TYPE_SUPPORTED_RATES, + IE_TYPE_EXTENDED_SUPPORTED_RATES, + IE_TYPE_EDCA_PARAMETER_SET, + IE_TYPE_RCPI, + IE_TYPE_RSNI, + IE_TYPE_RM_ENABLED_CAPABILITIES, + IE_TYPE_RSN, + IE_TYPE_MOBILITY_DOMAIN, + IE_TYPE_FAST_BSS_TRANSITION, + IE_TYPE_DSE_REGISTERED_LOCATION, + IE_TYPE_TIMEOUT_INTERVAL, + IE_TYPE_HT_CAPABILITIES, + IE_TYPE_HT_OPERATION, + IE_TYPE_BSS_COEXISTENCE, + IE_TYPE_OVERLAPPING_BSS_SCAN_PARAMETERS, + IE_TYPE_EXTENDED_CAPABILITIES, + IE_TYPE_BSS_MAX_IDLE_PERIOD, + IE_TYPE_TIM_BROADCAST_RESPONSE, + IE_TYPE_QOS_MAP_SET, + IE_TYPE_QMF_POLICY, + IE_TYPE_MULTIBAND, + IE_TYPE_DMG_CAPABILITIES, + IE_TYPE_DMG_OPERATION, + IE_TYPE_MULTIPLE_MAC_SUBLAYERS, + IE_TYPE_NEIGHBOR_REPORT, + IE_TYPE_VHT_CAPABILITIES, + IE_TYPE_VHT_OPERATION, + IE_TYPE_OPERATING_MODE_NOTIFICATION, + IE_TYPE_FUTURE_CHANNEL_GUIDANCE, + IE_TYPE_FILS_SESSION, + IE_TYPE_FILS_PUBLIC_KEY, + IE_TYPE_FILS_KEY_CONFIRMATION, + IE_TYPE_FILS_HLP_CONTAINER, + IE_TYPE_FILS_IP_ADDRESS, + IE_TYPE_KEY_DELIVERY, + IE_TYPE_S1G_SECTOR_OPERATION, + IE_TYPE_TWT, + IE_TYPE_TSF_TIMER_ACCURACY, + IE_TYPE_S1G_CAPABILITIES, + IE_TYPE_S1G_OPERATION, + IE_TYPE_AID_RESPONSE, + IE_TYPE_SECTORIZED_GROUP_ID_LIST, + IE_TYPE_S1G_RELAY, + IE_TYPE_HEADER_COMPRESSION, + IE_TYPE_SST_OPERATION, + IE_TYPE_MAD, + IE_TYPE_S1G_RELAY_ACTIVATION, + IE_TYPE_CDMG_CAPABILITIES, + IE_TYPE_CMMG_CAPABILITIES, + IE_TYPE_CMMG_OPERATION, + IE_TYPE_GLK_GCR_PARAMETER_SET, + IE_TYPE_RSNX, + IE_TYPE_MSCS_DESCRIPTOR, + IE_TYPE_VENDOR_SPECIFIC, +}; + +/* 802.11-2020 section 9.3.3.7 */ +static const enum ie_type reassociation_request_ie_order[] = { + IE_TYPE_SSID, + IE_TYPE_SUPPORTED_RATES, + IE_TYPE_EXTENDED_SUPPORTED_RATES, + IE_TYPE_POWER_CAPABILITY, + IE_TYPE_SUPPORTED_CHANNELS, + IE_TYPE_RSN, + IE_TYPE_QOS_CAPABILITY, + IE_TYPE_RM_ENABLED_CAPABILITIES, + IE_TYPE_MOBILITY_DOMAIN, + IE_TYPE_FAST_BSS_TRANSITION, + IE_TYPE_RIC_DATA, + IE_TYPE_SUPPORTED_OPERATING_CLASSES, + IE_TYPE_HT_CAPABILITIES, + IE_TYPE_BSS_COEXISTENCE, + IE_TYPE_EXTENDED_CAPABILITIES, + IE_TYPE_QOS_TRAFFIC_CAPABILITY, + IE_TYPE_TIM_BROADCAST_REQUEST, + IE_TYPE_FMS_REQUEST, + IE_TYPE_DMS_REQUEST, + IE_TYPE_INTERWORKING, + IE_TYPE_MULTIBAND, + IE_TYPE_DMG_CAPABILITIES, + IE_TYPE_MULTIPLE_MAC_SUBLAYERS, + IE_TYPE_VHT_CAPABILITIES, + IE_TYPE_OPERATING_MODE_NOTIFICATION, + IE_TYPE_FILS_SESSION, + IE_TYPE_FILS_PUBLIC_KEY, + IE_TYPE_FILS_KEY_CONFIRMATION, + IE_TYPE_FILS_HLP_CONTAINER, + IE_TYPE_FILS_IP_ADDRESS, + IE_TYPE_TWT, + IE_TYPE_AID_REQUEST, + IE_TYPE_S1G_CAPABILITIES, + IE_TYPE_EL_OPERATION, + IE_TYPE_BSS_MAX_IDLE_PERIOD, + IE_TYPE_S1G_RELAY, + IE_TYPE_HEADER_COMPRESSION, + IE_TYPE_MAD, + IE_TYPE_REACHABLE_ADDRESS, + IE_TYPE_S1G_RELAY_ACTIVATION, + IE_TYPE_CDMG_CAPABILITIES, + IE_TYPE_CMMG_CAPABILITIES, + IE_TYPE_OCI, + IE_TYPE_GLK_GCR_PARAMETER_SET, + IE_TYPE_RSNX, + IE_TYPE_SUPPLEMENTAL_CLASS_2_CAPABILITIES, + IE_TYPE_MSCS_DESCRIPTOR, + IE_TYPE_VENDOR_SPECIFIC, +}; + +/* 802.11-2020 section 9.3.3.8 */ +static const enum ie_type reassociation_response_ie_order[] = { + IE_TYPE_AID, + IE_TYPE_SUPPORTED_RATES, + IE_TYPE_EXTENDED_SUPPORTED_RATES, + IE_TYPE_EDCA_PARAMETER_SET, + IE_TYPE_RCPI, + IE_TYPE_RSNI, + IE_TYPE_RM_ENABLED_CAPABILITIES, + IE_TYPE_RSN, + IE_TYPE_MOBILITY_DOMAIN, + IE_TYPE_FAST_BSS_TRANSITION, + IE_TYPE_RIC_DATA, + IE_TYPE_DSE_REGISTERED_LOCATION, + IE_TYPE_TIMEOUT_INTERVAL, + IE_TYPE_HT_CAPABILITIES, + IE_TYPE_HT_OPERATION, + IE_TYPE_BSS_COEXISTENCE, + IE_TYPE_OVERLAPPING_BSS_SCAN_PARAMETERS, + IE_TYPE_EXTENDED_CAPABILITIES, + IE_TYPE_BSS_MAX_IDLE_PERIOD, + IE_TYPE_TIM_BROADCAST_RESPONSE, + IE_TYPE_FMS_RESPONSE, + IE_TYPE_DMS_RESPONSE, + IE_TYPE_QOS_MAP_SET, + IE_TYPE_QMF_POLICY, + IE_TYPE_MULTIBAND, + IE_TYPE_DMG_CAPABILITIES, + IE_TYPE_DMG_OPERATION, + IE_TYPE_MULTIPLE_MAC_SUBLAYERS, + IE_TYPE_NEIGHBOR_REPORT, + IE_TYPE_VHT_CAPABILITIES, + IE_TYPE_VHT_OPERATION, + IE_TYPE_OPERATING_MODE_NOTIFICATION, + IE_TYPE_FUTURE_CHANNEL_GUIDANCE, + IE_TYPE_FILS_SESSION, + IE_TYPE_FILS_PUBLIC_KEY, + IE_TYPE_FILS_KEY_CONFIRMATION, + IE_TYPE_FILS_HLP_CONTAINER, + IE_TYPE_FILS_IP_ADDRESS, + IE_TYPE_KEY_DELIVERY, + IE_TYPE_S1G_SECTOR_OPERATION, + IE_TYPE_TWT, + IE_TYPE_TSF_TIMER_ACCURACY, + IE_TYPE_S1G_CAPABILITIES, + IE_TYPE_S1G_OPERATION, + IE_TYPE_AID_RESPONSE, + IE_TYPE_SECTORIZED_GROUP_ID_LIST, + IE_TYPE_S1G_RELAY, + IE_TYPE_HEADER_COMPRESSION, + IE_TYPE_SST_OPERATION, + IE_TYPE_MAD, + IE_TYPE_S1G_RELAY_ACTIVATION, + IE_TYPE_CDMG_CAPABILITIES, + IE_TYPE_CMMG_CAPABILITIES, + IE_TYPE_CMMG_OPERATION, + IE_TYPE_OCI, + IE_TYPE_GLK_GCR_PARAMETER_SET, + IE_TYPE_RSNX, + IE_TYPE_MSCS_DESCRIPTOR, + IE_TYPE_VENDOR_SPECIFIC, +}; + +/* 802.11-2020 section 9.3.3.9 */ +static const enum ie_type probe_request_ie_order[] = { + IE_TYPE_SSID, + IE_TYPE_SUPPORTED_RATES, + IE_TYPE_REQUEST, + IE_TYPE_EXTENDED_SUPPORTED_RATES, + IE_TYPE_DSSS_PARAMETER_SET, + IE_TYPE_SUPPORTED_OPERATING_CLASSES, + IE_TYPE_HT_CAPABILITIES, + IE_TYPE_BSS_COEXISTENCE, + IE_TYPE_EXTENDED_CAPABILITIES, + IE_TYPE_SSID_LIST, + IE_TYPE_CHANNEL_USAGE, + IE_TYPE_INTERWORKING, + IE_TYPE_MESH_ID, + IE_TYPE_MULTIBAND, + IE_TYPE_DMG_CAPABILITIES, + IE_TYPE_MULTIPLE_MAC_SUBLAYERS, + IE_TYPE_VHT_CAPABILITIES, + IE_TYPE_ESTIMATED_SERVICE_PARAMETERS, + IE_TYPE_EXTENDED_REQUEST, + IE_TYPE_FILS_REQUEST_PARAMETERS, + IE_TYPE_AP_CSN, + IE_TYPE_CHANGE_SEQUENCE, + IE_TYPE_S1G_RELAY_DISCOVERY, + IE_TYPE_PV1_PROBE_RESPONSE_OPTION, + IE_TYPE_S1G_CAPABILITIES, + IE_TYPE_EL_OPERATION, + IE_TYPE_MAD, + IE_TYPE_VENDOR_SPECIFIC_REQUEST, + IE_TYPE_CDMG_CAPABILITIES, + IE_TYPE_CLUSTER_PROBE, + IE_TYPE_CMMG_CAPABILITIES, + IE_TYPE_ESTIMATED_SERVICE_PARAMETERS_OUT, + IE_TYPE_SUPPLEMENTAL_CLASS_2_CAPABILITIES, + IE_TYPE_VENDOR_SPECIFIC, +}; + static bool validate_mgmt_header(const struct mmpdu_header *mpdu, int len, int *offset) { @@ -149,335 +412,85 @@ static bool validate_mgmt_ies(const uint8_t *ies, size_t ies_len, return true; } -/* 802.11-2020 section 9.3.3.5 */ static bool validate_association_request_mmpdu(const struct mmpdu_header *mpdu, int len, int *offset) { const struct mmpdu_association_request *body = (const void *) mpdu + *offset; - static const enum ie_type ie_order[] = { - IE_TYPE_SSID, - IE_TYPE_SUPPORTED_RATES, - IE_TYPE_EXTENDED_SUPPORTED_RATES, - IE_TYPE_POWER_CAPABILITY, - IE_TYPE_SUPPORTED_CHANNELS, - IE_TYPE_RSN, - IE_TYPE_QOS_CAPABILITY, - IE_TYPE_RM_ENABLED_CAPABILITIES, - IE_TYPE_MOBILITY_DOMAIN, - IE_TYPE_SUPPORTED_OPERATING_CLASSES, - IE_TYPE_HT_CAPABILITIES, - IE_TYPE_BSS_COEXISTENCE, - IE_TYPE_EXTENDED_CAPABILITIES, - IE_TYPE_QOS_TRAFFIC_CAPABILITY, - IE_TYPE_TIM_BROADCAST_REQUEST, - IE_TYPE_INTERWORKING, - IE_TYPE_MULTIBAND, - IE_TYPE_DMG_CAPABILITIES, - IE_TYPE_MULTIPLE_MAC_SUBLAYERS, - IE_TYPE_VHT_CAPABILITIES, - IE_TYPE_OPERATING_MODE_NOTIFICATION, - IE_TYPE_FILS_SESSION, - IE_TYPE_FILS_PUBLIC_KEY, - IE_TYPE_FILS_KEY_CONFIRMATION, - IE_TYPE_FILS_HLP_CONTAINER, - IE_TYPE_FILS_IP_ADDRESS, - IE_TYPE_TWT, - IE_TYPE_AID_REQUEST, - IE_TYPE_S1G_CAPABILITIES, - IE_TYPE_EL_OPERATION, - IE_TYPE_S1G_RELAY, - IE_TYPE_BSS_MAX_IDLE_PERIOD, - IE_TYPE_HEADER_COMPRESSION, - IE_TYPE_MAD, - IE_TYPE_REACHABLE_ADDRESS, - IE_TYPE_S1G_RELAY_ACTIVATION, - IE_TYPE_CDMG_CAPABILITIES, - IE_TYPE_CMMG_CAPABILITIES, - IE_TYPE_GLK_GCR_PARAMETER_SET, - IE_TYPE_FAST_BSS_TRANSITION, - IE_TYPE_RSNX, - IE_TYPE_SUPPLEMENTAL_CLASS_2_CAPABILITIES, - IE_TYPE_MSCS_DESCRIPTOR, - IE_TYPE_VENDOR_SPECIFIC, - }; if (len < *offset + (int) sizeof(struct mmpdu_association_request)) return false; *offset += sizeof(struct mmpdu_association_request); - return validate_mgmt_ies(body->ies, len - *offset, ie_order, - L_ARRAY_SIZE(ie_order)); + return validate_mgmt_ies(body->ies, len - *offset, + association_request_ie_order, + L_ARRAY_SIZE(association_request_ie_order)); } -/* 802.11-2020 section 9.3.3.6 */ static bool validate_association_response_mmpdu(const struct mmpdu_header *mpdu, int len, int *offset) { const struct mmpdu_association_response *body = (const void *) mpdu + *offset; - static const enum ie_type ie_order[] = { - IE_TYPE_AID, - IE_TYPE_SUPPORTED_RATES, - IE_TYPE_EXTENDED_SUPPORTED_RATES, - IE_TYPE_EDCA_PARAMETER_SET, - IE_TYPE_RCPI, - IE_TYPE_RSNI, - IE_TYPE_RM_ENABLED_CAPABILITIES, - IE_TYPE_RSN, - IE_TYPE_MOBILITY_DOMAIN, - IE_TYPE_FAST_BSS_TRANSITION, - IE_TYPE_DSE_REGISTERED_LOCATION, - IE_TYPE_TIMEOUT_INTERVAL, - IE_TYPE_HT_CAPABILITIES, - IE_TYPE_HT_OPERATION, - IE_TYPE_BSS_COEXISTENCE, - IE_TYPE_OVERLAPPING_BSS_SCAN_PARAMETERS, - IE_TYPE_EXTENDED_CAPABILITIES, - IE_TYPE_BSS_MAX_IDLE_PERIOD, - IE_TYPE_TIM_BROADCAST_RESPONSE, - IE_TYPE_QOS_MAP_SET, - IE_TYPE_QMF_POLICY, - IE_TYPE_MULTIBAND, - IE_TYPE_DMG_CAPABILITIES, - IE_TYPE_DMG_OPERATION, - IE_TYPE_MULTIPLE_MAC_SUBLAYERS, - IE_TYPE_NEIGHBOR_REPORT, - IE_TYPE_VHT_CAPABILITIES, - IE_TYPE_VHT_OPERATION, - IE_TYPE_OPERATING_MODE_NOTIFICATION, - IE_TYPE_FUTURE_CHANNEL_GUIDANCE, - IE_TYPE_FILS_SESSION, - IE_TYPE_FILS_PUBLIC_KEY, - IE_TYPE_FILS_KEY_CONFIRMATION, - IE_TYPE_FILS_HLP_CONTAINER, - IE_TYPE_FILS_IP_ADDRESS, - IE_TYPE_KEY_DELIVERY, - IE_TYPE_S1G_SECTOR_OPERATION, - IE_TYPE_TWT, - IE_TYPE_TSF_TIMER_ACCURACY, - IE_TYPE_S1G_CAPABILITIES, - IE_TYPE_S1G_OPERATION, - IE_TYPE_AID_RESPONSE, - IE_TYPE_SECTORIZED_GROUP_ID_LIST, - IE_TYPE_S1G_RELAY, - IE_TYPE_HEADER_COMPRESSION, - IE_TYPE_SST_OPERATION, - IE_TYPE_MAD, - IE_TYPE_S1G_RELAY_ACTIVATION, - IE_TYPE_CDMG_CAPABILITIES, - IE_TYPE_CMMG_CAPABILITIES, - IE_TYPE_CMMG_OPERATION, - IE_TYPE_GLK_GCR_PARAMETER_SET, - IE_TYPE_RSNX, - IE_TYPE_MSCS_DESCRIPTOR, - IE_TYPE_VENDOR_SPECIFIC, - }; if (len < *offset + (int) sizeof(struct mmpdu_association_response)) return false; *offset += sizeof(struct mmpdu_association_response); - return validate_mgmt_ies(body->ies, len - *offset, ie_order, - L_ARRAY_SIZE(ie_order)); + return validate_mgmt_ies(body->ies, len - *offset, + association_response_ie_order, + L_ARRAY_SIZE(association_response_ie_order)); } -/* 802.11-2020 section 9.3.3.7 */ static bool validate_reassociation_request_mmpdu( const struct mmpdu_header *mpdu, int len, int *offset) { const struct mmpdu_reassociation_request *body = (const void *) mpdu + *offset; - static const enum ie_type ie_order[] = { - IE_TYPE_SSID, - IE_TYPE_SUPPORTED_RATES, - IE_TYPE_EXTENDED_SUPPORTED_RATES, - IE_TYPE_POWER_CAPABILITY, - IE_TYPE_SUPPORTED_CHANNELS, - IE_TYPE_RSN, - IE_TYPE_QOS_CAPABILITY, - IE_TYPE_RM_ENABLED_CAPABILITIES, - IE_TYPE_MOBILITY_DOMAIN, - IE_TYPE_FAST_BSS_TRANSITION, - IE_TYPE_RIC_DATA, - IE_TYPE_SUPPORTED_OPERATING_CLASSES, - IE_TYPE_HT_CAPABILITIES, - IE_TYPE_BSS_COEXISTENCE, - IE_TYPE_EXTENDED_CAPABILITIES, - IE_TYPE_QOS_TRAFFIC_CAPABILITY, - IE_TYPE_TIM_BROADCAST_REQUEST, - IE_TYPE_FMS_REQUEST, - IE_TYPE_DMS_REQUEST, - IE_TYPE_INTERWORKING, - IE_TYPE_MULTIBAND, - IE_TYPE_DMG_CAPABILITIES, - IE_TYPE_MULTIPLE_MAC_SUBLAYERS, - IE_TYPE_VHT_CAPABILITIES, - IE_TYPE_OPERATING_MODE_NOTIFICATION, - IE_TYPE_FILS_SESSION, - IE_TYPE_FILS_PUBLIC_KEY, - IE_TYPE_FILS_KEY_CONFIRMATION, - IE_TYPE_FILS_HLP_CONTAINER, - IE_TYPE_FILS_IP_ADDRESS, - IE_TYPE_TWT, - IE_TYPE_AID_REQUEST, - IE_TYPE_S1G_CAPABILITIES, - IE_TYPE_EL_OPERATION, - IE_TYPE_BSS_MAX_IDLE_PERIOD, - IE_TYPE_S1G_RELAY, - IE_TYPE_HEADER_COMPRESSION, - IE_TYPE_MAD, - IE_TYPE_REACHABLE_ADDRESS, - IE_TYPE_S1G_RELAY_ACTIVATION, - IE_TYPE_CDMG_CAPABILITIES, - IE_TYPE_CMMG_CAPABILITIES, - IE_TYPE_OCI, - IE_TYPE_GLK_GCR_PARAMETER_SET, - IE_TYPE_RSNX, - IE_TYPE_SUPPLEMENTAL_CLASS_2_CAPABILITIES, - IE_TYPE_MSCS_DESCRIPTOR, - IE_TYPE_VENDOR_SPECIFIC, - }; if (len < *offset + (int) sizeof(struct mmpdu_reassociation_request)) return false; *offset += sizeof(struct mmpdu_reassociation_request); - return validate_mgmt_ies(body->ies, len - *offset, ie_order, - L_ARRAY_SIZE(ie_order)); + return validate_mgmt_ies(body->ies, len - *offset, + reassociation_request_ie_order, + L_ARRAY_SIZE(reassociation_request_ie_order)); } -/* 802.11-2020 section 9.3.3.8 */ static bool validate_reassociation_response_mmpdu( const struct mmpdu_header *mpdu, int len, int *offset) { const struct mmpdu_reassociation_response *body = (const void *) mpdu + *offset; - static const enum ie_type ie_order[] = { - IE_TYPE_AID, - IE_TYPE_SUPPORTED_RATES, - IE_TYPE_EXTENDED_SUPPORTED_RATES, - IE_TYPE_EDCA_PARAMETER_SET, - IE_TYPE_RCPI, - IE_TYPE_RSNI, - IE_TYPE_RM_ENABLED_CAPABILITIES, - IE_TYPE_RSN, - IE_TYPE_MOBILITY_DOMAIN, - IE_TYPE_FAST_BSS_TRANSITION, - IE_TYPE_RIC_DATA, - IE_TYPE_DSE_REGISTERED_LOCATION, - IE_TYPE_TIMEOUT_INTERVAL, - IE_TYPE_HT_CAPABILITIES, - IE_TYPE_HT_OPERATION, - IE_TYPE_BSS_COEXISTENCE, - IE_TYPE_OVERLAPPING_BSS_SCAN_PARAMETERS, - IE_TYPE_EXTENDED_CAPABILITIES, - IE_TYPE_BSS_MAX_IDLE_PERIOD, - IE_TYPE_TIM_BROADCAST_RESPONSE, - IE_TYPE_FMS_RESPONSE, - IE_TYPE_DMS_RESPONSE, - IE_TYPE_QOS_MAP_SET, - IE_TYPE_QMF_POLICY, - IE_TYPE_MULTIBAND, - IE_TYPE_DMG_CAPABILITIES, - IE_TYPE_DMG_OPERATION, - IE_TYPE_MULTIPLE_MAC_SUBLAYERS, - IE_TYPE_NEIGHBOR_REPORT, - IE_TYPE_VHT_CAPABILITIES, - IE_TYPE_VHT_OPERATION, - IE_TYPE_OPERATING_MODE_NOTIFICATION, - IE_TYPE_FUTURE_CHANNEL_GUIDANCE, - IE_TYPE_FILS_SESSION, - IE_TYPE_FILS_PUBLIC_KEY, - IE_TYPE_FILS_KEY_CONFIRMATION, - IE_TYPE_FILS_HLP_CONTAINER, - IE_TYPE_FILS_IP_ADDRESS, - IE_TYPE_KEY_DELIVERY, - IE_TYPE_S1G_SECTOR_OPERATION, - IE_TYPE_TWT, - IE_TYPE_TSF_TIMER_ACCURACY, - IE_TYPE_S1G_CAPABILITIES, - IE_TYPE_S1G_OPERATION, - IE_TYPE_AID_RESPONSE, - IE_TYPE_SECTORIZED_GROUP_ID_LIST, - IE_TYPE_S1G_RELAY, - IE_TYPE_HEADER_COMPRESSION, - IE_TYPE_SST_OPERATION, - IE_TYPE_MAD, - IE_TYPE_S1G_RELAY_ACTIVATION, - IE_TYPE_CDMG_CAPABILITIES, - IE_TYPE_CMMG_CAPABILITIES, - IE_TYPE_CMMG_OPERATION, - IE_TYPE_OCI, - IE_TYPE_GLK_GCR_PARAMETER_SET, - IE_TYPE_RSNX, - IE_TYPE_MSCS_DESCRIPTOR, - IE_TYPE_VENDOR_SPECIFIC, - }; if (len < *offset + (int) sizeof(struct mmpdu_reassociation_response)) return false; *offset += sizeof(struct mmpdu_reassociation_response); - return validate_mgmt_ies(body->ies, len - *offset, ie_order, - L_ARRAY_SIZE(ie_order)); + return validate_mgmt_ies(body->ies, len - *offset, + reassociation_response_ie_order, + L_ARRAY_SIZE(reassociation_response_ie_order)); } -/* 802.11-2020 section 9.3.3.9 */ static bool validate_probe_request_mmpdu(const struct mmpdu_header *mpdu, int len, int *offset) { const struct mmpdu_probe_request *body = (const void *) mpdu + *offset; - static const enum ie_type ie_order[] = { - IE_TYPE_SSID, - IE_TYPE_SUPPORTED_RATES, - IE_TYPE_REQUEST, - IE_TYPE_EXTENDED_SUPPORTED_RATES, - IE_TYPE_DSSS_PARAMETER_SET, - IE_TYPE_SUPPORTED_OPERATING_CLASSES, - IE_TYPE_HT_CAPABILITIES, - IE_TYPE_BSS_COEXISTENCE, - IE_TYPE_EXTENDED_CAPABILITIES, - IE_TYPE_SSID_LIST, - IE_TYPE_CHANNEL_USAGE, - IE_TYPE_INTERWORKING, - IE_TYPE_MESH_ID, - IE_TYPE_MULTIBAND, - IE_TYPE_DMG_CAPABILITIES, - IE_TYPE_MULTIPLE_MAC_SUBLAYERS, - IE_TYPE_VHT_CAPABILITIES, - IE_TYPE_ESTIMATED_SERVICE_PARAMETERS, - IE_TYPE_EXTENDED_REQUEST, - IE_TYPE_FILS_REQUEST_PARAMETERS, - IE_TYPE_AP_CSN, - IE_TYPE_CHANGE_SEQUENCE, - IE_TYPE_S1G_RELAY_DISCOVERY, - IE_TYPE_PV1_PROBE_RESPONSE_OPTION, - IE_TYPE_S1G_CAPABILITIES, - IE_TYPE_EL_OPERATION, - IE_TYPE_MAD, - IE_TYPE_VENDOR_SPECIFIC_REQUEST, - IE_TYPE_CDMG_CAPABILITIES, - IE_TYPE_CLUSTER_PROBE, - IE_TYPE_CMMG_CAPABILITIES, - IE_TYPE_ESTIMATED_SERVICE_PARAMETERS_OUT, - IE_TYPE_SUPPLEMENTAL_CLASS_2_CAPABILITIES, - IE_TYPE_VENDOR_SPECIFIC, - }; if (len < *offset + (int) sizeof(struct mmpdu_probe_request)) return false; *offset += sizeof(struct mmpdu_probe_request); - return validate_mgmt_ies(body->ies, len - *offset, ie_order, - L_ARRAY_SIZE(ie_order)); + return validate_mgmt_ies(body->ies, len - *offset, + probe_request_ie_order, + L_ARRAY_SIZE(probe_request_ie_order)); } /* 802.11-2016 section 9.3.3.11 */ @@ -782,3 +795,80 @@ const void *mmpdu_body(const struct mmpdu_header *mmpdu) { return ((const uint8_t *) mmpdu + mmpdu_header_len(mmpdu)); } + +struct ie_sort_info { + const enum ie_type *ie_order; + size_t n_elem; +}; + +static struct ie_sort_info sortinfo; + +static unsigned int ie_order_find(const struct iovec *iov) +{ + const uint8_t *ie = iov->iov_base; + enum ie_type type = ie[0]; + unsigned int i; + + if (ie[0] == IE_TYPE_EXTENSION) + type = 256 + ie[2]; + + for (i = 0; i < sortinfo.n_elem; i++) { + if (sortinfo.ie_order[i] != type) + continue; + + return i; + } + + return UINT_MAX; +} + +static int ie_order_compare(const void *a, const void *b) +{ + const struct iovec *iova = a; + const struct iovec *iovb = b; + unsigned int ia = ie_order_find(iova); + unsigned int ib = ie_order_find(iovb); + + if (ia < ib) + return -1; + if (ia > ib) + return 1; + return 0; +} + +int mpdu_sort_ies(enum mpdu_management_subtype type, + struct iovec *iov, size_t n_iovs) +{ + switch (type) { + case MPDU_MANAGEMENT_SUBTYPE_ASSOCIATION_REQUEST: + sortinfo.ie_order = association_request_ie_order; + sortinfo.n_elem = L_ARRAY_SIZE(association_request_ie_order); + break; + case MPDU_MANAGEMENT_SUBTYPE_ASSOCIATION_RESPONSE: + sortinfo.ie_order = association_response_ie_order; + sortinfo.n_elem = L_ARRAY_SIZE(association_response_ie_order); + break; + case MPDU_MANAGEMENT_SUBTYPE_REASSOCIATION_REQUEST: + sortinfo.ie_order = reassociation_request_ie_order; + sortinfo.n_elem = L_ARRAY_SIZE(reassociation_request_ie_order); + break; + case MPDU_MANAGEMENT_SUBTYPE_REASSOCIATION_RESPONSE: + sortinfo.ie_order = reassociation_response_ie_order; + sortinfo.n_elem = L_ARRAY_SIZE(reassociation_response_ie_order); + break; + case MPDU_MANAGEMENT_SUBTYPE_PROBE_REQUEST: + sortinfo.ie_order = probe_request_ie_order; + sortinfo.n_elem = L_ARRAY_SIZE(probe_request_ie_order); + break; + default: + return -ENOTSUP; + } + + /* + * qsort_r would be better, but it is still missing on some non-glibc + * implementations, and since iwd is not multi-threaded, qsort is + * just as good + */ + qsort(iov, n_iovs, sizeof(struct iovec), ie_order_compare); + return 0; +} diff --git a/src/mpdu.h b/src/mpdu.h index 17015c7a..98c264f9 100644 --- a/src/mpdu.h +++ b/src/mpdu.h @@ -411,3 +411,6 @@ struct mmpdu_deauthentication { const struct mmpdu_header *mpdu_validate(const uint8_t *frame, int len); const void *mmpdu_body(const struct mmpdu_header *mpdu); size_t mmpdu_header_len(const struct mmpdu_header *mmpdu); + +int mpdu_sort_ies(enum mpdu_management_subtype type, + struct iovec *iov, size_t n_iovs);