Skip to content

Commit bf24770

Browse files
committedJul 19, 2017
Move family-specific NETLINK_SOCK_DIAG parsers to separate files
Split netlink_sock_diag.c that grew too big. * defs.h (tcp_states, tcp_state_flags): New xlat prototypes. * netlink_sock_diag.h: New file. * netlink_inet_diag.c: Likewise. * netlink_netlink_diag.c: Likewise. * netlink_packet_diag.c: Likewise. * netlink_smc_diag.c: Likewise. * netlink_unix_diag.c: Likewise. * Makefile.am (strace_SOURCES): Add them. * netlink_sock_diag.c: Move family-specific parsers and associated header includes to separate files. * nlattr.h (DECL_NLA(meminfo)): New prototype. * nlattr.c: Include <linux/sock_diag.h>. (print_meminfo, decode_nla_meminfo): New functions from netlink_sock_diag.c.
1 parent c56a3c3 commit bf24770

11 files changed

+1347
-1158
lines changed
 

‎Makefile.am

+6
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,14 @@ strace_SOURCES = \
183183
net.c \
184184
netlink.c \
185185
netlink.h \
186+
netlink_sock_diag.h \
187+
netlink_inet_diag.c \
188+
netlink_netlink_diag.c \
189+
netlink_packet_diag.c \
186190
netlink_selinux.c \
191+
netlink_smc_diag.c \
187192
netlink_sock_diag.c \
193+
netlink_unix_diag.c \
188194
nlattr.c \
189195
nlattr.h \
190196
nsfs.c \

‎defs.h

+2
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ extern const struct xlat setns_types[];
302302
extern const struct xlat sg_io_info[];
303303
extern const struct xlat socketlayers[];
304304
extern const struct xlat socktypes[];
305+
extern const struct xlat tcp_state_flags[];
306+
extern const struct xlat tcp_states[];
305307
extern const struct xlat whence_codes[];
306308

307309
/* Format of syscall return values */

‎netlink_inet_diag.c

+467
Large diffs are not rendered by default.

‎netlink_netlink_diag.c

+191
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/*
2+
* Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3+
* Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4+
* Copyright (c) 2017 The strace developers.
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
* 3. The name of the author may not be used to endorse or promote products
16+
* derived from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*/
29+
30+
#include "defs.h"
31+
#include "netlink.h"
32+
#include "netlink_sock_diag.h"
33+
#include "nlattr.h"
34+
#include "print_fields.h"
35+
36+
#include <linux/sock_diag.h>
37+
#include <linux/netlink_diag.h>
38+
39+
#include "xlat/netlink_diag_attrs.h"
40+
#include "xlat/netlink_diag_show.h"
41+
#include "xlat/netlink_socket_flags.h"
42+
#include "xlat/netlink_states.h"
43+
44+
DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_req)
45+
{
46+
struct netlink_diag_req req = { .sdiag_family = family };
47+
const size_t offset = sizeof(req.sdiag_family);
48+
49+
PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
50+
tprints(", ");
51+
if (len >= sizeof(req)) {
52+
if (!umoven_or_printaddr(tcp, addr + offset,
53+
sizeof(req) - offset,
54+
(void *) &req + offset)) {
55+
if (NDIAG_PROTO_ALL == req.sdiag_protocol)
56+
tprintf("%s=%s",
57+
"sdiag_protocol", "NDIAG_PROTO_ALL");
58+
else
59+
PRINT_FIELD_XVAL("", req, sdiag_protocol,
60+
netlink_protocols,
61+
"NETLINK_???");
62+
PRINT_FIELD_U(", ", req, ndiag_ino);
63+
PRINT_FIELD_FLAGS(", ", req, ndiag_show,
64+
netlink_diag_show, "NDIAG_SHOW_???");
65+
PRINT_FIELD_COOKIE(", ", req, ndiag_cookie);
66+
}
67+
} else
68+
tprints("...");
69+
tprints("}");
70+
}
71+
72+
static bool
73+
print_group(struct tcb *const tcp,
74+
void *const elem_buf,
75+
const size_t elem_size,
76+
void *const opaque_data)
77+
{
78+
if (elem_size < sizeof(kernel_ulong_t))
79+
tprintf("%#0*x", (int) elem_size * 2 + 2,
80+
*(unsigned int *) elem_buf);
81+
else
82+
tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
83+
*(kernel_ulong_t *) elem_buf);
84+
85+
return true;
86+
}
87+
88+
static bool
89+
decode_netlink_diag_groups(struct tcb *const tcp,
90+
const kernel_ulong_t addr,
91+
const unsigned int len,
92+
const void *const opaque_data)
93+
{
94+
kernel_ulong_t buf;
95+
const size_t nmemb = len / current_wordsize;
96+
97+
if (!nmemb)
98+
return false;
99+
100+
print_array(tcp, addr, nmemb, &buf, current_wordsize,
101+
umoven_or_printaddr, print_group, 0);
102+
103+
return true;
104+
}
105+
106+
static bool
107+
decode_netlink_diag_ring(struct tcb *const tcp,
108+
const kernel_ulong_t addr,
109+
const unsigned int len,
110+
const void *const opaque_data)
111+
{
112+
struct netlink_diag_ring ndr;
113+
114+
if (len < sizeof(ndr))
115+
return false;
116+
if (umove_or_printaddr(tcp, addr, &ndr))
117+
return true;
118+
119+
PRINT_FIELD_U("{", ndr, ndr_block_size);
120+
PRINT_FIELD_U(", ", ndr, ndr_block_nr);
121+
PRINT_FIELD_U(", ", ndr, ndr_frame_size);
122+
PRINT_FIELD_U(", ", ndr, ndr_frame_nr);
123+
tprints("}");
124+
125+
return true;
126+
}
127+
128+
static bool
129+
decode_netlink_diag_flags(struct tcb *const tcp,
130+
const kernel_ulong_t addr,
131+
const unsigned int len,
132+
const void *const opaque_data)
133+
{
134+
uint32_t flags;
135+
136+
if (len < sizeof(flags))
137+
return false;
138+
if (umove_or_printaddr(tcp, addr, &flags))
139+
return true;
140+
141+
printflags(netlink_socket_flags, flags, "NDIAG_FLAG_???");
142+
143+
return true;
144+
}
145+
146+
static const nla_decoder_t netlink_diag_msg_nla_decoders[] = {
147+
[NETLINK_DIAG_MEMINFO] = decode_nla_meminfo,
148+
[NETLINK_DIAG_GROUPS] = decode_netlink_diag_groups,
149+
[NETLINK_DIAG_RX_RING] = decode_netlink_diag_ring,
150+
[NETLINK_DIAG_TX_RING] = decode_netlink_diag_ring,
151+
[NETLINK_DIAG_FLAGS] = decode_netlink_diag_flags
152+
};
153+
154+
DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_msg)
155+
{
156+
struct netlink_diag_msg msg = { .ndiag_family = family };
157+
size_t offset = sizeof(msg.ndiag_family);
158+
bool decode_nla = false;
159+
160+
PRINT_FIELD_XVAL("{", msg, ndiag_family, addrfams, "AF_???");
161+
tprints(", ");
162+
if (len >= sizeof(msg)) {
163+
if (!umoven_or_printaddr(tcp, addr + offset,
164+
sizeof(msg) - offset,
165+
(void *) &msg + offset)) {
166+
PRINT_FIELD_XVAL("", msg, ndiag_type,
167+
socktypes, "SOCK_???");
168+
PRINT_FIELD_XVAL(", ", msg, ndiag_protocol,
169+
netlink_protocols, "NETLINK_???");
170+
PRINT_FIELD_XVAL(", ", msg, ndiag_state,
171+
netlink_states, "NETLINK_???");
172+
PRINT_FIELD_U(", ", msg, ndiag_portid);
173+
PRINT_FIELD_U(", ", msg, ndiag_dst_portid);
174+
PRINT_FIELD_U(", ", msg, ndiag_dst_group);
175+
PRINT_FIELD_U(", ", msg, ndiag_ino);
176+
PRINT_FIELD_COOKIE(", ", msg, ndiag_cookie);
177+
decode_nla = true;
178+
}
179+
} else
180+
tprints("...");
181+
tprints("}");
182+
183+
offset = NLA_ALIGN(sizeof(msg));
184+
if (decode_nla && len > offset) {
185+
tprints(", ");
186+
decode_nlattr(tcp, addr + offset, len - offset,
187+
netlink_diag_attrs, "NETLINK_DIAG_???",
188+
netlink_diag_msg_nla_decoders,
189+
ARRAY_SIZE(netlink_diag_msg_nla_decoders), NULL);
190+
}
191+
}

‎netlink_packet_diag.c

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/*
2+
* Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3+
* Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4+
* Copyright (c) 2017 The strace developers.
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
* 3. The name of the author may not be used to endorse or promote products
16+
* derived from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*/
29+
30+
#include "defs.h"
31+
#include "netlink.h"
32+
#include "netlink_sock_diag.h"
33+
#include "nlattr.h"
34+
#include "print_fields.h"
35+
36+
#include <linux/filter.h>
37+
#include <linux/sock_diag.h>
38+
#include <linux/packet_diag.h>
39+
40+
#include "xlat/packet_diag_attrs.h"
41+
#include "xlat/packet_diag_info_flags.h"
42+
#include "xlat/packet_diag_show.h"
43+
44+
DECL_NETLINK_DIAG_DECODER(decode_packet_diag_req)
45+
{
46+
struct packet_diag_req req = { .sdiag_family = family };
47+
const size_t offset = sizeof(req.sdiag_family);
48+
49+
PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
50+
tprints(", ");
51+
if (len >= sizeof(req)) {
52+
if (!umoven_or_printaddr(tcp, addr + offset,
53+
sizeof(req) - offset,
54+
(void *) &req + offset)) {
55+
PRINT_FIELD_XVAL("", req, sdiag_protocol,
56+
ethernet_protocols, "ETH_P_???");
57+
PRINT_FIELD_U(", ", req, pdiag_ino);
58+
PRINT_FIELD_FLAGS(", ", req, pdiag_show,
59+
packet_diag_show, "PACKET_SHOW_???");
60+
PRINT_FIELD_COOKIE(", ", req, pdiag_cookie);
61+
}
62+
} else
63+
tprints("...");
64+
tprints("}");
65+
}
66+
67+
static bool
68+
decode_packet_diag_info(struct tcb *const tcp,
69+
const kernel_ulong_t addr,
70+
const unsigned int len,
71+
const void *const opaque_data)
72+
{
73+
struct packet_diag_info pinfo;
74+
75+
if (len < sizeof(pinfo))
76+
return false;
77+
if (umove_or_printaddr(tcp, addr, &pinfo))
78+
return true;
79+
80+
PRINT_FIELD_U("{", pinfo, pdi_index);
81+
PRINT_FIELD_U(", ", pinfo, pdi_version);
82+
PRINT_FIELD_U(", ", pinfo, pdi_reserve);
83+
PRINT_FIELD_U(", ", pinfo, pdi_copy_thresh);
84+
PRINT_FIELD_U(", ", pinfo, pdi_tstamp);
85+
PRINT_FIELD_FLAGS(", ", pinfo, pdi_flags,
86+
packet_diag_info_flags, "PDI_???");
87+
tprints("}");
88+
89+
return true;
90+
}
91+
92+
static bool
93+
print_packet_diag_mclist(struct tcb *const tcp, void *const elem_buf,
94+
const size_t elem_size, void *const opaque_data)
95+
{
96+
struct packet_diag_mclist *dml = elem_buf;
97+
uint16_t alen = dml->pdmc_alen > sizeof(dml->pdmc_addr) ?
98+
sizeof(dml->pdmc_addr) : dml->pdmc_alen;
99+
100+
PRINT_FIELD_IFINDEX("{", *dml, pdmc_index);
101+
PRINT_FIELD_U(", ", *dml, pdmc_count);
102+
PRINT_FIELD_U(", ", *dml, pdmc_type);
103+
PRINT_FIELD_U(", ", *dml, pdmc_alen);
104+
PRINT_FIELD_STRING(", ", *dml, pdmc_addr, alen, QUOTE_FORCE_HEX);
105+
tprints("}");
106+
107+
return true;
108+
}
109+
110+
static bool
111+
decode_packet_diag_mclist(struct tcb *const tcp,
112+
const kernel_ulong_t addr,
113+
const unsigned int len,
114+
const void *const opaque_data)
115+
{
116+
struct packet_diag_mclist dml;
117+
const size_t nmemb = len / sizeof(dml);
118+
119+
if (!nmemb)
120+
return false;
121+
122+
print_array(tcp, addr, nmemb, &dml, sizeof(dml),
123+
umoven_or_printaddr, print_packet_diag_mclist, 0);
124+
125+
return true;
126+
}
127+
128+
static bool
129+
decode_packet_diag_ring(struct tcb *const tcp,
130+
const kernel_ulong_t addr,
131+
const unsigned int len,
132+
const void *const opaque_data)
133+
{
134+
struct packet_diag_ring pdr;
135+
136+
if (len < sizeof(pdr))
137+
return false;
138+
if (umove_or_printaddr(tcp, addr, &pdr))
139+
return true;
140+
141+
PRINT_FIELD_U("{", pdr, pdr_block_size);
142+
PRINT_FIELD_U(", ", pdr, pdr_block_nr);
143+
PRINT_FIELD_U(", ", pdr, pdr_frame_size);
144+
PRINT_FIELD_U(", ", pdr, pdr_frame_nr);
145+
PRINT_FIELD_U(", ", pdr, pdr_retire_tmo);
146+
PRINT_FIELD_U(", ", pdr, pdr_sizeof_priv);
147+
PRINT_FIELD_U(", ", pdr, pdr_features);
148+
tprints("}");
149+
150+
return true;
151+
}
152+
153+
static bool
154+
decode_packet_diag_filter(struct tcb *const tcp,
155+
const kernel_ulong_t addr,
156+
const unsigned int len,
157+
const void *const opaque_data)
158+
{
159+
const unsigned int nmemb = len / sizeof(struct sock_filter);
160+
if (!nmemb || (unsigned short) nmemb != nmemb)
161+
return false;
162+
163+
print_sock_fprog(tcp, addr, nmemb);
164+
165+
return true;
166+
}
167+
168+
static const nla_decoder_t packet_diag_msg_nla_decoders[] = {
169+
[PACKET_DIAG_INFO] = decode_packet_diag_info,
170+
[PACKET_DIAG_MCLIST] = decode_packet_diag_mclist,
171+
[PACKET_DIAG_RX_RING] = decode_packet_diag_ring,
172+
[PACKET_DIAG_TX_RING] = decode_packet_diag_ring,
173+
[PACKET_DIAG_FANOUT] = decode_nla_u32,
174+
[PACKET_DIAG_UID] = decode_nla_u32,
175+
[PACKET_DIAG_MEMINFO] = decode_nla_meminfo,
176+
[PACKET_DIAG_FILTER] = decode_packet_diag_filter
177+
};
178+
179+
DECL_NETLINK_DIAG_DECODER(decode_packet_diag_msg)
180+
{
181+
struct packet_diag_msg msg = { .pdiag_family = family };
182+
size_t offset = sizeof(msg.pdiag_family);
183+
bool decode_nla = false;
184+
185+
PRINT_FIELD_XVAL("{", msg, pdiag_family, addrfams, "AF_???");
186+
tprints(", ");
187+
if (len >= sizeof(msg)) {
188+
if (!umoven_or_printaddr(tcp, addr + offset,
189+
sizeof(msg) - offset,
190+
(void *) &msg + offset)) {
191+
PRINT_FIELD_XVAL("", msg, pdiag_type,
192+
socktypes, "SOCK_???");
193+
PRINT_FIELD_U(", ", msg, pdiag_num);
194+
PRINT_FIELD_U(", ", msg, pdiag_ino);
195+
PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
196+
decode_nla = true;
197+
}
198+
} else
199+
tprints("...");
200+
tprints("}");
201+
202+
offset = NLA_ALIGN(sizeof(msg));
203+
if (decode_nla && len > offset) {
204+
tprints(", ");
205+
decode_nlattr(tcp, addr + offset, len - offset,
206+
packet_diag_attrs, "PACKET_DIAG_???",
207+
packet_diag_msg_nla_decoders,
208+
ARRAY_SIZE(packet_diag_msg_nla_decoders), NULL);
209+
}
210+
}

‎netlink_smc_diag.c

+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
* Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3+
* Copyright (c) 2017 The strace developers.
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
* 3. The name of the author may not be used to endorse or promote products
15+
* derived from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#include "defs.h"
30+
#include <sys/socket.h>
31+
32+
#ifdef AF_SMC
33+
34+
# include "netlink.h"
35+
# include "netlink_sock_diag.h"
36+
# include "nlattr.h"
37+
# include "print_fields.h"
38+
39+
# include <arpa/inet.h>
40+
# include <linux/smc_diag.h>
41+
42+
# include "xlat/smc_diag_attrs.h"
43+
# include "xlat/smc_diag_extended_flags.h"
44+
# include "xlat/smc_link_group_roles.h"
45+
# include "xlat/smc_states.h"
46+
47+
DECL_NETLINK_DIAG_DECODER(decode_smc_diag_req)
48+
{
49+
struct smc_diag_req req = { .diag_family = family };
50+
const size_t offset = sizeof(req.diag_family);
51+
52+
PRINT_FIELD_XVAL("{", req, diag_family, addrfams, "AF_???");
53+
tprints(", ");
54+
if (len >= sizeof(req)) {
55+
if (!umoven_or_printaddr(tcp, addr + offset,
56+
sizeof(req) - offset,
57+
(void *) &req + offset)) {
58+
PRINT_FIELD_FLAGS("", req, diag_ext,
59+
smc_diag_extended_flags,
60+
"1<<SMC_DIAG_\?\?\?-1");
61+
/*
62+
* AF_SMC protocol family socket handler
63+
* keeping the AF_INET sock address.
64+
*/
65+
PRINT_FIELD_INET_DIAG_SOCKID(", ", req, id, AF_INET);
66+
}
67+
} else
68+
tprints("...");
69+
tprints("}");
70+
}
71+
72+
static void
73+
print_smc_diag_cursor(const struct smc_diag_cursor *const cursor)
74+
{
75+
PRINT_FIELD_U("{", *cursor, reserved);
76+
PRINT_FIELD_U(", ", *cursor, wrap);
77+
PRINT_FIELD_U(", ", *cursor, count);
78+
tprints("}");
79+
}
80+
81+
# define PRINT_FIELD_SMC_DIAG_CURSOR(prefix_, where_, field_) \
82+
do { \
83+
tprintf("%s%s=", (prefix_), #field_); \
84+
print_smc_diag_cursor(&(where_).field_); \
85+
} while (0)
86+
87+
static bool
88+
decode_smc_diag_conninfo(struct tcb *const tcp,
89+
const kernel_ulong_t addr,
90+
const unsigned int len,
91+
const void *const opaque_data)
92+
{
93+
struct smc_diag_conninfo cinfo;
94+
95+
if (len < sizeof(cinfo))
96+
return false;
97+
if (umove_or_printaddr(tcp, addr, &cinfo))
98+
return true;
99+
100+
PRINT_FIELD_U("{", cinfo, token);
101+
PRINT_FIELD_U(", ", cinfo, sndbuf_size);
102+
PRINT_FIELD_U(", ", cinfo, rmbe_size);
103+
PRINT_FIELD_U(", ", cinfo, peer_rmbe_size);
104+
PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, rx_prod);
105+
PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, rx_cons);
106+
PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_prod);
107+
PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_cons);
108+
PRINT_FIELD_0X(", ", cinfo, rx_prod_flags);
109+
PRINT_FIELD_0X(", ", cinfo, rx_conn_state_flags);
110+
PRINT_FIELD_0X(", ", cinfo, tx_prod_flags);
111+
PRINT_FIELD_0X(", ", cinfo, tx_conn_state_flags);
112+
PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_prep);
113+
PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_sent);
114+
PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_fin);
115+
tprints("}");
116+
117+
return true;
118+
}
119+
120+
static bool
121+
decode_smc_diag_lgrinfo(struct tcb *const tcp,
122+
const kernel_ulong_t addr,
123+
const unsigned int len,
124+
const void *const opaque_data)
125+
{
126+
struct smc_diag_lgrinfo linfo;
127+
128+
if (len < sizeof(linfo))
129+
return false;
130+
if (umove_or_printaddr(tcp, addr, &linfo))
131+
return true;
132+
133+
tprints("{lnk[0]={");
134+
PRINT_FIELD_U("", linfo.lnk[0], link_id);
135+
PRINT_FIELD_CSTRING(", ", linfo.lnk[0], ibname);
136+
PRINT_FIELD_U(", ", linfo.lnk[0], ibport);
137+
PRINT_FIELD_CSTRING(", ", linfo.lnk[0], gid);
138+
PRINT_FIELD_CSTRING(", ", linfo.lnk[0], peer_gid);
139+
PRINT_FIELD_XVAL("}, ", linfo, role, smc_link_group_roles, "SMC_???");
140+
tprints("}");
141+
142+
return true;
143+
}
144+
145+
static const nla_decoder_t smc_diag_msg_nla_decoders[] = {
146+
[SMC_DIAG_CONNINFO] = decode_smc_diag_conninfo,
147+
[SMC_DIAG_LGRINFO] = decode_smc_diag_lgrinfo,
148+
[SMC_DIAG_SHUTDOWN] = decode_nla_u8
149+
};
150+
151+
DECL_NETLINK_DIAG_DECODER(decode_smc_diag_msg)
152+
{
153+
struct smc_diag_msg msg = { .diag_family = family };
154+
size_t offset = sizeof(msg.diag_family);
155+
bool decode_nla = false;
156+
157+
PRINT_FIELD_XVAL("{", msg, diag_family, addrfams, "AF_???");
158+
tprints(", ");
159+
if (len >= sizeof(msg)) {
160+
if (!umoven_or_printaddr(tcp, addr + offset,
161+
sizeof(msg) - offset,
162+
(void *) &msg + offset)) {
163+
PRINT_FIELD_XVAL("", msg, diag_state,
164+
smc_states, "SMC_???");
165+
PRINT_FIELD_U(", ", msg, diag_fallback);
166+
PRINT_FIELD_U(", ", msg, diag_shutdown);
167+
/*
168+
* AF_SMC protocol family socket handler
169+
* keeping the AF_INET sock address.
170+
*/
171+
PRINT_FIELD_INET_DIAG_SOCKID(", ", msg, id, AF_INET);
172+
PRINT_FIELD_U(", ", msg, diag_uid);
173+
PRINT_FIELD_U(", ", msg, diag_inode);
174+
decode_nla = true;
175+
}
176+
} else
177+
tprints("...");
178+
tprints("}");
179+
180+
offset = NLA_ALIGN(sizeof(msg));
181+
if (decode_nla && len > offset) {
182+
tprints(", ");
183+
decode_nlattr(tcp, addr + offset, len - offset,
184+
smc_diag_attrs, "SMC_DIAG_???",
185+
smc_diag_msg_nla_decoders,
186+
ARRAY_SIZE(smc_diag_msg_nla_decoders), NULL);
187+
}
188+
}
189+
190+
#endif /* AF_SMC */

‎netlink_sock_diag.c

+2-1,158
Large diffs are not rendered by default.

‎netlink_sock_diag.h

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3+
* Copyright (c) 2016-2017 The strace developers.
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
* 3. The name of the author may not be used to endorse or promote products
15+
* derived from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#ifndef STRACE_NETLINK_SOCK_DIAG_H
30+
#define STRACE_NETLINK_SOCK_DIAG_H
31+
32+
#define DECL_NETLINK_DIAG_DECODER(diag_decode_name) \
33+
void \
34+
diag_decode_name(struct tcb *tcp, \
35+
const struct nlmsghdr *nlmsghdr, \
36+
uint8_t family, \
37+
kernel_ulong_t addr, \
38+
unsigned int len)
39+
40+
extern DECL_NETLINK_DIAG_DECODER(decode_inet_diag_msg);
41+
extern DECL_NETLINK_DIAG_DECODER(decode_inet_diag_req);
42+
extern DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_msg);
43+
extern DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_req);
44+
extern DECL_NETLINK_DIAG_DECODER(decode_packet_diag_msg);
45+
extern DECL_NETLINK_DIAG_DECODER(decode_packet_diag_req);
46+
extern DECL_NETLINK_DIAG_DECODER(decode_smc_diag_msg);
47+
extern DECL_NETLINK_DIAG_DECODER(decode_smc_diag_req);
48+
extern DECL_NETLINK_DIAG_DECODER(decode_unix_diag_msg);
49+
extern DECL_NETLINK_DIAG_DECODER(decode_unix_diag_req);
50+
51+
struct inet_diag_sockid;
52+
53+
extern void
54+
print_inet_diag_sockid(const struct inet_diag_sockid *, const uint8_t family);
55+
56+
#define PRINT_FIELD_INET_DIAG_SOCKID(prefix_, where_, field_, af_) \
57+
do { \
58+
STRACE_PRINTF("%s%s=", (prefix_), #field_); \
59+
print_inet_diag_sockid(&(where_).field_, (af_)); \
60+
} while (0)
61+
62+
63+
#endif /* !STRACE_NETLINK_SOCK_DIAG_H */

‎netlink_unix_diag.c

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3+
* Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4+
* Copyright (c) 2017 The strace developers.
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
* 3. The name of the author may not be used to endorse or promote products
16+
* derived from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*/
29+
30+
#include "defs.h"
31+
#include "netlink.h"
32+
#include "netlink_sock_diag.h"
33+
#include "nlattr.h"
34+
#include "print_fields.h"
35+
36+
#include <linux/sock_diag.h>
37+
#include <linux/unix_diag.h>
38+
39+
#include "xlat/unix_diag_attrs.h"
40+
#include "xlat/unix_diag_show.h"
41+
42+
DECL_NETLINK_DIAG_DECODER(decode_unix_diag_req)
43+
{
44+
struct unix_diag_req req = { .sdiag_family = family };
45+
const size_t offset = sizeof(req.sdiag_family);
46+
47+
PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
48+
tprints(", ");
49+
if (len >= sizeof(req)) {
50+
if (!umoven_or_printaddr(tcp, addr + offset,
51+
sizeof(req) - offset,
52+
(void *) &req + offset)) {
53+
PRINT_FIELD_U("", req, sdiag_protocol);
54+
PRINT_FIELD_FLAGS(", ", req, udiag_states,
55+
tcp_state_flags, "1<<TCP_???");
56+
PRINT_FIELD_U(", ", req, udiag_ino);
57+
PRINT_FIELD_FLAGS(", ", req, udiag_show,
58+
unix_diag_show, "UDIAG_SHOW_???");
59+
PRINT_FIELD_COOKIE(", ", req, udiag_cookie);
60+
}
61+
} else
62+
tprints("...");
63+
tprints("}");
64+
}
65+
66+
static bool
67+
decode_unix_diag_vfs(struct tcb *const tcp,
68+
const kernel_ulong_t addr,
69+
const unsigned int len,
70+
const void *const opaque_data)
71+
{
72+
struct unix_diag_vfs uv;
73+
74+
if (len < sizeof(uv))
75+
return false;
76+
if (umove_or_printaddr(tcp, addr, &uv))
77+
return true;
78+
79+
PRINT_FIELD_DEV("{", uv, udiag_vfs_dev);
80+
PRINT_FIELD_U(", ", uv, udiag_vfs_ino);
81+
tprints("}");
82+
83+
return true;
84+
}
85+
86+
static bool
87+
print_inode(struct tcb *const tcp,
88+
void *const elem_buf,
89+
const size_t elem_size,
90+
void *const opaque_data)
91+
{
92+
tprintf("%" PRIu32, *(uint32_t *) elem_buf);
93+
94+
return true;
95+
}
96+
97+
static bool
98+
decode_unix_diag_inode(struct tcb *const tcp,
99+
const kernel_ulong_t addr,
100+
const unsigned int len,
101+
const void *const opaque_data)
102+
{
103+
uint32_t inode;
104+
const size_t nmemb = len / sizeof(inode);
105+
106+
if (!nmemb)
107+
return false;
108+
109+
print_array(tcp, addr, nmemb, &inode, sizeof(inode),
110+
umoven_or_printaddr, print_inode, 0);
111+
112+
return true;
113+
}
114+
115+
static bool
116+
decode_unix_diag_rqlen(struct tcb *const tcp,
117+
const kernel_ulong_t addr,
118+
const unsigned int len,
119+
const void *const opaque_data)
120+
{
121+
struct unix_diag_rqlen rql;
122+
123+
if (len < sizeof(rql))
124+
return false;
125+
if (umove_or_printaddr(tcp, addr, &rql))
126+
return true;
127+
128+
PRINT_FIELD_U("{", rql, udiag_rqueue);
129+
PRINT_FIELD_U(", ", rql, udiag_wqueue);
130+
tprints("}");
131+
132+
return true;
133+
}
134+
135+
static const nla_decoder_t unix_diag_msg_nla_decoders[] = {
136+
[UNIX_DIAG_NAME] = decode_nla_str,
137+
[UNIX_DIAG_VFS] = decode_unix_diag_vfs,
138+
[UNIX_DIAG_PEER] = decode_nla_u32,
139+
[UNIX_DIAG_ICONS] = decode_unix_diag_inode,
140+
[UNIX_DIAG_RQLEN] = decode_unix_diag_rqlen,
141+
[UNIX_DIAG_MEMINFO] = decode_nla_meminfo,
142+
[UNIX_DIAG_SHUTDOWN] = decode_nla_u8
143+
};
144+
145+
DECL_NETLINK_DIAG_DECODER(decode_unix_diag_msg)
146+
{
147+
struct unix_diag_msg msg = { .udiag_family = family };
148+
size_t offset = sizeof(msg.udiag_family);
149+
bool decode_nla = false;
150+
151+
PRINT_FIELD_XVAL("{", msg, udiag_family, addrfams, "AF_???");
152+
tprints(", ");
153+
if (len >= sizeof(msg)) {
154+
if (!umoven_or_printaddr(tcp, addr + offset,
155+
sizeof(msg) - offset,
156+
(void *) &msg + offset)) {
157+
PRINT_FIELD_XVAL("", msg, udiag_type,
158+
socktypes, "SOCK_???");
159+
PRINT_FIELD_XVAL(", ", msg, udiag_state,
160+
tcp_states, "TCP_???");
161+
PRINT_FIELD_U(", ", msg, udiag_ino);
162+
PRINT_FIELD_COOKIE(", ", msg, udiag_cookie);
163+
decode_nla = true;
164+
}
165+
} else
166+
tprints("...");
167+
tprints("}");
168+
169+
offset = NLMSG_ALIGN(sizeof(msg));
170+
if (decode_nla && len > offset) {
171+
tprints(", ");
172+
decode_nlattr(tcp, addr + offset, len - offset,
173+
unix_diag_attrs, "UNIX_DIAG_???",
174+
unix_diag_msg_nla_decoders,
175+
ARRAY_SIZE(unix_diag_msg_nla_decoders), NULL);
176+
}
177+
}

‎nlattr.c

+38
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "defs.h"
3131
#include "netlink.h"
3232
#include "nlattr.h"
33+
#include <linux/sock_diag.h>
3334

3435
static bool
3536
fetch_nlattr(struct tcb *const tcp, struct nlattr *const nlattr,
@@ -166,6 +167,43 @@ decode_nla_strn(struct tcb *const tcp,
166167
return true;
167168
}
168169

170+
static bool
171+
print_meminfo(struct tcb *const tcp,
172+
void *const elem_buf,
173+
const size_t elem_size,
174+
void *const opaque_data)
175+
{
176+
unsigned int *const count = opaque_data;
177+
178+
if ((*count)++ >= SK_MEMINFO_VARS) {
179+
tprints("...");
180+
return false;
181+
}
182+
183+
tprintf("%" PRIu32, *(uint32_t *) elem_buf);
184+
185+
return true;
186+
}
187+
188+
bool
189+
decode_nla_meminfo(struct tcb *const tcp,
190+
const kernel_ulong_t addr,
191+
const unsigned int len,
192+
const void *const opaque_data)
193+
{
194+
uint32_t mem;
195+
const size_t nmemb = len / sizeof(mem);
196+
197+
if (!nmemb)
198+
return false;
199+
200+
unsigned int count = 0;
201+
print_array(tcp, addr, nmemb, &mem, sizeof(mem),
202+
umoven_or_printaddr, print_meminfo, &count);
203+
204+
return true;
205+
}
206+
169207
#define DECODE_NLA_INTEGER(name, type, fmt) \
170208
bool \
171209
decode_nla_ ## name(struct tcb *const tcp, \

‎nlattr.h

+1
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,6 @@ DECL_NLA(s32);
5656
DECL_NLA(s64);
5757
DECL_NLA(str);
5858
DECL_NLA(strn);
59+
DECL_NLA(meminfo);
5960

6061
#endif /* !STRACE_NLATTR_H */

0 commit comments

Comments
 (0)
Please sign in to comment.