1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include <linux/module.h>
41#include <linux/version.h>
42#include <linux/config.h>
43#include <linux/spinlock.h>
44#include <linux/socket.h>
45#include <linux/skbuff.h>
46#include <linux/kernel.h>
47#include <linux/timer.h>
48#include <linux/netlink.h>
49#include <linux/netdevice.h>
50#include <linux/mm.h>
51#include <linux/socket.h>
52#include <linux/netfilter_ipv4/ip_tables.h>
53#include <linux/netfilter_ipv4/ipt_ULOG.h>
54#include <linux/netfilter_ipv4/lockhelp.h>
55#include <net/sock.h>
56#include <linux/bitops.h>
57
58MODULE_LICENSE("GPL");
59MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
60MODULE_DESCRIPTION("IP tables userspace logging module");
61
62#define ULOG_NL_EVENT 111
63#define ULOG_MAXNLGROUPS 32
64
65#if 0
66#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ":" \
67 format, ## args)
68#else
69#define DEBUGP(format, args...)
70#endif
71
72#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0)
73
74static unsigned int nlbufsiz = 4096;
75MODULE_PARM(nlbufsiz, "i");
76MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
77
78static unsigned int flushtimeout = 10 * HZ;
79MODULE_PARM(flushtimeout, "i");
80MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
81
82
83
84typedef struct {
85 unsigned int qlen;
86 struct nlmsghdr *lastnlh;
87 struct sk_buff *skb;
88 struct timer_list timer;
89} ulog_buff_t;
90
91static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS];
92
93static struct sock *nflognl;
94DECLARE_LOCK(ulog_lock);
95
96
97static void ulog_send(unsigned int nlgroupnum)
98{
99 ulog_buff_t *ub = &ulog_buffers[nlgroupnum];
100
101 if (timer_pending(&ub->timer)) {
102 DEBUGP("ipt_ULOG: ulog_send: timer was pending, deleting\n");
103 del_timer(&ub->timer);
104 }
105
106
107 if (ub->qlen > 1)
108 ub->lastnlh->nlmsg_type = NLMSG_DONE;
109
110 NETLINK_CB(ub->skb).dst_groups = (1 << nlgroupnum);
111 DEBUGP("ipt_ULOG: throwing %d packets to netlink mask %u\n",
112 ub->qlen, nlgroupnum);
113 netlink_broadcast(nflognl, ub->skb, 0, (1 << nlgroupnum), GFP_ATOMIC);
114
115 ub->qlen = 0;
116 ub->skb = NULL;
117 ub->lastnlh = NULL;
118
119}
120
121
122
123static void ulog_timer(unsigned long data)
124{
125 DEBUGP("ipt_ULOG: timer function called, calling ulog_send\n");
126
127
128
129 LOCK_BH(&ulog_lock);
130 ulog_send(data);
131 UNLOCK_BH(&ulog_lock);
132}
133
134struct sk_buff *ulog_alloc_skb(unsigned int size)
135{
136 struct sk_buff *skb;
137
138
139
140
141
142 skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
143 if (!skb) {
144 PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n",
145 nlbufsiz);
146
147
148
149
150 skb = alloc_skb(size, GFP_ATOMIC);
151 if (!skb)
152 PRINTR("ipt_ULOG: can't even allocate %ub\n", size);
153 }
154
155 return skb;
156}
157
158static unsigned int ipt_ulog_target(struct sk_buff **pskb,
159 unsigned int hooknum,
160 const struct net_device *in,
161 const struct net_device *out,
162 const void *targinfo, void *userinfo)
163{
164 ulog_buff_t *ub;
165 ulog_packet_msg_t *pm;
166 size_t size, copy_len;
167 struct nlmsghdr *nlh;
168 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
169
170
171
172
173 unsigned int groupnum = ffs(loginfo->nl_group) - 1;
174
175
176 if ((loginfo->copy_range == 0) ||
177 (loginfo->copy_range > (*pskb)->len)) {
178 copy_len = (*pskb)->len;
179 } else {
180 copy_len = loginfo->copy_range;
181 }
182
183 size = NLMSG_SPACE(sizeof(*pm) + copy_len);
184
185 ub = &ulog_buffers[groupnum];
186
187 LOCK_BH(&ulog_lock);
188
189 if (!ub->skb) {
190 if (!(ub->skb = ulog_alloc_skb(size)))
191 goto alloc_failure;
192 } else if (ub->qlen >= loginfo->qthreshold ||
193 size > skb_tailroom(ub->skb)) {
194
195
196
197 ulog_send(groupnum);
198
199 if (!(ub->skb = ulog_alloc_skb(size)))
200 goto alloc_failure;
201 }
202
203 DEBUGP("ipt_ULOG: qlen %d, qthreshold %d\n", ub->qlen,
204 loginfo->qthreshold);
205
206
207 nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT,
208 sizeof(*pm)+copy_len);
209 ub->qlen++;
210
211 pm = NLMSG_DATA(nlh);
212
213
214 pm->data_len = copy_len;
215 pm->timestamp_sec = (*pskb)->stamp.tv_sec;
216 pm->timestamp_usec = (*pskb)->stamp.tv_usec;
217 pm->mark = (*pskb)->nfmark;
218 pm->hook = hooknum;
219 if (loginfo->prefix[0] != '\0')
220 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
221 else
222 *(pm->prefix) = '\0';
223
224 if (in && in->hard_header_len > 0
225 && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph
226 && in->hard_header_len <= ULOG_MAC_LEN) {
227 memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
228 pm->mac_len = in->hard_header_len;
229 } else
230 pm->mac_len = 0;
231
232 if (in)
233 strncpy(pm->indev_name, in->name, sizeof(pm->indev_name));
234 else
235 pm->indev_name[0] = '\0';
236
237 if (out)
238 strncpy(pm->outdev_name, out->name, sizeof(pm->outdev_name));
239 else
240 pm->outdev_name[0] = '\0';
241
242 if (copy_len)
243 memcpy(pm->payload, (*pskb)->data, copy_len);
244
245
246 if (ub->qlen > 1) {
247 ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
248 }
249
250 ub->lastnlh = nlh;
251
252
253 if (!timer_pending(&ub->timer)) {
254 ub->timer.expires = jiffies + flushtimeout;
255 add_timer(&ub->timer);
256 }
257
258
259 if (ub->qlen >= loginfo->qthreshold) {
260 if (loginfo->qthreshold > 1)
261 nlh->nlmsg_type = NLMSG_DONE;
262 ulog_send(groupnum);
263 }
264
265 UNLOCK_BH(&ulog_lock);
266
267 return IPT_CONTINUE;
268
269
270nlmsg_failure:
271 PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
272
273alloc_failure:
274 PRINTR("ipt_ULOG: Error building netlink message\n");
275
276 UNLOCK_BH(&ulog_lock);
277
278 return IPT_CONTINUE;
279}
280
281static int ipt_ulog_checkentry(const char *tablename,
282 const struct ipt_entry *e,
283 void *targinfo,
284 unsigned int targinfosize,
285 unsigned int hookmask)
286{
287 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
288
289 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ulog_info))) {
290 DEBUGP("ipt_ULOG: targinfosize %u != 0\n", targinfosize);
291 return 0;
292 }
293
294 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
295 DEBUGP("ipt_ULOG: prefix term %i\n",
296 loginfo->prefix[sizeof(loginfo->prefix) - 1]);
297 return 0;
298 }
299
300 if (loginfo->qthreshold > ULOG_MAX_QLEN) {
301 DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n",
302 loginfo->qthreshold);
303 return 0;
304 }
305
306 return 1;
307}
308
309static struct ipt_target ipt_ulog_reg =
310 { {NULL, NULL}, "ULOG", ipt_ulog_target, ipt_ulog_checkentry, NULL,
311THIS_MODULE
312};
313
314static int __init init(void)
315{
316 int i;
317
318 DEBUGP("ipt_ULOG: init module\n");
319
320 if (nlbufsiz >= 128*1024) {
321 printk("Netlink buffer has to be <= 128kB\n");
322 return -EINVAL;
323 }
324
325
326 for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
327 init_timer(&ulog_buffers[i].timer);
328 ulog_buffers[i].timer.function = ulog_timer;
329 ulog_buffers[i].timer.data = i;
330 }
331
332 nflognl = netlink_kernel_create(NETLINK_NFLOG, NULL);
333 if (!nflognl)
334 return -ENOMEM;
335
336 if (ipt_register_target(&ipt_ulog_reg) != 0) {
337 sock_release(nflognl->socket);
338 return -EINVAL;
339 }
340
341 return 0;
342}
343
344static void __exit fini(void)
345{
346 ulog_buff_t *ub;
347 int i;
348
349 DEBUGP("ipt_ULOG: cleanup_module\n");
350
351 ipt_unregister_target(&ipt_ulog_reg);
352 sock_release(nflognl->socket);
353
354
355 for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
356 ub = &ulog_buffers[i];
357 if (timer_pending(&ub->timer)) {
358 DEBUGP("timer was pending, deleting\n");
359 del_timer(&ub->timer);
360 }
361
362 if (ub->skb) {
363 kfree_skb(ub->skb);
364 ub->skb = NULL;
365 }
366 }
367
368}
369
370module_init(init);
371module_exit(fini);
372