xref: /openbsd/sys/net/pfvar.h (revision 610f49f8)
1 /*	$OpenBSD: pfvar.h,v 1.63 2002/02/14 23:53:32 dhartmei Exp $ */
2 
3 /*
4  * Copyright (c) 2001 Daniel Hartmeier
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  *    - Redistributions of source code must retain the above copyright
12  *      notice, this list of conditions and the following disclaimer.
13  *    - Redistributions in binary form must reproduce the above
14  *      copyright notice, this list of conditions and the following
15  *      disclaimer in the documentation and/or other materials provided
16  *      with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 #ifndef _NET_PFVAR_H_
34 #define _NET_PFVAR_H_
35 
36 #include <sys/types.h>
37 #include <sys/queue.h>
38 
39 enum	{ PF_IN=0, PF_OUT=1 };
40 enum	{ PF_PASS=0, PF_DROP=1, PF_SCRUB=2 };
41 enum	{ PF_OP_IRG=1, PF_OP_EQ=2, PF_OP_NE=3, PF_OP_LT=4,
42 	  PF_OP_LE=5, PF_OP_GT=6, PF_OP_GE=7, PF_OP_XRG=8 };
43 enum	{ PF_DEBUG_NONE=0, PF_DEBUG_URGENT=1, PF_DEBUG_MISC=2 };
44 enum	{ PF_CHANGE_ADD_HEAD=1, PF_CHANGE_ADD_TAIL=2,
45 	  PF_CHANGE_ADD_BEFORE=3, PF_CHANGE_ADD_AFTER=4,
46 	  PF_CHANGE_REMOVE=5 };
47 enum	{ PFTM_TCP_FIRST_PACKET=0, PFTM_TCP_OPENING=1, PFTM_TCP_ESTABLISHED=2,
48 	  PFTM_TCP_CLOSING=3, PFTM_TCP_FIN_WAIT=4, PFTM_TCP_CLOSED=5,
49 	  PFTM_UDP_FIRST_PACKET=6, PFTM_UDP_SINGLE=7, PFTM_UDP_MULTIPLE=8,
50 	  PFTM_ICMP_FIRST_PACKET=9, PFTM_ICMP_ERROR_REPLY=10,
51 	  PFTM_OTHER_FIRST_PACKET=11, PFTM_OTHER_SINGLE=12,
52 	  PFTM_OTHER_MULTIPLE=13, PFTM_FRAG=14, PFTM_INTERVAL=15, PFTM_MAX=16 };
53 enum	{ PF_FASTROUTE=1, PF_ROUTETO=2, PF_DUPTO=3 };
54 
55 struct pf_addr {
56 	union {
57 		struct in_addr 		v4;
58 		struct in6_addr 	v6;
59 		u_int8_t		addr8[16];
60 		u_int16_t		addr16[8];
61 		u_int32_t		addr32[4];
62 	} pfa;		    /* 128-bit address */
63 #define v4	pfa.v4
64 #define v6	pfa.v6
65 #define addr8	pfa.addr8
66 #define addr16	pfa.addr16
67 #define addr32	pfa.addr32
68 };
69 
70 /*
71  * Address manipulation macros
72  */
73 
74 #ifdef _KERNEL
75 
76 #ifdef INET
77 #ifndef INET6
78 #define PF_INET_ONLY
79 #endif /* ! INET6 */
80 #endif /* INET */
81 
82 #ifdef INET6
83 #ifndef INET
84 #define PF_INET6_ONLY
85 #endif /* ! INET */
86 #endif /* INET6 */
87 
88 #ifdef INET
89 #ifdef INET6
90 #define PF_INET_INET6
91 #endif /* INET6 */
92 #endif /* INET */
93 
94 #else
95 
96 #define PF_INET_INET6
97 
98 #endif /* _KERNEL */
99 
100 /* Both IPv4 and IPv6 */
101 #ifdef PF_INET_INET6
102 
103 #define PF_AEQ(a, b, c) \
104 	((c == AF_INET && (a)->addr32[0] == (b)->addr32[0]) || \
105 	(c == AF_INET6 && (a)->addr32[0] == (b)->addr32[0] && \
106 	(a)->addr32[1] == (b)->addr32[1] && \
107 	(a)->addr32[2] == (b)->addr32[2] && \
108 	(a)->addr32[3] == (b)->addr32[3])) \
109 
110 #define PF_ANEQ(a, b, c) \
111 	((c == AF_INET && (a)->addr32[0] != (b)->addr32[0]) || \
112 	(c == AF_INET6 && ((a)->addr32[0] != (b)->addr32[0] || \
113 	(a)->addr32[1] != (b)->addr32[1] || \
114 	(a)->addr32[2] != (b)->addr32[2] || \
115 	(a)->addr32[3] != (b)->addr32[3]))) \
116 
117 #define PF_AZERO(a, c) \
118 	((c == AF_INET && !(a)->addr32[0]) || \
119 	(c == AF_INET6 && !(a)->addr32[0] && \
120 	!(a)->addr32[1] && !(a)->addr32[2] && \
121 	!(a)->addr32[3] )) \
122 
123 #define PF_MATCHA(n, a, m, b, f) \
124 	pf_match_addr(n, a, m, b, f)
125 
126 #define PF_ACPY(a, b, f) \
127 	pf_addrcpy(a, b, f)
128 
129 #else
130 
131 /* Just IPv6 */
132 #ifdef PF_INET6_ONLY
133 
134 #define PF_AEQ(a, b, c) \
135 	((a)->addr32[0] == (b)->addr32[0] && \
136 	(a)->addr32[1] == (b)->addr32[1] && \
137 	(a)->addr32[2] == (b)->addr32[2] && \
138 	(a)->addr32[3] == (b)->addr32[3]) \
139 
140 #define PF_ANEQ(a, b, c) \
141 	((a)->addr32[0] != (b)->addr32[0] || \
142 	(a)->addr32[1] != (b)->addr32[1] || \
143 	(a)->addr32[2] != (b)->addr32[2] || \
144 	(a)->addr32[3] != (b)->addr32[3]) \
145 
146 #define PF_AZERO(a, c) \
147 	(!(a)->addr32[0] && \
148 	!(a)->addr32[1] && \
149 	!(a)->addr32[2] && \
150 	!(a)->addr32[3] ) \
151 
152 #define PF_MATCHA(n, a, m, b, f) \
153 	pf_match_addr(n, a, m, b, f)
154 
155 #define PF_ACPY(a, b, f) \
156 	pf_addrcpy(a, b, f)
157 
158 #else
159 
160 /* Just IPv4 */
161 #ifdef PF_INET_ONLY
162 
163 #define PF_AEQ(a, b, c) \
164 	((a)->addr32[0] == (b)->addr32[0])
165 
166 #define PF_ANEQ(a, b, c) \
167 	((a)->addr32[0] != (b)->addr32[0])
168 
169 #define PF_AZERO(a, c) \
170 	(!(a)->addr32[0])
171 
172 #define PF_MATCHA(n, a, m, b, f) \
173 	pf_match_addr(n, a, m, b, f)
174 
175 #define PF_ACPY(a, b, f) \
176 	(a)->v4.s_addr = (b)->v4.s_addr
177 
178 
179 #endif /* PF_INET_ONLY */
180 #endif /* PF_INET6_ONLY */
181 #endif /* PF_INET_INET6 */
182 
183 struct pf_rule_addr {
184 	struct pf_addr	addr;
185 	struct pf_addr	mask;
186 	u_int16_t	port[2];
187 	u_int8_t	not;
188 	u_int8_t	port_op;
189 };
190 
191 struct pf_rule {
192 	char		 ifname[IFNAMSIZ];
193 	char		 rt_ifname[IFNAMSIZ];
194 #define PF_RULE_LABEL_SIZE	32
195 	char		 label[PF_RULE_LABEL_SIZE];
196 	struct ifnet	*ifp;
197 	struct ifnet	*rt_ifp;
198 	struct pf_rule_addr src;
199 	struct pf_rule_addr dst;
200 	struct pf_addr	 rt_addr;
201 
202 #define PF_SKIP_ACTION		0
203 #define PF_SKIP_IFP		1
204 #define PF_SKIP_DIR		2
205 #define PF_SKIP_AF		3
206 #define PF_SKIP_PROTO		4
207 #define PF_SKIP_SRC_ADDR	5
208 #define PF_SKIP_SRC_PORT	6
209 #define PF_SKIP_DST_ADDR	7
210 #define PF_SKIP_DST_PORT	8
211 #define PF_SKIP_COUNT		9
212 	struct pf_rule	*skip[PF_SKIP_COUNT];
213 	TAILQ_ENTRY(pf_rule)	entries;
214 
215 	u_int64_t	 evaluations;
216 	u_int64_t	 packets;
217 	u_int64_t	 bytes;
218 
219 	u_int16_t	 nr;
220 	u_int16_t	 return_icmp;
221 
222 	u_int8_t	 action;
223 	u_int8_t	 direction;
224 	u_int8_t	 log;
225 	u_int8_t	 quick;
226 
227 #define PF_STATE_NORMAL		0x1
228 #define PF_STATE_MODULATE	0x2
229 	u_int8_t	 keep_state;
230 	u_int8_t	 af;
231 	u_int8_t	 proto;
232 	u_int8_t	 type;
233 	u_int8_t	 code;
234 
235 	u_int8_t	 flags;
236 	u_int8_t	 flagset;
237 
238 	u_int8_t	 rule_flag;
239 	u_int8_t	 min_ttl;	/* minimum ttl for packet normalize */
240 	u_int8_t	 allow_opts;
241 	u_int8_t	 rt;
242 };
243 
244 #define	PFRULE_RETURNRST	0x01
245 #define	PFRULE_NODF		0x02
246 
247 struct pf_state_host {
248 	struct pf_addr	addr;
249 	u_int16_t	port;
250 	u_int16_t	pad;
251 };
252 
253 struct pf_state_peer {
254 	u_int32_t	seqlo;		/* Max sequence number sent 	*/
255 	u_int32_t	seqhi;		/* Max the other end ACKd + win	*/
256 	u_int32_t	seqdiff;	/* Sequence number modulator	*/
257 	u_int16_t	max_win;
258 	u_int8_t	state;
259 	u_int8_t	pad;
260 };
261 
262 struct pf_state {
263 	TAILQ_ENTRY(pf_state)	entries;
264 	struct pf_state_host lan;
265 	struct pf_state_host gwy;
266 	struct pf_state_host ext;
267 	struct pf_state_peer src;
268 	struct pf_state_peer dst;
269 	struct pf_rule	*rule;
270 	u_int32_t	 creation;
271 	u_int32_t	 expire;
272 	u_int32_t	 packets;
273 	u_int32_t	 bytes;
274 	u_int8_t	 af;
275 	u_int8_t	 proto;
276 	u_int8_t	 direction;
277 	u_int8_t	 log;
278 	u_int8_t	 allow_opts;
279 };
280 
281 struct pf_nat {
282 	char		 ifname[IFNAMSIZ];
283 	struct ifnet	*ifp;
284 	TAILQ_ENTRY(pf_nat)	entries;
285 	struct pf_addr	 saddr;
286 	struct pf_addr	 smask;
287 	struct pf_addr	 daddr;
288 	struct pf_addr	 dmask;
289 	struct pf_addr	 raddr;
290 	u_int8_t	 af;
291 	u_int8_t	 proto;
292 	u_int8_t	 snot;
293 	u_int8_t	 dnot;
294 	u_int8_t	 ifnot;
295 	u_int8_t	 no;
296 };
297 
298 struct pf_binat {
299 	char		 ifname[IFNAMSIZ];
300 	struct ifnet	*ifp;
301 	TAILQ_ENTRY(pf_binat)	entries;
302 	struct pf_addr	 saddr;
303 	struct pf_addr	 daddr;
304 	struct pf_addr	 dmask;
305 	struct pf_addr	 raddr;
306 	u_int8_t	 af;
307 	u_int8_t	 proto;
308 	u_int8_t	 dnot;
309 	u_int8_t	 no;
310 };
311 
312 struct pf_rdr {
313 	char		 ifname[IFNAMSIZ];
314 	struct ifnet	*ifp;
315 	TAILQ_ENTRY(pf_rdr)	entries;
316 	struct pf_addr	 saddr;
317 	struct pf_addr	 smask;
318 	struct pf_addr	 daddr;
319 	struct pf_addr	 dmask;
320 	struct pf_addr	 raddr;
321 	u_int16_t	 dport;
322 	u_int16_t	 dport2;
323 	u_int16_t	 rport;
324 	u_int8_t	 af;
325 	u_int8_t	 proto;
326 	u_int8_t	 snot;
327 	u_int8_t	 dnot;
328 	u_int8_t	 ifnot;
329 	u_int8_t	 opts;
330 	u_int8_t	 no;
331 };
332 
333 struct pf_tree_key {
334 	struct pf_addr	 addr[2];
335 	u_int16_t	 port[2];
336 	u_int8_t	 proto;
337 	u_int8_t	 af;
338 };
339 
340 TAILQ_HEAD(pf_rulequeue, pf_rule);
341 
342 struct pf_pdesc {
343 	u_int64_t	 tot_len; 	/* Make Mickey money */
344 	union {
345 		struct tcphdr		*tcp;
346 		struct udphdr		*udp;
347 		struct icmp		*icmp;
348 #ifdef INET6
349 		struct icmp6_hdr	*icmp6;
350 #endif /* INET6 */
351 		void			*any;
352 	} hdr;
353 	struct pf_addr	*src;
354 	struct pf_addr	*dst;
355 	u_int16_t	*ip_sum;
356 	u_int32_t	 p_len; 	/* total length of payload */
357 	u_int16_t	 flags;		/* Let SCRUB trigger behavior in
358 					 * state code. Easier than tags */
359 	u_int8_t	 af;
360 	u_int8_t	 proto;
361 };
362 
363 /* flags for RDR options */
364 #define PF_DPORT_RANGE	0x01		/* Dest port uses range */
365 #define PF_RPORT_RANGE	0x02		/* RDR'ed port uses range */
366 
367 /* Reasons code for passing/dropping a packet */
368 #define PFRES_MATCH	0		/* Explicit match of a rule */
369 #define PFRES_BADOFF	1		/* Bad offset for pull_hdr */
370 #define PFRES_FRAG	2		/* Dropping following fragment */
371 #define PFRES_SHORT	3		/* Dropping short packet */
372 #define PFRES_NORM	4		/* Dropping by normalizer */
373 #define PFRES_MEMORY	5		/* Dropped due to lacking mem */
374 #define PFRES_MAX	6		/* total+1 */
375 
376 #define PFRES_NAMES { \
377 	"match", \
378 	"bad-offset", \
379 	"fragment", \
380 	"short", \
381 	"normalize", \
382 	"memory", \
383 	NULL \
384 }
385 
386 #define FCNT_STATE_SEARCH	0
387 #define FCNT_STATE_INSERT	1
388 #define FCNT_STATE_REMOVALS	2
389 #define FCNT_MAX		3
390 
391 #define FCNT_NAMES { \
392 	"state searches", \
393 	"state inserts", \
394 	"state removals", \
395 	NULL \
396 }
397 
398 #define ACTION_SET(a, x) \
399 	do { \
400 		if ((a) != NULL) \
401 			*(a) = (x); \
402 	} while (0)
403 
404 #define REASON_SET(a, x) \
405 	do { \
406 		if ((a) != NULL) \
407 			*(a) = (x); \
408 		if (x < PFRES_MAX) \
409 			pf_status.counters[x]++; \
410 	} while (0)
411 
412 struct pf_status {
413 	u_int64_t	counters[PFRES_MAX];
414 	u_int64_t	fcounters[FCNT_MAX];
415 	u_int64_t	pcounters[2][2][3];
416 	u_int64_t	bcounters[2][2];
417 	u_int32_t	running;
418 	u_int32_t	states;
419 	u_int32_t	since;
420 	u_int32_t	debug;
421 };
422 
423 /*
424  * ioctl parameter structures
425  */
426 
427 struct pfioc_rule {
428 	u_int32_t	 ticket;
429 	u_int32_t	 nr;
430 	struct pf_rule	 rule;
431 };
432 
433 struct pfioc_changerule {
434 	u_int32_t	 action;
435 	struct pf_rule	 oldrule;
436 	struct pf_rule	 newrule;
437 };
438 
439 struct pfioc_nat {
440 	u_int32_t	 ticket;
441 	u_int32_t	 nr;
442 	struct pf_nat	 nat;
443 };
444 
445 struct pfioc_changenat {
446 	u_int32_t	 action;
447 	struct pf_nat	 oldnat;
448 	struct pf_nat	 newnat;
449 };
450 
451 struct pfioc_natlook {
452 	struct pf_addr	 saddr;
453 	struct pf_addr	 daddr;
454 	struct pf_addr	 rsaddr;
455 	struct pf_addr	 rdaddr;
456 	u_int16_t	 sport;
457 	u_int16_t	 dport;
458 	u_int16_t	 rsport;
459 	u_int16_t	 rdport;
460 	u_int8_t	 af;
461 	u_int8_t	 proto;
462 	u_int8_t	 direction;
463 };
464 
465 struct pfioc_binat {
466 	u_int32_t	 ticket;
467 	u_int32_t	 nr;
468 	struct pf_binat	 binat;
469 };
470 
471 struct pfioc_changebinat {
472 	u_int32_t	action;
473 	struct pf_binat	oldbinat;
474 	struct pf_binat	newbinat;
475 };
476 
477 struct pfioc_rdr {
478 	u_int32_t	 ticket;
479 	u_int32_t	 nr;
480 	struct pf_rdr	 rdr;
481 };
482 
483 struct pfioc_changerdr {
484 	u_int32_t	 action;
485 	struct pf_rdr	 oldrdr;
486 	struct pf_rdr	 newrdr;
487 };
488 
489 struct pfioc_state {
490 	u_int32_t	 nr;
491 	struct pf_state	 state;
492 };
493 
494 struct pfioc_states {
495 	int	ps_len;
496 	union {
497 		caddr_t psu_buf;
498 		struct pf_state *psu_states;
499 	} ps_u;
500 #define ps_buf		ps_u.psu_buf
501 #define ps_states	ps_u.psu_states
502 };
503 
504 struct pfioc_if {
505 	char		 ifname[IFNAMSIZ];
506 };
507 
508 struct pfioc_tm {
509 	int		 timeout;
510 	int		 seconds;
511 };
512 
513 /*
514  * ioctl operations
515  */
516 
517 #define DIOCSTART	_IO  ('D',  1)
518 #define DIOCSTOP	_IO  ('D',  2)
519 #define DIOCBEGINRULES	_IOWR('D',  3, u_int32_t)
520 #define DIOCADDRULE	_IOWR('D',  4, struct pfioc_rule)
521 #define DIOCCOMMITRULES	_IOWR('D',  5, u_int32_t)
522 #define DIOCGETRULES	_IOWR('D',  6, struct pfioc_rule)
523 #define DIOCGETRULE	_IOWR('D',  7, struct pfioc_rule)
524 #define DIOCBEGINNATS	_IOWR('D',  8, u_int32_t)
525 #define DIOCADDNAT	_IOWR('D',  9, struct pfioc_nat)
526 #define DIOCCOMMITNATS	_IOWR('D', 10, u_int32_t)
527 #define DIOCGETNATS	_IOWR('D', 11, struct pfioc_nat)
528 #define DIOCGETNAT	_IOWR('D', 12, struct pfioc_nat)
529 #define DIOCBEGINRDRS	_IOWR('D', 13, u_int32_t)
530 #define DIOCADDRDR	_IOWR('D', 14, struct pfioc_rdr)
531 #define DIOCCOMMITRDRS	_IOWR('D', 15, u_int32_t)
532 #define DIOCGETRDRS	_IOWR('D', 16, struct pfioc_rdr)
533 #define DIOCGETRDR	_IOWR('D', 17, struct pfioc_rdr)
534 #define DIOCCLRSTATES	_IO  ('D', 18)
535 #define DIOCGETSTATE	_IOWR('D', 19, struct pfioc_state)
536 #define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
537 #define DIOCGETSTATUS	_IOWR('D', 21, struct pf_status)
538 #define DIOCCLRSTATUS	_IO  ('D', 22)
539 #define DIOCNATLOOK	_IOWR('D', 23, struct pfioc_natlook)
540 #define DIOCSETDEBUG	_IOWR('D', 24, u_int32_t)
541 #define DIOCGETSTATES	_IOWR('D', 25, struct pfioc_states)
542 #define DIOCCHANGERULE	_IOWR('D', 26, struct pfioc_changerule)
543 #define DIOCCHANGENAT	_IOWR('D', 27, struct pfioc_changenat)
544 #define DIOCCHANGERDR	_IOWR('D', 28, struct pfioc_changerdr)
545 #define DIOCSETTIMEOUT	_IOWR('D', 29, struct pfioc_tm)
546 #define DIOCGETTIMEOUT	_IOWR('D', 30, struct pfioc_tm)
547 #define DIOCBEGINBINATS	_IOWR('D', 31, u_int32_t)
548 #define DIOCADDBINAT	_IOWR('D', 32, struct pfioc_binat)
549 #define DIOCCOMMITBINATS _IOWR('D', 33, u_int32_t)
550 #define DIOCGETBINATS	_IOWR('D', 34, struct pfioc_binat)
551 #define DIOCGETBINAT	_IOWR('D', 35, struct pfioc_binat)
552 #define DIOCCHANGEBINAT	_IOWR('D', 36, struct pfioc_changebinat)
553 #define DIOCADDSTATE	_IOWR('D', 37, struct pfioc_state)
554 #define DIOCCLRRULECTRS	_IO  ('D', 38)
555 
556 #ifdef _KERNEL
557 
558 #ifdef INET
559 int	pf_test(int, struct ifnet *, struct mbuf **);
560 #endif /* INET */
561 
562 #ifdef INET6
563 int	pf_test6(int, struct ifnet *, struct mbuf **);
564 #endif /* INET */
565 
566 struct pf_tree_node;
567 struct pf_state
568 	*pf_find_state(struct pf_tree_node *, struct pf_tree_key *);
569 int	pf_tree_insert(struct pf_tree_node **, struct pf_tree_node *,
570 	    struct pf_tree_key *, struct pf_state *);
571 int	pf_tree_remove(struct pf_tree_node **, struct pf_tree_node *,
572 	    struct pf_tree_key *);
573 
574 int	pflog_packet(struct ifnet *, struct mbuf *, int, u_short, u_short,
575 	    struct pf_rule *);
576 int	pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
577 	    struct pf_addr *, int);
578 int	pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
579 
580 void	pf_normalize_init(void);
581 int	pf_normalize_ip(struct mbuf **, int, struct ifnet *, u_short *);
582 void	pf_purge_expired_fragments(void);
583 
584 extern struct pf_rulequeue *pf_rules_active;
585 extern struct pf_status pf_status;
586 #endif /* _KERNEL */
587 
588 #endif /* _NET_PFVAR_H_ */
589