1 /*
2 * Copyright (c) 2018 Chen Jingpiao <chenjingpiao@gmail.com>
3 * Copyright (c) 2018-2021 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #include "defs.h"
10 #include "nlattr.h"
11
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include "netlink.h"
15 #include <linux/netfilter/nfnetlink.h>
16
17 #include "xlat/netfilter_versions.h"
18 #include "xlat/nl_netfilter_msg_types.h"
19 #include "xlat/nl_netfilter_subsys_ids.h"
20
21 bool
22 decode_netlink_netfilter(struct tcb *const tcp,
23 const struct nlmsghdr *const nlmsghdr,
24 const kernel_ulong_t addr,
25 const unsigned int len)
26 {
27 if (nlmsghdr->nlmsg_type == NLMSG_DONE)
28 return false;
29
30 struct nfgenmsg nfmsg;
31
32 if (len < sizeof(nfmsg))
33 printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
34 else if (!umove_or_printaddr(tcp, addr, &nfmsg)) {
35 const uint8_t subsys_id = (uint8_t) (nlmsghdr->nlmsg_type >> 8);
36 uint16_t res_id = ntohs(nfmsg.res_id);
37
38 tprint_struct_begin();
39 PRINT_FIELD_XVAL(nfmsg, nfgen_family, addrfams, "AF_???");
40 tprint_struct_next();
41 PRINT_FIELD_XVAL(nfmsg, version, netfilter_versions,
42 "NFNETLINK_???");
43
44 /*
45 * Work around wrong endianness in res_id field,
46 * see linux commit v4.3-rc1~28^2~47^2~1
47 */
48 tprint_struct_next();
49 tprints_field_name("res_id");
50 if (subsys_id == NFNL_SUBSYS_NFTABLES
51 && res_id == NFNL_SUBSYS_NFTABLES) {
52 print_xlat_ex(nfmsg.res_id,
53 "htons(NFNL_SUBSYS_NFTABLES)",
54 XLAT_STYLE_DEFAULT);
55 } else if (subsys_id == NFNL_SUBSYS_NFTABLES
56 && nfmsg.res_id == NFNL_SUBSYS_NFTABLES) {
57 print_xlat_ex(nfmsg.res_id, "NFNL_SUBSYS_NFTABLES",
58 XLAT_STYLE_DEFAULT);
59 } else {
60 tprints_arg_begin("htons");
61 PRINT_VAL_U(res_id);
62 tprint_arg_end();
63 }
64 tprint_struct_end();
65
66 const size_t offset = NLMSG_ALIGN(sizeof(nfmsg));
67 if (len > offset) {
68 tprint_array_next();
69 if ((nlmsghdr->nlmsg_type >= NFNL_MSG_BATCH_BEGIN
70 && nlmsghdr->nlmsg_type <= NFNL_MSG_BATCH_END)
71 || nlmsghdr->nlmsg_type < NLMSG_MIN_TYPE)
72 printstr_ex(tcp, addr + offset,
73 len - offset, QUOTE_FORCE_HEX);
74 else
75 decode_nlattr(tcp, addr + offset, len - offset,
76 NULL, NULL, NULL, 0, NULL);
77 }
78 }
79
80 return true;
81 }