diff --git a/src/cmdu_validate.c b/src/cmdu_validate.c
index db88f3d5342268bdf7b5188014a97befb769bca9..13ba37367fe6e3fb814109f028f15f2d19dde9ae 100644
--- a/src/cmdu_validate.c
+++ b/src/cmdu_validate.c
@@ -208,7 +208,7 @@ static int validate_wsc_m2(uint8_t *m2, uint16_t m2_size)
{
uint8_t *data;
uint8_t *m2_end;
- bool ret = false;
+ bool ret = -1;
if (!m2 || !m2_size)
return -1;
@@ -227,17 +227,17 @@ static int validate_wsc_m2(uint8_t *m2, uint16_t m2_size)
if (data + attr_len > m2_end) {
dbg("%s: parse_wsc_m2 failed\n", __func__);
- ret = false;
+ ret = -1;
break;
}
if (attr_type == ATTR_MSG_TYPE) {
if (attr_len != 1) {
- ret = false;
+ ret = -1;
break;
}
if (*data == MSG_TYPE_M2)
- ret = true;
+ ret = 0;
}
data += attr_len;
@@ -247,6 +247,304 @@ static int validate_wsc_m2(uint8_t *m2, uint16_t m2_size)
return ret;
}
+/* Check WSC TLV (containing M2) */
+static int check_wsc_tlv(struct tlv *t)
+{
+ uint8_t *tv_data;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+ if (!tlv_len)
+ return -1;
+
+ tv_data = (uint8_t *)t->data;
+ if (!tv_data)
+ return -1;
+
+ return validate_wsc_m2(tv_data, tlv_len);
+}
+
+/* Check 1905.1 AL MAC address type TLV */
+static int check_al_mac_addr_type_tlv(struct tlv *t)
+{
+ uint8_t *tv_data;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* macaddr (6 bytes) */
+ if (tlv_len != 6)
+ return -1;
+
+ tv_data = (uint8_t *)t->data;
+ if (!tv_data)
+ return -1;
+
+ return 0;
+}
+
+/* Check AP Radio Indentifier TLV */
+static int check_ap_radio_dentifier_tlv(struct tlv *t)
+{
+ uint8_t *tv_data;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* bssid (6 bytes) */
+ if (tlv_len != 6)
+ return -1;
+
+ tv_data = (uint8_t *)t->data;
+ if (!tv_data)
+ return -1;
+
+ return 0;
+}
+
+/* Check Default 802.1Q Settings TLV */
+static int check_default_11q_settings_tlv(struct tlv *t)
+{
+ struct tlv_default_8021q_settings *tlv;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* pvid + pcp (3 bytes) */
+ if (tlv_len != sizeof(struct tlv_default_8021q_settings))
+ return -1;
+
+ tlv = (struct tlv_default_8021q_settings *)t->data;
+ if (!tlv)
+ return -1;
+
+ return 0;
+}
+
+/* Check SupportedFreqBand TLV */
+static int check_supported_band_tlv(struct tlv *t)
+{
+ struct tlv_supported_band *tlv;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* band (1 byte) */
+ if (tlv_len != sizeof(struct tlv_supported_band))
+ return -1;
+
+ tlv = (struct tlv_supported_band *)t->data;
+ if (!tlv)
+ return -1;
+
+ return 0;
+}
+
+/* Check SupportedRole TLV */
+static int check_supported_role_tlv(struct tlv *t)
+{
+ struct tlv_supported_role *tlv;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* role (1 byte) */
+ if (tlv_len != sizeof(struct tlv_supported_role))
+ return -1;
+
+ tlv = (struct tlv_supported_role *)t->data;
+ if (!tlv)
+ return -1;
+
+ return 0;
+}
+
+/* Check MultiAP Profile TLV */
+static int check_map_profile_tlv(struct tlv *t)
+{
+ struct tlv_map_profile *tlv;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* profile (1 byte) */
+ if (tlv_len != sizeof(struct tlv_map_profile))
+ return -1;
+
+ tlv = (struct tlv_map_profile *)t->data;
+ if (!tlv)
+ return -1;
+
+ return 0;
+}
+
+/* Check SearchedRole TLV */
+static int check_searched_role_tlv(struct tlv *t)
+{
+ struct tlv_searched_role *tlv;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* role (1 byte) */
+ if (tlv_len != sizeof(struct tlv_searched_role))
+ return -1;
+
+ tlv = (struct tlv_searched_role *)t->data;
+ if (!tlv)
+ return -1;
+
+ return 0;
+}
+
+/* Check AutoconfigFreqBand TLV */
+static int check_autoconfig_freq_band_tlv(struct tlv *t)
+{
+ struct tlv_autoconfig_band *tlv;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+
+ /* band (1 byte) */
+ if (tlv_len != sizeof(struct tlv_autoconfig_band))
+ return -1;
+
+ tlv = (struct tlv_autoconfig_band *)t->data;
+ if (!tlv)
+ return -1;
+
+ return 0;
+}
+
+/* Check Traffic Separation Policy TLV */
+static int check_traffic_separation_policy_tlv(struct tlv *t)
+{
+ int i, offset = 0;
+ uint8_t num_ssid;
+ uint8_t *tv_data;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+ /* at least 1 byte: num_ssid */
+ if (tlv_len < 1)
+ return -1;
+
+ tv_data = (uint8_t *)t->data;
+ if (!tv_data)
+ return -1;
+
+ num_ssid = tv_data[offset++];
+
+ for (i = 0; i < num_ssid; i++) {
+ int ssid_len;
+
+ /* ssid_len (1 byte) */
+ if (offset + 1 > tlv_len)
+ return -1;
+ ssid_len = tv_data[offset++];
+
+ /* ssid (ssid_len bytes) */
+ if (offset + ssid_len > tlv_len)
+ return -1;
+ offset += ssid_len;
+
+ /* vid (2 bytes) */
+ if (offset + 2 > tlv_len)
+ return -1;
+ offset += 2;
+ }
+
+ return 0;
+}
+
+/* Check SupportedService TLV */
+static int check_supported_service_tlv(struct tlv *t)
+{
+ int offset = 0;
+ uint8_t num_services;
+ uint8_t *tv_data;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+ /* at least 1 byte: num_services */
+ if (tlv_len < 1)
+ return -1;
+
+ tv_data = (uint8_t *)t->data;
+ if (!tv_data)
+ return -1;
+
+ num_services = tv_data[offset++];
+
+ /* services (num_services bytes) */
+ if (offset + num_services > tlv_len)
+ return -1;
+
+ return 0;
+}
+
+/* Check SearchedService TLV */
+static int check_searched_service_tlv(struct tlv *t)
+{
+ int offset = 0;
+ uint8_t num_services;
+ uint8_t *tv_data;
+ uint16_t tlv_len;
+
+ if (!t)
+ return -1;
+
+ tlv_len = tlv_length(t);
+ /* at least 1 byte: num_services */
+ if (tlv_len < 1)
+ return -1;
+
+ tv_data = (uint8_t *)t->data;
+ if (!tv_data)
+ return -1;
+
+ num_services = tv_data[offset++];
+
+ /* services (num_services bytes) */
+ if (offset + num_services > tlv_len)
+ return -1;
+
+ return 0;
+}
+
bool validate_ap_autoconfig_wsc(struct cmdu_buff *cmdu, struct tlv *tv[][16])
{
struct tlv_policy a_policy[] = {
@@ -285,90 +583,21 @@ bool validate_ap_autoconfig_wsc(struct cmdu_buff *cmdu, struct tlv *tv[][16])
}
/* Parse Default 802.1Q Settings TLV */
- if (tv[0][0]) {
- struct tlv_default_8021q_settings *tlv;
- uint16_t tlv_len = tlv_length(tv[0][0]);
-
- if (tlv_len != sizeof(struct tlv_default_8021q_settings))
- return false;
-
- tlv = (struct tlv_default_8021q_settings *)tv[0][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_default_11q_settings_tlv(tv[0][0]))
+ return false;
/* Parse Traffic Separation Policy TLV */
- if (tv[1][0]) {
- int i, offset = 0;
- uint8_t *tv_data;
- uint8_t num_ssid;
- uint16_t tlv_len = tlv_length(tv[1][0]);
-
- if (!tlv_len)
- return false;
-
- tv_data = (uint8_t *)tv[1][0]->data;
- if (!tv_data)
- return false;
-
- /* num_ssid (1 byte) */
- if (offset + 1 > tlv_len)
- return false;
-
- num_ssid = tv_data[offset++];
-
- for (i = 0; i < num_ssid; i++) {
- int ssid_len;
-
- /* ssid_len (1 byte) */
- if (offset + 1 > tlv_len)
- return false;
-
- ssid_len = tv_data[offset++];
-
- /* ssid (ssid_len bytes) */
- if (offset + ssid_len > tlv_len)
- return false;
-
- offset += ssid_len;
-
- /* vid (2 bytes) */
- if (offset + 2 > tlv_len)
- return false;
-
- offset += 2;
- }
- }
+ if (check_traffic_separation_policy_tlv(tv[1][0]))
+ return false;
/* Parse AP Radio Identifier TLV */
- if (tv[2][0]) {
- uint8_t *tv_data;
- uint16_t tlv_len = tlv_length(tv[2][0]);
-
- /* bssid (6 bytes) */
- if (tlv_len != 6)
- return false;
-
- tv_data = (uint8_t *) tv[2][0]->data;
- if (!tv_data)
- return false;
- }
+ if (check_ap_radio_dentifier_tlv(tv[2][0]))
+ return false;
/* Parse WSC TLVs (containing M2) */
while (tv[3][num]) {
- uint8_t *tv_data;
- uint16_t tlv_len = tlv_length(tv[3][num]);
-
- if (!tlv_len)
+ if (check_wsc_tlv(tv[3][num]))
return false;
-
- tv_data = (uint8_t *) tv[3][num]->data;
- if (!tv_data)
- return false;
-
- if (!validate_wsc_m2(tv_data, tlv_len))
- return false;
-
num++;
}
@@ -424,114 +653,28 @@ bool validate_ap_autoconfig_search(struct cmdu_buff *cmdu, struct tlv *tv[][16])
}
/* Parse 1905.1 AL MAC address type TLV */
- if (tv[0][0]) {
- uint8_t *tv_data;
- uint16_t tlv_len = tlv_length(tv[0][0]);
-
- /* macaddr (6 bytes) */
- if (tlv_len != 6)
- return false;
-
- tv_data = (uint8_t *) tv[0][0]->data;
- if (!tv_data)
- return false;
- }
+ if (check_al_mac_addr_type_tlv(tv[0][0]))
+ return false;
/* Parse SearchedRole TLV */
- if (tv[1][0]) {
- struct tlv_searched_role *tlv;
- uint16_t tlv_len = tlv_length(tv[1][0]);
-
- /* role (1 byte) */
- if (tlv_len != sizeof(struct tlv_searched_role))
- return false;
-
- tlv = (struct tlv_searched_role *)tv[1][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_searched_role_tlv(tv[1][0]))
+ return false;
/* Parse AutoconfigFreqBand TLV */
- if (tv[2][0]) {
- struct tlv_autoconfig_band *tlv;
- uint16_t tlv_len = tlv_length(tv[2][0]);
-
- /* band (1 byte) */
- if (tlv_len != sizeof(struct tlv_autoconfig_band))
- return false;
-
- tlv = (struct tlv_autoconfig_band *)tv[2][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_autoconfig_freq_band_tlv(tv[2][0]))
+ return false;
/* Parse SupportedService TLV */
- if (tv[3][0]) {
- uint8_t *tv_data;
- uint8_t num_services;
- int offset = 0;
- uint16_t tlv_len = tlv_length(tv[3][0]);
-
- if (tlv_len < 1)
- return false;
-
- tv_data = (uint8_t *) tv[3][0]->data;
- if (!tv_data)
- return false;
-
- /* num_services (1 byte) */
- if (offset + 1 > tlv_len)
- return false;
-
- num_services = tv_data[offset];
-
- offset += 1;
-
- /* services (num_services bytes) */
- if (offset + num_services > tlv_len)
- return false;
- }
+ if (check_supported_service_tlv(tv[3][0]))
+ return false;
/* Parse SearchedService TLV */
- if (tv[4][0]) {
- uint8_t *tv_data;
- uint8_t num_services;
- int offset = 0;
- uint16_t tlv_len = tlv_length(tv[4][0]);
-
- if (tlv_len < 1)
- return false;
-
- tv_data = (uint8_t *) tv[4][0]->data;
- if (!tv_data)
- return false;
-
- /* num_services (1 byte) */
- if (offset + 1 > tlv_len)
- return false;
-
- num_services = tv_data[offset];
-
- offset += 1;
-
- /* services (num_services bytes) */
- if (offset + num_services > tlv_len)
- return false;
- }
+ if (check_searched_service_tlv(tv[4][0]))
+ return false;
/* Parse MultiAP Profile TLV */
- if (tv[5][0]) {
- struct tlv_map_profile *tlv;
- uint16_t tlv_len = tlv_length(tv[5][0]);
-
- /* profile (1 byte) */
- if (tlv_len != sizeof(struct tlv_map_profile))
- return false;
-
- tlv = (struct tlv_map_profile *)tv[5][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_map_profile_tlv(tv[5][0]))
+ return false;
return true;
}
@@ -576,73 +719,20 @@ bool validate_ap_autoconfig_response(struct cmdu_buff *cmdu, struct tlv *tv[][16
}
/* Parse SupportedRole TLV */
- if (tv[0][0]) {
- struct tlv_supported_role *tlv;
- uint16_t tlv_len = tlv_length(tv[0][0]);
-
- /* role (1 byte) */
- if (tlv_len != sizeof(struct tlv_supported_role))
- return false;
-
- tlv = (struct tlv_supported_role *)tv[0][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_supported_role_tlv(tv[0][0]))
+ return false;
/* Parse SupportedService TLV */
- if (tv[1][0]) {
- uint8_t *tv_data;
- uint8_t num_services;
- int offset = 0;
- uint16_t tlv_len = tlv_length(tv[1][0]);
-
- if (tlv_len < 1)
- return false;
-
- tv_data = (uint8_t *) tv[1][0]->data;
- if (!tv_data)
- return false;
-
- /* num_services (1 byte) */
- if (offset + 1 > tlv_len)
- return false;
-
- num_services = tv_data[offset];
-
- offset += 1;
-
- /* services (num_services bytes) */
- if (offset + num_services > tlv_len)
- return false;
- }
+ if (check_supported_service_tlv(tv[1][0]))
+ return false;
/* Parse MultiAP Profile TLV */
- if (tv[2][0]) {
- struct tlv_map_profile *tlv;
- uint16_t tlv_len = tlv_length(tv[2][0]);
-
- /* profile (1 byte) */
- if (tlv_len != sizeof(struct tlv_map_profile))
- return false;
-
- tlv = (struct tlv_map_profile *)tv[2][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_map_profile_tlv(tv[2][0]))
+ return false;
/* Parse SupportedFreqBand TLV */
- if (tv[3][0]) {
- struct tlv_supported_band *tlv;
- uint16_t tlv_len = tlv_length(tv[3][0]);
-
- /* band (1 byte) */
- if (tlv_len != sizeof(struct tlv_supported_band))
- return false;
-
- tlv = (struct tlv_supported_band *)tv[3][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_supported_band_tlv(tv[3][0]))
+ return false;
return true;
}
@@ -684,46 +774,16 @@ bool validate_ap_autoconfig_renew(struct cmdu_buff *cmdu, struct tlv *tv[][16])
}
/* Parse 1905.1 AL MAC address type TLV */
- if (tv[0][0]) {
- uint8_t *tv_data;
- uint16_t tlv_len = tlv_length(tv[0][0]);
-
- /* macaddr (6 bytes) */
- if (tlv_len != 6)
- return false;
-
- tv_data = (uint8_t *) tv[0][0]->data;
- if (!tv_data)
- return false;
- }
+ if (check_al_mac_addr_type_tlv(tv[0][0]))
+ return false;
/* Parse SupportedFreqBand TLV */
- if (tv[1][0]) {
- struct tlv_supported_band *tlv;
- uint16_t tlv_len = tlv_length(tv[1][0]);
-
- /* band (1 byte) */
- if (tlv_len != sizeof(struct tlv_supported_band))
- return false;
-
- tlv = (struct tlv_supported_band *)tv[1][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_supported_band_tlv(tv[1][0]))
+ return false;
/* Parse SupportedRole TLV */
- if (tv[2][0]) {
- struct tlv_supported_role *tlv;
- uint16_t tlv_len = tlv_length(tv[2][0]);
-
- /* role (1 byte) */
- if (tlv_len != sizeof(struct tlv_supported_role))
- return false;
-
- tlv = (struct tlv_supported_role *)tv[2][0]->data;
- if (!tlv)
- return false;
- }
+ if (check_supported_role_tlv(tv[2][0]))
+ return false;
return true;
}