ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / net / ipv4 / netfilter / iptable_raw.c
1 /* 
2  * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
3  *
4  * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5  */
6 #include <linux/module.h>
7 #include <linux/netfilter_ipv4/ip_tables.h>
8
9 #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
10
11 /* Standard entry. */
12 struct ipt_standard
13 {
14         struct ipt_entry entry;
15         struct ipt_standard_target target;
16 };
17
18 struct ipt_error_target
19 {
20         struct ipt_entry_target target;
21         char errorname[IPT_FUNCTION_MAXNAMELEN];
22 };
23
24 struct ipt_error
25 {
26         struct ipt_entry entry;
27         struct ipt_error_target target;
28 };
29
30 static struct
31 {
32         struct ipt_replace repl;
33         struct ipt_standard entries[2];
34         struct ipt_error term;
35 } initial_table __initdata
36 = { { "raw", RAW_VALID_HOOKS, 3,
37       sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
38       { [NF_IP_PRE_ROUTING] 0,
39         [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
40       { [NF_IP_PRE_ROUTING] 0,
41         [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
42       0, NULL, { } },
43     {
44             /* PRE_ROUTING */
45             { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
46                 0,
47                 sizeof(struct ipt_entry),
48                 sizeof(struct ipt_standard),
49                 0, { 0, 0 }, { } },
50               { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
51                 -NF_ACCEPT - 1 } },
52             /* LOCAL_OUT */
53             { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
54                 0,
55                 sizeof(struct ipt_entry),
56                 sizeof(struct ipt_standard),
57                 0, { 0, 0 }, { } },
58               { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
59                 -NF_ACCEPT - 1 } }
60     },
61     /* ERROR */
62     { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
63         0,
64         sizeof(struct ipt_entry),
65         sizeof(struct ipt_error),
66         0, { 0, 0 }, { } },
67       { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
68           { } },
69         "ERROR"
70       }
71     }
72 };
73
74 static struct ipt_table packet_raw = { 
75         .name = "raw", 
76         .table = &initial_table.repl,
77         .valid_hooks =  RAW_VALID_HOOKS, 
78         .lock = RW_LOCK_UNLOCKED, 
79         .me = THIS_MODULE
80 };
81
82 /* The work comes in here from netfilter.c. */
83 static unsigned int
84 ipt_hook(unsigned int hook,
85          struct sk_buff **pskb,
86          const struct net_device *in,
87          const struct net_device *out,
88          int (*okfn)(struct sk_buff *))
89 {
90         return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
91 }
92
93 /* 'raw' is the very first table. */
94 static struct nf_hook_ops ipt_ops[] = {
95         {
96           .hook = ipt_hook, 
97           .pf = PF_INET, 
98           .hooknum = NF_IP_PRE_ROUTING, 
99           .priority = NF_IP_PRI_RAW
100         },
101         {
102           .hook = ipt_hook, 
103           .pf = PF_INET, 
104           .hooknum = NF_IP_LOCAL_OUT, 
105           .priority = NF_IP_PRI_RAW
106         },
107 };
108
109 static int __init init(void)
110 {
111         int ret;
112
113         /* Register table */
114         ret = ipt_register_table(&packet_raw);
115         if (ret < 0)
116                 return ret;
117
118         /* Register hooks */
119         ret = nf_register_hook(&ipt_ops[0]);
120         if (ret < 0)
121                 goto cleanup_table;
122
123         ret = nf_register_hook(&ipt_ops[1]);
124         if (ret < 0)
125                 goto cleanup_hook0;
126
127         return ret;
128
129  cleanup_hook0:
130         nf_unregister_hook(&ipt_ops[0]);
131  cleanup_table:
132         ipt_unregister_table(&packet_raw);
133
134         return ret;
135 }
136
137 static void __exit fini(void)
138 {
139         unsigned int i;
140
141         for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
142                 nf_unregister_hook(&ipt_ops[i]);
143
144         ipt_unregister_table(&packet_raw);
145 }
146
147 module_init(init);
148 module_exit(fini);
149 MODULE_LICENSE("GPL");