From 93701b4afe62a8e2ee96efc8ecb4dbcdf8306b3f Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 24 Dec 2018 23:56:25 +0200 Subject: [PATCH] tests: Allow TX/RX data test to use different frame length This is needed for MACsec test cases with a bit shorter MTU. Signed-off-by: Jouni Malinen --- tests/hwsim/hwsim_utils.py | 39 +++++++++++++++++++++++++--- wpa_supplicant/ctrl_iface.c | 52 ++++++++++++++++++++++++++----------- 2 files changed, 73 insertions(+), 18 deletions(-) diff --git a/tests/hwsim/hwsim_utils.py b/tests/hwsim/hwsim_utils.py index 06d59c4f6..84f87a5a3 100644 --- a/tests/hwsim/hwsim_utils.py +++ b/tests/hwsim/hwsim_utils.py @@ -13,7 +13,8 @@ from wpasupplicant import WpaSupplicant def run_connectivity_test(dev1, dev2, tos, dev1group=False, dev2group=False, ifname1=None, ifname2=None, config=True, timeout=5, - multicast_to_unicast=False, broadcast=True): + multicast_to_unicast=False, broadcast=True, + send_len=None): addr1 = dev1.own_addr() if not dev1group and isinstance(dev1, WpaSupplicant): addr = dev1.get_driver_status_field('addr') @@ -57,6 +58,8 @@ def run_connectivity_test(dev1, dev2, tos, dev1group=False, dev2group=False, raise Exception("Failed to enable data test functionality") cmd = "DATA_TEST_TX {} {} {}".format(addr2, addr1, tos) + if send_len is not None: + cmd += " len=" + str(send_len) if dev1group: dev1.group_request(cmd) else: @@ -69,9 +72,17 @@ def run_connectivity_test(dev1, dev2, tos, dev1group=False, dev2group=False, raise Exception("dev1->dev2 unicast data delivery failed") if "DATA-TEST-RX {} {}".format(addr2, addr1) not in ev: raise Exception("Unexpected dev1->dev2 unicast data result") + if send_len is not None: + if " len=" + str(send_len) not in ev: + raise Exception("Unexpected dev1->dev2 unicast data length") + else: + if " len=" in ev: + raise Exception("Unexpected dev1->dev2 unicast data length") if broadcast: cmd = "DATA_TEST_TX ff:ff:ff:ff:ff:ff {} {}".format(addr1, tos) + if send_len is not None: + cmd += " len=" + str(send_len) for i in xrange(broadcast_retry_c): try: if dev1group: @@ -87,12 +98,20 @@ def run_connectivity_test(dev1, dev2, tos, dev1group=False, dev2group=False, raise Exception("dev1->dev2 broadcast data delivery failed") if "DATA-TEST-RX ff:ff:ff:ff:ff:ff {}".format(addr1) not in ev: raise Exception("Unexpected dev1->dev2 broadcast data result") + if send_len is not None: + if " len=" + str(send_len) not in ev: + raise Exception("Unexpected dev1->dev2 broadcast data length") + else: + if " len=" in ev: + raise Exception("Unexpected dev1->dev2 broadcast data length") break except Exception as e: if i == broadcast_retry_c - 1: raise cmd = "DATA_TEST_TX {} {} {}".format(addr1, addr2, tos) + if send_len is not None: + cmd += " len=" + str(send_len) if dev2group: dev2.group_request(cmd) else: @@ -105,9 +124,17 @@ def run_connectivity_test(dev1, dev2, tos, dev1group=False, dev2group=False, raise Exception("dev2->dev1 unicast data delivery failed") if "DATA-TEST-RX {} {}".format(addr1, addr2) not in ev: raise Exception("Unexpected dev2->dev1 unicast data result") + if send_len is not None: + if " len=" + str(send_len) not in ev: + raise Exception("Unexpected dev2->dev1 unicast data length") + else: + if " len=" in ev: + raise Exception("Unexpected dev2->dev1 unicast data length") if broadcast: cmd = "DATA_TEST_TX ff:ff:ff:ff:ff:ff {} {}".format(addr2, tos) + if send_len is not None: + cmd += " len=" + str(send_len) for i in xrange(broadcast_retry_c): try: if dev2group: @@ -129,6 +156,12 @@ def run_connectivity_test(dev1, dev2, tos, dev1group=False, dev2group=False, else: if "DATA-TEST-RX ff:ff:ff:ff:ff:ff {}".format(addr2) not in ev: raise Exception("Unexpected dev2->dev1 broadcast data result") + if send_len is not None: + if " len=" + str(send_len) not in ev: + raise Exception("Unexpected dev2->dev1 broadcast data length") + else: + if " len=" in ev: + raise Exception("Unexpected dev2->dev1 broadcast data length") break except Exception as e: if i == broadcast_retry_c - 1: @@ -148,7 +181,7 @@ def test_connectivity(dev1, dev2, dscp=None, tos=None, max_tries=1, dev1group=False, dev2group=False, ifname1=None, ifname2=None, config=True, timeout=5, multicast_to_unicast=False, success_expected=True, - broadcast=True): + broadcast=True, send_len=None): if dscp: tos = dscp << 2 if not tos: @@ -162,7 +195,7 @@ def test_connectivity(dev1, dev2, dscp=None, tos=None, max_tries=1, ifname1, ifname2, config=config, timeout=timeout, multicast_to_unicast=multicast_to_unicast, - broadcast=broadcast) + broadcast=broadcast, send_len=send_len) success = True break except Exception, e: diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index ebc232f7f..591d30f22 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -8779,26 +8779,39 @@ static void wpas_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf, struct iphdr ip; const u8 *pos; unsigned int i; + char extra[30]; - if (len != HWSIM_PACKETLEN) + if (len < sizeof(*eth) + sizeof(ip) || len > HWSIM_PACKETLEN) { + wpa_printf(MSG_DEBUG, + "test data: RX - ignore unexpected length %d", + (int) len); return; + } eth = (const struct ether_header *) buf; os_memcpy(&ip, eth + 1, sizeof(ip)); pos = &buf[sizeof(*eth) + sizeof(ip)]; if (ip.ihl != 5 || ip.version != 4 || - ntohs(ip.tot_len) != HWSIM_IP_LEN) + ntohs(ip.tot_len) > HWSIM_IP_LEN) { + wpa_printf(MSG_DEBUG, + "test data: RX - ignore unexpect IP header"); return; - - for (i = 0; i < HWSIM_IP_LEN - sizeof(ip); i++) { - if (*pos != (u8) i) - return; - pos++; } - wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR, - MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost)); + for (i = 0; i < ntohs(ip.tot_len) - sizeof(ip); i++) { + if (*pos != (u8) i) { + wpa_printf(MSG_DEBUG, + "test data: RX - ignore mismatching payload"); + return; + } + pos++; + } + extra[0] = '\0'; + if (ntohs(ip.tot_len) != HWSIM_IP_LEN) + os_snprintf(extra, sizeof(extra), " len=%d", ntohs(ip.tot_len)); + wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR "%s", + MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost), extra); } @@ -8842,7 +8855,7 @@ static int wpas_ctrl_iface_data_test_config(struct wpa_supplicant *wpa_s, static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) { u8 dst[ETH_ALEN], src[ETH_ALEN]; - char *pos; + char *pos, *pos2; int used; long int val; u8 tos; @@ -8851,11 +8864,12 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) struct iphdr *ip; u8 *dpos; unsigned int i; + size_t send_len = HWSIM_IP_LEN; if (wpa_s->l2_test == NULL) return -1; - /* format: */ + /* format: [len=] */ pos = cmd; used = hwaddr_aton2(pos, dst); @@ -8869,11 +8883,19 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) return -1; pos += used; - val = strtol(pos, NULL, 0); + val = strtol(pos, &pos2, 0); if (val < 0 || val > 0xff) return -1; tos = val; + pos = os_strstr(pos2, " len="); + if (pos) { + i = atoi(pos + 5); + if (i < sizeof(*ip) || i > HWSIM_IP_LEN) + return -1; + send_len = i; + } + eth = (struct ether_header *) &buf[2]; os_memcpy(eth->ether_dhost, dst, ETH_ALEN); os_memcpy(eth->ether_shost, src, ETH_ALEN); @@ -8884,17 +8906,17 @@ static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd) ip->version = 4; ip->ttl = 64; ip->tos = tos; - ip->tot_len = htons(HWSIM_IP_LEN); + ip->tot_len = htons(send_len); ip->protocol = 1; ip->saddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1); ip->daddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2); ip->check = ipv4_hdr_checksum(ip, sizeof(*ip)); dpos = (u8 *) (ip + 1); - for (i = 0; i < HWSIM_IP_LEN - sizeof(*ip); i++) + for (i = 0; i < send_len - sizeof(*ip); i++) *dpos++ = i; if (l2_packet_send(wpa_s->l2_test, dst, ETHERTYPE_IP, &buf[2], - HWSIM_PACKETLEN) < 0) + sizeof(struct ether_header) + send_len) < 0) return -1; wpa_dbg(wpa_s, MSG_DEBUG, "test data: TX dst=" MACSTR " src=" MACSTR