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 */
arpt_hook(unsigned int hook,struct sk_buff ** pskb,const struct net_device * in,const struct net_device * out,int (* okfn)(struct sk_buff *))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 
init(void)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 
fini(void)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");
175