]> granicus.if.org Git - strace/blob - rtnl_addr.c
xlat: provide fallback definitions for XDP_FLAGS_* constants
[strace] / rtnl_addr.c
1 /*
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.
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 #include "print_fields.h"
14
15 #include "netlink.h"
16 #include <linux/rtnetlink.h>
17 #ifdef HAVE_LINUX_IF_ADDR_H
18 # include <linux/if_addr.h>
19 #endif
20
21 #include "xlat/ifaddrflags.h"
22 #include "xlat/routing_scopes.h"
23 #include "xlat/rtnl_addr_attrs.h"
24
25 static bool
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)
30 {
31         const struct ifaddrmsg *const ifaddr = opaque_data;
32
33         decode_inet_addr(tcp, addr, len, ifaddr->ifa_family, NULL);
34
35         return true;
36 }
37
38 static bool
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)
43 {
44         struct ifa_cacheinfo ci;
45
46         if (len < sizeof(ci))
47                 return false;
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);
53                 tprintf("}");
54         }
55
56         return true;
57 }
58
59 static bool
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)
64 {
65         uint32_t ifa_flags;
66
67         if (len < sizeof(ifa_flags))
68                 return false;
69         else if (!umove_or_printaddr(tcp, addr, &ifa_flags))
70                 printflags(ifaddrflags, ifa_flags, "IFA_F_???");
71
72         return true;
73 }
74
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,
86 };
87
88 DECL_NETLINK_ROUTE_DECODER(decode_ifaddrmsg)
89 {
90         struct ifaddrmsg ifaddr = { .ifa_family = family };
91         size_t offset = sizeof(ifaddr.ifa_family);
92         bool decode_nla = false;
93
94         PRINT_FIELD_XVAL("{", ifaddr, ifa_family, addrfams, "AF_???");
95
96         tprints(", ");
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);
107                         decode_nla = true;
108                 }
109         } else
110                 tprints("...");
111         tprints("}");
112
113         offset = NLMSG_ALIGN(sizeof(ifaddr));
114         if (decode_nla && len > offset) {
115                 tprints(", ");
116                 decode_nlattr(tcp, addr + offset, len - offset,
117                               rtnl_addr_attrs, "IFA_???",
118                               ifaddrmsg_nla_decoders,
119                               ARRAY_SIZE(ifaddrmsg_nla_decoders), &ifaddr);
120         }
121 }