2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2016-2018 The strace developers.
7 * SPDX-License-Identifier: LGPL-2.1-or-later
11 #include "netlink_route.h"
13 #include "print_fields.h"
16 #include <linux/rtnetlink.h>
17 #ifdef HAVE_LINUX_IF_ADDR_H
18 # include <linux/if_addr.h>
21 #include "xlat/ifaddrflags.h"
22 #include "xlat/routing_scopes.h"
23 #include "xlat/rtnl_addr_attrs.h"
26 decode_ifa_address(struct tcb *const tcp,
27 const kernel_ulong_t addr,
28 const unsigned int len,
29 const void *const opaque_data)
31 const struct ifaddrmsg *const ifaddr = opaque_data;
33 decode_inet_addr(tcp, addr, len, ifaddr->ifa_family, NULL);
39 decode_ifa_cacheinfo(struct tcb *const tcp,
40 const kernel_ulong_t addr,
41 const unsigned int len,
42 const void *const opaque_data)
44 struct ifa_cacheinfo ci;
48 else if (!umove_or_printaddr(tcp, addr, &ci)) {
49 PRINT_FIELD_U("{", ci, ifa_prefered);
50 PRINT_FIELD_U(", ", ci, ifa_valid);
51 PRINT_FIELD_U(", ", ci, cstamp);
52 PRINT_FIELD_U(", ", ci, tstamp);
60 decode_ifa_flags(struct tcb *const tcp,
61 const kernel_ulong_t addr,
62 const unsigned int len,
63 const void *const opaque_data)
67 if (len < sizeof(ifa_flags))
69 else if (!umove_or_printaddr(tcp, addr, &ifa_flags))
70 printflags(ifaddrflags, ifa_flags, "IFA_F_???");
75 static const nla_decoder_t ifaddrmsg_nla_decoders[] = {
76 [IFA_ADDRESS] = decode_ifa_address,
77 [IFA_LOCAL] = decode_ifa_address,
78 [IFA_LABEL] = decode_nla_str,
79 [IFA_BROADCAST] = decode_ifa_address,
80 [IFA_ANYCAST] = decode_ifa_address,
81 [IFA_CACHEINFO] = decode_ifa_cacheinfo,
82 [IFA_MULTICAST] = decode_ifa_address,
83 [IFA_FLAGS] = decode_ifa_flags,
84 [IFA_RT_PRIORITY] = decode_nla_u32,
85 [IFA_TARGET_NETNSID] = decode_nla_s32,
88 DECL_NETLINK_ROUTE_DECODER(decode_ifaddrmsg)
90 struct ifaddrmsg ifaddr = { .ifa_family = family };
91 size_t offset = sizeof(ifaddr.ifa_family);
92 bool decode_nla = false;
94 PRINT_FIELD_XVAL("{", ifaddr, ifa_family, addrfams, "AF_???");
97 if (len >= sizeof(ifaddr)) {
98 if (!umoven_or_printaddr(tcp, addr + offset,
99 sizeof(ifaddr) - offset,
100 (char *) &ifaddr + offset)) {
101 PRINT_FIELD_U("", ifaddr, ifa_prefixlen);
102 PRINT_FIELD_FLAGS(", ", ifaddr, ifa_flags,
103 ifaddrflags, "IFA_F_???");
104 PRINT_FIELD_XVAL(", ", ifaddr, ifa_scope,
105 routing_scopes, NULL);
106 PRINT_FIELD_IFINDEX(", ", ifaddr, ifa_index);
113 offset = NLMSG_ALIGN(sizeof(ifaddr));
114 if (decode_nla && len > offset) {
116 decode_nlattr(tcp, addr + offset, len - offset,
117 rtnl_addr_attrs, "IFA_???",
118 ifaddrmsg_nla_decoders,
119 ARRAY_SIZE(ifaddrmsg_nla_decoders), &ifaddr);