]> granicus.if.org Git - strace/commitdiff
tests: check decoding of SO_TIMESTAMP*_NEW control messages
authorDmitry V. Levin <ldv@altlinux.org>
Fri, 17 May 2019 16:16:29 +0000 (16:16 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Fri, 17 May 2019 16:16:29 +0000 (16:16 +0000)
* 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.

configure.ac
tests/msg_control.c
tests/sockopt-timestamp.c

index 86d3626b218e1d9323ae8d1f1317ccaf9f3f7721..e7df4fe609808fd37ff217d398a58b30ffef6f64 100644 (file)
@@ -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>])
index 84d6ccff474006ef6b70b3583f56966f9d836eef..4b277ec35d0b90ee374656ecaabbd624bf7f3b1e 100644 (file)
 #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_???");
 }
index d6f6ccf9b6a3935a629fca2f65d422f9239ed39c..c265992583b60dbfade3758183cb8769f8e33eee 100644 (file)
 #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;