1 /* This file contains all the functions required for the standalone
4 These are not required by the compatibility layer.
7 /* (c) 2005 Echo Licenced under the GNU General
10 #include <linux/config.h>
11 #include <linux/types.h>
13 #include <linux/netfilter.h>
14 #include <linux/netfilter_ipv4.h>
15 #include <linux/module.h>
16 #include <linux/skbuff.h>
17 #include <linux/proc_fs.h>
19 #include <linux/sysctl.h>
21 #include <net/checksum.h>
25 #include <linux/netfilter_ipv4/traffic_defs.h>
26 #include <linux/netfilter_ipv4/ip_conntrack.h>
31 #define DEBUGP(format, args...)
36 struct module *ip_traffic_module = THIS_MODULE;
37 MODULE_LICENSE ("GPL");
39 #define MEGA_BYTE 0x00080000 //Mega byte
41 unsigned int traffic_bytes = 0; // means 0MB
42 unsigned int traffic_tmp = 0; //use to temporaly store the bytes less than 1 M
44 extern struct list_head traffic_config_list_head;
47 list_traffics (char *buffer, char **start, off_t offset, int length)
51 const struct list_head *__t = &traffic_config_list_head;
54 char *tmp = kmalloc (BUFFSIZE, GFP_KERNEL);
57 printk ("kernel malloc memory failed.\n");
64 * This simple implementation can only work in condition that data needed to show and
65 * configure is less than 4K.
66 * If the assumption is not true, then you should deal with the parameters start&offset
67 * You can find some helps in linux/fs/proc/generic.c about line 65.
70 sprintf (tmp, "%sthrough_bytes(MB)=%d\n", tmp, traffic_bytes);
74 if (__t == (&traffic_config_list_head))
80 snprintf (tmp, BUFFSIZE, "%sip=%d\tlimit=%d\tblock=%d\n", tmp,
81 ((const ptraffic_config_t) __t)->ip_address,
82 ((const ptraffic_config_t) __t)->ip_traffic_MAX,
83 ((const ptraffic_config_t) __t)->autoBlock);
86 strncpy (buffer, tmp, BUFFSIZE);
88 len = strlen (buffer);
94 * The function is used to count the packet through the wan interface.
95 * Packet is counted and indentified by IP address.
97 * When the sum of packet for certain IP address reaches the budget, than the
98 * 1. No more packet can be sent to Internet through the router here.
99 * 2. No more new connection is allowed to established, but the current
100 * connection is not affected at all.
104 ip_traffic_control (unsigned int hooknum, struct sk_buff **pskb,
105 const struct net_device *in,
106 const struct net_device *out,
107 int (*okfn) (struct sk_buff *))
110 char *p = (char *) &addr;
111 struct list_head *__t = &traffic_config_list_head;
112 //for check the conntrack status of the packet.
113 struct ip_conntrack *ct;
114 enum ip_conntrack_info ctinfo;
115 unsigned int verdict = NF_ACCEPT;
117 int found = 0; //the packet is in the list
118 struct list_head other = NULL; //refer to configuration for other pc.
127 printk (KERN_INFO "a packet with daddr=%ld sapass throuth post_routing.\n",
128 (*pskb)->nh.iph->daddr);
129 printk (KERN_INFO "htonl(addr) = %ld", htonl (addr));
133 // the packet coming from/to wan interface
135 if ((out->name != NULL && strcmp (out->name, "br0") != 0)
136 || (*pskb)->sk == NULL)
139 if (out->name != NULL && strcmp (out->name, "br0") != 0)
141 traffic_tmp += (*pskb)->nh.iph->tot_len;
142 if (traffic_tmp >= MEGA_BYTE)
144 traffic_bytes += traffic_tmp / MEGA_BYTE;
145 traffic_tmp = traffic_tmp % MEGA_BYTE;
151 if ((*pskb)->sk == NULL)
156 if (__t == (&traffic_config_list_head))
161 /* if ((*pskb)->mac.raw >= (*pskb)->head
162 && ((*pskb)->mac.raw + ETH_HLEN) <= (*pskb)->data
163 && memcmp ((*pskb)->mac.ethernet->h_source,
164 ((ptraffic_config_t) __t)->h_dest, ETH_ALEN) == 0)
166 if (((ptraffic_config_t) __t)->ip_address == 0)
168 if ((*pskb)->nh.iph->daddr ==
169 htonl (((ptraffic_config_t) __t)->ip_address)
170 || (*pskb)->nh.iph->saddr ==
171 htonl (((ptraffic_config_t) __t)->ip_address))
173 ((ptraffic_config_t) __t)->ip_traffic_local +=
174 (*pskb)->nh.iph->tot_len;
175 if (((ptraffic_config_t) __t)->ip_traffic_local >=
178 ((ptraffic_config_t) __t)->ip_traffic_MAX -=
179 ((ptraffic_config_t) __t)->ip_traffic_local /
181 ((ptraffic_config_t) __t)->ip_traffic_local =
182 ((ptraffic_config_t) __t)->ip_traffic_local %
185 if (((ptraffic_config_t) __t)->ip_traffic_MAX <= 0)
187 //the verdict is according the autoBlock value
188 if (((ptraffic_config_t) __t)->autoBlock == 1)
192 ct = ip_conntrack_get (*pskb, &ctinfo);
194 && (ctinfo == IP_CT_NEW
195 || ctinfo == IP_CT_RELATED))
216 //do other accounting and block action
217 if (found == 0 && other != NULL)
219 ((ptraffic_config_t) other)->ip_traffic_local +=
220 (*pskb)->nh.iph->tot_len;
221 if (((ptraffic_config_t) other)->ip_traffic_local >= MEGA_BYTE)
223 ((ptraffic_config_t) other)->ip_traffic_MAX -=
224 ((ptraffic_config_t) other)->ip_traffic_local / MEGA_BYTE;
225 ((ptraffic_config_t) other)->ip_traffic_local =
226 ((ptraffic_config_t) other)->ip_traffic_local % MEGA_BYTE;
229 if (((ptraffic_config_t) other)->ip_traffic_MAX <= 0)
231 //the verdict is according the autoBlock value
232 if (((ptraffic_config_t) other)->autoBlock == 1)
236 ct = ip_conntrack_get (*pskb, &ctinfo);
237 if (ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED))
258 * just count the packet received from wan
262 ip_general_traffic_control (unsigned int hooknum, struct sk_buff **pskb,
263 const struct net_device *in,
264 const struct net_device *out,
265 int (*okfn) (struct sk_buff *))
267 if (in->name != NULL && strcmp (in->name, "br0") != 0)
269 traffic_tmp += (*pskb)->nh.iph->tot_len;
270 if (traffic_tmp >= MEGA_BYTE)
272 traffic_bytes += traffic_tmp / MEGA_BYTE;
273 traffic_tmp = traffic_tmp % MEGA_BYTE;
281 * When the data is prepared to leave the ip stack, traffic control is done.
282 * So we made a hook call-back function at POST_ROUTING
284 static struct nf_hook_ops ip_traffic_control_ops = {
285 .hook = ip_traffic_control,
286 .owner = THIS_MODULE,
288 .hooknum = NF_IP_POST_ROUTING,
289 .priority = NF_IP_PRI_CONNTRACK,
292 static struct nf_hook_ops ip_general_traffic_control_ops = {
293 .hook = ip_general_traffic_control,
294 .owner = THIS_MODULE,
296 .hooknum = NF_IP_PRE_ROUTING,
297 .priority = NF_IP_PRI_CONNTRACK,
300 static int init_or_cleanup (int init)
302 struct proc_dir_entry *proc;
308 /* ret = ip_traffic_init();
310 goto cleanup_nothing;
312 proc = proc_net_create ("ip_traffic", 0440, list_traffics);
315 proc->owner = THIS_MODULE;
317 ret = nf_register_hook (&ip_traffic_control_ops);
320 printk ("ip_traffic: can't register hook.\n");
323 ret = nf_register_hook (&ip_general_traffic_control_ops);
326 printk ("ip_traffic: can't register hook.\n");
333 nf_unregister_hook (&ip_general_traffic_control_ops);
335 nf_unregister_hook (&ip_traffic_control_ops);
337 proc_net_remove ("ip_traffic");
340 ip_traffic_cleanup();
346 static int __init init (void)
348 return init_or_cleanup (1);
351 static void __exit fini (void)