summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2019-05-17 16:16:29 +0000
committerDmitry V. Levin <ldv@altlinux.org>2019-05-17 16:16:29 +0000
commit9a2457d7cedef53d2890c38a7cd12af3c2c22c78 (patch)
tree7f74e9b2f1f37cfee6427ba5161206dd70062d82
parente26b1a755a66bf868a00003ca29498e1a3d150a0 (diff)
downloadstrace-9a2457d7cedef53d2890c38a7cd12af3c2c22c78.tar.gz
tests: check decoding of SO_TIMESTAMP*_NEW control messages
* configure.ac (AC_CHECK_TYPES): Check for struct __kernel_timespec and struct __kernel_sock_timeval. * tests/msg_control.c [HAVE_STRUCT___KERNEL_SOCK_TIMEVAL || HAVE_STRUCT___KERNEL_TIMESPEC]: Include <linux/time_types.h>. (test_scm_timestamp): Rename to test_scm_timestamp_old. (test_scm_timestampns): Rename to test_scm_timestampns_old. (test_scm_timestamping): Rename to test_scm_timestamping_old. [HAVE_STRUCT___KERNEL_SOCK_TIMEVAL] (test_scm_timestamp_new): New function. [HAVE_STRUCT___KERNEL_TIMESPEC] (test_scm_timestampns_new, test_scm_timestamping_new): New functions. (test_sol_socket): Use them. * tests/sockopt-timestamp.c [HAVE_STRUCT___KERNEL_SOCK_TIMEVAL || HAVE_STRUCT___KERNEL_TIMESPEC]: Include <linux/time_types.h>. Include "xlat/sock_options.h" in XLAT_MACROS_ONLY mode. (print_timestampns_old): Define unconditionally. [HAVE_STRUCT___KERNEL_SOCK_TIMEVAL] (print_timestamp_new): New function. [HAVE_STRUCT___KERNEL_TIMESPEC] (print_timestampns_new): Likewise. (main): Test SO_TIMESTAMPNS_OLD unconditionally. [HAVE_STRUCT___KERNEL_SOCK_TIMEVAL]: Test SO_TIMESTAMP_NEW. [HAVE_STRUCT___KERNEL_TIMESPEC]: Test SO_TIMESTAMPNS_NEW.
-rw-r--r--configure.ac3
-rw-r--r--tests/msg_control.c180
-rw-r--r--tests/sockopt-timestamp.c59
3 files changed, 226 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac
index 86d3626b2..e7df4fe60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -283,6 +283,9 @@ AC_CHECK_TYPES([struct mmsghdr],,, [#include <sys/socket.h>])
AC_CHECK_TYPES([__kernel_long_t, __kernel_ulong_t],,,
[#include <asm/posix_types.h>])
+AC_CHECK_TYPES([struct __kernel_timespec, struct __kernel_sock_timeval],,,
+[#include <linux/time_types.h>])
+
AC_CHECK_TYPES([struct stat64, struct __old_kernel_stat],,,
[#include <sys/types.h>
#include <asm/stat.h>])
diff --git a/tests/msg_control.c b/tests/msg_control.c
index 84d6ccff4..4b277ec35 100644
--- a/tests/msg_control.c
+++ b/tests/msg_control.c
@@ -20,6 +20,11 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#if defined HAVE_STRUCT___KERNEL_SOCK_TIMEVAL \
+ || defined HAVE_STRUCT___KERNEL_TIMESPEC
+# include <linux/time_types.h>
+#endif
+
#include "xlat.h"
#define XLAT_MACROS_ONLY
#include "xlat/sock_options.h"
@@ -210,7 +215,7 @@ test_scm_rights3(struct msghdr *const mh, void *const page, const size_t nfds)
}
static void
-test_scm_timestamp(struct msghdr *const mh, void *const page)
+test_scm_timestamp_old(struct msghdr *const mh, void *const page)
{
size_t len = CMSG_SPACE(sizeof(struct timeval));
struct cmsghdr *cmsg = get_cmsghdr(page, len);
@@ -255,7 +260,7 @@ test_scm_timestamp(struct msghdr *const mh, void *const page)
}
static void
-test_scm_timestampns(struct msghdr *const mh, void *const page)
+test_scm_timestampns_old(struct msghdr *const mh, void *const page)
{
size_t len = CMSG_SPACE(sizeof(struct timespec));
struct cmsghdr *cmsg = get_cmsghdr(page, len);
@@ -301,7 +306,7 @@ test_scm_timestampns(struct msghdr *const mh, void *const page)
}
static void
-test_scm_timestamping(struct msghdr *const mh, void *const page)
+test_scm_timestamping_old(struct msghdr *const mh, void *const page)
{
size_t len = CMSG_SPACE(3 * sizeof(struct timespec));
struct cmsghdr *cmsg = get_cmsghdr(page, len);
@@ -355,6 +360,162 @@ test_scm_timestamping(struct msghdr *const mh, void *const page)
(unsigned long) len, rc, errno2name());
}
+#ifdef HAVE_STRUCT___KERNEL_SOCK_TIMEVAL
+static void
+test_scm_timestamp_new(struct msghdr *const mh, void *const page)
+{
+ size_t len = CMSG_SPACE(sizeof(struct __kernel_sock_timeval));
+ struct cmsghdr *cmsg = get_cmsghdr(page, len);
+
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct __kernel_sock_timeval));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SO_TIMESTAMP_NEW;
+ struct __kernel_sock_timeval *tv =
+ (struct __kernel_sock_timeval *) CMSG_DATA(cmsg);
+ tv->tv_sec = 0xdefaceddeadbeef;
+ tv->tv_usec = 0xdec0dedcafef00d;
+
+ mh->msg_control = cmsg;
+ mh->msg_controllen = len;
+
+ int rc = sendmsg(-1, mh, 0);
+ printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
+ ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
+ ", cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMP_NEW"
+ ", cmsg_data={tv_sec=%lld, tv_usec=%llu}}]"
+ ", msg_controllen=%lu, msg_flags=0}, 0) = %s\n",
+ (unsigned) cmsg->cmsg_len,
+ (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec),
+ (unsigned long) len, sprintrc(rc));
+
+ len = CMSG_SPACE(sizeof(struct __kernel_sock_timeval) - sizeof(long));
+ cmsg = get_cmsghdr(page, len);
+
+ cmsg->cmsg_len =
+ CMSG_LEN(sizeof(struct __kernel_sock_timeval) - sizeof(long));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SO_TIMESTAMP_NEW;
+
+ mh->msg_control = cmsg;
+ mh->msg_controllen = len;
+
+ rc = sendmsg(-1, mh, 0);
+ printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
+ ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
+ ", cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMP_NEW, cmsg_data=?}]"
+ ", msg_controllen=%lu, msg_flags=0}, 0) = %s\n",
+ (unsigned) cmsg->cmsg_len,
+ (unsigned long) len, sprintrc(rc));
+}
+#endif /* HAVE_STRUCT___KERNEL_SOCK_TIMEVAL */
+
+#ifdef HAVE_STRUCT___KERNEL_TIMESPEC
+static void
+test_scm_timestampns_new(struct msghdr *const mh, void *const page)
+{
+ size_t len = CMSG_SPACE(sizeof(struct __kernel_timespec));
+ struct cmsghdr *cmsg = get_cmsghdr(page, len);
+
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct __kernel_timespec));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SO_TIMESTAMPNS_NEW;
+ struct __kernel_timespec *ts =
+ (struct __kernel_timespec *) CMSG_DATA(cmsg);
+ ts->tv_sec = 0xdefaceddeadbeef;
+ ts->tv_nsec = 0xdec0dedcafef00d;
+
+ mh->msg_control = cmsg;
+ mh->msg_controllen = len;
+
+ int rc = sendmsg(-1, mh, 0);
+ printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
+ ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
+ ", cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMPNS_NEW"
+ ", cmsg_data={tv_sec=%lld, tv_nsec=%llu}}]"
+ ", msg_controllen=%lu, msg_flags=0}, 0) = %s\n",
+ (unsigned) cmsg->cmsg_len,
+ (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec),
+ (unsigned long) len, sprintrc(rc));
+
+ len = CMSG_SPACE(sizeof(struct __kernel_timespec) - sizeof(long));
+ cmsg = get_cmsghdr(page, len);
+
+ cmsg->cmsg_len =
+ CMSG_LEN(sizeof(struct __kernel_timespec) - sizeof(long));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SO_TIMESTAMPNS_NEW;
+
+ mh->msg_control = cmsg;
+ mh->msg_controllen = len;
+
+ rc = sendmsg(-1, mh, 0);
+ printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
+ ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
+ ", cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMPNS_NEW"
+ ", cmsg_data=?}]"
+ ", msg_controllen=%lu, msg_flags=0}, 0) = %s\n",
+ (unsigned) cmsg->cmsg_len,
+ (unsigned long) len, sprintrc(rc));
+}
+
+static void
+test_scm_timestamping_new(struct msghdr *const mh, void *const page)
+{
+ size_t len = CMSG_SPACE(3 * sizeof(struct __kernel_timespec));
+ struct cmsghdr *cmsg = get_cmsghdr(page, len);
+
+ cmsg->cmsg_len = CMSG_LEN(3 * sizeof(struct __kernel_timespec));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SO_TIMESTAMPING_NEW;
+ struct __kernel_timespec *ts =
+ (struct __kernel_timespec *) CMSG_DATA(cmsg);
+ ts[0].tv_sec = 0xdeface0deadbef1;
+ ts[0].tv_nsec = 0xdec0de2cafef0d3;
+ ts[1].tv_sec = 0xdeface4deadbef5;
+ ts[1].tv_nsec = 0xdec0de6cafef0d7;
+ ts[2].tv_sec = 0xdeface8deadbef9;
+ ts[2].tv_nsec = 0xdec0dedcafef00d;
+
+ mh->msg_control = cmsg;
+ mh->msg_controllen = len;
+
+ int rc = sendmsg(-1, mh, 0);
+ printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
+ ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
+ ", cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMPING_NEW"
+ ", cmsg_data=[{tv_sec=%lld, tv_nsec=%llu}"
+ ", {tv_sec=%lld, tv_nsec=%llu}, {tv_sec=%lld, tv_nsec=%llu}]}]"
+ ", msg_controllen=%lu, msg_flags=0}, 0) = %s\n",
+ (unsigned) cmsg->cmsg_len, (long long) ts[0].tv_sec,
+ zero_extend_signed_to_ull(ts[0].tv_nsec),
+ (long long) ts[1].tv_sec,
+ zero_extend_signed_to_ull(ts[1].tv_nsec),
+ (long long) ts[2].tv_sec,
+ zero_extend_signed_to_ull(ts[2].tv_nsec),
+ (unsigned long) len, sprintrc(rc));
+
+ len = CMSG_SPACE(3 * sizeof(struct __kernel_timespec) - sizeof(long));
+ cmsg = get_cmsghdr(page, len);
+
+ cmsg->cmsg_len =
+ CMSG_LEN(3 * sizeof(struct __kernel_timespec) - sizeof(long));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SO_TIMESTAMPING_NEW;
+
+ mh->msg_control = cmsg;
+ mh->msg_controllen = len;
+
+ rc = sendmsg(-1, mh, 0);
+ printf("sendmsg(-1, {msg_name=NULL, msg_namelen=0, msg_iov=NULL"
+ ", msg_iovlen=0, msg_control=[{cmsg_len=%u"
+ ", cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMPING_NEW"
+ ", cmsg_data=?}]"
+ ", msg_controllen=%lu, msg_flags=0}, 0) = %s\n",
+ (unsigned) cmsg->cmsg_len,
+ (unsigned long) len, sprintrc(rc));
+}
+#endif /* HAVE_STRUCT___KERNEL_TIMESPEC */
+
static void
print_security(const struct cmsghdr *const cmsg, const size_t cmsg_len)
{
@@ -504,9 +665,16 @@ test_sol_socket(struct msghdr *const mh, void *const page)
test_scm_rights3(mh, page, DEFAULT_STRLEN);
test_scm_rights3(mh, page, DEFAULT_STRLEN + 1);
- test_scm_timestamp(mh, page);
- test_scm_timestampns(mh, page);
- test_scm_timestamping(mh, page);
+ test_scm_timestamp_old(mh, page);
+ test_scm_timestampns_old(mh, page);
+ test_scm_timestamping_old(mh, page);
+#ifdef HAVE_STRUCT___KERNEL_SOCK_TIMEVAL
+ test_scm_timestamp_new(mh, page);
+#endif
+#ifdef HAVE_STRUCT___KERNEL_TIMESPEC
+ test_scm_timestampns_new(mh, page);
+ test_scm_timestamping_new(mh, page);
+#endif
test_unknown_type(mh, page, ARG_STR(SOL_SOCKET), "SCM_???");
}
diff --git a/tests/sockopt-timestamp.c b/tests/sockopt-timestamp.c
index d6f6ccf9b..c26599258 100644
--- a/tests/sockopt-timestamp.c
+++ b/tests/sockopt-timestamp.c
@@ -12,15 +12,14 @@
#include <unistd.h>
#include <sys/socket.h>
-#ifndef SO_TIMESTAMP_OLD
-# define SO_TIMESTAMP_OLD SO_TIMESTAMP
+#if defined HAVE_STRUCT___KERNEL_SOCK_TIMEVAL \
+ || defined HAVE_STRUCT___KERNEL_TIMESPEC
+# include <linux/time_types.h>
#endif
-#ifndef SO_TIMESTAMPNS_OLD
-# ifdef SO_TIMESTAMPNS
-# define SO_TIMESTAMPNS_OLD SO_TIMESTAMPNS
-# endif
-#endif
+#define XLAT_MACROS_ONLY
+#include "xlat/sock_options.h"
+#undef XLAT_MACROS_ONLY
static void
print_timestamp_old(const struct cmsghdr *c)
@@ -39,7 +38,6 @@ print_timestamp_old(const struct cmsghdr *c)
(long long) tv->tv_sec, (long long) tv->tv_usec);
}
-#ifdef SO_TIMESTAMPNS_OLD
static void
print_timestampns_old(const struct cmsghdr *c)
{
@@ -56,7 +54,44 @@ print_timestampns_old(const struct cmsghdr *c)
printf("{tv_sec=%lld, tv_nsec=%lld}",
(long long) ts->tv_sec, (long long) ts->tv_nsec);
}
-#endif /* SO_TIMESTAMPNS_OLD */
+
+#ifdef HAVE_STRUCT___KERNEL_SOCK_TIMEVAL
+static void
+print_timestamp_new(const struct cmsghdr *c)
+{
+ const void *cmsg_header = c;
+ const void *cmsg_data = CMSG_DATA(c);
+ const struct __kernel_sock_timeval *tv = cmsg_data;
+ const unsigned int expected_len = sizeof(*tv);
+ const unsigned int data_len = c->cmsg_len - (cmsg_data - cmsg_header);
+
+ if (expected_len != data_len)
+ perror_msg_and_fail("sizeof(struct __kernel_sock_timeval) = %u"
+ ", data_len = %u\n",
+ expected_len, data_len);
+ printf("{tv_sec=%lld, tv_usec=%lld}",
+ (long long) tv->tv_sec, (long long) tv->tv_usec);
+}
+#endif /* HAVE_STRUCT___KERNEL_SOCK_TIMEVAL */
+
+#ifdef HAVE_STRUCT___KERNEL_TIMESPEC
+static void
+print_timestampns_new(const struct cmsghdr *c)
+{
+ const void *cmsg_header = c;
+ const void *cmsg_data = CMSG_DATA(c);
+ const struct __kernel_timespec *ts = cmsg_data;
+ const unsigned int expected_len = sizeof(*ts);
+ const unsigned int data_len = c->cmsg_len - (cmsg_data - cmsg_header);
+
+ if (expected_len != data_len)
+ perror_msg_and_fail("sizeof(struct __kernel_timespec) = %u"
+ ", data_len = %u\n",
+ expected_len, data_len);
+ printf("{tv_sec=%lld, tv_nsec=%lld}",
+ (long long) ts->tv_sec, (long long) ts->tv_nsec);
+}
+#endif /* HAVE_STRUCT___KERNEL_TIMESPEC */
static unsigned int
test_sockopt(int so_val, const char *str, void (*fun)(const struct cmsghdr *))
@@ -141,8 +176,12 @@ main(void)
void (*fun)(const struct cmsghdr *);
} tests[] = {
{ SO_TIMESTAMP_OLD, "SO_TIMESTAMP_OLD", print_timestamp_old },
-#ifdef SO_TIMESTAMPNS_OLD
{ SO_TIMESTAMPNS_OLD, "SO_TIMESTAMPNS_OLD", print_timestampns_old },
+#ifdef HAVE_STRUCT___KERNEL_SOCK_TIMEVAL
+ { SO_TIMESTAMP_NEW, "SO_TIMESTAMP_NEW", print_timestamp_new },
+#endif
+#ifdef HAVE_STRUCT___KERNEL_TIMESPEC
+ { SO_TIMESTAMPNS_NEW, "SO_TIMESTAMPNS_NEW", print_timestampns_new },
#endif
};
unsigned int tested = 0;