1/*
2 * 25-Jul-1998 Major changes to allow for ip chain table
3 *
4 * 3-Jan-2000 Named tables to allow packet selection for different uses.
5 */
6
7/*
8 * 	Format of an IP6 firewall descriptor
9 *
10 * 	src, dst, src_mask, dst_mask are always stored in network byte order.
11 * 	flags are stored in host byte order (of course).
12 * 	Port numbers are stored in HOST byte order.
13 */
14
15#ifndef _IP6_TABLES_H
16#define _IP6_TABLES_H
17
18#ifdef __KERNEL__
19#include <linux/if.h>
20#include <linux/types.h>
21#include <linux/in6.h>
22#include <linux/ipv6.h>
23#include <linux/skbuff.h>
24#endif
25#include <linux/compiler.h>
26#include <linux/netfilter_ipv6.h>
27
28#include <linux/netfilter/x_tables.h>
29
30#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
31#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
32
33#define ip6t_match xt_match
34#define ip6t_target xt_target
35#define ip6t_table xt_table
36#define ip6t_get_revision xt_get_revision
37
38/* Yes, Virginia, you have to zero the padding. */
39struct ip6t_ip6 {
40	/* Source and destination IP6 addr */
41	struct in6_addr src, dst;
42	/* Mask for src and dest IP6 addr */
43	struct in6_addr smsk, dmsk;
44	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
45	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
46
47	/* ARGH, HopByHop uses 0, so can't do 0 = ANY,
48	   instead IP6T_F_NOPROTO must be set */
49	u_int16_t proto;
50	/* TOS to match iff flags & IP6T_F_TOS */
51	u_int8_t tos;
52
53	/* Flags word */
54	u_int8_t flags;
55	/* Inverse flags */
56	u_int8_t invflags;
57};
58
59#define ip6t_entry_match xt_entry_match
60#define ip6t_entry_target xt_entry_target
61#define ip6t_standard_target xt_standard_target
62
63#define ip6t_counters	xt_counters
64
65/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
66#define IP6T_F_PROTO		0x01	/* Set if rule cares about upper
67					   protocols */
68#define IP6T_F_TOS		0x02	/* Match the TOS. */
69#define IP6T_F_GOTO		0x04	/* Set if jump is a goto */
70#define IP6T_F_MASK		0x07	/* All possible flag bits mask. */
71
72/* Values for "inv" field in struct ip6t_ip6. */
73#define IP6T_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
74#define IP6T_INV_VIA_OUT		0x02	/* Invert the sense of OUT IFACE */
75#define IP6T_INV_TOS		0x04	/* Invert the sense of TOS. */
76#define IP6T_INV_SRCIP		0x08	/* Invert the sense of SRC IP. */
77#define IP6T_INV_DSTIP		0x10	/* Invert the sense of DST OP. */
78#define IP6T_INV_FRAG		0x20	/* Invert the sense of FRAG. */
79#define IP6T_INV_PROTO		XT_INV_PROTO
80#define IP6T_INV_MASK		0x7F	/* All possible flag bits mask. */
81
82/* This structure defines each of the firewall rules.  Consists of 3
83   parts which are 1) general IP header stuff 2) match specific
84   stuff 3) the target to perform if the rule matches */
85struct ip6t_entry
86{
87	struct ip6t_ip6 ipv6;
88
89	/* Mark with fields that we care about. */
90	unsigned int nfcache;
91
92	/* Size of ipt_entry + matches */
93	u_int16_t target_offset;
94	/* Size of ipt_entry + matches + target */
95	u_int16_t next_offset;
96
97	/* Back pointer */
98	unsigned int comefrom;
99
100	/* Packet and byte counters. */
101	struct xt_counters counters;
102
103	/* The matches (if any), then the target. */
104	unsigned char elems[0];
105};
106
107/*
108 * New IP firewall options for [gs]etsockopt at the RAW IP level.
109 * Unlike BSD Linux inherits IP options so you don't have to use
110 * a raw socket for this. Instead we check rights in the calls. */
111#define IP6T_BASE_CTL			XT_BASE_CTL
112
113#define IP6T_SO_SET_REPLACE		XT_SO_SET_REPLACE
114#define IP6T_SO_SET_ADD_COUNTERS	XT_SO_SET_ADD_COUNTERS
115#define IP6T_SO_SET_MAX			XT_SO_SET_MAX
116
117#define IP6T_SO_GET_INFO		XT_SO_GET_INFO
118#define IP6T_SO_GET_ENTRIES		XT_SO_GET_ENTRIES
119#define	IP6T_SO_GET_REVISION_MATCH	XT_SO_GET_REVISION_MATCH
120#define	IP6T_SO_GET_REVISION_TARGET	XT_SO_GET_REVISION_TARGET
121#define IP6T_SO_GET_MAX			XT_SO_GET_REVISION_TARGET
122
123/* CONTINUE verdict for targets */
124#define IP6T_CONTINUE XT_CONTINUE
125
126/* For standard target */
127#define IP6T_RETURN XT_RETURN
128
129/* TCP/UDP matching stuff */
130#include <linux/netfilter/xt_tcpudp.h>
131
132#define ip6t_tcp xt_tcp
133#define ip6t_udp xt_udp
134
135/* Values for "inv" field in struct ipt_tcp. */
136#define IP6T_TCP_INV_SRCPT	XT_TCP_INV_SRCPT
137#define IP6T_TCP_INV_DSTPT	XT_TCP_INV_DSTPT
138#define IP6T_TCP_INV_FLAGS	XT_TCP_INV_FLAGS
139#define IP6T_TCP_INV_OPTION	XT_TCP_INV_OPTION
140#define IP6T_TCP_INV_MASK	XT_TCP_INV_MASK
141
142/* Values for "invflags" field in struct ipt_udp. */
143#define IP6T_UDP_INV_SRCPT	XT_UDP_INV_SRCPT
144#define IP6T_UDP_INV_DSTPT	XT_UDP_INV_DSTPT
145#define IP6T_UDP_INV_MASK	XT_UDP_INV_MASK
146
147/* ICMP matching stuff */
148struct ip6t_icmp
149{
150	u_int8_t type;				/* type to match */
151	u_int8_t code[2];			/* range of code */
152	u_int8_t invflags;			/* Inverse flags */
153};
154
155/* Values for "inv" field for struct ipt_icmp. */
156#define IP6T_ICMP_INV	0x01	/* Invert the sense of type/code test */
157
158/* The argument to IP6T_SO_GET_INFO */
159struct ip6t_getinfo
160{
161	/* Which table: caller fills this in. */
162	char name[IP6T_TABLE_MAXNAMELEN];
163
164	/* Kernel fills these in. */
165	/* Which hook entry points are valid: bitmask */
166	unsigned int valid_hooks;
167
168	/* Hook entry points: one per netfilter hook. */
169	unsigned int hook_entry[NF_IP6_NUMHOOKS];
170
171	/* Underflow points. */
172	unsigned int underflow[NF_IP6_NUMHOOKS];
173
174	/* Number of entries */
175	unsigned int num_entries;
176
177	/* Size of entries. */
178	unsigned int size;
179};
180
181/* The argument to IP6T_SO_SET_REPLACE. */
182struct ip6t_replace
183{
184	/* Which table. */
185	char name[IP6T_TABLE_MAXNAMELEN];
186
187	/* Which hook entry points are valid: bitmask.  You can't
188           change this. */
189	unsigned int valid_hooks;
190
191	/* Number of entries */
192	unsigned int num_entries;
193
194	/* Total size of new entries */
195	unsigned int size;
196
197	/* Hook entry points. */
198	unsigned int hook_entry[NF_IP6_NUMHOOKS];
199
200	/* Underflow points. */
201	unsigned int underflow[NF_IP6_NUMHOOKS];
202
203	/* Information about old entries: */
204	/* Number of counters (must be equal to current number of entries). */
205	unsigned int num_counters;
206	/* The old entries' counters. */
207	struct xt_counters __user *counters;
208
209	/* The entries (hang off end: not really an array). */
210	struct ip6t_entry entries[0];
211};
212
213/* The argument to IP6T_SO_ADD_COUNTERS. */
214#define ip6t_counters_info xt_counters_info
215
216/* The argument to IP6T_SO_GET_ENTRIES. */
217struct ip6t_get_entries
218{
219	/* Which table: user fills this in. */
220	char name[IP6T_TABLE_MAXNAMELEN];
221
222	/* User fills this in: total entry size. */
223	unsigned int size;
224
225	/* The entries. */
226	struct ip6t_entry entrytable[0];
227};
228
229/* Standard return verdict, or do jump. */
230#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
231/* Error verdict. */
232#define IP6T_ERROR_TARGET XT_ERROR_TARGET
233
234/* Helper functions */
235static __inline__ struct ip6t_entry_target *
236ip6t_get_target(struct ip6t_entry *e)
237{
238	return (void *)e + e->target_offset;
239}
240
241/* fn returns 0 to continue iteration */
242#define IP6T_MATCH_ITERATE(e, fn, args...)	\
243({						\
244	unsigned int __i;			\
245	int __ret = 0;				\
246	struct ip6t_entry_match *__m;		\
247						\
248	for (__i = sizeof(struct ip6t_entry);	\
249	     __i < (e)->target_offset;		\
250	     __i += __m->u.match_size) {	\
251		__m = (void *)(e) + __i;	\
252						\
253		__ret = fn(__m , ## args);	\
254		if (__ret != 0)			\
255			break;			\
256	}					\
257	__ret;					\
258})
259
260/* fn returns 0 to continue iteration */
261#define IP6T_ENTRY_ITERATE(entries, size, fn, args...)		\
262({								\
263	unsigned int __i;					\
264	int __ret = 0;						\
265	struct ip6t_entry *__e;					\
266								\
267	for (__i = 0; __i < (size); __i += __e->next_offset) {	\
268		__e = (void *)(entries) + __i;			\
269								\
270		__ret = fn(__e , ## args);			\
271		if (__ret != 0)					\
272			break;					\
273	}							\
274	__ret;							\
275})
276
277/*
278 *	Main firewall chains definitions and global var's definitions.
279 */
280
281#ifdef __KERNEL__
282
283#include <linux/init.h>
284extern void ip6t_init(void) __init;
285
286#define ip6t_register_target(tgt) 		\
287({	(tgt)->family = AF_INET6;		\
288 	xt_register_target(tgt); })
289#define ip6t_unregister_target(tgt) xt_unregister_target(tgt)
290
291#define ip6t_register_match(match)		\
292({	(match)->family = AF_INET6;		\
293	xt_register_match(match); })
294#define ip6t_unregister_match(match) xt_unregister_match(match)
295
296extern int ip6t_register_table(struct ip6t_table *table,
297			       const struct ip6t_replace *repl);
298extern void ip6t_unregister_table(struct ip6t_table *table);
299extern unsigned int ip6t_do_table(struct sk_buff **pskb,
300				  unsigned int hook,
301				  const struct net_device *in,
302				  const struct net_device *out,
303				  struct ip6t_table *table,
304				  void *userdata);
305
306/* Check for an extension */
307extern int ip6t_ext_hdr(u8 nexthdr);
308/* find specified header and get offset to it */
309extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
310			 int target, unsigned short *fragoff);
311
312extern int ip6_masked_addrcmp(const struct in6_addr *addr1,
313			      const struct in6_addr *mask,
314			      const struct in6_addr *addr2);
315
316#define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))
317
318#endif /*__KERNEL__*/
319#endif /* _IP6_TABLES_H */
320