• 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 <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
nfnlmsg_log_msg_parse_vlan(struct nlattr * attr_full,struct nfnl_log_msg * msg)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 
nfnlmsg_log_msg_parse(struct nlmsghdr * nlh,struct nfnl_log_msg ** result)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 
log_msg_parser(struct nl_cache_ops * ops,struct sockaddr_nl * who,struct nlmsghdr * nlh,struct nl_parser_param * pp)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 
log_msg_init(void)247 static void __init log_msg_init(void)
248 {
249 	nl_cache_mngt_register(&nfnl_log_msg_ops);
250 }
251 
log_msg_exit(void)252 static void __exit log_msg_exit(void)
253 {
254 	nl_cache_mngt_unregister(&nfnl_log_msg_ops);
255 }
256 
257 /** @} */
258