Annotation of sys/net/pf.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pf.c,v 1.552 2007/08/21 15:57:27 dhartmei Exp $ */
2:
3: /*
4: * Copyright (c) 2001 Daniel Hartmeier
5: * Copyright (c) 2002,2003 Henning Brauer
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: *
12: * - Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * - Redistributions in binary form must reproduce the above
15: * copyright notice, this list of conditions and the following
16: * disclaimer in the documentation and/or other materials provided
17: * with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22: * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23: * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30: * POSSIBILITY OF SUCH DAMAGE.
31: *
32: * Effort sponsored in part by the Defense Advanced Research Projects
33: * Agency (DARPA) and Air Force Research Laboratory, Air Force
34: * Materiel Command, USAF, under agreement number F30602-01-2-0537.
35: *
36: */
37:
38: #include "bpfilter.h"
39: #include "pflog.h"
40: #include "pfsync.h"
41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/mbuf.h>
45: #include <sys/filio.h>
46: #include <sys/socket.h>
47: #include <sys/socketvar.h>
48: #include <sys/kernel.h>
49: #include <sys/time.h>
50: #include <sys/pool.h>
51: #include <sys/proc.h>
52: #include <sys/rwlock.h>
53:
54: #include <net/if.h>
55: #include <net/if_types.h>
56: #include <net/bpf.h>
57: #include <net/route.h>
58: #include <net/radix_mpath.h>
59:
60: #include <netinet/in.h>
61: #include <netinet/in_var.h>
62: #include <netinet/in_systm.h>
63: #include <netinet/ip.h>
64: #include <netinet/ip_var.h>
65: #include <netinet/tcp.h>
66: #include <netinet/tcp_seq.h>
67: #include <netinet/udp.h>
68: #include <netinet/ip_icmp.h>
69: #include <netinet/in_pcb.h>
70: #include <netinet/tcp_timer.h>
71: #include <netinet/tcp_var.h>
72: #include <netinet/udp_var.h>
73: #include <netinet/icmp_var.h>
74: #include <netinet/if_ether.h>
75:
76: #include <dev/rndvar.h>
77: #include <net/pfvar.h>
78: #include <net/if_pflog.h>
79:
80: #if NPFSYNC > 0
81: #include <net/if_pfsync.h>
82: #endif /* NPFSYNC > 0 */
83:
84: #ifdef INET6
85: #include <netinet/ip6.h>
86: #include <netinet/in_pcb.h>
87: #include <netinet/icmp6.h>
88: #include <netinet6/nd6.h>
89: #endif /* INET6 */
90:
91:
92: #define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
93:
94: /*
95: * Global variables
96: */
97:
98: /* state tables */
99: struct pf_state_tree_lan_ext pf_statetbl_lan_ext;
100: struct pf_state_tree_ext_gwy pf_statetbl_ext_gwy;
101:
102: struct pf_altqqueue pf_altqs[2];
103: struct pf_palist pf_pabuf;
104: struct pf_altqqueue *pf_altqs_active;
105: struct pf_altqqueue *pf_altqs_inactive;
106: struct pf_status pf_status;
107:
108: u_int32_t ticket_altqs_active;
109: u_int32_t ticket_altqs_inactive;
110: int altqs_inactive_open;
111: u_int32_t ticket_pabuf;
112:
113: struct pf_anchor_stackframe {
114: struct pf_ruleset *rs;
115: struct pf_rule *r;
116: struct pf_anchor_node *parent;
117: struct pf_anchor *child;
118: } pf_anchor_stack[64];
119:
120: struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
121: struct pool pf_state_pl, pf_state_key_pl;
122: struct pool pf_altq_pl;
123:
124: void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
125:
126: void pf_init_threshold(struct pf_threshold *, u_int32_t,
127: u_int32_t);
128: void pf_add_threshold(struct pf_threshold *);
129: int pf_check_threshold(struct pf_threshold *);
130:
131: void pf_change_ap(struct pf_addr *, u_int16_t *,
132: u_int16_t *, u_int16_t *, struct pf_addr *,
133: u_int16_t, u_int8_t, sa_family_t);
134: int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
135: struct tcphdr *, struct pf_state_peer *);
136: #ifdef INET6
137: void pf_change_a6(struct pf_addr *, u_int16_t *,
138: struct pf_addr *, u_int8_t);
139: #endif /* INET6 */
140: void pf_change_icmp(struct pf_addr *, u_int16_t *,
141: struct pf_addr *, struct pf_addr *, u_int16_t,
142: u_int16_t *, u_int16_t *, u_int16_t *,
143: u_int16_t *, u_int8_t, sa_family_t);
144: void pf_send_tcp(const struct pf_rule *, sa_family_t,
145: const struct pf_addr *, const struct pf_addr *,
146: u_int16_t, u_int16_t, u_int32_t, u_int32_t,
147: u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
148: u_int16_t, struct ether_header *, struct ifnet *);
149: void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
150: sa_family_t, struct pf_rule *);
151: struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
152: int, int, struct pfi_kif *,
153: struct pf_addr *, u_int16_t, struct pf_addr *,
154: u_int16_t, int);
155: struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
156: int, int, struct pfi_kif *, struct pf_src_node **,
157: struct pf_addr *, u_int16_t,
158: struct pf_addr *, u_int16_t,
159: struct pf_addr *, u_int16_t *);
160: void pf_attach_state(struct pf_state_key *,
161: struct pf_state *, int);
162: void pf_detach_state(struct pf_state *, int);
163: int pf_test_rule(struct pf_rule **, struct pf_state **,
164: int, struct pfi_kif *, struct mbuf *, int,
165: void *, struct pf_pdesc *, struct pf_rule **,
166: struct pf_ruleset **, struct ifqueue *);
167: int pf_test_fragment(struct pf_rule **, int,
168: struct pfi_kif *, struct mbuf *, void *,
169: struct pf_pdesc *, struct pf_rule **,
170: struct pf_ruleset **);
171: int pf_test_state_tcp(struct pf_state **, int,
172: struct pfi_kif *, struct mbuf *, int,
173: void *, struct pf_pdesc *, u_short *);
174: int pf_test_state_udp(struct pf_state **, int,
175: struct pfi_kif *, struct mbuf *, int,
176: void *, struct pf_pdesc *);
177: int pf_test_state_icmp(struct pf_state **, int,
178: struct pfi_kif *, struct mbuf *, int,
179: void *, struct pf_pdesc *, u_short *);
180: int pf_test_state_other(struct pf_state **, int,
181: struct pfi_kif *, struct pf_pdesc *);
182: int pf_match_tag(struct mbuf *, struct pf_rule *, int *);
183: void pf_step_into_anchor(int *, struct pf_ruleset **, int,
184: struct pf_rule **, struct pf_rule **, int *);
185: int pf_step_out_of_anchor(int *, struct pf_ruleset **,
186: int, struct pf_rule **, struct pf_rule **,
187: int *);
188: void pf_hash(struct pf_addr *, struct pf_addr *,
189: struct pf_poolhashkey *, sa_family_t);
190: int pf_map_addr(u_int8_t, struct pf_rule *,
191: struct pf_addr *, struct pf_addr *,
192: struct pf_addr *, struct pf_src_node **);
193: int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
194: struct pf_addr *, struct pf_addr *, u_int16_t,
195: struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
196: struct pf_src_node **);
197: void pf_route(struct mbuf **, struct pf_rule *, int,
198: struct ifnet *, struct pf_state *,
199: struct pf_pdesc *);
200: void pf_route6(struct mbuf **, struct pf_rule *, int,
201: struct ifnet *, struct pf_state *,
202: struct pf_pdesc *);
203: int pf_socket_lookup(int, struct pf_pdesc *);
204: u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
205: sa_family_t);
206: u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
207: sa_family_t);
208: u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
209: u_int16_t);
210: void pf_set_rt_ifp(struct pf_state *,
211: struct pf_addr *);
212: int pf_check_proto_cksum(struct mbuf *, int, int,
213: u_int8_t, sa_family_t);
214: int pf_addr_wrap_neq(struct pf_addr_wrap *,
215: struct pf_addr_wrap *);
216: struct pf_state *pf_find_state(struct pfi_kif *,
217: struct pf_state_key_cmp *, u_int8_t);
218: int pf_src_connlimit(struct pf_state **);
219: void pf_stateins_err(const char *, struct pf_state *,
220: struct pfi_kif *);
221: int pf_check_congestion(struct ifqueue *);
222:
223: extern struct pool pfr_ktable_pl;
224: extern struct pool pfr_kentry_pl;
225:
226: struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
227: { &pf_state_pl, PFSTATE_HIWAT },
228: { &pf_src_tree_pl, PFSNODE_HIWAT },
229: { &pf_frent_pl, PFFRAG_FRENT_HIWAT },
230: { &pfr_ktable_pl, PFR_KTABLE_HIWAT },
231: { &pfr_kentry_pl, PFR_KENTRY_HIWAT }
232: };
233:
234: #define STATE_LOOKUP() \
235: do { \
236: if (direction == PF_IN) \
237: *state = pf_find_state(kif, &key, PF_EXT_GWY); \
238: else \
239: *state = pf_find_state(kif, &key, PF_LAN_EXT); \
240: if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
241: return (PF_DROP); \
242: if (direction == PF_OUT && \
243: (((*state)->rule.ptr->rt == PF_ROUTETO && \
244: (*state)->rule.ptr->direction == PF_OUT) || \
245: ((*state)->rule.ptr->rt == PF_REPLYTO && \
246: (*state)->rule.ptr->direction == PF_IN)) && \
247: (*state)->rt_kif != NULL && \
248: (*state)->rt_kif != kif) \
249: return (PF_PASS); \
250: } while (0)
251:
252: #define STATE_TRANSLATE(sk) \
253: (sk)->lan.addr.addr32[0] != (sk)->gwy.addr.addr32[0] || \
254: ((sk)->af == AF_INET6 && \
255: ((sk)->lan.addr.addr32[1] != (sk)->gwy.addr.addr32[1] || \
256: (sk)->lan.addr.addr32[2] != (sk)->gwy.addr.addr32[2] || \
257: (sk)->lan.addr.addr32[3] != (sk)->gwy.addr.addr32[3])) || \
258: (sk)->lan.port != (sk)->gwy.port
259:
260: #define BOUND_IFACE(r, k) \
261: ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
262:
263: #define STATE_INC_COUNTERS(s) \
264: do { \
265: s->rule.ptr->states++; \
266: if (s->anchor.ptr != NULL) \
267: s->anchor.ptr->states++; \
268: if (s->nat_rule.ptr != NULL) \
269: s->nat_rule.ptr->states++; \
270: } while (0)
271:
272: #define STATE_DEC_COUNTERS(s) \
273: do { \
274: if (s->nat_rule.ptr != NULL) \
275: s->nat_rule.ptr->states--; \
276: if (s->anchor.ptr != NULL) \
277: s->anchor.ptr->states--; \
278: s->rule.ptr->states--; \
279: } while (0)
280:
281: static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
282: static __inline int pf_state_compare_lan_ext(struct pf_state_key *,
283: struct pf_state_key *);
284: static __inline int pf_state_compare_ext_gwy(struct pf_state_key *,
285: struct pf_state_key *);
286: static __inline int pf_state_compare_id(struct pf_state *,
287: struct pf_state *);
288:
289: struct pf_src_tree tree_src_tracking;
290:
291: struct pf_state_tree_id tree_id;
292: struct pf_state_queue state_list;
293:
294: RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
295: RB_GENERATE(pf_state_tree_lan_ext, pf_state_key,
296: entry_lan_ext, pf_state_compare_lan_ext);
297: RB_GENERATE(pf_state_tree_ext_gwy, pf_state_key,
298: entry_ext_gwy, pf_state_compare_ext_gwy);
299: RB_GENERATE(pf_state_tree_id, pf_state,
300: entry_id, pf_state_compare_id);
301:
302: #define PF_DT_SKIP_LANEXT 0x01
303: #define PF_DT_SKIP_EXTGWY 0x02
304:
305: static __inline int
306: pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
307: {
308: int diff;
309:
310: if (a->rule.ptr > b->rule.ptr)
311: return (1);
312: if (a->rule.ptr < b->rule.ptr)
313: return (-1);
314: if ((diff = a->af - b->af) != 0)
315: return (diff);
316: switch (a->af) {
317: #ifdef INET
318: case AF_INET:
319: if (a->addr.addr32[0] > b->addr.addr32[0])
320: return (1);
321: if (a->addr.addr32[0] < b->addr.addr32[0])
322: return (-1);
323: break;
324: #endif /* INET */
325: #ifdef INET6
326: case AF_INET6:
327: if (a->addr.addr32[3] > b->addr.addr32[3])
328: return (1);
329: if (a->addr.addr32[3] < b->addr.addr32[3])
330: return (-1);
331: if (a->addr.addr32[2] > b->addr.addr32[2])
332: return (1);
333: if (a->addr.addr32[2] < b->addr.addr32[2])
334: return (-1);
335: if (a->addr.addr32[1] > b->addr.addr32[1])
336: return (1);
337: if (a->addr.addr32[1] < b->addr.addr32[1])
338: return (-1);
339: if (a->addr.addr32[0] > b->addr.addr32[0])
340: return (1);
341: if (a->addr.addr32[0] < b->addr.addr32[0])
342: return (-1);
343: break;
344: #endif /* INET6 */
345: }
346: return (0);
347: }
348:
349: static __inline int
350: pf_state_compare_lan_ext(struct pf_state_key *a, struct pf_state_key *b)
351: {
352: int diff;
353:
354: if ((diff = a->proto - b->proto) != 0)
355: return (diff);
356: if ((diff = a->af - b->af) != 0)
357: return (diff);
358: switch (a->af) {
359: #ifdef INET
360: case AF_INET:
361: if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
362: return (1);
363: if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
364: return (-1);
365: if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
366: return (1);
367: if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
368: return (-1);
369: break;
370: #endif /* INET */
371: #ifdef INET6
372: case AF_INET6:
373: if (a->lan.addr.addr32[3] > b->lan.addr.addr32[3])
374: return (1);
375: if (a->lan.addr.addr32[3] < b->lan.addr.addr32[3])
376: return (-1);
377: if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
378: return (1);
379: if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
380: return (-1);
381: if (a->lan.addr.addr32[2] > b->lan.addr.addr32[2])
382: return (1);
383: if (a->lan.addr.addr32[2] < b->lan.addr.addr32[2])
384: return (-1);
385: if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
386: return (1);
387: if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
388: return (-1);
389: if (a->lan.addr.addr32[1] > b->lan.addr.addr32[1])
390: return (1);
391: if (a->lan.addr.addr32[1] < b->lan.addr.addr32[1])
392: return (-1);
393: if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
394: return (1);
395: if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
396: return (-1);
397: if (a->lan.addr.addr32[0] > b->lan.addr.addr32[0])
398: return (1);
399: if (a->lan.addr.addr32[0] < b->lan.addr.addr32[0])
400: return (-1);
401: if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
402: return (1);
403: if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
404: return (-1);
405: break;
406: #endif /* INET6 */
407: }
408:
409: if ((diff = a->lan.port - b->lan.port) != 0)
410: return (diff);
411: if ((diff = a->ext.port - b->ext.port) != 0)
412: return (diff);
413:
414: return (0);
415: }
416:
417: static __inline int
418: pf_state_compare_ext_gwy(struct pf_state_key *a, struct pf_state_key *b)
419: {
420: int diff;
421:
422: if ((diff = a->proto - b->proto) != 0)
423: return (diff);
424: if ((diff = a->af - b->af) != 0)
425: return (diff);
426: switch (a->af) {
427: #ifdef INET
428: case AF_INET:
429: if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
430: return (1);
431: if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
432: return (-1);
433: if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
434: return (1);
435: if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
436: return (-1);
437: break;
438: #endif /* INET */
439: #ifdef INET6
440: case AF_INET6:
441: if (a->ext.addr.addr32[3] > b->ext.addr.addr32[3])
442: return (1);
443: if (a->ext.addr.addr32[3] < b->ext.addr.addr32[3])
444: return (-1);
445: if (a->gwy.addr.addr32[3] > b->gwy.addr.addr32[3])
446: return (1);
447: if (a->gwy.addr.addr32[3] < b->gwy.addr.addr32[3])
448: return (-1);
449: if (a->ext.addr.addr32[2] > b->ext.addr.addr32[2])
450: return (1);
451: if (a->ext.addr.addr32[2] < b->ext.addr.addr32[2])
452: return (-1);
453: if (a->gwy.addr.addr32[2] > b->gwy.addr.addr32[2])
454: return (1);
455: if (a->gwy.addr.addr32[2] < b->gwy.addr.addr32[2])
456: return (-1);
457: if (a->ext.addr.addr32[1] > b->ext.addr.addr32[1])
458: return (1);
459: if (a->ext.addr.addr32[1] < b->ext.addr.addr32[1])
460: return (-1);
461: if (a->gwy.addr.addr32[1] > b->gwy.addr.addr32[1])
462: return (1);
463: if (a->gwy.addr.addr32[1] < b->gwy.addr.addr32[1])
464: return (-1);
465: if (a->ext.addr.addr32[0] > b->ext.addr.addr32[0])
466: return (1);
467: if (a->ext.addr.addr32[0] < b->ext.addr.addr32[0])
468: return (-1);
469: if (a->gwy.addr.addr32[0] > b->gwy.addr.addr32[0])
470: return (1);
471: if (a->gwy.addr.addr32[0] < b->gwy.addr.addr32[0])
472: return (-1);
473: break;
474: #endif /* INET6 */
475: }
476:
477: if ((diff = a->ext.port - b->ext.port) != 0)
478: return (diff);
479: if ((diff = a->gwy.port - b->gwy.port) != 0)
480: return (diff);
481:
482: return (0);
483: }
484:
485: static __inline int
486: pf_state_compare_id(struct pf_state *a, struct pf_state *b)
487: {
488: if (a->id > b->id)
489: return (1);
490: if (a->id < b->id)
491: return (-1);
492: if (a->creatorid > b->creatorid)
493: return (1);
494: if (a->creatorid < b->creatorid)
495: return (-1);
496:
497: return (0);
498: }
499:
500: #ifdef INET6
501: void
502: pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
503: {
504: switch (af) {
505: #ifdef INET
506: case AF_INET:
507: dst->addr32[0] = src->addr32[0];
508: break;
509: #endif /* INET */
510: case AF_INET6:
511: dst->addr32[0] = src->addr32[0];
512: dst->addr32[1] = src->addr32[1];
513: dst->addr32[2] = src->addr32[2];
514: dst->addr32[3] = src->addr32[3];
515: break;
516: }
517: }
518: #endif /* INET6 */
519:
520: struct pf_state *
521: pf_find_state_byid(struct pf_state_cmp *key)
522: {
523: pf_status.fcounters[FCNT_STATE_SEARCH]++;
524:
525: return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
526: }
527:
528: struct pf_state *
529: pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int8_t tree)
530: {
531: struct pf_state_key *sk;
532: struct pf_state *s;
533:
534: pf_status.fcounters[FCNT_STATE_SEARCH]++;
535:
536: switch (tree) {
537: case PF_LAN_EXT:
538: sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
539: (struct pf_state_key *)key);
540: break;
541: case PF_EXT_GWY:
542: sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
543: (struct pf_state_key *)key);
544: break;
545: default:
546: panic("pf_find_state");
547: }
548:
549: /* list is sorted, if-bound states before floating ones */
550: if (sk != NULL)
551: TAILQ_FOREACH(s, &sk->states, next)
552: if (s->kif == pfi_all || s->kif == kif)
553: return (s);
554:
555: return (NULL);
556: }
557:
558: struct pf_state *
559: pf_find_state_all(struct pf_state_key_cmp *key, u_int8_t tree, int *more)
560: {
561: struct pf_state_key *sk;
562: struct pf_state *s, *ret = NULL;
563:
564: pf_status.fcounters[FCNT_STATE_SEARCH]++;
565:
566: switch (tree) {
567: case PF_LAN_EXT:
568: sk = RB_FIND(pf_state_tree_lan_ext,
569: &pf_statetbl_lan_ext, (struct pf_state_key *)key);
570: break;
571: case PF_EXT_GWY:
572: sk = RB_FIND(pf_state_tree_ext_gwy,
573: &pf_statetbl_ext_gwy, (struct pf_state_key *)key);
574: break;
575: default:
576: panic("pf_find_state_all");
577: }
578:
579: if (sk != NULL) {
580: ret = TAILQ_FIRST(&sk->states);
581: if (more == NULL)
582: return (ret);
583:
584: TAILQ_FOREACH(s, &sk->states, next)
585: (*more)++;
586: }
587:
588: return (ret);
589: }
590:
591: void
592: pf_init_threshold(struct pf_threshold *threshold,
593: u_int32_t limit, u_int32_t seconds)
594: {
595: threshold->limit = limit * PF_THRESHOLD_MULT;
596: threshold->seconds = seconds;
597: threshold->count = 0;
598: threshold->last = time_second;
599: }
600:
601: void
602: pf_add_threshold(struct pf_threshold *threshold)
603: {
604: u_int32_t t = time_second, diff = t - threshold->last;
605:
606: if (diff >= threshold->seconds)
607: threshold->count = 0;
608: else
609: threshold->count -= threshold->count * diff /
610: threshold->seconds;
611: threshold->count += PF_THRESHOLD_MULT;
612: threshold->last = t;
613: }
614:
615: int
616: pf_check_threshold(struct pf_threshold *threshold)
617: {
618: return (threshold->count > threshold->limit);
619: }
620:
621: int
622: pf_src_connlimit(struct pf_state **state)
623: {
624: int bad = 0;
625:
626: (*state)->src_node->conn++;
627: (*state)->src.tcp_est = 1;
628: pf_add_threshold(&(*state)->src_node->conn_rate);
629:
630: if ((*state)->rule.ptr->max_src_conn &&
631: (*state)->rule.ptr->max_src_conn <
632: (*state)->src_node->conn) {
633: pf_status.lcounters[LCNT_SRCCONN]++;
634: bad++;
635: }
636:
637: if ((*state)->rule.ptr->max_src_conn_rate.limit &&
638: pf_check_threshold(&(*state)->src_node->conn_rate)) {
639: pf_status.lcounters[LCNT_SRCCONNRATE]++;
640: bad++;
641: }
642:
643: if (!bad)
644: return (0);
645:
646: if ((*state)->rule.ptr->overload_tbl) {
647: struct pfr_addr p;
648: u_int32_t killed = 0;
649:
650: pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
651: if (pf_status.debug >= PF_DEBUG_MISC) {
652: printf("pf_src_connlimit: blocking address ");
653: pf_print_host(&(*state)->src_node->addr, 0,
654: (*state)->state_key->af);
655: }
656:
657: bzero(&p, sizeof(p));
658: p.pfra_af = (*state)->state_key->af;
659: switch ((*state)->state_key->af) {
660: #ifdef INET
661: case AF_INET:
662: p.pfra_net = 32;
663: p.pfra_ip4addr = (*state)->src_node->addr.v4;
664: break;
665: #endif /* INET */
666: #ifdef INET6
667: case AF_INET6:
668: p.pfra_net = 128;
669: p.pfra_ip6addr = (*state)->src_node->addr.v6;
670: break;
671: #endif /* INET6 */
672: }
673:
674: pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
675: &p, time_second);
676:
677: /* kill existing states if that's required. */
678: if ((*state)->rule.ptr->flush) {
679: struct pf_state_key *sk;
680: struct pf_state *st;
681:
682: pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
683: RB_FOREACH(st, pf_state_tree_id, &tree_id) {
684: sk = st->state_key;
685: /*
686: * Kill states from this source. (Only those
687: * from the same rule if PF_FLUSH_GLOBAL is not
688: * set)
689: */
690: if (sk->af ==
691: (*state)->state_key->af &&
692: (((*state)->state_key->direction ==
693: PF_OUT &&
694: PF_AEQ(&(*state)->src_node->addr,
695: &sk->lan.addr, sk->af)) ||
696: ((*state)->state_key->direction == PF_IN &&
697: PF_AEQ(&(*state)->src_node->addr,
698: &sk->ext.addr, sk->af))) &&
699: ((*state)->rule.ptr->flush &
700: PF_FLUSH_GLOBAL ||
701: (*state)->rule.ptr == st->rule.ptr)) {
702: st->timeout = PFTM_PURGE;
703: st->src.state = st->dst.state =
704: TCPS_CLOSED;
705: killed++;
706: }
707: }
708: if (pf_status.debug >= PF_DEBUG_MISC)
709: printf(", %u states killed", killed);
710: }
711: if (pf_status.debug >= PF_DEBUG_MISC)
712: printf("\n");
713: }
714:
715: /* kill this state */
716: (*state)->timeout = PFTM_PURGE;
717: (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
718: return (1);
719: }
720:
721: int
722: pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
723: struct pf_addr *src, sa_family_t af)
724: {
725: struct pf_src_node k;
726:
727: if (*sn == NULL) {
728: k.af = af;
729: PF_ACPY(&k.addr, src, af);
730: if (rule->rule_flag & PFRULE_RULESRCTRACK ||
731: rule->rpool.opts & PF_POOL_STICKYADDR)
732: k.rule.ptr = rule;
733: else
734: k.rule.ptr = NULL;
735: pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
736: *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
737: }
738: if (*sn == NULL) {
739: if (!rule->max_src_nodes ||
740: rule->src_nodes < rule->max_src_nodes)
741: (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT);
742: else
743: pf_status.lcounters[LCNT_SRCNODES]++;
744: if ((*sn) == NULL)
745: return (-1);
746: bzero(*sn, sizeof(struct pf_src_node));
747:
748: pf_init_threshold(&(*sn)->conn_rate,
749: rule->max_src_conn_rate.limit,
750: rule->max_src_conn_rate.seconds);
751:
752: (*sn)->af = af;
753: if (rule->rule_flag & PFRULE_RULESRCTRACK ||
754: rule->rpool.opts & PF_POOL_STICKYADDR)
755: (*sn)->rule.ptr = rule;
756: else
757: (*sn)->rule.ptr = NULL;
758: PF_ACPY(&(*sn)->addr, src, af);
759: if (RB_INSERT(pf_src_tree,
760: &tree_src_tracking, *sn) != NULL) {
761: if (pf_status.debug >= PF_DEBUG_MISC) {
762: printf("pf: src_tree insert failed: ");
763: pf_print_host(&(*sn)->addr, 0, af);
764: printf("\n");
765: }
766: pool_put(&pf_src_tree_pl, *sn);
767: return (-1);
768: }
769: (*sn)->creation = time_second;
770: (*sn)->ruletype = rule->action;
771: if ((*sn)->rule.ptr != NULL)
772: (*sn)->rule.ptr->src_nodes++;
773: pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
774: pf_status.src_nodes++;
775: } else {
776: if (rule->max_src_states &&
777: (*sn)->states >= rule->max_src_states) {
778: pf_status.lcounters[LCNT_SRCSTATES]++;
779: return (-1);
780: }
781: }
782: return (0);
783: }
784:
785: void
786: pf_stateins_err(const char *tree, struct pf_state *s, struct pfi_kif *kif)
787: {
788: struct pf_state_key *sk = s->state_key;
789:
790: if (pf_status.debug >= PF_DEBUG_MISC) {
791: printf("pf: state insert failed: %s %s", tree, kif->pfik_name);
792: printf(" lan: ");
793: pf_print_host(&sk->lan.addr, sk->lan.port,
794: sk->af);
795: printf(" gwy: ");
796: pf_print_host(&sk->gwy.addr, sk->gwy.port,
797: sk->af);
798: printf(" ext: ");
799: pf_print_host(&sk->ext.addr, sk->ext.port,
800: sk->af);
801: if (s->sync_flags & PFSTATE_FROMSYNC)
802: printf(" (from sync)");
803: printf("\n");
804: }
805: }
806:
807: int
808: pf_insert_state(struct pfi_kif *kif, struct pf_state *s)
809: {
810: struct pf_state_key *cur;
811: struct pf_state *sp;
812:
813: KASSERT(s->state_key != NULL);
814: s->kif = kif;
815:
816: if ((cur = RB_INSERT(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
817: s->state_key)) != NULL) {
818: /* key exists. check for same kif, if none, add to key */
819: TAILQ_FOREACH(sp, &cur->states, next)
820: if (sp->kif == kif) { /* collision! */
821: pf_stateins_err("tree_lan_ext", s, kif);
822: return (-1);
823: }
824: pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
825: pf_attach_state(cur, s, kif == pfi_all ? 1 : 0);
826: }
827:
828: /* if cur != NULL, we already found a state key and attached to it */
829: if (cur == NULL && (cur = RB_INSERT(pf_state_tree_ext_gwy,
830: &pf_statetbl_ext_gwy, s->state_key)) != NULL) {
831: /* must not happen. we must have found the sk above! */
832: pf_stateins_err("tree_ext_gwy", s, kif);
833: pf_detach_state(s, PF_DT_SKIP_EXTGWY);
834: return (-1);
835: }
836:
837: if (s->id == 0 && s->creatorid == 0) {
838: s->id = htobe64(pf_status.stateid++);
839: s->creatorid = pf_status.hostid;
840: }
841: if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
842: if (pf_status.debug >= PF_DEBUG_MISC) {
843: printf("pf: state insert failed: "
844: "id: %016llx creatorid: %08x",
845: betoh64(s->id), ntohl(s->creatorid));
846: if (s->sync_flags & PFSTATE_FROMSYNC)
847: printf(" (from sync)");
848: printf("\n");
849: }
850: pf_detach_state(s, 0);
851: return (-1);
852: }
853: TAILQ_INSERT_TAIL(&state_list, s, entry_list);
854: pf_status.fcounters[FCNT_STATE_INSERT]++;
855: pf_status.states++;
856: pfi_kif_ref(kif, PFI_KIF_REF_STATE);
857: #if NPFSYNC
858: pfsync_insert_state(s);
859: #endif
860: return (0);
861: }
862:
863: void
864: pf_purge_thread(void *v)
865: {
866: int nloops = 0, s;
867:
868: for (;;) {
869: tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
870:
871: s = splsoftnet();
872:
873: /* process a fraction of the state table every second */
874: pf_purge_expired_states(1 + (pf_status.states
875: / pf_default_rule.timeout[PFTM_INTERVAL]));
876:
877: /* purge other expired types every PFTM_INTERVAL seconds */
878: if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
879: pf_purge_expired_fragments();
880: pf_purge_expired_src_nodes(0);
881: nloops = 0;
882: }
883:
884: splx(s);
885: }
886: }
887:
888: u_int32_t
889: pf_state_expires(const struct pf_state *state)
890: {
891: u_int32_t timeout;
892: u_int32_t start;
893: u_int32_t end;
894: u_int32_t states;
895:
896: /* handle all PFTM_* > PFTM_MAX here */
897: if (state->timeout == PFTM_PURGE)
898: return (time_second);
899: if (state->timeout == PFTM_UNTIL_PACKET)
900: return (0);
901: KASSERT(state->timeout != PFTM_UNLINKED);
902: KASSERT(state->timeout < PFTM_MAX);
903: timeout = state->rule.ptr->timeout[state->timeout];
904: if (!timeout)
905: timeout = pf_default_rule.timeout[state->timeout];
906: start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
907: if (start) {
908: end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
909: states = state->rule.ptr->states;
910: } else {
911: start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
912: end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
913: states = pf_status.states;
914: }
915: if (end && states > start && start < end) {
916: if (states < end)
917: return (state->expire + timeout * (end - states) /
918: (end - start));
919: else
920: return (time_second);
921: }
922: return (state->expire + timeout);
923: }
924:
925: void
926: pf_purge_expired_src_nodes(int waslocked)
927: {
928: struct pf_src_node *cur, *next;
929: int locked = waslocked;
930:
931: for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
932: next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
933:
934: if (cur->states <= 0 && cur->expire <= time_second) {
935: if (! locked) {
936: rw_enter_write(&pf_consistency_lock);
937: next = RB_NEXT(pf_src_tree,
938: &tree_src_tracking, cur);
939: locked = 1;
940: }
941: if (cur->rule.ptr != NULL) {
942: cur->rule.ptr->src_nodes--;
943: if (cur->rule.ptr->states <= 0 &&
944: cur->rule.ptr->max_src_nodes <= 0)
945: pf_rm_rule(NULL, cur->rule.ptr);
946: }
947: RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
948: pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
949: pf_status.src_nodes--;
950: pool_put(&pf_src_tree_pl, cur);
951: }
952: }
953:
954: if (locked && !waslocked)
955: rw_exit_write(&pf_consistency_lock);
956: }
957:
958: void
959: pf_src_tree_remove_state(struct pf_state *s)
960: {
961: u_int32_t timeout;
962:
963: if (s->src_node != NULL) {
964: if (s->state_key->proto == IPPROTO_TCP) {
965: if (s->src.tcp_est)
966: --s->src_node->conn;
967: }
968: if (--s->src_node->states <= 0) {
969: timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
970: if (!timeout)
971: timeout =
972: pf_default_rule.timeout[PFTM_SRC_NODE];
973: s->src_node->expire = time_second + timeout;
974: }
975: }
976: if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
977: if (--s->nat_src_node->states <= 0) {
978: timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
979: if (!timeout)
980: timeout =
981: pf_default_rule.timeout[PFTM_SRC_NODE];
982: s->nat_src_node->expire = time_second + timeout;
983: }
984: }
985: s->src_node = s->nat_src_node = NULL;
986: }
987:
988: /* callers should be at splsoftnet */
989: void
990: pf_unlink_state(struct pf_state *cur)
991: {
992: if (cur->src.state == PF_TCPS_PROXY_DST) {
993: pf_send_tcp(cur->rule.ptr, cur->state_key->af,
994: &cur->state_key->ext.addr, &cur->state_key->lan.addr,
995: cur->state_key->ext.port, cur->state_key->lan.port,
996: cur->src.seqhi, cur->src.seqlo + 1,
997: TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
998: }
999: RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1000: #if NPFSYNC
1001: if (cur->creatorid == pf_status.hostid)
1002: pfsync_delete_state(cur);
1003: #endif
1004: cur->timeout = PFTM_UNLINKED;
1005: pf_src_tree_remove_state(cur);
1006: pf_detach_state(cur, 0);
1007: }
1008:
1009: /* callers should be at splsoftnet and hold the
1010: * write_lock on pf_consistency_lock */
1011: void
1012: pf_free_state(struct pf_state *cur)
1013: {
1014: #if NPFSYNC
1015: if (pfsyncif != NULL &&
1016: (pfsyncif->sc_bulk_send_next == cur ||
1017: pfsyncif->sc_bulk_terminator == cur))
1018: return;
1019: #endif
1020: KASSERT(cur->timeout == PFTM_UNLINKED);
1021: if (--cur->rule.ptr->states <= 0 &&
1022: cur->rule.ptr->src_nodes <= 0)
1023: pf_rm_rule(NULL, cur->rule.ptr);
1024: if (cur->nat_rule.ptr != NULL)
1025: if (--cur->nat_rule.ptr->states <= 0 &&
1026: cur->nat_rule.ptr->src_nodes <= 0)
1027: pf_rm_rule(NULL, cur->nat_rule.ptr);
1028: if (cur->anchor.ptr != NULL)
1029: if (--cur->anchor.ptr->states <= 0)
1030: pf_rm_rule(NULL, cur->anchor.ptr);
1031: pf_normalize_tcp_cleanup(cur);
1032: pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
1033: TAILQ_REMOVE(&state_list, cur, entry_list);
1034: if (cur->tag)
1035: pf_tag_unref(cur->tag);
1036: pool_put(&pf_state_pl, cur);
1037: pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1038: pf_status.states--;
1039: }
1040:
1041: void
1042: pf_purge_expired_states(u_int32_t maxcheck)
1043: {
1044: static struct pf_state *cur = NULL;
1045: struct pf_state *next;
1046: int locked = 0;
1047:
1048: while (maxcheck--) {
1049: /* wrap to start of list when we hit the end */
1050: if (cur == NULL) {
1051: cur = TAILQ_FIRST(&state_list);
1052: if (cur == NULL)
1053: break; /* list empty */
1054: }
1055:
1056: /* get next state, as cur may get deleted */
1057: next = TAILQ_NEXT(cur, entry_list);
1058:
1059: if (cur->timeout == PFTM_UNLINKED) {
1060: /* free unlinked state */
1061: if (! locked) {
1062: rw_enter_write(&pf_consistency_lock);
1063: locked = 1;
1064: }
1065: pf_free_state(cur);
1066: } else if (pf_state_expires(cur) <= time_second) {
1067: /* unlink and free expired state */
1068: pf_unlink_state(cur);
1069: if (! locked) {
1070: rw_enter_write(&pf_consistency_lock);
1071: locked = 1;
1072: }
1073: pf_free_state(cur);
1074: }
1075: cur = next;
1076: }
1077:
1078: if (locked)
1079: rw_exit_write(&pf_consistency_lock);
1080: }
1081:
1082: int
1083: pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1084: {
1085: if (aw->type != PF_ADDR_TABLE)
1086: return (0);
1087: if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
1088: return (1);
1089: return (0);
1090: }
1091:
1092: void
1093: pf_tbladdr_remove(struct pf_addr_wrap *aw)
1094: {
1095: if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
1096: return;
1097: pfr_detach_table(aw->p.tbl);
1098: aw->p.tbl = NULL;
1099: }
1100:
1101: void
1102: pf_tbladdr_copyout(struct pf_addr_wrap *aw)
1103: {
1104: struct pfr_ktable *kt = aw->p.tbl;
1105:
1106: if (aw->type != PF_ADDR_TABLE || kt == NULL)
1107: return;
1108: if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
1109: kt = kt->pfrkt_root;
1110: aw->p.tbl = NULL;
1111: aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
1112: kt->pfrkt_cnt : -1;
1113: }
1114:
1115: void
1116: pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
1117: {
1118: switch (af) {
1119: #ifdef INET
1120: case AF_INET: {
1121: u_int32_t a = ntohl(addr->addr32[0]);
1122: printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
1123: (a>>8)&255, a&255);
1124: if (p) {
1125: p = ntohs(p);
1126: printf(":%u", p);
1127: }
1128: break;
1129: }
1130: #endif /* INET */
1131: #ifdef INET6
1132: case AF_INET6: {
1133: u_int16_t b;
1134: u_int8_t i, curstart = 255, curend = 0,
1135: maxstart = 0, maxend = 0;
1136: for (i = 0; i < 8; i++) {
1137: if (!addr->addr16[i]) {
1138: if (curstart == 255)
1139: curstart = i;
1140: else
1141: curend = i;
1142: } else {
1143: if (curstart) {
1144: if ((curend - curstart) >
1145: (maxend - maxstart)) {
1146: maxstart = curstart;
1147: maxend = curend;
1148: curstart = 255;
1149: }
1150: }
1151: }
1152: }
1153: for (i = 0; i < 8; i++) {
1154: if (i >= maxstart && i <= maxend) {
1155: if (maxend != 7) {
1156: if (i == maxstart)
1157: printf(":");
1158: } else {
1159: if (i == maxend)
1160: printf(":");
1161: }
1162: } else {
1163: b = ntohs(addr->addr16[i]);
1164: printf("%x", b);
1165: if (i < 7)
1166: printf(":");
1167: }
1168: }
1169: if (p) {
1170: p = ntohs(p);
1171: printf("[%u]", p);
1172: }
1173: break;
1174: }
1175: #endif /* INET6 */
1176: }
1177: }
1178:
1179: void
1180: pf_print_state(struct pf_state *s)
1181: {
1182: struct pf_state_key *sk = s->state_key;
1183: switch (sk->proto) {
1184: case IPPROTO_TCP:
1185: printf("TCP ");
1186: break;
1187: case IPPROTO_UDP:
1188: printf("UDP ");
1189: break;
1190: case IPPROTO_ICMP:
1191: printf("ICMP ");
1192: break;
1193: case IPPROTO_ICMPV6:
1194: printf("ICMPV6 ");
1195: break;
1196: default:
1197: printf("%u ", sk->proto);
1198: break;
1199: }
1200: pf_print_host(&sk->lan.addr, sk->lan.port, sk->af);
1201: printf(" ");
1202: pf_print_host(&sk->gwy.addr, sk->gwy.port, sk->af);
1203: printf(" ");
1204: pf_print_host(&sk->ext.addr, sk->ext.port, sk->af);
1205: printf(" [lo=%u high=%u win=%u modulator=%u", s->src.seqlo,
1206: s->src.seqhi, s->src.max_win, s->src.seqdiff);
1207: if (s->src.wscale && s->dst.wscale)
1208: printf(" wscale=%u", s->src.wscale & PF_WSCALE_MASK);
1209: printf("]");
1210: printf(" [lo=%u high=%u win=%u modulator=%u", s->dst.seqlo,
1211: s->dst.seqhi, s->dst.max_win, s->dst.seqdiff);
1212: if (s->src.wscale && s->dst.wscale)
1213: printf(" wscale=%u", s->dst.wscale & PF_WSCALE_MASK);
1214: printf("]");
1215: printf(" %u:%u", s->src.state, s->dst.state);
1216: }
1217:
1218: void
1219: pf_print_flags(u_int8_t f)
1220: {
1221: if (f)
1222: printf(" ");
1223: if (f & TH_FIN)
1224: printf("F");
1225: if (f & TH_SYN)
1226: printf("S");
1227: if (f & TH_RST)
1228: printf("R");
1229: if (f & TH_PUSH)
1230: printf("P");
1231: if (f & TH_ACK)
1232: printf("A");
1233: if (f & TH_URG)
1234: printf("U");
1235: if (f & TH_ECE)
1236: printf("E");
1237: if (f & TH_CWR)
1238: printf("W");
1239: }
1240:
1241: #define PF_SET_SKIP_STEPS(i) \
1242: do { \
1243: while (head[i] != cur) { \
1244: head[i]->skip[i].ptr = cur; \
1245: head[i] = TAILQ_NEXT(head[i], entries); \
1246: } \
1247: } while (0)
1248:
1249: void
1250: pf_calc_skip_steps(struct pf_rulequeue *rules)
1251: {
1252: struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
1253: int i;
1254:
1255: cur = TAILQ_FIRST(rules);
1256: prev = cur;
1257: for (i = 0; i < PF_SKIP_COUNT; ++i)
1258: head[i] = cur;
1259: while (cur != NULL) {
1260:
1261: if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
1262: PF_SET_SKIP_STEPS(PF_SKIP_IFP);
1263: if (cur->direction != prev->direction)
1264: PF_SET_SKIP_STEPS(PF_SKIP_DIR);
1265: if (cur->af != prev->af)
1266: PF_SET_SKIP_STEPS(PF_SKIP_AF);
1267: if (cur->proto != prev->proto)
1268: PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
1269: if (cur->src.neg != prev->src.neg ||
1270: pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
1271: PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
1272: if (cur->src.port[0] != prev->src.port[0] ||
1273: cur->src.port[1] != prev->src.port[1] ||
1274: cur->src.port_op != prev->src.port_op)
1275: PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
1276: if (cur->dst.neg != prev->dst.neg ||
1277: pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
1278: PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
1279: if (cur->dst.port[0] != prev->dst.port[0] ||
1280: cur->dst.port[1] != prev->dst.port[1] ||
1281: cur->dst.port_op != prev->dst.port_op)
1282: PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
1283:
1284: prev = cur;
1285: cur = TAILQ_NEXT(cur, entries);
1286: }
1287: for (i = 0; i < PF_SKIP_COUNT; ++i)
1288: PF_SET_SKIP_STEPS(i);
1289: }
1290:
1291: int
1292: pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
1293: {
1294: if (aw1->type != aw2->type)
1295: return (1);
1296: switch (aw1->type) {
1297: case PF_ADDR_ADDRMASK:
1298: if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
1299: return (1);
1300: if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
1301: return (1);
1302: return (0);
1303: case PF_ADDR_DYNIFTL:
1304: return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1305: case PF_ADDR_NOROUTE:
1306: case PF_ADDR_URPFFAILED:
1307: return (0);
1308: case PF_ADDR_TABLE:
1309: return (aw1->p.tbl != aw2->p.tbl);
1310: case PF_ADDR_RTLABEL:
1311: return (aw1->v.rtlabel != aw2->v.rtlabel);
1312: default:
1313: printf("invalid address type: %d\n", aw1->type);
1314: return (1);
1315: }
1316: }
1317:
1318: u_int16_t
1319: pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
1320: {
1321: u_int32_t l;
1322:
1323: if (udp && !cksum)
1324: return (0x0000);
1325: l = cksum + old - new;
1326: l = (l >> 16) + (l & 65535);
1327: l = l & 65535;
1328: if (udp && !l)
1329: return (0xFFFF);
1330: return (l);
1331: }
1332:
1333: void
1334: pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
1335: struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
1336: {
1337: struct pf_addr ao;
1338: u_int16_t po = *p;
1339:
1340: PF_ACPY(&ao, a, af);
1341: PF_ACPY(a, an, af);
1342:
1343: *p = pn;
1344:
1345: switch (af) {
1346: #ifdef INET
1347: case AF_INET:
1348: *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1349: ao.addr16[0], an->addr16[0], 0),
1350: ao.addr16[1], an->addr16[1], 0);
1351: *p = pn;
1352: *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1353: ao.addr16[0], an->addr16[0], u),
1354: ao.addr16[1], an->addr16[1], u),
1355: po, pn, u);
1356: break;
1357: #endif /* INET */
1358: #ifdef INET6
1359: case AF_INET6:
1360: *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1361: pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1362: pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
1363: ao.addr16[0], an->addr16[0], u),
1364: ao.addr16[1], an->addr16[1], u),
1365: ao.addr16[2], an->addr16[2], u),
1366: ao.addr16[3], an->addr16[3], u),
1367: ao.addr16[4], an->addr16[4], u),
1368: ao.addr16[5], an->addr16[5], u),
1369: ao.addr16[6], an->addr16[6], u),
1370: ao.addr16[7], an->addr16[7], u),
1371: po, pn, u);
1372: break;
1373: #endif /* INET6 */
1374: }
1375: }
1376:
1377:
1378: /* Changes a u_int32_t. Uses a void * so there are no align restrictions */
1379: void
1380: pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
1381: {
1382: u_int32_t ao;
1383:
1384: memcpy(&ao, a, sizeof(ao));
1385: memcpy(a, &an, sizeof(u_int32_t));
1386: *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
1387: ao % 65536, an % 65536, u);
1388: }
1389:
1390: #ifdef INET6
1391: void
1392: pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
1393: {
1394: struct pf_addr ao;
1395:
1396: PF_ACPY(&ao, a, AF_INET6);
1397: PF_ACPY(a, an, AF_INET6);
1398:
1399: *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1400: pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1401: pf_cksum_fixup(pf_cksum_fixup(*c,
1402: ao.addr16[0], an->addr16[0], u),
1403: ao.addr16[1], an->addr16[1], u),
1404: ao.addr16[2], an->addr16[2], u),
1405: ao.addr16[3], an->addr16[3], u),
1406: ao.addr16[4], an->addr16[4], u),
1407: ao.addr16[5], an->addr16[5], u),
1408: ao.addr16[6], an->addr16[6], u),
1409: ao.addr16[7], an->addr16[7], u);
1410: }
1411: #endif /* INET6 */
1412:
1413: void
1414: pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
1415: struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
1416: u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
1417: {
1418: struct pf_addr oia, ooa;
1419:
1420: PF_ACPY(&oia, ia, af);
1421: PF_ACPY(&ooa, oa, af);
1422:
1423: /* Change inner protocol port, fix inner protocol checksum. */
1424: if (ip != NULL) {
1425: u_int16_t oip = *ip;
1426: u_int32_t opc;
1427:
1428: if (pc != NULL)
1429: opc = *pc;
1430: *ip = np;
1431: if (pc != NULL)
1432: *pc = pf_cksum_fixup(*pc, oip, *ip, u);
1433: *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
1434: if (pc != NULL)
1435: *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
1436: }
1437: /* Change inner ip address, fix inner ip and icmp checksums. */
1438: PF_ACPY(ia, na, af);
1439: switch (af) {
1440: #ifdef INET
1441: case AF_INET: {
1442: u_int32_t oh2c = *h2c;
1443:
1444: *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
1445: oia.addr16[0], ia->addr16[0], 0),
1446: oia.addr16[1], ia->addr16[1], 0);
1447: *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
1448: oia.addr16[0], ia->addr16[0], 0),
1449: oia.addr16[1], ia->addr16[1], 0);
1450: *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
1451: break;
1452: }
1453: #endif /* INET */
1454: #ifdef INET6
1455: case AF_INET6:
1456: *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1457: pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1458: pf_cksum_fixup(pf_cksum_fixup(*ic,
1459: oia.addr16[0], ia->addr16[0], u),
1460: oia.addr16[1], ia->addr16[1], u),
1461: oia.addr16[2], ia->addr16[2], u),
1462: oia.addr16[3], ia->addr16[3], u),
1463: oia.addr16[4], ia->addr16[4], u),
1464: oia.addr16[5], ia->addr16[5], u),
1465: oia.addr16[6], ia->addr16[6], u),
1466: oia.addr16[7], ia->addr16[7], u);
1467: break;
1468: #endif /* INET6 */
1469: }
1470: /* Change outer ip address, fix outer ip or icmpv6 checksum. */
1471: PF_ACPY(oa, na, af);
1472: switch (af) {
1473: #ifdef INET
1474: case AF_INET:
1475: *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
1476: ooa.addr16[0], oa->addr16[0], 0),
1477: ooa.addr16[1], oa->addr16[1], 0);
1478: break;
1479: #endif /* INET */
1480: #ifdef INET6
1481: case AF_INET6:
1482: *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1483: pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
1484: pf_cksum_fixup(pf_cksum_fixup(*ic,
1485: ooa.addr16[0], oa->addr16[0], u),
1486: ooa.addr16[1], oa->addr16[1], u),
1487: ooa.addr16[2], oa->addr16[2], u),
1488: ooa.addr16[3], oa->addr16[3], u),
1489: ooa.addr16[4], oa->addr16[4], u),
1490: ooa.addr16[5], oa->addr16[5], u),
1491: ooa.addr16[6], oa->addr16[6], u),
1492: ooa.addr16[7], oa->addr16[7], u);
1493: break;
1494: #endif /* INET6 */
1495: }
1496: }
1497:
1498:
1499: /*
1500: * Need to modulate the sequence numbers in the TCP SACK option
1501: * (credits to Krzysztof Pfaff for report and patch)
1502: */
1503: int
1504: pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
1505: struct tcphdr *th, struct pf_state_peer *dst)
1506: {
1507: int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen;
1508: u_int8_t opts[MAX_TCPOPTLEN], *opt = opts;
1509: int copyback = 0, i, olen;
1510: struct sackblk sack;
1511:
1512: #define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2)
1513: if (hlen < TCPOLEN_SACKLEN ||
1514: !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af))
1515: return 0;
1516:
1517: while (hlen >= TCPOLEN_SACKLEN) {
1518: olen = opt[1];
1519: switch (*opt) {
1520: case TCPOPT_EOL: /* FALLTHROUGH */
1521: case TCPOPT_NOP:
1522: opt++;
1523: hlen--;
1524: break;
1525: case TCPOPT_SACK:
1526: if (olen > hlen)
1527: olen = hlen;
1528: if (olen >= TCPOLEN_SACKLEN) {
1529: for (i = 2; i + TCPOLEN_SACK <= olen;
1530: i += TCPOLEN_SACK) {
1531: memcpy(&sack, &opt[i], sizeof(sack));
1532: pf_change_a(&sack.start, &th->th_sum,
1533: htonl(ntohl(sack.start) -
1534: dst->seqdiff), 0);
1535: pf_change_a(&sack.end, &th->th_sum,
1536: htonl(ntohl(sack.end) -
1537: dst->seqdiff), 0);
1538: memcpy(&opt[i], &sack, sizeof(sack));
1539: }
1540: copyback = 1;
1541: }
1542: /* FALLTHROUGH */
1543: default:
1544: if (olen < 2)
1545: olen = 2;
1546: hlen -= olen;
1547: opt += olen;
1548: }
1549: }
1550:
1551: if (copyback)
1552: m_copyback(m, off + sizeof(*th), thoptlen, opts);
1553: return (copyback);
1554: }
1555:
1556: void
1557: pf_send_tcp(const struct pf_rule *r, sa_family_t af,
1558: const struct pf_addr *saddr, const struct pf_addr *daddr,
1559: u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
1560: u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
1561: u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
1562: {
1563: struct mbuf *m;
1564: int len, tlen;
1565: #ifdef INET
1566: struct ip *h;
1567: #endif /* INET */
1568: #ifdef INET6
1569: struct ip6_hdr *h6;
1570: #endif /* INET6 */
1571: struct tcphdr *th;
1572: char *opt;
1573:
1574: /* maximum segment size tcp option */
1575: tlen = sizeof(struct tcphdr);
1576: if (mss)
1577: tlen += 4;
1578:
1579: switch (af) {
1580: #ifdef INET
1581: case AF_INET:
1582: len = sizeof(struct ip) + tlen;
1583: break;
1584: #endif /* INET */
1585: #ifdef INET6
1586: case AF_INET6:
1587: len = sizeof(struct ip6_hdr) + tlen;
1588: break;
1589: #endif /* INET6 */
1590: }
1591:
1592: /* create outgoing mbuf */
1593: m = m_gethdr(M_DONTWAIT, MT_HEADER);
1594: if (m == NULL)
1595: return;
1596: if (tag)
1597: m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
1598: m->m_pkthdr.pf.tag = rtag;
1599:
1600: if (r != NULL && r->rtableid >= 0)
1601: m->m_pkthdr.pf.rtableid = m->m_pkthdr.pf.rtableid;
1602:
1603: #ifdef ALTQ
1604: if (r != NULL && r->qid) {
1605: m->m_pkthdr.pf.qid = r->qid;
1606: /* add hints for ecn */
1607: m->m_pkthdr.pf.hdr = mtod(m, struct ip *);
1608: }
1609: #endif /* ALTQ */
1610: m->m_data += max_linkhdr;
1611: m->m_pkthdr.len = m->m_len = len;
1612: m->m_pkthdr.rcvif = NULL;
1613: bzero(m->m_data, len);
1614: switch (af) {
1615: #ifdef INET
1616: case AF_INET:
1617: h = mtod(m, struct ip *);
1618:
1619: /* IP header fields included in the TCP checksum */
1620: h->ip_p = IPPROTO_TCP;
1621: h->ip_len = htons(tlen);
1622: h->ip_src.s_addr = saddr->v4.s_addr;
1623: h->ip_dst.s_addr = daddr->v4.s_addr;
1624:
1625: th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
1626: break;
1627: #endif /* INET */
1628: #ifdef INET6
1629: case AF_INET6:
1630: h6 = mtod(m, struct ip6_hdr *);
1631:
1632: /* IP header fields included in the TCP checksum */
1633: h6->ip6_nxt = IPPROTO_TCP;
1634: h6->ip6_plen = htons(tlen);
1635: memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
1636: memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
1637:
1638: th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
1639: break;
1640: #endif /* INET6 */
1641: }
1642:
1643: /* TCP header */
1644: th->th_sport = sport;
1645: th->th_dport = dport;
1646: th->th_seq = htonl(seq);
1647: th->th_ack = htonl(ack);
1648: th->th_off = tlen >> 2;
1649: th->th_flags = flags;
1650: th->th_win = htons(win);
1651:
1652: if (mss) {
1653: opt = (char *)(th + 1);
1654: opt[0] = TCPOPT_MAXSEG;
1655: opt[1] = 4;
1656: HTONS(mss);
1657: bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
1658: }
1659:
1660: switch (af) {
1661: #ifdef INET
1662: case AF_INET:
1663: /* TCP checksum */
1664: th->th_sum = in_cksum(m, len);
1665:
1666: /* Finish the IP header */
1667: h->ip_v = 4;
1668: h->ip_hl = sizeof(*h) >> 2;
1669: h->ip_tos = IPTOS_LOWDELAY;
1670: h->ip_len = htons(len);
1671: h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
1672: h->ip_ttl = ttl ? ttl : ip_defttl;
1673: h->ip_sum = 0;
1674: if (eh == NULL) {
1675: ip_output(m, (void *)NULL, (void *)NULL, 0,
1676: (void *)NULL, (void *)NULL);
1677: } else {
1678: struct route ro;
1679: struct rtentry rt;
1680: struct ether_header *e = (void *)ro.ro_dst.sa_data;
1681:
1682: if (ifp == NULL) {
1683: m_freem(m);
1684: return;
1685: }
1686: rt.rt_ifp = ifp;
1687: ro.ro_rt = &rt;
1688: ro.ro_dst.sa_len = sizeof(ro.ro_dst);
1689: ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT;
1690: bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN);
1691: bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN);
1692: e->ether_type = eh->ether_type;
1693: ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER,
1694: (void *)NULL, (void *)NULL);
1695: }
1696: break;
1697: #endif /* INET */
1698: #ifdef INET6
1699: case AF_INET6:
1700: /* TCP checksum */
1701: th->th_sum = in6_cksum(m, IPPROTO_TCP,
1702: sizeof(struct ip6_hdr), tlen);
1703:
1704: h6->ip6_vfc |= IPV6_VERSION;
1705: h6->ip6_hlim = IPV6_DEFHLIM;
1706:
1707: ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
1708: break;
1709: #endif /* INET6 */
1710: }
1711: }
1712:
1713: void
1714: pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
1715: struct pf_rule *r)
1716: {
1717: struct mbuf *m0;
1718:
1719: m0 = m_copy(m, 0, M_COPYALL);
1720: m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
1721:
1722: if (r->rtableid >= 0)
1723: m0->m_pkthdr.pf.rtableid = r->rtableid;
1724:
1725: #ifdef ALTQ
1726: if (r->qid) {
1727: m0->m_pkthdr.pf.qid = r->qid;
1728: /* add hints for ecn */
1729: m0->m_pkthdr.pf.hdr = mtod(m0, struct ip *);
1730: }
1731: #endif /* ALTQ */
1732:
1733: switch (af) {
1734: #ifdef INET
1735: case AF_INET:
1736: icmp_error(m0, type, code, 0, 0);
1737: break;
1738: #endif /* INET */
1739: #ifdef INET6
1740: case AF_INET6:
1741: icmp6_error(m0, type, code, 0);
1742: break;
1743: #endif /* INET6 */
1744: }
1745: }
1746:
1747: /*
1748: * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
1749: * If n is 0, they match if they are equal. If n is != 0, they match if they
1750: * are different.
1751: */
1752: int
1753: pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
1754: struct pf_addr *b, sa_family_t af)
1755: {
1756: int match = 0;
1757:
1758: switch (af) {
1759: #ifdef INET
1760: case AF_INET:
1761: if ((a->addr32[0] & m->addr32[0]) ==
1762: (b->addr32[0] & m->addr32[0]))
1763: match++;
1764: break;
1765: #endif /* INET */
1766: #ifdef INET6
1767: case AF_INET6:
1768: if (((a->addr32[0] & m->addr32[0]) ==
1769: (b->addr32[0] & m->addr32[0])) &&
1770: ((a->addr32[1] & m->addr32[1]) ==
1771: (b->addr32[1] & m->addr32[1])) &&
1772: ((a->addr32[2] & m->addr32[2]) ==
1773: (b->addr32[2] & m->addr32[2])) &&
1774: ((a->addr32[3] & m->addr32[3]) ==
1775: (b->addr32[3] & m->addr32[3])))
1776: match++;
1777: break;
1778: #endif /* INET6 */
1779: }
1780: if (match) {
1781: if (n)
1782: return (0);
1783: else
1784: return (1);
1785: } else {
1786: if (n)
1787: return (1);
1788: else
1789: return (0);
1790: }
1791: }
1792:
1793: int
1794: pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
1795: {
1796: switch (op) {
1797: case PF_OP_IRG:
1798: return ((p > a1) && (p < a2));
1799: case PF_OP_XRG:
1800: return ((p < a1) || (p > a2));
1801: case PF_OP_RRG:
1802: return ((p >= a1) && (p <= a2));
1803: case PF_OP_EQ:
1804: return (p == a1);
1805: case PF_OP_NE:
1806: return (p != a1);
1807: case PF_OP_LT:
1808: return (p < a1);
1809: case PF_OP_LE:
1810: return (p <= a1);
1811: case PF_OP_GT:
1812: return (p > a1);
1813: case PF_OP_GE:
1814: return (p >= a1);
1815: }
1816: return (0); /* never reached */
1817: }
1818:
1819: int
1820: pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
1821: {
1822: NTOHS(a1);
1823: NTOHS(a2);
1824: NTOHS(p);
1825: return (pf_match(op, a1, a2, p));
1826: }
1827:
1828: int
1829: pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
1830: {
1831: if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1832: return (0);
1833: return (pf_match(op, a1, a2, u));
1834: }
1835:
1836: int
1837: pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
1838: {
1839: if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
1840: return (0);
1841: return (pf_match(op, a1, a2, g));
1842: }
1843:
1844: int
1845: pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag)
1846: {
1847: if (*tag == -1)
1848: *tag = m->m_pkthdr.pf.tag;
1849:
1850: return ((!r->match_tag_not && r->match_tag == *tag) ||
1851: (r->match_tag_not && r->match_tag != *tag));
1852: }
1853:
1854: int
1855: pf_tag_packet(struct mbuf *m, int tag, int rtableid)
1856: {
1857: if (tag <= 0 && rtableid < 0)
1858: return (0);
1859:
1860: if (tag > 0)
1861: m->m_pkthdr.pf.tag = tag;
1862: if (rtableid >= 0)
1863: m->m_pkthdr.pf.rtableid = rtableid;
1864:
1865: return (0);
1866: }
1867:
1868: void
1869: pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
1870: struct pf_rule **r, struct pf_rule **a, int *match)
1871: {
1872: struct pf_anchor_stackframe *f;
1873:
1874: (*r)->anchor->match = 0;
1875: if (match)
1876: *match = 0;
1877: if (*depth >= sizeof(pf_anchor_stack) /
1878: sizeof(pf_anchor_stack[0])) {
1879: printf("pf_step_into_anchor: stack overflow\n");
1880: *r = TAILQ_NEXT(*r, entries);
1881: return;
1882: } else if (*depth == 0 && a != NULL)
1883: *a = *r;
1884: f = pf_anchor_stack + (*depth)++;
1885: f->rs = *rs;
1886: f->r = *r;
1887: if ((*r)->anchor_wildcard) {
1888: f->parent = &(*r)->anchor->children;
1889: if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
1890: NULL) {
1891: *r = NULL;
1892: return;
1893: }
1894: *rs = &f->child->ruleset;
1895: } else {
1896: f->parent = NULL;
1897: f->child = NULL;
1898: *rs = &(*r)->anchor->ruleset;
1899: }
1900: *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
1901: }
1902:
1903: int
1904: pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
1905: struct pf_rule **r, struct pf_rule **a, int *match)
1906: {
1907: struct pf_anchor_stackframe *f;
1908: int quick = 0;
1909:
1910: do {
1911: if (*depth <= 0)
1912: break;
1913: f = pf_anchor_stack + *depth - 1;
1914: if (f->parent != NULL && f->child != NULL) {
1915: if (f->child->match ||
1916: (match != NULL && *match)) {
1917: f->r->anchor->match = 1;
1918: *match = 0;
1919: }
1920: f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
1921: if (f->child != NULL) {
1922: *rs = &f->child->ruleset;
1923: *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
1924: if (*r == NULL)
1925: continue;
1926: else
1927: break;
1928: }
1929: }
1930: (*depth)--;
1931: if (*depth == 0 && a != NULL)
1932: *a = NULL;
1933: *rs = f->rs;
1934: if (f->r->anchor->match || (match != NULL && *match))
1935: quick = f->r->quick;
1936: *r = TAILQ_NEXT(f->r, entries);
1937: } while (*r == NULL);
1938:
1939: return (quick);
1940: }
1941:
1942: #ifdef INET6
1943: void
1944: pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
1945: struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
1946: {
1947: switch (af) {
1948: #ifdef INET
1949: case AF_INET:
1950: naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
1951: ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
1952: break;
1953: #endif /* INET */
1954: case AF_INET6:
1955: naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
1956: ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
1957: naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
1958: ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
1959: naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
1960: ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
1961: naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
1962: ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
1963: break;
1964: }
1965: }
1966:
1967: void
1968: pf_addr_inc(struct pf_addr *addr, sa_family_t af)
1969: {
1970: switch (af) {
1971: #ifdef INET
1972: case AF_INET:
1973: addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
1974: break;
1975: #endif /* INET */
1976: case AF_INET6:
1977: if (addr->addr32[3] == 0xffffffff) {
1978: addr->addr32[3] = 0;
1979: if (addr->addr32[2] == 0xffffffff) {
1980: addr->addr32[2] = 0;
1981: if (addr->addr32[1] == 0xffffffff) {
1982: addr->addr32[1] = 0;
1983: addr->addr32[0] =
1984: htonl(ntohl(addr->addr32[0]) + 1);
1985: } else
1986: addr->addr32[1] =
1987: htonl(ntohl(addr->addr32[1]) + 1);
1988: } else
1989: addr->addr32[2] =
1990: htonl(ntohl(addr->addr32[2]) + 1);
1991: } else
1992: addr->addr32[3] =
1993: htonl(ntohl(addr->addr32[3]) + 1);
1994: break;
1995: }
1996: }
1997: #endif /* INET6 */
1998:
1999: #define mix(a,b,c) \
2000: do { \
2001: a -= b; a -= c; a ^= (c >> 13); \
2002: b -= c; b -= a; b ^= (a << 8); \
2003: c -= a; c -= b; c ^= (b >> 13); \
2004: a -= b; a -= c; a ^= (c >> 12); \
2005: b -= c; b -= a; b ^= (a << 16); \
2006: c -= a; c -= b; c ^= (b >> 5); \
2007: a -= b; a -= c; a ^= (c >> 3); \
2008: b -= c; b -= a; b ^= (a << 10); \
2009: c -= a; c -= b; c ^= (b >> 15); \
2010: } while (0)
2011:
2012: /*
2013: * hash function based on bridge_hash in if_bridge.c
2014: */
2015: void
2016: pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
2017: struct pf_poolhashkey *key, sa_family_t af)
2018: {
2019: u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
2020:
2021: switch (af) {
2022: #ifdef INET
2023: case AF_INET:
2024: a += inaddr->addr32[0];
2025: b += key->key32[1];
2026: mix(a, b, c);
2027: hash->addr32[0] = c + key->key32[2];
2028: break;
2029: #endif /* INET */
2030: #ifdef INET6
2031: case AF_INET6:
2032: a += inaddr->addr32[0];
2033: b += inaddr->addr32[2];
2034: mix(a, b, c);
2035: hash->addr32[0] = c;
2036: a += inaddr->addr32[1];
2037: b += inaddr->addr32[3];
2038: c += key->key32[1];
2039: mix(a, b, c);
2040: hash->addr32[1] = c;
2041: a += inaddr->addr32[2];
2042: b += inaddr->addr32[1];
2043: c += key->key32[2];
2044: mix(a, b, c);
2045: hash->addr32[2] = c;
2046: a += inaddr->addr32[3];
2047: b += inaddr->addr32[0];
2048: c += key->key32[3];
2049: mix(a, b, c);
2050: hash->addr32[3] = c;
2051: break;
2052: #endif /* INET6 */
2053: }
2054: }
2055:
2056: int
2057: pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
2058: struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
2059: {
2060: unsigned char hash[16];
2061: struct pf_pool *rpool = &r->rpool;
2062: struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
2063: struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
2064: struct pf_pooladdr *acur = rpool->cur;
2065: struct pf_src_node k;
2066:
2067: if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
2068: (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2069: k.af = af;
2070: PF_ACPY(&k.addr, saddr, af);
2071: if (r->rule_flag & PFRULE_RULESRCTRACK ||
2072: r->rpool.opts & PF_POOL_STICKYADDR)
2073: k.rule.ptr = r;
2074: else
2075: k.rule.ptr = NULL;
2076: pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
2077: *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
2078: if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
2079: PF_ACPY(naddr, &(*sn)->raddr, af);
2080: if (pf_status.debug >= PF_DEBUG_MISC) {
2081: printf("pf_map_addr: src tracking maps ");
2082: pf_print_host(&k.addr, 0, af);
2083: printf(" to ");
2084: pf_print_host(naddr, 0, af);
2085: printf("\n");
2086: }
2087: return (0);
2088: }
2089: }
2090:
2091: if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
2092: return (1);
2093: if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2094: switch (af) {
2095: #ifdef INET
2096: case AF_INET:
2097: if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
2098: (rpool->opts & PF_POOL_TYPEMASK) !=
2099: PF_POOL_ROUNDROBIN)
2100: return (1);
2101: raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
2102: rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
2103: break;
2104: #endif /* INET */
2105: #ifdef INET6
2106: case AF_INET6:
2107: if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
2108: (rpool->opts & PF_POOL_TYPEMASK) !=
2109: PF_POOL_ROUNDROBIN)
2110: return (1);
2111: raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
2112: rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
2113: break;
2114: #endif /* INET6 */
2115: }
2116: } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2117: if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
2118: return (1); /* unsupported */
2119: } else {
2120: raddr = &rpool->cur->addr.v.a.addr;
2121: rmask = &rpool->cur->addr.v.a.mask;
2122: }
2123:
2124: switch (rpool->opts & PF_POOL_TYPEMASK) {
2125: case PF_POOL_NONE:
2126: PF_ACPY(naddr, raddr, af);
2127: break;
2128: case PF_POOL_BITMASK:
2129: PF_POOLMASK(naddr, raddr, rmask, saddr, af);
2130: break;
2131: case PF_POOL_RANDOM:
2132: if (init_addr != NULL && PF_AZERO(init_addr, af)) {
2133: switch (af) {
2134: #ifdef INET
2135: case AF_INET:
2136: rpool->counter.addr32[0] = htonl(arc4random());
2137: break;
2138: #endif /* INET */
2139: #ifdef INET6
2140: case AF_INET6:
2141: if (rmask->addr32[3] != 0xffffffff)
2142: rpool->counter.addr32[3] =
2143: htonl(arc4random());
2144: else
2145: break;
2146: if (rmask->addr32[2] != 0xffffffff)
2147: rpool->counter.addr32[2] =
2148: htonl(arc4random());
2149: else
2150: break;
2151: if (rmask->addr32[1] != 0xffffffff)
2152: rpool->counter.addr32[1] =
2153: htonl(arc4random());
2154: else
2155: break;
2156: if (rmask->addr32[0] != 0xffffffff)
2157: rpool->counter.addr32[0] =
2158: htonl(arc4random());
2159: break;
2160: #endif /* INET6 */
2161: }
2162: PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2163: PF_ACPY(init_addr, naddr, af);
2164:
2165: } else {
2166: PF_AINC(&rpool->counter, af);
2167: PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
2168: }
2169: break;
2170: case PF_POOL_SRCHASH:
2171: pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
2172: PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
2173: break;
2174: case PF_POOL_ROUNDROBIN:
2175: if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2176: if (!pfr_pool_get(rpool->cur->addr.p.tbl,
2177: &rpool->tblidx, &rpool->counter,
2178: &raddr, &rmask, af))
2179: goto get_addr;
2180: } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2181: if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2182: &rpool->tblidx, &rpool->counter,
2183: &raddr, &rmask, af))
2184: goto get_addr;
2185: } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
2186: goto get_addr;
2187:
2188: try_next:
2189: if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
2190: rpool->cur = TAILQ_FIRST(&rpool->list);
2191: if (rpool->cur->addr.type == PF_ADDR_TABLE) {
2192: rpool->tblidx = -1;
2193: if (pfr_pool_get(rpool->cur->addr.p.tbl,
2194: &rpool->tblidx, &rpool->counter,
2195: &raddr, &rmask, af)) {
2196: /* table contains no address of type 'af' */
2197: if (rpool->cur != acur)
2198: goto try_next;
2199: return (1);
2200: }
2201: } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
2202: rpool->tblidx = -1;
2203: if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
2204: &rpool->tblidx, &rpool->counter,
2205: &raddr, &rmask, af)) {
2206: /* table contains no address of type 'af' */
2207: if (rpool->cur != acur)
2208: goto try_next;
2209: return (1);
2210: }
2211: } else {
2212: raddr = &rpool->cur->addr.v.a.addr;
2213: rmask = &rpool->cur->addr.v.a.mask;
2214: PF_ACPY(&rpool->counter, raddr, af);
2215: }
2216:
2217: get_addr:
2218: PF_ACPY(naddr, &rpool->counter, af);
2219: if (init_addr != NULL && PF_AZERO(init_addr, af))
2220: PF_ACPY(init_addr, naddr, af);
2221: PF_AINC(&rpool->counter, af);
2222: break;
2223: }
2224: if (*sn != NULL)
2225: PF_ACPY(&(*sn)->raddr, naddr, af);
2226:
2227: if (pf_status.debug >= PF_DEBUG_MISC &&
2228: (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
2229: printf("pf_map_addr: selected address ");
2230: pf_print_host(naddr, 0, af);
2231: printf("\n");
2232: }
2233:
2234: return (0);
2235: }
2236:
2237: int
2238: pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
2239: struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
2240: struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
2241: struct pf_src_node **sn)
2242: {
2243: struct pf_state_key_cmp key;
2244: struct pf_addr init_addr;
2245: u_int16_t cut;
2246:
2247: bzero(&init_addr, sizeof(init_addr));
2248: if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2249: return (1);
2250:
2251: if (proto == IPPROTO_ICMP) {
2252: low = 1;
2253: high = 65535;
2254: }
2255:
2256: do {
2257: key.af = af;
2258: key.proto = proto;
2259: PF_ACPY(&key.ext.addr, daddr, key.af);
2260: PF_ACPY(&key.gwy.addr, naddr, key.af);
2261: key.ext.port = dport;
2262:
2263: /*
2264: * port search; start random, step;
2265: * similar 2 portloop in in_pcbbind
2266: */
2267: if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
2268: proto == IPPROTO_ICMP)) {
2269: key.gwy.port = dport;
2270: if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2271: return (0);
2272: } else if (low == 0 && high == 0) {
2273: key.gwy.port = *nport;
2274: if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
2275: return (0);
2276: } else if (low == high) {
2277: key.gwy.port = htons(low);
2278: if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
2279: *nport = htons(low);
2280: return (0);
2281: }
2282: } else {
2283: u_int16_t tmp;
2284:
2285: if (low > high) {
2286: tmp = low;
2287: low = high;
2288: high = tmp;
2289: }
2290: /* low < high */
2291: cut = htonl(arc4random()) % (1 + high - low) + low;
2292: /* low <= cut <= high */
2293: for (tmp = cut; tmp <= high; ++(tmp)) {
2294: key.gwy.port = htons(tmp);
2295: if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2296: NULL) {
2297: *nport = htons(tmp);
2298: return (0);
2299: }
2300: }
2301: for (tmp = cut - 1; tmp >= low; --(tmp)) {
2302: key.gwy.port = htons(tmp);
2303: if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
2304: NULL) {
2305: *nport = htons(tmp);
2306: return (0);
2307: }
2308: }
2309: }
2310:
2311: switch (r->rpool.opts & PF_POOL_TYPEMASK) {
2312: case PF_POOL_RANDOM:
2313: case PF_POOL_ROUNDROBIN:
2314: if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
2315: return (1);
2316: break;
2317: case PF_POOL_NONE:
2318: case PF_POOL_SRCHASH:
2319: case PF_POOL_BITMASK:
2320: default:
2321: return (1);
2322: }
2323: } while (! PF_AEQ(&init_addr, naddr, af) );
2324:
2325: return (1); /* none available */
2326: }
2327:
2328: struct pf_rule *
2329: pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
2330: int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
2331: struct pf_addr *daddr, u_int16_t dport, int rs_num)
2332: {
2333: struct pf_rule *r, *rm = NULL;
2334: struct pf_ruleset *ruleset = NULL;
2335: int tag = -1;
2336: int rtableid = -1;
2337: int asd = 0;
2338:
2339: r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
2340: while (r && rm == NULL) {
2341: struct pf_rule_addr *src = NULL, *dst = NULL;
2342: struct pf_addr_wrap *xdst = NULL;
2343:
2344: if (r->action == PF_BINAT && direction == PF_IN) {
2345: src = &r->dst;
2346: if (r->rpool.cur != NULL)
2347: xdst = &r->rpool.cur->addr;
2348: } else {
2349: src = &r->src;
2350: dst = &r->dst;
2351: }
2352:
2353: r->evaluations++;
2354: if (pfi_kif_match(r->kif, kif) == r->ifnot)
2355: r = r->skip[PF_SKIP_IFP].ptr;
2356: else if (r->direction && r->direction != direction)
2357: r = r->skip[PF_SKIP_DIR].ptr;
2358: else if (r->af && r->af != pd->af)
2359: r = r->skip[PF_SKIP_AF].ptr;
2360: else if (r->proto && r->proto != pd->proto)
2361: r = r->skip[PF_SKIP_PROTO].ptr;
2362: else if (PF_MISMATCHAW(&src->addr, saddr, pd->af,
2363: src->neg, kif))
2364: r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
2365: PF_SKIP_DST_ADDR].ptr;
2366: else if (src->port_op && !pf_match_port(src->port_op,
2367: src->port[0], src->port[1], sport))
2368: r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
2369: PF_SKIP_DST_PORT].ptr;
2370: else if (dst != NULL &&
2371: PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL))
2372: r = r->skip[PF_SKIP_DST_ADDR].ptr;
2373: else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
2374: 0, NULL))
2375: r = TAILQ_NEXT(r, entries);
2376: else if (dst != NULL && dst->port_op &&
2377: !pf_match_port(dst->port_op, dst->port[0],
2378: dst->port[1], dport))
2379: r = r->skip[PF_SKIP_DST_PORT].ptr;
2380: else if (r->match_tag && !pf_match_tag(m, r, &tag))
2381: r = TAILQ_NEXT(r, entries);
2382: else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
2383: IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
2384: off, pd->hdr.tcp), r->os_fingerprint)))
2385: r = TAILQ_NEXT(r, entries);
2386: else {
2387: if (r->tag)
2388: tag = r->tag;
2389: if (r->rtableid >= 0)
2390: rtableid = r->rtableid;
2391: if (r->anchor == NULL) {
2392: rm = r;
2393: } else
2394: pf_step_into_anchor(&asd, &ruleset, rs_num,
2395: &r, NULL, NULL);
2396: }
2397: if (r == NULL)
2398: pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
2399: NULL, NULL);
2400: }
2401: if (pf_tag_packet(m, tag, rtableid))
2402: return (NULL);
2403: if (rm != NULL && (rm->action == PF_NONAT ||
2404: rm->action == PF_NORDR || rm->action == PF_NOBINAT))
2405: return (NULL);
2406: return (rm);
2407: }
2408:
2409: struct pf_rule *
2410: pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
2411: struct pfi_kif *kif, struct pf_src_node **sn,
2412: struct pf_addr *saddr, u_int16_t sport,
2413: struct pf_addr *daddr, u_int16_t dport,
2414: struct pf_addr *naddr, u_int16_t *nport)
2415: {
2416: struct pf_rule *r = NULL;
2417:
2418: if (direction == PF_OUT) {
2419: r = pf_match_translation(pd, m, off, direction, kif, saddr,
2420: sport, daddr, dport, PF_RULESET_BINAT);
2421: if (r == NULL)
2422: r = pf_match_translation(pd, m, off, direction, kif,
2423: saddr, sport, daddr, dport, PF_RULESET_NAT);
2424: } else {
2425: r = pf_match_translation(pd, m, off, direction, kif, saddr,
2426: sport, daddr, dport, PF_RULESET_RDR);
2427: if (r == NULL)
2428: r = pf_match_translation(pd, m, off, direction, kif,
2429: saddr, sport, daddr, dport, PF_RULESET_BINAT);
2430: }
2431:
2432: if (r != NULL) {
2433: switch (r->action) {
2434: case PF_NONAT:
2435: case PF_NOBINAT:
2436: case PF_NORDR:
2437: return (NULL);
2438: case PF_NAT:
2439: if (pf_get_sport(pd->af, pd->proto, r, saddr,
2440: daddr, dport, naddr, nport, r->rpool.proxy_port[0],
2441: r->rpool.proxy_port[1], sn)) {
2442: DPFPRINTF(PF_DEBUG_MISC,
2443: ("pf: NAT proxy port allocation "
2444: "(%u-%u) failed\n",
2445: r->rpool.proxy_port[0],
2446: r->rpool.proxy_port[1]));
2447: return (NULL);
2448: }
2449: break;
2450: case PF_BINAT:
2451: switch (direction) {
2452: case PF_OUT:
2453: if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
2454: switch (pd->af) {
2455: #ifdef INET
2456: case AF_INET:
2457: if (r->rpool.cur->addr.p.dyn->
2458: pfid_acnt4 < 1)
2459: return (NULL);
2460: PF_POOLMASK(naddr,
2461: &r->rpool.cur->addr.p.dyn->
2462: pfid_addr4,
2463: &r->rpool.cur->addr.p.dyn->
2464: pfid_mask4,
2465: saddr, AF_INET);
2466: break;
2467: #endif /* INET */
2468: #ifdef INET6
2469: case AF_INET6:
2470: if (r->rpool.cur->addr.p.dyn->
2471: pfid_acnt6 < 1)
2472: return (NULL);
2473: PF_POOLMASK(naddr,
2474: &r->rpool.cur->addr.p.dyn->
2475: pfid_addr6,
2476: &r->rpool.cur->addr.p.dyn->
2477: pfid_mask6,
2478: saddr, AF_INET6);
2479: break;
2480: #endif /* INET6 */
2481: }
2482: } else
2483: PF_POOLMASK(naddr,
2484: &r->rpool.cur->addr.v.a.addr,
2485: &r->rpool.cur->addr.v.a.mask,
2486: saddr, pd->af);
2487: break;
2488: case PF_IN:
2489: if (r->src.addr.type == PF_ADDR_DYNIFTL) {
2490: switch (pd->af) {
2491: #ifdef INET
2492: case AF_INET:
2493: if (r->src.addr.p.dyn->
2494: pfid_acnt4 < 1)
2495: return (NULL);
2496: PF_POOLMASK(naddr,
2497: &r->src.addr.p.dyn->
2498: pfid_addr4,
2499: &r->src.addr.p.dyn->
2500: pfid_mask4,
2501: daddr, AF_INET);
2502: break;
2503: #endif /* INET */
2504: #ifdef INET6
2505: case AF_INET6:
2506: if (r->src.addr.p.dyn->
2507: pfid_acnt6 < 1)
2508: return (NULL);
2509: PF_POOLMASK(naddr,
2510: &r->src.addr.p.dyn->
2511: pfid_addr6,
2512: &r->src.addr.p.dyn->
2513: pfid_mask6,
2514: daddr, AF_INET6);
2515: break;
2516: #endif /* INET6 */
2517: }
2518: } else
2519: PF_POOLMASK(naddr,
2520: &r->src.addr.v.a.addr,
2521: &r->src.addr.v.a.mask, daddr,
2522: pd->af);
2523: break;
2524: }
2525: break;
2526: case PF_RDR: {
2527: if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
2528: return (NULL);
2529: if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
2530: PF_POOL_BITMASK)
2531: PF_POOLMASK(naddr, naddr,
2532: &r->rpool.cur->addr.v.a.mask, daddr,
2533: pd->af);
2534:
2535: if (r->rpool.proxy_port[1]) {
2536: u_int32_t tmp_nport;
2537:
2538: tmp_nport = ((ntohs(dport) -
2539: ntohs(r->dst.port[0])) %
2540: (r->rpool.proxy_port[1] -
2541: r->rpool.proxy_port[0] + 1)) +
2542: r->rpool.proxy_port[0];
2543:
2544: /* wrap around if necessary */
2545: if (tmp_nport > 65535)
2546: tmp_nport -= 65535;
2547: *nport = htons((u_int16_t)tmp_nport);
2548: } else if (r->rpool.proxy_port[0])
2549: *nport = htons(r->rpool.proxy_port[0]);
2550: break;
2551: }
2552: default:
2553: return (NULL);
2554: }
2555: }
2556:
2557: return (r);
2558: }
2559:
2560: int
2561: pf_socket_lookup(int direction, struct pf_pdesc *pd)
2562: {
2563: struct pf_addr *saddr, *daddr;
2564: u_int16_t sport, dport;
2565: struct inpcbtable *tb;
2566: struct inpcb *inp;
2567:
2568: if (pd == NULL)
2569: return (-1);
2570: pd->lookup.uid = UID_MAX;
2571: pd->lookup.gid = GID_MAX;
2572: pd->lookup.pid = NO_PID;
2573: switch (pd->proto) {
2574: case IPPROTO_TCP:
2575: if (pd->hdr.tcp == NULL)
2576: return (-1);
2577: sport = pd->hdr.tcp->th_sport;
2578: dport = pd->hdr.tcp->th_dport;
2579: tb = &tcbtable;
2580: break;
2581: case IPPROTO_UDP:
2582: if (pd->hdr.udp == NULL)
2583: return (-1);
2584: sport = pd->hdr.udp->uh_sport;
2585: dport = pd->hdr.udp->uh_dport;
2586: tb = &udbtable;
2587: break;
2588: default:
2589: return (-1);
2590: }
2591: if (direction == PF_IN) {
2592: saddr = pd->src;
2593: daddr = pd->dst;
2594: } else {
2595: u_int16_t p;
2596:
2597: p = sport;
2598: sport = dport;
2599: dport = p;
2600: saddr = pd->dst;
2601: daddr = pd->src;
2602: }
2603: switch (pd->af) {
2604: #ifdef INET
2605: case AF_INET:
2606: inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
2607: if (inp == NULL) {
2608: inp = in_pcblookup_listen(tb, daddr->v4, dport, 0);
2609: if (inp == NULL)
2610: return (-1);
2611: }
2612: break;
2613: #endif /* INET */
2614: #ifdef INET6
2615: case AF_INET6:
2616: inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
2617: dport);
2618: if (inp == NULL) {
2619: inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0);
2620: if (inp == NULL)
2621: return (-1);
2622: }
2623: break;
2624: #endif /* INET6 */
2625:
2626: default:
2627: return (-1);
2628: }
2629: pd->lookup.uid = inp->inp_socket->so_euid;
2630: pd->lookup.gid = inp->inp_socket->so_egid;
2631: pd->lookup.pid = inp->inp_socket->so_cpid;
2632: return (1);
2633: }
2634:
2635: u_int8_t
2636: pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2637: {
2638: int hlen;
2639: u_int8_t hdr[60];
2640: u_int8_t *opt, optlen;
2641: u_int8_t wscale = 0;
2642:
2643: hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2644: if (hlen <= sizeof(struct tcphdr))
2645: return (0);
2646: if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2647: return (0);
2648: opt = hdr + sizeof(struct tcphdr);
2649: hlen -= sizeof(struct tcphdr);
2650: while (hlen >= 3) {
2651: switch (*opt) {
2652: case TCPOPT_EOL:
2653: case TCPOPT_NOP:
2654: ++opt;
2655: --hlen;
2656: break;
2657: case TCPOPT_WINDOW:
2658: wscale = opt[2];
2659: if (wscale > TCP_MAX_WINSHIFT)
2660: wscale = TCP_MAX_WINSHIFT;
2661: wscale |= PF_WSCALE_FLAG;
2662: /* FALLTHROUGH */
2663: default:
2664: optlen = opt[1];
2665: if (optlen < 2)
2666: optlen = 2;
2667: hlen -= optlen;
2668: opt += optlen;
2669: break;
2670: }
2671: }
2672: return (wscale);
2673: }
2674:
2675: u_int16_t
2676: pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
2677: {
2678: int hlen;
2679: u_int8_t hdr[60];
2680: u_int8_t *opt, optlen;
2681: u_int16_t mss = tcp_mssdflt;
2682:
2683: hlen = th_off << 2; /* hlen <= sizeof(hdr) */
2684: if (hlen <= sizeof(struct tcphdr))
2685: return (0);
2686: if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
2687: return (0);
2688: opt = hdr + sizeof(struct tcphdr);
2689: hlen -= sizeof(struct tcphdr);
2690: while (hlen >= TCPOLEN_MAXSEG) {
2691: switch (*opt) {
2692: case TCPOPT_EOL:
2693: case TCPOPT_NOP:
2694: ++opt;
2695: --hlen;
2696: break;
2697: case TCPOPT_MAXSEG:
2698: bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
2699: NTOHS(mss);
2700: /* FALLTHROUGH */
2701: default:
2702: optlen = opt[1];
2703: if (optlen < 2)
2704: optlen = 2;
2705: hlen -= optlen;
2706: opt += optlen;
2707: break;
2708: }
2709: }
2710: return (mss);
2711: }
2712:
2713: u_int16_t
2714: pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
2715: {
2716: #ifdef INET
2717: struct sockaddr_in *dst;
2718: struct route ro;
2719: #endif /* INET */
2720: #ifdef INET6
2721: struct sockaddr_in6 *dst6;
2722: struct route_in6 ro6;
2723: #endif /* INET6 */
2724: struct rtentry *rt = NULL;
2725: int hlen;
2726: u_int16_t mss = tcp_mssdflt;
2727:
2728: switch (af) {
2729: #ifdef INET
2730: case AF_INET:
2731: hlen = sizeof(struct ip);
2732: bzero(&ro, sizeof(ro));
2733: dst = (struct sockaddr_in *)&ro.ro_dst;
2734: dst->sin_family = AF_INET;
2735: dst->sin_len = sizeof(*dst);
2736: dst->sin_addr = addr->v4;
2737: rtalloc_noclone(&ro, NO_CLONING);
2738: rt = ro.ro_rt;
2739: break;
2740: #endif /* INET */
2741: #ifdef INET6
2742: case AF_INET6:
2743: hlen = sizeof(struct ip6_hdr);
2744: bzero(&ro6, sizeof(ro6));
2745: dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
2746: dst6->sin6_family = AF_INET6;
2747: dst6->sin6_len = sizeof(*dst6);
2748: dst6->sin6_addr = addr->v6;
2749: rtalloc_noclone((struct route *)&ro6, NO_CLONING);
2750: rt = ro6.ro_rt;
2751: break;
2752: #endif /* INET6 */
2753: }
2754:
2755: if (rt && rt->rt_ifp) {
2756: mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
2757: mss = max(tcp_mssdflt, mss);
2758: RTFREE(rt);
2759: }
2760: mss = min(mss, offer);
2761: mss = max(mss, 64); /* sanity - at least max opt space */
2762: return (mss);
2763: }
2764:
2765: void
2766: pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
2767: {
2768: struct pf_rule *r = s->rule.ptr;
2769:
2770: s->rt_kif = NULL;
2771: if (!r->rt || r->rt == PF_FASTROUTE)
2772: return;
2773: switch (s->state_key->af) {
2774: #ifdef INET
2775: case AF_INET:
2776: pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL,
2777: &s->nat_src_node);
2778: s->rt_kif = r->rpool.cur->kif;
2779: break;
2780: #endif /* INET */
2781: #ifdef INET6
2782: case AF_INET6:
2783: pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL,
2784: &s->nat_src_node);
2785: s->rt_kif = r->rpool.cur->kif;
2786: break;
2787: #endif /* INET6 */
2788: }
2789: }
2790:
2791: void
2792: pf_attach_state(struct pf_state_key *sk, struct pf_state *s, int tail)
2793: {
2794: s->state_key = sk;
2795: sk->refcnt++;
2796:
2797: /* list is sorted, if-bound states before floating */
2798: if (tail)
2799: TAILQ_INSERT_TAIL(&sk->states, s, next);
2800: else
2801: TAILQ_INSERT_HEAD(&sk->states, s, next);
2802: }
2803:
2804: void
2805: pf_detach_state(struct pf_state *s, int flags)
2806: {
2807: struct pf_state_key *sk = s->state_key;
2808:
2809: if (sk == NULL)
2810: return;
2811:
2812: s->state_key = NULL;
2813: TAILQ_REMOVE(&sk->states, s, next);
2814: if (--sk->refcnt == 0) {
2815: if (!(flags & PF_DT_SKIP_EXTGWY))
2816: RB_REMOVE(pf_state_tree_ext_gwy,
2817: &pf_statetbl_ext_gwy, sk);
2818: if (!(flags & PF_DT_SKIP_LANEXT))
2819: RB_REMOVE(pf_state_tree_lan_ext,
2820: &pf_statetbl_lan_ext, sk);
2821: pool_put(&pf_state_key_pl, sk);
2822: }
2823: }
2824:
2825: struct pf_state_key *
2826: pf_alloc_state_key(struct pf_state *s)
2827: {
2828: struct pf_state_key *sk;
2829:
2830: if ((sk = pool_get(&pf_state_key_pl, PR_NOWAIT)) == NULL)
2831: return (NULL);
2832: bzero(sk, sizeof(*sk));
2833: TAILQ_INIT(&sk->states);
2834: pf_attach_state(sk, s, 0);
2835:
2836: return (sk);
2837: }
2838:
2839: int
2840: pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
2841: struct pfi_kif *kif, struct mbuf *m, int off, void *h,
2842: struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
2843: struct ifqueue *ifq)
2844: {
2845: struct pf_rule *nr = NULL;
2846: struct pf_addr *saddr = pd->src, *daddr = pd->dst;
2847: u_int16_t bport, nport = 0;
2848: sa_family_t af = pd->af;
2849: struct pf_rule *r, *a = NULL;
2850: struct pf_ruleset *ruleset = NULL;
2851: struct pf_src_node *nsn = NULL;
2852: struct tcphdr *th = pd->hdr.tcp;
2853: u_short reason;
2854: int rewrite = 0, hdrlen = 0;
2855: int tag = -1, rtableid = -1;
2856: int asd = 0;
2857: int match = 0;
2858: int state_icmp = 0;
2859: u_int16_t mss = tcp_mssdflt;
2860: u_int16_t sport, dport;
2861: u_int8_t icmptype = 0, icmpcode = 0;
2862:
2863: if (direction == PF_IN && pf_check_congestion(ifq)) {
2864: REASON_SET(&reason, PFRES_CONGEST);
2865: return (PF_DROP);
2866: }
2867:
2868: sport = dport = hdrlen = 0;
2869:
2870: switch (pd->proto) {
2871: case IPPROTO_TCP:
2872: sport = th->th_sport;
2873: dport = th->th_dport;
2874: hdrlen = sizeof(*th);
2875: break;
2876: case IPPROTO_UDP:
2877: sport = pd->hdr.udp->uh_sport;
2878: dport = pd->hdr.udp->uh_dport;
2879: hdrlen = sizeof(*pd->hdr.udp);
2880: break;
2881: #ifdef INET
2882: case IPPROTO_ICMP:
2883: if (pd->af != AF_INET)
2884: break;
2885: sport = dport = pd->hdr.icmp->icmp_id;
2886: icmptype = pd->hdr.icmp->icmp_type;
2887: icmpcode = pd->hdr.icmp->icmp_code;
2888:
2889: if (icmptype == ICMP_UNREACH ||
2890: icmptype == ICMP_SOURCEQUENCH ||
2891: icmptype == ICMP_REDIRECT ||
2892: icmptype == ICMP_TIMXCEED ||
2893: icmptype == ICMP_PARAMPROB)
2894: state_icmp++;
2895: break;
2896: #endif /* INET */
2897: #ifdef INET6
2898: case IPPROTO_ICMPV6:
2899: if (pd->af != AF_INET6)
2900: break;
2901: sport = dport = pd->hdr.icmp6->icmp6_id;
2902: hdrlen = sizeof(*pd->hdr.icmp6);
2903: icmptype = pd->hdr.icmp6->icmp6_type;
2904: icmpcode = pd->hdr.icmp6->icmp6_code;
2905:
2906: if (icmptype == ICMP6_DST_UNREACH ||
2907: icmptype == ICMP6_PACKET_TOO_BIG ||
2908: icmptype == ICMP6_TIME_EXCEEDED ||
2909: icmptype == ICMP6_PARAM_PROB)
2910: state_icmp++;
2911: break;
2912: #endif /* INET6 */
2913: }
2914:
2915: r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
2916:
2917: if (direction == PF_OUT) {
2918: bport = nport = sport;
2919: /* check outgoing packet for BINAT/NAT */
2920: if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
2921: saddr, sport, daddr, dport, &pd->naddr, &nport)) != NULL) {
2922: PF_ACPY(&pd->baddr, saddr, af);
2923: switch (pd->proto) {
2924: case IPPROTO_TCP:
2925: pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
2926: &th->th_sum, &pd->naddr, nport, 0, af);
2927: sport = th->th_sport;
2928: rewrite++;
2929: break;
2930: case IPPROTO_UDP:
2931: pf_change_ap(saddr, &pd->hdr.udp->uh_sport,
2932: pd->ip_sum, &pd->hdr.udp->uh_sum,
2933: &pd->naddr, nport, 1, af);
2934: sport = pd->hdr.udp->uh_sport;
2935: rewrite++;
2936: break;
2937: #ifdef INET
2938: case IPPROTO_ICMP:
2939: pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
2940: pd->naddr.v4.s_addr, 0);
2941: pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
2942: pd->hdr.icmp->icmp_cksum, sport, nport, 0);
2943: pd->hdr.icmp->icmp_id = nport;
2944: m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
2945: break;
2946: #endif /* INET */
2947: #ifdef INET6
2948: case IPPROTO_ICMPV6:
2949: pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
2950: &pd->naddr, 0);
2951: rewrite++;
2952: break;
2953: #endif /* INET */
2954: default:
2955: switch (af) {
2956: #ifdef INET
2957: case AF_INET:
2958: pf_change_a(&saddr->v4.s_addr,
2959: pd->ip_sum, pd->naddr.v4.s_addr, 0);
2960: break;
2961: #endif /* INET */
2962: #ifdef INET6
2963: case AF_INET6:
2964: PF_ACPY(saddr, &pd->naddr, af);
2965: break;
2966: #endif /* INET */
2967: }
2968: break;
2969: }
2970:
2971: if (nr->natpass)
2972: r = NULL;
2973: pd->nat_rule = nr;
2974: }
2975: } else {
2976: bport = nport = dport;
2977: /* check incoming packet for BINAT/RDR */
2978: if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
2979: saddr, sport, daddr, dport, &pd->naddr, &nport)) != NULL) {
2980: PF_ACPY(&pd->baddr, daddr, af);
2981: switch (pd->proto) {
2982: case IPPROTO_TCP:
2983: pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
2984: &th->th_sum, &pd->naddr, nport, 0, af);
2985: dport = th->th_dport;
2986: rewrite++;
2987: break;
2988: case IPPROTO_UDP:
2989: pf_change_ap(daddr, &pd->hdr.udp->uh_dport,
2990: pd->ip_sum, &pd->hdr.udp->uh_sum,
2991: &pd->naddr, nport, 1, af);
2992: dport = pd->hdr.udp->uh_dport;
2993: rewrite++;
2994: break;
2995: #ifdef INET
2996: case IPPROTO_ICMP:
2997: pf_change_a(&daddr->v4.s_addr, pd->ip_sum,
2998: pd->naddr.v4.s_addr, 0);
2999: break;
3000: #endif /* INET */
3001: #ifdef INET6
3002: case IPPROTO_ICMPV6:
3003: pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
3004: &pd->naddr, 0);
3005: rewrite++;
3006: break;
3007: #endif /* INET6 */
3008: default:
3009: switch (af) {
3010: #ifdef INET
3011: case AF_INET:
3012: pf_change_a(&daddr->v4.s_addr,
3013: pd->ip_sum, pd->naddr.v4.s_addr, 0);
3014: break;
3015: #endif /* INET */
3016: #ifdef INET6
3017: case AF_INET6:
3018: PF_ACPY(daddr, &pd->naddr, af);
3019: break;
3020: #endif /* INET */
3021: }
3022: break;
3023: }
3024:
3025: if (nr->natpass)
3026: r = NULL;
3027: pd->nat_rule = nr;
3028: }
3029: }
3030:
3031: while (r != NULL) {
3032: r->evaluations++;
3033: if (pfi_kif_match(r->kif, kif) == r->ifnot)
3034: r = r->skip[PF_SKIP_IFP].ptr;
3035: else if (r->direction && r->direction != direction)
3036: r = r->skip[PF_SKIP_DIR].ptr;
3037: else if (r->af && r->af != af)
3038: r = r->skip[PF_SKIP_AF].ptr;
3039: else if (r->proto && r->proto != pd->proto)
3040: r = r->skip[PF_SKIP_PROTO].ptr;
3041: else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
3042: r->src.neg, kif))
3043: r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3044: /* tcp/udp only. port_op always 0 in other cases */
3045: else if (r->src.port_op && !pf_match_port(r->src.port_op,
3046: r->src.port[0], r->src.port[1], sport))
3047: r = r->skip[PF_SKIP_SRC_PORT].ptr;
3048: else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
3049: r->dst.neg, NULL))
3050: r = r->skip[PF_SKIP_DST_ADDR].ptr;
3051: /* tcp/udp only. port_op always 0 in other cases */
3052: else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
3053: r->dst.port[0], r->dst.port[1], dport))
3054: r = r->skip[PF_SKIP_DST_PORT].ptr;
3055: /* icmp only. type always 0 in other cases */
3056: else if (r->type && r->type != icmptype + 1)
3057: r = TAILQ_NEXT(r, entries);
3058: /* icmp only. type always 0 in other cases */
3059: else if (r->code && r->code != icmpcode + 1)
3060: r = TAILQ_NEXT(r, entries);
3061: else if (r->tos && !(r->tos == pd->tos))
3062: r = TAILQ_NEXT(r, entries);
3063: else if (r->rule_flag & PFRULE_FRAGMENT)
3064: r = TAILQ_NEXT(r, entries);
3065: else if (pd->proto == IPPROTO_TCP &&
3066: (r->flagset & th->th_flags) != r->flags)
3067: r = TAILQ_NEXT(r, entries);
3068: /* tcp/udp only. uid.op always 0 in other cases */
3069: else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
3070: pf_socket_lookup(direction, pd), 1)) &&
3071: !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
3072: pd->lookup.uid))
3073: r = TAILQ_NEXT(r, entries);
3074: /* tcp/udp only. gid.op always 0 in other cases */
3075: else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
3076: pf_socket_lookup(direction, pd), 1)) &&
3077: !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
3078: pd->lookup.gid))
3079: r = TAILQ_NEXT(r, entries);
3080: else if (r->prob && r->prob <= arc4random())
3081: r = TAILQ_NEXT(r, entries);
3082: else if (r->match_tag && !pf_match_tag(m, r, &tag))
3083: r = TAILQ_NEXT(r, entries);
3084: else if (r->os_fingerprint != PF_OSFP_ANY &&
3085: (pd->proto != IPPROTO_TCP || !pf_osfp_match(
3086: pf_osfp_fingerprint(pd, m, off, th),
3087: r->os_fingerprint)))
3088: r = TAILQ_NEXT(r, entries);
3089: else {
3090: if (r->tag)
3091: tag = r->tag;
3092: if (r->rtableid >= 0)
3093: rtableid = r->rtableid;
3094: if (r->anchor == NULL) {
3095: match = 1;
3096: *rm = r;
3097: *am = a;
3098: *rsm = ruleset;
3099: if ((*rm)->quick)
3100: break;
3101: r = TAILQ_NEXT(r, entries);
3102: } else
3103: pf_step_into_anchor(&asd, &ruleset,
3104: PF_RULESET_FILTER, &r, &a, &match);
3105: }
3106: if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3107: PF_RULESET_FILTER, &r, &a, &match))
3108: break;
3109: }
3110: r = *rm;
3111: a = *am;
3112: ruleset = *rsm;
3113:
3114: REASON_SET(&reason, PFRES_MATCH);
3115:
3116: if (r->log || (nr != NULL && nr->log)) {
3117: if (rewrite)
3118: m_copyback(m, off, hdrlen, pd->hdr.any);
3119: PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
3120: a, ruleset, pd);
3121: }
3122:
3123: if ((r->action == PF_DROP) &&
3124: ((r->rule_flag & PFRULE_RETURNRST) ||
3125: (r->rule_flag & PFRULE_RETURNICMP) ||
3126: (r->rule_flag & PFRULE_RETURN))) {
3127: /* undo NAT changes, if they have taken place */
3128: if (nr != NULL) {
3129: if (direction == PF_OUT) {
3130: switch (pd->proto) {
3131: case IPPROTO_TCP:
3132: pf_change_ap(saddr, &th->th_sport,
3133: pd->ip_sum, &th->th_sum,
3134: &pd->baddr, bport, 0, af);
3135: sport = th->th_sport;
3136: rewrite++;
3137: break;
3138: case IPPROTO_UDP:
3139: pf_change_ap(saddr,
3140: &pd->hdr.udp->uh_sport, pd->ip_sum,
3141: &pd->hdr.udp->uh_sum, &pd->baddr,
3142: bport, 1, af);
3143: sport = pd->hdr.udp->uh_sport;
3144: rewrite++;
3145: break;
3146: case IPPROTO_ICMP:
3147: #ifdef INET6
3148: case IPPROTO_ICMPV6:
3149: #endif
3150: /* nothing! */
3151: break;
3152: default:
3153: switch (af) {
3154: case AF_INET:
3155: pf_change_a(&saddr->v4.s_addr,
3156: pd->ip_sum,
3157: pd->baddr.v4.s_addr, 0);
3158: break;
3159: case AF_INET6:
3160: PF_ACPY(saddr, &pd->baddr, af);
3161: break;
3162: }
3163: }
3164: } else {
3165: switch (pd->proto) {
3166: case IPPROTO_TCP:
3167: pf_change_ap(daddr, &th->th_dport,
3168: pd->ip_sum, &th->th_sum,
3169: &pd->baddr, bport, 0, af);
3170: dport = th->th_dport;
3171: rewrite++;
3172: break;
3173: case IPPROTO_UDP:
3174: pf_change_ap(daddr,
3175: &pd->hdr.udp->uh_dport, pd->ip_sum,
3176: &pd->hdr.udp->uh_sum, &pd->baddr,
3177: bport, 1, af);
3178: dport = pd->hdr.udp->uh_dport;
3179: rewrite++;
3180: break;
3181: case IPPROTO_ICMP:
3182: #ifdef INET6
3183: case IPPROTO_ICMPV6:
3184: #endif
3185: /* nothing! */
3186: break;
3187: default:
3188: switch (af) {
3189: case AF_INET:
3190: pf_change_a(&daddr->v4.s_addr,
3191: pd->ip_sum,
3192: pd->baddr.v4.s_addr, 0);
3193: break;
3194: case AF_INET6:
3195: PF_ACPY(daddr, &pd->baddr, af);
3196: break;
3197: }
3198: }
3199: }
3200: }
3201: if (pd->proto == IPPROTO_TCP &&
3202: ((r->rule_flag & PFRULE_RETURNRST) ||
3203: (r->rule_flag & PFRULE_RETURN)) &&
3204: !(th->th_flags & TH_RST)) {
3205: u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
3206: struct ip *h = mtod(m, struct ip *);
3207:
3208: if (pf_check_proto_cksum(m, off,
3209: ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET))
3210: REASON_SET(&reason, PFRES_PROTCKSUM);
3211: else {
3212: if (th->th_flags & TH_SYN)
3213: ack++;
3214: if (th->th_flags & TH_FIN)
3215: ack++;
3216: pf_send_tcp(r, af, pd->dst,
3217: pd->src, th->th_dport, th->th_sport,
3218: ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
3219: r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
3220: }
3221: } else if ((af == AF_INET) && r->return_icmp)
3222: pf_send_icmp(m, r->return_icmp >> 8,
3223: r->return_icmp & 255, af, r);
3224: else if ((af == AF_INET6) && r->return_icmp6)
3225: pf_send_icmp(m, r->return_icmp6 >> 8,
3226: r->return_icmp6 & 255, af, r);
3227: }
3228:
3229: if (r->action == PF_DROP)
3230: return (PF_DROP);
3231:
3232: if (pf_tag_packet(m, tag, rtableid)) {
3233: REASON_SET(&reason, PFRES_MEMORY);
3234: return (PF_DROP);
3235: }
3236:
3237: if (!state_icmp && (r->keep_state || nr != NULL ||
3238: (pd->flags & PFDESC_TCP_NORM))) {
3239: /* create new state */
3240: u_int16_t len;
3241: struct pf_state *s = NULL;
3242: struct pf_state_key *sk = NULL;
3243: struct pf_src_node *sn = NULL;
3244:
3245: /* check maximums */
3246: if (r->max_states && (r->states >= r->max_states)) {
3247: pf_status.lcounters[LCNT_STATES]++;
3248: REASON_SET(&reason, PFRES_MAXSTATES);
3249: goto cleanup;
3250: }
3251: /* src node for filter rule */
3252: if ((r->rule_flag & PFRULE_SRCTRACK ||
3253: r->rpool.opts & PF_POOL_STICKYADDR) &&
3254: pf_insert_src_node(&sn, r, saddr, af) != 0) {
3255: REASON_SET(&reason, PFRES_SRCLIMIT);
3256: goto cleanup;
3257: }
3258: /* src node for translation rule */
3259: if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
3260: ((direction == PF_OUT &&
3261: pf_insert_src_node(&nsn, nr, &pd->baddr, af) != 0) ||
3262: (pf_insert_src_node(&nsn, nr, saddr, af) != 0))) {
3263: REASON_SET(&reason, PFRES_SRCLIMIT);
3264: goto cleanup;
3265: }
3266: s = pool_get(&pf_state_pl, PR_NOWAIT);
3267: if (s == NULL) {
3268: REASON_SET(&reason, PFRES_MEMORY);
3269: cleanup:
3270: if (sn != NULL && sn->states == 0 && sn->expire == 0) {
3271: RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
3272: pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3273: pf_status.src_nodes--;
3274: pool_put(&pf_src_tree_pl, sn);
3275: }
3276: if (nsn != sn && nsn != NULL && nsn->states == 0 &&
3277: nsn->expire == 0) {
3278: RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
3279: pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
3280: pf_status.src_nodes--;
3281: pool_put(&pf_src_tree_pl, nsn);
3282: }
3283: if (sk != NULL) {
3284: pool_put(&pf_state_key_pl, sk);
3285: }
3286: return (PF_DROP);
3287: }
3288: bzero(s, sizeof(*s));
3289: s->rule.ptr = r;
3290: s->nat_rule.ptr = nr;
3291: s->anchor.ptr = a;
3292: STATE_INC_COUNTERS(s);
3293: s->allow_opts = r->allow_opts;
3294: s->log = r->log & PF_LOG_ALL;
3295: if (nr != NULL)
3296: s->log |= nr->log & PF_LOG_ALL;
3297: switch (pd->proto) {
3298: case IPPROTO_TCP:
3299: len = pd->tot_len - off - (th->th_off << 2);
3300: s->src.seqlo = ntohl(th->th_seq);
3301: s->src.seqhi = s->src.seqlo + len + 1;
3302: if ((th->th_flags & (TH_SYN|TH_ACK)) ==
3303: TH_SYN && r->keep_state == PF_STATE_MODULATE) {
3304: /* Generate sequence number modulator */
3305: while ((s->src.seqdiff =
3306: tcp_rndiss_next() - s->src.seqlo) == 0)
3307: ;
3308: pf_change_a(&th->th_seq, &th->th_sum,
3309: htonl(s->src.seqlo + s->src.seqdiff), 0);
3310: rewrite = 1;
3311: } else
3312: s->src.seqdiff = 0;
3313: if (th->th_flags & TH_SYN) {
3314: s->src.seqhi++;
3315: s->src.wscale = pf_get_wscale(m, off,
3316: th->th_off, af);
3317: }
3318: s->src.max_win = MAX(ntohs(th->th_win), 1);
3319: if (s->src.wscale & PF_WSCALE_MASK) {
3320: /* Remove scale factor from initial window */
3321: int win = s->src.max_win;
3322: win += 1 << (s->src.wscale & PF_WSCALE_MASK);
3323: s->src.max_win = (win - 1) >>
3324: (s->src.wscale & PF_WSCALE_MASK);
3325: }
3326: if (th->th_flags & TH_FIN)
3327: s->src.seqhi++;
3328: s->dst.seqhi = 1;
3329: s->dst.max_win = 1;
3330: s->src.state = TCPS_SYN_SENT;
3331: s->dst.state = TCPS_CLOSED;
3332: s->timeout = PFTM_TCP_FIRST_PACKET;
3333: break;
3334: case IPPROTO_UDP:
3335: s->src.state = PFUDPS_SINGLE;
3336: s->dst.state = PFUDPS_NO_TRAFFIC;
3337: s->timeout = PFTM_UDP_FIRST_PACKET;
3338: break;
3339: case IPPROTO_ICMP:
3340: #ifdef INET6
3341: case IPPROTO_ICMPV6:
3342: #endif
3343: s->timeout = PFTM_ICMP_FIRST_PACKET;
3344: break;
3345: default:
3346: s->src.state = PFOTHERS_SINGLE;
3347: s->dst.state = PFOTHERS_NO_TRAFFIC;
3348: s->timeout = PFTM_OTHER_FIRST_PACKET;
3349: }
3350:
3351: s->creation = time_second;
3352: s->expire = time_second;
3353:
3354: if (sn != NULL) {
3355: s->src_node = sn;
3356: s->src_node->states++;
3357: }
3358: if (nsn != NULL) {
3359: PF_ACPY(&nsn->raddr, &pd->naddr, af);
3360: s->nat_src_node = nsn;
3361: s->nat_src_node->states++;
3362: }
3363: if (pd->proto == IPPROTO_TCP) {
3364: if ((pd->flags & PFDESC_TCP_NORM) &&
3365: pf_normalize_tcp_init(m, off, pd, th, &s->src,
3366: &s->dst)) {
3367: REASON_SET(&reason, PFRES_MEMORY);
3368: pf_src_tree_remove_state(s);
3369: STATE_DEC_COUNTERS(s);
3370: pool_put(&pf_state_pl, s);
3371: return (PF_DROP);
3372: }
3373: if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
3374: pf_normalize_tcp_stateful(m, off, pd, &reason,
3375: th, s, &s->src, &s->dst, &rewrite)) {
3376: /* This really shouldn't happen!!! */
3377: DPFPRINTF(PF_DEBUG_URGENT,
3378: ("pf_normalize_tcp_stateful failed on "
3379: "first pkt"));
3380: pf_normalize_tcp_cleanup(s);
3381: pf_src_tree_remove_state(s);
3382: STATE_DEC_COUNTERS(s);
3383: pool_put(&pf_state_pl, s);
3384: return (PF_DROP);
3385: }
3386: }
3387:
3388: if ((sk = pf_alloc_state_key(s)) == NULL) {
3389: REASON_SET(&reason, PFRES_MEMORY);
3390: goto cleanup;
3391: }
3392:
3393: sk->proto = pd->proto;
3394: sk->direction = direction;
3395: sk->af = af;
3396: if (direction == PF_OUT) {
3397: PF_ACPY(&sk->gwy.addr, saddr, af);
3398: PF_ACPY(&sk->ext.addr, daddr, af);
3399: switch (pd->proto) {
3400: case IPPROTO_ICMP:
3401: #ifdef INET6
3402: case IPPROTO_ICMPV6:
3403: #endif
3404: sk->gwy.port = nport;
3405: sk->ext.port = 0;
3406: break;
3407: default:
3408: sk->gwy.port = sport;
3409: sk->ext.port = dport;
3410: }
3411: if (nr != NULL) {
3412: PF_ACPY(&sk->lan.addr, &pd->baddr, af);
3413: sk->lan.port = bport;
3414: } else {
3415: PF_ACPY(&sk->lan.addr, &sk->gwy.addr, af);
3416: sk->lan.port = sk->gwy.port;
3417: }
3418: } else {
3419: PF_ACPY(&sk->lan.addr, daddr, af);
3420: PF_ACPY(&sk->ext.addr, saddr, af);
3421: switch (pd->proto) {
3422: case IPPROTO_ICMP:
3423: #ifdef INET6
3424: case IPPROTO_ICMPV6:
3425: #endif
3426: sk->lan.port = nport;
3427: sk->ext.port = 0;
3428: break;
3429: default:
3430: sk->lan.port = dport;
3431: sk->ext.port = sport;
3432: }
3433: if (nr != NULL) {
3434: PF_ACPY(&sk->gwy.addr, &pd->baddr, af);
3435: sk->gwy.port = bport;
3436: } else {
3437: PF_ACPY(&sk->gwy.addr, &sk->lan.addr, af);
3438: sk->gwy.port = sk->lan.port;
3439: }
3440: }
3441:
3442: pf_set_rt_ifp(s, saddr); /* needs s->state_key set */
3443:
3444: if (pf_insert_state(BOUND_IFACE(r, kif), s)) {
3445: if (pd->proto == IPPROTO_TCP)
3446: pf_normalize_tcp_cleanup(s);
3447: REASON_SET(&reason, PFRES_STATEINS);
3448: pf_src_tree_remove_state(s);
3449: STATE_DEC_COUNTERS(s);
3450: pool_put(&pf_state_pl, s);
3451: return (PF_DROP);
3452: } else
3453: *sm = s;
3454: if (tag > 0) {
3455: pf_tag_ref(tag);
3456: s->tag = tag;
3457: }
3458: if (pd->proto == IPPROTO_TCP &&
3459: (th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
3460: r->keep_state == PF_STATE_SYNPROXY) {
3461: s->src.state = PF_TCPS_PROXY_SRC;
3462: if (nr != NULL) {
3463: if (direction == PF_OUT) {
3464: pf_change_ap(saddr, &th->th_sport,
3465: pd->ip_sum, &th->th_sum, &pd->baddr,
3466: bport, 0, af);
3467: sport = th->th_sport;
3468: } else {
3469: pf_change_ap(daddr, &th->th_dport,
3470: pd->ip_sum, &th->th_sum, &pd->baddr,
3471: bport, 0, af);
3472: sport = th->th_dport;
3473: }
3474: }
3475: s->src.seqhi = htonl(arc4random());
3476: /* Find mss option */
3477: mss = pf_get_mss(m, off, th->th_off, af);
3478: mss = pf_calc_mss(saddr, af, mss);
3479: mss = pf_calc_mss(daddr, af, mss);
3480: s->src.mss = mss;
3481: pf_send_tcp(r, af, daddr, saddr, th->th_dport,
3482: th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
3483: TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
3484: REASON_SET(&reason, PFRES_SYNPROXY);
3485: return (PF_SYNPROXY_DROP);
3486: }
3487: }
3488:
3489: /* copy back packet headers if we performed NAT operations */
3490: if (rewrite)
3491: m_copyback(m, off, hdrlen, pd->hdr.any);
3492:
3493: return (PF_PASS);
3494: }
3495:
3496: int
3497: pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
3498: struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
3499: struct pf_ruleset **rsm)
3500: {
3501: struct pf_rule *r, *a = NULL;
3502: struct pf_ruleset *ruleset = NULL;
3503: sa_family_t af = pd->af;
3504: u_short reason;
3505: int tag = -1;
3506: int asd = 0;
3507: int match = 0;
3508:
3509: r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
3510: while (r != NULL) {
3511: r->evaluations++;
3512: if (pfi_kif_match(r->kif, kif) == r->ifnot)
3513: r = r->skip[PF_SKIP_IFP].ptr;
3514: else if (r->direction && r->direction != direction)
3515: r = r->skip[PF_SKIP_DIR].ptr;
3516: else if (r->af && r->af != af)
3517: r = r->skip[PF_SKIP_AF].ptr;
3518: else if (r->proto && r->proto != pd->proto)
3519: r = r->skip[PF_SKIP_PROTO].ptr;
3520: else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
3521: r->src.neg, kif))
3522: r = r->skip[PF_SKIP_SRC_ADDR].ptr;
3523: else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
3524: r->dst.neg, NULL))
3525: r = r->skip[PF_SKIP_DST_ADDR].ptr;
3526: else if (r->tos && !(r->tos == pd->tos))
3527: r = TAILQ_NEXT(r, entries);
3528: else if (r->src.port_op || r->dst.port_op ||
3529: r->flagset || r->type || r->code ||
3530: r->os_fingerprint != PF_OSFP_ANY)
3531: r = TAILQ_NEXT(r, entries);
3532: else if (r->prob && r->prob <= arc4random())
3533: r = TAILQ_NEXT(r, entries);
3534: else if (r->match_tag && !pf_match_tag(m, r, &tag))
3535: r = TAILQ_NEXT(r, entries);
3536: else {
3537: if (r->anchor == NULL) {
3538: match = 1;
3539: *rm = r;
3540: *am = a;
3541: *rsm = ruleset;
3542: if ((*rm)->quick)
3543: break;
3544: r = TAILQ_NEXT(r, entries);
3545: } else
3546: pf_step_into_anchor(&asd, &ruleset,
3547: PF_RULESET_FILTER, &r, &a, &match);
3548: }
3549: if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
3550: PF_RULESET_FILTER, &r, &a, &match))
3551: break;
3552: }
3553: r = *rm;
3554: a = *am;
3555: ruleset = *rsm;
3556:
3557: REASON_SET(&reason, PFRES_MATCH);
3558:
3559: if (r->log)
3560: PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset,
3561: pd);
3562:
3563: if (r->action != PF_PASS)
3564: return (PF_DROP);
3565:
3566: if (pf_tag_packet(m, tag, -1)) {
3567: REASON_SET(&reason, PFRES_MEMORY);
3568: return (PF_DROP);
3569: }
3570:
3571: return (PF_PASS);
3572: }
3573:
3574: int
3575: pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
3576: struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
3577: u_short *reason)
3578: {
3579: struct pf_state_key_cmp key;
3580: struct tcphdr *th = pd->hdr.tcp;
3581: u_int16_t win = ntohs(th->th_win);
3582: u_int32_t ack, end, seq, orig_seq;
3583: u_int8_t sws, dws;
3584: int ackskew;
3585: int copyback = 0;
3586: struct pf_state_peer *src, *dst;
3587:
3588: key.af = pd->af;
3589: key.proto = IPPROTO_TCP;
3590: if (direction == PF_IN) {
3591: PF_ACPY(&key.ext.addr, pd->src, key.af);
3592: PF_ACPY(&key.gwy.addr, pd->dst, key.af);
3593: key.ext.port = th->th_sport;
3594: key.gwy.port = th->th_dport;
3595: } else {
3596: PF_ACPY(&key.lan.addr, pd->src, key.af);
3597: PF_ACPY(&key.ext.addr, pd->dst, key.af);
3598: key.lan.port = th->th_sport;
3599: key.ext.port = th->th_dport;
3600: }
3601:
3602: STATE_LOOKUP();
3603:
3604: if (direction == (*state)->state_key->direction) {
3605: src = &(*state)->src;
3606: dst = &(*state)->dst;
3607: } else {
3608: src = &(*state)->dst;
3609: dst = &(*state)->src;
3610: }
3611:
3612: if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
3613: if (direction != (*state)->state_key->direction) {
3614: REASON_SET(reason, PFRES_SYNPROXY);
3615: return (PF_SYNPROXY_DROP);
3616: }
3617: if (th->th_flags & TH_SYN) {
3618: if (ntohl(th->th_seq) != (*state)->src.seqlo) {
3619: REASON_SET(reason, PFRES_SYNPROXY);
3620: return (PF_DROP);
3621: }
3622: pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
3623: pd->src, th->th_dport, th->th_sport,
3624: (*state)->src.seqhi, ntohl(th->th_seq) + 1,
3625: TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
3626: 0, NULL, NULL);
3627: REASON_SET(reason, PFRES_SYNPROXY);
3628: return (PF_SYNPROXY_DROP);
3629: } else if (!(th->th_flags & TH_ACK) ||
3630: (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
3631: (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
3632: REASON_SET(reason, PFRES_SYNPROXY);
3633: return (PF_DROP);
3634: } else if ((*state)->src_node != NULL &&
3635: pf_src_connlimit(state)) {
3636: REASON_SET(reason, PFRES_SRCLIMIT);
3637: return (PF_DROP);
3638: } else
3639: (*state)->src.state = PF_TCPS_PROXY_DST;
3640: }
3641: if ((*state)->src.state == PF_TCPS_PROXY_DST) {
3642: struct pf_state_host *src, *dst;
3643:
3644: if (direction == PF_OUT) {
3645: src = &(*state)->state_key->gwy;
3646: dst = &(*state)->state_key->ext;
3647: } else {
3648: src = &(*state)->state_key->ext;
3649: dst = &(*state)->state_key->lan;
3650: }
3651: if (direction == (*state)->state_key->direction) {
3652: if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
3653: (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
3654: (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
3655: REASON_SET(reason, PFRES_SYNPROXY);
3656: return (PF_DROP);
3657: }
3658: (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
3659: if ((*state)->dst.seqhi == 1)
3660: (*state)->dst.seqhi = htonl(arc4random());
3661: pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
3662: &dst->addr, src->port, dst->port,
3663: (*state)->dst.seqhi, 0, TH_SYN, 0,
3664: (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL);
3665: REASON_SET(reason, PFRES_SYNPROXY);
3666: return (PF_SYNPROXY_DROP);
3667: } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
3668: (TH_SYN|TH_ACK)) ||
3669: (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
3670: REASON_SET(reason, PFRES_SYNPROXY);
3671: return (PF_DROP);
3672: } else {
3673: (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
3674: (*state)->dst.seqlo = ntohl(th->th_seq);
3675: pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
3676: pd->src, th->th_dport, th->th_sport,
3677: ntohl(th->th_ack), ntohl(th->th_seq) + 1,
3678: TH_ACK, (*state)->src.max_win, 0, 0, 0,
3679: (*state)->tag, NULL, NULL);
3680: pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
3681: &dst->addr, src->port, dst->port,
3682: (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
3683: TH_ACK, (*state)->dst.max_win, 0, 0, 1,
3684: 0, NULL, NULL);
3685: (*state)->src.seqdiff = (*state)->dst.seqhi -
3686: (*state)->src.seqlo;
3687: (*state)->dst.seqdiff = (*state)->src.seqhi -
3688: (*state)->dst.seqlo;
3689: (*state)->src.seqhi = (*state)->src.seqlo +
3690: (*state)->dst.max_win;
3691: (*state)->dst.seqhi = (*state)->dst.seqlo +
3692: (*state)->src.max_win;
3693: (*state)->src.wscale = (*state)->dst.wscale = 0;
3694: (*state)->src.state = (*state)->dst.state =
3695: TCPS_ESTABLISHED;
3696: REASON_SET(reason, PFRES_SYNPROXY);
3697: return (PF_SYNPROXY_DROP);
3698: }
3699: }
3700:
3701: if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
3702: sws = src->wscale & PF_WSCALE_MASK;
3703: dws = dst->wscale & PF_WSCALE_MASK;
3704: } else
3705: sws = dws = 0;
3706:
3707: /*
3708: * Sequence tracking algorithm from Guido van Rooij's paper:
3709: * http://www.madison-gurkha.com/publications/tcp_filtering/
3710: * tcp_filtering.ps
3711: */
3712:
3713: orig_seq = seq = ntohl(th->th_seq);
3714: if (src->seqlo == 0) {
3715: /* First packet from this end. Set its state */
3716:
3717: if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
3718: src->scrub == NULL) {
3719: if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
3720: REASON_SET(reason, PFRES_MEMORY);
3721: return (PF_DROP);
3722: }
3723: }
3724:
3725: /* Deferred generation of sequence number modulator */
3726: if (dst->seqdiff && !src->seqdiff) {
3727: while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
3728: ;
3729: ack = ntohl(th->th_ack) - dst->seqdiff;
3730: pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
3731: src->seqdiff), 0);
3732: pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
3733: copyback = 1;
3734: } else {
3735: ack = ntohl(th->th_ack);
3736: }
3737:
3738: end = seq + pd->p_len;
3739: if (th->th_flags & TH_SYN) {
3740: end++;
3741: if (dst->wscale & PF_WSCALE_FLAG) {
3742: src->wscale = pf_get_wscale(m, off, th->th_off,
3743: pd->af);
3744: if (src->wscale & PF_WSCALE_FLAG) {
3745: /* Remove scale factor from initial
3746: * window */
3747: sws = src->wscale & PF_WSCALE_MASK;
3748: win = ((u_int32_t)win + (1 << sws) - 1)
3749: >> sws;
3750: dws = dst->wscale & PF_WSCALE_MASK;
3751: } else {
3752: /* fixup other window */
3753: dst->max_win <<= dst->wscale &
3754: PF_WSCALE_MASK;
3755: /* in case of a retrans SYN|ACK */
3756: dst->wscale = 0;
3757: }
3758: }
3759: }
3760: if (th->th_flags & TH_FIN)
3761: end++;
3762:
3763: src->seqlo = seq;
3764: if (src->state < TCPS_SYN_SENT)
3765: src->state = TCPS_SYN_SENT;
3766:
3767: /*
3768: * May need to slide the window (seqhi may have been set by
3769: * the crappy stack check or if we picked up the connection
3770: * after establishment)
3771: */
3772: if (src->seqhi == 1 ||
3773: SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
3774: src->seqhi = end + MAX(1, dst->max_win << dws);
3775: if (win > src->max_win)
3776: src->max_win = win;
3777:
3778: } else {
3779: ack = ntohl(th->th_ack) - dst->seqdiff;
3780: if (src->seqdiff) {
3781: /* Modulate sequence numbers */
3782: pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
3783: src->seqdiff), 0);
3784: pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
3785: copyback = 1;
3786: }
3787: end = seq + pd->p_len;
3788: if (th->th_flags & TH_SYN)
3789: end++;
3790: if (th->th_flags & TH_FIN)
3791: end++;
3792: }
3793:
3794: if ((th->th_flags & TH_ACK) == 0) {
3795: /* Let it pass through the ack skew check */
3796: ack = dst->seqlo;
3797: } else if ((ack == 0 &&
3798: (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
3799: /* broken tcp stacks do not set ack */
3800: (dst->state < TCPS_SYN_SENT)) {
3801: /*
3802: * Many stacks (ours included) will set the ACK number in an
3803: * FIN|ACK if the SYN times out -- no sequence to ACK.
3804: */
3805: ack = dst->seqlo;
3806: }
3807:
3808: if (seq == end) {
3809: /* Ease sequencing restrictions on no data packets */
3810: seq = src->seqlo;
3811: end = seq;
3812: }
3813:
3814: ackskew = dst->seqlo - ack;
3815:
3816:
3817: /*
3818: * Need to demodulate the sequence numbers in any TCP SACK options
3819: * (Selective ACK). We could optionally validate the SACK values
3820: * against the current ACK window, either forwards or backwards, but
3821: * I'm not confident that SACK has been implemented properly
3822: * everywhere. It wouldn't surprise me if several stacks accidently
3823: * SACK too far backwards of previously ACKed data. There really aren't
3824: * any security implications of bad SACKing unless the target stack
3825: * doesn't validate the option length correctly. Someone trying to
3826: * spoof into a TCP connection won't bother blindly sending SACK
3827: * options anyway.
3828: */
3829: if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
3830: if (pf_modulate_sack(m, off, pd, th, dst))
3831: copyback = 1;
3832: }
3833:
3834:
3835: #define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
3836: if (SEQ_GEQ(src->seqhi, end) &&
3837: /* Last octet inside other's window space */
3838: SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
3839: /* Retrans: not more than one window back */
3840: (ackskew >= -MAXACKWINDOW) &&
3841: /* Acking not more than one reassembled fragment backwards */
3842: (ackskew <= (MAXACKWINDOW << sws)) &&
3843: /* Acking not more than one window forward */
3844: ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
3845: (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) {
3846: /* Require an exact/+1 sequence match on resets when possible */
3847:
3848: if (dst->scrub || src->scrub) {
3849: if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
3850: *state, src, dst, ©back))
3851: return (PF_DROP);
3852: }
3853:
3854: /* update max window */
3855: if (src->max_win < win)
3856: src->max_win = win;
3857: /* synchronize sequencing */
3858: if (SEQ_GT(end, src->seqlo))
3859: src->seqlo = end;
3860: /* slide the window of what the other end can send */
3861: if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
3862: dst->seqhi = ack + MAX((win << sws), 1);
3863:
3864:
3865: /* update states */
3866: if (th->th_flags & TH_SYN)
3867: if (src->state < TCPS_SYN_SENT)
3868: src->state = TCPS_SYN_SENT;
3869: if (th->th_flags & TH_FIN)
3870: if (src->state < TCPS_CLOSING)
3871: src->state = TCPS_CLOSING;
3872: if (th->th_flags & TH_ACK) {
3873: if (dst->state == TCPS_SYN_SENT) {
3874: dst->state = TCPS_ESTABLISHED;
3875: if (src->state == TCPS_ESTABLISHED &&
3876: (*state)->src_node != NULL &&
3877: pf_src_connlimit(state)) {
3878: REASON_SET(reason, PFRES_SRCLIMIT);
3879: return (PF_DROP);
3880: }
3881: } else if (dst->state == TCPS_CLOSING)
3882: dst->state = TCPS_FIN_WAIT_2;
3883: }
3884: if (th->th_flags & TH_RST)
3885: src->state = dst->state = TCPS_TIME_WAIT;
3886:
3887: /* update expire time */
3888: (*state)->expire = time_second;
3889: if (src->state >= TCPS_FIN_WAIT_2 &&
3890: dst->state >= TCPS_FIN_WAIT_2)
3891: (*state)->timeout = PFTM_TCP_CLOSED;
3892: else if (src->state >= TCPS_CLOSING &&
3893: dst->state >= TCPS_CLOSING)
3894: (*state)->timeout = PFTM_TCP_FIN_WAIT;
3895: else if (src->state < TCPS_ESTABLISHED ||
3896: dst->state < TCPS_ESTABLISHED)
3897: (*state)->timeout = PFTM_TCP_OPENING;
3898: else if (src->state >= TCPS_CLOSING ||
3899: dst->state >= TCPS_CLOSING)
3900: (*state)->timeout = PFTM_TCP_CLOSING;
3901: else
3902: (*state)->timeout = PFTM_TCP_ESTABLISHED;
3903:
3904: /* Fall through to PASS packet */
3905:
3906: } else if ((dst->state < TCPS_SYN_SENT ||
3907: dst->state >= TCPS_FIN_WAIT_2 ||
3908: src->state >= TCPS_FIN_WAIT_2) &&
3909: SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
3910: /* Within a window forward of the originating packet */
3911: SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
3912: /* Within a window backward of the originating packet */
3913:
3914: /*
3915: * This currently handles three situations:
3916: * 1) Stupid stacks will shotgun SYNs before their peer
3917: * replies.
3918: * 2) When PF catches an already established stream (the
3919: * firewall rebooted, the state table was flushed, routes
3920: * changed...)
3921: * 3) Packets get funky immediately after the connection
3922: * closes (this should catch Solaris spurious ACK|FINs
3923: * that web servers like to spew after a close)
3924: *
3925: * This must be a little more careful than the above code
3926: * since packet floods will also be caught here. We don't
3927: * update the TTL here to mitigate the damage of a packet
3928: * flood and so the same code can handle awkward establishment
3929: * and a loosened connection close.
3930: * In the establishment case, a correct peer response will
3931: * validate the connection, go through the normal state code
3932: * and keep updating the state TTL.
3933: */
3934:
3935: if (pf_status.debug >= PF_DEBUG_MISC) {
3936: printf("pf: loose state match: ");
3937: pf_print_state(*state);
3938: pf_print_flags(th->th_flags);
3939: printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
3940: "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len,
3941: ackskew, (*state)->packets[0],
3942: (*state)->packets[1]);
3943: }
3944:
3945: if (dst->scrub || src->scrub) {
3946: if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
3947: *state, src, dst, ©back))
3948: return (PF_DROP);
3949: }
3950:
3951: /* update max window */
3952: if (src->max_win < win)
3953: src->max_win = win;
3954: /* synchronize sequencing */
3955: if (SEQ_GT(end, src->seqlo))
3956: src->seqlo = end;
3957: /* slide the window of what the other end can send */
3958: if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
3959: dst->seqhi = ack + MAX((win << sws), 1);
3960:
3961: /*
3962: * Cannot set dst->seqhi here since this could be a shotgunned
3963: * SYN and not an already established connection.
3964: */
3965:
3966: if (th->th_flags & TH_FIN)
3967: if (src->state < TCPS_CLOSING)
3968: src->state = TCPS_CLOSING;
3969: if (th->th_flags & TH_RST)
3970: src->state = dst->state = TCPS_TIME_WAIT;
3971:
3972: /* Fall through to PASS packet */
3973:
3974: } else {
3975: if ((*state)->dst.state == TCPS_SYN_SENT &&
3976: (*state)->src.state == TCPS_SYN_SENT) {
3977: /* Send RST for state mismatches during handshake */
3978: if (!(th->th_flags & TH_RST))
3979: pf_send_tcp((*state)->rule.ptr, pd->af,
3980: pd->dst, pd->src, th->th_dport,
3981: th->th_sport, ntohl(th->th_ack), 0,
3982: TH_RST, 0, 0,
3983: (*state)->rule.ptr->return_ttl, 1, 0,
3984: pd->eh, kif->pfik_ifp);
3985: src->seqlo = 0;
3986: src->seqhi = 1;
3987: src->max_win = 1;
3988: } else if (pf_status.debug >= PF_DEBUG_MISC) {
3989: printf("pf: BAD state: ");
3990: pf_print_state(*state);
3991: pf_print_flags(th->th_flags);
3992: printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
3993: "pkts=%llu:%llu dir=%s,%s\n",
3994: seq, orig_seq, ack, pd->p_len, ackskew,
3995: (*state)->packets[0], (*state)->packets[1],
3996: direction == PF_IN ? "in" : "out",
3997: direction == (*state)->state_key->direction ?
3998: "fwd" : "rev");
3999: printf("pf: State failure on: %c %c %c %c | %c %c\n",
4000: SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
4001: SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
4002: ' ': '2',
4003: (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
4004: (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
4005: SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
4006: SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
4007: }
4008: REASON_SET(reason, PFRES_BADSTATE);
4009: return (PF_DROP);
4010: }
4011:
4012: /* Any packets which have gotten here are to be passed */
4013:
4014: /* translate source/destination address, if necessary */
4015: if (STATE_TRANSLATE((*state)->state_key)) {
4016: if (direction == PF_OUT)
4017: pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
4018: &th->th_sum, &(*state)->state_key->gwy.addr,
4019: (*state)->state_key->gwy.port, 0, pd->af);
4020: else
4021: pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
4022: &th->th_sum, &(*state)->state_key->lan.addr,
4023: (*state)->state_key->lan.port, 0, pd->af);
4024: m_copyback(m, off, sizeof(*th), th);
4025: } else if (copyback) {
4026: /* Copyback sequence modulation or stateful scrub changes */
4027: m_copyback(m, off, sizeof(*th), th);
4028: }
4029:
4030: return (PF_PASS);
4031: }
4032:
4033: int
4034: pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
4035: struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
4036: {
4037: struct pf_state_peer *src, *dst;
4038: struct pf_state_key_cmp key;
4039: struct udphdr *uh = pd->hdr.udp;
4040:
4041: key.af = pd->af;
4042: key.proto = IPPROTO_UDP;
4043: if (direction == PF_IN) {
4044: PF_ACPY(&key.ext.addr, pd->src, key.af);
4045: PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4046: key.ext.port = uh->uh_sport;
4047: key.gwy.port = uh->uh_dport;
4048: } else {
4049: PF_ACPY(&key.lan.addr, pd->src, key.af);
4050: PF_ACPY(&key.ext.addr, pd->dst, key.af);
4051: key.lan.port = uh->uh_sport;
4052: key.ext.port = uh->uh_dport;
4053: }
4054:
4055: STATE_LOOKUP();
4056:
4057: if (direction == (*state)->state_key->direction) {
4058: src = &(*state)->src;
4059: dst = &(*state)->dst;
4060: } else {
4061: src = &(*state)->dst;
4062: dst = &(*state)->src;
4063: }
4064:
4065: /* update states */
4066: if (src->state < PFUDPS_SINGLE)
4067: src->state = PFUDPS_SINGLE;
4068: if (dst->state == PFUDPS_SINGLE)
4069: dst->state = PFUDPS_MULTIPLE;
4070:
4071: /* update expire time */
4072: (*state)->expire = time_second;
4073: if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
4074: (*state)->timeout = PFTM_UDP_MULTIPLE;
4075: else
4076: (*state)->timeout = PFTM_UDP_SINGLE;
4077:
4078: /* translate source/destination address, if necessary */
4079: if (STATE_TRANSLATE((*state)->state_key)) {
4080: if (direction == PF_OUT)
4081: pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
4082: &uh->uh_sum, &(*state)->state_key->gwy.addr,
4083: (*state)->state_key->gwy.port, 1, pd->af);
4084: else
4085: pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
4086: &uh->uh_sum, &(*state)->state_key->lan.addr,
4087: (*state)->state_key->lan.port, 1, pd->af);
4088: m_copyback(m, off, sizeof(*uh), uh);
4089: }
4090:
4091: return (PF_PASS);
4092: }
4093:
4094: int
4095: pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
4096: struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
4097: {
4098: struct pf_addr *saddr = pd->src, *daddr = pd->dst;
4099: u_int16_t icmpid, *icmpsum;
4100: u_int8_t icmptype;
4101: int state_icmp = 0;
4102: struct pf_state_key_cmp key;
4103:
4104: switch (pd->proto) {
4105: #ifdef INET
4106: case IPPROTO_ICMP:
4107: icmptype = pd->hdr.icmp->icmp_type;
4108: icmpid = pd->hdr.icmp->icmp_id;
4109: icmpsum = &pd->hdr.icmp->icmp_cksum;
4110:
4111: if (icmptype == ICMP_UNREACH ||
4112: icmptype == ICMP_SOURCEQUENCH ||
4113: icmptype == ICMP_REDIRECT ||
4114: icmptype == ICMP_TIMXCEED ||
4115: icmptype == ICMP_PARAMPROB)
4116: state_icmp++;
4117: break;
4118: #endif /* INET */
4119: #ifdef INET6
4120: case IPPROTO_ICMPV6:
4121: icmptype = pd->hdr.icmp6->icmp6_type;
4122: icmpid = pd->hdr.icmp6->icmp6_id;
4123: icmpsum = &pd->hdr.icmp6->icmp6_cksum;
4124:
4125: if (icmptype == ICMP6_DST_UNREACH ||
4126: icmptype == ICMP6_PACKET_TOO_BIG ||
4127: icmptype == ICMP6_TIME_EXCEEDED ||
4128: icmptype == ICMP6_PARAM_PROB)
4129: state_icmp++;
4130: break;
4131: #endif /* INET6 */
4132: }
4133:
4134: if (!state_icmp) {
4135:
4136: /*
4137: * ICMP query/reply message not related to a TCP/UDP packet.
4138: * Search for an ICMP state.
4139: */
4140: key.af = pd->af;
4141: key.proto = pd->proto;
4142: if (direction == PF_IN) {
4143: PF_ACPY(&key.ext.addr, pd->src, key.af);
4144: PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4145: key.ext.port = 0;
4146: key.gwy.port = icmpid;
4147: } else {
4148: PF_ACPY(&key.lan.addr, pd->src, key.af);
4149: PF_ACPY(&key.ext.addr, pd->dst, key.af);
4150: key.lan.port = icmpid;
4151: key.ext.port = 0;
4152: }
4153:
4154: STATE_LOOKUP();
4155:
4156: (*state)->expire = time_second;
4157: (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
4158:
4159: /* translate source/destination address, if necessary */
4160: if (STATE_TRANSLATE((*state)->state_key)) {
4161: if (direction == PF_OUT) {
4162: switch (pd->af) {
4163: #ifdef INET
4164: case AF_INET:
4165: pf_change_a(&saddr->v4.s_addr,
4166: pd->ip_sum,
4167: (*state)->state_key->gwy.addr.v4.s_addr, 0);
4168: pd->hdr.icmp->icmp_cksum =
4169: pf_cksum_fixup(
4170: pd->hdr.icmp->icmp_cksum, icmpid,
4171: (*state)->state_key->gwy.port, 0);
4172: pd->hdr.icmp->icmp_id =
4173: (*state)->state_key->gwy.port;
4174: m_copyback(m, off, ICMP_MINLEN,
4175: pd->hdr.icmp);
4176: break;
4177: #endif /* INET */
4178: #ifdef INET6
4179: case AF_INET6:
4180: pf_change_a6(saddr,
4181: &pd->hdr.icmp6->icmp6_cksum,
4182: &(*state)->state_key->gwy.addr, 0);
4183: m_copyback(m, off,
4184: sizeof(struct icmp6_hdr),
4185: pd->hdr.icmp6);
4186: break;
4187: #endif /* INET6 */
4188: }
4189: } else {
4190: switch (pd->af) {
4191: #ifdef INET
4192: case AF_INET:
4193: pf_change_a(&daddr->v4.s_addr,
4194: pd->ip_sum,
4195: (*state)->state_key->lan.addr.v4.s_addr, 0);
4196: pd->hdr.icmp->icmp_cksum =
4197: pf_cksum_fixup(
4198: pd->hdr.icmp->icmp_cksum, icmpid,
4199: (*state)->state_key->lan.port, 0);
4200: pd->hdr.icmp->icmp_id =
4201: (*state)->state_key->lan.port;
4202: m_copyback(m, off, ICMP_MINLEN,
4203: pd->hdr.icmp);
4204: break;
4205: #endif /* INET */
4206: #ifdef INET6
4207: case AF_INET6:
4208: pf_change_a6(daddr,
4209: &pd->hdr.icmp6->icmp6_cksum,
4210: &(*state)->state_key->lan.addr, 0);
4211: m_copyback(m, off,
4212: sizeof(struct icmp6_hdr),
4213: pd->hdr.icmp6);
4214: break;
4215: #endif /* INET6 */
4216: }
4217: }
4218: }
4219:
4220: return (PF_PASS);
4221:
4222: } else {
4223: /*
4224: * ICMP error message in response to a TCP/UDP packet.
4225: * Extract the inner TCP/UDP header and search for that state.
4226: */
4227:
4228: struct pf_pdesc pd2;
4229: #ifdef INET
4230: struct ip h2;
4231: #endif /* INET */
4232: #ifdef INET6
4233: struct ip6_hdr h2_6;
4234: int terminal = 0;
4235: #endif /* INET6 */
4236: int ipoff2;
4237: int off2;
4238:
4239: pd2.af = pd->af;
4240: switch (pd->af) {
4241: #ifdef INET
4242: case AF_INET:
4243: /* offset of h2 in mbuf chain */
4244: ipoff2 = off + ICMP_MINLEN;
4245:
4246: if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2),
4247: NULL, reason, pd2.af)) {
4248: DPFPRINTF(PF_DEBUG_MISC,
4249: ("pf: ICMP error message too short "
4250: "(ip)\n"));
4251: return (PF_DROP);
4252: }
4253: /*
4254: * ICMP error messages don't refer to non-first
4255: * fragments
4256: */
4257: if (h2.ip_off & htons(IP_OFFMASK)) {
4258: REASON_SET(reason, PFRES_FRAG);
4259: return (PF_DROP);
4260: }
4261:
4262: /* offset of protocol header that follows h2 */
4263: off2 = ipoff2 + (h2.ip_hl << 2);
4264:
4265: pd2.proto = h2.ip_p;
4266: pd2.src = (struct pf_addr *)&h2.ip_src;
4267: pd2.dst = (struct pf_addr *)&h2.ip_dst;
4268: pd2.ip_sum = &h2.ip_sum;
4269: break;
4270: #endif /* INET */
4271: #ifdef INET6
4272: case AF_INET6:
4273: ipoff2 = off + sizeof(struct icmp6_hdr);
4274:
4275: if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6),
4276: NULL, reason, pd2.af)) {
4277: DPFPRINTF(PF_DEBUG_MISC,
4278: ("pf: ICMP error message too short "
4279: "(ip6)\n"));
4280: return (PF_DROP);
4281: }
4282: pd2.proto = h2_6.ip6_nxt;
4283: pd2.src = (struct pf_addr *)&h2_6.ip6_src;
4284: pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
4285: pd2.ip_sum = NULL;
4286: off2 = ipoff2 + sizeof(h2_6);
4287: do {
4288: switch (pd2.proto) {
4289: case IPPROTO_FRAGMENT:
4290: /*
4291: * ICMPv6 error messages for
4292: * non-first fragments
4293: */
4294: REASON_SET(reason, PFRES_FRAG);
4295: return (PF_DROP);
4296: case IPPROTO_AH:
4297: case IPPROTO_HOPOPTS:
4298: case IPPROTO_ROUTING:
4299: case IPPROTO_DSTOPTS: {
4300: /* get next header and header length */
4301: struct ip6_ext opt6;
4302:
4303: if (!pf_pull_hdr(m, off2, &opt6,
4304: sizeof(opt6), NULL, reason,
4305: pd2.af)) {
4306: DPFPRINTF(PF_DEBUG_MISC,
4307: ("pf: ICMPv6 short opt\n"));
4308: return (PF_DROP);
4309: }
4310: if (pd2.proto == IPPROTO_AH)
4311: off2 += (opt6.ip6e_len + 2) * 4;
4312: else
4313: off2 += (opt6.ip6e_len + 1) * 8;
4314: pd2.proto = opt6.ip6e_nxt;
4315: /* goto the next header */
4316: break;
4317: }
4318: default:
4319: terminal++;
4320: break;
4321: }
4322: } while (!terminal);
4323: break;
4324: #endif /* INET6 */
4325: }
4326:
4327: switch (pd2.proto) {
4328: case IPPROTO_TCP: {
4329: struct tcphdr th;
4330: u_int32_t seq;
4331: struct pf_state_peer *src, *dst;
4332: u_int8_t dws;
4333: int copyback = 0;
4334:
4335: /*
4336: * Only the first 8 bytes of the TCP header can be
4337: * expected. Don't access any TCP header fields after
4338: * th_seq, an ackskew test is not possible.
4339: */
4340: if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason,
4341: pd2.af)) {
4342: DPFPRINTF(PF_DEBUG_MISC,
4343: ("pf: ICMP error message too short "
4344: "(tcp)\n"));
4345: return (PF_DROP);
4346: }
4347:
4348: key.af = pd2.af;
4349: key.proto = IPPROTO_TCP;
4350: if (direction == PF_IN) {
4351: PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4352: PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4353: key.ext.port = th.th_dport;
4354: key.gwy.port = th.th_sport;
4355: } else {
4356: PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4357: PF_ACPY(&key.ext.addr, pd2.src, key.af);
4358: key.lan.port = th.th_dport;
4359: key.ext.port = th.th_sport;
4360: }
4361:
4362: STATE_LOOKUP();
4363:
4364: if (direction == (*state)->state_key->direction) {
4365: src = &(*state)->dst;
4366: dst = &(*state)->src;
4367: } else {
4368: src = &(*state)->src;
4369: dst = &(*state)->dst;
4370: }
4371:
4372: if (src->wscale && dst->wscale)
4373: dws = dst->wscale & PF_WSCALE_MASK;
4374: else
4375: dws = 0;
4376:
4377: /* Demodulate sequence number */
4378: seq = ntohl(th.th_seq) - src->seqdiff;
4379: if (src->seqdiff) {
4380: pf_change_a(&th.th_seq, icmpsum,
4381: htonl(seq), 0);
4382: copyback = 1;
4383: }
4384:
4385: if (!SEQ_GEQ(src->seqhi, seq) ||
4386: !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws))) {
4387: if (pf_status.debug >= PF_DEBUG_MISC) {
4388: printf("pf: BAD ICMP %d:%d ",
4389: icmptype, pd->hdr.icmp->icmp_code);
4390: pf_print_host(pd->src, 0, pd->af);
4391: printf(" -> ");
4392: pf_print_host(pd->dst, 0, pd->af);
4393: printf(" state: ");
4394: pf_print_state(*state);
4395: printf(" seq=%u\n", seq);
4396: }
4397: REASON_SET(reason, PFRES_BADSTATE);
4398: return (PF_DROP);
4399: }
4400:
4401: if (STATE_TRANSLATE((*state)->state_key)) {
4402: if (direction == PF_IN) {
4403: pf_change_icmp(pd2.src, &th.th_sport,
4404: daddr, &(*state)->state_key->lan.addr,
4405: (*state)->state_key->lan.port, NULL,
4406: pd2.ip_sum, icmpsum,
4407: pd->ip_sum, 0, pd2.af);
4408: } else {
4409: pf_change_icmp(pd2.dst, &th.th_dport,
4410: saddr, &(*state)->state_key->gwy.addr,
4411: (*state)->state_key->gwy.port, NULL,
4412: pd2.ip_sum, icmpsum,
4413: pd->ip_sum, 0, pd2.af);
4414: }
4415: copyback = 1;
4416: }
4417:
4418: if (copyback) {
4419: switch (pd2.af) {
4420: #ifdef INET
4421: case AF_INET:
4422: m_copyback(m, off, ICMP_MINLEN,
4423: pd->hdr.icmp);
4424: m_copyback(m, ipoff2, sizeof(h2),
4425: &h2);
4426: break;
4427: #endif /* INET */
4428: #ifdef INET6
4429: case AF_INET6:
4430: m_copyback(m, off,
4431: sizeof(struct icmp6_hdr),
4432: pd->hdr.icmp6);
4433: m_copyback(m, ipoff2, sizeof(h2_6),
4434: &h2_6);
4435: break;
4436: #endif /* INET6 */
4437: }
4438: m_copyback(m, off2, 8, &th);
4439: }
4440:
4441: return (PF_PASS);
4442: break;
4443: }
4444: case IPPROTO_UDP: {
4445: struct udphdr uh;
4446:
4447: if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
4448: NULL, reason, pd2.af)) {
4449: DPFPRINTF(PF_DEBUG_MISC,
4450: ("pf: ICMP error message too short "
4451: "(udp)\n"));
4452: return (PF_DROP);
4453: }
4454:
4455: key.af = pd2.af;
4456: key.proto = IPPROTO_UDP;
4457: if (direction == PF_IN) {
4458: PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4459: PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4460: key.ext.port = uh.uh_dport;
4461: key.gwy.port = uh.uh_sport;
4462: } else {
4463: PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4464: PF_ACPY(&key.ext.addr, pd2.src, key.af);
4465: key.lan.port = uh.uh_dport;
4466: key.ext.port = uh.uh_sport;
4467: }
4468:
4469: STATE_LOOKUP();
4470:
4471: if (STATE_TRANSLATE((*state)->state_key)) {
4472: if (direction == PF_IN) {
4473: pf_change_icmp(pd2.src, &uh.uh_sport,
4474: daddr,
4475: &(*state)->state_key->lan.addr,
4476: (*state)->state_key->lan.port,
4477: &uh.uh_sum,
4478: pd2.ip_sum, icmpsum,
4479: pd->ip_sum, 1, pd2.af);
4480: } else {
4481: pf_change_icmp(pd2.dst, &uh.uh_dport,
4482: saddr,
4483: &(*state)->state_key->gwy.addr,
4484: (*state)->state_key->gwy.port, &uh.uh_sum,
4485: pd2.ip_sum, icmpsum,
4486: pd->ip_sum, 1, pd2.af);
4487: }
4488: switch (pd2.af) {
4489: #ifdef INET
4490: case AF_INET:
4491: m_copyback(m, off, ICMP_MINLEN,
4492: pd->hdr.icmp);
4493: m_copyback(m, ipoff2, sizeof(h2), &h2);
4494: break;
4495: #endif /* INET */
4496: #ifdef INET6
4497: case AF_INET6:
4498: m_copyback(m, off,
4499: sizeof(struct icmp6_hdr),
4500: pd->hdr.icmp6);
4501: m_copyback(m, ipoff2, sizeof(h2_6),
4502: &h2_6);
4503: break;
4504: #endif /* INET6 */
4505: }
4506: m_copyback(m, off2, sizeof(uh), &uh);
4507: }
4508:
4509: return (PF_PASS);
4510: break;
4511: }
4512: #ifdef INET
4513: case IPPROTO_ICMP: {
4514: struct icmp iih;
4515:
4516: if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
4517: NULL, reason, pd2.af)) {
4518: DPFPRINTF(PF_DEBUG_MISC,
4519: ("pf: ICMP error message too short i"
4520: "(icmp)\n"));
4521: return (PF_DROP);
4522: }
4523:
4524: key.af = pd2.af;
4525: key.proto = IPPROTO_ICMP;
4526: if (direction == PF_IN) {
4527: PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4528: PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4529: key.ext.port = 0;
4530: key.gwy.port = iih.icmp_id;
4531: } else {
4532: PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4533: PF_ACPY(&key.ext.addr, pd2.src, key.af);
4534: key.lan.port = iih.icmp_id;
4535: key.ext.port = 0;
4536: }
4537:
4538: STATE_LOOKUP();
4539:
4540: if (STATE_TRANSLATE((*state)->state_key)) {
4541: if (direction == PF_IN) {
4542: pf_change_icmp(pd2.src, &iih.icmp_id,
4543: daddr,
4544: &(*state)->state_key->lan.addr,
4545: (*state)->state_key->lan.port, NULL,
4546: pd2.ip_sum, icmpsum,
4547: pd->ip_sum, 0, AF_INET);
4548: } else {
4549: pf_change_icmp(pd2.dst, &iih.icmp_id,
4550: saddr,
4551: &(*state)->state_key->gwy.addr,
4552: (*state)->state_key->gwy.port, NULL,
4553: pd2.ip_sum, icmpsum,
4554: pd->ip_sum, 0, AF_INET);
4555: }
4556: m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
4557: m_copyback(m, ipoff2, sizeof(h2), &h2);
4558: m_copyback(m, off2, ICMP_MINLEN, &iih);
4559: }
4560:
4561: return (PF_PASS);
4562: break;
4563: }
4564: #endif /* INET */
4565: #ifdef INET6
4566: case IPPROTO_ICMPV6: {
4567: struct icmp6_hdr iih;
4568:
4569: if (!pf_pull_hdr(m, off2, &iih,
4570: sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
4571: DPFPRINTF(PF_DEBUG_MISC,
4572: ("pf: ICMP error message too short "
4573: "(icmp6)\n"));
4574: return (PF_DROP);
4575: }
4576:
4577: key.af = pd2.af;
4578: key.proto = IPPROTO_ICMPV6;
4579: if (direction == PF_IN) {
4580: PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4581: PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4582: key.ext.port = 0;
4583: key.gwy.port = iih.icmp6_id;
4584: } else {
4585: PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4586: PF_ACPY(&key.ext.addr, pd2.src, key.af);
4587: key.lan.port = iih.icmp6_id;
4588: key.ext.port = 0;
4589: }
4590:
4591: STATE_LOOKUP();
4592:
4593: if (STATE_TRANSLATE((*state)->state_key)) {
4594: if (direction == PF_IN) {
4595: pf_change_icmp(pd2.src, &iih.icmp6_id,
4596: daddr,
4597: &(*state)->state_key->lan.addr,
4598: (*state)->state_key->lan.port, NULL,
4599: pd2.ip_sum, icmpsum,
4600: pd->ip_sum, 0, AF_INET6);
4601: } else {
4602: pf_change_icmp(pd2.dst, &iih.icmp6_id,
4603: saddr, &(*state)->state_key->gwy.addr,
4604: (*state)->state_key->gwy.port, NULL,
4605: pd2.ip_sum, icmpsum,
4606: pd->ip_sum, 0, AF_INET6);
4607: }
4608: m_copyback(m, off, sizeof(struct icmp6_hdr),
4609: pd->hdr.icmp6);
4610: m_copyback(m, ipoff2, sizeof(h2_6), &h2_6);
4611: m_copyback(m, off2, sizeof(struct icmp6_hdr),
4612: &iih);
4613: }
4614:
4615: return (PF_PASS);
4616: break;
4617: }
4618: #endif /* INET6 */
4619: default: {
4620: key.af = pd2.af;
4621: key.proto = pd2.proto;
4622: if (direction == PF_IN) {
4623: PF_ACPY(&key.ext.addr, pd2.dst, key.af);
4624: PF_ACPY(&key.gwy.addr, pd2.src, key.af);
4625: key.ext.port = 0;
4626: key.gwy.port = 0;
4627: } else {
4628: PF_ACPY(&key.lan.addr, pd2.dst, key.af);
4629: PF_ACPY(&key.ext.addr, pd2.src, key.af);
4630: key.lan.port = 0;
4631: key.ext.port = 0;
4632: }
4633:
4634: STATE_LOOKUP();
4635:
4636: if (STATE_TRANSLATE((*state)->state_key)) {
4637: if (direction == PF_IN) {
4638: pf_change_icmp(pd2.src, NULL,
4639: daddr,
4640: &(*state)->state_key->lan.addr,
4641: 0, NULL,
4642: pd2.ip_sum, icmpsum,
4643: pd->ip_sum, 0, pd2.af);
4644: } else {
4645: pf_change_icmp(pd2.dst, NULL,
4646: saddr,
4647: &(*state)->state_key->gwy.addr,
4648: 0, NULL,
4649: pd2.ip_sum, icmpsum,
4650: pd->ip_sum, 0, pd2.af);
4651: }
4652: switch (pd2.af) {
4653: #ifdef INET
4654: case AF_INET:
4655: m_copyback(m, off, ICMP_MINLEN,
4656: pd->hdr.icmp);
4657: m_copyback(m, ipoff2, sizeof(h2), &h2);
4658: break;
4659: #endif /* INET */
4660: #ifdef INET6
4661: case AF_INET6:
4662: m_copyback(m, off,
4663: sizeof(struct icmp6_hdr),
4664: pd->hdr.icmp6);
4665: m_copyback(m, ipoff2, sizeof(h2_6),
4666: &h2_6);
4667: break;
4668: #endif /* INET6 */
4669: }
4670: }
4671:
4672: return (PF_PASS);
4673: break;
4674: }
4675: }
4676: }
4677: }
4678:
4679: int
4680: pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
4681: struct pf_pdesc *pd)
4682: {
4683: struct pf_state_peer *src, *dst;
4684: struct pf_state_key_cmp key;
4685:
4686: key.af = pd->af;
4687: key.proto = pd->proto;
4688: if (direction == PF_IN) {
4689: PF_ACPY(&key.ext.addr, pd->src, key.af);
4690: PF_ACPY(&key.gwy.addr, pd->dst, key.af);
4691: key.ext.port = 0;
4692: key.gwy.port = 0;
4693: } else {
4694: PF_ACPY(&key.lan.addr, pd->src, key.af);
4695: PF_ACPY(&key.ext.addr, pd->dst, key.af);
4696: key.lan.port = 0;
4697: key.ext.port = 0;
4698: }
4699:
4700: STATE_LOOKUP();
4701:
4702: if (direction == (*state)->state_key->direction) {
4703: src = &(*state)->src;
4704: dst = &(*state)->dst;
4705: } else {
4706: src = &(*state)->dst;
4707: dst = &(*state)->src;
4708: }
4709:
4710: /* update states */
4711: if (src->state < PFOTHERS_SINGLE)
4712: src->state = PFOTHERS_SINGLE;
4713: if (dst->state == PFOTHERS_SINGLE)
4714: dst->state = PFOTHERS_MULTIPLE;
4715:
4716: /* update expire time */
4717: (*state)->expire = time_second;
4718: if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
4719: (*state)->timeout = PFTM_OTHER_MULTIPLE;
4720: else
4721: (*state)->timeout = PFTM_OTHER_SINGLE;
4722:
4723: /* translate source/destination address, if necessary */
4724: if (STATE_TRANSLATE((*state)->state_key)) {
4725: if (direction == PF_OUT)
4726: switch (pd->af) {
4727: #ifdef INET
4728: case AF_INET:
4729: pf_change_a(&pd->src->v4.s_addr,
4730: pd->ip_sum,
4731: (*state)->state_key->gwy.addr.v4.s_addr,
4732: 0);
4733: break;
4734: #endif /* INET */
4735: #ifdef INET6
4736: case AF_INET6:
4737: PF_ACPY(pd->src,
4738: &(*state)->state_key->gwy.addr, pd->af);
4739: break;
4740: #endif /* INET6 */
4741: }
4742: else
4743: switch (pd->af) {
4744: #ifdef INET
4745: case AF_INET:
4746: pf_change_a(&pd->dst->v4.s_addr,
4747: pd->ip_sum,
4748: (*state)->state_key->lan.addr.v4.s_addr,
4749: 0);
4750: break;
4751: #endif /* INET */
4752: #ifdef INET6
4753: case AF_INET6:
4754: PF_ACPY(pd->dst,
4755: &(*state)->state_key->lan.addr, pd->af);
4756: break;
4757: #endif /* INET6 */
4758: }
4759: }
4760:
4761: return (PF_PASS);
4762: }
4763:
4764: /*
4765: * ipoff and off are measured from the start of the mbuf chain.
4766: * h must be at "ipoff" on the mbuf chain.
4767: */
4768: void *
4769: pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
4770: u_short *actionp, u_short *reasonp, sa_family_t af)
4771: {
4772: switch (af) {
4773: #ifdef INET
4774: case AF_INET: {
4775: struct ip *h = mtod(m, struct ip *);
4776: u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
4777:
4778: if (fragoff) {
4779: if (fragoff >= len)
4780: ACTION_SET(actionp, PF_PASS);
4781: else {
4782: ACTION_SET(actionp, PF_DROP);
4783: REASON_SET(reasonp, PFRES_FRAG);
4784: }
4785: return (NULL);
4786: }
4787: if (m->m_pkthdr.len < off + len ||
4788: ntohs(h->ip_len) < off + len) {
4789: ACTION_SET(actionp, PF_DROP);
4790: REASON_SET(reasonp, PFRES_SHORT);
4791: return (NULL);
4792: }
4793: break;
4794: }
4795: #endif /* INET */
4796: #ifdef INET6
4797: case AF_INET6: {
4798: struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
4799:
4800: if (m->m_pkthdr.len < off + len ||
4801: (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) <
4802: (unsigned)(off + len)) {
4803: ACTION_SET(actionp, PF_DROP);
4804: REASON_SET(reasonp, PFRES_SHORT);
4805: return (NULL);
4806: }
4807: break;
4808: }
4809: #endif /* INET6 */
4810: }
4811: m_copydata(m, off, len, p);
4812: return (p);
4813: }
4814:
4815: int
4816: pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif)
4817: {
4818: struct sockaddr_in *dst;
4819: int ret = 1;
4820: int check_mpath;
4821: extern int ipmultipath;
4822: #ifdef INET6
4823: extern int ip6_multipath;
4824: struct sockaddr_in6 *dst6;
4825: struct route_in6 ro;
4826: #else
4827: struct route ro;
4828: #endif
4829: struct radix_node *rn;
4830: struct rtentry *rt;
4831: struct ifnet *ifp;
4832:
4833: check_mpath = 0;
4834: bzero(&ro, sizeof(ro));
4835: switch (af) {
4836: case AF_INET:
4837: dst = satosin(&ro.ro_dst);
4838: dst->sin_family = AF_INET;
4839: dst->sin_len = sizeof(*dst);
4840: dst->sin_addr = addr->v4;
4841: if (ipmultipath)
4842: check_mpath = 1;
4843: break;
4844: #ifdef INET6
4845: case AF_INET6:
4846: dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
4847: dst6->sin6_family = AF_INET6;
4848: dst6->sin6_len = sizeof(*dst6);
4849: dst6->sin6_addr = addr->v6;
4850: if (ip6_multipath)
4851: check_mpath = 1;
4852: break;
4853: #endif /* INET6 */
4854: default:
4855: return (0);
4856: }
4857:
4858: /* Skip checks for ipsec interfaces */
4859: if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
4860: goto out;
4861:
4862: rtalloc_noclone((struct route *)&ro, NO_CLONING);
4863:
4864: if (ro.ro_rt != NULL) {
4865: /* No interface given, this is a no-route check */
4866: if (kif == NULL)
4867: goto out;
4868:
4869: if (kif->pfik_ifp == NULL) {
4870: ret = 0;
4871: goto out;
4872: }
4873:
4874: /* Perform uRPF check if passed input interface */
4875: ret = 0;
4876: rn = (struct radix_node *)ro.ro_rt;
4877: do {
4878: rt = (struct rtentry *)rn;
4879: if (rt->rt_ifp->if_type == IFT_CARP)
4880: ifp = rt->rt_ifp->if_carpdev;
4881: else
4882: ifp = rt->rt_ifp;
4883:
4884: if (kif->pfik_ifp == ifp)
4885: ret = 1;
4886: rn = rn_mpath_next(rn);
4887: } while (check_mpath == 1 && rn != NULL && ret == 0);
4888: } else
4889: ret = 0;
4890: out:
4891: if (ro.ro_rt != NULL)
4892: RTFREE(ro.ro_rt);
4893: return (ret);
4894: }
4895:
4896: int
4897: pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
4898: {
4899: struct sockaddr_in *dst;
4900: #ifdef INET6
4901: struct sockaddr_in6 *dst6;
4902: struct route_in6 ro;
4903: #else
4904: struct route ro;
4905: #endif
4906: int ret = 0;
4907:
4908: bzero(&ro, sizeof(ro));
4909: switch (af) {
4910: case AF_INET:
4911: dst = satosin(&ro.ro_dst);
4912: dst->sin_family = AF_INET;
4913: dst->sin_len = sizeof(*dst);
4914: dst->sin_addr = addr->v4;
4915: break;
4916: #ifdef INET6
4917: case AF_INET6:
4918: dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
4919: dst6->sin6_family = AF_INET6;
4920: dst6->sin6_len = sizeof(*dst6);
4921: dst6->sin6_addr = addr->v6;
4922: break;
4923: #endif /* INET6 */
4924: default:
4925: return (0);
4926: }
4927:
4928: rtalloc_noclone((struct route *)&ro, NO_CLONING);
4929:
4930: if (ro.ro_rt != NULL) {
4931: if (ro.ro_rt->rt_labelid == aw->v.rtlabel)
4932: ret = 1;
4933: RTFREE(ro.ro_rt);
4934: }
4935:
4936: return (ret);
4937: }
4938:
4939: #ifdef INET
4940: void
4941: pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
4942: struct pf_state *s, struct pf_pdesc *pd)
4943: {
4944: struct mbuf *m0, *m1;
4945: struct route iproute;
4946: struct route *ro = NULL;
4947: struct sockaddr_in *dst;
4948: struct ip *ip;
4949: struct ifnet *ifp = NULL;
4950: struct pf_addr naddr;
4951: struct pf_src_node *sn = NULL;
4952: int error = 0;
4953: #ifdef IPSEC
4954: struct m_tag *mtag;
4955: #endif /* IPSEC */
4956:
4957: if (m == NULL || *m == NULL || r == NULL ||
4958: (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
4959: panic("pf_route: invalid parameters");
4960:
4961: if ((*m)->m_pkthdr.pf.routed++ > 3) {
4962: m0 = *m;
4963: *m = NULL;
4964: goto bad;
4965: }
4966:
4967: if (r->rt == PF_DUPTO) {
4968: if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
4969: return;
4970: } else {
4971: if ((r->rt == PF_REPLYTO) == (r->direction == dir))
4972: return;
4973: m0 = *m;
4974: }
4975:
4976: if (m0->m_len < sizeof(struct ip)) {
4977: DPFPRINTF(PF_DEBUG_URGENT,
4978: ("pf_route: m0->m_len < sizeof(struct ip)\n"));
4979: goto bad;
4980: }
4981:
4982: ip = mtod(m0, struct ip *);
4983:
4984: ro = &iproute;
4985: bzero((caddr_t)ro, sizeof(*ro));
4986: dst = satosin(&ro->ro_dst);
4987: dst->sin_family = AF_INET;
4988: dst->sin_len = sizeof(*dst);
4989: dst->sin_addr = ip->ip_dst;
4990:
4991: if (r->rt == PF_FASTROUTE) {
4992: rtalloc(ro);
4993: if (ro->ro_rt == 0) {
4994: ipstat.ips_noroute++;
4995: goto bad;
4996: }
4997:
4998: ifp = ro->ro_rt->rt_ifp;
4999: ro->ro_rt->rt_use++;
5000:
5001: if (ro->ro_rt->rt_flags & RTF_GATEWAY)
5002: dst = satosin(ro->ro_rt->rt_gateway);
5003: } else {
5004: if (TAILQ_EMPTY(&r->rpool.list)) {
5005: DPFPRINTF(PF_DEBUG_URGENT,
5006: ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n"));
5007: goto bad;
5008: }
5009: if (s == NULL) {
5010: pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
5011: &naddr, NULL, &sn);
5012: if (!PF_AZERO(&naddr, AF_INET))
5013: dst->sin_addr.s_addr = naddr.v4.s_addr;
5014: ifp = r->rpool.cur->kif ?
5015: r->rpool.cur->kif->pfik_ifp : NULL;
5016: } else {
5017: if (!PF_AZERO(&s->rt_addr, AF_INET))
5018: dst->sin_addr.s_addr =
5019: s->rt_addr.v4.s_addr;
5020: ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
5021: }
5022: }
5023: if (ifp == NULL)
5024: goto bad;
5025:
5026: if (oifp != ifp) {
5027: if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
5028: goto bad;
5029: else if (m0 == NULL)
5030: goto done;
5031: if (m0->m_len < sizeof(struct ip)) {
5032: DPFPRINTF(PF_DEBUG_URGENT,
5033: ("pf_route: m0->m_len < sizeof(struct ip)\n"));
5034: goto bad;
5035: }
5036: ip = mtod(m0, struct ip *);
5037: }
5038:
5039: /* Copied from ip_output. */
5040: #ifdef IPSEC
5041: /*
5042: * If deferred crypto processing is needed, check that the
5043: * interface supports it.
5044: */
5045: if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL))
5046: != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
5047: /* Notify IPsec to do its own crypto. */
5048: ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
5049: goto bad;
5050: }
5051: #endif /* IPSEC */
5052:
5053: /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
5054: if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) {
5055: if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
5056: ifp->if_bridge != NULL) {
5057: in_delayed_cksum(m0);
5058: m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clear */
5059: }
5060: } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) {
5061: if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
5062: ifp->if_bridge != NULL) {
5063: in_delayed_cksum(m0);
5064: m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clear */
5065: }
5066: }
5067:
5068: if (ntohs(ip->ip_len) <= ifp->if_mtu) {
5069: if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
5070: ifp->if_bridge == NULL) {
5071: m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
5072: ipstat.ips_outhwcsum++;
5073: } else {
5074: ip->ip_sum = 0;
5075: ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
5076: }
5077: /* Update relevant hardware checksum stats for TCP/UDP */
5078: if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
5079: tcpstat.tcps_outhwcsum++;
5080: else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
5081: udpstat.udps_outhwcsum++;
5082: error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
5083: goto done;
5084: }
5085:
5086: /*
5087: * Too large for interface; fragment if possible.
5088: * Must be able to put at least 8 bytes per fragment.
5089: */
5090: if (ip->ip_off & htons(IP_DF)) {
5091: ipstat.ips_cantfrag++;
5092: if (r->rt != PF_DUPTO) {
5093: icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5094: ifp->if_mtu);
5095: goto done;
5096: } else
5097: goto bad;
5098: }
5099:
5100: m1 = m0;
5101: error = ip_fragment(m0, ifp, ifp->if_mtu);
5102: if (error) {
5103: m0 = NULL;
5104: goto bad;
5105: }
5106:
5107: for (m0 = m1; m0; m0 = m1) {
5108: m1 = m0->m_nextpkt;
5109: m0->m_nextpkt = 0;
5110: if (error == 0)
5111: error = (*ifp->if_output)(ifp, m0, sintosa(dst),
5112: NULL);
5113: else
5114: m_freem(m0);
5115: }
5116:
5117: if (error == 0)
5118: ipstat.ips_fragmented++;
5119:
5120: done:
5121: if (r->rt != PF_DUPTO)
5122: *m = NULL;
5123: if (ro == &iproute && ro->ro_rt)
5124: RTFREE(ro->ro_rt);
5125: return;
5126:
5127: bad:
5128: m_freem(m0);
5129: goto done;
5130: }
5131: #endif /* INET */
5132:
5133: #ifdef INET6
5134: void
5135: pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5136: struct pf_state *s, struct pf_pdesc *pd)
5137: {
5138: struct mbuf *m0;
5139: struct route_in6 ip6route;
5140: struct route_in6 *ro;
5141: struct sockaddr_in6 *dst;
5142: struct ip6_hdr *ip6;
5143: struct ifnet *ifp = NULL;
5144: struct pf_addr naddr;
5145: struct pf_src_node *sn = NULL;
5146: int error = 0;
5147:
5148: if (m == NULL || *m == NULL || r == NULL ||
5149: (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
5150: panic("pf_route6: invalid parameters");
5151:
5152: if ((*m)->m_pkthdr.pf.routed++ > 3) {
5153: m0 = *m;
5154: *m = NULL;
5155: goto bad;
5156: }
5157:
5158: if (r->rt == PF_DUPTO) {
5159: if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
5160: return;
5161: } else {
5162: if ((r->rt == PF_REPLYTO) == (r->direction == dir))
5163: return;
5164: m0 = *m;
5165: }
5166:
5167: if (m0->m_len < sizeof(struct ip6_hdr)) {
5168: DPFPRINTF(PF_DEBUG_URGENT,
5169: ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
5170: goto bad;
5171: }
5172: ip6 = mtod(m0, struct ip6_hdr *);
5173:
5174: ro = &ip6route;
5175: bzero((caddr_t)ro, sizeof(*ro));
5176: dst = (struct sockaddr_in6 *)&ro->ro_dst;
5177: dst->sin6_family = AF_INET6;
5178: dst->sin6_len = sizeof(*dst);
5179: dst->sin6_addr = ip6->ip6_dst;
5180:
5181: /* Cheat. XXX why only in the v6 case??? */
5182: if (r->rt == PF_FASTROUTE) {
5183: m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
5184: ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
5185: return;
5186: }
5187:
5188: if (TAILQ_EMPTY(&r->rpool.list)) {
5189: DPFPRINTF(PF_DEBUG_URGENT,
5190: ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));
5191: goto bad;
5192: }
5193: if (s == NULL) {
5194: pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
5195: &naddr, NULL, &sn);
5196: if (!PF_AZERO(&naddr, AF_INET6))
5197: PF_ACPY((struct pf_addr *)&dst->sin6_addr,
5198: &naddr, AF_INET6);
5199: ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
5200: } else {
5201: if (!PF_AZERO(&s->rt_addr, AF_INET6))
5202: PF_ACPY((struct pf_addr *)&dst->sin6_addr,
5203: &s->rt_addr, AF_INET6);
5204: ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
5205: }
5206: if (ifp == NULL)
5207: goto bad;
5208:
5209: if (oifp != ifp) {
5210: if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
5211: goto bad;
5212: else if (m0 == NULL)
5213: goto done;
5214: if (m0->m_len < sizeof(struct ip6_hdr)) {
5215: DPFPRINTF(PF_DEBUG_URGENT,
5216: ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
5217: goto bad;
5218: }
5219: ip6 = mtod(m0, struct ip6_hdr *);
5220: }
5221:
5222: /*
5223: * If the packet is too large for the outgoing interface,
5224: * send back an icmp6 error.
5225: */
5226: if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
5227: dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
5228: if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
5229: error = nd6_output(ifp, ifp, m0, dst, NULL);
5230: } else {
5231: in6_ifstat_inc(ifp, ifs6_in_toobig);
5232: if (r->rt != PF_DUPTO)
5233: icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
5234: else
5235: goto bad;
5236: }
5237:
5238: done:
5239: if (r->rt != PF_DUPTO)
5240: *m = NULL;
5241: return;
5242:
5243: bad:
5244: m_freem(m0);
5245: goto done;
5246: }
5247: #endif /* INET6 */
5248:
5249:
5250: /*
5251: * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
5252: * off is the offset where the protocol header starts
5253: * len is the total length of protocol header plus payload
5254: * returns 0 when the checksum is valid, otherwise returns 1.
5255: */
5256: int
5257: pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
5258: sa_family_t af)
5259: {
5260: u_int16_t flag_ok, flag_bad;
5261: u_int16_t sum;
5262:
5263: switch (p) {
5264: case IPPROTO_TCP:
5265: flag_ok = M_TCP_CSUM_IN_OK;
5266: flag_bad = M_TCP_CSUM_IN_BAD;
5267: break;
5268: case IPPROTO_UDP:
5269: flag_ok = M_UDP_CSUM_IN_OK;
5270: flag_bad = M_UDP_CSUM_IN_BAD;
5271: break;
5272: case IPPROTO_ICMP:
5273: #ifdef INET6
5274: case IPPROTO_ICMPV6:
5275: #endif /* INET6 */
5276: flag_ok = flag_bad = 0;
5277: break;
5278: default:
5279: return (1);
5280: }
5281: if (m->m_pkthdr.csum_flags & flag_ok)
5282: return (0);
5283: if (m->m_pkthdr.csum_flags & flag_bad)
5284: return (1);
5285: if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
5286: return (1);
5287: if (m->m_pkthdr.len < off + len)
5288: return (1);
5289: switch (af) {
5290: #ifdef INET
5291: case AF_INET:
5292: if (p == IPPROTO_ICMP) {
5293: if (m->m_len < off)
5294: return (1);
5295: m->m_data += off;
5296: m->m_len -= off;
5297: sum = in_cksum(m, len);
5298: m->m_data -= off;
5299: m->m_len += off;
5300: } else {
5301: if (m->m_len < sizeof(struct ip))
5302: return (1);
5303: sum = in4_cksum(m, p, off, len);
5304: }
5305: break;
5306: #endif /* INET */
5307: #ifdef INET6
5308: case AF_INET6:
5309: if (m->m_len < sizeof(struct ip6_hdr))
5310: return (1);
5311: sum = in6_cksum(m, p, off, len);
5312: break;
5313: #endif /* INET6 */
5314: default:
5315: return (1);
5316: }
5317: if (sum) {
5318: m->m_pkthdr.csum_flags |= flag_bad;
5319: switch (p) {
5320: case IPPROTO_TCP:
5321: tcpstat.tcps_rcvbadsum++;
5322: break;
5323: case IPPROTO_UDP:
5324: udpstat.udps_badsum++;
5325: break;
5326: case IPPROTO_ICMP:
5327: icmpstat.icps_checksum++;
5328: break;
5329: #ifdef INET6
5330: case IPPROTO_ICMPV6:
5331: icmp6stat.icp6s_checksum++;
5332: break;
5333: #endif /* INET6 */
5334: }
5335: return (1);
5336: }
5337: m->m_pkthdr.csum_flags |= flag_ok;
5338: return (0);
5339: }
5340:
5341: #ifdef INET
5342: int
5343: pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
5344: struct ether_header *eh)
5345: {
5346: struct pfi_kif *kif;
5347: u_short action, reason = 0, log = 0;
5348: struct mbuf *m = *m0;
5349: struct ip *h;
5350: struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
5351: struct pf_state *s = NULL;
5352: struct pf_state_key *sk = NULL;
5353: struct pf_ruleset *ruleset = NULL;
5354: struct pf_pdesc pd;
5355: int off, dirndx, pqid = 0;
5356:
5357: if (!pf_status.running)
5358: return (PF_PASS);
5359:
5360: memset(&pd, 0, sizeof(pd));
5361: if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
5362: kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
5363: else
5364: kif = (struct pfi_kif *)ifp->if_pf_kif;
5365:
5366: if (kif == NULL) {
5367: DPFPRINTF(PF_DEBUG_URGENT,
5368: ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
5369: return (PF_DROP);
5370: }
5371: if (kif->pfik_flags & PFI_IFLAG_SKIP)
5372: return (PF_PASS);
5373:
5374: #ifdef DIAGNOSTIC
5375: if ((m->m_flags & M_PKTHDR) == 0)
5376: panic("non-M_PKTHDR is passed to pf_test");
5377: #endif /* DIAGNOSTIC */
5378:
5379: if (m->m_pkthdr.len < (int)sizeof(*h)) {
5380: action = PF_DROP;
5381: REASON_SET(&reason, PFRES_SHORT);
5382: log = 1;
5383: goto done;
5384: }
5385:
5386: if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
5387: return (PF_PASS);
5388:
5389: /* We do IP header normalization and packet reassembly here */
5390: if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
5391: action = PF_DROP;
5392: goto done;
5393: }
5394: m = *m0; /* pf_normalize messes with m0 */
5395: h = mtod(m, struct ip *);
5396:
5397: off = h->ip_hl << 2;
5398: if (off < (int)sizeof(*h)) {
5399: action = PF_DROP;
5400: REASON_SET(&reason, PFRES_SHORT);
5401: log = 1;
5402: goto done;
5403: }
5404:
5405: pd.src = (struct pf_addr *)&h->ip_src;
5406: pd.dst = (struct pf_addr *)&h->ip_dst;
5407: PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET);
5408: pd.ip_sum = &h->ip_sum;
5409: pd.proto = h->ip_p;
5410: pd.af = AF_INET;
5411: pd.tos = h->ip_tos;
5412: pd.tot_len = ntohs(h->ip_len);
5413: pd.eh = eh;
5414:
5415: /* handle fragments that didn't get reassembled by normalization */
5416: if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
5417: action = pf_test_fragment(&r, dir, kif, m, h,
5418: &pd, &a, &ruleset);
5419: goto done;
5420: }
5421:
5422: switch (h->ip_p) {
5423:
5424: case IPPROTO_TCP: {
5425: struct tcphdr th;
5426:
5427: pd.hdr.tcp = &th;
5428: if (!pf_pull_hdr(m, off, &th, sizeof(th),
5429: &action, &reason, AF_INET)) {
5430: log = action != PF_PASS;
5431: goto done;
5432: }
5433: pd.p_len = pd.tot_len - off - (th.th_off << 2);
5434: if ((th.th_flags & TH_ACK) && pd.p_len == 0)
5435: pqid = 1;
5436: action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
5437: if (action == PF_DROP)
5438: goto done;
5439: action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
5440: &reason);
5441: if (action == PF_PASS) {
5442: #if NPFSYNC
5443: pfsync_update_state(s);
5444: #endif /* NPFSYNC */
5445: r = s->rule.ptr;
5446: a = s->anchor.ptr;
5447: log = s->log;
5448: } else if (s == NULL)
5449: action = pf_test_rule(&r, &s, dir, kif,
5450: m, off, h, &pd, &a, &ruleset, &ipintrq);
5451: break;
5452: }
5453:
5454: case IPPROTO_UDP: {
5455: struct udphdr uh;
5456:
5457: pd.hdr.udp = &uh;
5458: if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
5459: &action, &reason, AF_INET)) {
5460: log = action != PF_PASS;
5461: goto done;
5462: }
5463: if (uh.uh_dport == 0 ||
5464: ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
5465: ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
5466: action = PF_DROP;
5467: REASON_SET(&reason, PFRES_SHORT);
5468: goto done;
5469: }
5470: action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
5471: if (action == PF_PASS) {
5472: #if NPFSYNC
5473: pfsync_update_state(s);
5474: #endif /* NPFSYNC */
5475: r = s->rule.ptr;
5476: a = s->anchor.ptr;
5477: log = s->log;
5478: } else if (s == NULL)
5479: action = pf_test_rule(&r, &s, dir, kif,
5480: m, off, h, &pd, &a, &ruleset, &ipintrq);
5481: break;
5482: }
5483:
5484: case IPPROTO_ICMP: {
5485: struct icmp ih;
5486:
5487: pd.hdr.icmp = &ih;
5488: if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
5489: &action, &reason, AF_INET)) {
5490: log = action != PF_PASS;
5491: goto done;
5492: }
5493: action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
5494: &reason);
5495: if (action == PF_PASS) {
5496: #if NPFSYNC
5497: pfsync_update_state(s);
5498: #endif /* NPFSYNC */
5499: r = s->rule.ptr;
5500: a = s->anchor.ptr;
5501: log = s->log;
5502: } else if (s == NULL)
5503: action = pf_test_rule(&r, &s, dir, kif,
5504: m, off, h, &pd, &a, &ruleset, &ipintrq);
5505: break;
5506: }
5507:
5508: default:
5509: action = pf_test_state_other(&s, dir, kif, &pd);
5510: if (action == PF_PASS) {
5511: #if NPFSYNC
5512: pfsync_update_state(s);
5513: #endif /* NPFSYNC */
5514: r = s->rule.ptr;
5515: a = s->anchor.ptr;
5516: log = s->log;
5517: } else if (s == NULL)
5518: action = pf_test_rule(&r, &s, dir, kif, m, off, h,
5519: &pd, &a, &ruleset, &ipintrq);
5520: break;
5521: }
5522:
5523: done:
5524: if (action == PF_PASS && h->ip_hl > 5 &&
5525: !((s && s->allow_opts) || r->allow_opts)) {
5526: action = PF_DROP;
5527: REASON_SET(&reason, PFRES_IPOPTIONS);
5528: log = 1;
5529: DPFPRINTF(PF_DEBUG_MISC,
5530: ("pf: dropping packet with ip options\n"));
5531: }
5532:
5533: if ((s && s->tag) || r->rtableid)
5534: pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
5535:
5536: #ifdef ALTQ
5537: if (action == PF_PASS && r->qid) {
5538: if (pqid || (pd.tos & IPTOS_LOWDELAY))
5539: m->m_pkthdr.pf.qid = r->pqid;
5540: else
5541: m->m_pkthdr.pf.qid = r->qid;
5542: /* add hints for ecn */
5543: m->m_pkthdr.pf.hdr = h;
5544: }
5545: #endif /* ALTQ */
5546:
5547: /*
5548: * connections redirected to loopback should not match sockets
5549: * bound specifically to loopback due to security implications,
5550: * see tcp_input() and in_pcblookup_listen().
5551: */
5552: if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
5553: pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
5554: (s->nat_rule.ptr->action == PF_RDR ||
5555: s->nat_rule.ptr->action == PF_BINAT) &&
5556: (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
5557: m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
5558:
5559: if (log) {
5560: struct pf_rule *lr;
5561:
5562: if (s != NULL && s->nat_rule.ptr != NULL &&
5563: s->nat_rule.ptr->log & PF_LOG_ALL)
5564: lr = s->nat_rule.ptr;
5565: else
5566: lr = r;
5567: PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset,
5568: &pd);
5569: }
5570:
5571: kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
5572: kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
5573:
5574: if (action == PF_PASS || r->action == PF_DROP) {
5575: dirndx = (dir == PF_OUT);
5576: r->packets[dirndx]++;
5577: r->bytes[dirndx] += pd.tot_len;
5578: if (a != NULL) {
5579: a->packets[dirndx]++;
5580: a->bytes[dirndx] += pd.tot_len;
5581: }
5582: if (s != NULL) {
5583: sk = s->state_key;
5584: if (s->nat_rule.ptr != NULL) {
5585: s->nat_rule.ptr->packets[dirndx]++;
5586: s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
5587: }
5588: if (s->src_node != NULL) {
5589: s->src_node->packets[dirndx]++;
5590: s->src_node->bytes[dirndx] += pd.tot_len;
5591: }
5592: if (s->nat_src_node != NULL) {
5593: s->nat_src_node->packets[dirndx]++;
5594: s->nat_src_node->bytes[dirndx] += pd.tot_len;
5595: }
5596: dirndx = (dir == sk->direction) ? 0 : 1;
5597: s->packets[dirndx]++;
5598: s->bytes[dirndx] += pd.tot_len;
5599: }
5600: tr = r;
5601: nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
5602: if (nr != NULL) {
5603: struct pf_addr *x;
5604: /*
5605: * XXX: we need to make sure that the addresses
5606: * passed to pfr_update_stats() are the same than
5607: * the addresses used during matching (pfr_match)
5608: */
5609: if (r == &pf_default_rule) {
5610: tr = nr;
5611: x = (sk == NULL || sk->direction == dir) ?
5612: &pd.baddr : &pd.naddr;
5613: } else
5614: x = (sk == NULL || sk->direction == dir) ?
5615: &pd.naddr : &pd.baddr;
5616: if (x == &pd.baddr || s == NULL) {
5617: /* we need to change the address */
5618: if (dir == PF_OUT)
5619: pd.src = x;
5620: else
5621: pd.dst = x;
5622: }
5623: }
5624: if (tr->src.addr.type == PF_ADDR_TABLE)
5625: pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
5626: sk->direction == dir) ?
5627: pd.src : pd.dst, pd.af,
5628: pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
5629: tr->src.neg);
5630: if (tr->dst.addr.type == PF_ADDR_TABLE)
5631: pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
5632: sk->direction == dir) ? pd.dst : pd.src, pd.af,
5633: pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
5634: tr->dst.neg);
5635: }
5636:
5637:
5638: if (action == PF_SYNPROXY_DROP) {
5639: m_freem(*m0);
5640: *m0 = NULL;
5641: action = PF_PASS;
5642: } else if (r->rt)
5643: /* pf_route can free the mbuf causing *m0 to become NULL */
5644: pf_route(m0, r, dir, kif->pfik_ifp, s, &pd);
5645:
5646: return (action);
5647: }
5648: #endif /* INET */
5649:
5650: #ifdef INET6
5651: int
5652: pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
5653: struct ether_header *eh)
5654: {
5655: struct pfi_kif *kif;
5656: u_short action, reason = 0, log = 0;
5657: struct mbuf *m = *m0, *n = NULL;
5658: struct ip6_hdr *h;
5659: struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
5660: struct pf_state *s = NULL;
5661: struct pf_state_key *sk = NULL;
5662: struct pf_ruleset *ruleset = NULL;
5663: struct pf_pdesc pd;
5664: int off, terminal = 0, dirndx, rh_cnt = 0;
5665:
5666: if (!pf_status.running)
5667: return (PF_PASS);
5668:
5669: memset(&pd, 0, sizeof(pd));
5670: if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
5671: kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
5672: else
5673: kif = (struct pfi_kif *)ifp->if_pf_kif;
5674:
5675: if (kif == NULL) {
5676: DPFPRINTF(PF_DEBUG_URGENT,
5677: ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
5678: return (PF_DROP);
5679: }
5680: if (kif->pfik_flags & PFI_IFLAG_SKIP)
5681: return (PF_PASS);
5682:
5683: #ifdef DIAGNOSTIC
5684: if ((m->m_flags & M_PKTHDR) == 0)
5685: panic("non-M_PKTHDR is passed to pf_test6");
5686: #endif /* DIAGNOSTIC */
5687:
5688: if (m->m_pkthdr.len < (int)sizeof(*h)) {
5689: action = PF_DROP;
5690: REASON_SET(&reason, PFRES_SHORT);
5691: log = 1;
5692: goto done;
5693: }
5694:
5695: if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
5696: return (PF_PASS);
5697:
5698: /* We do IP header normalization and packet reassembly here */
5699: if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
5700: action = PF_DROP;
5701: goto done;
5702: }
5703: m = *m0; /* pf_normalize messes with m0 */
5704: h = mtod(m, struct ip6_hdr *);
5705:
5706: #if 1
5707: /*
5708: * we do not support jumbogram yet. if we keep going, zero ip6_plen
5709: * will do something bad, so drop the packet for now.
5710: */
5711: if (htons(h->ip6_plen) == 0) {
5712: action = PF_DROP;
5713: REASON_SET(&reason, PFRES_NORM); /*XXX*/
5714: goto done;
5715: }
5716: #endif
5717:
5718: pd.src = (struct pf_addr *)&h->ip6_src;
5719: pd.dst = (struct pf_addr *)&h->ip6_dst;
5720: PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET6);
5721: pd.ip_sum = NULL;
5722: pd.af = AF_INET6;
5723: pd.tos = 0;
5724: pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
5725: pd.eh = eh;
5726:
5727: off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
5728: pd.proto = h->ip6_nxt;
5729: do {
5730: switch (pd.proto) {
5731: case IPPROTO_FRAGMENT:
5732: action = pf_test_fragment(&r, dir, kif, m, h,
5733: &pd, &a, &ruleset);
5734: if (action == PF_DROP)
5735: REASON_SET(&reason, PFRES_FRAG);
5736: goto done;
5737: case IPPROTO_ROUTING: {
5738: struct ip6_rthdr rthdr;
5739:
5740: if (rh_cnt++) {
5741: DPFPRINTF(PF_DEBUG_MISC,
5742: ("pf: IPv6 more than one rthdr\n"));
5743: action = PF_DROP;
5744: REASON_SET(&reason, PFRES_IPOPTIONS);
5745: log = 1;
5746: goto done;
5747: }
5748: if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL,
5749: &reason, pd.af)) {
5750: DPFPRINTF(PF_DEBUG_MISC,
5751: ("pf: IPv6 short rthdr\n"));
5752: action = PF_DROP;
5753: REASON_SET(&reason, PFRES_SHORT);
5754: log = 1;
5755: goto done;
5756: }
5757: if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
5758: DPFPRINTF(PF_DEBUG_MISC,
5759: ("pf: IPv6 rthdr0\n"));
5760: action = PF_DROP;
5761: REASON_SET(&reason, PFRES_IPOPTIONS);
5762: log = 1;
5763: goto done;
5764: }
5765: /* FALLTHROUGH */
5766: }
5767: case IPPROTO_AH:
5768: case IPPROTO_HOPOPTS:
5769: case IPPROTO_DSTOPTS: {
5770: /* get next header and header length */
5771: struct ip6_ext opt6;
5772:
5773: if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
5774: NULL, &reason, pd.af)) {
5775: DPFPRINTF(PF_DEBUG_MISC,
5776: ("pf: IPv6 short opt\n"));
5777: action = PF_DROP;
5778: log = 1;
5779: goto done;
5780: }
5781: if (pd.proto == IPPROTO_AH)
5782: off += (opt6.ip6e_len + 2) * 4;
5783: else
5784: off += (opt6.ip6e_len + 1) * 8;
5785: pd.proto = opt6.ip6e_nxt;
5786: /* goto the next header */
5787: break;
5788: }
5789: default:
5790: terminal++;
5791: break;
5792: }
5793: } while (!terminal);
5794:
5795: /* if there's no routing header, use unmodified mbuf for checksumming */
5796: if (!n)
5797: n = m;
5798:
5799: switch (pd.proto) {
5800:
5801: case IPPROTO_TCP: {
5802: struct tcphdr th;
5803:
5804: pd.hdr.tcp = &th;
5805: if (!pf_pull_hdr(m, off, &th, sizeof(th),
5806: &action, &reason, AF_INET6)) {
5807: log = action != PF_PASS;
5808: goto done;
5809: }
5810: pd.p_len = pd.tot_len - off - (th.th_off << 2);
5811: action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
5812: if (action == PF_DROP)
5813: goto done;
5814: action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
5815: &reason);
5816: if (action == PF_PASS) {
5817: #if NPFSYNC
5818: pfsync_update_state(s);
5819: #endif /* NPFSYNC */
5820: r = s->rule.ptr;
5821: a = s->anchor.ptr;
5822: log = s->log;
5823: } else if (s == NULL)
5824: action = pf_test_rule(&r, &s, dir, kif,
5825: m, off, h, &pd, &a, &ruleset, &ip6intrq);
5826: break;
5827: }
5828:
5829: case IPPROTO_UDP: {
5830: struct udphdr uh;
5831:
5832: pd.hdr.udp = &uh;
5833: if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
5834: &action, &reason, AF_INET6)) {
5835: log = action != PF_PASS;
5836: goto done;
5837: }
5838: if (uh.uh_dport == 0 ||
5839: ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
5840: ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
5841: action = PF_DROP;
5842: REASON_SET(&reason, PFRES_SHORT);
5843: goto done;
5844: }
5845: action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
5846: if (action == PF_PASS) {
5847: #if NPFSYNC
5848: pfsync_update_state(s);
5849: #endif /* NPFSYNC */
5850: r = s->rule.ptr;
5851: a = s->anchor.ptr;
5852: log = s->log;
5853: } else if (s == NULL)
5854: action = pf_test_rule(&r, &s, dir, kif,
5855: m, off, h, &pd, &a, &ruleset, &ip6intrq);
5856: break;
5857: }
5858:
5859: case IPPROTO_ICMPV6: {
5860: struct icmp6_hdr ih;
5861:
5862: pd.hdr.icmp6 = &ih;
5863: if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
5864: &action, &reason, AF_INET6)) {
5865: log = action != PF_PASS;
5866: goto done;
5867: }
5868: action = pf_test_state_icmp(&s, dir, kif,
5869: m, off, h, &pd, &reason);
5870: if (action == PF_PASS) {
5871: #if NPFSYNC
5872: pfsync_update_state(s);
5873: #endif /* NPFSYNC */
5874: r = s->rule.ptr;
5875: a = s->anchor.ptr;
5876: log = s->log;
5877: } else if (s == NULL)
5878: action = pf_test_rule(&r, &s, dir, kif,
5879: m, off, h, &pd, &a, &ruleset, &ip6intrq);
5880: break;
5881: }
5882:
5883: default:
5884: action = pf_test_state_other(&s, dir, kif, &pd);
5885: if (action == PF_PASS) {
5886: #if NPFSYNC
5887: pfsync_update_state(s);
5888: #endif /* NPFSYNC */
5889: r = s->rule.ptr;
5890: a = s->anchor.ptr;
5891: log = s->log;
5892: } else if (s == NULL)
5893: action = pf_test_rule(&r, &s, dir, kif, m, off, h,
5894: &pd, &a, &ruleset, &ip6intrq);
5895: break;
5896: }
5897:
5898: done:
5899: if (n != m) {
5900: m_freem(n);
5901: n = NULL;
5902: }
5903:
5904: /* handle dangerous IPv6 extension headers. */
5905: if (action == PF_PASS && rh_cnt &&
5906: !((s && s->allow_opts) || r->allow_opts)) {
5907: action = PF_DROP;
5908: REASON_SET(&reason, PFRES_IPOPTIONS);
5909: log = 1;
5910: DPFPRINTF(PF_DEBUG_MISC,
5911: ("pf: dropping packet with dangerous v6 headers\n"));
5912: }
5913:
5914: if ((s && s->tag) || r->rtableid)
5915: pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
5916:
5917: #ifdef ALTQ
5918: if (action == PF_PASS && r->qid) {
5919: if (pd.tos & IPTOS_LOWDELAY)
5920: m->m_pkthdr.pf.qid = r->pqid;
5921: else
5922: m->m_pkthdr.pf.qid = r->qid;
5923: /* add hints for ecn */
5924: m->m_pkthdr.pf.hdr = h;
5925: }
5926: #endif /* ALTQ */
5927:
5928: if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
5929: pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
5930: (s->nat_rule.ptr->action == PF_RDR ||
5931: s->nat_rule.ptr->action == PF_BINAT) &&
5932: IN6_IS_ADDR_LOOPBACK(&pd.dst->v6))
5933: m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
5934:
5935: if (log) {
5936: struct pf_rule *lr;
5937:
5938: if (s != NULL && s->nat_rule.ptr != NULL &&
5939: s->nat_rule.ptr->log & PF_LOG_ALL)
5940: lr = s->nat_rule.ptr;
5941: else
5942: lr = r;
5943: PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset,
5944: &pd);
5945: }
5946:
5947: kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
5948: kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
5949:
5950: if (action == PF_PASS || r->action == PF_DROP) {
5951: dirndx = (dir == PF_OUT);
5952: r->packets[dirndx]++;
5953: r->bytes[dirndx] += pd.tot_len;
5954: if (a != NULL) {
5955: a->packets[dirndx]++;
5956: a->bytes[dirndx] += pd.tot_len;
5957: }
5958: if (s != NULL) {
5959: sk = s->state_key;
5960: if (s->nat_rule.ptr != NULL) {
5961: s->nat_rule.ptr->packets[dirndx]++;
5962: s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
5963: }
5964: if (s->src_node != NULL) {
5965: s->src_node->packets[dirndx]++;
5966: s->src_node->bytes[dirndx] += pd.tot_len;
5967: }
5968: if (s->nat_src_node != NULL) {
5969: s->nat_src_node->packets[dirndx]++;
5970: s->nat_src_node->bytes[dirndx] += pd.tot_len;
5971: }
5972: dirndx = (dir == sk->direction) ? 0 : 1;
5973: s->packets[dirndx]++;
5974: s->bytes[dirndx] += pd.tot_len;
5975: }
5976: tr = r;
5977: nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
5978: if (nr != NULL) {
5979: struct pf_addr *x;
5980: /*
5981: * XXX: we need to make sure that the addresses
5982: * passed to pfr_update_stats() are the same than
5983: * the addresses used during matching (pfr_match)
5984: */
5985: if (r == &pf_default_rule) {
5986: tr = nr;
5987: x = (s == NULL || sk->direction == dir) ?
5988: &pd.baddr : &pd.naddr;
5989: } else {
5990: x = (s == NULL || sk->direction == dir) ?
5991: &pd.naddr : &pd.baddr;
5992: }
5993: if (x == &pd.baddr || s == NULL) {
5994: if (dir == PF_OUT)
5995: pd.src = x;
5996: else
5997: pd.dst = x;
5998: }
5999: }
6000: if (tr->src.addr.type == PF_ADDR_TABLE)
6001: pfr_update_stats(tr->src.addr.p.tbl, (sk == NULL ||
6002: sk->direction == dir) ? pd.src : pd.dst, pd.af,
6003: pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6004: tr->src.neg);
6005: if (tr->dst.addr.type == PF_ADDR_TABLE)
6006: pfr_update_stats(tr->dst.addr.p.tbl, (sk == NULL ||
6007: sk->direction == dir) ? pd.dst : pd.src, pd.af,
6008: pd.tot_len, dir == PF_OUT, r->action == PF_PASS,
6009: tr->dst.neg);
6010: }
6011:
6012:
6013: if (action == PF_SYNPROXY_DROP) {
6014: m_freem(*m0);
6015: *m0 = NULL;
6016: action = PF_PASS;
6017: } else if (r->rt)
6018: /* pf_route6 can free the mbuf causing *m0 to become NULL */
6019: pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd);
6020:
6021: return (action);
6022: }
6023: #endif /* INET6 */
6024:
6025: int
6026: pf_check_congestion(struct ifqueue *ifq)
6027: {
6028: if (ifq->ifq_congestion)
6029: return (1);
6030: else
6031: return (0);
6032: }
CVSweb