2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2016-2017 The strace developers.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
31 #include "netlink_route.h"
33 #include "print_fields.h"
36 #ifdef HAVE_LINUX_IF_LINK_H
37 # include <linux/if_link.h>
39 #include <linux/rtnetlink.h>
41 #include "xlat/rtnl_link_attrs.h"
44 decode_rtnl_link_stats(struct tcb *const tcp,
45 const kernel_ulong_t addr,
46 const unsigned int len,
47 const void *const opaque_data)
49 struct rtnl_link_stats st;
50 const unsigned int min_size =
51 offsetofend(struct rtnl_link_stats, tx_compressed);
52 const unsigned int size = len < sizeof(st) ? min_size : sizeof(st);
56 else if (!umoven_or_printaddr(tcp, addr, size, &st)) {
57 PRINT_FIELD_U("{", st, rx_packets);
58 PRINT_FIELD_U(", ", st, tx_packets);
59 PRINT_FIELD_U(", ", st, rx_bytes);
60 PRINT_FIELD_U(", ", st, tx_bytes);
61 PRINT_FIELD_U(", ", st, rx_errors);
62 PRINT_FIELD_U(", ", st, tx_errors);
63 PRINT_FIELD_U(", ", st, rx_dropped);
64 PRINT_FIELD_U(", ", st, tx_dropped);
65 PRINT_FIELD_U(", ", st, multicast);
66 PRINT_FIELD_U(", ", st, collisions);
68 PRINT_FIELD_U(", ", st, rx_length_errors);
69 PRINT_FIELD_U(", ", st, rx_over_errors);
70 PRINT_FIELD_U(", ", st, rx_crc_errors);
71 PRINT_FIELD_U(", ", st, rx_frame_errors);
72 PRINT_FIELD_U(", ", st, rx_fifo_errors);
73 PRINT_FIELD_U(", ", st, rx_missed_errors);
75 PRINT_FIELD_U(", ", st, tx_aborted_errors);
76 PRINT_FIELD_U(", ", st, tx_carrier_errors);
77 PRINT_FIELD_U(", ", st, tx_fifo_errors);
78 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
79 PRINT_FIELD_U(", ", st, tx_window_errors);
81 PRINT_FIELD_U(", ", st, rx_compressed);
82 PRINT_FIELD_U(", ", st, tx_compressed);
83 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
84 if (len >= sizeof(st))
85 PRINT_FIELD_U(", ", st, rx_nohandler);
94 decode_rtnl_link_ifmap(struct tcb *const tcp,
95 const kernel_ulong_t addr,
96 const unsigned int len,
97 const void *const opaque_data)
99 struct rtnl_link_ifmap map;
100 const unsigned int sizeof_ifmap =
101 offsetofend(struct rtnl_link_ifmap, port);
103 if (len < sizeof_ifmap)
105 else if (!umoven_or_printaddr(tcp, addr, sizeof_ifmap, &map)) {
106 PRINT_FIELD_X("{", map, mem_start);
107 PRINT_FIELD_X(", ", map, mem_end);
108 PRINT_FIELD_X(", ", map, base_addr);
109 PRINT_FIELD_U(", ", map, irq);
110 PRINT_FIELD_U(", ", map, dma);
111 PRINT_FIELD_U(", ", map, port);
119 decode_rtnl_link_stats64(struct tcb *const tcp,
120 const kernel_ulong_t addr,
121 const unsigned int len,
122 const void *const opaque_data)
124 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
125 struct rtnl_link_stats64 st;
126 const unsigned int min_size =
127 offsetofend(struct rtnl_link_stats64, tx_compressed);
128 const unsigned int size = len < sizeof(st) ? min_size : sizeof(st);
132 else if (!umoven_or_printaddr(tcp, addr, size, &st)) {
133 PRINT_FIELD_U("{", st, rx_packets);
134 PRINT_FIELD_U(", ", st, tx_packets);
135 PRINT_FIELD_U(", ", st, rx_bytes);
136 PRINT_FIELD_U(", ", st, tx_bytes);
137 PRINT_FIELD_U(", ", st, rx_errors);
138 PRINT_FIELD_U(", ", st, tx_errors);
139 PRINT_FIELD_U(", ", st, rx_dropped);
140 PRINT_FIELD_U(", ", st, tx_dropped);
141 PRINT_FIELD_U(", ", st, multicast);
142 PRINT_FIELD_U(", ", st, collisions);
144 PRINT_FIELD_U(", ", st, rx_length_errors);
145 PRINT_FIELD_U(", ", st, rx_over_errors);
146 PRINT_FIELD_U(", ", st, rx_crc_errors);
147 PRINT_FIELD_U(", ", st, rx_frame_errors);
148 PRINT_FIELD_U(", ", st, rx_fifo_errors);
149 PRINT_FIELD_U(", ", st, rx_missed_errors);
151 PRINT_FIELD_U(", ", st, tx_aborted_errors);
152 PRINT_FIELD_U(", ", st, tx_carrier_errors);
153 PRINT_FIELD_U(", ", st, tx_fifo_errors);
154 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
155 PRINT_FIELD_U(", ", st, tx_window_errors);
157 PRINT_FIELD_U(", ", st, rx_compressed);
158 PRINT_FIELD_U(", ", st, tx_compressed);
159 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
160 if (len >= sizeof(st))
161 PRINT_FIELD_U(", ", st, rx_nohandler);
172 static const nla_decoder_t ifinfomsg_nla_decoders[] = {
173 [IFLA_ADDRESS] = NULL, /* unimplemented */
174 [IFLA_BROADCAST] = NULL, /* unimplemented */
175 [IFLA_IFNAME] = decode_nla_str,
176 [IFLA_MTU] = decode_nla_u32,
177 [IFLA_LINK] = decode_nla_u32,
178 [IFLA_QDISC] = decode_nla_str,
179 [IFLA_STATS] = decode_rtnl_link_stats,
180 [IFLA_COST] = NULL, /* unused */
181 [IFLA_PRIORITY] = NULL, /* unused */
182 [IFLA_MASTER] = decode_nla_u32,
183 [IFLA_WIRELESS] = NULL, /* unimplemented */
184 [IFLA_PROTINFO] = NULL, /* unimplemented */
185 [IFLA_TXQLEN] = decode_nla_u32,
186 [IFLA_MAP] = decode_rtnl_link_ifmap,
187 [IFLA_WEIGHT] = decode_nla_u32,
188 [IFLA_OPERSTATE] = decode_nla_u8,
189 [IFLA_LINKMODE] = decode_nla_u8,
190 [IFLA_LINKINFO] = NULL, /* unimplemented */
191 [IFLA_NET_NS_PID] = decode_nla_u32,
192 [IFLA_IFALIAS] = decode_nla_str,
193 [IFLA_NUM_VF] = decode_nla_u32,
194 [IFLA_VFINFO_LIST] = NULL, /* unimplemented */
195 [IFLA_STATS64] = decode_rtnl_link_stats64,
196 [IFLA_VF_PORTS] = NULL, /* unimplemented */
197 [IFLA_PORT_SELF] = NULL, /* unimplemented */
198 [IFLA_AF_SPEC] = NULL, /* unimplemented */
199 [IFLA_GROUP] = decode_nla_u32,
200 [IFLA_NET_NS_FD] = decode_nla_u32,
201 [IFLA_EXT_MASK] = decode_nla_u32,
202 [IFLA_PROMISCUITY] = decode_nla_u32,
203 [IFLA_NUM_TX_QUEUES] = decode_nla_u32,
204 [IFLA_NUM_RX_QUEUES] = decode_nla_u32,
205 [IFLA_CARRIER] = decode_nla_u8,
206 [IFLA_PHYS_PORT_ID] = NULL, /* default parser */
207 [IFLA_CARRIER_CHANGES] = decode_nla_u32,
208 [IFLA_PHYS_SWITCH_ID] = NULL, /* default parser */
209 [IFLA_LINK_NETNSID] = decode_nla_s32,
210 [IFLA_PHYS_PORT_NAME] = decode_nla_str,
211 [IFLA_PROTO_DOWN] = decode_nla_u8,
212 [IFLA_GSO_MAX_SEGS] = decode_nla_u32,
213 [IFLA_GSO_MAX_SIZE] = decode_nla_u32,
215 [IFLA_XDP] = NULL, /* unimplemented */
216 [IFLA_EVENT] = decode_nla_u32
219 DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
221 struct ifinfomsg ifinfo = { .ifi_family = family };
222 size_t offset = sizeof(ifinfo.ifi_family);
223 bool decode_nla = false;
225 PRINT_FIELD_XVAL("{", ifinfo, ifi_family, addrfams, "AF_???");
228 if (len >= sizeof(ifinfo)) {
229 if (!umoven_or_printaddr(tcp, addr + offset,
230 sizeof(ifinfo) - offset,
231 (void *) &ifinfo + offset)) {
232 PRINT_FIELD_XVAL("", ifinfo, ifi_type,
233 arp_hardware_types, "ARPHRD_???");
234 PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
235 PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
236 iffflags, "IFF_???");
237 PRINT_FIELD_X(", ", ifinfo, ifi_change);
244 offset = NLMSG_ALIGN(sizeof(ifinfo));
245 if (decode_nla && len > offset) {
247 decode_nlattr(tcp, addr + offset, len - offset,
248 rtnl_link_attrs, "IFLA_???",
249 ifinfomsg_nla_decoders,
250 ARRAY_SIZE(ifinfomsg_nla_decoders), NULL);