xref: /netbsd-src/sys/net/npf/npf.h (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: npf.h,v 1.10 2011/11/06 02:49:03 rmind Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This material is based upon work partially supported by The
8  * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Public NPF interfaces.
34  */
35 
36 #ifndef _NPF_NET_H_
37 #define _NPF_NET_H_
38 
39 #include <sys/param.h>
40 #include <sys/types.h>
41 
42 #include <sys/ioctl.h>
43 #include <prop/proplib.h>
44 
45 #include <netinet/in_systm.h>
46 #include <netinet/in.h>
47 
48 #ifdef _NPF_TESTING
49 #include "testing.h"
50 #endif
51 
52 #define	NPF_VERSION		3
53 
54 /*
55  * Public declarations and definitions.
56  */
57 
58 /* Storage of address (both for IPv4 and IPv6) and netmask */
59 typedef struct in6_addr		npf_addr_t;
60 typedef uint8_t			npf_netmask_t;
61 
62 #define	NPF_NO_NETMASK		((npf_netmask_t)~0)
63 
64 #if defined(_KERNEL) || defined(_NPF_TESTING)
65 
66 /* Network buffer. */
67 typedef void			nbuf_t;
68 
69 struct npf_rproc;
70 struct npf_hook;
71 
72 typedef struct npf_rproc	npf_rproc_t;
73 typedef struct npf_hook		npf_hook_t;
74 
75 /*
76  * Packet information cache.
77  */
78 #include <netinet/ip.h>
79 #include <netinet/ip6.h>
80 #include <netinet/tcp.h>
81 #include <netinet/udp.h>
82 #include <netinet/ip_icmp.h>
83 
84 #define	NPC_IP4		0x01	/* Indicates fetched IPv4 header. */
85 #define	NPC_IP6		0x02	/* Indicates IPv6 header. */
86 #define	NPC_IPFRAG	0x04	/* IPv4/IPv6 fragment. */
87 #define	NPC_LAYER4	0x08	/* Layer 4 has been fetched. */
88 
89 #define	NPC_TCP		0x10	/* TCP header. */
90 #define	NPC_UDP		0x20	/* UDP header. */
91 #define	NPC_ICMP	0x40	/* ICMP header. */
92 #define	NPC_ICMP_ID	0x80	/* ICMP with query ID. */
93 
94 #define	NPC_IP46	(NPC_IP4|NPC_IP6)
95 
96 typedef struct {
97 	/* Information flags. */
98 	uint32_t		npc_info;
99 	/* Pointers to the IP v4/v6 addresses. */
100 	npf_addr_t *		npc_srcip;
101 	npf_addr_t *		npc_dstip;
102 	/* Size (v4 or v6) of IP addresses. */
103 	int			npc_ipsz;
104 	size_t			npc_hlen;
105 	int			npc_next_proto;
106 	/* IPv4, IPv6. */
107 	union {
108 		struct ip	v4;
109 		struct ip6_hdr	v6;
110 	} npc_ip;
111 	/* TCP, UDP, ICMP. */
112 	union {
113 		struct tcphdr	tcp;
114 		struct udphdr	udp;
115 		struct icmp	icmp;
116 	} npc_l4;
117 } npf_cache_t;
118 
119 static inline void
120 npf_generate_mask(npf_addr_t *dst, const npf_netmask_t omask)
121 {
122 	uint_fast8_t length = omask;
123 
124 	/* Note: maximum length is 32 for IPv4 and 128 for IPv6. */
125 	KASSERT(length <= 128);
126 
127 	for (int i = 0; i < 4; i++) {
128 		if (length >= 32) {
129 			dst->s6_addr32[i] = htonl(0xffffffff);
130 			length -= 32;
131 		} else {
132 			dst->s6_addr32[i] = htonl(0xffffffff << (32 - length));
133 			length = 0;
134 		}
135 	}
136 }
137 
138 static inline void
139 npf_calculate_masked_addr(npf_addr_t *dst, const npf_addr_t *src,
140     const npf_netmask_t omask)
141 {
142 	npf_addr_t mask;
143 
144 	npf_generate_mask(&mask, omask);
145 	for (int i = 0; i < 4; i++) {
146 		dst->s6_addr32[i] = src->s6_addr32[i] & mask.s6_addr32[i];
147 	}
148 }
149 
150 /*
151  * npf_compare_cidr: compare two addresses, either IPv4 or IPv6.
152  *
153  * => If the mask is NULL, ignore it.
154  */
155 static inline int
156 npf_compare_cidr(const npf_addr_t *addr1, const npf_netmask_t mask1,
157     const npf_addr_t *addr2, const npf_netmask_t mask2)
158 {
159 	npf_addr_t realmask1, realmask2;
160 
161 	if (mask1 != NPF_NO_NETMASK) {
162 		npf_generate_mask(&realmask1, mask1);
163 	}
164 	if (mask2 != NPF_NO_NETMASK) {
165 		npf_generate_mask(&realmask2, mask2);
166 	}
167 	for (int i = 0; i < 4; i++) {
168 		const uint32_t x = mask1 != NPF_NO_NETMASK ?
169 		    addr1->s6_addr32[i] & realmask1.s6_addr32[i] :
170 		    addr1->s6_addr32[i];
171 		const uint32_t y = mask2 != NPF_NO_NETMASK ?
172 		    addr2->s6_addr32[i] & realmask2.s6_addr32[i] :
173 		    addr2->s6_addr32[i];
174 		if (x < y) {
175 			return -1;
176 		}
177 		if (x > y) {
178 			return 1;
179 		}
180 	}
181 
182 	return 0;
183 }
184 
185 static inline bool
186 npf_iscached(const npf_cache_t *npc, const int inf)
187 {
188 
189 	return __predict_true((npc->npc_info & inf) != 0);
190 }
191 
192 static inline int
193 npf_cache_ipproto(const npf_cache_t *npc)
194 {
195 	KASSERT(npf_iscached(npc, NPC_IP46));
196 	return npc->npc_next_proto;
197 }
198 
199 static inline int
200 npf_cache_hlen(const npf_cache_t *npc, nbuf_t *nbuf)
201 {
202 	KASSERT(npf_iscached(npc, NPC_IP46));
203 	return npc->npc_hlen;
204 }
205 
206 /* Network buffer interface. */
207 void *		nbuf_dataptr(void *);
208 void *		nbuf_advance(nbuf_t **, void *, u_int);
209 int		nbuf_advfetch(nbuf_t **, void **, u_int, size_t, void *);
210 int		nbuf_advstore(nbuf_t **, void **, u_int, size_t, void *);
211 int		nbuf_fetch_datum(nbuf_t *, void *, size_t, void *);
212 int		nbuf_store_datum(nbuf_t *, void *, size_t, void *);
213 
214 int		nbuf_add_tag(nbuf_t *, uint32_t, uint32_t);
215 int		nbuf_find_tag(nbuf_t *, uint32_t, void **);
216 
217 #if 0
218 npf_hook_t *	npf_hook_register(npf_rule_t *,
219 		    void (*)(npf_cache_t *, nbuf_t *, void *), void *);
220 void		npf_hook_unregister(npf_rule_t *, npf_hook_t *);
221 #endif
222 
223 #endif	/* _KERNEL */
224 
225 /* Rule attributes. */
226 #define	NPF_RULE_PASS			0x0001
227 #define	NPF_RULE_DEFAULT		0x0002
228 #define	NPF_RULE_FINAL			0x0004
229 #define	NPF_RULE_KEEPSTATE		0x0008
230 #define	NPF_RULE_RETRST			0x0010
231 #define	NPF_RULE_RETICMP		0x0020
232 
233 #define	NPF_RULE_IN			0x10000000
234 #define	NPF_RULE_OUT			0x20000000
235 #define	NPF_RULE_DIMASK			(NPF_RULE_IN | NPF_RULE_OUT)
236 
237 /* Rule procedure flags. */
238 #define	NPF_RPROC_LOG			0x0001
239 #define	NPF_RPROC_NORMALIZE		0x0002
240 
241 /* Address translation types and flags. */
242 #define	NPF_NATIN			1
243 #define	NPF_NATOUT			2
244 
245 #define	NPF_NAT_PORTS			0x01
246 #define	NPF_NAT_PORTMAP			0x02
247 
248 /* Table types. */
249 #define	NPF_TABLE_HASH			1
250 #define	NPF_TABLE_RBTREE		2
251 
252 /* Layers. */
253 #define	NPF_LAYER_2			2
254 #define	NPF_LAYER_3			3
255 
256 /* XXX mbuf.h: just for now. */
257 #define	PACKET_TAG_NPF			10
258 
259 /*
260  * IOCTL structures.
261  */
262 
263 #define	NPF_IOCTL_TBLENT_ADD		1
264 #define	NPF_IOCTL_TBLENT_REM		2
265 
266 typedef struct npf_ioctl_table {
267 	int			nct_action;
268 	u_int			nct_tid;
269 	npf_addr_t		nct_addr;
270 	npf_netmask_t		nct_mask;
271 } npf_ioctl_table_t;
272 
273 typedef enum {
274 	/* Packets passed. */
275 	NPF_STAT_PASS_DEFAULT,
276 	NPF_STAT_PASS_RULESET,
277 	NPF_STAT_PASS_SESSION,
278 	/* Packets blocked. */
279 	NPF_STAT_BLOCK_DEFAULT,
280 	NPF_STAT_BLOCK_RULESET,
281 	/* Session and NAT entries. */
282 	NPF_STAT_SESSION_CREATE,
283 	NPF_STAT_SESSION_DESTROY,
284 	NPF_STAT_NAT_CREATE,
285 	NPF_STAT_NAT_DESTROY,
286 	/* Invalid state cases. */
287 	NPF_STAT_INVALID_STATE,
288 	NPF_STAT_INVALID_STATE_TCP1,
289 	NPF_STAT_INVALID_STATE_TCP2,
290 	NPF_STAT_INVALID_STATE_TCP3,
291 	/* Raced packets. */
292 	NPF_STAT_RACE_SESSION,
293 	NPF_STAT_RACE_NAT,
294 	/* Rule procedure cases. */
295 	NPF_STAT_RPROC_LOG,
296 	NPF_STAT_RPROC_NORM,
297 	/* Other errors. */
298 	NPF_STAT_ERROR,
299 	/* Count (last). */
300 	NPF_STATS_COUNT
301 } npf_stats_t;
302 
303 #define	NPF_STATS_SIZE		(sizeof(uint64_t) * NPF_STATS_COUNT)
304 
305 /*
306  * IOCTL operations.
307  */
308 
309 #define	IOC_NPF_VERSION		_IOR('N', 100, int)
310 #define	IOC_NPF_SWITCH		_IOW('N', 101, int)
311 #define	IOC_NPF_RELOAD		_IOW('N', 102, struct plistref)
312 #define	IOC_NPF_TABLE		_IOW('N', 103, struct npf_ioctl_table)
313 #define	IOC_NPF_STATS		_IOW('N', 104, void *)
314 #define	IOC_NPF_SESSIONS_SAVE	_IOR('N', 105, struct plistref)
315 #define	IOC_NPF_SESSIONS_LOAD	_IOW('N', 106, struct plistref)
316 #define	IOC_NPF_UPDATE_RULE	_IOW('N', 107, struct plistref)
317 
318 #endif	/* _NPF_NET_H_ */
319