• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "nl-default.h"
17 
18 #include <sys/types.h>
19 
20 #include <linux/netfilter/nfnetlink_log.h>
21 
22 #include <netlink/attr.h>
23 #include <netlink/netfilter/nfnl.h>
24 #include <netlink/netfilter/log_msg.h>
25 
26 #include "nl-netfilter.h"
27 #include "nl-priv-dynamic-core/cache-api.h"
28 
29 static struct nla_policy log_msg_policy[NFULA_MAX+1] = {
30 	[NFULA_PACKET_HDR]		= {
31 		.minlen = sizeof(struct nfulnl_msg_packet_hdr)
32 	},
33 	[NFULA_MARK]			= { .type = NLA_U32 },
34 	[NFULA_TIMESTAMP]		= {
35 		.minlen = sizeof(struct nfulnl_msg_packet_timestamp)
36 	},
37 	[NFULA_IFINDEX_INDEV]		= { .type = NLA_U32 },
38 	[NFULA_IFINDEX_OUTDEV]		= { .type = NLA_U32 },
39 	[NFULA_IFINDEX_PHYSINDEV]	= { .type = NLA_U32 },
40 	[NFULA_IFINDEX_PHYSOUTDEV]	= { .type = NLA_U32 },
41 	[NFULA_HWADDR]			= {
42 		.minlen = sizeof(struct nfulnl_msg_packet_hw)
43 	},
44 	//[NFULA_PAYLOAD]
45 	[NFULA_PREFIX]			= { .type = NLA_STRING, },
46 	[NFULA_UID]			= { .type = NLA_U32 },
47 	[NFULA_GID]			= { .type = NLA_U32 },
48 	[NFULA_SEQ]			= { .type = NLA_U32 },
49 	[NFULA_SEQ_GLOBAL]		= { .type = NLA_U32 },
50 	[NFULA_HWTYPE]			= { .type = NLA_U16 },
51 	[NFULA_HWLEN]			= { .type = NLA_U16 },
52 	[NFULA_VLAN]			= { .type = NLA_NESTED },
53 	[NFULA_CT]			= { .type = NLA_NESTED },
54 	[NFULA_CT_INFO]			= { .type = NLA_U32 },
55 };
56 
57 static struct nla_policy log_msg_vlan_policy[NFULA_VLAN_MAX+1] = {
58 	[NFULA_VLAN_PROTO]		= { .type = NLA_U16 },
59 	[NFULA_VLAN_TCI]		= { .type = NLA_U16 },
60 };
61 
62 static int
nfnlmsg_log_msg_parse_vlan(struct nlattr * attr_full,struct nfnl_log_msg * msg)63 nfnlmsg_log_msg_parse_vlan(struct nlattr *attr_full, struct nfnl_log_msg *msg)
64 {
65 	struct nlattr *tb[NFULA_VLAN_MAX+1];
66 	struct nlattr *attr;
67 	int err;
68 
69 	err = nla_parse_nested(tb, NFULA_VLAN_MAX, attr_full,
70 			       log_msg_vlan_policy);
71 	if (err < 0)
72 		return err;
73 
74 	attr = tb[NFULA_VLAN_PROTO];
75 	if (attr)
76 		nfnl_log_msg_set_vlan_proto(msg, nla_get_u16(attr));
77 
78 	attr = tb[NFULA_VLAN_TCI];
79 	if (attr)
80 		nfnl_log_msg_set_vlan_tag(msg, ntohs(nla_get_u16(attr)));
81 
82 	return 0;
83 }
84 
nfnlmsg_log_msg_parse(struct nlmsghdr * nlh,struct nfnl_log_msg ** result)85 int nfnlmsg_log_msg_parse(struct nlmsghdr *nlh, struct nfnl_log_msg **result)
86 {
87 	struct nfnl_log_msg *msg;
88 	struct nlattr *tb[NFULA_MAX+1];
89 	struct nlattr *attr;
90 	int err;
91 
92 	msg = nfnl_log_msg_alloc();
93 	if (!msg)
94 		return -NLE_NOMEM;
95 
96 	msg->ce_msgtype = nlh->nlmsg_type;
97 
98 	err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFULA_MAX,
99 			  log_msg_policy);
100 	if (err < 0)
101 		goto errout;
102 
103 	nfnl_log_msg_set_family(msg, nfnlmsg_family(nlh));
104 
105 	attr = tb[NFULA_PACKET_HDR];
106 	if (attr) {
107 		struct nfulnl_msg_packet_hdr *hdr = nla_data(attr);
108 
109 		if (hdr->hw_protocol)
110 			nfnl_log_msg_set_hwproto(msg, hdr->hw_protocol);
111 		nfnl_log_msg_set_hook(msg, hdr->hook);
112 	}
113 
114 	attr = tb[NFULA_MARK];
115 	if (attr)
116 		nfnl_log_msg_set_mark(msg, ntohl(nla_get_u32(attr)));
117 
118 	attr = tb[NFULA_TIMESTAMP];
119 	if (attr) {
120 		struct nfulnl_msg_packet_timestamp *timestamp = nla_data(attr);
121 		struct timeval tv;
122 
123 		tv.tv_sec = ntohll(timestamp->sec);
124 		tv.tv_usec = ntohll(timestamp->usec);
125 		nfnl_log_msg_set_timestamp(msg, &tv);
126 	}
127 
128 	attr = tb[NFULA_IFINDEX_INDEV];
129 	if (attr)
130 		nfnl_log_msg_set_indev(msg, ntohl(nla_get_u32(attr)));
131 
132 	attr = tb[NFULA_IFINDEX_OUTDEV];
133 	if (attr)
134 		nfnl_log_msg_set_outdev(msg, ntohl(nla_get_u32(attr)));
135 
136 	attr = tb[NFULA_IFINDEX_PHYSINDEV];
137 	if (attr)
138 		nfnl_log_msg_set_physindev(msg, ntohl(nla_get_u32(attr)));
139 
140 	attr = tb[NFULA_IFINDEX_PHYSOUTDEV];
141 	if (attr)
142 		nfnl_log_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr)));
143 
144 	attr = tb[NFULA_HWADDR];
145 	if (attr) {
146 		struct nfulnl_msg_packet_hw *hw = nla_data(attr);
147 
148 		nfnl_log_msg_set_hwaddr(msg, hw->hw_addr, ntohs(hw->hw_addrlen));
149 	}
150 
151 	attr = tb[NFULA_PAYLOAD];
152 	if (attr) {
153 		err = nfnl_log_msg_set_payload(msg, nla_data(attr), nla_len(attr));
154 		if (err < 0)
155 			goto errout;
156 	}
157 
158 	attr = tb[NFULA_PREFIX];
159 	if (attr) {
160 		err = nfnl_log_msg_set_prefix(msg, nla_data(attr));
161 		if (err < 0)
162 			goto errout;
163 	}
164 
165 	attr = tb[NFULA_UID];
166 	if (attr)
167 		nfnl_log_msg_set_uid(msg, ntohl(nla_get_u32(attr)));
168 
169 	attr = tb[NFULA_GID];
170 	if (attr)
171 		nfnl_log_msg_set_gid(msg, ntohl(nla_get_u32(attr)));
172 
173 	attr = tb[NFULA_SEQ];
174 	if (attr)
175 		nfnl_log_msg_set_seq(msg, ntohl(nla_get_u32(attr)));
176 
177 	attr = tb[NFULA_SEQ_GLOBAL];
178 	if (attr)
179 		nfnl_log_msg_set_seq_global(msg, ntohl(nla_get_u32(attr)));
180 
181 	attr = tb[NFULA_HWTYPE];
182 	if (attr)
183 		nfnl_log_msg_set_hwtype(msg, ntohs(nla_get_u16(attr)));
184 
185 	attr = tb[NFULA_HWLEN];
186 	if (attr)
187 		nfnl_log_msg_set_hwlen(msg, ntohs(nla_get_u16(attr)));
188 
189 	attr = tb[NFULA_HWHEADER];
190 	if (attr)
191 		nfnl_log_msg_set_hwheader(msg, nla_data(attr), nla_len(attr));
192 
193 	attr = tb[NFULA_VLAN];
194 	if (attr) {
195 		err = nfnlmsg_log_msg_parse_vlan(attr, msg);
196 		if (err < 0)
197 			goto errout;
198 	}
199 
200 	attr = tb[NFULA_CT];
201 	if (attr) {
202 		struct nfnl_ct *ct = NULL;
203 		err = nfnlmsg_ct_parse_nested(attr, &ct);
204 		if (err < 0)
205 			goto errout;
206 		nfnl_log_msg_set_ct(msg, ct);
207 		nfnl_ct_put(ct);
208 	}
209 
210 	attr = tb[NFULA_CT_INFO];
211 	if (attr)
212 		nfnl_log_msg_set_ct_info(msg, ntohl(nla_get_u32(attr)));
213 
214 	*result = msg;
215 	return 0;
216 
217 errout:
218 	nfnl_log_msg_put(msg);
219 	return err;
220 }
221 
log_msg_parser(struct nl_cache_ops * ops,struct sockaddr_nl * who,struct nlmsghdr * nlh,struct nl_parser_param * pp)222 static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
223 			  struct nlmsghdr *nlh, struct nl_parser_param *pp)
224 {
225 	struct nfnl_log_msg *msg;
226 	int err;
227 
228 	if ((err = nfnlmsg_log_msg_parse(nlh, &msg)) < 0)
229 		return err;
230 
231 	err = pp->pp_cb((struct nl_object *) msg, pp);
232 	nfnl_log_msg_put(msg);
233 	return err;
234 }
235 
236 /** @} */
237 
238 #define NFNLMSG_LOG_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_ULOG, (type))
239 static struct nl_cache_ops nfnl_log_msg_ops = {
240 	.co_name		= "netfilter/log_msg",
241 	.co_hdrsize		= NFNL_HDRLEN,
242 	.co_msgtypes		= {
243 		{ NFNLMSG_LOG_TYPE(NFULNL_MSG_PACKET), NL_ACT_NEW, "new" },
244 		END_OF_MSGTYPES_LIST,
245 	},
246 	.co_protocol		= NETLINK_NETFILTER,
247 	.co_msg_parser		= log_msg_parser,
248 	.co_obj_ops		= &log_msg_obj_ops,
249 };
250 
log_msg_init(void)251 static void _nl_init log_msg_init(void)
252 {
253 	nl_cache_mngt_register(&nfnl_log_msg_ops);
254 }
255 
log_msg_exit(void)256 static void _nl_exit log_msg_exit(void)
257 {
258 	nl_cache_mngt_unregister(&nfnl_log_msg_ops);
259 }
260 
261 /** @} */
262