1 /*
2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2016-2021 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-or-later
8 */
9
10 #include "defs.h"
11 #include "netlink_route.h"
12 #include "nlattr.h"
13
14 #include <linux/ip.h>
15 #include <linux/rtnetlink.h>
16
17 #include "xlat/ip_type_of_services.h"
18 #include "xlat/lwtunnel_encap_types.h"
19 #include "xlat/route_nexthop_flags.h"
20 #include "xlat/routing_flags.h"
21 #include "xlat/routing_protocols.h"
22 #include "xlat/routing_table_ids.h"
23 #include "xlat/routing_types.h"
24 #include "xlat/rtnl_route_attrs.h"
25 #include "xlat/rtnl_rta_metrics_attrs.h"
26
27 bool
28 decode_nla_rt_class(struct tcb *const tcp,
29 const kernel_ulong_t addr,
30 const unsigned int len,
31 const void *const opaque_data)
32 {
33 uint32_t num;
34
35 if (len < sizeof(num))
36 return false;
37 if (!umove_or_printaddr(tcp, addr, &num))
38 printxval(routing_table_ids, num, NULL);
39 return true;
40 }
41
42 bool
43 decode_nla_rt_proto(struct tcb *const tcp,
44 const kernel_ulong_t addr,
45 const unsigned int len,
46 const void *const opaque_data)
47 {
48 uint8_t num;
49
50 if (len < sizeof(num))
51 return false;
52 if (!umove_or_printaddr(tcp, addr, &num))
53 printxval(routing_protocols, num, "RTPROT_???");
54 return true;
55 }
56
57 static bool
58 decode_route_addr(struct tcb *const tcp,
59 const kernel_ulong_t addr,
60 const unsigned int len,
61 const void *const opaque_data)
62 {
63 const struct rtmsg *const rtmsg = opaque_data;
64
65 decode_inet_addr(tcp, addr, len, rtmsg->rtm_family, NULL);
66
67 return true;
68 }
69
70 static const nla_decoder_t rta_metrics_nla_decoders[] = {
71 [RTAX_LOCK] = decode_nla_u32,
72 [RTAX_MTU] = decode_nla_u32,
73 [RTAX_WINDOW] = decode_nla_u32,
74 [RTAX_RTT] = decode_nla_u32,
75 [RTAX_RTTVAR] = decode_nla_u32,
76 [RTAX_SSTHRESH] = decode_nla_u32,
77 [RTAX_CWND] = decode_nla_u32,
78 [RTAX_ADVMSS] = decode_nla_u32,
79 [RTAX_REORDERING] = decode_nla_u32,
80 [RTAX_HOPLIMIT] = decode_nla_u32,
81 [RTAX_INITCWND] = decode_nla_u32,
82 [RTAX_FEATURES] = decode_nla_u32,
83 [RTAX_RTO_MIN] = decode_nla_u32,
84 [RTAX_INITRWND] = decode_nla_u32,
85 [RTAX_QUICKACK] = decode_nla_u32,
86 [RTAX_CC_ALGO] = decode_nla_str
87 };
88
89 static bool
90 decode_rta_metrics(struct tcb *const tcp,
91 const kernel_ulong_t addr,
92 const unsigned int len,
93 const void *const opaque_data)
94 {
95 decode_nlattr(tcp, addr, len, rtnl_rta_metrics_attrs,
96 "RTAX_???", rta_metrics_nla_decoders,
97 ARRAY_SIZE(rta_metrics_nla_decoders), opaque_data);
98
99 return true;
100 }
101
102 static bool
103 decode_rta_multipath(struct tcb *const tcp,
104 const kernel_ulong_t addr,
105 const unsigned int len,
106 const void *const opaque_data);
107
108 static bool
109 decode_rta_cacheinfo(struct tcb *const tcp,
110 const kernel_ulong_t addr,
111 const unsigned int len,
112 const void *const opaque_data)
113 {
114 struct rta_cacheinfo ci;
115
116 if (len < sizeof(ci))
117 return false;
118 else if (!umove_or_printaddr(tcp, addr, &ci)) {
119 tprint_struct_begin();
120 PRINT_FIELD_U(ci, rta_clntref);
121 tprint_struct_next();
122 PRINT_FIELD_U(ci, rta_lastuse);
123 tprint_struct_next();
124 PRINT_FIELD_U(ci, rta_expires);
125 tprint_struct_next();
126 PRINT_FIELD_U(ci, rta_error);
127 tprint_struct_next();
128 PRINT_FIELD_U(ci, rta_used);
129 tprint_struct_next();
130 PRINT_FIELD_X(ci, rta_id);
131 tprint_struct_next();
132 PRINT_FIELD_U(ci, rta_ts);
133 tprint_struct_next();
134 PRINT_FIELD_U(ci, rta_tsage);
135 tprint_struct_end();
136 }
137
138 return true;
139 }
140
141 static bool
142 decode_rta_mfc_stats(struct tcb *const tcp,
143 const kernel_ulong_t addr,
144 const unsigned int len,
145 const void *const opaque_data)
146 {
147 struct rta_mfc_stats mfcs;
148
149 if (len < sizeof(mfcs))
150 return false;
151 else if (!umove_or_printaddr(tcp, addr, &mfcs)) {
152 tprint_struct_begin();
153 PRINT_FIELD_U(mfcs, mfcs_packets);
154 tprint_struct_next();
155 PRINT_FIELD_U(mfcs, mfcs_bytes);
156 tprint_struct_next();
157 PRINT_FIELD_U(mfcs, mfcs_wrong_if);
158 tprint_struct_end();
159 }
160
161 return true;
162 }
163
164 static bool
165 decode_rtvia(struct tcb *const tcp,
166 const kernel_ulong_t addr,
167 const unsigned int len,
168 const void *const opaque_data)
169 {
170 struct rtvia via;
171
172 if (len < sizeof(via))
173 return false;
174 else if (!umove_or_printaddr(tcp, addr, &via)) {
175 tprint_struct_begin();
176 PRINT_FIELD_XVAL(via, rtvia_family, addrfams, "AF_???");
177
178 const unsigned int offset = offsetof(struct rtvia, rtvia_addr);
179
180 if (len > offset) {
181 tprint_struct_next();
182 decode_inet_addr(tcp, addr + offset, len - offset,
183 via.rtvia_family, "rtvia_addr");
184 }
185 tprint_struct_end();
186 }
187
188 return true;
189 }
190
191 bool
192 decode_nla_lwt_encap_type(struct tcb *const tcp,
193 const kernel_ulong_t addr,
194 const unsigned int len,
195 const void *const opaque_data)
196 {
197 uint16_t type;
198
199 if (len < sizeof(type))
200 return false;
201 else if (!umove_or_printaddr(tcp, addr, &type))
202 printxval(lwtunnel_encap_types, type, "LWTUNNEL_ENCAP_???");
203
204 return true;
205 }
206
207 static const nla_decoder_t rtmsg_nla_decoders[] = {
208 [RTA_DST] = decode_route_addr,
209 [RTA_SRC] = decode_route_addr,
210 [RTA_IIF] = decode_nla_ifindex,
211 [RTA_OIF] = decode_nla_ifindex,
212 [RTA_GATEWAY] = decode_route_addr,
213 [RTA_PRIORITY] = decode_nla_u32,
214 [RTA_PREFSRC] = decode_route_addr,
215 [RTA_METRICS] = decode_rta_metrics,
216 [RTA_MULTIPATH] = decode_rta_multipath,
217 [RTA_PROTOINFO] = decode_nla_u32,
218 [RTA_FLOW] = decode_nla_u32,
219 [RTA_CACHEINFO] = decode_rta_cacheinfo,
220 [RTA_SESSION] = NULL, /* unused */
221 [RTA_MP_ALGO] = decode_nla_u32,
222 [RTA_TABLE] = decode_nla_rt_class,
223 [RTA_MARK] = decode_nla_u32,
224 [RTA_MFC_STATS] = decode_rta_mfc_stats,
225 [RTA_VIA] = decode_rtvia,
226 [RTA_NEWDST] = decode_route_addr,
227 [RTA_PREF] = decode_nla_u8,
228 [RTA_ENCAP_TYPE] = decode_nla_lwt_encap_type,
229 [RTA_ENCAP] = NULL, /* unimplemented */
230 [RTA_EXPIRES] = decode_nla_u64,
231 [RTA_PAD] = NULL,
232 [RTA_UID] = decode_nla_u32,
233 [RTA_TTL_PROPAGATE] = decode_nla_u8,
234 [RTA_IP_PROTO] = decode_nla_u8,
235 [RTA_SPORT] = decode_nla_u16,
236 [RTA_DPORT] = decode_nla_u16
237 };
238
239 /*
240 * RTA_MULTIPATH payload is a list of struct rtnexthop-headed RTA_* netlink
241 * attributes:
242 *
243 * {RTA_MULTIPATH nlattr hdr} [ [{struct rtnexthop}, {RTA_* nlattr}],
244 * [{struct rtnexthop}, {RTA_* nlattr}], ... ]
245 */
246 static bool
247 decode_rta_multipath(struct tcb *const tcp,
248 const kernel_ulong_t addr,
249 const unsigned int len,
250 const void *const opaque_data)
251 {
252 bool is_array = false;
253 struct rtnexthop nh;
254 kernel_ulong_t cur = addr;
255 kernel_ulong_t left = len;
256
257 if (len < sizeof(nh))
258 return false;
259
260 while (!umove_or_printaddr(tcp, cur, &nh)) {
261 static const size_t offset = RTNH_ALIGN(sizeof(nh));
262 const unsigned int rtnh_len = MIN(left, nh.rtnh_len);
263
264 if (cur == addr && nh.rtnh_len < len) {
265 tprint_array_begin();
266 is_array = true;
267 }
268
269 if (cur > addr)
270 tprint_array_next();
271
272 if (rtnh_len > offset)
273 tprint_array_begin();
274
275 /* print the whole structure regardless of its rtnh_len */
276 tprint_struct_begin();
277 PRINT_FIELD_U(nh, rtnh_len);
278 tprint_struct_next();
279 PRINT_FIELD_FLAGS(nh, rtnh_flags,
280 route_nexthop_flags, "RTNH_F_???");
281 tprint_struct_next();
282 PRINT_FIELD_U(nh, rtnh_hops);
283 tprint_struct_next();
284 PRINT_FIELD_IFINDEX(nh, rtnh_ifindex);
285 tprint_struct_end();
286
287 if (rtnh_len > offset) {
288 tprint_array_next();
289 decode_nlattr(tcp, cur + offset, rtnh_len - offset,
290 rtnl_route_attrs, "RTA_???",
291 rtmsg_nla_decoders,
292 ARRAY_SIZE(rtmsg_nla_decoders),
293 opaque_data);
294 }
295
296 if (rtnh_len > offset)
297 tprint_array_end();
298
299 if (RTNH_ALIGN(rtnh_len) >= left)
300 break;
301
302 cur += RTNH_ALIGN(rtnh_len);
303 left -= RTNH_ALIGN(rtnh_len);
304 }
305
306 if (is_array)
307 tprint_array_end();
308
309 return true;
310 }
311
312 DECL_NETLINK_ROUTE_DECODER(decode_rtmsg)
313 {
314 struct rtmsg rtmsg = { .rtm_family = family };
315 size_t offset = sizeof(rtmsg.rtm_family);
316 bool decode_nla = false;
317
318 tprint_struct_begin();
319 PRINT_FIELD_XVAL(rtmsg, rtm_family, addrfams, "AF_???");
320 tprint_struct_next();
321
322 if (len >= sizeof(rtmsg)) {
323 if (!umoven_or_printaddr(tcp, addr + offset,
324 sizeof(rtmsg) - offset,
325 (char *) &rtmsg + offset)) {
326 PRINT_FIELD_U(rtmsg, rtm_dst_len);
327 tprint_struct_next();
328 PRINT_FIELD_U(rtmsg, rtm_src_len);
329 tprint_struct_next();
330 PRINT_FIELD_FLAGS(rtmsg, rtm_tos,
331 ip_type_of_services, "IPTOS_TOS_???");
332 tprint_struct_next();
333 PRINT_FIELD_XVAL(rtmsg, rtm_table,
334 routing_table_ids, NULL);
335 tprint_struct_next();
336 PRINT_FIELD_XVAL(rtmsg, rtm_protocol,
337 routing_protocols, "RTPROT_???");
338 tprint_struct_next();
339 PRINT_FIELD_XVAL(rtmsg, rtm_scope,
340 routing_scopes, NULL);
341 tprint_struct_next();
342 PRINT_FIELD_XVAL(rtmsg, rtm_type,
343 routing_types, "RTN_???");
344 tprint_struct_next();
345 PRINT_FIELD_FLAGS(rtmsg, rtm_flags,
346 routing_flags, "RTM_F_???");
347 decode_nla = true;
348 }
349 } else
350 tprint_more_data_follows();
351 tprint_struct_end();
352
353 offset = NLMSG_ALIGN(sizeof(rtmsg));
354 if (decode_nla && len > offset) {
355 tprint_array_next();
356 decode_nlattr(tcp, addr + offset, len - offset,
357 rtnl_route_attrs, "RTA_???",
358 rtmsg_nla_decoders,
359 ARRAY_SIZE(rtmsg_nla_decoders), &rtmsg);
360 }
361 }