Test for setting socket option IP_MULTICAST_IF using struct ip_mreqn is buggy.
System call setsockopt() can use both in_addr and ip_mreqn structs but getsockopt()
returns struct in_addr only. Therefore the test failed because the size
of the passed and returned structure did not match.
I added second function test_sockopt_value_ext() that takes additional two
parameters that are expected when getsockopt() is called.
The former test_sockopt_value() was changed to a wrapper of the new
function test_sockopt_value_ext().
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
---
test_tools/multicast/offline/sockopt_if.c | 10 ++++++----
test_tools/multicast/sockopt_utils.h | 16 ++++++++++++++--
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/test_tools/multicast/offline/sockopt_if.c
b/test_tools/multicast/offline/sockopt_if.c
index 2396629..a6c9534 100644
--- a/test_tools/multicast/offline/sockopt_if.c
+++ b/test_tools/multicast/offline/sockopt_if.c
@@ -39,14 +39,16 @@ void test_if()
struct ip_mreqn mreqn;
mreqn.imr_multiaddr.s_addr = inet_addr("239.1.2.3");
mreqn.imr_address.s_addr = INADDR_ANY;
+ address.s_addr = INADDR_ANY;
mreqn.imr_ifindex = 0;
- test_sockopt_value("IP_MULTICAST_IF set to INADDR_ANY",
- IP_MULTICAST_IF, &mreqn, sizeof(mreqn));
+ test_sockopt_value_ext("IP_MULTICAST_IF set to INADDR_ANY mreqn",
+ IP_MULTICAST_IF, &mreqn, sizeof(mreqn), &address, size);
mreqn.imr_address.s_addr = inet_addr("127.0.0.1");
- test_sockopt_value("IP_MULTICAST_IF set to 127.0.0.1",
- IP_MULTICAST_IF, &mreqn, sizeof(mreqn));
+ address.s_addr = inet_addr("127.0.0.1");
+ test_sockopt_value_ext("IP_MULTICAST_IF set to 127.0.0.1 mreqn",
+ IP_MULTICAST_IF, &mreqn, sizeof(mreqn), &address, size);
/* Errors */
diff --git a/test_tools/multicast/sockopt_utils.h b/test_tools/multicast/sockopt_utils.h
index 6486f71..330b765 100644
--- a/test_tools/multicast/sockopt_utils.h
+++ b/test_tools/multicast/sockopt_utils.h
@@ -122,11 +122,23 @@ void test_setsockopt(char* test_name, int optname, void *optval,
printf("%s=pass\n", test_name);
}
+/* In some cases setsockopt and getsockopt can work with different data
+ * structures, e.g. setsockopt() can use 'struct ip_mreqn' for setting
+ * the source ip address and getsockopt() always returns 'struct in_addr'.
+ * This function is provided to deal with such situation.
+ */
+void test_sockopt_value_ext(char* test_name, int optname,
+ void *optval, socklen_t optlen,
+ void *expval, socklen_t explen)
+{
+ test_setsockopt(test_name, optname, optval, optlen);
+ test_getsockopt(test_name, optname, expval, explen);
+}
+
void test_sockopt_value(char* test_name, int optname,
void *optval, socklen_t optlen)
{
- test_setsockopt(test_name, optname, optval, optlen);
- test_getsockopt(test_name, optname, optval, optlen);
+ test_sockopt_value_ext(test_name, optname, optval, optlen, optval, optlen);
}
void test_setsockopt_error(char* test_name, int optname, void *optval,
--
1.9.3