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
12 #include "netlink_route.h"
13 #include "nlattr.h"
14
15 #include <linux/if_addrlabel.h>
16 #include "netlink.h"
17
18 #include "xlat/rtnl_addrlabel_attrs.h"
19
20 static bool
21 decode_ifal_address(struct tcb *const tcp,
22 const kernel_ulong_t addr,
23 const unsigned int len,
24 const void *const opaque_data)
25 {
26 const struct ifaddrlblmsg *const ifal = opaque_data;
27
28 decode_inet_addr(tcp, addr, len, ifal->ifal_family, NULL);
29
30 return true;
31 }
32
33 static const nla_decoder_t ifaddrlblmsg_nla_decoders[] = {
34 [IFAL_ADDRESS] = decode_ifal_address,
35 [IFAL_LABEL] = decode_nla_u32
36 };
37
38 DECL_NETLINK_ROUTE_DECODER(decode_ifaddrlblmsg)
39 {
40 struct ifaddrlblmsg ifal = { .ifal_family = family };
41 size_t offset = sizeof(ifal.ifal_family);
42 bool decode_nla = false;
43
44 tprint_struct_begin();
45 PRINT_FIELD_XVAL(ifal, ifal_family, addrfams, "AF_???");
46 tprint_struct_next();
47
48 if (len >= sizeof(ifal)) {
49 if (!umoven_or_printaddr(tcp, addr + offset,
50 sizeof(ifal) - offset,
51 (char *) &ifal + offset)) {
52 PRINT_FIELD_U(ifal, ifal_prefixlen);
53 tprint_struct_next();
54 PRINT_FIELD_U(ifal, ifal_flags);
55 tprint_struct_next();
56 PRINT_FIELD_IFINDEX(ifal, ifal_index);
57 tprint_struct_next();
58 PRINT_FIELD_U(ifal, ifal_seq);
59 decode_nla = true;
60 }
61 } else
62 tprint_more_data_follows();
63 tprint_struct_end();
64
65 offset = NLMSG_ALIGN(sizeof(ifal));
66 if (decode_nla && len > offset) {
67 tprint_array_next();
68 decode_nlattr(tcp, addr + offset, len - offset,
69 rtnl_addrlabel_attrs, "IFAL_???",
70 ifaddrlblmsg_nla_decoders,
71 ARRAY_SIZE(ifaddrlblmsg_nla_decoders), &ifal);
72 }
73 }