2 * This is a module which is used for counting packets.
4 #include <linux/module.h>
5 #include <linux/skbuff.h>
7 #include <linux/spinlock.h>
11 #include <linux/netfilter_ipv4/ip_tables.h>
14 #include <net/route.h>
15 #include <linux/netfilter_ipv4/ipt_ACCOUNT.h>
20 //#define DEBUGP(format, args...)
23 struct ipt_account_table *ipt_account_tables = NULL;
24 struct ipt_account_handle *ipt_account_handles = NULL;
26 static spinlock_t ipt_account_lock = SPIN_LOCK_UNLOCKED;
29 ipt_account_target(struct sk_buff **pskb,
31 const struct net_device *in,
32 const struct net_device *out,
36 spin_lock_bh(&ipt_account_lock);
37 spin_unlock_bh(&ipt_account_lock);
42 /* Recursive free of all data structures */
43 void ipt_account_data_free(void *data, unsigned char netsize)
49 // Free for 8 bit network. Special: 0.0.0.0/0
50 if (netsize >= 24 || netsize == 0)
57 // Free for 16 bit network
60 struct ipt_account_mask_16 *mask_16 = (struct ipt_account_mask_16 *)data;
62 for (b=0; b < 255; b++)
64 if (mask_16->mask_24[b] != 0)
66 kfree(mask_16->mask_24[b]);
67 mask_16->mask_24[b] = NULL;
75 // Free for 24 bit network
79 for (a=0; a < 255; a++)
81 if (((struct ipt_account_mask_8 *)data)->mask_16[a])
83 struct ipt_account_mask_16 *mask_16 = (struct ipt_account_mask_16*)((struct ipt_account_mask_8 *)data)->mask_16[a];
84 for (b=0; b < 255; b++)
86 if (mask_16->mask_24[b]) {
87 kfree(mask_16->mask_24[b]);
88 mask_16->mask_24[b] = NULL;
100 printk("ACCOUNT: ipt_account_data_free called with broken netsize: %d\n", netsize);
104 /* Look for existing table / insert new one. Return internal ID or -1 on error */
105 int ipt_account_table_insert(char *name, unsigned int ip, unsigned int netmask)
109 DEBUGP("ACCOUNT: ipt_account_table_insert: %s, %u/%u\n", name, ip, netmask);
111 // Look for existing table
112 for (i = 0; i < ACCOUNT_MAX_TABLES; i++)
114 if (strcmp(ipt_account_tables[i].name, name) == 0)
116 DEBUGP("ACCOUT: Found existing slot: %d - %u/%u\n", i, ipt_account_tables[i].ip, ipt_account_tables[i].netmask);
118 if (ipt_account_tables[i].ip != ip || ipt_account_tables[i].netmask != netmask)
120 printk("ACCOUNT: Table %s found, but IP/netmask mismatch. IP/netmask found: %u/%u\n",
121 name, ipt_account_tables[i].ip, ipt_account_tables[i].netmask);
125 ipt_account_tables[i].refcount++;
126 DEBUGP("ACCOUNT: Refcount: %d\n", ipt_account_tables[i].refcount);
132 for (i = 0; i < ACCOUNT_MAX_TABLES; i++)
135 if (ipt_account_tables[i].name[0] == 0)
137 DEBUGP("ACCOUNT: Found free slot: %d\n", i);
139 strncpy (ipt_account_tables[i].name, name, ACCOUNT_TABLE_NAME_LEN-1);
141 ipt_account_tables[i].ip = ip;
142 ipt_account_tables[i].netmask = netmask;
145 unsigned int j, calc_mask;
146 calc_mask = htonl(netmask);
147 for (j = 31; j > 0; j--)
149 if (calc_mask&(1<<j))
150 ipt_account_tables[i].netsize++;
154 printk("ACCOUNT: calculated netsize: %u\n", ipt_account_tables[i].netsize);
156 ipt_account_tables[i].refcount++;
157 if (!(ipt_account_tables[i].data = (void *)get_zeroed_page(GFP_KERNEL)))
159 printk("ACCOUNT: Out of memory for data of table: %s\n", name);
160 memset(&ipt_account_tables[i], 0, sizeof(struct ipt_account_table));
167 // No free slot found
168 printk("ACCOUNT: No free table slot found (max: %d). Please increase ACCOUNT_MAX_TABLES.\n", ACCOUNT_MAX_TABLES);
172 static int ipt_account_checkentry(const char *tablename,
173 const struct ipt_entry *e,
175 unsigned int targinfosize,
176 unsigned int hook_mask)
178 struct ipt_account_info *info = targinfo;
180 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_account_info))) {
181 DEBUGP("ACCOUNT: targinfosize %u != %u\n",
182 targinfosize, IPT_ALIGN(sizeof(struct ipt_account_info)));
186 int table_nr = ipt_account_table_insert(info->table_name, info->net_ip, info->net_mask);
189 printk("ACCOUNT: Table insert problem. Aborting\n");
193 // Table nr caching so we don't have to do an extra string compare for every packet
194 info->table_nr = table_nr;
199 static struct ipt_target ipt_account_reg
200 = { { NULL, NULL }, "ACCOUNT", ipt_account_target, ipt_account_checkentry, NULL,
203 static int __init init(void)
205 if (!(ipt_account_tables = kmalloc(ACCOUNT_MAX_TABLES, sizeof(struct ipt_account_table))))
207 printk("ACCOUNT: Out of memory allocating account_tables structure");
210 memset(ipt_account_tables, 0, sizeof(struct ipt_account_table));
212 if (!(ipt_account_handles = kmalloc(ACCOUNT_MAX_HANDLES, sizeof(struct ipt_account_handle))))
214 printk("ACCOUNT: Out of memory allocating account_handles structure");
215 kfree (ipt_account_tables);
216 ipt_account_tables = NULL;
219 memset(ipt_account_handles, 0, sizeof(struct ipt_account_handle));
221 if (ipt_register_target(&ipt_account_reg))
227 static void __exit fini(void)
229 ipt_unregister_target(&ipt_account_reg);
231 kfree(ipt_account_tables);
232 ipt_account_tables = NULL;
234 kfree(ipt_account_handles);
235 ipt_account_handles = NULL;
240 MODULE_LICENSE("GPL");