import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / net / ipv4 / netfilter / arptable_filter.c
1 /*
2  * Filtering ARP tables module.
3  *
4  * Copyright (C) 2002 David S. Miller (davem@redhat.com)
5  *
6  */
7
8 #include <linux/module.h>
9 #include <linux/netfilter_arp/arp_tables.h>
10
11 #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT))
12
13 /* Standard entry. */
14 struct arpt_standard
15 {
16         struct arpt_entry entry;
17         struct arpt_standard_target target;
18 };
19
20 struct arpt_error_target
21 {
22         struct arpt_entry_target target;
23         char errorname[ARPT_FUNCTION_MAXNAMELEN];
24 };
25
26 struct arpt_error
27 {
28         struct arpt_entry entry;
29         struct arpt_error_target target;
30 };
31
32 static struct
33 {
34         struct arpt_replace repl;
35         struct arpt_standard entries[2];
36         struct arpt_error term;
37 } initial_table __initdata
38 = { { "filter", FILTER_VALID_HOOKS, 3,
39       sizeof(struct arpt_standard) * 2 + sizeof(struct arpt_error),
40       { [NF_ARP_IN] 0,
41         [NF_ARP_OUT] sizeof(struct arpt_standard) },
42       { [NF_ARP_IN] 0,
43         [NF_ARP_OUT] sizeof(struct arpt_standard), },
44       0, NULL, { } },
45     {
46             /* ARP_IN */
47             {
48                     {
49                             {
50                                     { 0 }, { 0 }, { 0 }, { 0 },
51                                     0, 0,
52                                     { { 0, }, { 0, } },
53                                     { { 0, }, { 0, } },
54                                     0, 0,
55                                     0, 0,
56                                     0, 0,
57                                     "", "", { 0 }, { 0 },
58                                     0, 0
59                             },
60                             sizeof(struct arpt_entry),
61                             sizeof(struct arpt_standard),
62                             0,
63                             { 0, 0 }, { } },
64                     { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
65                       -NF_ACCEPT - 1 }
66             },
67             /* ARP_OUT */
68             {
69                     {
70                             {
71                                     { 0 }, { 0 }, { 0 }, { 0 },
72                                     0, 0,
73                                     { { 0, }, { 0, } },
74                                     { { 0, }, { 0, } },
75                                     0, 0,
76                                     0, 0,
77                                     0, 0,
78                                     "", "", { 0 }, { 0 },
79                                     0, 0
80                             },
81                             sizeof(struct arpt_entry),
82                             sizeof(struct arpt_standard),
83                             0,
84                             { 0, 0 }, { } },
85                     { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
86                       -NF_ACCEPT - 1 }
87             }
88     },
89     /* ERROR */
90     {
91             {
92                     {
93                             { 0 }, { 0 }, { 0 }, { 0 },
94                             0, 0,
95                             { { 0, }, { 0, } },
96                             { { 0, }, { 0, } },
97                             0, 0,
98                             0, 0,
99                             0, 0,
100                             "", "", { 0 }, { 0 },
101                             0, 0
102                     },
103                     sizeof(struct arpt_entry),
104                     sizeof(struct arpt_error),
105                     0,
106                     { 0, 0 }, { } },
107             { { { { ARPT_ALIGN(sizeof(struct arpt_error_target)), ARPT_ERROR_TARGET } },
108                 { } },
109               "ERROR"
110             }
111     }
112 };
113
114 static struct arpt_table packet_filter
115 = { { NULL, NULL }, "filter", &initial_table.repl,
116     FILTER_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL, THIS_MODULE };
117
118 /* The work comes in here from netfilter.c */
119 static unsigned int arpt_hook(unsigned int hook,
120                               struct sk_buff **pskb,
121                               const struct net_device *in,
122                               const struct net_device *out,
123                               int (*okfn)(struct sk_buff *))
124 {
125         return arpt_do_table(pskb, hook, in, out, &packet_filter, NULL);
126 }
127
128 static struct nf_hook_ops arpt_ops[]
129 = { { { NULL, NULL }, arpt_hook, NF_ARP, NF_ARP_IN, 0 },
130     { { NULL, NULL }, arpt_hook, NF_ARP, NF_ARP_OUT, 0 }
131 };
132
133 static int __init init(void)
134 {
135         int ret;
136
137         /* Register table */
138         ret = arpt_register_table(&packet_filter);
139         if (ret < 0)
140                 return ret;
141
142         /* Register hooks */
143         ret = nf_register_hook(&arpt_ops[0]);
144         if (ret < 0)
145                 goto cleanup_table;
146
147         ret = nf_register_hook(&arpt_ops[1]);
148         if (ret < 0)
149                 goto cleanup_hook0;
150
151         return ret;
152
153 cleanup_hook0:
154         nf_unregister_hook(&arpt_ops[0]);
155
156 cleanup_table:
157         arpt_unregister_table(&packet_filter);
158
159         return ret;
160 }
161
162 static void __exit fini(void)
163 {
164         unsigned int i;
165
166         for (i = 0; i < sizeof(arpt_ops)/sizeof(struct nf_hook_ops); i++)
167                 nf_unregister_hook(&arpt_ops[i]);
168
169         arpt_unregister_table(&packet_filter);
170 }
171
172 module_init(init);
173 module_exit(fini);
174 MODULE_LICENSE("GPL");