diff --git a/tests/net/igmp/src/main.c b/tests/net/igmp/src/main.c index fb098b46a03..4881c6b91fe 100644 --- a/tests/net/igmp/src/main.c +++ b/tests/net/igmp/src/main.c @@ -45,6 +45,24 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_IPV4_LOG_LEVEL); #define DBG(fmt, ...) #endif +static const unsigned char igmp_v2_query[] = { + /* IPv4 header */ + 0x46, 0xc0, 0x00, 0x20, 0x1b, 0x58, 0x00, 0x00, 0x01, 0x02, 0x66, 0x79, + 0xc0, 0x00, 0x02, 0x45, 0xe0, 0x00, 0x00, 0x01, 0x94, 0x04, 0x00, 0x00, + + /* IGMP header */ + 0x11, 0xff, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const unsigned char igmp_v3_query[] = { + /* IPv4 header */ + 0x46, 0xc0, 0x00, 0x24, 0xac, 0x72, 0x00, 0x00, 0x01, 0x02, 0xd5, 0x5a, + 0xc0, 0x00, 0x02, 0x45, 0xe0, 0x00, 0x00, 0x01, 0x94, 0x04, 0x00, 0x00, + + /* IGMP header */ + 0x11, 0x64, 0xec, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7d, 0x00, 0x00, +}; + static struct in_addr my_addr = { { { 192, 0, 2, 1 } } }; static struct in_addr mcast_addr = { { { 224, 0, 2, 63 } } }; static struct in_addr any_addr = INADDR_ANY_INIT; @@ -56,6 +74,8 @@ static bool is_join_msg_ok; static bool is_leave_msg_ok; static bool is_query_received; static bool is_report_sent; +static bool is_igmpv2_query_sent; +static bool is_igmpv3_query_sent; static bool ignore_already; K_SEM_DEFINE(wait_data, 0, UINT_MAX); @@ -151,8 +171,8 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt) k_sem_give(&wait_data); } else if (igmp_header->type == NET_IPV4_IGMP_REPORT_V2) { NET_DBG("Received v2 report...."); - zassert_false(IS_ENABLED(CONFIG_NET_IPV4_IGMPV3), - "Wrong IGMP report received (IGMPv2)"); + zassert_true(!IS_ENABLED(CONFIG_NET_IPV4_IGMPV3) || is_igmpv2_query_sent, + "Wrong IGMP report received (IGMPv2)"); is_join_msg_ok = true; is_report_sent = true; k_sem_give(&wait_data); @@ -160,6 +180,7 @@ static int tester_send(const struct device *dev, struct net_pkt *pkt) NET_DBG("Received v3 report...."); zassert_true(IS_ENABLED(CONFIG_NET_IPV4_IGMPV3), "Wrong IGMP report received (IGMPv3)"); + zassert_false(is_igmpv2_query_sent, "IGMPv3 response to IGMPv2 request"); #if defined(CONFIG_NET_IPV4_IGMPV3) zassert_true(ntohs(igmp_header->groups_len) == 1, @@ -285,6 +306,24 @@ static void igmp_teardown(void *dummy) net_if_ipv4_addr_rm(net_iface, &my_addr); } +static struct net_pkt *prepare_igmp_query(struct net_if *iface, bool is_igmpv3) +{ + struct net_pkt *pkt; + + const unsigned char *igmp_query = is_igmpv3 ? igmp_v3_query : igmp_v2_query; + size_t igmp_query_size = is_igmpv3 ? sizeof(igmp_v3_query) : sizeof(igmp_v2_query); + + pkt = net_pkt_alloc_with_buffer(iface, igmp_query_size, AF_INET, IPPROTO_IGMP, K_FOREVER); + zassert_not_null(pkt, "Failed to allocate buffer"); + + zassert_ok(net_pkt_write(pkt, igmp_query, igmp_query_size)); + + net_pkt_set_overwrite(pkt, true); + net_pkt_cursor_init(pkt); + + return pkt; +} + static void join_group(void) { int ret; @@ -559,4 +598,47 @@ ZTEST_USER(net_igmp, test_socket_catch_join_with_index) socket_leave_group_with_index(&my_addr); } +static void igmp_send_query(bool is_imgpv3) +{ + struct net_pkt *pkt; + + is_report_sent = false; + is_join_msg_ok = false; + + is_igmpv2_query_sent = false; + is_igmpv3_query_sent = false; + + /* Joining group first to get reply on query*/ + join_group(); + + is_igmpv2_query_sent = !is_imgpv3; + is_igmpv3_query_sent = is_imgpv3; + + pkt = prepare_igmp_query(net_iface, is_imgpv3); + zassert_not_null(pkt, "IGMPv2 query packet prep failed"); + + zassert_equal(net_ipv4_input(pkt, false), NET_OK, "Failed to send"); + + zassert_ok(k_sem_take(&wait_data, K_MSEC(WAIT_TIME)), "Timeout while waiting query event"); + + zassert_true(is_report_sent, "Did not catch query event"); + + zassert_true(is_join_msg_ok, "Join msg invalid"); + + is_igmpv2_query_sent = false; + is_igmpv3_query_sent = false; + + leave_group(); +} + +ZTEST_USER(net_igmp, test_igmpv3_query) +{ + igmp_send_query(true); +} + +ZTEST_USER(net_igmp, test_igmpv2_query) +{ + igmp_send_query(false); +} + ZTEST_SUITE(net_igmp, NULL, igmp_setup, NULL, NULL, igmp_teardown);