From: Dmitry V. Levin <ldv@altlinux.org> Date: Fri, 30 Jun 2017 21:38:49 +0000 (+0000) Subject: tests: enhance nlattr_inet_diag_msg test X-Git-Tag: v4.18~28 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aecff115c0e70dfe2ce64c7208083505777eda24;p=strace tests: enhance nlattr_inet_diag_msg test * tests/test_nlattr.h: New file. * tests/Makefile.am (libtests_a_SOURCES): Add it. * tests/nlattr_inet_diag_msg.c: Include "test_nlattr.h". (test_inet_diag_meminfo, test_inet_diag_vegasinfo, test_inet_diag_dctcpinfo, test_inet_diag_bbrinfo): Remove. (address): New variable. (init_inet_diag_msg): Remove "address" argument, add const qualifier to all remaining arguments. (print_inet_diag_msg, print_uint): New functions. (main): Use macros from test_nlattr.h file. --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 275e9f8d..fd07b03c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -63,6 +63,7 @@ libtests_a_SOURCES = \ skip_unavailable.c \ sprintrc.c \ tail_alloc.c \ + test_nlattr.h \ tests.h \ tprintf.c \ # end of libtests_a_SOURCES diff --git a/tests/nlattr_inet_diag_msg.c b/tests/nlattr_inet_diag_msg.c index dd0c46cc..65ca667b 100644 --- a/tests/nlattr_inet_diag_msg.c +++ b/tests/nlattr_inet_diag_msg.c @@ -27,30 +27,27 @@ */ #include "tests.h" -#include "netlink.h" #include <stdio.h> #include <string.h> -#include <sys/socket.h> #include <netinet/tcp.h> #include <arpa/inet.h> +#include "test_nlattr.h" #include <linux/inet_diag.h> -#include <linux/rtnetlink.h> #include <linux/sock_diag.h> +static const char address[] = "10.11.12.13"; + static void -init_inet_diag_msg(struct nlmsghdr *nlh, unsigned int msg_len, - const char *address) +init_inet_diag_msg(struct nlmsghdr *const nlh, const unsigned int msg_len) { - struct inet_diag_msg *msg; - SET_STRUCT(struct nlmsghdr, nlh, .nlmsg_len = msg_len, .nlmsg_type = SOCK_DIAG_BY_FAMILY, .nlmsg_flags = NLM_F_DUMP ); - msg = NLMSG_DATA(nlh); + struct inet_diag_msg *const msg = NLMSG_DATA(nlh); SET_STRUCT(struct inet_diag_msg, msg, .idiag_family = AF_INET, .idiag_state = TCP_LISTEN @@ -62,33 +59,9 @@ init_inet_diag_msg(struct nlmsghdr *nlh, unsigned int msg_len, } static void -test_inet_diag_meminfo(const int fd) +print_inet_diag_msg(const unsigned int msg_len) { - const int hdrlen = sizeof(struct inet_diag_msg); - const char address[] = "87.65.43.21"; - struct nlmsghdr *nlh; - struct nlattr *nla; - unsigned int nla_len; - unsigned int msg_len; - void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); - long rc; - - /* len < sizeof(struct inet_diag_meminfo) */ - nla_len = NLA_HDRLEN + 2; - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_MEMINFO - ); - memcpy(RTA_DATA(nla), "12", 2); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" + printf("{len=%u, type=SOCK_DIAG_BY_FAMILY" ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" ", id={idiag_sport=htons(0), idiag_dport=htons(0)" @@ -96,358 +69,60 @@ test_inet_diag_meminfo(const int fd) ", inet_pton(AF_INET, \"%s\", &idiag_dst)" ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_MEMINFO}" - ", \"12\"}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - msg_len, sprintrc(rc)); - - /* short read of inet_diag_meminfo */ - nla_len = NLA_HDRLEN + sizeof(struct inet_diag_meminfo); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - (nla_len - 1); - init_inet_diag_msg(nlh, msg_len, address); + ", idiag_inode=0}", + msg_len, address, address); +} - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_MEMINFO - ); +static void +print_uint(const unsigned int *p) +{ + printf("%u", *p); +} - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); +int +main(void) +{ + skip_if_unavailable("/proc/self/fd/"); - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_MEMINFO}" - ", %p}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - RTA_DATA(nla), msg_len, sprintrc(rc)); + const int fd = create_nl_socket(NETLINK_SOCK_DIAG); + const unsigned int hdrlen = sizeof(struct inet_diag_msg); + void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); - /* inet_diag_meminfo */ - nla_len = NLA_HDRLEN + sizeof(struct inet_diag_meminfo); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); +#define DEFAULT_STRLEN 32 + static char pattern[DEFAULT_STRLEN]; + fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1); - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_MEMINFO - ); static const struct inet_diag_meminfo minfo = { .idiag_rmem = 0xfadcacdb, .idiag_wmem = 0xbdabcada, .idiag_fmem = 0xbadbfafb, .idiag_tmem = 0xfdacdadf }; - memcpy(RTA_DATA(nla), &minfo, sizeof(minfo)); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_MEMINFO}" - ", {idiag_rmem=%u, idiag_wmem=%u, idiag_fmem=%u, idiag_tmem=%u}}}" - ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - minfo.idiag_rmem, minfo.idiag_wmem, - minfo.idiag_fmem, minfo.idiag_tmem, - msg_len, sprintrc(rc)); -} - -static void -test_inet_diag_vegasinfo(const int fd) -{ - const int hdrlen = sizeof(struct inet_diag_msg); - const char address[] = "87.65.43.21"; - struct nlmsghdr *nlh; - struct nlattr *nla; - unsigned int nla_len; - unsigned int msg_len; - void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); - long rc; - - /* len < sizeof(struct tcpvegas_info) */ - nla_len = NLA_HDRLEN + 2; - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_VEGASINFO - ); - memcpy(RTA_DATA(nla), "12", 2); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_VEGASINFO}" - ", \"12\"}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - msg_len, sprintrc(rc)); + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_inet_diag_msg, print_inet_diag_msg, + INET_DIAG_MEMINFO, pattern, minfo, + PRINT_FIELD_U("{", minfo, idiag_rmem); + PRINT_FIELD_U(", ", minfo, idiag_wmem); + PRINT_FIELD_U(", ", minfo, idiag_fmem); + PRINT_FIELD_U(", ", minfo, idiag_tmem); + printf("}")); - /* short read of tcpvegas_info */ - nla_len = NLA_HDRLEN + sizeof(struct tcpvegas_info); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - (nla_len - 1); - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_VEGASINFO - ); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_VEGASINFO}" - ", %p}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - RTA_DATA(nla), msg_len, sprintrc(rc)); - - /* tcpvegas_info */ - nla_len = NLA_HDRLEN + sizeof(struct tcpvegas_info); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_VEGASINFO - ); static const struct tcpvegas_info vegas = { .tcpv_enabled = 0xfadcacdb, .tcpv_rttcnt = 0xbdabcada, .tcpv_rtt = 0xbadbfafb, .tcpv_minrtt = 0xfdacdadf }; - memcpy(RTA_DATA(nla), &vegas, sizeof(vegas)); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_VEGASINFO}" - ", {tcpv_enabled=%u, tcpv_rttcnt=%u, tcpv_rtt=%u" - ", tcpv_minrtt=%u}}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - vegas.tcpv_enabled, vegas.tcpv_rttcnt, - vegas.tcpv_rtt, vegas.tcpv_minrtt, - msg_len, sprintrc(rc)); -} - -static void -test_inet_diag_skmeminfo(const int fd) -{ - const int hdrlen = sizeof(struct inet_diag_msg); - const char address[] = "87.65.43.21"; - struct nlmsghdr *nlh; - struct nlattr *nla; - unsigned int nla_len; - unsigned int msg_len; - void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); - long rc; - - /* len < sizeof(uint32_t) */ - nla_len = NLA_HDRLEN + 2; - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_SKMEMINFO - ); - memcpy(RTA_DATA(nla), "12", 2); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u" - ", nla_type=INET_DIAG_SKMEMINFO}, \"12\"}}" - ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - msg_len, sprintrc(rc)); - - /* len = sizeof(uint32_t) * 2 - 1 */ - nla_len = NLA_HDRLEN + sizeof(uint32_t) * 2 - 1; - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_SKMEMINFO - ); - static const uint32_t mem[] = { 0xaffacbad, 0xffadbcab }; - memcpy(RTA_DATA(nla), mem, sizeof(mem[0])); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_SKMEMINFO}" - ", [%u]}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - mem[0], msg_len, sprintrc(rc)); - - /* len = sizeof(uint32_t) * 2 */ - nla_len = NLA_HDRLEN + sizeof(uint32_t) * 2; - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_SKMEMINFO - ); - memcpy(RTA_DATA(nla), mem, sizeof(mem)); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_SKMEMINFO}" - ", [%u, %u]}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - mem[0], mem[1], msg_len, sprintrc(rc)); -} - -static void -test_inet_diag_dctcpinfo(const int fd) -{ - const int hdrlen = sizeof(struct inet_diag_msg); - const char address[] = "87.65.43.21"; - struct nlmsghdr *nlh; - struct nlattr *nla; - unsigned int nla_len; - unsigned int msg_len; - void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); - long rc; + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_inet_diag_msg, print_inet_diag_msg, + INET_DIAG_VEGASINFO, pattern, vegas, + PRINT_FIELD_U("{", vegas, tcpv_enabled); + PRINT_FIELD_U(", ", vegas, tcpv_rttcnt); + PRINT_FIELD_U(", ", vegas, tcpv_rtt); + PRINT_FIELD_U(", ", vegas, tcpv_minrtt); + printf("}")); - /* len < sizeof(struct tcp_dctcp_info) */ - nla_len = NLA_HDRLEN + 2; - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_DCTCPINFO - ); - memcpy(RTA_DATA(nla), "12", 2); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_DCTCPINFO}" - ", \"12\"}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - msg_len, sprintrc(rc)); - - /* short read of tcp_dctcp_info */ - nla_len = NLA_HDRLEN + sizeof(struct tcp_dctcp_info); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - (nla_len - 1); - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_DCTCPINFO - ); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_DCTCPINFO}" - ", %p}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - RTA_DATA(nla), msg_len, sprintrc(rc)); - - /* tcp_dctcp_info */ - nla_len = NLA_HDRLEN + sizeof(struct tcp_dctcp_info); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_DCTCPINFO - ); static const struct tcp_dctcp_info dctcp = { .dctcp_enabled = 0xfdac, .dctcp_ce_state = 0xfadc, @@ -455,106 +130,16 @@ test_inet_diag_dctcpinfo(const int fd) .dctcp_ab_ecn = 0xbadbfafb, .dctcp_ab_tot = 0xfdacdadf }; - memcpy(RTA_DATA(nla), &dctcp, sizeof(dctcp)); + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_inet_diag_msg, print_inet_diag_msg, + INET_DIAG_DCTCPINFO, pattern, dctcp, + PRINT_FIELD_U("{", dctcp, dctcp_enabled); + PRINT_FIELD_U(", ", dctcp, dctcp_ce_state); + PRINT_FIELD_U(", ", dctcp, dctcp_alpha); + PRINT_FIELD_U(", ", dctcp, dctcp_ab_ecn); + PRINT_FIELD_U(", ", dctcp, dctcp_ab_tot); + printf("}")); - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_DCTCPINFO}" - ", {dctcp_enabled=%u, dctcp_ce_state=%u" - ", dctcp_alpha=%u, dctcp_ab_ecn=%u, dctcp_ab_tot=%u}}}" - ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - dctcp.dctcp_enabled, dctcp.dctcp_ce_state, - dctcp.dctcp_alpha, dctcp.dctcp_ab_ecn, - dctcp.dctcp_ab_tot, msg_len, sprintrc(rc)); -} - -static void -test_inet_diag_bbrinfo(const int fd) -{ - const int hdrlen = sizeof(struct inet_diag_msg); - const char address[] = "12.34.56.78"; - struct nlmsghdr *nlh; - struct nlattr *nla; - unsigned int nla_len; - unsigned int msg_len; - void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); - long rc; - - /* len < sizeof(struct tcp_bbr_info) */ - nla_len = NLA_HDRLEN + 2; - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_BBRINFO - ); - memcpy(RTA_DATA(nla), "12", 2); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_BBRINFO}" - ", \"12\"}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - msg_len, sprintrc(rc)); - - /* short read of tcp_bbr_info */ - nla_len = NLA_HDRLEN + sizeof(struct tcp_bbr_info); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - (nla_len - 1); - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_BBRINFO - ); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); - - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_BBRINFO}" - ", %p}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - RTA_DATA(nla), msg_len, sprintrc(rc)); - - /* tcp_bbr_info */ - nla_len = NLA_HDRLEN + sizeof(struct tcp_bbr_info); - msg_len = NLMSG_SPACE(hdrlen) + nla_len; - nlh = nlh0 - nla_len; - init_inet_diag_msg(nlh, msg_len, address); - - nla = NLMSG_ATTR(nlh, hdrlen); - SET_STRUCT(struct nlattr, nla, - .nla_len = nla_len, - .nla_type = INET_DIAG_BBRINFO - ); static const struct tcp_bbr_info bbr = { .bbr_bw_lo = 0xfdacdadf, .bbr_bw_hi = 0xfadcacdb, @@ -562,41 +147,21 @@ test_inet_diag_bbrinfo(const int fd) .bbr_pacing_gain = 0xbadbfafb, .bbr_cwnd_gain = 0xfdacdadf }; - memcpy(RTA_DATA(nla), &bbr, sizeof(bbr)); - - rc = sendto(fd, nlh, msg_len, MSG_DONTWAIT, NULL, 0); + TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, + init_inet_diag_msg, print_inet_diag_msg, + INET_DIAG_BBRINFO, pattern, bbr, + PRINT_FIELD_X("{", bbr, bbr_bw_lo); + PRINT_FIELD_X(", ", bbr, bbr_bw_hi); + PRINT_FIELD_U(", ", bbr, bbr_min_rtt); + PRINT_FIELD_U(", ", bbr, bbr_pacing_gain); + PRINT_FIELD_U(", ", bbr, bbr_cwnd_gain); + printf("}")); - printf("sendto(%d, {{len=%u, type=SOCK_DIAG_BY_FAMILY" - ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET" - ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0" - ", id={idiag_sport=htons(0), idiag_dport=htons(0)" - ", inet_pton(AF_INET, \"%s\", &idiag_src)" - ", inet_pton(AF_INET, \"%s\", &idiag_dst)" - ", idiag_if=0, idiag_cookie=[0, 0]}, idiag_expires=0" - ", idiag_rqueue=0, idiag_wqueue=0, idiag_uid=0" - ", idiag_inode=0}, {{nla_len=%u, nla_type=INET_DIAG_BBRINFO}" - ", {bbr_bw_lo=%#x, bbr_bw_hi=%#x, bbr_min_rtt=%u" - ", bbr_pacing_gain=%u, bbr_cwnd_gain=%u}}}" - ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", - fd, msg_len, address, address, nla_len, - bbr.bbr_bw_lo, bbr.bbr_bw_hi, bbr.bbr_min_rtt, - bbr.bbr_pacing_gain, bbr.bbr_cwnd_gain, - msg_len, sprintrc(rc)); -} - -int main(void) -{ - skip_if_unavailable("/proc/self/fd/"); - - int fd = create_nl_socket(NETLINK_SOCK_DIAG); - - test_inet_diag_meminfo(fd); - test_inet_diag_vegasinfo(fd); - test_inet_diag_skmeminfo(fd); - test_inet_diag_dctcpinfo(fd); - test_inet_diag_bbrinfo(fd); - - printf("+++ exited with 0 +++\n"); + static const uint32_t mem[] = { 0xaffacbad, 0xffadbcab }; + TEST_NLATTR_ARRAY(fd, nlh0, hdrlen, + init_inet_diag_msg, print_inet_diag_msg, + INET_DIAG_SKMEMINFO, pattern, mem, print_uint); + puts("+++ exited with 0 +++"); return 0; } diff --git a/tests/test_nlattr.h b/tests/test_nlattr.h new file mode 100644 index 00000000..fb23f347 --- /dev/null +++ b/tests/test_nlattr.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2017 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" + +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> +#include "netlink.h" +#include <linux/rtnetlink.h> + +static void +init_nlattr(struct nlattr *const nla, + const uint16_t nla_len, + const uint16_t nla_type, + const void *const src, + const size_t n) +{ + SET_STRUCT(struct nlattr, nla, + .nla_len = nla_len, + .nla_type = nla_type, + ); + + memcpy(RTA_DATA(nla), src, n); +} + +static void +print_nlattr(const unsigned int nla_len, const char *const nla_type) +{ + printf(", {{nla_len=%u, nla_type=%s}, ", nla_len, nla_type); +} + +#define TEST_NLATTR_(fd_, nlh0_, hdrlen_, \ + init_msg_, print_msg_, \ + nla_type_, nla_type_str_, \ + nla_data_len_, src_, slen_, ...) \ + do { \ + struct nlmsghdr *const nlh = \ + (nlh0_) - (NLA_HDRLEN + (slen_)); \ + struct nlattr *const nla = NLMSG_ATTR(nlh, (hdrlen_)); \ + const unsigned int nla_len = \ + NLA_HDRLEN + (nla_data_len_); \ + const unsigned int msg_len = \ + NLMSG_SPACE(hdrlen_) + nla_len; \ + \ + (init_msg_)(nlh, msg_len); \ + init_nlattr(nla, nla_len, (nla_type_), \ + (src_), (slen_)); \ + \ + const char *const errstr = \ + sprintrc(sendto((fd_), nlh, msg_len, \ + MSG_DONTWAIT, NULL, 0)); \ + \ + printf("sendto(%d, {", (fd_)); \ + (print_msg_)(msg_len); \ + print_nlattr(nla_len, (nla_type_str_)); \ + \ + { __VA_ARGS__; } \ + \ + printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", \ + msg_len, errstr); \ + } while (0) + +#define TEST_NLATTR(fd_, nlh0_, hdrlen_, \ + init_msg_, print_msg_, \ + nla_type_, \ + nla_data_len_, src_, slen_, ...) \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + (nla_data_len_), (src_), (slen_), __VA_ARGS__) + +#define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_, \ + init_msg_, print_msg_, \ + nla_type_, pattern_, obj_, ...) \ + do { \ + /* len < sizeof(obj_) */ \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + sizeof(obj_) - 1, \ + (pattern_), sizeof(obj_) - 1, \ + printf("\"%.*s\"", \ + (int) sizeof(obj_) - 1, (pattern_))); \ + /* short read of sizeof(obj_) */ \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + sizeof(obj_), \ + (pattern_), sizeof(obj_) - 1, \ + printf("%p", \ + RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))))); \ + /* sizeof(obj_) */ \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + sizeof(obj_), \ + &(obj_), sizeof(obj_), \ + __VA_ARGS__); \ + } while (0) + +#define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_, \ + init_msg_, print_msg_, \ + nla_type_, pattern_, obj_, print_elem_) \ + do { \ + /* len < sizeof((obj_)[0]) */ \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + sizeof((obj_)[0]) - 1, \ + (pattern_), sizeof((obj_)[0]) - 1, \ + printf("\"%.*s\"", \ + (int) sizeof((obj_)[0]) - 1, \ + (pattern_))); \ + /* sizeof((obj_)[0]) < len < sizeof(obj_) */ \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + sizeof(obj_) - 1, \ + &(obj_), sizeof(obj_) - 1, \ + printf("["); \ + size_t i; \ + for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \ + if (i) printf(", "); \ + (print_elem_)(&(obj_)[i]); \ + } \ + printf("]")); \ + /* short read of sizeof(obj_) */ \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + sizeof(obj_), \ + &(obj_), sizeof(obj_) - 1, \ + printf("["); \ + size_t i; \ + for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \ + if (i) printf(", "); \ + (print_elem_)(&(obj_)[i]); \ + } \ + printf(", %p]", \ + RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))) \ + + sizeof((obj_)[0]))); \ + /* sizeof(obj_) */ \ + TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \ + (init_msg_), (print_msg_), \ + (nla_type_), #nla_type_, \ + sizeof(obj_), \ + &(obj_), sizeof(obj_), \ + printf("["); \ + size_t i; \ + for (i = 0; i < ARRAY_SIZE(obj_); ++i) { \ + if (i) printf(", "); \ + (print_elem_)(&(obj_)[i]); \ + } \ + printf("]")); \ + } while (0) + +#define PRINT_FIELD_U(prefix_, where_, field_) \ + printf("%s%s=%u", (prefix_), #field_, ((where_).field_)) + +#define PRINT_FIELD_X(prefix_, where_, field_) \ + printf("%s%s=%#x", (prefix_), #field_, ((where_).field_))