Copy over 2.6.36 files to 3.0 - so patch-o-matic finds them
[ipt_ACCOUNT] / linux-2.6.36 / net / ipv4 / netfilter / ipt_ACCOUNT.c
1 /***************************************************************************
2  *   This is a module which is used for counting packets.                  *
3  *   See http://www.intra2net.com/opensource/ipt_account                   *
4  *   for further information                                               *
5  *                                                                         *
6  *   Copyright (C) 2004-2011 by Intra2net AG                               *
7  *   opensource@intra2net.com                                              *
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License                  *
11  *   version 2 as published by the Free Software Foundation;               *
12  *                                                                         *
13  ***************************************************************************/
14
15 #include <linux/module.h>
16 #include <linux/version.h>
17 #include <linux/skbuff.h>
18 #include <linux/ip.h>
19 #include <net/icmp.h>
20 #include <net/udp.h>
21 #include <net/tcp.h>
22 #include <linux/netfilter_ipv4/ip_tables.h>
23
24 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
25     #include <linux/semaphore.h>
26 #else
27     #include <asm/semaphore.h>
28 #endif
29
30 #include <linux/kernel.h>
31 #include <linux/mm.h>
32 #include <linux/string.h>
33 #include <linux/spinlock.h>
34 #include <asm/uaccess.h>
35
36 #include <net/route.h>
37 #include <linux/netfilter_ipv4/ipt_ACCOUNT.h>
38
39 #if 0
40 #define DEBUGP printk
41 #else
42 #define DEBUGP(format, args...)
43 #endif
44
45 #if (PAGE_SIZE < 4096)
46 #error "ipt_ACCOUNT needs at least a PAGE_SIZE of 4096"
47 #endif
48
49 static struct ipt_acc_table *ipt_acc_tables = NULL;
50 static struct ipt_acc_handle *ipt_acc_handles = NULL;
51 static void *ipt_acc_tmpbuf = NULL;
52
53 /* Spinlock used for manipulating the current accounting tables/data */
54 static DEFINE_SPINLOCK(ipt_acc_lock);
55 /* Mutex (semaphore) used for manipulating userspace handles/snapshot data */
56 static struct semaphore ipt_acc_userspace_mutex;
57
58 /* Allocates a page and clears it */
59 static void *ipt_acc_zalloc_page(void)
60 {
61     // Don't use get_zeroed_page until it's fixed in the kernel.
62     // get_zeroed_page(GFP_ATOMIC)
63     void *mem = (void *)__get_free_page(GFP_ATOMIC);
64     if (mem) {
65         memset (mem, 0, PAGE_SIZE);
66     }
67
68     return mem;
69 }
70
71 /* Recursive free of all data structures */
72 static void ipt_acc_data_free(void *data, unsigned char depth)
73 {
74     /* Empty data set */
75     if (!data)
76         return;
77
78     /* Free for 8 bit network */
79     if (depth == 0) {
80         free_page((unsigned long)data);
81         return;
82     }
83
84     /* Free for 16 bit network */
85     if (depth == 1) {
86         struct ipt_acc_mask_16 *mask_16 = (struct ipt_acc_mask_16 *)data;
87         unsigned int b;
88         for (b=0; b <= 255; b++) {
89             if (mask_16->mask_24[b]) {
90                 free_page((unsigned long)mask_16->mask_24[b]);
91             }
92         }
93         free_page((unsigned long)data);
94         return;
95     }
96
97     /* Free for 24 bit network */
98     if (depth == 2) {
99         unsigned int a, b;
100         for (a=0; a <= 255; a++) {
101             if (((struct ipt_acc_mask_8 *)data)->mask_16[a]) {
102                 struct ipt_acc_mask_16 *mask_16 = (struct ipt_acc_mask_16*)
103                                    ((struct ipt_acc_mask_8 *)data)->mask_16[a];
104
105                 for (b=0; b <= 255; b++) {
106                     if (mask_16->mask_24[b]) {
107                         free_page((unsigned long)mask_16->mask_24[b]);
108                     }
109                 }
110                 free_page((unsigned long)mask_16);
111             }
112         }
113         free_page((unsigned long)data);
114         return;
115     }
116
117     printk("ACCOUNT: ipt_acc_data_free called with unknown depth: %d\n", 
118            depth);
119     return;
120 }
121
122 /* Look for existing table / insert new one. 
123    Return internal ID or -1 on error */
124 static int ipt_acc_table_insert(char *name, u_int32_t ip, u_int32_t netmask)
125 {
126     unsigned int i;
127
128     DEBUGP("ACCOUNT: ipt_acc_table_insert: %s, %pI4/%pI4\n",
129                                          name, &ip, &netmask);
130
131     /* Look for existing table */
132     for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
133         if (strncmp(ipt_acc_tables[i].name, name, 
134                     ACCOUNT_TABLE_NAME_LEN) == 0) {
135             DEBUGP("ACCOUNT: Found existing slot: %d - "
136                    "%pI4/%pI4\n", i,
137                    &ipt_acc_tables[i].ip,
138                    &ipt_acc_tables[i].netmask);
139
140             if (ipt_acc_tables[i].ip != ip 
141                 || ipt_acc_tables[i].netmask != netmask) {
142                 printk("ACCOUNT: Table %s found, but IP/netmask mismatch. "
143                        "IP/netmask found: %pI4/%pI4\n",
144                        name, &ipt_acc_tables[i].ip, 
145                        &ipt_acc_tables[i].netmask);
146                 return -1;
147             }
148
149             ipt_acc_tables[i].refcount++;
150             DEBUGP("ACCOUNT: Refcount: %d\n", ipt_acc_tables[i].refcount);
151             return i;
152         }
153     }
154
155     /* Insert new table */
156     for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
157         /* Found free slot */
158         if (ipt_acc_tables[i].name[0] == 0) {
159             unsigned int netsize=0;
160             u_int32_t calc_mask;
161             int j;  /* needs to be signed, otherwise we risk endless loop */
162
163             DEBUGP("ACCOUNT: Found free slot: %d\n", i);
164             strncpy (ipt_acc_tables[i].name, name, ACCOUNT_TABLE_NAME_LEN-1);
165
166             ipt_acc_tables[i].ip = ip;
167             ipt_acc_tables[i].netmask = netmask;
168
169             /* Calculate netsize */
170             calc_mask = htonl(netmask);
171             for (j = 31; j >= 0; j--) {
172                 if (calc_mask&(1<<j))
173                     netsize++;
174                 else
175                     break;
176             }
177
178             /* Calculate depth from netsize */
179             if (netsize >= 24)
180                 ipt_acc_tables[i].depth = 0;
181             else if (netsize >= 16)
182                 ipt_acc_tables[i].depth = 1;
183             else if(netsize >= 8)
184                 ipt_acc_tables[i].depth = 2;
185
186             DEBUGP("ACCOUNT: calculated netsize: %u -> "
187                    "ipt_acc_table depth %u\n", netsize, 
188                    ipt_acc_tables[i].depth);
189
190             ipt_acc_tables[i].refcount++;
191             if ((ipt_acc_tables[i].data
192                 = ipt_acc_zalloc_page()) == NULL) {
193                 printk("ACCOUNT: out of memory for data of table: %s\n", name);
194                 memset(&ipt_acc_tables[i], 0, 
195                        sizeof(struct ipt_acc_table));
196                 return -1;
197             }
198
199             return i;
200         }
201     }
202
203     /* No free slot found */
204     printk("ACCOUNT: No free table slot found (max: %d). "
205            "Please increase ACCOUNT_MAX_TABLES.\n", ACCOUNT_MAX_TABLES);
206     return -1;
207 }
208
209 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
210 static int ipt_acc_checkentry(const struct xt_tgchk_param *par)
211 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
212 static bool ipt_acc_checkentry(const struct xt_tgchk_param *par)
213 #else
214 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
215 static bool ipt_acc_checkentry(const char *tablename,
216 #else
217 static int ipt_acc_checkentry(const char *tablename,
218 #endif
219 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
220                               const void *e,
221 #else
222                               const struct ipt_entry *e,
223 #endif
224 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
225                               const struct xt_target *target,
226 #endif
227                               void *targinfo,
228 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
229                               unsigned int targinfosize,
230 #endif
231                               unsigned int hook_mask)
232 #endif /* >= 2.6.28 */
233 {
234 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
235     struct ipt_acc_info *info = par->targinfo;
236 #else
237     struct ipt_acc_info *info = targinfo;
238 #endif
239     int table_nr;
240
241 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
242     if (targinfosize != IPT_ALIGN(sizeof(struct ipt_acc_info))) {
243         DEBUGP("ACCOUNT: targinfosize %u != %u\n",
244                targinfosize, IPT_ALIGN(sizeof(struct ipt_acc_info)));
245         return 0;
246     }
247 #endif
248
249     spin_lock_bh(&ipt_acc_lock);
250     table_nr = ipt_acc_table_insert(info->table_name, info->net_ip,
251                                                       info->net_mask);
252     spin_unlock_bh(&ipt_acc_lock);
253
254     if (table_nr == -1) {
255         printk("ACCOUNT: Table insert problem. Aborting\n");
256 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
257         return -EINVAL;
258 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
259         return false;
260 #else
261         return 0;
262 #endif
263     }
264     /* Table nr caching so we don't have to do an extra string compare 
265        for every packet */
266     info->table_nr = table_nr;
267
268     /* All fine */
269 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
270     return 0;
271 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
272     return true;
273 #else
274     return 1;
275 #endif
276 }
277
278 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
279 static void ipt_acc_destroy(const struct xt_tgdtor_param *par)
280 #else
281 static void ipt_acc_destroy(
282 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
283                             const struct xt_target *target,
284 #endif
285 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
286                             void *targinfo)
287 #else
288                             void *targinfo,
289                             unsigned int targinfosize)
290 #endif
291 #endif /* >= 2.6.28 */
292 {
293     unsigned int i;
294 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
295     struct ipt_acc_info *info = par->targinfo;
296 #else
297     struct ipt_acc_info *info = targinfo;
298 #endif
299
300 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
301     if (targinfosize != IPT_ALIGN(sizeof(struct ipt_acc_info))) {
302         DEBUGP("ACCOUNT: targinfosize %u != %u\n",
303                targinfosize, IPT_ALIGN(sizeof(struct ipt_acc_info)));
304     }
305 #endif
306
307     spin_lock_bh(&ipt_acc_lock);
308
309     DEBUGP("ACCOUNT: ipt_acc_deleteentry called for table: %s (#%d)\n", 
310            info->table_name, info->table_nr);
311
312     info->table_nr = -1;    /* Set back to original state */
313
314     /* Look for table */
315     for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
316         if (strncmp(ipt_acc_tables[i].name, info->table_name, 
317                     ACCOUNT_TABLE_NAME_LEN) == 0) {
318             DEBUGP("ACCOUNT: Found table at slot: %d\n", i);
319
320             ipt_acc_tables[i].refcount--;
321             DEBUGP("ACCOUNT: Refcount left: %d\n", 
322                    ipt_acc_tables[i].refcount);
323
324             /* Table not needed anymore? */
325             if (ipt_acc_tables[i].refcount == 0) {
326                 DEBUGP("ACCOUNT: Destroying table at slot: %d\n", i);
327                 ipt_acc_data_free(ipt_acc_tables[i].data, 
328                                       ipt_acc_tables[i].depth);
329                 memset(&ipt_acc_tables[i], 0, 
330                        sizeof(struct ipt_acc_table));
331             }
332
333             spin_unlock_bh(&ipt_acc_lock);
334             return;
335         }
336     }
337
338     /* Table not found */
339     printk("ACCOUNT: Table %s not found for destroy\n", info->table_name);
340     spin_unlock_bh(&ipt_acc_lock);
341 }
342
343 static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
344                                u_int32_t net_ip, u_int32_t netmask,
345                                u_int32_t src_ip, u_int32_t dst_ip,
346                                u_int32_t size, u_int32_t *itemcount)
347 {
348     unsigned char is_src = 0, is_dst = 0, src_slot, dst_slot;
349     char is_src_new_ip = 0, is_dst_new_ip = 0; /* Check if this entry is new */
350
351     DEBUGP("ACCOUNT: ipt_acc_depth0_insert: %pI4/%pI4 "
352            "for net %pI4/%pI4, size: %u\n", &src_ip,
353            &dst_ip, &net_ip, &netmask, size);
354
355     /* Check if src/dst is inside our network. */
356     /* Special: net_ip = 0.0.0.0/0 gets stored as src in slot 0 */
357     if (!netmask)
358         src_ip = 0;
359     if ((net_ip&netmask) == (src_ip&netmask))
360         is_src = 1;
361     if ((net_ip&netmask) == (dst_ip&netmask) && netmask)
362         is_dst = 1;
363
364     if (!is_src && !is_dst) {
365         DEBUGP("ACCOUNT: Skipping packet %pI4/%pI4 "
366                "for net %pI4/%pI4\n", &src_ip,
367                &dst_ip, &net_ip, &netmask);
368         return;
369     }
370
371     /* Calculate array positions */
372     src_slot = (unsigned char)((src_ip&0xFF000000) >> 24);
373     dst_slot = (unsigned char)((dst_ip&0xFF000000) >> 24);
374
375     /* Increase size counters */
376     if (is_src) {
377         /* Calculate network slot */
378         DEBUGP("ACCOUNT: Calculated SRC 8 bit network slot: %d\n", src_slot);
379         if (!mask_24->ip[src_slot].src_packets 
380             && !mask_24->ip[src_slot].dst_packets)
381             is_src_new_ip = 1;
382
383         mask_24->ip[src_slot].src_packets++;
384         mask_24->ip[src_slot].src_bytes+=size;
385     }
386     if (is_dst) {
387         DEBUGP("ACCOUNT: Calculated DST 8 bit network slot: %d\n", dst_slot);
388         if (!mask_24->ip[dst_slot].src_packets 
389             && !mask_24->ip[dst_slot].dst_packets)
390             is_dst_new_ip = 1;
391
392         mask_24->ip[dst_slot].dst_packets++;
393         mask_24->ip[dst_slot].dst_bytes+=size;
394     }
395
396     /* Increase itemcounter */
397     DEBUGP("ACCOUNT: Itemcounter before: %d\n", *itemcount);
398     if (src_slot == dst_slot) {
399         if (is_src_new_ip || is_dst_new_ip) {
400             DEBUGP("ACCOUNT: src_slot == dst_slot: %d, %d\n", 
401                    is_src_new_ip, is_dst_new_ip);
402             (*itemcount)++;
403         }
404     } else {
405         if (is_src_new_ip) {
406             DEBUGP("ACCOUNT: New src_ip: %pI4\n", &src_ip);
407             (*itemcount)++;
408         }
409         if (is_dst_new_ip) {
410             DEBUGP("ACCOUNT: New dst_ip: %pI4\n", &dst_ip);
411             (*itemcount)++;
412         }
413     }
414     DEBUGP("ACCOUNT: Itemcounter after: %d\n", *itemcount);
415 }
416
417 static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16, 
418                                u_int32_t net_ip, u_int32_t netmask, 
419                                u_int32_t src_ip, u_int32_t dst_ip,
420                                u_int32_t size, u_int32_t *itemcount)
421 {
422     /* Do we need to process src IP? */
423     if ((net_ip&netmask) == (src_ip&netmask)) {
424         unsigned char slot = (unsigned char)((src_ip&0x00FF0000) >> 16);
425         DEBUGP("ACCOUNT: Calculated SRC 16 bit network slot: %d\n", slot);
426
427         /* Do we need to create a new mask_24 bucket? */
428         if (!mask_16->mask_24[slot] && (mask_16->mask_24[slot] = 
429              ipt_acc_zalloc_page()) == NULL) {
430             printk("ACCOUNT: Can't process packet because out of memory!\n");
431             return;
432         }
433
434         ipt_acc_depth0_insert((struct ipt_acc_mask_24 *)mask_16->mask_24[slot],
435                                   net_ip, netmask, src_ip, 0, size, itemcount);
436     }
437
438     /* Do we need to process dst IP? */
439     if ((net_ip&netmask) == (dst_ip&netmask)) {
440         unsigned char slot = (unsigned char)((dst_ip&0x00FF0000) >> 16);
441         DEBUGP("ACCOUNT: Calculated DST 16 bit network slot: %d\n", slot);
442
443         /* Do we need to create a new mask_24 bucket? */
444         if (!mask_16->mask_24[slot] && (mask_16->mask_24[slot] 
445             = ipt_acc_zalloc_page()) == NULL) {
446             printk("ACCOUT: Can't process packet because out of memory!\n");
447             return;
448         }
449
450         ipt_acc_depth0_insert((struct ipt_acc_mask_24 *)mask_16->mask_24[slot],
451                                   net_ip, netmask, 0, dst_ip, size, itemcount);
452     }
453 }
454
455 static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8, 
456                                u_int32_t net_ip, u_int32_t netmask,
457                                u_int32_t src_ip, u_int32_t dst_ip,
458                                u_int32_t size, u_int32_t *itemcount)
459 {
460     /* Do we need to process src IP? */
461     if ((net_ip&netmask) == (src_ip&netmask)) {
462         unsigned char slot = (unsigned char)((src_ip&0x0000FF00) >> 8);
463         DEBUGP("ACCOUNT: Calculated SRC 24 bit network slot: %d\n", slot);
464
465         /* Do we need to create a new mask_24 bucket? */
466         if (!mask_8->mask_16[slot] && (mask_8->mask_16[slot] 
467             = ipt_acc_zalloc_page()) == NULL) {
468             printk("ACCOUNT: Can't process packet because out of memory!\n");
469             return;
470         }
471
472         ipt_acc_depth1_insert((struct ipt_acc_mask_16 *)mask_8->mask_16[slot],
473                                   net_ip, netmask, src_ip, 0, size, itemcount);
474     }
475
476     /* Do we need to process dst IP? */
477     if ((net_ip&netmask) == (dst_ip&netmask)) {
478         unsigned char slot = (unsigned char)((dst_ip&0x0000FF00) >> 8);
479         DEBUGP("ACCOUNT: Calculated DST 24 bit network slot: %d\n", slot);
480
481         /* Do we need to create a new mask_24 bucket? */
482         if (!mask_8->mask_16[slot] && (mask_8->mask_16[slot] 
483             = ipt_acc_zalloc_page()) == NULL) {
484             printk("ACCOUNT: Can't process packet because out of memory!\n");
485             return;
486         }
487
488         ipt_acc_depth1_insert((struct ipt_acc_mask_16 *)mask_8->mask_16[slot],
489                                   net_ip, netmask, 0, dst_ip, size, itemcount);
490     }
491 }
492
493 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
494 static unsigned int ipt_acc_target(struct sk_buff *skb, const struct xt_action_param *par)
495 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
496 static unsigned int ipt_acc_target(struct sk_buff *skb, const struct xt_target_param *par)
497 #else
498 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
499 static unsigned int ipt_acc_target(struct sk_buff *skb,
500 #else
501 static unsigned int ipt_acc_target(struct sk_buff **pskb,
502 #endif
503                                    const struct net_device *in,
504                                    const struct net_device *out,
505                                    unsigned int hooknum,
506 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
507                                    const struct xt_target *target,
508 #endif
509 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
510                                    const void *targinfo)
511 #else
512                                    const void *targinfo,
513                                    void *userinfo)
514 #endif
515 #endif /* 2.6.28 */
516 {
517     const struct ipt_acc_info *info =
518 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
519         par->targinfo;
520 #else
521         (const struct ipt_acc_info *)targinfo;
522 #endif
523
524 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
525     u_int32_t src_ip = ip_hdr(skb)->saddr;
526     u_int32_t dst_ip = ip_hdr(skb)->daddr;
527     u_int32_t size = ntohs(ip_hdr(skb)->tot_len);
528 #else
529 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
530     u_int32_t src_ip = ip_hdr(*pskb)->saddr;
531     u_int32_t dst_ip = ip_hdr(*pskb)->daddr;
532     u_int32_t size = ntohs(ip_hdr(*pskb)->tot_len);
533 #else
534     u_int32_t src_ip = (*pskb)->nh.iph->saddr;
535     u_int32_t dst_ip = (*pskb)->nh.iph->daddr;
536     u_int32_t size = ntohs((*pskb)->nh.iph->tot_len);
537 #endif
538 #endif
539
540     spin_lock_bh(&ipt_acc_lock);
541
542     if (ipt_acc_tables[info->table_nr].name[0] == 0) {
543         printk("ACCOUNT: ipt_acc_target: Invalid table id %u. "
544                "IPs %pI4/%pI4\n", info->table_nr, 
545                &src_ip, &dst_ip);
546         spin_unlock_bh(&ipt_acc_lock);
547         return XT_CONTINUE;
548     }
549
550     /* 8 bit network or "any" network */
551     if (ipt_acc_tables[info->table_nr].depth == 0) {
552         /* Count packet and check if the IP is new */
553         ipt_acc_depth0_insert(
554             (struct ipt_acc_mask_24 *)ipt_acc_tables[info->table_nr].data,
555             ipt_acc_tables[info->table_nr].ip, 
556             ipt_acc_tables[info->table_nr].netmask,
557             src_ip, dst_ip, size, &ipt_acc_tables[info->table_nr].itemcount);
558         spin_unlock_bh(&ipt_acc_lock);
559         return XT_CONTINUE;
560     }
561
562     /* 16 bit network */
563     if (ipt_acc_tables[info->table_nr].depth == 1) {
564         ipt_acc_depth1_insert(
565             (struct ipt_acc_mask_16 *)ipt_acc_tables[info->table_nr].data,
566             ipt_acc_tables[info->table_nr].ip, 
567             ipt_acc_tables[info->table_nr].netmask,
568             src_ip, dst_ip, size, &ipt_acc_tables[info->table_nr].itemcount);
569         spin_unlock_bh(&ipt_acc_lock);
570         return XT_CONTINUE;
571     }
572
573     /* 24 bit network */
574     if (ipt_acc_tables[info->table_nr].depth == 2) {
575         ipt_acc_depth2_insert(
576             (struct ipt_acc_mask_8 *)ipt_acc_tables[info->table_nr].data,
577             ipt_acc_tables[info->table_nr].ip, 
578             ipt_acc_tables[info->table_nr].netmask,
579             src_ip, dst_ip, size, &ipt_acc_tables[info->table_nr].itemcount);
580         spin_unlock_bh(&ipt_acc_lock);
581         return XT_CONTINUE;
582     }
583
584     printk("ACCOUNT: ipt_acc_target: Unable to process packet. "
585            "Table id %u. IPs %pI4/%pI4\n", 
586            info->table_nr, &src_ip, &dst_ip);
587
588     spin_unlock_bh(&ipt_acc_lock);
589     return XT_CONTINUE;
590 }
591
592 /*
593     Functions dealing with "handles":
594     Handles are snapshots of a accounting state.
595     
596     read snapshots are only for debugging the code
597     and are very expensive concerning speed/memory
598     compared to read_and_flush.
599     
600     The functions aren't protected by spinlocks themselves
601     as this is done in the ioctl part of the code.
602 */
603
604 /*
605     Find a free handle slot. Normally only one should be used,
606     but there could be two or more applications accessing the data
607     at the same time.
608 */
609 static int ipt_acc_handle_find_slot(void)
610 {
611     unsigned int i;
612     /* Insert new table */
613     for (i = 0; i < ACCOUNT_MAX_HANDLES; i++) {
614         /* Found free slot */
615         if (ipt_acc_handles[i].data == NULL) {
616             /* Don't "mark" data as used as we are protected by a spinlock 
617                by the calling function. handle_find_slot() is only a function
618                to prevent code duplication. */
619             return i;
620         }
621     }
622
623     /* No free slot found */
624     printk("ACCOUNT: No free handle slot found (max: %u). "
625            "Please increase ACCOUNT_MAX_HANDLES.\n", ACCOUNT_MAX_HANDLES);
626     return -1;
627 }
628
629 static int ipt_acc_handle_free(unsigned int handle)
630 {
631     if (handle >= ACCOUNT_MAX_HANDLES) {
632         printk("ACCOUNT: Invalid handle for ipt_acc_handle_free() specified:"
633                " %u\n", handle);
634         return -EINVAL;
635     }
636
637     ipt_acc_data_free(ipt_acc_handles[handle].data, 
638                           ipt_acc_handles[handle].depth);
639     memset (&ipt_acc_handles[handle], 0, sizeof (struct ipt_acc_handle));
640     return 0;
641 }
642
643 /* Prepare data for read without flush. Use only for debugging!
644    Real applications should use read&flush as it's way more efficent */
645 static int ipt_acc_handle_prepare_read(char *tablename,
646          struct ipt_acc_handle *dest, u_int32_t *count)
647 {
648     int table_nr=-1;
649     unsigned char depth;
650
651     for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
652         if (strncmp(ipt_acc_tables[table_nr].name, tablename, 
653             ACCOUNT_TABLE_NAME_LEN) == 0)
654                 break;
655
656     if (table_nr == ACCOUNT_MAX_TABLES) {
657         printk("ACCOUNT: ipt_acc_handle_prepare_read(): "
658                "Table %s not found\n", tablename);
659         return -1;
660     }
661
662     /* Fill up handle structure */
663     dest->ip = ipt_acc_tables[table_nr].ip;
664     dest->depth = ipt_acc_tables[table_nr].depth;
665     dest->itemcount = ipt_acc_tables[table_nr].itemcount;
666
667     /* allocate "root" table */
668     if ((dest->data = ipt_acc_zalloc_page()) == NULL) {
669         printk("ACCOUNT: out of memory for root table "
670                "in ipt_acc_handle_prepare_read()\n");
671         return -1;
672     }
673
674     /* Recursive copy of complete data structure */
675     depth = dest->depth;
676     if (depth == 0) {
677         memcpy(dest->data, 
678                ipt_acc_tables[table_nr].data, 
679                sizeof(struct ipt_acc_mask_24));
680     } else if (depth == 1) {
681         struct ipt_acc_mask_16 *src_16 = 
682             (struct ipt_acc_mask_16 *)ipt_acc_tables[table_nr].data;
683         struct ipt_acc_mask_16 *network_16 =
684             (struct ipt_acc_mask_16 *)dest->data;
685         unsigned int b;
686
687         for (b = 0; b <= 255; b++) {
688             if (src_16->mask_24[b]) {
689                 if ((network_16->mask_24[b] = 
690                      ipt_acc_zalloc_page()) == NULL) {
691                     printk("ACCOUNT: out of memory during copy of 16 bit "
692                            "network in ipt_acc_handle_prepare_read()\n");
693                     ipt_acc_data_free(dest->data, depth);
694                     return -1;
695                 }
696
697                 memcpy(network_16->mask_24[b], src_16->mask_24[b], 
698                        sizeof(struct ipt_acc_mask_24));
699             }
700         }
701     } else if(depth == 2) {
702         struct ipt_acc_mask_8 *src_8 = 
703             (struct ipt_acc_mask_8 *)ipt_acc_tables[table_nr].data;
704         struct ipt_acc_mask_8 *network_8 = 
705             (struct ipt_acc_mask_8 *)dest->data;
706         struct ipt_acc_mask_16 *src_16, *network_16;
707         unsigned int a, b;
708
709         for (a = 0; a <= 255; a++) {
710             if (src_8->mask_16[a]) {
711                 if ((network_8->mask_16[a] = 
712                      ipt_acc_zalloc_page()) == NULL) {
713                     printk("ACCOUNT: out of memory during copy of 24 bit network"
714                            " in ipt_acc_handle_prepare_read()\n");
715                     ipt_acc_data_free(dest->data, depth);
716                     return -1;
717                 }
718
719                 memcpy(network_8->mask_16[a], src_8->mask_16[a], 
720                        sizeof(struct ipt_acc_mask_16));
721
722                 src_16 = src_8->mask_16[a];
723                 network_16 = network_8->mask_16[a];
724
725                 for (b = 0; b <= 255; b++) {
726                     if (src_16->mask_24[b]) {
727                         if ((network_16->mask_24[b] = 
728                              ipt_acc_zalloc_page()) == NULL) {
729                             printk("ACCOUNT: out of memory during copy of 16 bit"
730                                    " network in ipt_acc_handle_prepare_read()\n");
731                             ipt_acc_data_free(dest->data, depth);
732                             return -1;
733                         }
734
735                         memcpy(network_16->mask_24[b], src_16->mask_24[b], 
736                                sizeof(struct ipt_acc_mask_24));
737                     }
738                 }
739             }
740         }
741     }
742
743     *count = ipt_acc_tables[table_nr].itemcount;
744     
745     return 0;
746 }
747
748 /* Prepare data for read and flush it */
749 static int ipt_acc_handle_prepare_read_flush(char *tablename,
750                struct ipt_acc_handle *dest, u_int32_t *count)
751 {
752     int table_nr;
753     void *new_data_page;
754
755     for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
756         if (strncmp(ipt_acc_tables[table_nr].name, tablename, 
757             ACCOUNT_TABLE_NAME_LEN) == 0)
758                 break;
759
760     if (table_nr == ACCOUNT_MAX_TABLES) {
761         printk("ACCOUNT: ipt_acc_handle_prepare_read_flush(): "
762                "Table %s not found\n", tablename);
763         return -1;
764     }
765
766     /* Try to allocate memory */
767     if (!(new_data_page = ipt_acc_zalloc_page())) {
768         printk("ACCOUNT: ipt_acc_handle_prepare_read_flush(): "
769                "Out of memory!\n");
770         return -1;
771     }
772
773     /* Fill up handle structure */
774     dest->ip = ipt_acc_tables[table_nr].ip;
775     dest->depth = ipt_acc_tables[table_nr].depth;
776     dest->itemcount = ipt_acc_tables[table_nr].itemcount;
777     dest->data = ipt_acc_tables[table_nr].data;
778     *count = ipt_acc_tables[table_nr].itemcount;
779
780     /* "Flush" table data */
781     ipt_acc_tables[table_nr].data = new_data_page;
782     ipt_acc_tables[table_nr].itemcount = 0;
783
784     return 0;
785 }
786
787 /* Copy 8 bit network data into a prepared buffer.
788    We only copy entries != 0 to increase performance.
789 */
790 static int ipt_acc_handle_copy_data(void *to_user, unsigned long *to_user_pos,
791                                   unsigned long *tmpbuf_pos, 
792                                   struct ipt_acc_mask_24 *data,
793                                   u_int32_t net_ip, u_int32_t net_OR_mask)
794 {
795     struct ipt_acc_handle_ip handle_ip;
796     size_t handle_ip_size = sizeof (struct ipt_acc_handle_ip);
797     unsigned int i;
798     
799     for (i = 0; i <= 255; i++) {
800         if (data->ip[i].src_packets || data->ip[i].dst_packets) {
801             handle_ip.ip = net_ip | net_OR_mask | (i<<24);
802             
803             handle_ip.src_packets = data->ip[i].src_packets;
804             handle_ip.src_bytes = data->ip[i].src_bytes;
805             handle_ip.dst_packets = data->ip[i].dst_packets;
806             handle_ip.dst_bytes = data->ip[i].dst_bytes;
807
808             /* Temporary buffer full? Flush to userspace */
809             if (*tmpbuf_pos+handle_ip_size >= PAGE_SIZE) {
810                 if (copy_to_user(to_user + *to_user_pos, ipt_acc_tmpbuf,
811                                                            *tmpbuf_pos))
812                     return -EFAULT;
813                 *to_user_pos = *to_user_pos + *tmpbuf_pos;
814                 *tmpbuf_pos = 0;
815             }
816             memcpy(ipt_acc_tmpbuf+*tmpbuf_pos, &handle_ip, handle_ip_size);
817             *tmpbuf_pos += handle_ip_size;
818         }
819     }
820     
821     return 0;
822 }
823    
824 /* Copy the data from our internal structure 
825    We only copy entries != 0 to increase performance.
826    Overwrites ipt_acc_tmpbuf.
827 */
828 static int ipt_acc_handle_get_data(u_int32_t handle, void *to_user)
829 {
830     unsigned long to_user_pos=0, tmpbuf_pos=0;
831     u_int32_t net_ip;
832     unsigned char depth;
833
834     if (handle >= ACCOUNT_MAX_HANDLES) {
835         printk("ACCOUNT: invalid handle for ipt_acc_handle_get_data() "
836                "specified: %u\n", handle);
837         return -1;
838     }
839
840     if (ipt_acc_handles[handle].data == NULL) {
841         printk("ACCOUNT: handle %u is BROKEN: Contains no data\n", handle);
842         return -1;
843     }
844
845     net_ip = ipt_acc_handles[handle].ip;
846     depth = ipt_acc_handles[handle].depth;
847
848     /* 8 bit network */
849     if (depth == 0) {
850         struct ipt_acc_mask_24 *network = 
851             (struct ipt_acc_mask_24*)ipt_acc_handles[handle].data;
852         if (ipt_acc_handle_copy_data(to_user, &to_user_pos, &tmpbuf_pos,
853                                      network, net_ip, 0))
854             return -1;
855         
856         /* Flush remaining data to userspace */
857         if (tmpbuf_pos)
858             if (copy_to_user(to_user+to_user_pos, ipt_acc_tmpbuf, tmpbuf_pos))
859                 return -1;
860
861         return 0;
862     }
863
864     /* 16 bit network */
865     if (depth == 1) {
866         struct ipt_acc_mask_16 *network_16 = 
867             (struct ipt_acc_mask_16*)ipt_acc_handles[handle].data;
868         unsigned int b;
869         for (b = 0; b <= 255; b++) {
870             if (network_16->mask_24[b]) {
871                 struct ipt_acc_mask_24 *network = 
872                     (struct ipt_acc_mask_24*)network_16->mask_24[b];
873                 if (ipt_acc_handle_copy_data(to_user, &to_user_pos,
874                                       &tmpbuf_pos, network, net_ip, (b << 16)))
875                     return -1;
876             }
877         }
878
879         /* Flush remaining data to userspace */
880         if (tmpbuf_pos)
881             if (copy_to_user(to_user+to_user_pos, ipt_acc_tmpbuf, tmpbuf_pos))
882                 return -1;
883
884         return 0;
885     }
886
887     /* 24 bit network */
888     if (depth == 2) {
889         struct ipt_acc_mask_8 *network_8 = 
890             (struct ipt_acc_mask_8*)ipt_acc_handles[handle].data;
891         unsigned int a, b;
892         for (a = 0; a <= 255; a++) {
893             if (network_8->mask_16[a]) {
894                 struct ipt_acc_mask_16 *network_16 = 
895                     (struct ipt_acc_mask_16*)network_8->mask_16[a];
896                 for (b = 0; b <= 255; b++) {
897                     if (network_16->mask_24[b]) {
898                         struct ipt_acc_mask_24 *network = 
899                             (struct ipt_acc_mask_24*)network_16->mask_24[b];
900                         if (ipt_acc_handle_copy_data(to_user,
901                                        &to_user_pos, &tmpbuf_pos,
902                                        network, net_ip, (a << 8) | (b << 16)))
903                             return -1;
904                     }
905                 }
906             }
907         }
908
909         /* Flush remaining data to userspace */
910         if (tmpbuf_pos)
911             if (copy_to_user(to_user+to_user_pos, ipt_acc_tmpbuf, tmpbuf_pos))
912                 return -1;
913
914         return 0;
915     }
916     
917     return -1;
918 }
919
920 static int ipt_acc_set_ctl(struct sock *sk, int cmd, 
921                                void *user, unsigned int len)
922 {
923     struct ipt_acc_handle_sockopt handle;
924     int ret = -EINVAL;
925
926     if (!capable(CAP_NET_ADMIN))
927         return -EPERM;
928
929     switch (cmd) {
930     case IPT_SO_SET_ACCOUNT_HANDLE_FREE:
931         if (len != sizeof(struct ipt_acc_handle_sockopt)) {
932             printk("ACCOUNT: ipt_acc_set_ctl: wrong data size (%u != %zu) "
933                    "for IPT_SO_SET_HANDLE_FREE\n", 
934                    len, sizeof(struct ipt_acc_handle_sockopt));
935             break;
936         }
937
938         if (copy_from_user (&handle, user, len)) {
939             printk("ACCOUNT: ipt_acc_set_ctl: copy_from_user failed for "
940                    "IPT_SO_SET_HANDLE_FREE\n");
941             break;
942         }
943
944         down(&ipt_acc_userspace_mutex);
945         ret = ipt_acc_handle_free(handle.handle_nr);
946         up(&ipt_acc_userspace_mutex);
947         break;
948     case IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL: {
949             unsigned int i;
950             down(&ipt_acc_userspace_mutex);
951             for (i = 0; i < ACCOUNT_MAX_HANDLES; i++)
952                 ipt_acc_handle_free(i);
953             up(&ipt_acc_userspace_mutex);
954             ret = 0;
955             break;
956         }
957     default:
958         printk("ACCOUNT: ipt_acc_set_ctl: unknown request %i\n", cmd);
959     }
960
961     return ret;
962 }
963
964 static int ipt_acc_get_ctl(struct sock *sk, int cmd, void *user, int *len)
965 {
966     struct ipt_acc_handle_sockopt handle;
967     int ret = -EINVAL;
968
969     if (!capable(CAP_NET_ADMIN))
970         return -EPERM;
971
972     switch (cmd) {
973     case IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH:
974     case IPT_SO_GET_ACCOUNT_PREPARE_READ: {
975             struct ipt_acc_handle dest;
976
977             if (*len < sizeof(struct ipt_acc_handle_sockopt)) {
978                 printk("ACCOUNT: ipt_acc_get_ctl: wrong data size (%u != %zu) "
979                     "for IPT_SO_GET_ACCOUNT_PREPARE_READ/READ_FLUSH\n",
980                     *len, sizeof(struct ipt_acc_handle_sockopt));
981                 break;
982             }
983
984             if (copy_from_user (&handle, user, 
985                                 sizeof(struct ipt_acc_handle_sockopt))) {
986                 return -EFAULT;
987                 break;
988             }
989
990             spin_lock_bh(&ipt_acc_lock);
991             if (cmd == IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH)
992                 ret = ipt_acc_handle_prepare_read_flush(
993                                     handle.name, &dest, &handle.itemcount);
994             else
995                 ret = ipt_acc_handle_prepare_read(
996                                     handle.name, &dest, &handle.itemcount);
997             spin_unlock_bh(&ipt_acc_lock);
998             // Error occured during prepare_read?
999            if (ret == -1)
1000                 return -EINVAL;
1001
1002             /* Allocate a userspace handle */
1003             down(&ipt_acc_userspace_mutex);
1004             if ((handle.handle_nr = ipt_acc_handle_find_slot()) == -1) {
1005                 ipt_acc_data_free(dest.data, dest.depth);
1006                 up(&ipt_acc_userspace_mutex);
1007                 return -EINVAL;
1008             }
1009             memcpy(&ipt_acc_handles[handle.handle_nr], &dest,
1010                              sizeof(struct ipt_acc_handle));
1011             up(&ipt_acc_userspace_mutex);
1012
1013             if (copy_to_user(user, &handle, 
1014                             sizeof(struct ipt_acc_handle_sockopt))) {
1015                 return -EFAULT;
1016                 break;
1017             }
1018             ret = 0;
1019             break;
1020         }
1021     case IPT_SO_GET_ACCOUNT_GET_DATA:
1022         if (*len < sizeof(struct ipt_acc_handle_sockopt)) {
1023             printk("ACCOUNT: ipt_acc_get_ctl: wrong data size (%u != %zu)"
1024                    " for IPT_SO_GET_ACCOUNT_PREPARE_READ/READ_FLUSH\n",
1025                    *len, sizeof(struct ipt_acc_handle_sockopt));
1026             break;
1027         }
1028
1029         if (copy_from_user (&handle, user, 
1030                             sizeof(struct ipt_acc_handle_sockopt))) {
1031             return -EFAULT;
1032             break;
1033         }
1034
1035         if (handle.handle_nr >= ACCOUNT_MAX_HANDLES) {
1036             return -EINVAL;
1037             break;
1038         }
1039
1040         if (*len < ipt_acc_handles[handle.handle_nr].itemcount
1041                    * sizeof(struct ipt_acc_handle_ip)) {
1042             printk("ACCOUNT: ipt_acc_get_ctl: not enough space (%u < %zu)"
1043                    " to store data from IPT_SO_GET_ACCOUNT_GET_DATA\n",
1044                    *len, ipt_acc_handles[handle.handle_nr].itemcount
1045                    * sizeof(struct ipt_acc_handle_ip));
1046             ret = -ENOMEM;
1047             break;
1048         }
1049
1050         down(&ipt_acc_userspace_mutex);
1051         ret = ipt_acc_handle_get_data(handle.handle_nr, user);
1052         up(&ipt_acc_userspace_mutex);
1053         if (ret) {
1054             printk("ACCOUNT: ipt_acc_get_ctl: ipt_acc_handle_get_data"
1055                    " failed for handle %u\n", handle.handle_nr);
1056             break;
1057         }
1058
1059         ret = 0;
1060         break;
1061     case IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE: {
1062             unsigned int i;
1063             if (*len < sizeof(struct ipt_acc_handle_sockopt)) {
1064                 printk("ACCOUNT: ipt_acc_get_ctl: wrong data size (%u != %zu)"
1065                        " for IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE\n",
1066                        *len, sizeof(struct ipt_acc_handle_sockopt));
1067                 break;
1068             }
1069
1070             /* Find out how many handles are in use */
1071             handle.itemcount = 0;
1072             down(&ipt_acc_userspace_mutex);
1073             for (i = 0; i < ACCOUNT_MAX_HANDLES; i++)
1074                 if (ipt_acc_handles[i].data)
1075                     handle.itemcount++;
1076             up(&ipt_acc_userspace_mutex);
1077
1078             if (copy_to_user(user, &handle, 
1079                              sizeof(struct ipt_acc_handle_sockopt))) {
1080                 return -EFAULT;
1081                 break;
1082             }
1083             ret = 0;
1084             break;
1085         }
1086     case IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES: {
1087             u_int32_t size = 0, i, name_len;
1088             char *tnames;
1089
1090             spin_lock_bh(&ipt_acc_lock);
1091
1092             /* Determine size of table names */
1093             for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
1094                 if (ipt_acc_tables[i].name[0] != 0)
1095                     size += strlen (ipt_acc_tables[i].name) + 1;
1096             }
1097             size += 1;    /* Terminating NULL character */
1098
1099             if (*len < size || size > PAGE_SIZE) {
1100                 spin_unlock_bh(&ipt_acc_lock);
1101                 printk("ACCOUNT: ipt_acc_get_ctl: not enough space (%u < %u < %lu)"
1102                        " to store table names\n", *len, size, PAGE_SIZE);
1103                 ret = -ENOMEM;
1104                 break;
1105             }
1106             /* Copy table names to userspace */
1107             tnames = ipt_acc_tmpbuf;
1108             for (i = 0; i < ACCOUNT_MAX_TABLES; i++) {
1109                 if (ipt_acc_tables[i].name[0] != 0) {
1110                     name_len = strlen (ipt_acc_tables[i].name) + 1;
1111                     memcpy(tnames, ipt_acc_tables[i].name, name_len);
1112                     tnames += name_len;
1113                 }
1114             }
1115             spin_unlock_bh(&ipt_acc_lock);
1116
1117             /* Terminating NULL character */
1118             *tnames = 0;
1119
1120             /* Transfer to userspace */
1121             if (copy_to_user(user, ipt_acc_tmpbuf, size))
1122                 return -EFAULT;
1123
1124             ret = 0;
1125             break;
1126         }
1127     default:
1128         printk("ACCOUNT: ipt_acc_get_ctl: unknown request %i\n", cmd);
1129     }
1130
1131     return ret;
1132 }
1133
1134 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
1135 static struct xt_target xt_acc_reg = {
1136 #else
1137 static struct ipt_target ipt_acc_reg = {
1138 #endif
1139     .name = "ACCOUNT",
1140 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
1141     .family = AF_INET,
1142 #endif
1143     .target = ipt_acc_target,
1144 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
1145     .targetsize = sizeof(struct ipt_acc_info),
1146 #endif
1147     .checkentry = ipt_acc_checkentry,
1148     .destroy = ipt_acc_destroy,
1149     .me = THIS_MODULE
1150 };
1151
1152 static struct nf_sockopt_ops ipt_acc_sockopts = {
1153     .pf = PF_INET,
1154     .set_optmin = IPT_SO_SET_ACCOUNT_HANDLE_FREE,
1155     .set_optmax = IPT_SO_SET_ACCOUNT_MAX+1,
1156     .set = ipt_acc_set_ctl,
1157     .get_optmin = IPT_SO_GET_ACCOUNT_PREPARE_READ,
1158     .get_optmax = IPT_SO_GET_ACCOUNT_MAX+1,
1159     .get = ipt_acc_get_ctl
1160 };
1161
1162 static int __init init(void)
1163 {
1164     sema_init(&ipt_acc_userspace_mutex, 1);
1165
1166     if ((ipt_acc_tables = 
1167          kmalloc(ACCOUNT_MAX_TABLES * 
1168                  sizeof(struct ipt_acc_table), GFP_KERNEL)) == NULL) {
1169         printk("ACCOUNT: Out of memory allocating account_tables structure");
1170         goto error_cleanup;
1171     }
1172     memset(ipt_acc_tables, 0,
1173            ACCOUNT_MAX_TABLES * sizeof(struct ipt_acc_table));
1174
1175     if ((ipt_acc_handles = 
1176          kmalloc(ACCOUNT_MAX_HANDLES * 
1177                  sizeof(struct ipt_acc_handle), GFP_KERNEL)) == NULL) {
1178         printk("ACCOUNT: Out of memory allocating account_handles structure");
1179         goto error_cleanup;
1180     }
1181     memset(ipt_acc_handles, 0,
1182            ACCOUNT_MAX_HANDLES * sizeof(struct ipt_acc_handle));
1183
1184     /* Allocate one page as temporary storage */
1185     if ((ipt_acc_tmpbuf = (void*)__get_free_page(GFP_KERNEL)) == NULL) {
1186         printk("ACCOUNT: Out of memory for temporary buffer page\n");
1187         goto error_cleanup;
1188     }
1189
1190     /* Register setsockopt */
1191     if (nf_register_sockopt(&ipt_acc_sockopts) < 0) {
1192         printk("ACCOUNT: Can't register sockopts. Aborting\n");
1193         goto error_cleanup;
1194     }
1195
1196 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
1197     if (xt_register_target(&xt_acc_reg))
1198 #else
1199     if (ipt_register_target(&ipt_acc_reg))
1200 #endif
1201         goto error_cleanup;
1202
1203     return 0;
1204
1205 error_cleanup:
1206     if(ipt_acc_tables)
1207         kfree(ipt_acc_tables);
1208     if(ipt_acc_handles)
1209         kfree(ipt_acc_handles);
1210     if (ipt_acc_tmpbuf)
1211         free_page((unsigned long)ipt_acc_tmpbuf);
1212
1213     return -EINVAL;
1214 }
1215
1216 static void __exit fini(void)
1217 {
1218 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
1219     xt_unregister_target(&xt_acc_reg);
1220 #else
1221     ipt_unregister_target(&ipt_acc_reg);
1222 #endif
1223
1224     nf_unregister_sockopt(&ipt_acc_sockopts);
1225
1226     kfree(ipt_acc_tables);
1227     kfree(ipt_acc_handles);
1228     free_page((unsigned long)ipt_acc_tmpbuf);
1229 }
1230
1231 module_init(init);
1232 module_exit(fini);
1233 MODULE_LICENSE("GPL");