libnl  3.6.0
log_msg.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
4  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
5  * Copyright (c) 2007 Secure Computing Corporation
6  * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
7  */
8 
9 /**
10  * @ingroup nfnl
11  * @defgroup log Log
12  * @brief
13  * @{
14  */
15 
16 #include <sys/types.h>
17 #include <linux/netfilter/nfnetlink_log.h>
18 
19 #include <netlink-private/netlink.h>
20 #include <netlink/attr.h>
21 #include <netlink/netfilter/nfnl.h>
22 #include <netlink/netfilter/log_msg.h>
23 #include <netlink-private/utils.h>
24 
25 static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
26  [NFULA_PACKET_HDR] = {
27  .minlen = sizeof(struct nfulnl_msg_packet_hdr)
28  },
29  [NFULA_MARK] = { .type = NLA_U32 },
30  [NFULA_TIMESTAMP] = {
31  .minlen = sizeof(struct nfulnl_msg_packet_timestamp)
32  },
33  [NFULA_IFINDEX_INDEV] = { .type = NLA_U32 },
34  [NFULA_IFINDEX_OUTDEV] = { .type = NLA_U32 },
35  [NFULA_IFINDEX_PHYSINDEV] = { .type = NLA_U32 },
36  [NFULA_IFINDEX_PHYSOUTDEV] = { .type = NLA_U32 },
37  [NFULA_HWADDR] = {
38  .minlen = sizeof(struct nfulnl_msg_packet_hw)
39  },
40  //[NFULA_PAYLOAD]
41  [NFULA_PREFIX] = { .type = NLA_STRING, },
42  [NFULA_UID] = { .type = NLA_U32 },
43  [NFULA_GID] = { .type = NLA_U32 },
44  [NFULA_SEQ] = { .type = NLA_U32 },
45  [NFULA_SEQ_GLOBAL] = { .type = NLA_U32 },
46  [NFULA_HWTYPE] = { .type = NLA_U16 },
47  [NFULA_HWLEN] = { .type = NLA_U16 },
48  [NFULA_VLAN] = { .type = NLA_NESTED },
49  [NFULA_CT] = { .type = NLA_NESTED },
50  [NFULA_CT_INFO] = { .type = NLA_U32 },
51 };
52 
53 static struct nla_policy log_msg_vlan_policy[NFULA_VLAN_MAX+1] = {
54  [NFULA_VLAN_PROTO] = { .type = NLA_U16 },
55  [NFULA_VLAN_TCI] = { .type = NLA_U16 },
56 };
57 
58 static int
59 nfnlmsg_log_msg_parse_vlan(struct nlattr *attr_full, struct nfnl_log_msg *msg)
60 {
61  struct nlattr *tb[NFULA_VLAN_MAX+1];
62  struct nlattr *attr;
63  int err;
64 
65  err = nla_parse_nested(tb, NFULA_VLAN_MAX, attr_full,
66  log_msg_vlan_policy);
67  if (err < 0)
68  return err;
69 
70  attr = tb[NFULA_VLAN_PROTO];
71  if (attr)
72  nfnl_log_msg_set_vlan_proto(msg, nla_get_u16(attr));
73 
74  attr = tb[NFULA_VLAN_TCI];
75  if (attr)
76  nfnl_log_msg_set_vlan_tag(msg, ntohs(nla_get_u16(attr)));
77 
78  return 0;
79 }
80 
81 int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
82 {
83  struct nfnl_log_msg *msg;
84  struct nlattr *tb[NFULA_MAX+1];
85  struct nlattr *attr;
86  int err;
87 
88  msg = nfnl_log_msg_alloc();
89  if (!msg)
90  return -NLE_NOMEM;
91 
92  msg->ce_msgtype = nlh->nlmsg_type;
93 
94  err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX,
95  log_msg_policy);
96  if (err < 0)
97  goto errout;
98 
99  nfnl_log_msg_set_family(msg, nfnlmsg_family(nlh));
100 
101  attr = tb[NFULA_PACKET_HDR];
102  if (attr) {
103  struct nfulnl_msg_packet_hdr *hdr = nla_data(attr);
104 
105  if (hdr->hw_protocol)
106  nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol);
107  nfnl_log_msg_set_hook(msg, hdr->hook);
108  }
109 
110  attr = tb[NFULA_MARK];
111  if (attr)
112  nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr)));
113 
114  attr = tb[NFULA_TIMESTAMP];
115  if (attr) {
116  struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr);
117  struct timeval tv;
118 
119  tv.tv_sec = ntohll(timestamp->sec);
120  tv.tv_usec = ntohll(timestamp->usec);
121  nfnl_log_msg_set_timestamp(msg, &tv);
122  }
123 
124  attr = tb[NFULA_IFINDEX_INDEV];
125  if (attr)
126  nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr)));
127 
128  attr = tb[NFULA_IFINDEX_OUTDEV];
129  if (attr)
130  nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr)));
131 
132  attr = tb[NFULA_IFINDEX_PHYSINDEV];
133  if (attr)
134  nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr)));
135 
136  attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
137  if (attr)
138  nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr)));
139 
140  attr = tb[NFULA_HWADDR];
141  if (attr) {
142  struct nfulnl_msg_packet_hw *hw = nla_data(attr);
143 
144  nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen));
145  }
146 
147  attr = tb[NFULA_PAYLOAD];
148  if (attr) {
149  err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr));
150  if (err < 0)
151  goto errout;
152  }
153 
154  attr = tb[NFULA_PREFIX];
155  if (attr) {
156  err = nfnl_log_msg_set_prefix(msg, nla_data(attr));
157  if (err < 0)
158  goto errout;
159  }
160 
161  attr = tb[NFULA_UID];
162  if (attr)
163  nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr)));
164 
165  attr = tb[NFULA_GID];
166  if (attr)
167  nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr)));
168 
169  attr = tb[NFULA_SEQ];
170  if (attr)
171  nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr)));
172 
173  attr = tb[NFULA_SEQ_GLOBAL];
174  if (attr)
175  nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr)));
176 
177  attr = tb[NFULA_HWTYPE];
178  if (attr)
179  nfnl_log_msg_set_hwtype(msg, ntohs(nla_get_u16(attr)));
180 
181  attr = tb[NFULA_HWLEN];
182  if (attr)
183  nfnl_log_msg_set_hwlen(msg, ntohs(nla_get_u16(attr)));
184 
185  attr = tb[NFULA_HWHEADER];
186  if (attr)
187  nfnl_log_msg_set_hwheader(msg, nla_data(attr), nla_len(attr));
188 
189  attr = tb[NFULA_VLAN];
190  if (attr) {
191  err = nfnlmsg_log_msg_parse_vlan(attr, msg);
192  if (err < 0)
193  goto errout;
194  }
195 
196  attr = tb[NFULA_CT];
197  if (attr) {
198  struct nfnl_ct *ct = NULL;
199  err = nfnlmsg_ct_parse_nested(attr, &ct);
200  if (err < 0)
201  goto errout;
202  nfnl_log_msg_set_ct(msg, ct);
203  nfnl_ct_put(ct);
204  }
205 
206  attr = tb[NFULA_CT_INFO];
207  if (attr)
208  nfnl_log_msg_set_ct_info(msg, ntohl(nla_get_u32(attr)));
209 
210  *result = msg;
211  return 0;
212 
213 errout:
214  nfnl_log_msg_put(msg);
215  return err;
216 }
217 
218 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
219  struct nlmsghdr *nlh, struct nl_parser_param *pp)
220 {
221  struct nfnl_log_msg *msg;
222  int err;
223 
224  if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0)
225  return err;
226 
227  err = pp->pp_cb((struct nl_object *) msg, pp);
228  nfnl_log_msg_put(msg);
229  return err;
230 }
231 
232 /** @} */
233 
234 #define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type))
235 static struct nl_cache_ops nfnl_log_msg_ops = {
236  .co_name = "netfilter/log_msg",
237  .co_hdrsize = NFNL_HDRLEN,
238  .co_msgtypes = {
239  { NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" },
240  END_OF_MSGTYPES_LIST,
241  },
242  .co_protocol = NETLINK_NETFILTER,
243  .co_msg_parser = log_msg_parser,
244  .co_obj_ops = &log_msg_obj_ops,
245 };
246 
247 static void __init log_msg_init(void)
248 {
249  nl_cache_mngt_register(&nfnl_log_msg_ops);
250 }
251 
252 static void __exit log_msg_exit(void)
253 {
254  nl_cache_mngt_unregister(&nfnl_log_msg_ops);
255 }
256 
257 /** @} */
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:649
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:1013
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:125
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:114
@ NLA_STRING
NUL terminated character string.
Definition: attr.h:39
@ NLA_U16
16 bit integer
Definition: attr.h:36
@ NLA_NESTED
Nested attributes.
Definition: attr.h:42
@ NLA_U32
32 bit integer
Definition: attr.h:37
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Definition: cache_mngt.c:281
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
Definition: cache_mngt.c:246
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
Definition: msg.c:208
uint8_t nfnlmsg_family(struct nlmsghdr *nlh)
Get netfilter family from message.
Definition: nfnl.c:146
Attribute validation policy.
Definition: attr.h:63
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:68
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:65