diff --git a/src/1905_tlvs.h b/src/1905_tlvs.h index 88c5faff03d0b861447da9f82bf8931170df0a6a..9e1239d03d1a7d0f797b40a25f6d260b365c2d9c 100644 --- a/src/1905_tlvs.h +++ b/src/1905_tlvs.h @@ -126,6 +126,7 @@ #define IEEE80211_ROLE_UNKNOWN (0xff) + typedef uint8_t macaddr_t[6]; diff --git a/src/cmdu.c b/src/cmdu.c index 1a46b62f8b4aceb7cd1fe6ba6367529c44a543e6..dd5c69b228a1834e84b070b5c70e192a83137a69 100644 --- a/src/cmdu.c +++ b/src/cmdu.c @@ -126,6 +126,47 @@ uint16_t tlv_total_length(struct tlv *t) return tlv_length(t) + 3; } +static size_t tlv_minsize(uint8_t type) +{ + size_t sizeof_tlv[] = { + [TLV_TYPE_END_OF_MESSAGE] = sizeof(struct tlv_eom), + [TLV_TYPE_AL_MAC_ADDRESS_TYPE] = sizeof(struct tlv_aladdr), + [TLV_TYPE_MAC_ADDRESS_TYPE] = sizeof(struct tlv_macaddr), + [TLV_TYPE_DEVICE_INFORMATION_TYPE] = sizeof(struct tlv_device_info), + [TLV_TYPE_DEVICE_BRIDGING_CAPABILITIES] = sizeof(struct tlv_device_bridge_caps), + [TLV_TYPE_NON_1905_NEIGHBOR_DEVICE_LIST] = sizeof(struct tlv_non1905_neighbor), + [TLV_TYPE_NEIGHBOR_DEVICE_LIST] = sizeof(struct tlv_1905neighbor), + [TLV_TYPE_LINK_METRIC_QUERY] = sizeof(struct tlv_linkmetric_query), + [TLV_TYPE_TRANSMITTER_LINK_METRIC] = sizeof(struct tlv_tx_linkmetric), + [TLV_TYPE_RECEIVER_LINK_METRIC] = sizeof(struct tlv_rx_linkmetric), + [TLV_TYPE_VENDOR_SPECIFIC] = sizeof(struct tlv_vendor_specific), + [TLV_TYPE_LINK_METRIC_RESULT_CODE] = sizeof(struct tlv_linkmetric_result), + [TLV_TYPE_SEARCHED_ROLE] = sizeof(struct tlv_searched_role), + [TLV_TYPE_AUTOCONFIG_FREQ_BAND] = sizeof(struct tlv_autoconfig_band), + [TLV_TYPE_SUPPORTED_ROLE] = sizeof(struct tlv_supported_role), + [TLV_TYPE_SUPPORTED_FREQ_BAND] = sizeof(struct tlv_supported_band), + [TLV_TYPE_WSC] = sizeof(struct tlv_wsc), + [TLV_TYPE_PUSH_BUTTON_EVENT_NOTIFICATION] = sizeof(struct tlv_pbc_notification), + [TLV_TYPE_PUSH_BUTTON_JOIN_NOTIFICATION] = sizeof(struct tlv_pbc_join_notification), + [TLV_TYPE_GENERIC_PHY_DEVICE_INFORMATION] = sizeof(struct tlv_generic_phy_devinfo), + [TLV_TYPE_DEVICE_IDENTIFICATION] = sizeof(struct tlv_device_identification), + [TLV_TYPE_CONTROL_URL] = sizeof(struct tlv_control_url), + [TLV_TYPE_IPV4] = sizeof(struct tlv_ipv4), + [TLV_TYPE_IPV6] = sizeof(struct tlv_ipv6), + [TLV_TYPE_GENERIC_PHY_EVENT_NOTIFICATION] = sizeof(struct tlv_pbc_generic_phy_notification), + [TLV_TYPE_1905_PROFILE_VERSION] = sizeof(struct tlv_1905_profile), + [TLV_TYPE_POWER_OFF_INTERFACE] = sizeof(struct tlv_power_off), + [TLV_TYPE_INTERFACE_POWER_CHANGE_INFORMATION] = sizeof(struct tlv_powerchange_request), + [TLV_TYPE_INTERFACE_POWER_CHANGE_STATUS] = sizeof(struct tlv_powerchange_status), + [TLV_TYPE_L2_NEIGHBOR_DEVICE] = sizeof(struct tlv_l2_neighbor), + }; + + if (type >= TLV_TYPE_END_OF_MESSAGE && type <= TLV_TYPE_L2_NEIGHBOR_DEVICE) + return sizeof_tlv[type]; + + return 0; +} + int is_cmdu_type_valid(uint16_t type) { return (type >= CMDU_TYPE_TOPOLOGY_DISCOVERY && @@ -554,6 +595,9 @@ int cmdu_parse_tlv_single(struct cmdu_buff *c, struct tlv *tv[], if (policy->maxlen > 0 && tlv_length(t) > policy->maxlen) continue; + if (tlv_length(t) < tlv_minsize(t)) + continue; + if (tv[0] && policy->present == TLV_PRESENT_ONE) break; @@ -598,6 +642,9 @@ int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[][16], tlv_length(t) > policy[i].maxlen) continue; + if (tlv_length(t) < tlv_minsize(t)) + continue; + if (tv[i][0]) { if (policy[i].present == TLV_PRESENT_ONE) continue;