2 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3 * Copyright (c) 2017-2018 The strace developers.
6 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include <arpa/inet.h>
15 #include <netinet/tcp.h>
16 #include "test_nlattr.h"
17 #include <linux/inet_diag.h>
18 #include <linux/sock_diag.h>
20 static const char * const sk_meminfo_strs[] = {
21 "SK_MEMINFO_RMEM_ALLOC",
23 "SK_MEMINFO_WMEM_ALLOC",
25 "SK_MEMINFO_FWD_ALLOC",
26 "SK_MEMINFO_WMEM_QUEUED",
32 static const char address[] = "10.11.12.13";
35 init_inet_diag_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
37 SET_STRUCT(struct nlmsghdr, nlh,
39 .nlmsg_type = SOCK_DIAG_BY_FAMILY,
40 .nlmsg_flags = NLM_F_DUMP
43 struct inet_diag_msg *const msg = NLMSG_DATA(nlh);
44 SET_STRUCT(struct inet_diag_msg, msg,
45 .idiag_family = AF_INET,
46 .idiag_state = TCP_LISTEN,
47 .id.idiag_if = ifindex_lo()
50 if (!inet_pton(AF_INET, address, msg->id.idiag_src) ||
51 !inet_pton(AF_INET, address, msg->id.idiag_dst))
52 perror_msg_and_skip("inet_pton");
56 print_inet_diag_msg(const unsigned int msg_len)
58 printf("{len=%u, type=SOCK_DIAG_BY_FAMILY"
59 ", flags=NLM_F_DUMP, seq=0, pid=0}, {idiag_family=AF_INET"
60 ", idiag_state=TCP_LISTEN, idiag_timer=0, idiag_retrans=0"
61 ", id={idiag_sport=htons(0), idiag_dport=htons(0)"
62 ", idiag_src=inet_addr(\"%s\")"
63 ", idiag_dst=inet_addr(\"%s\")"
64 ", idiag_if=" IFINDEX_LO_STR
65 ", idiag_cookie=[0, 0]}"
66 ", idiag_expires=0, idiag_rqueue=0, idiag_wqueue=0"
67 ", idiag_uid=0, idiag_inode=0}",
68 msg_len, address, address);
72 print_uint(const unsigned int *p, size_t i)
74 if (i >= ARRAY_SIZE(sk_meminfo_strs))
75 printf("[%zu /* SK_MEMINFO_??? */", i);
77 printf("[%s", sk_meminfo_strs[i]);
85 skip_if_unavailable("/proc/self/fd/");
87 static const struct inet_diag_meminfo minfo = {
88 .idiag_rmem = 0xfadcacdb,
89 .idiag_wmem = 0xbdabcada,
90 .idiag_fmem = 0xbadbfafb,
91 .idiag_tmem = 0xfdacdadf
93 static const struct tcpvegas_info vegas = {
94 .tcpv_enabled = 0xfadcacdb,
95 .tcpv_rttcnt = 0xbdabcada,
96 .tcpv_rtt = 0xbadbfafb,
97 .tcpv_minrtt = 0xfdacdadf
99 static const struct tcp_dctcp_info dctcp = {
100 .dctcp_enabled = 0xfdac,
101 .dctcp_ce_state = 0xfadc,
102 .dctcp_alpha = 0xbdabcada,
103 .dctcp_ab_ecn = 0xbadbfafb,
104 .dctcp_ab_tot = 0xfdacdadf
106 static const struct tcp_bbr_info bbr = {
107 .bbr_bw_lo = 0xfdacdadf,
108 .bbr_bw_hi = 0xfadcacdb,
109 .bbr_min_rtt = 0xbdabcada,
110 .bbr_pacing_gain = 0xbadbfafb,
111 .bbr_cwnd_gain = 0xfdacdadf
113 static const uint32_t mem[] = { 0xaffacbad, 0xffadbcab };
114 static uint32_t bigmem[SK_MEMINFO_VARS + 1];
115 static const uint32_t mark = 0xabdfadca;
116 static const uint8_t shutdown = 0xcd;
118 const int fd = create_nl_socket(NETLINK_SOCK_DIAG);
119 const unsigned int hdrlen = sizeof(struct inet_diag_msg);
120 void *const nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
122 MAX(sizeof(bigmem), DEFAULT_STRLEN));
124 static char pattern[4096];
125 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
127 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
128 init_inet_diag_msg, print_inet_diag_msg,
129 INET_DIAG_MEMINFO, pattern, minfo,
130 PRINT_FIELD_U("{", minfo, idiag_rmem);
131 PRINT_FIELD_U(", ", minfo, idiag_wmem);
132 PRINT_FIELD_U(", ", minfo, idiag_fmem);
133 PRINT_FIELD_U(", ", minfo, idiag_tmem);
136 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
137 init_inet_diag_msg, print_inet_diag_msg,
138 INET_DIAG_VEGASINFO, pattern, vegas,
139 PRINT_FIELD_U("{", vegas, tcpv_enabled);
140 PRINT_FIELD_U(", ", vegas, tcpv_rttcnt);
141 PRINT_FIELD_U(", ", vegas, tcpv_rtt);
142 PRINT_FIELD_U(", ", vegas, tcpv_minrtt);
146 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
147 init_inet_diag_msg, print_inet_diag_msg,
148 INET_DIAG_DCTCPINFO, pattern, dctcp,
149 PRINT_FIELD_U("{", dctcp, dctcp_enabled);
150 PRINT_FIELD_U(", ", dctcp, dctcp_ce_state);
151 PRINT_FIELD_U(", ", dctcp, dctcp_alpha);
152 PRINT_FIELD_U(", ", dctcp, dctcp_ab_ecn);
153 PRINT_FIELD_U(", ", dctcp, dctcp_ab_tot);
156 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
157 init_inet_diag_msg, print_inet_diag_msg,
158 INET_DIAG_BBRINFO, pattern, bbr,
159 PRINT_FIELD_X("{", bbr, bbr_bw_lo);
160 PRINT_FIELD_X(", ", bbr, bbr_bw_hi);
161 PRINT_FIELD_U(", ", bbr, bbr_min_rtt);
162 PRINT_FIELD_U(", ", bbr, bbr_pacing_gain);
163 PRINT_FIELD_U(", ", bbr, bbr_cwnd_gain);
166 TEST_NLATTR_ARRAY(fd, nlh0, hdrlen,
167 init_inet_diag_msg, print_inet_diag_msg,
168 INET_DIAG_SKMEMINFO, pattern, mem, print_uint);
170 memcpy(bigmem, pattern, sizeof(bigmem));
172 TEST_NLATTR_ARRAY(fd, nlh0, hdrlen,
173 init_inet_diag_msg, print_inet_diag_msg,
174 INET_DIAG_SKMEMINFO, pattern, bigmem, print_uint);
176 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
177 init_inet_diag_msg, print_inet_diag_msg,
178 INET_DIAG_MARK, pattern, mark,
181 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
182 init_inet_diag_msg, print_inet_diag_msg,
183 INET_DIAG_CLASS_ID, pattern, mark,
186 TEST_NLATTR(fd, nlh0, hdrlen,
187 init_inet_diag_msg, print_inet_diag_msg, INET_DIAG_SHUTDOWN,
188 sizeof(shutdown), &shutdown, sizeof(shutdown),
189 printf("%u", shutdown));
191 char *const str = tail_alloc(DEFAULT_STRLEN);
192 fill_memory_ex(str, DEFAULT_STRLEN, '0', 10);
193 TEST_NLATTR(fd, nlh0, hdrlen,
194 init_inet_diag_msg, print_inet_diag_msg, INET_DIAG_CONG,
195 DEFAULT_STRLEN, str, DEFAULT_STRLEN,
196 printf("\"%.*s\"...", DEFAULT_STRLEN, str));
197 str[DEFAULT_STRLEN - 1] = '\0';
198 TEST_NLATTR(fd, nlh0, hdrlen,
199 init_inet_diag_msg, print_inet_diag_msg, INET_DIAG_CONG,
200 DEFAULT_STRLEN, str, DEFAULT_STRLEN,
201 printf("\"%s\"", str));
203 puts("+++ exited with 0 +++");