Line data Source code
1 : /* $OpenBSD: pf.c,v 1.1075 2018/09/13 19:53:58 bluhm Exp $ */
2 :
3 : /*
4 : * Copyright (c) 2001 Daniel Hartmeier
5 : * Copyright (c) 2002 - 2013 Henning Brauer <henning@openbsd.org>
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 "carp.h"
40 : #include "pflog.h"
41 : #include "pfsync.h"
42 : #include "pflow.h"
43 :
44 : #include <sys/param.h>
45 : #include <sys/systm.h>
46 : #include <sys/mbuf.h>
47 : #include <sys/filio.h>
48 : #include <sys/socket.h>
49 : #include <sys/socketvar.h>
50 : #include <sys/kernel.h>
51 : #include <sys/time.h>
52 : #include <sys/pool.h>
53 : #include <sys/proc.h>
54 : #include <sys/rwlock.h>
55 : #include <sys/syslog.h>
56 :
57 : #include <crypto/sha2.h>
58 :
59 : #include <net/if.h>
60 : #include <net/if_var.h>
61 : #include <net/if_types.h>
62 : #include <net/route.h>
63 :
64 : #include <netinet/in.h>
65 : #include <netinet/in_var.h>
66 : #include <netinet/ip.h>
67 : #include <netinet/in_pcb.h>
68 : #include <netinet/ip_var.h>
69 : #include <netinet/ip_icmp.h>
70 : #include <netinet/icmp_var.h>
71 : #include <netinet/tcp.h>
72 : #include <netinet/tcp_seq.h>
73 : #include <netinet/tcp_timer.h>
74 : #include <netinet/tcp_var.h>
75 : #include <netinet/tcp_fsm.h>
76 : #include <netinet/udp.h>
77 : #include <netinet/udp_var.h>
78 : #include <netinet/ip_divert.h>
79 :
80 : #ifdef INET6
81 : #include <netinet6/in6_var.h>
82 : #include <netinet/ip6.h>
83 : #include <netinet6/ip6_var.h>
84 : #include <netinet/icmp6.h>
85 : #include <netinet6/nd6.h>
86 : #include <netinet6/ip6_divert.h>
87 : #endif /* INET6 */
88 :
89 : #include <net/pfvar.h>
90 : #include <net/pfvar_priv.h>
91 :
92 : #if NPFLOG > 0
93 : #include <net/if_pflog.h>
94 : #endif /* NPFLOG > 0 */
95 :
96 : #if NPFLOW > 0
97 : #include <net/if_pflow.h>
98 : #endif /* NPFLOW > 0 */
99 :
100 : #if NPFSYNC > 0
101 : #include <net/if_pfsync.h>
102 : #endif /* NPFSYNC > 0 */
103 :
104 : #ifdef DDB
105 : #include <machine/db_machdep.h>
106 : #include <ddb/db_interface.h>
107 : #endif
108 :
109 : /*
110 : * Global variables
111 : */
112 : struct pf_state_tree pf_statetbl;
113 : struct pf_queuehead pf_queues[2];
114 : struct pf_queuehead *pf_queues_active;
115 : struct pf_queuehead *pf_queues_inactive;
116 :
117 : struct pf_status pf_status;
118 :
119 : int pf_hdr_limit = 20; /* arbitrary limit, tune in ddb */
120 :
121 : SHA2_CTX pf_tcp_secret_ctx;
122 : u_char pf_tcp_secret[16];
123 : int pf_tcp_secret_init;
124 : int pf_tcp_iss_off;
125 :
126 : int pf_npurge;
127 : struct task pf_purge_task = TASK_INITIALIZER(pf_purge, &pf_npurge);
128 : struct timeout pf_purge_to = TIMEOUT_INITIALIZER(pf_purge_timeout, NULL);
129 :
130 : enum pf_test_status {
131 : PF_TEST_FAIL = -1,
132 : PF_TEST_OK,
133 : PF_TEST_QUICK
134 : };
135 :
136 : struct pf_test_ctx {
137 : enum pf_test_status test_status;
138 : struct pf_pdesc *pd;
139 : struct pf_rule_actions act;
140 : u_int8_t icmpcode;
141 : u_int8_t icmptype;
142 : int icmp_dir;
143 : int state_icmp;
144 : int tag;
145 : u_short reason;
146 : struct pf_rule_item *ri;
147 : struct pf_src_node *sns[PF_SN_MAX];
148 : struct pf_rule_slist rules;
149 : struct pf_rule *nr;
150 : struct pf_rule **rm;
151 : struct pf_rule *a;
152 : struct pf_rule **am;
153 : struct pf_ruleset **rsm;
154 : struct pf_ruleset *arsm;
155 : struct pf_ruleset *aruleset;
156 : struct tcphdr *th;
157 : int depth;
158 : };
159 :
160 : #define PF_ANCHOR_STACK_MAX 64
161 :
162 : struct pool pf_src_tree_pl, pf_rule_pl, pf_queue_pl;
163 : struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl;
164 : struct pool pf_rule_item_pl, pf_sn_item_pl, pf_pktdelay_pl;
165 :
166 : void pf_add_threshold(struct pf_threshold *);
167 : int pf_check_threshold(struct pf_threshold *);
168 : int pf_check_tcp_cksum(struct mbuf *, int, int,
169 : sa_family_t);
170 : static __inline void pf_cksum_fixup(u_int16_t *, u_int16_t, u_int16_t,
171 : u_int8_t);
172 : void pf_cksum_fixup_a(u_int16_t *, const struct pf_addr *,
173 : const struct pf_addr *, sa_family_t, u_int8_t);
174 : int pf_modulate_sack(struct pf_pdesc *,
175 : struct pf_state_peer *);
176 : int pf_icmp_mapping(struct pf_pdesc *, u_int8_t, int *,
177 : u_int16_t *, u_int16_t *);
178 : int pf_change_icmp_af(struct mbuf *, int,
179 : struct pf_pdesc *, struct pf_pdesc *,
180 : struct pf_addr *, struct pf_addr *, sa_family_t,
181 : sa_family_t);
182 : int pf_translate_a(struct pf_pdesc *, struct pf_addr *,
183 : struct pf_addr *);
184 : void pf_translate_icmp(struct pf_pdesc *, struct pf_addr *,
185 : u_int16_t *, struct pf_addr *, struct pf_addr *,
186 : u_int16_t);
187 : int pf_translate_icmp_af(struct pf_pdesc*, int, void *);
188 : void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, int,
189 : sa_family_t, struct pf_rule *, u_int);
190 : void pf_detach_state(struct pf_state *);
191 : void pf_state_key_detach(struct pf_state *, int);
192 : u_int32_t pf_tcp_iss(struct pf_pdesc *);
193 : void pf_rule_to_actions(struct pf_rule *,
194 : struct pf_rule_actions *);
195 : int pf_test_rule(struct pf_pdesc *, struct pf_rule **,
196 : struct pf_state **, struct pf_rule **,
197 : struct pf_ruleset **, u_short *);
198 : static __inline int pf_create_state(struct pf_pdesc *, struct pf_rule *,
199 : struct pf_rule *, struct pf_rule *,
200 : struct pf_state_key **, struct pf_state_key **,
201 : int *, struct pf_state **, int,
202 : struct pf_rule_slist *, struct pf_rule_actions *,
203 : struct pf_src_node *[]);
204 : static __inline int pf_state_key_addr_setup(struct pf_pdesc *, void *,
205 : int, struct pf_addr *, int, struct pf_addr *,
206 : int, int);
207 : int pf_state_key_setup(struct pf_pdesc *, struct
208 : pf_state_key **, struct pf_state_key **, int);
209 : int pf_tcp_track_full(struct pf_pdesc *,
210 : struct pf_state **, u_short *, int *, int);
211 : int pf_tcp_track_sloppy(struct pf_pdesc *,
212 : struct pf_state **, u_short *);
213 : static __inline int pf_synproxy(struct pf_pdesc *, struct pf_state **,
214 : u_short *);
215 : int pf_test_state(struct pf_pdesc *, struct pf_state **,
216 : u_short *, int);
217 : int pf_icmp_state_lookup(struct pf_pdesc *,
218 : struct pf_state_key_cmp *, struct pf_state **,
219 : u_int16_t, u_int16_t, int, int *, int, int);
220 : int pf_test_state_icmp(struct pf_pdesc *,
221 : struct pf_state **, u_short *);
222 : u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, int,
223 : u_int16_t);
224 : static __inline int pf_set_rt_ifp(struct pf_state *, struct pf_addr *,
225 : sa_family_t);
226 : struct pf_divert *pf_get_divert(struct mbuf *);
227 : int pf_walk_header(struct pf_pdesc *, struct ip *,
228 : u_short *);
229 : int pf_walk_option6(struct pf_pdesc *, struct ip6_hdr *,
230 : int, int, u_short *);
231 : int pf_walk_header6(struct pf_pdesc *, struct ip6_hdr *,
232 : u_short *);
233 : void pf_print_state_parts(struct pf_state *,
234 : struct pf_state_key *, struct pf_state_key *);
235 : int pf_addr_wrap_neq(struct pf_addr_wrap *,
236 : struct pf_addr_wrap *);
237 : int pf_compare_state_keys(struct pf_state_key *,
238 : struct pf_state_key *, struct pfi_kif *, u_int);
239 : int pf_find_state(struct pf_pdesc *,
240 : struct pf_state_key_cmp *, struct pf_state **);
241 : int pf_src_connlimit(struct pf_state **);
242 : int pf_match_rcvif(struct mbuf *, struct pf_rule *);
243 : int pf_step_into_anchor(struct pf_test_ctx *,
244 : struct pf_rule *);
245 : int pf_match_rule(struct pf_test_ctx *,
246 : struct pf_ruleset *);
247 : void pf_counters_inc(int, struct pf_pdesc *,
248 : struct pf_state *, struct pf_rule *,
249 : struct pf_rule *);
250 :
251 : int pf_state_key_isvalid(struct pf_state_key *);
252 : struct pf_state_key *pf_state_key_ref(struct pf_state_key *);
253 : void pf_state_key_unref(struct pf_state_key *);
254 : void pf_state_key_link_reverse(struct pf_state_key *,
255 : struct pf_state_key *);
256 : void pf_state_key_unlink_reverse(struct pf_state_key *);
257 : void pf_state_key_link_inpcb(struct pf_state_key *,
258 : struct inpcb *);
259 : void pf_state_key_unlink_inpcb(struct pf_state_key *);
260 : void pf_inpcb_unlink_state_key(struct inpcb *);
261 : void pf_pktenqueue_delayed(void *);
262 :
263 : #if NPFLOG > 0
264 : void pf_log_matches(struct pf_pdesc *, struct pf_rule *,
265 : struct pf_rule *, struct pf_ruleset *,
266 : struct pf_rule_slist *);
267 : #endif /* NPFLOG > 0 */
268 :
269 : extern struct pool pfr_ktable_pl;
270 : extern struct pool pfr_kentry_pl;
271 :
272 : struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
273 : { &pf_state_pl, PFSTATE_HIWAT, PFSTATE_HIWAT },
274 : { &pf_src_tree_pl, PFSNODE_HIWAT, PFSNODE_HIWAT },
275 : { &pf_frent_pl, PFFRAG_FRENT_HIWAT, PFFRAG_FRENT_HIWAT },
276 : { &pfr_ktable_pl, PFR_KTABLE_HIWAT, PFR_KTABLE_HIWAT },
277 : { &pfr_kentry_pl, PFR_KENTRY_HIWAT, PFR_KENTRY_HIWAT },
278 : { &pf_pktdelay_pl, PF_PKTDELAY_MAXPKTS, PF_PKTDELAY_MAXPKTS }
279 : };
280 :
281 : #define BOUND_IFACE(r, k) \
282 : ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
283 :
284 : #define STATE_INC_COUNTERS(s) \
285 : do { \
286 : struct pf_rule_item *mrm; \
287 : s->rule.ptr->states_cur++; \
288 : s->rule.ptr->states_tot++; \
289 : if (s->anchor.ptr != NULL) { \
290 : s->anchor.ptr->states_cur++; \
291 : s->anchor.ptr->states_tot++; \
292 : } \
293 : SLIST_FOREACH(mrm, &s->match_rules, entry) \
294 : mrm->r->states_cur++; \
295 : } while (0)
296 :
297 : static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
298 : static __inline int pf_state_compare_key(struct pf_state_key *,
299 : struct pf_state_key *);
300 : static __inline int pf_state_compare_id(struct pf_state *,
301 : struct pf_state *);
302 : #ifdef INET6
303 : static __inline void pf_cksum_uncover(u_int16_t *, u_int16_t, u_int8_t);
304 : static __inline void pf_cksum_cover(u_int16_t *, u_int16_t, u_int8_t);
305 : #endif /* INET6 */
306 : static __inline void pf_set_protostate(struct pf_state *, int, u_int8_t);
307 :
308 : struct pf_src_tree tree_src_tracking;
309 :
310 : struct pf_state_tree_id tree_id;
311 : struct pf_state_queue state_list;
312 :
313 0 : RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
314 0 : RB_GENERATE(pf_state_tree, pf_state_key, entry, pf_state_compare_key);
315 0 : RB_GENERATE(pf_state_tree_id, pf_state,
316 : entry_id, pf_state_compare_id);
317 :
318 : SLIST_HEAD(pf_rule_gcl, pf_rule) pf_rule_gcl =
319 : SLIST_HEAD_INITIALIZER(pf_rule_gcl);
320 :
321 : __inline int
322 0 : pf_addr_compare(struct pf_addr *a, struct pf_addr *b, sa_family_t af)
323 : {
324 0 : switch (af) {
325 : case AF_INET:
326 0 : if (a->addr32[0] > b->addr32[0])
327 0 : return (1);
328 0 : if (a->addr32[0] < b->addr32[0])
329 0 : return (-1);
330 : break;
331 : #ifdef INET6
332 : case AF_INET6:
333 0 : if (a->addr32[3] > b->addr32[3])
334 0 : return (1);
335 0 : if (a->addr32[3] < b->addr32[3])
336 0 : return (-1);
337 0 : if (a->addr32[2] > b->addr32[2])
338 0 : return (1);
339 0 : if (a->addr32[2] < b->addr32[2])
340 0 : return (-1);
341 0 : if (a->addr32[1] > b->addr32[1])
342 0 : return (1);
343 0 : if (a->addr32[1] < b->addr32[1])
344 0 : return (-1);
345 0 : if (a->addr32[0] > b->addr32[0])
346 0 : return (1);
347 0 : if (a->addr32[0] < b->addr32[0])
348 0 : return (-1);
349 : break;
350 : #endif /* INET6 */
351 : }
352 0 : return (0);
353 0 : }
354 :
355 : static __inline int
356 0 : pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
357 : {
358 : int diff;
359 :
360 0 : if (a->rule.ptr > b->rule.ptr)
361 0 : return (1);
362 0 : if (a->rule.ptr < b->rule.ptr)
363 0 : return (-1);
364 0 : if ((diff = a->type - b->type) != 0)
365 0 : return (diff);
366 0 : if ((diff = a->af - b->af) != 0)
367 0 : return (diff);
368 0 : if ((diff = pf_addr_compare(&a->addr, &b->addr, a->af)) != 0)
369 0 : return (diff);
370 0 : return (0);
371 0 : }
372 :
373 : static __inline void
374 0 : pf_set_protostate(struct pf_state *s, int which, u_int8_t newstate)
375 : {
376 0 : if (which == PF_PEER_DST || which == PF_PEER_BOTH)
377 0 : s->dst.state = newstate;
378 0 : if (which == PF_PEER_DST)
379 : return;
380 :
381 0 : if (s->src.state == newstate)
382 : return;
383 0 : if (s->creatorid == pf_status.hostid && s->key[PF_SK_STACK] != NULL &&
384 0 : s->key[PF_SK_STACK]->proto == IPPROTO_TCP &&
385 0 : !(TCPS_HAVEESTABLISHED(s->src.state) ||
386 0 : s->src.state == TCPS_CLOSED) &&
387 0 : (TCPS_HAVEESTABLISHED(newstate) || newstate == TCPS_CLOSED))
388 0 : pf_status.states_halfopen--;
389 :
390 0 : s->src.state = newstate;
391 0 : }
392 :
393 : void
394 0 : pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
395 : {
396 0 : switch (af) {
397 : case AF_INET:
398 0 : dst->addr32[0] = src->addr32[0];
399 0 : break;
400 : #ifdef INET6
401 : case AF_INET6:
402 0 : dst->addr32[0] = src->addr32[0];
403 0 : dst->addr32[1] = src->addr32[1];
404 0 : dst->addr32[2] = src->addr32[2];
405 0 : dst->addr32[3] = src->addr32[3];
406 0 : break;
407 : #endif /* INET6 */
408 : default:
409 0 : unhandled_af(af);
410 : }
411 0 : }
412 :
413 : void
414 0 : pf_init_threshold(struct pf_threshold *threshold,
415 : u_int32_t limit, u_int32_t seconds)
416 : {
417 0 : threshold->limit = limit * PF_THRESHOLD_MULT;
418 0 : threshold->seconds = seconds;
419 0 : threshold->count = 0;
420 0 : threshold->last = time_uptime;
421 0 : }
422 :
423 : void
424 0 : pf_add_threshold(struct pf_threshold *threshold)
425 : {
426 0 : u_int32_t t = time_uptime, diff = t - threshold->last;
427 :
428 0 : if (diff >= threshold->seconds)
429 0 : threshold->count = 0;
430 : else
431 0 : threshold->count -= threshold->count * diff /
432 : threshold->seconds;
433 0 : threshold->count += PF_THRESHOLD_MULT;
434 0 : threshold->last = t;
435 0 : }
436 :
437 : int
438 0 : pf_check_threshold(struct pf_threshold *threshold)
439 : {
440 0 : return (threshold->count > threshold->limit);
441 : }
442 :
443 : int
444 0 : pf_src_connlimit(struct pf_state **state)
445 : {
446 : int bad = 0;
447 : struct pf_src_node *sn;
448 :
449 0 : if ((sn = pf_get_src_node((*state), PF_SN_NONE)) == NULL)
450 0 : return (0);
451 :
452 0 : sn->conn++;
453 0 : (*state)->src.tcp_est = 1;
454 0 : pf_add_threshold(&sn->conn_rate);
455 :
456 0 : if ((*state)->rule.ptr->max_src_conn &&
457 0 : (*state)->rule.ptr->max_src_conn < sn->conn) {
458 0 : pf_status.lcounters[LCNT_SRCCONN]++;
459 : bad++;
460 0 : }
461 :
462 0 : if ((*state)->rule.ptr->max_src_conn_rate.limit &&
463 0 : pf_check_threshold(&sn->conn_rate)) {
464 0 : pf_status.lcounters[LCNT_SRCCONNRATE]++;
465 0 : bad++;
466 0 : }
467 :
468 0 : if (!bad)
469 0 : return (0);
470 :
471 0 : if ((*state)->rule.ptr->overload_tbl) {
472 0 : struct pfr_addr p;
473 : u_int32_t killed = 0;
474 :
475 0 : pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
476 0 : if (pf_status.debug >= LOG_NOTICE) {
477 0 : log(LOG_NOTICE,
478 : "pf: pf_src_connlimit: blocking address ");
479 0 : pf_print_host(&sn->addr, 0,
480 0 : (*state)->key[PF_SK_WIRE]->af);
481 0 : }
482 :
483 0 : memset(&p, 0, sizeof(p));
484 0 : p.pfra_af = (*state)->key[PF_SK_WIRE]->af;
485 0 : switch ((*state)->key[PF_SK_WIRE]->af) {
486 : case AF_INET:
487 0 : p.pfra_net = 32;
488 0 : p.pfra_ip4addr = sn->addr.v4;
489 0 : break;
490 : #ifdef INET6
491 : case AF_INET6:
492 0 : p.pfra_net = 128;
493 0 : p.pfra_ip6addr = sn->addr.v6;
494 0 : break;
495 : #endif /* INET6 */
496 : }
497 :
498 0 : pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
499 0 : &p, time_second);
500 :
501 : /* kill existing states if that's required. */
502 0 : if ((*state)->rule.ptr->flush) {
503 : struct pf_state_key *sk;
504 : struct pf_state *st;
505 :
506 0 : pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
507 0 : RB_FOREACH(st, pf_state_tree_id, &tree_id) {
508 0 : sk = st->key[PF_SK_WIRE];
509 : /*
510 : * Kill states from this source. (Only those
511 : * from the same rule if PF_FLUSH_GLOBAL is not
512 : * set)
513 : */
514 0 : if (sk->af ==
515 0 : (*state)->key[PF_SK_WIRE]->af &&
516 0 : (((*state)->direction == PF_OUT &&
517 0 : PF_AEQ(&sn->addr, &sk->addr[1], sk->af)) ||
518 0 : ((*state)->direction == PF_IN &&
519 0 : PF_AEQ(&sn->addr, &sk->addr[0], sk->af))) &&
520 0 : ((*state)->rule.ptr->flush &
521 0 : PF_FLUSH_GLOBAL ||
522 0 : (*state)->rule.ptr == st->rule.ptr)) {
523 0 : st->timeout = PFTM_PURGE;
524 0 : pf_set_protostate(st, PF_PEER_BOTH,
525 : TCPS_CLOSED);
526 0 : killed++;
527 0 : }
528 : }
529 0 : if (pf_status.debug >= LOG_NOTICE)
530 0 : addlog(", %u states killed", killed);
531 0 : }
532 0 : if (pf_status.debug >= LOG_NOTICE)
533 0 : addlog("\n");
534 0 : }
535 :
536 : /* kill this state */
537 0 : (*state)->timeout = PFTM_PURGE;
538 0 : pf_set_protostate(*state, PF_PEER_BOTH, TCPS_CLOSED);
539 0 : return (1);
540 0 : }
541 :
542 : int
543 0 : pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
544 : enum pf_sn_types type, sa_family_t af, struct pf_addr *src,
545 : struct pf_addr *raddr)
546 : {
547 0 : struct pf_src_node k;
548 :
549 0 : if (*sn == NULL) {
550 0 : k.af = af;
551 0 : k.type = type;
552 0 : PF_ACPY(&k.addr, src, af);
553 0 : k.rule.ptr = rule;
554 0 : pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
555 0 : *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
556 0 : }
557 0 : if (*sn == NULL) {
558 0 : if (!rule->max_src_nodes ||
559 0 : rule->src_nodes < rule->max_src_nodes)
560 0 : (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT | PR_ZERO);
561 : else
562 0 : pf_status.lcounters[LCNT_SRCNODES]++;
563 0 : if ((*sn) == NULL)
564 0 : return (-1);
565 :
566 0 : pf_init_threshold(&(*sn)->conn_rate,
567 0 : rule->max_src_conn_rate.limit,
568 0 : rule->max_src_conn_rate.seconds);
569 :
570 0 : (*sn)->type = type;
571 0 : (*sn)->af = af;
572 0 : (*sn)->rule.ptr = rule;
573 0 : PF_ACPY(&(*sn)->addr, src, af);
574 0 : if (raddr)
575 0 : PF_ACPY(&(*sn)->raddr, raddr, af);
576 0 : if (RB_INSERT(pf_src_tree,
577 0 : &tree_src_tracking, *sn) != NULL) {
578 0 : if (pf_status.debug >= LOG_NOTICE) {
579 0 : log(LOG_NOTICE,
580 : "pf: src_tree insert failed: ");
581 0 : pf_print_host(&(*sn)->addr, 0, af);
582 0 : addlog("\n");
583 0 : }
584 0 : pool_put(&pf_src_tree_pl, *sn);
585 0 : return (-1);
586 : }
587 0 : (*sn)->creation = time_uptime;
588 0 : (*sn)->rule.ptr->src_nodes++;
589 0 : pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
590 0 : pf_status.src_nodes++;
591 0 : } else {
592 0 : if (rule->max_src_states &&
593 0 : (*sn)->states >= rule->max_src_states) {
594 0 : pf_status.lcounters[LCNT_SRCSTATES]++;
595 0 : return (-1);
596 : }
597 : }
598 0 : return (0);
599 0 : }
600 :
601 : void
602 0 : pf_remove_src_node(struct pf_src_node *sn)
603 : {
604 0 : if (sn->states > 0 || sn->expire > time_uptime)
605 : return;
606 :
607 0 : sn->rule.ptr->src_nodes--;
608 0 : if (sn->rule.ptr->states_cur == 0 &&
609 0 : sn->rule.ptr->src_nodes == 0)
610 0 : pf_rm_rule(NULL, sn->rule.ptr);
611 0 : RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
612 0 : pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
613 0 : pf_status.src_nodes--;
614 0 : pool_put(&pf_src_tree_pl, sn);
615 0 : }
616 :
617 : struct pf_src_node *
618 0 : pf_get_src_node(struct pf_state *s, enum pf_sn_types type)
619 : {
620 : struct pf_sn_item *sni;
621 :
622 0 : SLIST_FOREACH(sni, &s->src_nodes, next)
623 0 : if (sni->sn->type == type)
624 0 : return (sni->sn);
625 0 : return (NULL);
626 0 : }
627 :
628 : void
629 0 : pf_state_rm_src_node(struct pf_state *s, struct pf_src_node *sn)
630 : {
631 : struct pf_sn_item *sni, *snin, *snip = NULL;
632 :
633 0 : for (sni = SLIST_FIRST(&s->src_nodes); sni; sni = snin) {
634 0 : snin = SLIST_NEXT(sni, next);
635 0 : if (sni->sn == sn) {
636 0 : if (snip)
637 0 : SLIST_REMOVE_AFTER(snip, next);
638 : else
639 0 : SLIST_REMOVE_HEAD(&s->src_nodes, next);
640 0 : pool_put(&pf_sn_item_pl, sni);
641 : sni = NULL;
642 0 : sn->states--;
643 0 : }
644 0 : if (sni != NULL)
645 0 : snip = sni;
646 : }
647 0 : }
648 :
649 : /* state table stuff */
650 :
651 : static __inline int
652 0 : pf_state_compare_key(struct pf_state_key *a, struct pf_state_key *b)
653 : {
654 : int diff;
655 :
656 0 : if ((diff = a->proto - b->proto) != 0)
657 0 : return (diff);
658 0 : if ((diff = a->af - b->af) != 0)
659 0 : return (diff);
660 0 : if ((diff = pf_addr_compare(&a->addr[0], &b->addr[0], a->af)) != 0)
661 0 : return (diff);
662 0 : if ((diff = pf_addr_compare(&a->addr[1], &b->addr[1], a->af)) != 0)
663 0 : return (diff);
664 0 : if ((diff = a->port[0] - b->port[0]) != 0)
665 0 : return (diff);
666 0 : if ((diff = a->port[1] - b->port[1]) != 0)
667 0 : return (diff);
668 0 : if ((diff = a->rdomain - b->rdomain) != 0)
669 0 : return (diff);
670 0 : return (0);
671 0 : }
672 :
673 : static __inline int
674 0 : pf_state_compare_id(struct pf_state *a, struct pf_state *b)
675 : {
676 0 : if (a->id > b->id)
677 0 : return (1);
678 0 : if (a->id < b->id)
679 0 : return (-1);
680 0 : if (a->creatorid > b->creatorid)
681 0 : return (1);
682 0 : if (a->creatorid < b->creatorid)
683 0 : return (-1);
684 :
685 0 : return (0);
686 0 : }
687 :
688 : int
689 0 : pf_state_key_attach(struct pf_state_key *sk, struct pf_state *s, int idx)
690 : {
691 : struct pf_state_item *si;
692 : struct pf_state_key *cur;
693 : struct pf_state *olds = NULL;
694 :
695 0 : KASSERT(s->key[idx] == NULL);
696 0 : if ((cur = RB_INSERT(pf_state_tree, &pf_statetbl, sk)) != NULL) {
697 : /* key exists. check for same kif, if none, add to key */
698 0 : TAILQ_FOREACH(si, &cur->states, entry)
699 0 : if (si->s->kif == s->kif &&
700 0 : ((si->s->key[PF_SK_WIRE]->af == sk->af &&
701 0 : si->s->direction == s->direction) ||
702 0 : (si->s->key[PF_SK_WIRE]->af !=
703 0 : si->s->key[PF_SK_STACK]->af &&
704 0 : sk->af == si->s->key[PF_SK_STACK]->af &&
705 0 : si->s->direction != s->direction))) {
706 : int reuse = 0;
707 :
708 0 : if (sk->proto == IPPROTO_TCP &&
709 0 : si->s->src.state >= TCPS_FIN_WAIT_2 &&
710 0 : si->s->dst.state >= TCPS_FIN_WAIT_2)
711 0 : reuse = 1;
712 0 : if (pf_status.debug >= LOG_NOTICE) {
713 0 : log(LOG_NOTICE,
714 : "pf: %s key attach %s on %s: ",
715 0 : (idx == PF_SK_WIRE) ?
716 : "wire" : "stack",
717 0 : reuse ? "reuse" : "failed",
718 0 : s->kif->pfik_name);
719 0 : pf_print_state_parts(s,
720 0 : (idx == PF_SK_WIRE) ? sk : NULL,
721 0 : (idx == PF_SK_STACK) ? sk : NULL);
722 0 : addlog(", existing: ");
723 0 : pf_print_state_parts(si->s,
724 : (idx == PF_SK_WIRE) ? sk : NULL,
725 : (idx == PF_SK_STACK) ? sk : NULL);
726 0 : addlog("\n");
727 0 : }
728 0 : if (reuse) {
729 0 : pf_set_protostate(si->s, PF_PEER_BOTH,
730 : TCPS_CLOSED);
731 : /* remove late or sks can go away */
732 0 : olds = si->s;
733 : } else {
734 0 : pool_put(&pf_state_key_pl, sk);
735 0 : return (-1); /* collision! */
736 : }
737 0 : }
738 0 : pool_put(&pf_state_key_pl, sk);
739 0 : s->key[idx] = cur;
740 0 : } else
741 0 : s->key[idx] = sk;
742 :
743 0 : if ((si = pool_get(&pf_state_item_pl, PR_NOWAIT)) == NULL) {
744 0 : pf_state_key_detach(s, idx);
745 0 : return (-1);
746 : }
747 0 : si->s = s;
748 :
749 : /* list is sorted, if-bound states before floating */
750 0 : if (s->kif == pfi_all)
751 0 : TAILQ_INSERT_TAIL(&s->key[idx]->states, si, entry);
752 : else
753 0 : TAILQ_INSERT_HEAD(&s->key[idx]->states, si, entry);
754 :
755 0 : if (olds)
756 0 : pf_remove_state(olds);
757 :
758 0 : return (0);
759 0 : }
760 :
761 : void
762 0 : pf_detach_state(struct pf_state *s)
763 : {
764 0 : if (s->key[PF_SK_WIRE] == s->key[PF_SK_STACK])
765 0 : s->key[PF_SK_WIRE] = NULL;
766 :
767 0 : if (s->key[PF_SK_STACK] != NULL)
768 0 : pf_state_key_detach(s, PF_SK_STACK);
769 :
770 0 : if (s->key[PF_SK_WIRE] != NULL)
771 0 : pf_state_key_detach(s, PF_SK_WIRE);
772 0 : }
773 :
774 : void
775 0 : pf_state_key_detach(struct pf_state *s, int idx)
776 : {
777 : struct pf_state_item *si;
778 : struct pf_state_key *sk;
779 :
780 0 : if (s->key[idx] == NULL)
781 0 : return;
782 :
783 0 : si = TAILQ_FIRST(&s->key[idx]->states);
784 0 : while (si && si->s != s)
785 0 : si = TAILQ_NEXT(si, entry);
786 :
787 0 : if (si) {
788 0 : TAILQ_REMOVE(&s->key[idx]->states, si, entry);
789 0 : pool_put(&pf_state_item_pl, si);
790 0 : }
791 :
792 0 : sk = s->key[idx];
793 0 : s->key[idx] = NULL;
794 0 : if (TAILQ_EMPTY(&sk->states)) {
795 0 : RB_REMOVE(pf_state_tree, &pf_statetbl, sk);
796 0 : sk->removed = 1;
797 0 : pf_state_key_unlink_reverse(sk);
798 0 : pf_state_key_unlink_inpcb(sk);
799 0 : pf_state_key_unref(sk);
800 0 : }
801 0 : }
802 :
803 : struct pf_state_key *
804 0 : pf_alloc_state_key(int pool_flags)
805 : {
806 : struct pf_state_key *sk;
807 :
808 0 : if ((sk = pool_get(&pf_state_key_pl, pool_flags)) == NULL)
809 0 : return (NULL);
810 0 : TAILQ_INIT(&sk->states);
811 :
812 0 : return (sk);
813 0 : }
814 :
815 : static __inline int
816 0 : pf_state_key_addr_setup(struct pf_pdesc *pd, void *arg, int sidx,
817 : struct pf_addr *saddr, int didx, struct pf_addr *daddr, int af, int multi)
818 : {
819 0 : struct pf_state_key_cmp *key = arg;
820 : #ifdef INET6
821 : struct pf_addr *target;
822 :
823 0 : if (af == AF_INET || pd->proto != IPPROTO_ICMPV6)
824 : goto copy;
825 :
826 0 : switch (pd->hdr.icmp6.icmp6_type) {
827 : case ND_NEIGHBOR_SOLICIT:
828 0 : if (multi)
829 0 : return (-1);
830 0 : target = (struct pf_addr *)&pd->hdr.nd_ns.nd_ns_target;
831 : daddr = target;
832 0 : break;
833 : case ND_NEIGHBOR_ADVERT:
834 0 : if (multi)
835 0 : return (-1);
836 0 : target = (struct pf_addr *)&pd->hdr.nd_ns.nd_ns_target;
837 : saddr = target;
838 0 : if (IN6_IS_ADDR_MULTICAST(&pd->dst->v6)) {
839 0 : key->addr[didx].addr32[0] = 0;
840 0 : key->addr[didx].addr32[1] = 0;
841 0 : key->addr[didx].addr32[2] = 0;
842 0 : key->addr[didx].addr32[3] = 0;
843 : daddr = NULL; /* overwritten */
844 0 : }
845 : break;
846 : default:
847 0 : if (multi) {
848 0 : key->addr[sidx].addr32[0] = __IPV6_ADDR_INT32_MLL;
849 0 : key->addr[sidx].addr32[1] = 0;
850 0 : key->addr[sidx].addr32[2] = 0;
851 0 : key->addr[sidx].addr32[3] = __IPV6_ADDR_INT32_ONE;
852 : saddr = NULL; /* overwritten */
853 0 : }
854 : }
855 : copy:
856 : #endif /* INET6 */
857 0 : if (saddr)
858 0 : PF_ACPY(&key->addr[sidx], saddr, af);
859 0 : if (daddr)
860 0 : PF_ACPY(&key->addr[didx], daddr, af);
861 :
862 0 : return (0);
863 0 : }
864 :
865 : int
866 0 : pf_state_key_setup(struct pf_pdesc *pd, struct pf_state_key **skw,
867 : struct pf_state_key **sks, int rtableid)
868 : {
869 : /* if returning error we MUST pool_put state keys ourselves */
870 : struct pf_state_key *sk1, *sk2;
871 0 : u_int wrdom = pd->rdomain;
872 0 : int afto = pd->af != pd->naf;
873 :
874 0 : if ((sk1 = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL)
875 0 : return (ENOMEM);
876 :
877 0 : pf_state_key_addr_setup(pd, sk1, pd->sidx, pd->src, pd->didx, pd->dst,
878 0 : pd->af, 0);
879 0 : sk1->port[pd->sidx] = pd->osport;
880 0 : sk1->port[pd->didx] = pd->odport;
881 0 : sk1->proto = pd->proto;
882 0 : sk1->af = pd->af;
883 0 : sk1->rdomain = pd->rdomain;
884 0 : PF_REF_INIT(sk1->refcnt);
885 0 : sk1->removed = 0;
886 0 : if (rtableid >= 0)
887 0 : wrdom = rtable_l2(rtableid);
888 :
889 0 : if (PF_ANEQ(&pd->nsaddr, pd->src, pd->af) ||
890 0 : PF_ANEQ(&pd->ndaddr, pd->dst, pd->af) ||
891 0 : pd->nsport != pd->osport || pd->ndport != pd->odport ||
892 0 : wrdom != pd->rdomain || afto) { /* NAT/NAT64 */
893 0 : if ((sk2 = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL) {
894 0 : pool_put(&pf_state_key_pl, sk1);
895 0 : return (ENOMEM);
896 : }
897 0 : pf_state_key_addr_setup(pd, sk2, afto ? pd->didx : pd->sidx,
898 0 : &pd->nsaddr, afto ? pd->sidx : pd->didx, &pd->ndaddr,
899 0 : pd->naf, 0);
900 0 : sk2->port[afto ? pd->didx : pd->sidx] = pd->nsport;
901 0 : sk2->port[afto ? pd->sidx : pd->didx] = pd->ndport;
902 0 : if (afto) {
903 0 : switch (pd->proto) {
904 : case IPPROTO_ICMP:
905 0 : sk2->proto = IPPROTO_ICMPV6;
906 0 : break;
907 : case IPPROTO_ICMPV6:
908 0 : sk2->proto = IPPROTO_ICMP;
909 0 : break;
910 : default:
911 0 : sk2->proto = pd->proto;
912 0 : }
913 : } else
914 0 : sk2->proto = pd->proto;
915 0 : sk2->af = pd->naf;
916 0 : sk2->rdomain = wrdom;
917 0 : PF_REF_INIT(sk2->refcnt);
918 0 : sk2->removed = 0;
919 0 : } else
920 : sk2 = sk1;
921 :
922 0 : if (pd->dir == PF_IN) {
923 0 : *skw = sk1;
924 0 : *sks = sk2;
925 0 : } else {
926 0 : *sks = sk1;
927 0 : *skw = sk2;
928 : }
929 :
930 0 : if (pf_status.debug >= LOG_DEBUG) {
931 0 : log(LOG_DEBUG, "pf: key setup: ");
932 0 : pf_print_state_parts(NULL, *skw, *sks);
933 0 : addlog("\n");
934 0 : }
935 :
936 0 : return (0);
937 0 : }
938 :
939 : int
940 0 : pf_state_insert(struct pfi_kif *kif, struct pf_state_key **skw,
941 : struct pf_state_key **sks, struct pf_state *s)
942 : {
943 : PF_ASSERT_LOCKED();
944 :
945 0 : s->kif = kif;
946 0 : if (*skw == *sks) {
947 0 : if (pf_state_key_attach(*skw, s, PF_SK_WIRE))
948 0 : return (-1);
949 0 : *skw = *sks = s->key[PF_SK_WIRE];
950 0 : s->key[PF_SK_STACK] = s->key[PF_SK_WIRE];
951 0 : } else {
952 0 : if (pf_state_key_attach(*skw, s, PF_SK_WIRE)) {
953 0 : pool_put(&pf_state_key_pl, *sks);
954 0 : return (-1);
955 : }
956 0 : *skw = s->key[PF_SK_WIRE];
957 0 : if (pf_state_key_attach(*sks, s, PF_SK_STACK)) {
958 0 : pf_state_key_detach(s, PF_SK_WIRE);
959 0 : return (-1);
960 : }
961 0 : *sks = s->key[PF_SK_STACK];
962 : }
963 :
964 0 : if (s->id == 0 && s->creatorid == 0) {
965 0 : s->id = htobe64(pf_status.stateid++);
966 0 : s->creatorid = pf_status.hostid;
967 0 : }
968 0 : if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
969 0 : if (pf_status.debug >= LOG_NOTICE) {
970 0 : log(LOG_NOTICE, "pf: state insert failed: "
971 : "id: %016llx creatorid: %08x",
972 0 : betoh64(s->id), ntohl(s->creatorid));
973 0 : addlog("\n");
974 0 : }
975 0 : pf_detach_state(s);
976 0 : return (-1);
977 : }
978 0 : TAILQ_INSERT_TAIL(&state_list, s, entry_list);
979 0 : pf_status.fcounters[FCNT_STATE_INSERT]++;
980 0 : pf_status.states++;
981 0 : pfi_kif_ref(kif, PFI_KIF_REF_STATE);
982 : #if NPFSYNC > 0
983 0 : pfsync_insert_state(s);
984 : #endif /* NPFSYNC > 0 */
985 0 : return (0);
986 0 : }
987 :
988 : struct pf_state *
989 0 : pf_find_state_byid(struct pf_state_cmp *key)
990 : {
991 0 : pf_status.fcounters[FCNT_STATE_SEARCH]++;
992 :
993 0 : return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
994 : }
995 :
996 : int
997 0 : pf_compare_state_keys(struct pf_state_key *a, struct pf_state_key *b,
998 : struct pfi_kif *kif, u_int dir)
999 : {
1000 : /* a (from hdr) and b (new) must be exact opposites of each other */
1001 0 : if (a->af == b->af && a->proto == b->proto &&
1002 0 : PF_AEQ(&a->addr[0], &b->addr[1], a->af) &&
1003 0 : PF_AEQ(&a->addr[1], &b->addr[0], a->af) &&
1004 0 : a->port[0] == b->port[1] &&
1005 0 : a->port[1] == b->port[0] && a->rdomain == b->rdomain)
1006 0 : return (0);
1007 : else {
1008 : /* mismatch. must not happen. */
1009 0 : if (pf_status.debug >= LOG_ERR) {
1010 0 : log(LOG_ERR,
1011 : "pf: state key linking mismatch! dir=%s, "
1012 : "if=%s, stored af=%u, a0: ",
1013 0 : dir == PF_OUT ? "OUT" : "IN",
1014 0 : kif->pfik_name, a->af);
1015 0 : pf_print_host(&a->addr[0], a->port[0], a->af);
1016 0 : addlog(", a1: ");
1017 0 : pf_print_host(&a->addr[1], a->port[1], a->af);
1018 0 : addlog(", proto=%u", a->proto);
1019 0 : addlog(", found af=%u, a0: ", b->af);
1020 0 : pf_print_host(&b->addr[0], b->port[0], b->af);
1021 0 : addlog(", a1: ");
1022 0 : pf_print_host(&b->addr[1], b->port[1], b->af);
1023 0 : addlog(", proto=%u", b->proto);
1024 0 : addlog("\n");
1025 0 : }
1026 0 : return (-1);
1027 : }
1028 0 : }
1029 :
1030 : int
1031 0 : pf_find_state(struct pf_pdesc *pd, struct pf_state_key_cmp *key,
1032 : struct pf_state **state)
1033 : {
1034 : struct pf_state_key *sk, *pkt_sk, *inp_sk;
1035 : struct pf_state_item *si;
1036 : struct pf_state *s = NULL;
1037 :
1038 0 : pf_status.fcounters[FCNT_STATE_SEARCH]++;
1039 0 : if (pf_status.debug >= LOG_DEBUG) {
1040 0 : log(LOG_DEBUG, "pf: key search, if=%s: ", pd->kif->pfik_name);
1041 0 : pf_print_state_parts(NULL, (struct pf_state_key *)key, NULL);
1042 0 : addlog("\n");
1043 0 : }
1044 :
1045 : inp_sk = NULL;
1046 : pkt_sk = NULL;
1047 : sk = NULL;
1048 0 : if (pd->dir == PF_OUT) {
1049 : /* first if block deals with outbound forwarded packet */
1050 0 : pkt_sk = pd->m->m_pkthdr.pf.statekey;
1051 :
1052 0 : if (!pf_state_key_isvalid(pkt_sk)) {
1053 0 : pf_mbuf_unlink_state_key(pd->m);
1054 : pkt_sk = NULL;
1055 0 : }
1056 :
1057 0 : if (pkt_sk && pf_state_key_isvalid(pkt_sk->reverse))
1058 0 : sk = pkt_sk->reverse;
1059 :
1060 0 : if (pkt_sk == NULL) {
1061 : /* here we deal with local outbound packet */
1062 0 : if (pd->m->m_pkthdr.pf.inp != NULL) {
1063 0 : inp_sk = pd->m->m_pkthdr.pf.inp->inp_pf_sk;
1064 0 : if (pf_state_key_isvalid(inp_sk))
1065 0 : sk = inp_sk;
1066 : else
1067 0 : pf_inpcb_unlink_state_key(
1068 0 : pd->m->m_pkthdr.pf.inp);
1069 : }
1070 : }
1071 : }
1072 :
1073 0 : if (sk == NULL) {
1074 0 : if ((sk = RB_FIND(pf_state_tree, &pf_statetbl,
1075 0 : (struct pf_state_key *)key)) == NULL)
1076 0 : return (PF_DROP);
1077 0 : if (pd->dir == PF_OUT && pkt_sk &&
1078 0 : pf_compare_state_keys(pkt_sk, sk, pd->kif, pd->dir) == 0)
1079 0 : pf_state_key_link_reverse(sk, pkt_sk);
1080 0 : else if (pd->dir == PF_OUT && pd->m->m_pkthdr.pf.inp &&
1081 0 : !pd->m->m_pkthdr.pf.inp->inp_pf_sk && !sk->inp)
1082 0 : pf_state_key_link_inpcb(sk, pd->m->m_pkthdr.pf.inp);
1083 : }
1084 :
1085 : /* remove firewall data from outbound packet */
1086 0 : if (pd->dir == PF_OUT)
1087 0 : pf_pkt_addr_changed(pd->m);
1088 :
1089 : /* list is sorted, if-bound states before floating ones */
1090 0 : TAILQ_FOREACH(si, &sk->states, entry)
1091 0 : if ((si->s->kif == pfi_all || si->s->kif == pd->kif) &&
1092 0 : ((si->s->key[PF_SK_WIRE]->af == si->s->key[PF_SK_STACK]->af
1093 0 : && sk == (pd->dir == PF_IN ? si->s->key[PF_SK_WIRE] :
1094 0 : si->s->key[PF_SK_STACK])) ||
1095 0 : (si->s->key[PF_SK_WIRE]->af != si->s->key[PF_SK_STACK]->af
1096 0 : && pd->dir == PF_IN && (sk == si->s->key[PF_SK_STACK] ||
1097 0 : sk == si->s->key[PF_SK_WIRE])))) {
1098 0 : s = si->s;
1099 0 : break;
1100 : }
1101 :
1102 0 : if (s == NULL || s->timeout == PFTM_PURGE)
1103 0 : return (PF_DROP);
1104 :
1105 0 : if (s->rule.ptr->pktrate.limit && pd->dir == s->direction) {
1106 0 : pf_add_threshold(&s->rule.ptr->pktrate);
1107 0 : if (pf_check_threshold(&s->rule.ptr->pktrate))
1108 0 : return (PF_DROP);
1109 : }
1110 :
1111 0 : *state = s;
1112 0 : if (pd->dir == PF_OUT && s->rt_kif != NULL && s->rt_kif != pd->kif &&
1113 0 : ((s->rule.ptr->rt == PF_ROUTETO &&
1114 0 : s->rule.ptr->direction == PF_OUT) ||
1115 0 : (s->rule.ptr->rt == PF_REPLYTO &&
1116 0 : s->rule.ptr->direction == PF_IN)))
1117 0 : return (PF_PASS);
1118 :
1119 0 : return (PF_MATCH);
1120 0 : }
1121 :
1122 : struct pf_state *
1123 0 : pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more)
1124 : {
1125 : struct pf_state_key *sk;
1126 : struct pf_state_item *si, *ret = NULL;
1127 :
1128 0 : pf_status.fcounters[FCNT_STATE_SEARCH]++;
1129 :
1130 0 : sk = RB_FIND(pf_state_tree, &pf_statetbl, (struct pf_state_key *)key);
1131 :
1132 0 : if (sk != NULL) {
1133 0 : TAILQ_FOREACH(si, &sk->states, entry)
1134 0 : if (dir == PF_INOUT ||
1135 0 : (sk == (dir == PF_IN ? si->s->key[PF_SK_WIRE] :
1136 0 : si->s->key[PF_SK_STACK]))) {
1137 0 : if (more == NULL)
1138 0 : return (si->s);
1139 :
1140 0 : if (ret)
1141 0 : (*more)++;
1142 : else
1143 : ret = si;
1144 : }
1145 : }
1146 0 : return (ret ? ret->s : NULL);
1147 0 : }
1148 :
1149 : void
1150 0 : pf_state_export(struct pfsync_state *sp, struct pf_state *st)
1151 : {
1152 : int32_t expire;
1153 :
1154 0 : memset(sp, 0, sizeof(struct pfsync_state));
1155 :
1156 : /* copy from state key */
1157 0 : sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
1158 0 : sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
1159 0 : sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
1160 0 : sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
1161 0 : sp->key[PF_SK_WIRE].rdomain = htons(st->key[PF_SK_WIRE]->rdomain);
1162 0 : sp->key[PF_SK_WIRE].af = st->key[PF_SK_WIRE]->af;
1163 0 : sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
1164 0 : sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
1165 0 : sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
1166 0 : sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
1167 0 : sp->key[PF_SK_STACK].rdomain = htons(st->key[PF_SK_STACK]->rdomain);
1168 0 : sp->key[PF_SK_STACK].af = st->key[PF_SK_STACK]->af;
1169 0 : sp->rtableid[PF_SK_WIRE] = htonl(st->rtableid[PF_SK_WIRE]);
1170 0 : sp->rtableid[PF_SK_STACK] = htonl(st->rtableid[PF_SK_STACK]);
1171 0 : sp->proto = st->key[PF_SK_WIRE]->proto;
1172 0 : sp->af = st->key[PF_SK_WIRE]->af;
1173 :
1174 : /* copy from state */
1175 0 : strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
1176 0 : memcpy(&sp->rt_addr, &st->rt_addr, sizeof(sp->rt_addr));
1177 0 : sp->creation = htonl(time_uptime - st->creation);
1178 0 : expire = pf_state_expires(st);
1179 0 : if (expire <= time_uptime)
1180 0 : sp->expire = htonl(0);
1181 : else
1182 0 : sp->expire = htonl(expire - time_uptime);
1183 :
1184 0 : sp->direction = st->direction;
1185 : #if NPFLOG > 0
1186 0 : sp->log = st->log;
1187 : #endif /* NPFLOG > 0 */
1188 0 : sp->timeout = st->timeout;
1189 0 : sp->state_flags = htons(st->state_flags);
1190 0 : if (!SLIST_EMPTY(&st->src_nodes))
1191 0 : sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
1192 :
1193 0 : sp->id = st->id;
1194 0 : sp->creatorid = st->creatorid;
1195 0 : pf_state_peer_hton(&st->src, &sp->src);
1196 0 : pf_state_peer_hton(&st->dst, &sp->dst);
1197 :
1198 0 : if (st->rule.ptr == NULL)
1199 0 : sp->rule = htonl(-1);
1200 : else
1201 0 : sp->rule = htonl(st->rule.ptr->nr);
1202 0 : if (st->anchor.ptr == NULL)
1203 0 : sp->anchor = htonl(-1);
1204 : else
1205 0 : sp->anchor = htonl(st->anchor.ptr->nr);
1206 0 : sp->nat_rule = htonl(-1); /* left for compat, nat_rule is gone */
1207 :
1208 0 : pf_state_counter_hton(st->packets[0], sp->packets[0]);
1209 0 : pf_state_counter_hton(st->packets[1], sp->packets[1]);
1210 0 : pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
1211 0 : pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
1212 :
1213 0 : sp->max_mss = htons(st->max_mss);
1214 0 : sp->min_ttl = st->min_ttl;
1215 0 : sp->set_tos = st->set_tos;
1216 0 : sp->set_prio[0] = st->set_prio[0];
1217 0 : sp->set_prio[1] = st->set_prio[1];
1218 0 : }
1219 :
1220 : /* END state table stuff */
1221 :
1222 : void
1223 0 : pf_purge_expired_rules(void)
1224 : {
1225 : struct pf_rule *r;
1226 :
1227 : PF_ASSERT_LOCKED();
1228 :
1229 0 : if (SLIST_EMPTY(&pf_rule_gcl))
1230 0 : return;
1231 :
1232 0 : while ((r = SLIST_FIRST(&pf_rule_gcl)) != NULL) {
1233 0 : SLIST_REMOVE(&pf_rule_gcl, r, pf_rule, gcle);
1234 0 : KASSERT(r->rule_flag & PFRULE_EXPIRED);
1235 0 : pf_purge_rule(r);
1236 : }
1237 0 : }
1238 :
1239 : void
1240 0 : pf_purge_timeout(void *unused)
1241 : {
1242 0 : task_add(net_tq(0), &pf_purge_task);
1243 0 : }
1244 :
1245 : void
1246 0 : pf_purge(void *xnloops)
1247 : {
1248 0 : int *nloops = xnloops;
1249 :
1250 0 : KERNEL_LOCK();
1251 0 : NET_LOCK();
1252 :
1253 : /*
1254 : * process a fraction of the state table every second
1255 : * Note:
1256 : * we no longer need PF_LOCK() here, because
1257 : * pf_purge_expired_states() uses pf_state_lock to maintain
1258 : * consistency.
1259 : */
1260 0 : pf_purge_expired_states(1 + (pf_status.states
1261 0 : / pf_default_rule.timeout[PFTM_INTERVAL]));
1262 :
1263 : PF_LOCK();
1264 : /* purge other expired types every PFTM_INTERVAL seconds */
1265 0 : if (++(*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) {
1266 0 : pf_purge_expired_src_nodes();
1267 0 : pf_purge_expired_rules();
1268 0 : }
1269 : PF_UNLOCK();
1270 :
1271 : /*
1272 : * Fragments don't require PF_LOCK(), they use their own lock.
1273 : */
1274 0 : if ((*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) {
1275 0 : pf_purge_expired_fragments();
1276 0 : *nloops = 0;
1277 0 : }
1278 0 : NET_UNLOCK();
1279 0 : KERNEL_UNLOCK();
1280 :
1281 0 : timeout_add(&pf_purge_to, 1 * hz);
1282 0 : }
1283 :
1284 : int32_t
1285 0 : pf_state_expires(const struct pf_state *state)
1286 : {
1287 : u_int32_t timeout;
1288 : u_int32_t start;
1289 : u_int32_t end;
1290 : u_int32_t states;
1291 :
1292 : /* handle all PFTM_* > PFTM_MAX here */
1293 0 : if (state->timeout == PFTM_PURGE)
1294 0 : return (0);
1295 :
1296 0 : KASSERT(state->timeout != PFTM_UNLINKED);
1297 0 : KASSERT(state->timeout < PFTM_MAX);
1298 :
1299 0 : timeout = state->rule.ptr->timeout[state->timeout];
1300 0 : if (!timeout)
1301 0 : timeout = pf_default_rule.timeout[state->timeout];
1302 :
1303 0 : start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
1304 0 : if (start) {
1305 0 : end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
1306 0 : states = state->rule.ptr->states_cur;
1307 0 : } else {
1308 0 : start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
1309 0 : end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
1310 0 : states = pf_status.states;
1311 : }
1312 0 : if (end && states > start && start < end) {
1313 0 : if (states >= end)
1314 0 : return (0);
1315 :
1316 0 : timeout = (u_int64_t)timeout * (end - states) / (end - start);
1317 0 : }
1318 :
1319 0 : return (state->expire + timeout);
1320 0 : }
1321 :
1322 : void
1323 0 : pf_purge_expired_src_nodes(void)
1324 : {
1325 : struct pf_src_node *cur, *next;
1326 :
1327 : PF_ASSERT_LOCKED();
1328 :
1329 0 : for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
1330 0 : next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
1331 :
1332 0 : if (cur->states == 0 && cur->expire <= time_uptime) {
1333 0 : next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
1334 0 : pf_remove_src_node(cur);
1335 0 : }
1336 : }
1337 0 : }
1338 :
1339 : void
1340 0 : pf_src_tree_remove_state(struct pf_state *s)
1341 : {
1342 : u_int32_t timeout;
1343 : struct pf_sn_item *sni;
1344 :
1345 0 : while ((sni = SLIST_FIRST(&s->src_nodes)) != NULL) {
1346 0 : SLIST_REMOVE_HEAD(&s->src_nodes, next);
1347 0 : if (s->src.tcp_est)
1348 0 : --sni->sn->conn;
1349 0 : if (--sni->sn->states == 0) {
1350 0 : timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
1351 0 : if (!timeout)
1352 0 : timeout =
1353 0 : pf_default_rule.timeout[PFTM_SRC_NODE];
1354 0 : sni->sn->expire = time_uptime + timeout;
1355 0 : }
1356 0 : pool_put(&pf_sn_item_pl, sni);
1357 : }
1358 0 : }
1359 :
1360 : void
1361 0 : pf_remove_state(struct pf_state *cur)
1362 : {
1363 : PF_ASSERT_LOCKED();
1364 :
1365 : /* handle load balancing related tasks */
1366 0 : pf_postprocess_addr(cur);
1367 :
1368 0 : if (cur->src.state == PF_TCPS_PROXY_DST) {
1369 0 : pf_send_tcp(cur->rule.ptr, cur->key[PF_SK_WIRE]->af,
1370 0 : &cur->key[PF_SK_WIRE]->addr[1],
1371 0 : &cur->key[PF_SK_WIRE]->addr[0],
1372 0 : cur->key[PF_SK_WIRE]->port[1],
1373 0 : cur->key[PF_SK_WIRE]->port[0],
1374 0 : cur->src.seqhi, cur->src.seqlo + 1,
1375 0 : TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag,
1376 0 : cur->key[PF_SK_WIRE]->rdomain);
1377 0 : }
1378 0 : if (cur->key[PF_SK_STACK]->proto == IPPROTO_TCP)
1379 0 : pf_set_protostate(cur, PF_PEER_BOTH, TCPS_CLOSED);
1380 :
1381 0 : RB_REMOVE(pf_state_tree_id, &tree_id, cur);
1382 : #if NPFLOW > 0
1383 0 : if (cur->state_flags & PFSTATE_PFLOW)
1384 0 : export_pflow(cur);
1385 : #endif /* NPFLOW > 0 */
1386 : #if NPFSYNC > 0
1387 0 : pfsync_delete_state(cur);
1388 : #endif /* NPFSYNC > 0 */
1389 0 : cur->timeout = PFTM_UNLINKED;
1390 0 : pf_src_tree_remove_state(cur);
1391 0 : pf_detach_state(cur);
1392 0 : }
1393 :
1394 : void
1395 0 : pf_remove_divert_state(struct pf_state_key *sk)
1396 : {
1397 : struct pf_state_item *si;
1398 :
1399 0 : TAILQ_FOREACH(si, &sk->states, entry) {
1400 0 : if (sk == si->s->key[PF_SK_STACK] && si->s->rule.ptr &&
1401 0 : (si->s->rule.ptr->divert.type == PF_DIVERT_TO ||
1402 0 : si->s->rule.ptr->divert.type == PF_DIVERT_REPLY)) {
1403 0 : pf_remove_state(si->s);
1404 0 : break;
1405 : }
1406 : }
1407 0 : }
1408 :
1409 : void
1410 0 : pf_free_state(struct pf_state *cur)
1411 : {
1412 : struct pf_rule_item *ri;
1413 :
1414 : PF_ASSERT_LOCKED();
1415 :
1416 : #if NPFSYNC > 0
1417 0 : if (pfsync_state_in_use(cur))
1418 0 : return;
1419 : #endif /* NPFSYNC > 0 */
1420 0 : KASSERT(cur->timeout == PFTM_UNLINKED);
1421 0 : if (--cur->rule.ptr->states_cur == 0 &&
1422 0 : cur->rule.ptr->src_nodes == 0)
1423 0 : pf_rm_rule(NULL, cur->rule.ptr);
1424 0 : if (cur->anchor.ptr != NULL)
1425 0 : if (--cur->anchor.ptr->states_cur == 0)
1426 0 : pf_rm_rule(NULL, cur->anchor.ptr);
1427 0 : while ((ri = SLIST_FIRST(&cur->match_rules))) {
1428 0 : SLIST_REMOVE_HEAD(&cur->match_rules, entry);
1429 0 : if (--ri->r->states_cur == 0 &&
1430 0 : ri->r->src_nodes == 0)
1431 0 : pf_rm_rule(NULL, ri->r);
1432 0 : pool_put(&pf_rule_item_pl, ri);
1433 : }
1434 0 : pf_normalize_tcp_cleanup(cur);
1435 0 : pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
1436 0 : TAILQ_REMOVE(&state_list, cur, entry_list);
1437 0 : if (cur->tag)
1438 0 : pf_tag_unref(cur->tag);
1439 0 : pf_state_unref(cur);
1440 0 : pf_status.fcounters[FCNT_STATE_REMOVALS]++;
1441 0 : pf_status.states--;
1442 0 : }
1443 :
1444 : void
1445 0 : pf_purge_expired_states(u_int32_t maxcheck)
1446 : {
1447 : static struct pf_state *cur = NULL;
1448 : struct pf_state *next;
1449 : SLIST_HEAD(pf_state_gcl, pf_state) gcl;
1450 :
1451 : PF_ASSERT_UNLOCKED();
1452 : SLIST_INIT(&gcl);
1453 :
1454 : PF_STATE_ENTER_READ();
1455 0 : while (maxcheck--) {
1456 : /* wrap to start of list when we hit the end */
1457 0 : if (cur == NULL) {
1458 0 : cur = pf_state_ref(TAILQ_FIRST(&state_list));
1459 0 : if (cur == NULL)
1460 : break; /* list empty */
1461 : }
1462 :
1463 : /* get next state, as cur may get deleted */
1464 0 : next = TAILQ_NEXT(cur, entry_list);
1465 :
1466 0 : if ((cur->timeout == PFTM_UNLINKED) ||
1467 0 : (pf_state_expires(cur) <= time_uptime))
1468 0 : SLIST_INSERT_HEAD(&gcl, cur, gc_list);
1469 : else
1470 0 : pf_state_unref(cur);
1471 :
1472 0 : cur = pf_state_ref(next);
1473 : }
1474 : PF_STATE_EXIT_READ();
1475 :
1476 : PF_LOCK();
1477 : PF_STATE_ENTER_WRITE();
1478 0 : while ((next = SLIST_FIRST(&gcl)) != NULL) {
1479 0 : SLIST_REMOVE_HEAD(&gcl, gc_list);
1480 0 : if (next->timeout == PFTM_UNLINKED)
1481 0 : pf_free_state(next);
1482 0 : else if (pf_state_expires(next) <= time_uptime) {
1483 0 : pf_remove_state(next);
1484 0 : pf_free_state(next);
1485 0 : }
1486 :
1487 0 : pf_state_unref(next);
1488 : }
1489 : PF_STATE_EXIT_WRITE();
1490 : PF_UNLOCK();
1491 0 : }
1492 :
1493 : int
1494 0 : pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
1495 : {
1496 0 : if (aw->type != PF_ADDR_TABLE)
1497 0 : return (0);
1498 0 : if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL)
1499 0 : return (1);
1500 0 : return (0);
1501 0 : }
1502 :
1503 : void
1504 0 : pf_tbladdr_remove(struct pf_addr_wrap *aw)
1505 : {
1506 0 : if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
1507 : return;
1508 0 : pfr_detach_table(aw->p.tbl);
1509 0 : aw->p.tbl = NULL;
1510 0 : }
1511 :
1512 : void
1513 0 : pf_tbladdr_copyout(struct pf_addr_wrap *aw)
1514 : {
1515 0 : struct pfr_ktable *kt = aw->p.tbl;
1516 :
1517 0 : if (aw->type != PF_ADDR_TABLE || kt == NULL)
1518 0 : return;
1519 0 : if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
1520 0 : kt = kt->pfrkt_root;
1521 0 : aw->p.tbl = NULL;
1522 0 : aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
1523 0 : kt->pfrkt_cnt : -1;
1524 0 : }
1525 :
1526 : void
1527 0 : pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
1528 : {
1529 0 : switch (af) {
1530 : case AF_INET: {
1531 0 : u_int32_t a = ntohl(addr->addr32[0]);
1532 0 : addlog("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
1533 0 : (a>>8)&255, a&255);
1534 0 : if (p) {
1535 0 : p = ntohs(p);
1536 0 : addlog(":%u", p);
1537 0 : }
1538 : break;
1539 : }
1540 : #ifdef INET6
1541 : case AF_INET6: {
1542 : u_int16_t b;
1543 : u_int8_t i, curstart, curend, maxstart, maxend;
1544 : curstart = curend = maxstart = maxend = 255;
1545 0 : for (i = 0; i < 8; i++) {
1546 0 : if (!addr->addr16[i]) {
1547 0 : if (curstart == 255)
1548 0 : curstart = i;
1549 : curend = i;
1550 0 : } else {
1551 0 : if ((curend - curstart) >
1552 0 : (maxend - maxstart)) {
1553 : maxstart = curstart;
1554 : maxend = curend;
1555 0 : }
1556 : curstart = curend = 255;
1557 : }
1558 : }
1559 0 : if ((curend - curstart) >
1560 0 : (maxend - maxstart)) {
1561 : maxstart = curstart;
1562 : maxend = curend;
1563 0 : }
1564 0 : for (i = 0; i < 8; i++) {
1565 0 : if (i >= maxstart && i <= maxend) {
1566 0 : if (i == 0)
1567 0 : addlog(":");
1568 0 : if (i == maxend)
1569 0 : addlog(":");
1570 : } else {
1571 0 : b = ntohs(addr->addr16[i]);
1572 0 : addlog("%x", b);
1573 0 : if (i < 7)
1574 0 : addlog(":");
1575 : }
1576 : }
1577 0 : if (p) {
1578 0 : p = ntohs(p);
1579 0 : addlog("[%u]", p);
1580 0 : }
1581 : break;
1582 : }
1583 : #endif /* INET6 */
1584 : }
1585 0 : }
1586 :
1587 : void
1588 0 : pf_print_state(struct pf_state *s)
1589 : {
1590 0 : pf_print_state_parts(s, NULL, NULL);
1591 0 : }
1592 :
1593 : void
1594 0 : pf_print_state_parts(struct pf_state *s,
1595 : struct pf_state_key *skwp, struct pf_state_key *sksp)
1596 : {
1597 : struct pf_state_key *skw, *sks;
1598 : u_int8_t proto, dir;
1599 :
1600 : /* Do our best to fill these, but they're skipped if NULL */
1601 0 : skw = skwp ? skwp : (s ? s->key[PF_SK_WIRE] : NULL);
1602 0 : sks = sksp ? sksp : (s ? s->key[PF_SK_STACK] : NULL);
1603 0 : proto = skw ? skw->proto : (sks ? sks->proto : 0);
1604 0 : dir = s ? s->direction : 0;
1605 :
1606 0 : switch (proto) {
1607 : case IPPROTO_IPV4:
1608 0 : addlog("IPv4");
1609 0 : break;
1610 : case IPPROTO_IPV6:
1611 0 : addlog("IPv6");
1612 0 : break;
1613 : case IPPROTO_TCP:
1614 0 : addlog("TCP");
1615 0 : break;
1616 : case IPPROTO_UDP:
1617 0 : addlog("UDP");
1618 0 : break;
1619 : case IPPROTO_ICMP:
1620 0 : addlog("ICMP");
1621 0 : break;
1622 : case IPPROTO_ICMPV6:
1623 0 : addlog("ICMPv6");
1624 0 : break;
1625 : default:
1626 0 : addlog("%u", proto);
1627 0 : break;
1628 : }
1629 0 : switch (dir) {
1630 : case PF_IN:
1631 0 : addlog(" in");
1632 0 : break;
1633 : case PF_OUT:
1634 0 : addlog(" out");
1635 0 : break;
1636 : }
1637 0 : if (skw) {
1638 0 : addlog(" wire: (%d) ", skw->rdomain);
1639 0 : pf_print_host(&skw->addr[0], skw->port[0], skw->af);
1640 0 : addlog(" ");
1641 0 : pf_print_host(&skw->addr[1], skw->port[1], skw->af);
1642 0 : }
1643 0 : if (sks) {
1644 0 : addlog(" stack: (%d) ", sks->rdomain);
1645 0 : if (sks != skw) {
1646 0 : pf_print_host(&sks->addr[0], sks->port[0], sks->af);
1647 0 : addlog(" ");
1648 0 : pf_print_host(&sks->addr[1], sks->port[1], sks->af);
1649 0 : } else
1650 0 : addlog("-");
1651 : }
1652 0 : if (s) {
1653 0 : if (proto == IPPROTO_TCP) {
1654 0 : addlog(" [lo=%u high=%u win=%u modulator=%u",
1655 0 : s->src.seqlo, s->src.seqhi,
1656 0 : s->src.max_win, s->src.seqdiff);
1657 0 : if (s->src.wscale && s->dst.wscale)
1658 0 : addlog(" wscale=%u",
1659 0 : s->src.wscale & PF_WSCALE_MASK);
1660 0 : addlog("]");
1661 0 : addlog(" [lo=%u high=%u win=%u modulator=%u",
1662 0 : s->dst.seqlo, s->dst.seqhi,
1663 0 : s->dst.max_win, s->dst.seqdiff);
1664 0 : if (s->src.wscale && s->dst.wscale)
1665 0 : addlog(" wscale=%u",
1666 0 : s->dst.wscale & PF_WSCALE_MASK);
1667 0 : addlog("]");
1668 0 : }
1669 0 : addlog(" %u:%u", s->src.state, s->dst.state);
1670 0 : if (s->rule.ptr)
1671 0 : addlog(" @%d", s->rule.ptr->nr);
1672 : }
1673 0 : }
1674 :
1675 : void
1676 0 : pf_print_flags(u_int8_t f)
1677 : {
1678 0 : if (f)
1679 0 : addlog(" ");
1680 0 : if (f & TH_FIN)
1681 0 : addlog("F");
1682 0 : if (f & TH_SYN)
1683 0 : addlog("S");
1684 0 : if (f & TH_RST)
1685 0 : addlog("R");
1686 0 : if (f & TH_PUSH)
1687 0 : addlog("P");
1688 0 : if (f & TH_ACK)
1689 0 : addlog("A");
1690 0 : if (f & TH_URG)
1691 0 : addlog("U");
1692 0 : if (f & TH_ECE)
1693 0 : addlog("E");
1694 0 : if (f & TH_CWR)
1695 0 : addlog("W");
1696 0 : }
1697 :
1698 : #define PF_SET_SKIP_STEPS(i) \
1699 : do { \
1700 : while (head[i] != cur) { \
1701 : head[i]->skip[i].ptr = cur; \
1702 : head[i] = TAILQ_NEXT(head[i], entries); \
1703 : } \
1704 : } while (0)
1705 :
1706 : void
1707 0 : pf_calc_skip_steps(struct pf_rulequeue *rules)
1708 : {
1709 0 : struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
1710 : int i;
1711 :
1712 0 : cur = TAILQ_FIRST(rules);
1713 : prev = cur;
1714 0 : for (i = 0; i < PF_SKIP_COUNT; ++i)
1715 0 : head[i] = cur;
1716 0 : while (cur != NULL) {
1717 0 : if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
1718 0 : PF_SET_SKIP_STEPS(PF_SKIP_IFP);
1719 0 : if (cur->direction != prev->direction)
1720 0 : PF_SET_SKIP_STEPS(PF_SKIP_DIR);
1721 0 : if (cur->onrdomain != prev->onrdomain ||
1722 0 : cur->ifnot != prev->ifnot)
1723 0 : PF_SET_SKIP_STEPS(PF_SKIP_RDOM);
1724 0 : if (cur->af != prev->af)
1725 0 : PF_SET_SKIP_STEPS(PF_SKIP_AF);
1726 0 : if (cur->proto != prev->proto)
1727 0 : PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
1728 0 : if (cur->src.neg != prev->src.neg ||
1729 0 : pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
1730 0 : PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
1731 0 : if (cur->dst.neg != prev->dst.neg ||
1732 0 : pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
1733 0 : PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
1734 0 : if (cur->src.port[0] != prev->src.port[0] ||
1735 0 : cur->src.port[1] != prev->src.port[1] ||
1736 0 : cur->src.port_op != prev->src.port_op)
1737 0 : PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
1738 0 : if (cur->dst.port[0] != prev->dst.port[0] ||
1739 0 : cur->dst.port[1] != prev->dst.port[1] ||
1740 0 : cur->dst.port_op != prev->dst.port_op)
1741 0 : PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
1742 :
1743 : prev = cur;
1744 0 : cur = TAILQ_NEXT(cur, entries);
1745 : }
1746 0 : for (i = 0; i < PF_SKIP_COUNT; ++i)
1747 0 : PF_SET_SKIP_STEPS(i);
1748 0 : }
1749 :
1750 : int
1751 0 : pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
1752 : {
1753 0 : if (aw1->type != aw2->type)
1754 0 : return (1);
1755 0 : switch (aw1->type) {
1756 : case PF_ADDR_ADDRMASK:
1757 : case PF_ADDR_RANGE:
1758 0 : if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, AF_INET6))
1759 0 : return (1);
1760 0 : if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, AF_INET6))
1761 0 : return (1);
1762 0 : return (0);
1763 : case PF_ADDR_DYNIFTL:
1764 0 : return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
1765 : case PF_ADDR_NONE:
1766 : case PF_ADDR_NOROUTE:
1767 : case PF_ADDR_URPFFAILED:
1768 0 : return (0);
1769 : case PF_ADDR_TABLE:
1770 0 : return (aw1->p.tbl != aw2->p.tbl);
1771 : case PF_ADDR_RTLABEL:
1772 0 : return (aw1->v.rtlabel != aw2->v.rtlabel);
1773 : default:
1774 0 : addlog("invalid address type: %d\n", aw1->type);
1775 0 : return (1);
1776 : }
1777 0 : }
1778 :
1779 : /* This algorithm computes 'a + b - c' in ones-complement using a trick to
1780 : * emulate at most one ones-complement subtraction. This thereby limits net
1781 : * carries/borrows to at most one, eliminating a reduction step and saving one
1782 : * each of +, >>, & and ~.
1783 : *
1784 : * def. x mod y = x - (x//y)*y for integer x,y
1785 : * def. sum = x mod 2^16
1786 : * def. accumulator = (x >> 16) mod 2^16
1787 : *
1788 : * The trick works as follows: subtracting exactly one u_int16_t from the
1789 : * u_int32_t x incurs at most one underflow, wrapping its upper 16-bits, the
1790 : * accumulator, to 2^16 - 1. Adding this to the 16-bit sum preserves the
1791 : * ones-complement borrow:
1792 : *
1793 : * (sum + accumulator) mod 2^16
1794 : * = { assume underflow: accumulator := 2^16 - 1 }
1795 : * (sum + 2^16 - 1) mod 2^16
1796 : * = { mod }
1797 : * (sum - 1) mod 2^16
1798 : *
1799 : * Although this breaks for sum = 0, giving 0xffff, which is ones-complement's
1800 : * other zero, not -1, that cannot occur: the 16-bit sum cannot be underflown
1801 : * to zero as that requires subtraction of at least 2^16, which exceeds a
1802 : * single u_int16_t's range.
1803 : *
1804 : * We use the following theorem to derive the implementation:
1805 : *
1806 : * th. (x + (y mod z)) mod z = (x + y) mod z (0)
1807 : * proof.
1808 : * (x + (y mod z)) mod z
1809 : * = { def mod }
1810 : * (x + y - (y//z)*z) mod z
1811 : * = { (a + b*c) mod c = a mod c }
1812 : * (x + y) mod z [end of proof]
1813 : *
1814 : * ... and thereby obtain:
1815 : *
1816 : * (sum + accumulator) mod 2^16
1817 : * = { def. accumulator, def. sum }
1818 : * (x mod 2^16 + (x >> 16) mod 2^16) mod 2^16
1819 : * = { (0), twice }
1820 : * (x + (x >> 16)) mod 2^16
1821 : * = { x mod 2^n = x & (2^n - 1) }
1822 : * (x + (x >> 16)) & 0xffff
1823 : *
1824 : * Note: this serves also as a reduction step for at most one add (as the
1825 : * trailing mod 2^16 prevents further reductions by destroying carries).
1826 : */
1827 : static __inline void
1828 0 : pf_cksum_fixup(u_int16_t *cksum, u_int16_t was, u_int16_t now,
1829 : u_int8_t proto)
1830 : {
1831 : u_int32_t x;
1832 0 : const int udp = proto == IPPROTO_UDP;
1833 :
1834 0 : x = *cksum + was - now;
1835 0 : x = (x + (x >> 16)) & 0xffff;
1836 :
1837 : /* optimise: eliminate a branch when not udp */
1838 0 : if (udp && *cksum == 0x0000)
1839 0 : return;
1840 0 : if (udp && x == 0x0000)
1841 0 : x = 0xffff;
1842 :
1843 0 : *cksum = (u_int16_t)(x);
1844 0 : }
1845 :
1846 : #ifdef INET6
1847 : /* pre: coverage(cksum) is superset of coverage(covered_cksum) */
1848 : static __inline void
1849 0 : pf_cksum_uncover(u_int16_t *cksum, u_int16_t covered_cksum, u_int8_t proto)
1850 : {
1851 0 : pf_cksum_fixup(cksum, ~covered_cksum, 0x0, proto);
1852 0 : }
1853 :
1854 : /* pre: disjoint(coverage(cksum), coverage(uncovered_cksum)) */
1855 : static __inline void
1856 0 : pf_cksum_cover(u_int16_t *cksum, u_int16_t uncovered_cksum, u_int8_t proto)
1857 : {
1858 0 : pf_cksum_fixup(cksum, 0x0, ~uncovered_cksum, proto);
1859 0 : }
1860 : #endif /* INET6 */
1861 :
1862 : /* pre: *a is 16-bit aligned within its packet
1863 : *
1864 : * This algorithm emulates 16-bit ones-complement sums on a twos-complement
1865 : * machine by conserving ones-complement's otherwise discarded carries in the
1866 : * upper bits of x. These accumulated carries when added to the lower 16-bits
1867 : * over at least zero 'reduction' steps then complete the ones-complement sum.
1868 : *
1869 : * def. sum = x mod 2^16
1870 : * def. accumulator = (x >> 16)
1871 : *
1872 : * At most two reduction steps
1873 : *
1874 : * x := sum + accumulator
1875 : * = { def sum, def accumulator }
1876 : * x := x mod 2^16 + (x >> 16)
1877 : * = { x mod 2^n = x & (2^n - 1) }
1878 : * x := (x & 0xffff) + (x >> 16)
1879 : *
1880 : * are necessary to incorporate the accumulated carries (at most one per add)
1881 : * i.e. to reduce x < 2^16 from at most 16 carries in the upper 16 bits.
1882 : *
1883 : * The function is also invariant over the endian of the host. Why?
1884 : *
1885 : * Define the unary transpose operator ~ on a bitstring in python slice
1886 : * notation as lambda m: m[P:] + m[:P] , for some constant pivot P.
1887 : *
1888 : * th. ~ distributes over ones-complement addition, denoted by +_1, i.e.
1889 : *
1890 : * ~m +_1 ~n = ~(m +_1 n) (for all bitstrings m,n of equal length)
1891 : *
1892 : * proof. Regard the bitstrings in m +_1 n as split at P, forming at most two
1893 : * 'half-adds'. Under ones-complement addition, each half-add carries to the
1894 : * other, so the sum of each half-add is unaffected by their relative
1895 : * order. Therefore:
1896 : *
1897 : * ~m +_1 ~n
1898 : * = { half-adds invariant under transposition }
1899 : * ~s
1900 : * = { substitute }
1901 : * ~(m +_1 n) [end of proof]
1902 : *
1903 : * th. Summing two in-memory ones-complement 16-bit variables m,n on a machine
1904 : * with the converse endian does not alter the result.
1905 : *
1906 : * proof.
1907 : * { converse machine endian: load/store transposes, P := 8 }
1908 : * ~(~m +_1 ~n)
1909 : * = { ~ over +_1 }
1910 : * ~~m +_1 ~~n
1911 : * = { ~ is an involution }
1912 : * m +_1 n [end of proof]
1913 : *
1914 : */
1915 : #define NEG(x) ((u_int16_t)~(x))
1916 : void
1917 0 : pf_cksum_fixup_a(u_int16_t *cksum, const struct pf_addr *a,
1918 : const struct pf_addr *an, sa_family_t af, u_int8_t proto)
1919 : {
1920 : u_int32_t x;
1921 0 : const u_int16_t *n = an->addr16;
1922 0 : const u_int16_t *o = a->addr16;
1923 0 : const int udp = proto == IPPROTO_UDP;
1924 :
1925 0 : switch (af) {
1926 : case AF_INET:
1927 0 : x = *cksum + o[0] + NEG(n[0]) + o[1] + NEG(n[1]);
1928 0 : break;
1929 : #ifdef INET6
1930 : case AF_INET6:
1931 0 : x = *cksum + o[0] + NEG(n[0]) + o[1] + NEG(n[1]) +\
1932 0 : o[2] + NEG(n[2]) + o[3] + NEG(n[3]) +\
1933 0 : o[4] + NEG(n[4]) + o[5] + NEG(n[5]) +\
1934 0 : o[6] + NEG(n[6]) + o[7] + NEG(n[7]);
1935 0 : break;
1936 : #endif /* INET6 */
1937 : default:
1938 0 : unhandled_af(af);
1939 : }
1940 :
1941 0 : x = (x & 0xffff) + (x >> 16);
1942 0 : x = (x & 0xffff) + (x >> 16);
1943 :
1944 : /* optimise: eliminate a branch when not udp */
1945 0 : if (udp && *cksum == 0x0000)
1946 0 : return;
1947 0 : if (udp && x == 0x0000)
1948 0 : x = 0xffff;
1949 :
1950 0 : *cksum = (u_int16_t)(x);
1951 0 : }
1952 :
1953 : int
1954 0 : pf_patch_8(struct pf_pdesc *pd, u_int8_t *f, u_int8_t v, bool hi)
1955 : {
1956 : int rewrite = 0;
1957 :
1958 0 : if (*f != v) {
1959 0 : u_int16_t old = htons(hi ? (*f << 8) : *f);
1960 0 : u_int16_t new = htons(hi ? ( v << 8) : v);
1961 :
1962 0 : pf_cksum_fixup(pd->pcksum, old, new, pd->proto);
1963 0 : *f = v;
1964 : rewrite = 1;
1965 0 : }
1966 :
1967 0 : return (rewrite);
1968 : }
1969 :
1970 : /* pre: *f is 16-bit aligned within its packet */
1971 : int
1972 0 : pf_patch_16(struct pf_pdesc *pd, u_int16_t *f, u_int16_t v)
1973 : {
1974 : int rewrite = 0;
1975 :
1976 0 : if (*f != v) {
1977 0 : pf_cksum_fixup(pd->pcksum, *f, v, pd->proto);
1978 0 : *f = v;
1979 : rewrite = 1;
1980 0 : }
1981 :
1982 0 : return (rewrite);
1983 : }
1984 :
1985 : int
1986 0 : pf_patch_16_unaligned(struct pf_pdesc *pd, void *f, u_int16_t v, bool hi)
1987 : {
1988 : int rewrite = 0;
1989 : u_int8_t *fb = (u_int8_t*)f;
1990 : u_int8_t *vb = (u_int8_t*)&v;
1991 :
1992 0 : if (hi && ALIGNED_POINTER(f, u_int16_t)) {
1993 0 : return (pf_patch_16(pd, f, v)); /* optimise */
1994 : }
1995 :
1996 0 : rewrite += pf_patch_8(pd, fb++, *vb++, hi);
1997 0 : rewrite += pf_patch_8(pd, fb++, *vb++,!hi);
1998 :
1999 0 : return (rewrite);
2000 0 : }
2001 :
2002 : /* pre: *f is 16-bit aligned within its packet */
2003 : /* pre: pd->proto != IPPROTO_UDP */
2004 : int
2005 0 : pf_patch_32(struct pf_pdesc *pd, u_int32_t *f, u_int32_t v)
2006 : {
2007 : int rewrite = 0;
2008 0 : u_int16_t *pc = pd->pcksum;
2009 0 : u_int8_t proto = pd->proto;
2010 :
2011 : /* optimise: inline udp fixup code is unused; let compiler scrub it */
2012 0 : if (proto == IPPROTO_UDP)
2013 0 : panic("%s: udp", __func__);
2014 :
2015 : /* optimise: skip *f != v guard; true for all use-cases */
2016 0 : pf_cksum_fixup(pc, *f / (1 << 16), v / (1 << 16), proto);
2017 0 : pf_cksum_fixup(pc, *f % (1 << 16), v % (1 << 16), proto);
2018 :
2019 0 : *f = v;
2020 : rewrite = 1;
2021 :
2022 0 : return (rewrite);
2023 : }
2024 :
2025 : int
2026 0 : pf_patch_32_unaligned(struct pf_pdesc *pd, void *f, u_int32_t v, bool hi)
2027 : {
2028 : int rewrite = 0;
2029 : u_int8_t *fb = (u_int8_t*)f;
2030 : u_int8_t *vb = (u_int8_t*)&v;
2031 :
2032 0 : if (hi && ALIGNED_POINTER(f, u_int32_t)) {
2033 0 : return (pf_patch_32(pd, f, v)); /* optimise */
2034 : }
2035 :
2036 0 : rewrite += pf_patch_8(pd, fb++, *vb++, hi);
2037 0 : rewrite += pf_patch_8(pd, fb++, *vb++,!hi);
2038 0 : rewrite += pf_patch_8(pd, fb++, *vb++, hi);
2039 0 : rewrite += pf_patch_8(pd, fb++, *vb++,!hi);
2040 :
2041 0 : return (rewrite);
2042 0 : }
2043 :
2044 : int
2045 0 : pf_icmp_mapping(struct pf_pdesc *pd, u_int8_t type, int *icmp_dir,
2046 : u_int16_t *virtual_id, u_int16_t *virtual_type)
2047 : {
2048 : /*
2049 : * ICMP types marked with PF_OUT are typically responses to
2050 : * PF_IN, and will match states in the opposite direction.
2051 : * PF_IN ICMP types need to match a state with that type.
2052 : */
2053 0 : *icmp_dir = PF_OUT;
2054 :
2055 : /* Queries (and responses) */
2056 0 : switch (pd->af) {
2057 : case AF_INET:
2058 0 : switch (type) {
2059 : case ICMP_ECHO:
2060 0 : *icmp_dir = PF_IN;
2061 : /* FALLTHROUGH */
2062 : case ICMP_ECHOREPLY:
2063 0 : *virtual_type = ICMP_ECHO;
2064 0 : *virtual_id = pd->hdr.icmp.icmp_id;
2065 0 : break;
2066 :
2067 : case ICMP_TSTAMP:
2068 0 : *icmp_dir = PF_IN;
2069 : /* FALLTHROUGH */
2070 : case ICMP_TSTAMPREPLY:
2071 0 : *virtual_type = ICMP_TSTAMP;
2072 0 : *virtual_id = pd->hdr.icmp.icmp_id;
2073 0 : break;
2074 :
2075 : case ICMP_IREQ:
2076 0 : *icmp_dir = PF_IN;
2077 : /* FALLTHROUGH */
2078 : case ICMP_IREQREPLY:
2079 0 : *virtual_type = ICMP_IREQ;
2080 0 : *virtual_id = pd->hdr.icmp.icmp_id;
2081 0 : break;
2082 :
2083 : case ICMP_MASKREQ:
2084 0 : *icmp_dir = PF_IN;
2085 : /* FALLTHROUGH */
2086 : case ICMP_MASKREPLY:
2087 0 : *virtual_type = ICMP_MASKREQ;
2088 0 : *virtual_id = pd->hdr.icmp.icmp_id;
2089 0 : break;
2090 :
2091 : case ICMP_IPV6_WHEREAREYOU:
2092 0 : *icmp_dir = PF_IN;
2093 : /* FALLTHROUGH */
2094 : case ICMP_IPV6_IAMHERE:
2095 0 : *virtual_type = ICMP_IPV6_WHEREAREYOU;
2096 0 : *virtual_id = 0; /* Nothing sane to match on! */
2097 0 : break;
2098 :
2099 : case ICMP_MOBILE_REGREQUEST:
2100 0 : *icmp_dir = PF_IN;
2101 : /* FALLTHROUGH */
2102 : case ICMP_MOBILE_REGREPLY:
2103 0 : *virtual_type = ICMP_MOBILE_REGREQUEST;
2104 0 : *virtual_id = 0; /* Nothing sane to match on! */
2105 0 : break;
2106 :
2107 : case ICMP_ROUTERSOLICIT:
2108 0 : *icmp_dir = PF_IN;
2109 : /* FALLTHROUGH */
2110 : case ICMP_ROUTERADVERT:
2111 0 : *virtual_type = ICMP_ROUTERSOLICIT;
2112 0 : *virtual_id = 0; /* Nothing sane to match on! */
2113 0 : break;
2114 :
2115 : /* These ICMP types map to other connections */
2116 : case ICMP_UNREACH:
2117 : case ICMP_SOURCEQUENCH:
2118 : case ICMP_REDIRECT:
2119 : case ICMP_TIMXCEED:
2120 : case ICMP_PARAMPROB:
2121 : /* These will not be used, but set them anyway */
2122 0 : *icmp_dir = PF_IN;
2123 0 : *virtual_type = htons(type);
2124 0 : *virtual_id = 0;
2125 0 : return (1); /* These types match to another state */
2126 :
2127 : /*
2128 : * All remaining ICMP types get their own states,
2129 : * and will only match in one direction.
2130 : */
2131 : default:
2132 0 : *icmp_dir = PF_IN;
2133 0 : *virtual_type = type;
2134 0 : *virtual_id = 0;
2135 0 : break;
2136 : }
2137 : break;
2138 : #ifdef INET6
2139 : case AF_INET6:
2140 0 : switch (type) {
2141 : case ICMP6_ECHO_REQUEST:
2142 0 : *icmp_dir = PF_IN;
2143 : /* FALLTHROUGH */
2144 : case ICMP6_ECHO_REPLY:
2145 0 : *virtual_type = ICMP6_ECHO_REQUEST;
2146 0 : *virtual_id = pd->hdr.icmp6.icmp6_id;
2147 0 : break;
2148 :
2149 : case MLD_LISTENER_QUERY:
2150 : case MLD_LISTENER_REPORT: {
2151 0 : struct mld_hdr *mld = &pd->hdr.mld;
2152 : u_int32_t h;
2153 :
2154 : /*
2155 : * Listener Report can be sent by clients
2156 : * without an associated Listener Query.
2157 : * In addition to that, when Report is sent as a
2158 : * reply to a Query its source and destination
2159 : * address are different.
2160 : */
2161 0 : *icmp_dir = PF_IN;
2162 0 : *virtual_type = MLD_LISTENER_QUERY;
2163 : /* generate fake id for these messages */
2164 0 : h = mld->mld_addr.s6_addr32[0] ^
2165 0 : mld->mld_addr.s6_addr32[1] ^
2166 0 : mld->mld_addr.s6_addr32[2] ^
2167 0 : mld->mld_addr.s6_addr32[3];
2168 0 : *virtual_id = (h >> 16) ^ (h & 0xffff);
2169 : break;
2170 : }
2171 :
2172 : /*
2173 : * ICMP6_FQDN and ICMP6_NI query/reply are the same type as
2174 : * ICMP6_WRU
2175 : */
2176 : case ICMP6_WRUREQUEST:
2177 0 : *icmp_dir = PF_IN;
2178 : /* FALLTHROUGH */
2179 : case ICMP6_WRUREPLY:
2180 0 : *virtual_type = ICMP6_WRUREQUEST;
2181 0 : *virtual_id = 0; /* Nothing sane to match on! */
2182 0 : break;
2183 :
2184 : case MLD_MTRACE:
2185 0 : *icmp_dir = PF_IN;
2186 : /* FALLTHROUGH */
2187 : case MLD_MTRACE_RESP:
2188 0 : *virtual_type = MLD_MTRACE;
2189 0 : *virtual_id = 0; /* Nothing sane to match on! */
2190 0 : break;
2191 :
2192 : case ND_NEIGHBOR_SOLICIT:
2193 0 : *icmp_dir = PF_IN;
2194 : /* FALLTHROUGH */
2195 : case ND_NEIGHBOR_ADVERT: {
2196 0 : struct nd_neighbor_solicit *nd = &pd->hdr.nd_ns;
2197 : u_int32_t h;
2198 :
2199 0 : *virtual_type = ND_NEIGHBOR_SOLICIT;
2200 : /* generate fake id for these messages */
2201 0 : h = nd->nd_ns_target.s6_addr32[0] ^
2202 0 : nd->nd_ns_target.s6_addr32[1] ^
2203 0 : nd->nd_ns_target.s6_addr32[2] ^
2204 0 : nd->nd_ns_target.s6_addr32[3];
2205 0 : *virtual_id = (h >> 16) ^ (h & 0xffff);
2206 : break;
2207 : }
2208 :
2209 : /*
2210 : * These ICMP types map to other connections.
2211 : * ND_REDIRECT can't be in this list because the triggering
2212 : * packet header is optional.
2213 : */
2214 : case ICMP6_DST_UNREACH:
2215 : case ICMP6_PACKET_TOO_BIG:
2216 : case ICMP6_TIME_EXCEEDED:
2217 : case ICMP6_PARAM_PROB:
2218 : /* These will not be used, but set them anyway */
2219 0 : *icmp_dir = PF_IN;
2220 0 : *virtual_type = htons(type);
2221 0 : *virtual_id = 0;
2222 0 : return (1); /* These types match to another state */
2223 : /*
2224 : * All remaining ICMP6 types get their own states,
2225 : * and will only match in one direction.
2226 : */
2227 : default:
2228 0 : *icmp_dir = PF_IN;
2229 0 : *virtual_type = type;
2230 0 : *virtual_id = 0;
2231 0 : break;
2232 : }
2233 : break;
2234 : #endif /* INET6 */
2235 : }
2236 0 : *virtual_type = htons(*virtual_type);
2237 0 : return (0); /* These types match to their own state */
2238 0 : }
2239 :
2240 : void
2241 0 : pf_translate_icmp(struct pf_pdesc *pd, struct pf_addr *qa, u_int16_t *qp,
2242 : struct pf_addr *oa, struct pf_addr *na, u_int16_t np)
2243 : {
2244 : /* note: doesn't trouble to fixup quoted checksums, if any */
2245 :
2246 : /* change quoted protocol port */
2247 0 : if (qp != NULL)
2248 0 : pf_patch_16(pd, qp, np);
2249 :
2250 : /* change quoted ip address */
2251 0 : pf_cksum_fixup_a(pd->pcksum, qa, na, pd->af, pd->proto);
2252 0 : PF_ACPY(qa, na, pd->af);
2253 :
2254 : /* change network-header's ip address */
2255 0 : if (oa)
2256 0 : pf_translate_a(pd, oa, na);
2257 0 : }
2258 :
2259 : /* pre: *a is 16-bit aligned within its packet */
2260 : /* *a is a network header src/dst address */
2261 : int
2262 0 : pf_translate_a(struct pf_pdesc *pd, struct pf_addr *a, struct pf_addr *an)
2263 : {
2264 : int rewrite = 0;
2265 :
2266 : /* warning: !PF_ANEQ != PF_AEQ */
2267 0 : if (!PF_ANEQ(a, an, pd->af))
2268 0 : return (0);
2269 :
2270 : /* fixup transport pseudo-header, if any */
2271 0 : switch (pd->proto) {
2272 : case IPPROTO_TCP: /* FALLTHROUGH */
2273 : case IPPROTO_UDP: /* FALLTHROUGH */
2274 : case IPPROTO_ICMPV6:
2275 0 : pf_cksum_fixup_a(pd->pcksum, a, an, pd->af, pd->proto);
2276 0 : break;
2277 : default:
2278 : break; /* assume no pseudo-header */
2279 : }
2280 :
2281 0 : PF_ACPY(a, an, pd->af);
2282 : rewrite = 1;
2283 :
2284 0 : return (rewrite);
2285 0 : }
2286 :
2287 : #if INET6
2288 : /* pf_translate_af() may change pd->m, adjust local copies after calling */
2289 : int
2290 0 : pf_translate_af(struct pf_pdesc *pd)
2291 : {
2292 : static const struct pf_addr zero;
2293 : struct ip *ip4;
2294 : struct ip6_hdr *ip6;
2295 : int copyback = 0;
2296 : u_int hlen, ohlen, dlen;
2297 : u_int16_t *pc;
2298 : u_int8_t af_proto, naf_proto;
2299 :
2300 0 : hlen = (pd->naf == AF_INET) ? sizeof(*ip4) : sizeof(*ip6);
2301 0 : ohlen = pd->off;
2302 0 : dlen = pd->tot_len - pd->off;
2303 0 : pc = pd->pcksum;
2304 :
2305 0 : af_proto = naf_proto = pd->proto;
2306 0 : if (naf_proto == IPPROTO_ICMP)
2307 : af_proto = IPPROTO_ICMPV6;
2308 0 : if (naf_proto == IPPROTO_ICMPV6)
2309 : af_proto = IPPROTO_ICMP;
2310 :
2311 : /* uncover stale pseudo-header */
2312 0 : switch (af_proto) {
2313 : case IPPROTO_ICMPV6:
2314 : /* optimise: unchanged for TCP/UDP */
2315 0 : pf_cksum_fixup(pc, htons(af_proto), 0x0, af_proto);
2316 0 : pf_cksum_fixup(pc, htons(dlen), 0x0, af_proto);
2317 : /* FALLTHROUGH */
2318 : case IPPROTO_UDP: /* FALLTHROUGH */
2319 : case IPPROTO_TCP:
2320 0 : pf_cksum_fixup_a(pc, pd->src, &zero, pd->af, af_proto);
2321 0 : pf_cksum_fixup_a(pc, pd->dst, &zero, pd->af, af_proto);
2322 : copyback = 1;
2323 0 : break;
2324 : default:
2325 : break; /* assume no pseudo-header */
2326 : }
2327 :
2328 : /* replace the network header */
2329 0 : m_adj(pd->m, pd->off);
2330 0 : pd->src = NULL;
2331 0 : pd->dst = NULL;
2332 :
2333 0 : if ((M_PREPEND(pd->m, hlen, M_DONTWAIT)) == NULL) {
2334 0 : pd->m = NULL;
2335 0 : return (-1);
2336 : }
2337 :
2338 0 : pd->off = hlen;
2339 0 : pd->tot_len += hlen - ohlen;
2340 :
2341 0 : switch (pd->naf) {
2342 : case AF_INET:
2343 0 : ip4 = mtod(pd->m, struct ip *);
2344 0 : memset(ip4, 0, hlen);
2345 0 : ip4->ip_v = IPVERSION;
2346 0 : ip4->ip_hl = hlen >> 2;
2347 0 : ip4->ip_tos = pd->tos;
2348 0 : ip4->ip_len = htons(hlen + dlen);
2349 0 : ip4->ip_id = htons(ip_randomid());
2350 0 : ip4->ip_off = htons(IP_DF);
2351 0 : ip4->ip_ttl = pd->ttl;
2352 0 : ip4->ip_p = pd->proto;
2353 0 : ip4->ip_src = pd->nsaddr.v4;
2354 0 : ip4->ip_dst = pd->ndaddr.v4;
2355 0 : break;
2356 : case AF_INET6:
2357 0 : ip6 = mtod(pd->m, struct ip6_hdr *);
2358 0 : memset(ip6, 0, hlen);
2359 0 : ip6->ip6_vfc = IPV6_VERSION;
2360 0 : ip6->ip6_flow |= htonl((u_int32_t)pd->tos << 20);
2361 0 : ip6->ip6_plen = htons(dlen);
2362 0 : ip6->ip6_nxt = pd->proto;
2363 0 : if (!pd->ttl || pd->ttl > IPV6_DEFHLIM)
2364 0 : ip6->ip6_hlim = IPV6_DEFHLIM;
2365 : else
2366 0 : ip6->ip6_hlim = pd->ttl;
2367 0 : ip6->ip6_src = pd->nsaddr.v6;
2368 0 : ip6->ip6_dst = pd->ndaddr.v6;
2369 0 : break;
2370 : default:
2371 0 : unhandled_af(pd->naf);
2372 : }
2373 :
2374 : /* UDP over IPv6 must be checksummed per rfc2460 p27 */
2375 0 : if (naf_proto == IPPROTO_UDP && *pc == 0x0000 &&
2376 0 : pd->naf == AF_INET6) {
2377 0 : pd->m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
2378 0 : }
2379 :
2380 : /* cover fresh pseudo-header */
2381 0 : switch (naf_proto) {
2382 : case IPPROTO_ICMPV6:
2383 : /* optimise: unchanged for TCP/UDP */
2384 0 : pf_cksum_fixup(pc, 0x0, htons(naf_proto), naf_proto);
2385 0 : pf_cksum_fixup(pc, 0x0, htons(dlen), naf_proto);
2386 : /* FALLTHROUGH */
2387 : case IPPROTO_UDP: /* FALLTHROUGH */
2388 : case IPPROTO_TCP:
2389 0 : pf_cksum_fixup_a(pc, &zero, &pd->nsaddr, pd->naf, naf_proto);
2390 0 : pf_cksum_fixup_a(pc, &zero, &pd->ndaddr, pd->naf, naf_proto);
2391 : copyback = 1;
2392 0 : break;
2393 : default:
2394 : break; /* assume no pseudo-header */
2395 : }
2396 :
2397 : /* flush pd->pcksum */
2398 0 : if (copyback)
2399 0 : m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
2400 :
2401 0 : return (0);
2402 0 : }
2403 :
2404 : int
2405 0 : pf_change_icmp_af(struct mbuf *m, int ipoff2, struct pf_pdesc *pd,
2406 : struct pf_pdesc *pd2, struct pf_addr *src, struct pf_addr *dst,
2407 : sa_family_t af, sa_family_t naf)
2408 : {
2409 : struct mbuf *n = NULL;
2410 : struct ip *ip4;
2411 : struct ip6_hdr *ip6;
2412 : u_int hlen, ohlen, dlen;
2413 : int d;
2414 :
2415 0 : if (af == naf || (af != AF_INET && af != AF_INET6) ||
2416 0 : (naf != AF_INET && naf != AF_INET6))
2417 0 : return (-1);
2418 :
2419 : /* split the mbuf chain on the quoted ip/ip6 header boundary */
2420 0 : if ((n = m_split(m, ipoff2, M_DONTWAIT)) == NULL)
2421 0 : return (-1);
2422 :
2423 : /* new quoted header */
2424 0 : hlen = naf == AF_INET ? sizeof(*ip4) : sizeof(*ip6);
2425 : /* old quoted header */
2426 0 : ohlen = pd2->off - ipoff2;
2427 :
2428 : /* trim old quoted header */
2429 0 : pf_cksum_uncover(pd->pcksum, in_cksum(n, ohlen), pd->proto);
2430 0 : m_adj(n, ohlen);
2431 :
2432 : /* prepend a new, translated, quoted header */
2433 0 : if ((M_PREPEND(n, hlen, M_DONTWAIT)) == NULL)
2434 0 : return (-1);
2435 :
2436 0 : switch (naf) {
2437 : case AF_INET:
2438 0 : ip4 = mtod(n, struct ip *);
2439 0 : memset(ip4, 0, sizeof(*ip4));
2440 0 : ip4->ip_v = IPVERSION;
2441 0 : ip4->ip_hl = sizeof(*ip4) >> 2;
2442 0 : ip4->ip_len = htons(sizeof(*ip4) + pd2->tot_len - ohlen);
2443 0 : ip4->ip_id = htons(ip_randomid());
2444 0 : ip4->ip_off = htons(IP_DF);
2445 0 : ip4->ip_ttl = pd2->ttl;
2446 0 : if (pd2->proto == IPPROTO_ICMPV6)
2447 0 : ip4->ip_p = IPPROTO_ICMP;
2448 : else
2449 0 : ip4->ip_p = pd2->proto;
2450 0 : ip4->ip_src = src->v4;
2451 0 : ip4->ip_dst = dst->v4;
2452 0 : ip4->ip_sum = in_cksum(n, ip4->ip_hl << 2);
2453 0 : break;
2454 : case AF_INET6:
2455 0 : ip6 = mtod(n, struct ip6_hdr *);
2456 0 : memset(ip6, 0, sizeof(*ip6));
2457 0 : ip6->ip6_vfc = IPV6_VERSION;
2458 0 : ip6->ip6_plen = htons(pd2->tot_len - ohlen);
2459 0 : if (pd2->proto == IPPROTO_ICMP)
2460 0 : ip6->ip6_nxt = IPPROTO_ICMPV6;
2461 : else
2462 0 : ip6->ip6_nxt = pd2->proto;
2463 0 : if (!pd2->ttl || pd2->ttl > IPV6_DEFHLIM)
2464 0 : ip6->ip6_hlim = IPV6_DEFHLIM;
2465 : else
2466 0 : ip6->ip6_hlim = pd2->ttl;
2467 0 : ip6->ip6_src = src->v6;
2468 0 : ip6->ip6_dst = dst->v6;
2469 0 : break;
2470 : }
2471 :
2472 : /* cover new quoted header */
2473 : /* optimise: any new AF_INET header of ours sums to zero */
2474 0 : if (naf != AF_INET) {
2475 0 : pf_cksum_cover(pd->pcksum, in_cksum(n, hlen), pd->proto);
2476 0 : }
2477 :
2478 : /* reattach modified quoted packet to outer header */
2479 : {
2480 0 : int nlen = n->m_pkthdr.len;
2481 0 : m_cat(m, n);
2482 0 : m->m_pkthdr.len += nlen;
2483 : }
2484 :
2485 : /* account for altered length */
2486 0 : d = hlen - ohlen;
2487 :
2488 0 : if (pd->proto == IPPROTO_ICMPV6) {
2489 : /* fixup pseudo-header */
2490 0 : dlen = pd->tot_len - pd->off;
2491 0 : pf_cksum_fixup(pd->pcksum,
2492 0 : htons(dlen), htons(dlen + d), pd->proto);
2493 0 : }
2494 :
2495 0 : pd->tot_len += d;
2496 0 : pd2->tot_len += d;
2497 0 : pd2->off += d;
2498 :
2499 : /* note: not bothering to update network headers as
2500 : these due for rewrite by pf_translate_af() */
2501 :
2502 0 : return (0);
2503 0 : }
2504 :
2505 :
2506 : #define PTR_IP(field) (offsetof(struct ip, field))
2507 : #define PTR_IP6(field) (offsetof(struct ip6_hdr, field))
2508 :
2509 : int
2510 0 : pf_translate_icmp_af(struct pf_pdesc *pd, int af, void *arg)
2511 : {
2512 : struct icmp *icmp4;
2513 : struct icmp6_hdr *icmp6;
2514 : u_int32_t mtu;
2515 : int32_t ptr = -1;
2516 : u_int8_t type;
2517 : u_int8_t code;
2518 :
2519 0 : switch (af) {
2520 : case AF_INET:
2521 0 : icmp6 = arg;
2522 0 : type = icmp6->icmp6_type;
2523 0 : code = icmp6->icmp6_code;
2524 0 : mtu = ntohl(icmp6->icmp6_mtu);
2525 :
2526 0 : switch (type) {
2527 : case ICMP6_ECHO_REQUEST:
2528 : type = ICMP_ECHO;
2529 0 : break;
2530 : case ICMP6_ECHO_REPLY:
2531 : type = ICMP_ECHOREPLY;
2532 0 : break;
2533 : case ICMP6_DST_UNREACH:
2534 : type = ICMP_UNREACH;
2535 0 : switch (code) {
2536 : case ICMP6_DST_UNREACH_NOROUTE:
2537 : case ICMP6_DST_UNREACH_BEYONDSCOPE:
2538 : case ICMP6_DST_UNREACH_ADDR:
2539 : code = ICMP_UNREACH_HOST;
2540 0 : break;
2541 : case ICMP6_DST_UNREACH_ADMIN:
2542 : code = ICMP_UNREACH_HOST_PROHIB;
2543 0 : break;
2544 : case ICMP6_DST_UNREACH_NOPORT:
2545 : code = ICMP_UNREACH_PORT;
2546 0 : break;
2547 : default:
2548 0 : return (-1);
2549 : }
2550 : break;
2551 : case ICMP6_PACKET_TOO_BIG:
2552 : type = ICMP_UNREACH;
2553 : code = ICMP_UNREACH_NEEDFRAG;
2554 0 : mtu -= 20;
2555 0 : break;
2556 : case ICMP6_TIME_EXCEEDED:
2557 : type = ICMP_TIMXCEED;
2558 0 : break;
2559 : case ICMP6_PARAM_PROB:
2560 0 : switch (code) {
2561 : case ICMP6_PARAMPROB_HEADER:
2562 : type = ICMP_PARAMPROB;
2563 : code = ICMP_PARAMPROB_ERRATPTR;
2564 : ptr = ntohl(icmp6->icmp6_pptr);
2565 :
2566 0 : if (ptr == PTR_IP6(ip6_vfc))
2567 : ; /* preserve */
2568 0 : else if (ptr == PTR_IP6(ip6_vfc) + 1)
2569 0 : ptr = PTR_IP(ip_tos);
2570 0 : else if (ptr == PTR_IP6(ip6_plen) ||
2571 0 : ptr == PTR_IP6(ip6_plen) + 1)
2572 0 : ptr = PTR_IP(ip_len);
2573 0 : else if (ptr == PTR_IP6(ip6_nxt))
2574 0 : ptr = PTR_IP(ip_p);
2575 0 : else if (ptr == PTR_IP6(ip6_hlim))
2576 0 : ptr = PTR_IP(ip_ttl);
2577 0 : else if (ptr >= PTR_IP6(ip6_src) &&
2578 0 : ptr < PTR_IP6(ip6_dst))
2579 0 : ptr = PTR_IP(ip_src);
2580 0 : else if (ptr >= PTR_IP6(ip6_dst) &&
2581 0 : ptr < sizeof(struct ip6_hdr))
2582 : ptr = PTR_IP(ip_dst);
2583 : else {
2584 0 : return (-1);
2585 : }
2586 : break;
2587 : case ICMP6_PARAMPROB_NEXTHEADER:
2588 : type = ICMP_UNREACH;
2589 : code = ICMP_UNREACH_PROTOCOL;
2590 0 : break;
2591 : default:
2592 0 : return (-1);
2593 : }
2594 : break;
2595 : default:
2596 0 : return (-1);
2597 : }
2598 :
2599 0 : pf_patch_8(pd, &icmp6->icmp6_type, type, PF_HI);
2600 0 : pf_patch_8(pd, &icmp6->icmp6_code, code, PF_LO);
2601 :
2602 : /* aligns well with a icmpv4 nextmtu */
2603 0 : pf_patch_32(pd, &icmp6->icmp6_mtu, htonl(mtu));
2604 :
2605 : /* icmpv4 pptr is a one most significant byte */
2606 0 : if (ptr >= 0)
2607 0 : pf_patch_32(pd, &icmp6->icmp6_pptr, htonl(ptr << 24));
2608 : break;
2609 : case AF_INET6:
2610 0 : icmp4 = arg;
2611 0 : type = icmp4->icmp_type;
2612 0 : code = icmp4->icmp_code;
2613 0 : mtu = ntohs(icmp4->icmp_nextmtu);
2614 :
2615 0 : switch (type) {
2616 : case ICMP_ECHO:
2617 : type = ICMP6_ECHO_REQUEST;
2618 0 : break;
2619 : case ICMP_ECHOREPLY:
2620 : type = ICMP6_ECHO_REPLY;
2621 0 : break;
2622 : case ICMP_UNREACH:
2623 : type = ICMP6_DST_UNREACH;
2624 0 : switch (code) {
2625 : case ICMP_UNREACH_NET:
2626 : case ICMP_UNREACH_HOST:
2627 : case ICMP_UNREACH_NET_UNKNOWN:
2628 : case ICMP_UNREACH_HOST_UNKNOWN:
2629 : case ICMP_UNREACH_ISOLATED:
2630 : case ICMP_UNREACH_TOSNET:
2631 : case ICMP_UNREACH_TOSHOST:
2632 : code = ICMP6_DST_UNREACH_NOROUTE;
2633 0 : break;
2634 : case ICMP_UNREACH_PORT:
2635 : code = ICMP6_DST_UNREACH_NOPORT;
2636 0 : break;
2637 : case ICMP_UNREACH_NET_PROHIB:
2638 : case ICMP_UNREACH_HOST_PROHIB:
2639 : case ICMP_UNREACH_FILTER_PROHIB:
2640 : case ICMP_UNREACH_PRECEDENCE_CUTOFF:
2641 : code = ICMP6_DST_UNREACH_ADMIN;
2642 0 : break;
2643 : case ICMP_UNREACH_PROTOCOL:
2644 : type = ICMP6_PARAM_PROB;
2645 : code = ICMP6_PARAMPROB_NEXTHEADER;
2646 : ptr = offsetof(struct ip6_hdr, ip6_nxt);
2647 0 : break;
2648 : case ICMP_UNREACH_NEEDFRAG:
2649 : type = ICMP6_PACKET_TOO_BIG;
2650 : code = 0;
2651 0 : mtu += 20;
2652 0 : break;
2653 : default:
2654 0 : return (-1);
2655 : }
2656 : break;
2657 : case ICMP_TIMXCEED:
2658 : type = ICMP6_TIME_EXCEEDED;
2659 0 : break;
2660 : case ICMP_PARAMPROB:
2661 : type = ICMP6_PARAM_PROB;
2662 0 : switch (code) {
2663 : case ICMP_PARAMPROB_ERRATPTR:
2664 : code = ICMP6_PARAMPROB_HEADER;
2665 0 : break;
2666 : case ICMP_PARAMPROB_LENGTH:
2667 : code = ICMP6_PARAMPROB_HEADER;
2668 0 : break;
2669 : default:
2670 0 : return (-1);
2671 : }
2672 :
2673 0 : ptr = icmp4->icmp_pptr;
2674 0 : if (ptr == 0 || ptr == PTR_IP(ip_tos))
2675 : ; /* preserve */
2676 0 : else if (ptr == PTR_IP(ip_len) ||
2677 0 : ptr == PTR_IP(ip_len) + 1)
2678 0 : ptr = PTR_IP6(ip6_plen);
2679 0 : else if (ptr == PTR_IP(ip_ttl))
2680 0 : ptr = PTR_IP6(ip6_hlim);
2681 0 : else if (ptr == PTR_IP(ip_p))
2682 0 : ptr = PTR_IP6(ip6_nxt);
2683 0 : else if (ptr >= PTR_IP(ip_src) &&
2684 0 : ptr < PTR_IP(ip_dst))
2685 0 : ptr = PTR_IP6(ip6_src);
2686 0 : else if (ptr >= PTR_IP(ip_dst) &&
2687 0 : ptr < sizeof(struct ip))
2688 : ptr = PTR_IP6(ip6_dst);
2689 : else {
2690 0 : return (-1);
2691 : }
2692 : break;
2693 : default:
2694 0 : return (-1);
2695 : }
2696 :
2697 0 : pf_patch_8(pd, &icmp4->icmp_type, type, PF_HI);
2698 0 : pf_patch_8(pd, &icmp4->icmp_code, code, PF_LO);
2699 0 : pf_patch_16(pd, &icmp4->icmp_nextmtu, htons(mtu));
2700 0 : if (ptr >= 0)
2701 0 : pf_patch_32(pd, &icmp4->icmp_void, htonl(ptr));
2702 : break;
2703 : }
2704 :
2705 0 : return (0);
2706 0 : }
2707 : #endif /* INET6 */
2708 :
2709 : /*
2710 : * Need to modulate the sequence numbers in the TCP SACK option
2711 : * (credits to Krzysztof Pfaff for report and patch)
2712 : */
2713 : int
2714 0 : pf_modulate_sack(struct pf_pdesc *pd, struct pf_state_peer *dst)
2715 : {
2716 0 : struct sackblk sack;
2717 : int copyback = 0, i;
2718 : int olen, optsoff;
2719 0 : u_int8_t opts[MAX_TCPOPTLEN], *opt, *eoh;
2720 :
2721 0 : olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
2722 0 : optsoff = pd->off + sizeof(struct tcphdr);
2723 : #define TCPOLEN_MINSACK (TCPOLEN_SACK + 2)
2724 0 : if (olen < TCPOLEN_MINSACK ||
2725 0 : !pf_pull_hdr(pd->m, optsoff, opts, olen, NULL, NULL, pd->af))
2726 0 : return (0);
2727 :
2728 0 : eoh = opts + olen;
2729 : opt = opts;
2730 0 : while ((opt = pf_find_tcpopt(opt, opts, olen,
2731 0 : TCPOPT_SACK, TCPOLEN_MINSACK)) != NULL)
2732 : {
2733 0 : size_t safelen = MIN(opt[1], (eoh - opt));
2734 0 : for (i = 2; i + TCPOLEN_SACK <= safelen; i += TCPOLEN_SACK) {
2735 0 : size_t startoff = (opt + i) - opts;
2736 0 : memcpy(&sack, &opt[i], sizeof(sack));
2737 0 : pf_patch_32_unaligned(pd, &sack.start,
2738 0 : htonl(ntohl(sack.start) - dst->seqdiff),
2739 0 : PF_ALGNMNT(startoff));
2740 0 : pf_patch_32_unaligned(pd, &sack.end,
2741 0 : htonl(ntohl(sack.end) - dst->seqdiff),
2742 0 : PF_ALGNMNT(startoff + sizeof(sack.start)));
2743 0 : memcpy(&opt[i], &sack, sizeof(sack));
2744 : }
2745 : copyback = 1;
2746 0 : opt += opt[1];
2747 : }
2748 :
2749 0 : if (copyback)
2750 0 : m_copyback(pd->m, optsoff, olen, opts, M_NOWAIT);
2751 0 : return (copyback);
2752 0 : }
2753 :
2754 : struct mbuf *
2755 0 : pf_build_tcp(const struct pf_rule *r, sa_family_t af,
2756 : const struct pf_addr *saddr, const struct pf_addr *daddr,
2757 : u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
2758 : u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
2759 : u_int16_t rtag, u_int sack, u_int rdom)
2760 : {
2761 : struct mbuf *m;
2762 : int len, tlen;
2763 : struct ip *h;
2764 : #ifdef INET6
2765 : struct ip6_hdr *h6;
2766 : #endif /* INET6 */
2767 : struct tcphdr *th;
2768 : char *opt;
2769 :
2770 : /* maximum segment size tcp option */
2771 : tlen = sizeof(struct tcphdr);
2772 0 : if (mss)
2773 0 : tlen += 4;
2774 0 : if (sack)
2775 0 : tlen += 2;
2776 :
2777 0 : switch (af) {
2778 : case AF_INET:
2779 0 : len = sizeof(struct ip) + tlen;
2780 0 : break;
2781 : #ifdef INET6
2782 : case AF_INET6:
2783 0 : len = sizeof(struct ip6_hdr) + tlen;
2784 0 : break;
2785 : #endif /* INET6 */
2786 : default:
2787 0 : unhandled_af(af);
2788 : }
2789 :
2790 : /* create outgoing mbuf */
2791 0 : m = m_gethdr(M_DONTWAIT, MT_HEADER);
2792 0 : if (m == NULL)
2793 0 : return (NULL);
2794 0 : if (tag)
2795 0 : m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
2796 0 : m->m_pkthdr.pf.tag = rtag;
2797 0 : m->m_pkthdr.ph_rtableid = rdom;
2798 0 : if (r && (r->scrub_flags & PFSTATE_SETPRIO))
2799 0 : m->m_pkthdr.pf.prio = r->set_prio[0];
2800 0 : if (r && r->qid)
2801 0 : m->m_pkthdr.pf.qid = r->qid;
2802 0 : m->m_data += max_linkhdr;
2803 0 : m->m_pkthdr.len = m->m_len = len;
2804 0 : m->m_pkthdr.ph_ifidx = 0;
2805 0 : m->m_pkthdr.csum_flags |= M_TCP_CSUM_OUT;
2806 0 : memset(m->m_data, 0, len);
2807 0 : switch (af) {
2808 : case AF_INET:
2809 0 : h = mtod(m, struct ip *);
2810 0 : h->ip_p = IPPROTO_TCP;
2811 0 : h->ip_len = htons(tlen);
2812 0 : h->ip_v = 4;
2813 0 : h->ip_hl = sizeof(*h) >> 2;
2814 0 : h->ip_tos = IPTOS_LOWDELAY;
2815 0 : h->ip_len = htons(len);
2816 0 : h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
2817 0 : h->ip_ttl = ttl ? ttl : ip_defttl;
2818 0 : h->ip_sum = 0;
2819 0 : h->ip_src.s_addr = saddr->v4.s_addr;
2820 0 : h->ip_dst.s_addr = daddr->v4.s_addr;
2821 :
2822 0 : th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
2823 0 : break;
2824 : #ifdef INET6
2825 : case AF_INET6:
2826 0 : h6 = mtod(m, struct ip6_hdr *);
2827 0 : h6->ip6_nxt = IPPROTO_TCP;
2828 0 : h6->ip6_plen = htons(tlen);
2829 0 : h6->ip6_vfc |= IPV6_VERSION;
2830 0 : h6->ip6_hlim = IPV6_DEFHLIM;
2831 0 : memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
2832 0 : memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
2833 :
2834 0 : th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
2835 0 : break;
2836 : #endif /* INET6 */
2837 : default:
2838 0 : unhandled_af(af);
2839 : }
2840 :
2841 : /* TCP header */
2842 0 : th->th_sport = sport;
2843 0 : th->th_dport = dport;
2844 0 : th->th_seq = htonl(seq);
2845 0 : th->th_ack = htonl(ack);
2846 0 : th->th_off = tlen >> 2;
2847 0 : th->th_flags = flags;
2848 0 : th->th_win = htons(win);
2849 :
2850 0 : opt = (char *)(th + 1);
2851 0 : if (mss) {
2852 0 : opt[0] = TCPOPT_MAXSEG;
2853 0 : opt[1] = 4;
2854 0 : mss = htons(mss);
2855 0 : memcpy((opt + 2), &mss, 2);
2856 0 : opt += 4;
2857 0 : }
2858 0 : if (sack) {
2859 0 : opt[0] = TCPOPT_SACK_PERMITTED;
2860 0 : opt[1] = 2;
2861 : opt += 2;
2862 0 : }
2863 :
2864 0 : return (m);
2865 0 : }
2866 :
2867 : void
2868 0 : pf_send_tcp(const struct pf_rule *r, sa_family_t af,
2869 : const struct pf_addr *saddr, const struct pf_addr *daddr,
2870 : u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
2871 : u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
2872 : u_int16_t rtag, u_int rdom)
2873 : {
2874 : struct mbuf *m;
2875 :
2876 0 : if ((m = pf_build_tcp(r, af, saddr, daddr, sport, dport, seq, ack,
2877 0 : flags, win, mss, ttl, tag, rtag, 0, rdom)) == NULL)
2878 0 : return;
2879 :
2880 0 : switch (af) {
2881 : case AF_INET:
2882 0 : ip_send(m);
2883 0 : break;
2884 : #ifdef INET6
2885 : case AF_INET6:
2886 0 : ip6_send(m);
2887 0 : break;
2888 : #endif /* INET6 */
2889 : }
2890 0 : }
2891 :
2892 : static void
2893 0 : pf_send_challenge_ack(struct pf_pdesc *pd, struct pf_state *s,
2894 : struct pf_state_peer *src, struct pf_state_peer *dst)
2895 : {
2896 : /*
2897 : * We are sending challenge ACK as a response to SYN packet, which
2898 : * matches existing state (modulo TCP window check). Therefore packet
2899 : * must be sent on behalf of destination.
2900 : *
2901 : * We expect sender to remain either silent, or send RST packet
2902 : * so both, firewall and remote peer, can purge dead state from
2903 : * memory.
2904 : */
2905 0 : pf_send_tcp(s->rule.ptr, pd->af, pd->dst, pd->src,
2906 0 : pd->hdr.tcp.th_dport, pd->hdr.tcp.th_sport, dst->seqlo,
2907 0 : src->seqlo, TH_ACK, 0, 0, s->rule.ptr->return_ttl, 1, 0,
2908 0 : pd->rdomain);
2909 0 : }
2910 :
2911 : void
2912 0 : pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, int param,
2913 : sa_family_t af, struct pf_rule *r, u_int rdomain)
2914 : {
2915 : struct mbuf *m0;
2916 :
2917 0 : if ((m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT)) == NULL)
2918 0 : return;
2919 :
2920 0 : m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
2921 0 : m0->m_pkthdr.ph_rtableid = rdomain;
2922 0 : if (r && (r->scrub_flags & PFSTATE_SETPRIO))
2923 0 : m0->m_pkthdr.pf.prio = r->set_prio[0];
2924 0 : if (r && r->qid)
2925 0 : m0->m_pkthdr.pf.qid = r->qid;
2926 :
2927 0 : switch (af) {
2928 : case AF_INET:
2929 0 : icmp_error(m0, type, code, 0, param);
2930 0 : break;
2931 : #ifdef INET6
2932 : case AF_INET6:
2933 0 : icmp6_error(m0, type, code, param);
2934 0 : break;
2935 : #endif /* INET6 */
2936 : }
2937 0 : }
2938 :
2939 : /*
2940 : * Return ((n = 0) == (a = b [with mask m]))
2941 : * Note: n != 0 => returns (a != b [with mask m])
2942 : */
2943 : int
2944 0 : pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
2945 : struct pf_addr *b, sa_family_t af)
2946 : {
2947 0 : switch (af) {
2948 : case AF_INET:
2949 0 : if ((a->addr32[0] & m->addr32[0]) ==
2950 0 : (b->addr32[0] & m->addr32[0]))
2951 0 : return (n == 0);
2952 : break;
2953 : #ifdef INET6
2954 : case AF_INET6:
2955 0 : if (((a->addr32[0] & m->addr32[0]) ==
2956 0 : (b->addr32[0] & m->addr32[0])) &&
2957 0 : ((a->addr32[1] & m->addr32[1]) ==
2958 0 : (b->addr32[1] & m->addr32[1])) &&
2959 0 : ((a->addr32[2] & m->addr32[2]) ==
2960 0 : (b->addr32[2] & m->addr32[2])) &&
2961 0 : ((a->addr32[3] & m->addr32[3]) ==
2962 0 : (b->addr32[3] & m->addr32[3])))
2963 0 : return (n == 0);
2964 : break;
2965 : #endif /* INET6 */
2966 : }
2967 :
2968 0 : return (n != 0);
2969 0 : }
2970 :
2971 : /*
2972 : * Return 1 if b <= a <= e, otherwise return 0.
2973 : */
2974 : int
2975 0 : pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
2976 : struct pf_addr *a, sa_family_t af)
2977 : {
2978 0 : switch (af) {
2979 : case AF_INET:
2980 0 : if ((ntohl(a->addr32[0]) < ntohl(b->addr32[0])) ||
2981 0 : (ntohl(a->addr32[0]) > ntohl(e->addr32[0])))
2982 0 : return (0);
2983 : break;
2984 : #ifdef INET6
2985 : case AF_INET6: {
2986 : int i;
2987 :
2988 : /* check a >= b */
2989 0 : for (i = 0; i < 4; ++i)
2990 0 : if (ntohl(a->addr32[i]) > ntohl(b->addr32[i]))
2991 : break;
2992 0 : else if (ntohl(a->addr32[i]) < ntohl(b->addr32[i]))
2993 0 : return (0);
2994 : /* check a <= e */
2995 0 : for (i = 0; i < 4; ++i)
2996 0 : if (ntohl(a->addr32[i]) < ntohl(e->addr32[i]))
2997 : break;
2998 0 : else if (ntohl(a->addr32[i]) > ntohl(e->addr32[i]))
2999 0 : return (0);
3000 0 : break;
3001 : }
3002 : #endif /* INET6 */
3003 : }
3004 0 : return (1);
3005 0 : }
3006 :
3007 : int
3008 0 : pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
3009 : {
3010 0 : switch (op) {
3011 : case PF_OP_IRG:
3012 0 : return ((p > a1) && (p < a2));
3013 : case PF_OP_XRG:
3014 0 : return ((p < a1) || (p > a2));
3015 : case PF_OP_RRG:
3016 0 : return ((p >= a1) && (p <= a2));
3017 : case PF_OP_EQ:
3018 0 : return (p == a1);
3019 : case PF_OP_NE:
3020 0 : return (p != a1);
3021 : case PF_OP_LT:
3022 0 : return (p < a1);
3023 : case PF_OP_LE:
3024 0 : return (p <= a1);
3025 : case PF_OP_GT:
3026 0 : return (p > a1);
3027 : case PF_OP_GE:
3028 0 : return (p >= a1);
3029 : }
3030 0 : return (0); /* never reached */
3031 0 : }
3032 :
3033 : int
3034 0 : pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
3035 : {
3036 0 : return (pf_match(op, ntohs(a1), ntohs(a2), ntohs(p)));
3037 : }
3038 :
3039 : int
3040 0 : pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
3041 : {
3042 0 : if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
3043 0 : return (0);
3044 0 : return (pf_match(op, a1, a2, u));
3045 0 : }
3046 :
3047 : int
3048 0 : pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
3049 : {
3050 0 : if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
3051 0 : return (0);
3052 0 : return (pf_match(op, a1, a2, g));
3053 0 : }
3054 :
3055 : int
3056 0 : pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag)
3057 : {
3058 0 : if (*tag == -1)
3059 0 : *tag = m->m_pkthdr.pf.tag;
3060 :
3061 0 : return ((!r->match_tag_not && r->match_tag == *tag) ||
3062 0 : (r->match_tag_not && r->match_tag != *tag));
3063 : }
3064 :
3065 : int
3066 0 : pf_match_rcvif(struct mbuf *m, struct pf_rule *r)
3067 : {
3068 : struct ifnet *ifp;
3069 : struct pfi_kif *kif;
3070 :
3071 0 : ifp = if_get(m->m_pkthdr.ph_ifidx);
3072 0 : if (ifp == NULL)
3073 0 : return (0);
3074 :
3075 : #if NCARP > 0
3076 0 : if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
3077 0 : kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
3078 : else
3079 : #endif /* NCARP */
3080 0 : kif = (struct pfi_kif *)ifp->if_pf_kif;
3081 :
3082 0 : if_put(ifp);
3083 :
3084 0 : if (kif == NULL) {
3085 0 : DPFPRINTF(LOG_ERR,
3086 : "%s: kif == NULL, @%d via %s", __func__,
3087 : r->nr, r->rcv_ifname);
3088 0 : return (0);
3089 : }
3090 :
3091 0 : return (pfi_kif_match(r->rcv_kif, kif));
3092 0 : }
3093 :
3094 : void
3095 0 : pf_tag_packet(struct mbuf *m, int tag, int rtableid)
3096 : {
3097 0 : if (tag > 0)
3098 0 : m->m_pkthdr.pf.tag = tag;
3099 0 : if (rtableid >= 0)
3100 0 : m->m_pkthdr.ph_rtableid = (u_int)rtableid;
3101 0 : }
3102 :
3103 : enum pf_test_status
3104 0 : pf_step_into_anchor(struct pf_test_ctx *ctx, struct pf_rule *r)
3105 : {
3106 : int rv;
3107 :
3108 0 : if (ctx->depth >= PF_ANCHOR_STACK_MAX) {
3109 0 : log(LOG_ERR, "pf_step_into_anchor: stack overflow\n");
3110 0 : return (PF_TEST_FAIL);
3111 : }
3112 :
3113 0 : ctx->depth++;
3114 :
3115 0 : if (r->anchor_wildcard) {
3116 : struct pf_anchor *child;
3117 : rv = PF_TEST_OK;
3118 0 : RB_FOREACH(child, pf_anchor_node, &r->anchor->children) {
3119 0 : rv = pf_match_rule(ctx, &child->ruleset);
3120 0 : if ((rv == PF_TEST_QUICK) || (rv == PF_TEST_FAIL)) {
3121 : /*
3122 : * we either hit a rule with quick action
3123 : * (more likely), or hit some runtime
3124 : * error (e.g. pool_get() failure).
3125 : */
3126 : break;
3127 : }
3128 : }
3129 0 : } else {
3130 0 : rv = pf_match_rule(ctx, &r->anchor->ruleset);
3131 : }
3132 :
3133 0 : ctx->depth--;
3134 :
3135 0 : return (rv);
3136 0 : }
3137 :
3138 : void
3139 0 : pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
3140 : struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
3141 : {
3142 0 : switch (af) {
3143 : case AF_INET:
3144 0 : naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
3145 0 : ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
3146 0 : break;
3147 : #ifdef INET6
3148 : case AF_INET6:
3149 0 : naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
3150 0 : ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
3151 0 : naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
3152 0 : ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
3153 0 : naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
3154 0 : ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
3155 0 : naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
3156 0 : ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
3157 0 : break;
3158 : #endif /* INET6 */
3159 : default:
3160 0 : unhandled_af(af);
3161 : }
3162 0 : }
3163 :
3164 : void
3165 0 : pf_addr_inc(struct pf_addr *addr, sa_family_t af)
3166 : {
3167 0 : switch (af) {
3168 : case AF_INET:
3169 0 : addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
3170 0 : break;
3171 : #ifdef INET6
3172 : case AF_INET6:
3173 0 : if (addr->addr32[3] == 0xffffffff) {
3174 0 : addr->addr32[3] = 0;
3175 0 : if (addr->addr32[2] == 0xffffffff) {
3176 0 : addr->addr32[2] = 0;
3177 0 : if (addr->addr32[1] == 0xffffffff) {
3178 0 : addr->addr32[1] = 0;
3179 0 : addr->addr32[0] =
3180 0 : htonl(ntohl(addr->addr32[0]) + 1);
3181 0 : } else
3182 0 : addr->addr32[1] =
3183 0 : htonl(ntohl(addr->addr32[1]) + 1);
3184 : } else
3185 0 : addr->addr32[2] =
3186 0 : htonl(ntohl(addr->addr32[2]) + 1);
3187 : } else
3188 0 : addr->addr32[3] =
3189 0 : htonl(ntohl(addr->addr32[3]) + 1);
3190 : break;
3191 : #endif /* INET6 */
3192 : default:
3193 0 : unhandled_af(af);
3194 : }
3195 0 : }
3196 :
3197 : int
3198 0 : pf_socket_lookup(struct pf_pdesc *pd)
3199 : {
3200 : struct pf_addr *saddr, *daddr;
3201 : u_int16_t sport, dport;
3202 : struct inpcbtable *tb;
3203 : struct inpcb *inp;
3204 :
3205 0 : pd->lookup.uid = UID_MAX;
3206 0 : pd->lookup.gid = GID_MAX;
3207 0 : pd->lookup.pid = NO_PID;
3208 0 : switch (pd->virtual_proto) {
3209 : case IPPROTO_TCP:
3210 0 : sport = pd->hdr.tcp.th_sport;
3211 0 : dport = pd->hdr.tcp.th_dport;
3212 : PF_ASSERT_LOCKED();
3213 0 : NET_ASSERT_LOCKED();
3214 : tb = &tcbtable;
3215 0 : break;
3216 : case IPPROTO_UDP:
3217 0 : sport = pd->hdr.udp.uh_sport;
3218 0 : dport = pd->hdr.udp.uh_dport;
3219 : PF_ASSERT_LOCKED();
3220 0 : NET_ASSERT_LOCKED();
3221 : tb = &udbtable;
3222 0 : break;
3223 : default:
3224 0 : return (-1);
3225 : }
3226 0 : if (pd->dir == PF_IN) {
3227 0 : saddr = pd->src;
3228 0 : daddr = pd->dst;
3229 0 : } else {
3230 : u_int16_t p;
3231 :
3232 : p = sport;
3233 : sport = dport;
3234 : dport = p;
3235 0 : saddr = pd->dst;
3236 0 : daddr = pd->src;
3237 : }
3238 0 : switch (pd->af) {
3239 : case AF_INET:
3240 : /*
3241 : * Fails when rtable is changed while evaluating the ruleset
3242 : * The socket looked up will not match the one hit in the end.
3243 : */
3244 0 : inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport,
3245 0 : pd->rdomain);
3246 0 : if (inp == NULL) {
3247 0 : inp = in_pcblookup_listen(tb, daddr->v4, dport,
3248 0 : NULL, pd->rdomain);
3249 0 : if (inp == NULL)
3250 0 : return (-1);
3251 : }
3252 : break;
3253 : #ifdef INET6
3254 : case AF_INET6:
3255 0 : inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
3256 0 : dport, pd->rdomain);
3257 0 : if (inp == NULL) {
3258 0 : inp = in6_pcblookup_listen(tb, &daddr->v6, dport,
3259 0 : NULL, pd->rdomain);
3260 0 : if (inp == NULL)
3261 0 : return (-1);
3262 : }
3263 : break;
3264 : #endif /* INET6 */
3265 : default:
3266 0 : unhandled_af(pd->af);
3267 : }
3268 0 : pd->lookup.uid = inp->inp_socket->so_euid;
3269 0 : pd->lookup.gid = inp->inp_socket->so_egid;
3270 0 : pd->lookup.pid = inp->inp_socket->so_cpid;
3271 0 : return (1);
3272 0 : }
3273 :
3274 : /* post: r => (r[0] == type /\ r[1] >= min_typelen >= 2 "validity"
3275 : * /\ (eoh - r) >= min_typelen >= 2 "safety" )
3276 : *
3277 : * warning: r + r[1] may exceed opts bounds for r[1] > min_typelen
3278 : */
3279 : u_int8_t*
3280 0 : pf_find_tcpopt(u_int8_t *opt, u_int8_t *opts, size_t hlen, u_int8_t type,
3281 : u_int8_t min_typelen)
3282 : {
3283 0 : u_int8_t *eoh = opts + hlen;
3284 :
3285 0 : if (min_typelen < 2)
3286 0 : return (NULL);
3287 :
3288 0 : while ((eoh - opt) >= min_typelen) {
3289 0 : switch (*opt) {
3290 : case TCPOPT_EOL:
3291 : /* FALLTHROUGH - Workaround the failure of some
3292 : systems to NOP-pad their bzero'd option buffers,
3293 : producing spurious EOLs */
3294 : case TCPOPT_NOP:
3295 0 : opt++;
3296 0 : continue;
3297 : default:
3298 0 : if (opt[0] == type &&
3299 0 : opt[1] >= min_typelen)
3300 0 : return (opt);
3301 : }
3302 :
3303 0 : opt += MAX(opt[1], 2); /* evade infinite loops */
3304 : }
3305 :
3306 0 : return (NULL);
3307 0 : }
3308 :
3309 : u_int8_t
3310 0 : pf_get_wscale(struct pf_pdesc *pd)
3311 : {
3312 : int olen;
3313 0 : u_int8_t opts[MAX_TCPOPTLEN], *opt;
3314 : u_int8_t wscale = 0;
3315 :
3316 0 : olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
3317 0 : if (olen < TCPOLEN_WINDOW || !pf_pull_hdr(pd->m,
3318 0 : pd->off + sizeof(struct tcphdr), opts, olen, NULL, NULL, pd->af))
3319 0 : return (0);
3320 :
3321 : opt = opts;
3322 0 : while ((opt = pf_find_tcpopt(opt, opts, olen,
3323 0 : TCPOPT_WINDOW, TCPOLEN_WINDOW)) != NULL) {
3324 0 : wscale = opt[2];
3325 0 : wscale = MIN(wscale, TCP_MAX_WINSHIFT);
3326 0 : wscale |= PF_WSCALE_FLAG;
3327 :
3328 0 : opt += opt[1];
3329 : }
3330 :
3331 0 : return (wscale);
3332 0 : }
3333 :
3334 : u_int16_t
3335 0 : pf_get_mss(struct pf_pdesc *pd)
3336 : {
3337 : int olen;
3338 0 : u_int8_t opts[MAX_TCPOPTLEN], *opt;
3339 0 : u_int16_t mss = tcp_mssdflt;
3340 :
3341 0 : olen = (pd->hdr.tcp.th_off << 2) - sizeof(struct tcphdr);
3342 0 : if (olen < TCPOLEN_MAXSEG || !pf_pull_hdr(pd->m,
3343 0 : pd->off + sizeof(struct tcphdr), opts, olen, NULL, NULL, pd->af))
3344 0 : return (0);
3345 :
3346 : opt = opts;
3347 0 : while ((opt = pf_find_tcpopt(opt, opts, olen,
3348 0 : TCPOPT_MAXSEG, TCPOLEN_MAXSEG)) != NULL) {
3349 0 : memcpy(&mss, (opt + 2), 2);
3350 0 : mss = ntohs(mss);
3351 :
3352 0 : opt += opt[1];
3353 : }
3354 0 : return (mss);
3355 0 : }
3356 :
3357 : u_int16_t
3358 0 : pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer)
3359 : {
3360 : struct ifnet *ifp;
3361 : struct sockaddr_in *dst;
3362 : #ifdef INET6
3363 : struct sockaddr_in6 *dst6;
3364 : #endif /* INET6 */
3365 : struct rtentry *rt = NULL;
3366 0 : struct sockaddr_storage ss;
3367 : int hlen;
3368 0 : u_int16_t mss = tcp_mssdflt;
3369 :
3370 0 : memset(&ss, 0, sizeof(ss));
3371 :
3372 0 : switch (af) {
3373 : case AF_INET:
3374 : hlen = sizeof(struct ip);
3375 0 : dst = (struct sockaddr_in *)&ss;
3376 0 : dst->sin_family = AF_INET;
3377 0 : dst->sin_len = sizeof(*dst);
3378 0 : dst->sin_addr = addr->v4;
3379 0 : rt = rtalloc(sintosa(dst), 0, rtableid);
3380 0 : break;
3381 : #ifdef INET6
3382 : case AF_INET6:
3383 : hlen = sizeof(struct ip6_hdr);
3384 0 : dst6 = (struct sockaddr_in6 *)&ss;
3385 0 : dst6->sin6_family = AF_INET6;
3386 0 : dst6->sin6_len = sizeof(*dst6);
3387 0 : dst6->sin6_addr = addr->v6;
3388 0 : rt = rtalloc(sin6tosa(dst6), 0, rtableid);
3389 0 : break;
3390 : #endif /* INET6 */
3391 : }
3392 :
3393 0 : if (rt != NULL && (ifp = if_get(rt->rt_ifidx)) != NULL) {
3394 0 : mss = ifp->if_mtu - hlen - sizeof(struct tcphdr);
3395 0 : mss = max(tcp_mssdflt, mss);
3396 0 : if_put(ifp);
3397 0 : }
3398 0 : rtfree(rt);
3399 0 : mss = min(mss, offer);
3400 0 : mss = max(mss, 64); /* sanity - at least max opt space */
3401 0 : return (mss);
3402 0 : }
3403 :
3404 : static __inline int
3405 0 : pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr, sa_family_t af)
3406 : {
3407 0 : struct pf_rule *r = s->rule.ptr;
3408 0 : struct pf_src_node *sns[PF_SN_MAX];
3409 : int rv;
3410 :
3411 0 : s->rt_kif = NULL;
3412 0 : if (!r->rt)
3413 0 : return (0);
3414 :
3415 0 : memset(sns, 0, sizeof(sns));
3416 0 : switch (af) {
3417 : case AF_INET:
3418 0 : rv = pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, sns,
3419 0 : &r->route, PF_SN_ROUTE);
3420 0 : break;
3421 : #ifdef INET6
3422 : case AF_INET6:
3423 0 : rv = pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, sns,
3424 0 : &r->route, PF_SN_ROUTE);
3425 0 : break;
3426 : #endif /* INET6 */
3427 : default:
3428 : rv = 1;
3429 0 : }
3430 :
3431 0 : if (rv == 0) {
3432 0 : s->rt_kif = r->route.kif;
3433 0 : s->natrule.ptr = r;
3434 0 : }
3435 :
3436 0 : return (rv);
3437 0 : }
3438 :
3439 : u_int32_t
3440 0 : pf_tcp_iss(struct pf_pdesc *pd)
3441 : {
3442 0 : SHA2_CTX ctx;
3443 0 : union {
3444 : uint8_t bytes[SHA512_DIGEST_LENGTH];
3445 : uint32_t words[1];
3446 : } digest;
3447 :
3448 0 : if (pf_tcp_secret_init == 0) {
3449 0 : arc4random_buf(pf_tcp_secret, sizeof(pf_tcp_secret));
3450 0 : SHA512Init(&pf_tcp_secret_ctx);
3451 0 : SHA512Update(&pf_tcp_secret_ctx, pf_tcp_secret,
3452 : sizeof(pf_tcp_secret));
3453 0 : pf_tcp_secret_init = 1;
3454 0 : }
3455 0 : ctx = pf_tcp_secret_ctx;
3456 :
3457 0 : SHA512Update(&ctx, &pd->rdomain, sizeof(pd->rdomain));
3458 0 : SHA512Update(&ctx, &pd->hdr.tcp.th_sport, sizeof(u_short));
3459 0 : SHA512Update(&ctx, &pd->hdr.tcp.th_dport, sizeof(u_short));
3460 0 : switch (pd->af) {
3461 : case AF_INET:
3462 0 : SHA512Update(&ctx, &pd->src->v4, sizeof(struct in_addr));
3463 0 : SHA512Update(&ctx, &pd->dst->v4, sizeof(struct in_addr));
3464 0 : break;
3465 : #ifdef INET6
3466 : case AF_INET6:
3467 0 : SHA512Update(&ctx, &pd->src->v6, sizeof(struct in6_addr));
3468 0 : SHA512Update(&ctx, &pd->dst->v6, sizeof(struct in6_addr));
3469 0 : break;
3470 : #endif /* INET6 */
3471 : }
3472 0 : SHA512Final(digest.bytes, &ctx);
3473 0 : pf_tcp_iss_off += 4096;
3474 0 : return (digest.words[0] + tcp_iss + pf_tcp_iss_off);
3475 0 : }
3476 :
3477 : void
3478 0 : pf_rule_to_actions(struct pf_rule *r, struct pf_rule_actions *a)
3479 : {
3480 0 : if (r->qid)
3481 0 : a->qid = r->qid;
3482 0 : if (r->pqid)
3483 0 : a->pqid = r->pqid;
3484 0 : if (r->rtableid >= 0)
3485 0 : a->rtableid = r->rtableid;
3486 : #if NPFLOG > 0
3487 0 : a->log |= r->log;
3488 : #endif /* NPFLOG > 0 */
3489 0 : if (r->scrub_flags & PFSTATE_SETTOS)
3490 0 : a->set_tos = r->set_tos;
3491 0 : if (r->min_ttl)
3492 0 : a->min_ttl = r->min_ttl;
3493 0 : if (r->max_mss)
3494 0 : a->max_mss = r->max_mss;
3495 0 : a->flags |= (r->scrub_flags & (PFSTATE_NODF|PFSTATE_RANDOMID|
3496 : PFSTATE_SETTOS|PFSTATE_SCRUB_TCP|PFSTATE_SETPRIO));
3497 0 : if (r->scrub_flags & PFSTATE_SETPRIO) {
3498 0 : a->set_prio[0] = r->set_prio[0];
3499 0 : a->set_prio[1] = r->set_prio[1];
3500 0 : }
3501 0 : if (r->rule_flag & PFRULE_SETDELAY)
3502 0 : a->delay = r->delay;
3503 0 : }
3504 :
3505 : #define PF_TEST_ATTRIB(t, a) \
3506 : if (t) { \
3507 : r = a; \
3508 : continue; \
3509 : } else do { \
3510 : } while (0)
3511 :
3512 : enum pf_test_status
3513 0 : pf_match_rule(struct pf_test_ctx *ctx, struct pf_ruleset *ruleset)
3514 : {
3515 : struct pf_rule *r;
3516 : struct pf_rule *save_a;
3517 : struct pf_ruleset *save_aruleset;
3518 :
3519 0 : r = TAILQ_FIRST(ruleset->rules.active.ptr);
3520 0 : while (r != NULL) {
3521 0 : r->evaluations++;
3522 0 : PF_TEST_ATTRIB(
3523 : (pfi_kif_match(r->kif, ctx->pd->kif) == r->ifnot),
3524 : r->skip[PF_SKIP_IFP].ptr);
3525 0 : PF_TEST_ATTRIB((r->direction && r->direction != ctx->pd->dir),
3526 : r->skip[PF_SKIP_DIR].ptr);
3527 0 : PF_TEST_ATTRIB((r->onrdomain >= 0 &&
3528 : (r->onrdomain == ctx->pd->rdomain) == r->ifnot),
3529 : r->skip[PF_SKIP_RDOM].ptr);
3530 0 : PF_TEST_ATTRIB((r->af && r->af != ctx->pd->af),
3531 : r->skip[PF_SKIP_AF].ptr);
3532 0 : PF_TEST_ATTRIB((r->proto && r->proto != ctx->pd->proto),
3533 : r->skip[PF_SKIP_PROTO].ptr);
3534 0 : PF_TEST_ATTRIB((PF_MISMATCHAW(&r->src.addr, &ctx->pd->nsaddr,
3535 : ctx->pd->naf, r->src.neg, ctx->pd->kif,
3536 : ctx->act.rtableid)),
3537 : r->skip[PF_SKIP_SRC_ADDR].ptr);
3538 0 : PF_TEST_ATTRIB((PF_MISMATCHAW(&r->dst.addr, &ctx->pd->ndaddr,
3539 : ctx->pd->af, r->dst.neg, NULL, ctx->act.rtableid)),
3540 : r->skip[PF_SKIP_DST_ADDR].ptr);
3541 :
3542 0 : switch (ctx->pd->virtual_proto) {
3543 : case PF_VPROTO_FRAGMENT:
3544 : /* tcp/udp only. port_op always 0 in other cases */
3545 0 : PF_TEST_ATTRIB((r->src.port_op || r->dst.port_op),
3546 : TAILQ_NEXT(r, entries));
3547 0 : PF_TEST_ATTRIB((ctx->pd->proto == IPPROTO_TCP &&
3548 : r->flagset),
3549 : TAILQ_NEXT(r, entries));
3550 : /* icmp only. type/code always 0 in other cases */
3551 0 : PF_TEST_ATTRIB((r->type || r->code),
3552 : TAILQ_NEXT(r, entries));
3553 : /* tcp/udp only. {uid|gid}.op always 0 in other cases */
3554 0 : PF_TEST_ATTRIB((r->gid.op || r->uid.op),
3555 : TAILQ_NEXT(r, entries));
3556 : break;
3557 :
3558 : case IPPROTO_TCP:
3559 0 : PF_TEST_ATTRIB(((r->flagset & ctx->th->th_flags) !=
3560 : r->flags),
3561 : TAILQ_NEXT(r, entries));
3562 0 : PF_TEST_ATTRIB((r->os_fingerprint != PF_OSFP_ANY &&
3563 : !pf_osfp_match(pf_osfp_fingerprint(ctx->pd),
3564 : r->os_fingerprint)),
3565 : TAILQ_NEXT(r, entries));
3566 : /* FALLTHROUGH */
3567 :
3568 : case IPPROTO_UDP:
3569 : /* tcp/udp only. port_op always 0 in other cases */
3570 0 : PF_TEST_ATTRIB((r->src.port_op &&
3571 : !pf_match_port(r->src.port_op, r->src.port[0],
3572 : r->src.port[1], ctx->pd->nsport)),
3573 : r->skip[PF_SKIP_SRC_PORT].ptr);
3574 0 : PF_TEST_ATTRIB((r->dst.port_op &&
3575 : !pf_match_port(r->dst.port_op, r->dst.port[0],
3576 : r->dst.port[1], ctx->pd->ndport)),
3577 : r->skip[PF_SKIP_DST_PORT].ptr);
3578 : /* tcp/udp only. uid.op always 0 in other cases */
3579 0 : PF_TEST_ATTRIB((r->uid.op && (ctx->pd->lookup.done ||
3580 : (ctx->pd->lookup.done =
3581 : pf_socket_lookup(ctx->pd), 1)) &&
3582 : !pf_match_uid(r->uid.op, r->uid.uid[0],
3583 : r->uid.uid[1], ctx->pd->lookup.uid)),
3584 : TAILQ_NEXT(r, entries));
3585 : /* tcp/udp only. gid.op always 0 in other cases */
3586 0 : PF_TEST_ATTRIB((r->gid.op && (ctx->pd->lookup.done ||
3587 : (ctx->pd->lookup.done =
3588 : pf_socket_lookup(ctx->pd), 1)) &&
3589 : !pf_match_gid(r->gid.op, r->gid.gid[0],
3590 : r->gid.gid[1], ctx->pd->lookup.gid)),
3591 : TAILQ_NEXT(r, entries));
3592 : break;
3593 :
3594 : case IPPROTO_ICMP:
3595 : case IPPROTO_ICMPV6:
3596 : /* icmp only. type always 0 in other cases */
3597 0 : PF_TEST_ATTRIB((r->type &&
3598 : r->type != ctx->icmptype + 1),
3599 : TAILQ_NEXT(r, entries));
3600 : /* icmp only. type always 0 in other cases */
3601 0 : PF_TEST_ATTRIB((r->code &&
3602 : r->code != ctx->icmpcode + 1),
3603 : TAILQ_NEXT(r, entries));
3604 : /* icmp only. don't create states on replies */
3605 0 : PF_TEST_ATTRIB((r->keep_state && !ctx->state_icmp &&
3606 : (r->rule_flag & PFRULE_STATESLOPPY) == 0 &&
3607 : ctx->icmp_dir != PF_IN),
3608 : TAILQ_NEXT(r, entries));
3609 : break;
3610 :
3611 : default:
3612 : break;
3613 : }
3614 :
3615 0 : PF_TEST_ATTRIB((r->rule_flag & PFRULE_FRAGMENT &&
3616 : ctx->pd->virtual_proto != PF_VPROTO_FRAGMENT),
3617 : TAILQ_NEXT(r, entries));
3618 0 : PF_TEST_ATTRIB((r->tos && !(r->tos == ctx->pd->tos)),
3619 : TAILQ_NEXT(r, entries));
3620 0 : PF_TEST_ATTRIB((r->prob &&
3621 : r->prob <= arc4random_uniform(UINT_MAX - 1) + 1),
3622 : TAILQ_NEXT(r, entries));
3623 0 : PF_TEST_ATTRIB((r->match_tag &&
3624 : !pf_match_tag(ctx->pd->m, r, &ctx->tag)),
3625 : TAILQ_NEXT(r, entries));
3626 0 : PF_TEST_ATTRIB((r->rcv_kif && pf_match_rcvif(ctx->pd->m, r) ==
3627 : r->rcvifnot),
3628 : TAILQ_NEXT(r, entries));
3629 0 : PF_TEST_ATTRIB((r->prio &&
3630 : (r->prio == PF_PRIO_ZERO ? 0 : r->prio) !=
3631 : ctx->pd->m->m_pkthdr.pf.prio),
3632 : TAILQ_NEXT(r, entries));
3633 :
3634 : /* must be last! */
3635 0 : if (r->pktrate.limit) {
3636 0 : pf_add_threshold(&r->pktrate);
3637 0 : PF_TEST_ATTRIB((pf_check_threshold(&r->pktrate)),
3638 : TAILQ_NEXT(r, entries));
3639 : }
3640 :
3641 : /* FALLTHROUGH */
3642 0 : if (r->tag)
3643 0 : ctx->tag = r->tag;
3644 0 : if (r->anchor == NULL) {
3645 0 : if (r->action == PF_MATCH) {
3646 0 : if ((ctx->ri = pool_get(&pf_rule_item_pl,
3647 0 : PR_NOWAIT)) == NULL) {
3648 0 : REASON_SET(&ctx->reason, PFRES_MEMORY);
3649 0 : ctx->test_status = PF_TEST_FAIL;
3650 0 : break;
3651 : }
3652 0 : ctx->ri->r = r;
3653 : /* order is irrelevant */
3654 0 : SLIST_INSERT_HEAD(&ctx->rules, ctx->ri, entry);
3655 0 : ctx->ri = NULL;
3656 0 : pf_rule_to_actions(r, &ctx->act);
3657 0 : if (r->rule_flag & PFRULE_AFTO)
3658 0 : ctx->pd->naf = r->naf;
3659 0 : if (pf_get_transaddr(r, ctx->pd, ctx->sns,
3660 0 : &ctx->nr) == -1) {
3661 0 : REASON_SET(&ctx->reason,
3662 : PFRES_TRANSLATE);
3663 0 : ctx->test_status = PF_TEST_FAIL;
3664 0 : break;
3665 : }
3666 : #if NPFLOG > 0
3667 0 : if (r->log) {
3668 0 : REASON_SET(&ctx->reason, PFRES_MATCH);
3669 0 : pflog_packet(ctx->pd, ctx->reason, r,
3670 0 : ctx->a, ruleset, NULL);
3671 0 : }
3672 : #endif /* NPFLOG > 0 */
3673 : } else {
3674 : /*
3675 : * found matching r
3676 : */
3677 0 : *ctx->rm = r;
3678 : /*
3679 : * anchor, with ruleset, where r belongs to
3680 : */
3681 0 : *ctx->am = ctx->a;
3682 : /*
3683 : * ruleset where r belongs to
3684 : */
3685 0 : *ctx->rsm = ruleset;
3686 : /*
3687 : * ruleset, where anchor belongs to.
3688 : */
3689 0 : ctx->arsm = ctx->aruleset;
3690 : }
3691 :
3692 : #if NPFLOG > 0
3693 0 : if (ctx->act.log & PF_LOG_MATCHES)
3694 0 : pf_log_matches(ctx->pd, r, ctx->a, ruleset,
3695 0 : &ctx->rules);
3696 : #endif /* NPFLOG > 0 */
3697 :
3698 0 : if (r->quick) {
3699 0 : ctx->test_status = PF_TEST_QUICK;
3700 0 : break;
3701 : }
3702 : } else {
3703 0 : save_a = ctx->a;
3704 0 : save_aruleset = ctx->aruleset;
3705 0 : ctx->a = r; /* remember anchor */
3706 0 : ctx->aruleset = ruleset; /* and its ruleset */
3707 : /*
3708 : * Note: we don't need to restore if we are not going
3709 : * to continue with ruleset evaluation.
3710 : */
3711 0 : if (pf_step_into_anchor(ctx, r) != PF_TEST_OK)
3712 : break;
3713 0 : ctx->a = save_a;
3714 0 : ctx->aruleset = save_aruleset;
3715 : }
3716 0 : r = TAILQ_NEXT(r, entries);
3717 : }
3718 :
3719 0 : return (ctx->test_status);
3720 : }
3721 :
3722 : int
3723 0 : pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
3724 : struct pf_rule **am, struct pf_ruleset **rsm, u_short *reason)
3725 : {
3726 : struct pf_rule *r = NULL;
3727 : struct pf_rule *a = NULL;
3728 : struct pf_ruleset *ruleset = NULL;
3729 0 : struct pf_state_key *skw = NULL, *sks = NULL;
3730 0 : int rewrite = 0;
3731 0 : u_int16_t virtual_type, virtual_id;
3732 : int action = PF_DROP;
3733 0 : struct pf_test_ctx ctx;
3734 : int rv;
3735 :
3736 0 : memset(&ctx, 0, sizeof(ctx));
3737 0 : ctx.pd = pd;
3738 0 : ctx.rm = rm;
3739 0 : ctx.am = am;
3740 0 : ctx.rsm = rsm;
3741 0 : ctx.th = &pd->hdr.tcp;
3742 0 : ctx.act.rtableid = pd->rdomain;
3743 0 : ctx.tag = -1;
3744 0 : SLIST_INIT(&ctx.rules);
3745 :
3746 0 : if (pd->dir == PF_IN && if_congested()) {
3747 0 : REASON_SET(&ctx.reason, PFRES_CONGEST);
3748 0 : return (PF_DROP);
3749 : }
3750 :
3751 0 : switch (pd->virtual_proto) {
3752 : case IPPROTO_ICMP:
3753 0 : ctx.icmptype = pd->hdr.icmp.icmp_type;
3754 0 : ctx.icmpcode = pd->hdr.icmp.icmp_code;
3755 0 : ctx.state_icmp = pf_icmp_mapping(pd, ctx.icmptype,
3756 0 : &ctx.icmp_dir, &virtual_id, &virtual_type);
3757 0 : if (ctx.icmp_dir == PF_IN) {
3758 0 : pd->osport = pd->nsport = virtual_id;
3759 0 : pd->odport = pd->ndport = virtual_type;
3760 0 : } else {
3761 0 : pd->osport = pd->nsport = virtual_type;
3762 0 : pd->odport = pd->ndport = virtual_id;
3763 : }
3764 : break;
3765 : #ifdef INET6
3766 : case IPPROTO_ICMPV6:
3767 0 : ctx.icmptype = pd->hdr.icmp6.icmp6_type;
3768 0 : ctx.icmpcode = pd->hdr.icmp6.icmp6_code;
3769 0 : ctx.state_icmp = pf_icmp_mapping(pd, ctx.icmptype,
3770 0 : &ctx.icmp_dir, &virtual_id, &virtual_type);
3771 0 : if (ctx.icmp_dir == PF_IN) {
3772 0 : pd->osport = pd->nsport = virtual_id;
3773 0 : pd->odport = pd->ndport = virtual_type;
3774 0 : } else {
3775 0 : pd->osport = pd->nsport = virtual_type;
3776 0 : pd->odport = pd->ndport = virtual_id;
3777 : }
3778 : break;
3779 : #endif /* INET6 */
3780 : }
3781 :
3782 : ruleset = &pf_main_ruleset;
3783 0 : rv = pf_match_rule(&ctx, ruleset);
3784 0 : if (rv == PF_TEST_FAIL) {
3785 : /*
3786 : * Reason has been set in pf_match_rule() already.
3787 : */
3788 : goto cleanup;
3789 : }
3790 :
3791 0 : r = *ctx.rm; /* matching rule */
3792 0 : a = *ctx.am; /* rule that defines an anchor containing 'r' */
3793 0 : ruleset = *ctx.rsm;/* ruleset of the anchor defined by the rule 'a' */
3794 0 : ctx.aruleset = ctx.arsm;/* ruleset of the 'a' rule itself */
3795 :
3796 : /* apply actions for last matching pass/block rule */
3797 0 : pf_rule_to_actions(r, &ctx.act);
3798 0 : if (r->rule_flag & PFRULE_AFTO)
3799 0 : pd->naf = r->naf;
3800 0 : if (pf_get_transaddr(r, pd, ctx.sns, &ctx.nr) == -1) {
3801 0 : REASON_SET(&ctx.reason, PFRES_TRANSLATE);
3802 0 : goto cleanup;
3803 : }
3804 0 : REASON_SET(&ctx.reason, PFRES_MATCH);
3805 :
3806 : #if NPFLOG > 0
3807 0 : if (r->log)
3808 0 : pflog_packet(pd, ctx.reason, r, a, ruleset, NULL);
3809 0 : if (ctx.act.log & PF_LOG_MATCHES)
3810 0 : pf_log_matches(pd, r, a, ruleset, &ctx.rules);
3811 : #endif /* NPFLOG > 0 */
3812 :
3813 0 : if (pd->virtual_proto != PF_VPROTO_FRAGMENT &&
3814 0 : (r->action == PF_DROP) &&
3815 0 : ((r->rule_flag & PFRULE_RETURNRST) ||
3816 0 : (r->rule_flag & PFRULE_RETURNICMP) ||
3817 0 : (r->rule_flag & PFRULE_RETURN))) {
3818 0 : if (pd->proto == IPPROTO_TCP &&
3819 0 : ((r->rule_flag & PFRULE_RETURNRST) ||
3820 0 : (r->rule_flag & PFRULE_RETURN)) &&
3821 0 : !(ctx.th->th_flags & TH_RST)) {
3822 : u_int32_t ack =
3823 0 : ntohl(ctx.th->th_seq) + pd->p_len;
3824 :
3825 0 : if (pf_check_tcp_cksum(pd->m, pd->off,
3826 0 : pd->tot_len - pd->off, pd->af))
3827 0 : REASON_SET(&ctx.reason, PFRES_PROTCKSUM);
3828 : else {
3829 0 : if (ctx.th->th_flags & TH_SYN)
3830 0 : ack++;
3831 0 : if (ctx.th->th_flags & TH_FIN)
3832 0 : ack++;
3833 0 : pf_send_tcp(r, pd->af, pd->dst,
3834 0 : pd->src, ctx.th->th_dport,
3835 0 : ctx.th->th_sport, ntohl(ctx.th->th_ack),
3836 0 : ack, TH_RST|TH_ACK, 0, 0, r->return_ttl,
3837 0 : 1, 0, pd->rdomain);
3838 : }
3839 0 : } else if ((pd->proto != IPPROTO_ICMP ||
3840 0 : ICMP_INFOTYPE(ctx.icmptype)) && pd->af == AF_INET &&
3841 0 : r->return_icmp)
3842 0 : pf_send_icmp(pd->m, r->return_icmp >> 8,
3843 0 : r->return_icmp & 255, 0, pd->af, r, pd->rdomain);
3844 0 : else if ((pd->proto != IPPROTO_ICMPV6 ||
3845 0 : (ctx.icmptype >= ICMP6_ECHO_REQUEST &&
3846 0 : ctx.icmptype != ND_REDIRECT)) && pd->af == AF_INET6 &&
3847 0 : r->return_icmp6)
3848 0 : pf_send_icmp(pd->m, r->return_icmp6 >> 8,
3849 0 : r->return_icmp6 & 255, 0, pd->af, r, pd->rdomain);
3850 : }
3851 :
3852 0 : if (r->action == PF_DROP)
3853 : goto cleanup;
3854 :
3855 0 : pf_tag_packet(pd->m, ctx.tag, ctx.act.rtableid);
3856 0 : if (ctx.act.rtableid >= 0 &&
3857 0 : rtable_l2(ctx.act.rtableid) != pd->rdomain)
3858 0 : pd->destchg = 1;
3859 :
3860 0 : if (r->action == PF_PASS && pd->badopts && ! r->allow_opts) {
3861 0 : REASON_SET(&ctx.reason, PFRES_IPOPTIONS);
3862 : #if NPFLOG > 0
3863 0 : pd->pflog |= PF_LOG_FORCE;
3864 : #endif /* NPFLOG > 0 */
3865 0 : DPFPRINTF(LOG_NOTICE, "dropping packet with "
3866 : "ip/ipv6 options in pf_test_rule()");
3867 : goto cleanup;
3868 : }
3869 :
3870 : action = PF_PASS;
3871 :
3872 0 : if (pd->virtual_proto != PF_VPROTO_FRAGMENT
3873 0 : && !ctx.state_icmp && r->keep_state) {
3874 :
3875 0 : if (r->rule_flag & PFRULE_SRCTRACK &&
3876 0 : pf_insert_src_node(&ctx.sns[PF_SN_NONE], r, PF_SN_NONE,
3877 0 : pd->af, pd->src, NULL) != 0) {
3878 0 : REASON_SET(&ctx.reason, PFRES_SRCLIMIT);
3879 0 : goto cleanup;
3880 : }
3881 :
3882 0 : if (r->max_states && (r->states_cur >= r->max_states)) {
3883 0 : pf_status.lcounters[LCNT_STATES]++;
3884 0 : REASON_SET(&ctx.reason, PFRES_MAXSTATES);
3885 0 : goto cleanup;
3886 : }
3887 :
3888 0 : action = pf_create_state(pd, r, a, ctx.nr, &skw, &sks,
3889 0 : &rewrite, sm, ctx.tag, &ctx.rules, &ctx.act, ctx.sns);
3890 :
3891 0 : if (action != PF_PASS)
3892 : goto cleanup;
3893 0 : if (sks != skw) {
3894 : struct pf_state_key *sk;
3895 :
3896 0 : if (pd->dir == PF_IN)
3897 0 : sk = sks;
3898 : else
3899 : sk = skw;
3900 0 : rewrite += pf_translate(pd,
3901 0 : &sk->addr[pd->af == pd->naf ? pd->sidx : pd->didx],
3902 0 : sk->port[pd->af == pd->naf ? pd->sidx : pd->didx],
3903 0 : &sk->addr[pd->af == pd->naf ? pd->didx : pd->sidx],
3904 0 : sk->port[pd->af == pd->naf ? pd->didx : pd->sidx],
3905 0 : virtual_type, ctx.icmp_dir);
3906 0 : }
3907 :
3908 : #ifdef INET6
3909 0 : if (rewrite && skw->af != sks->af)
3910 0 : action = PF_AFRT;
3911 : #endif /* INET6 */
3912 :
3913 : } else {
3914 0 : while ((ctx.ri = SLIST_FIRST(&ctx.rules))) {
3915 0 : SLIST_REMOVE_HEAD(&ctx.rules, entry);
3916 0 : pool_put(&pf_rule_item_pl, ctx.ri);
3917 : }
3918 : }
3919 :
3920 : /* copy back packet headers if needed */
3921 0 : if (rewrite && pd->hdrlen) {
3922 0 : m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
3923 0 : }
3924 :
3925 : #if NPFSYNC > 0
3926 0 : if (*sm != NULL && !ISSET((*sm)->state_flags, PFSTATE_NOSYNC) &&
3927 0 : pd->dir == PF_OUT && pfsync_up()) {
3928 : /*
3929 : * We want the state created, but we dont
3930 : * want to send this in case a partner
3931 : * firewall has to know about it to allow
3932 : * replies through it.
3933 : */
3934 0 : if (pfsync_defer(*sm, pd->m))
3935 0 : return (PF_DEFER);
3936 : }
3937 : #endif /* NPFSYNC > 0 */
3938 :
3939 0 : if (r->rule_flag & PFRULE_ONCE) {
3940 0 : r->rule_flag |= PFRULE_EXPIRED;
3941 0 : r->exptime = time_second;
3942 0 : SLIST_INSERT_HEAD(&pf_rule_gcl, r, gcle);
3943 0 : }
3944 :
3945 0 : return (action);
3946 :
3947 : cleanup:
3948 0 : while ((ctx.ri = SLIST_FIRST(&ctx.rules))) {
3949 0 : SLIST_REMOVE_HEAD(&ctx.rules, entry);
3950 0 : pool_put(&pf_rule_item_pl, ctx.ri);
3951 : }
3952 :
3953 0 : return (action);
3954 0 : }
3955 :
3956 : static __inline int
3957 0 : pf_create_state(struct pf_pdesc *pd, struct pf_rule *r, struct pf_rule *a,
3958 : struct pf_rule *nr, struct pf_state_key **skw, struct pf_state_key **sks,
3959 : int *rewrite, struct pf_state **sm, int tag, struct pf_rule_slist *rules,
3960 : struct pf_rule_actions *act, struct pf_src_node *sns[PF_SN_MAX])
3961 : {
3962 : struct pf_state *s = NULL;
3963 0 : struct tcphdr *th = &pd->hdr.tcp;
3964 0 : u_int16_t mss = tcp_mssdflt;
3965 0 : u_short reason;
3966 : u_int i;
3967 :
3968 0 : s = pool_get(&pf_state_pl, PR_NOWAIT | PR_ZERO);
3969 0 : if (s == NULL) {
3970 0 : REASON_SET(&reason, PFRES_MEMORY);
3971 0 : goto csfailed;
3972 : }
3973 0 : s->rule.ptr = r;
3974 0 : s->anchor.ptr = a;
3975 0 : s->natrule.ptr = nr;
3976 0 : if (r->allow_opts)
3977 0 : s->state_flags |= PFSTATE_ALLOWOPTS;
3978 0 : if (r->rule_flag & PFRULE_STATESLOPPY)
3979 0 : s->state_flags |= PFSTATE_SLOPPY;
3980 0 : if (r->rule_flag & PFRULE_PFLOW)
3981 0 : s->state_flags |= PFSTATE_PFLOW;
3982 : #if NPFLOG > 0
3983 0 : s->log = act->log & PF_LOG_ALL;
3984 : #endif /* NPFLOG > 0 */
3985 0 : s->qid = act->qid;
3986 0 : s->pqid = act->pqid;
3987 0 : s->rtableid[pd->didx] = act->rtableid;
3988 0 : s->rtableid[pd->sidx] = -1; /* return traffic is routed normally */
3989 0 : s->min_ttl = act->min_ttl;
3990 0 : s->set_tos = act->set_tos;
3991 0 : s->max_mss = act->max_mss;
3992 0 : s->state_flags |= act->flags;
3993 : #if NPFSYNC > 0
3994 0 : s->sync_state = PFSYNC_S_NONE;
3995 : #endif /* NPFSYNC > 0 */
3996 0 : s->set_prio[0] = act->set_prio[0];
3997 0 : s->set_prio[1] = act->set_prio[1];
3998 0 : s->delay = act->delay;
3999 0 : SLIST_INIT(&s->src_nodes);
4000 : /*
4001 : * must initialize refcnt, before pf_state_insert() gets called.
4002 : * pf_state_inserts() grabs reference for pfsync!
4003 : */
4004 0 : refcnt_init(&s->refcnt);
4005 :
4006 0 : switch (pd->proto) {
4007 : case IPPROTO_TCP:
4008 0 : s->src.seqlo = ntohl(th->th_seq);
4009 0 : s->src.seqhi = s->src.seqlo + pd->p_len + 1;
4010 0 : if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
4011 0 : r->keep_state == PF_STATE_MODULATE) {
4012 : /* Generate sequence number modulator */
4013 0 : if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) ==
4014 : 0)
4015 0 : s->src.seqdiff = 1;
4016 0 : pf_patch_32(pd,
4017 0 : &th->th_seq, htonl(s->src.seqlo + s->src.seqdiff));
4018 0 : *rewrite = 1;
4019 0 : } else
4020 0 : s->src.seqdiff = 0;
4021 0 : if (th->th_flags & TH_SYN) {
4022 0 : s->src.seqhi++;
4023 0 : s->src.wscale = pf_get_wscale(pd);
4024 0 : }
4025 0 : s->src.max_win = MAX(ntohs(th->th_win), 1);
4026 0 : if (s->src.wscale & PF_WSCALE_MASK) {
4027 : /* Remove scale factor from initial window */
4028 0 : int win = s->src.max_win;
4029 0 : win += 1 << (s->src.wscale & PF_WSCALE_MASK);
4030 0 : s->src.max_win = (win - 1) >>
4031 : (s->src.wscale & PF_WSCALE_MASK);
4032 0 : }
4033 0 : if (th->th_flags & TH_FIN)
4034 0 : s->src.seqhi++;
4035 0 : s->dst.seqhi = 1;
4036 0 : s->dst.max_win = 1;
4037 0 : pf_set_protostate(s, PF_PEER_SRC, TCPS_SYN_SENT);
4038 0 : pf_set_protostate(s, PF_PEER_DST, TCPS_CLOSED);
4039 0 : s->timeout = PFTM_TCP_FIRST_PACKET;
4040 0 : pf_status.states_halfopen++;
4041 0 : break;
4042 : case IPPROTO_UDP:
4043 0 : pf_set_protostate(s, PF_PEER_SRC, PFUDPS_SINGLE);
4044 0 : pf_set_protostate(s, PF_PEER_DST, PFUDPS_NO_TRAFFIC);
4045 0 : s->timeout = PFTM_UDP_FIRST_PACKET;
4046 0 : break;
4047 : case IPPROTO_ICMP:
4048 : #ifdef INET6
4049 : case IPPROTO_ICMPV6:
4050 : #endif /* INET6 */
4051 0 : s->timeout = PFTM_ICMP_FIRST_PACKET;
4052 0 : break;
4053 : default:
4054 0 : pf_set_protostate(s, PF_PEER_SRC, PFOTHERS_SINGLE);
4055 0 : pf_set_protostate(s, PF_PEER_DST, PFOTHERS_NO_TRAFFIC);
4056 0 : s->timeout = PFTM_OTHER_FIRST_PACKET;
4057 0 : }
4058 :
4059 0 : s->creation = time_uptime;
4060 0 : s->expire = time_uptime;
4061 :
4062 0 : if (pd->proto == IPPROTO_TCP) {
4063 0 : if (s->state_flags & PFSTATE_SCRUB_TCP &&
4064 0 : pf_normalize_tcp_init(pd, &s->src)) {
4065 0 : REASON_SET(&reason, PFRES_MEMORY);
4066 0 : goto csfailed;
4067 : }
4068 0 : if (s->state_flags & PFSTATE_SCRUB_TCP && s->src.scrub &&
4069 0 : pf_normalize_tcp_stateful(pd, &reason, s, &s->src, &s->dst,
4070 : rewrite)) {
4071 : /* This really shouldn't happen!!! */
4072 0 : DPFPRINTF(LOG_ERR,
4073 : "%s: tcp normalize failed on first pkt", __func__);
4074 : goto csfailed;
4075 : }
4076 : }
4077 0 : s->direction = pd->dir;
4078 :
4079 0 : if (pf_state_key_setup(pd, skw, sks, act->rtableid)) {
4080 0 : REASON_SET(&reason, PFRES_MEMORY);
4081 0 : goto csfailed;
4082 : }
4083 :
4084 0 : for (i = 0; i < PF_SN_MAX; i++)
4085 0 : if (sns[i] != NULL) {
4086 : struct pf_sn_item *sni;
4087 :
4088 0 : sni = pool_get(&pf_sn_item_pl, PR_NOWAIT);
4089 0 : if (sni == NULL) {
4090 0 : REASON_SET(&reason, PFRES_MEMORY);
4091 0 : goto csfailed;
4092 : }
4093 0 : sni->sn = sns[i];
4094 0 : SLIST_INSERT_HEAD(&s->src_nodes, sni, next);
4095 0 : sni->sn->states++;
4096 0 : }
4097 :
4098 0 : if (pf_set_rt_ifp(s, pd->src, (*skw)->af) != 0) {
4099 0 : REASON_SET(&reason, PFRES_NOROUTE);
4100 0 : goto csfailed;
4101 : }
4102 :
4103 0 : if (pf_state_insert(BOUND_IFACE(r, pd->kif), skw, sks, s)) {
4104 0 : pf_detach_state(s);
4105 0 : *sks = *skw = NULL;
4106 0 : REASON_SET(&reason, PFRES_STATEINS);
4107 0 : goto csfailed;
4108 : } else
4109 0 : *sm = s;
4110 :
4111 : /*
4112 : * Make state responsible for rules it binds here.
4113 : */
4114 0 : memcpy(&s->match_rules, rules, sizeof(s->match_rules));
4115 0 : memset(rules, 0, sizeof(*rules));
4116 0 : STATE_INC_COUNTERS(s);
4117 :
4118 0 : if (tag > 0) {
4119 0 : pf_tag_ref(tag);
4120 0 : s->tag = tag;
4121 0 : }
4122 0 : if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) ==
4123 0 : TH_SYN && r->keep_state == PF_STATE_SYNPROXY) {
4124 0 : int rtid = pd->rdomain;
4125 0 : if (act->rtableid >= 0)
4126 0 : rtid = act->rtableid;
4127 0 : pf_set_protostate(s, PF_PEER_SRC, PF_TCPS_PROXY_SRC);
4128 0 : s->src.seqhi = arc4random();
4129 : /* Find mss option */
4130 0 : mss = pf_get_mss(pd);
4131 0 : mss = pf_calc_mss(pd->src, pd->af, rtid, mss);
4132 0 : mss = pf_calc_mss(pd->dst, pd->af, rtid, mss);
4133 0 : s->src.mss = mss;
4134 0 : pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport,
4135 0 : th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
4136 0 : TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, pd->rdomain);
4137 0 : REASON_SET(&reason, PFRES_SYNPROXY);
4138 : return (PF_SYNPROXY_DROP);
4139 : }
4140 :
4141 0 : return (PF_PASS);
4142 :
4143 : csfailed:
4144 0 : if (s) {
4145 0 : pf_normalize_tcp_cleanup(s); /* safe even w/o init */
4146 0 : pf_src_tree_remove_state(s);
4147 0 : pool_put(&pf_state_pl, s);
4148 0 : }
4149 :
4150 0 : for (i = 0; i < PF_SN_MAX; i++)
4151 0 : if (sns[i] != NULL)
4152 0 : pf_remove_src_node(sns[i]);
4153 :
4154 0 : return (PF_DROP);
4155 0 : }
4156 :
4157 : int
4158 0 : pf_translate(struct pf_pdesc *pd, struct pf_addr *saddr, u_int16_t sport,
4159 : struct pf_addr *daddr, u_int16_t dport, u_int16_t virtual_type,
4160 : int icmp_dir)
4161 : {
4162 : /*
4163 : * when called from bpf_mtap_pflog, there are extra constraints:
4164 : * -mbuf is faked, m_data is the bpf buffer
4165 : * -pd is not fully set up
4166 : */
4167 : int rewrite = 0;
4168 0 : int afto = pd->af != pd->naf;
4169 :
4170 0 : if (afto || PF_ANEQ(daddr, pd->dst, pd->af))
4171 0 : pd->destchg = 1;
4172 :
4173 0 : switch (pd->proto) {
4174 : case IPPROTO_TCP: /* FALLTHROUGH */
4175 : case IPPROTO_UDP:
4176 0 : rewrite += pf_patch_16(pd, pd->sport, sport);
4177 0 : rewrite += pf_patch_16(pd, pd->dport, dport);
4178 0 : break;
4179 :
4180 : case IPPROTO_ICMP:
4181 : /* pf_translate() is also used when logging invalid packets */
4182 0 : if (pd->af != AF_INET)
4183 0 : return (0);
4184 :
4185 0 : if (afto) {
4186 : #ifdef INET6
4187 0 : if (pf_translate_icmp_af(pd, AF_INET6, &pd->hdr.icmp))
4188 0 : return (0);
4189 0 : pd->proto = IPPROTO_ICMPV6;
4190 : rewrite = 1;
4191 : #endif /* INET6 */
4192 0 : }
4193 0 : if (virtual_type == htons(ICMP_ECHO)) {
4194 0 : u_int16_t icmpid = (icmp_dir == PF_IN) ? sport : dport;
4195 0 : rewrite += pf_patch_16(pd,
4196 0 : &pd->hdr.icmp.icmp_id, icmpid);
4197 0 : }
4198 : break;
4199 :
4200 : #ifdef INET6
4201 : case IPPROTO_ICMPV6:
4202 : /* pf_translate() is also used when logging invalid packets */
4203 0 : if (pd->af != AF_INET6)
4204 0 : return (0);
4205 :
4206 0 : if (afto) {
4207 0 : if (pf_translate_icmp_af(pd, AF_INET, &pd->hdr.icmp6))
4208 0 : return (0);
4209 0 : pd->proto = IPPROTO_ICMP;
4210 : rewrite = 1;
4211 0 : }
4212 0 : if (virtual_type == htons(ICMP6_ECHO_REQUEST)) {
4213 0 : u_int16_t icmpid = (icmp_dir == PF_IN) ? sport : dport;
4214 0 : rewrite += pf_patch_16(pd,
4215 0 : &pd->hdr.icmp6.icmp6_id, icmpid);
4216 0 : }
4217 : break;
4218 : #endif /* INET6 */
4219 : }
4220 :
4221 0 : if (!afto) {
4222 0 : rewrite += pf_translate_a(pd, pd->src, saddr);
4223 0 : rewrite += pf_translate_a(pd, pd->dst, daddr);
4224 0 : }
4225 :
4226 0 : return (rewrite);
4227 0 : }
4228 :
4229 : int
4230 0 : pf_tcp_track_full(struct pf_pdesc *pd, struct pf_state **state, u_short *reason,
4231 : int *copyback, int reverse)
4232 : {
4233 0 : struct tcphdr *th = &pd->hdr.tcp;
4234 : struct pf_state_peer *src, *dst;
4235 0 : u_int16_t win = ntohs(th->th_win);
4236 : u_int32_t ack, end, data_end, seq, orig_seq;
4237 : u_int8_t sws, dws, psrc, pdst;
4238 : int ackskew;
4239 :
4240 0 : if ((pd->dir == (*state)->direction && !reverse) ||
4241 0 : (pd->dir != (*state)->direction && reverse)) {
4242 0 : src = &(*state)->src;
4243 0 : dst = &(*state)->dst;
4244 : psrc = PF_PEER_SRC;
4245 : pdst = PF_PEER_DST;
4246 0 : } else {
4247 0 : src = &(*state)->dst;
4248 0 : dst = &(*state)->src;
4249 : psrc = PF_PEER_DST;
4250 : pdst = PF_PEER_SRC;
4251 : }
4252 :
4253 0 : if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
4254 0 : sws = src->wscale & PF_WSCALE_MASK;
4255 0 : dws = dst->wscale & PF_WSCALE_MASK;
4256 0 : } else
4257 : sws = dws = 0;
4258 :
4259 : /*
4260 : * Sequence tracking algorithm from Guido van Rooij's paper:
4261 : * http://www.madison-gurkha.com/publications/tcp_filtering/
4262 : * tcp_filtering.ps
4263 : */
4264 :
4265 0 : orig_seq = seq = ntohl(th->th_seq);
4266 0 : if (src->seqlo == 0) {
4267 : /* First packet from this end. Set its state */
4268 :
4269 0 : if (((*state)->state_flags & PFSTATE_SCRUB_TCP || dst->scrub) &&
4270 0 : src->scrub == NULL) {
4271 0 : if (pf_normalize_tcp_init(pd, src)) {
4272 0 : REASON_SET(reason, PFRES_MEMORY);
4273 0 : return (PF_DROP);
4274 : }
4275 : }
4276 :
4277 : /* Deferred generation of sequence number modulator */
4278 0 : if (dst->seqdiff && !src->seqdiff) {
4279 : /* use random iss for the TCP server */
4280 0 : while ((src->seqdiff = arc4random() - seq) == 0)
4281 0 : continue;
4282 0 : ack = ntohl(th->th_ack) - dst->seqdiff;
4283 0 : pf_patch_32(pd, &th->th_seq, htonl(seq + src->seqdiff));
4284 0 : pf_patch_32(pd, &th->th_ack, htonl(ack));
4285 0 : *copyback = 1;
4286 0 : } else {
4287 0 : ack = ntohl(th->th_ack);
4288 : }
4289 :
4290 0 : end = seq + pd->p_len;
4291 0 : if (th->th_flags & TH_SYN) {
4292 0 : end++;
4293 0 : if (dst->wscale & PF_WSCALE_FLAG) {
4294 0 : src->wscale = pf_get_wscale(pd);
4295 0 : if (src->wscale & PF_WSCALE_FLAG) {
4296 : /* Remove scale factor from initial
4297 : * window */
4298 0 : sws = src->wscale & PF_WSCALE_MASK;
4299 0 : win = ((u_int32_t)win + (1 << sws) - 1)
4300 0 : >> sws;
4301 0 : dws = dst->wscale & PF_WSCALE_MASK;
4302 0 : } else {
4303 : /* fixup other window */
4304 0 : dst->max_win = MIN(TCP_MAXWIN,
4305 : (u_int32_t)dst->max_win <<
4306 : (dst->wscale & PF_WSCALE_MASK));
4307 : /* in case of a retrans SYN|ACK */
4308 0 : dst->wscale = 0;
4309 : }
4310 : }
4311 : }
4312 : data_end = end;
4313 0 : if (th->th_flags & TH_FIN)
4314 0 : end++;
4315 :
4316 0 : src->seqlo = seq;
4317 0 : if (src->state < TCPS_SYN_SENT)
4318 0 : pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
4319 :
4320 : /*
4321 : * May need to slide the window (seqhi may have been set by
4322 : * the crappy stack check or if we picked up the connection
4323 : * after establishment)
4324 : */
4325 0 : if (src->seqhi == 1 ||
4326 0 : SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
4327 0 : src->seqhi = end + MAX(1, dst->max_win << dws);
4328 0 : if (win > src->max_win)
4329 0 : src->max_win = win;
4330 :
4331 : } else {
4332 0 : ack = ntohl(th->th_ack) - dst->seqdiff;
4333 0 : if (src->seqdiff) {
4334 : /* Modulate sequence numbers */
4335 0 : pf_patch_32(pd, &th->th_seq, htonl(seq + src->seqdiff));
4336 0 : pf_patch_32(pd, &th->th_ack, htonl(ack));
4337 0 : *copyback = 1;
4338 0 : }
4339 0 : end = seq + pd->p_len;
4340 0 : if (th->th_flags & TH_SYN)
4341 0 : end++;
4342 : data_end = end;
4343 0 : if (th->th_flags & TH_FIN)
4344 0 : end++;
4345 : }
4346 :
4347 0 : if ((th->th_flags & TH_ACK) == 0) {
4348 : /* Let it pass through the ack skew check */
4349 0 : ack = dst->seqlo;
4350 0 : } else if ((ack == 0 &&
4351 0 : (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
4352 : /* broken tcp stacks do not set ack */
4353 0 : (dst->state < TCPS_SYN_SENT)) {
4354 : /*
4355 : * Many stacks (ours included) will set the ACK number in an
4356 : * FIN|ACK if the SYN times out -- no sequence to ACK.
4357 : */
4358 0 : ack = dst->seqlo;
4359 0 : }
4360 :
4361 0 : if (seq == end) {
4362 : /* Ease sequencing restrictions on no data packets */
4363 0 : seq = src->seqlo;
4364 : data_end = end = seq;
4365 0 : }
4366 :
4367 0 : ackskew = dst->seqlo - ack;
4368 :
4369 :
4370 : /*
4371 : * Need to demodulate the sequence numbers in any TCP SACK options
4372 : * (Selective ACK). We could optionally validate the SACK values
4373 : * against the current ACK window, either forwards or backwards, but
4374 : * I'm not confident that SACK has been implemented properly
4375 : * everywhere. It wouldn't surprise me if several stacks accidently
4376 : * SACK too far backwards of previously ACKed data. There really aren't
4377 : * any security implications of bad SACKing unless the target stack
4378 : * doesn't validate the option length correctly. Someone trying to
4379 : * spoof into a TCP connection won't bother blindly sending SACK
4380 : * options anyway.
4381 : */
4382 0 : if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
4383 0 : if (pf_modulate_sack(pd, dst))
4384 0 : *copyback = 1;
4385 : }
4386 :
4387 :
4388 : #define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
4389 0 : if (SEQ_GEQ(src->seqhi, data_end) &&
4390 : /* Last octet inside other's window space */
4391 0 : SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
4392 : /* Retrans: not more than one window back */
4393 0 : (ackskew >= -MAXACKWINDOW) &&
4394 : /* Acking not more than one reassembled fragment backwards */
4395 0 : (ackskew <= (MAXACKWINDOW << sws)) &&
4396 : /* Acking not more than one window forward */
4397 0 : ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
4398 0 : (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo))) {
4399 : /* Require an exact/+1 sequence match on resets when possible */
4400 :
4401 0 : if (dst->scrub || src->scrub) {
4402 0 : if (pf_normalize_tcp_stateful(pd, reason, *state, src,
4403 : dst, copyback))
4404 0 : return (PF_DROP);
4405 : }
4406 :
4407 : /* update max window */
4408 0 : if (src->max_win < win)
4409 0 : src->max_win = win;
4410 : /* synchronize sequencing */
4411 0 : if (SEQ_GT(end, src->seqlo))
4412 0 : src->seqlo = end;
4413 : /* slide the window of what the other end can send */
4414 0 : if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4415 0 : dst->seqhi = ack + MAX((win << sws), 1);
4416 :
4417 : /* update states */
4418 0 : if (th->th_flags & TH_SYN)
4419 0 : if (src->state < TCPS_SYN_SENT)
4420 0 : pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
4421 0 : if (th->th_flags & TH_FIN)
4422 0 : if (src->state < TCPS_CLOSING)
4423 0 : pf_set_protostate(*state, psrc, TCPS_CLOSING);
4424 0 : if (th->th_flags & TH_ACK) {
4425 0 : if (dst->state == TCPS_SYN_SENT) {
4426 0 : pf_set_protostate(*state, pdst,
4427 : TCPS_ESTABLISHED);
4428 0 : if (src->state == TCPS_ESTABLISHED &&
4429 0 : !SLIST_EMPTY(&(*state)->src_nodes) &&
4430 0 : pf_src_connlimit(state)) {
4431 0 : REASON_SET(reason, PFRES_SRCLIMIT);
4432 0 : return (PF_DROP);
4433 : }
4434 0 : } else if (dst->state == TCPS_CLOSING)
4435 0 : pf_set_protostate(*state, pdst,
4436 : TCPS_FIN_WAIT_2);
4437 : }
4438 0 : if (th->th_flags & TH_RST)
4439 0 : pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
4440 :
4441 : /* update expire time */
4442 0 : (*state)->expire = time_uptime;
4443 0 : if (src->state >= TCPS_FIN_WAIT_2 &&
4444 0 : dst->state >= TCPS_FIN_WAIT_2)
4445 0 : (*state)->timeout = PFTM_TCP_CLOSED;
4446 0 : else if (src->state >= TCPS_CLOSING &&
4447 0 : dst->state >= TCPS_CLOSING)
4448 0 : (*state)->timeout = PFTM_TCP_FIN_WAIT;
4449 0 : else if (src->state < TCPS_ESTABLISHED ||
4450 0 : dst->state < TCPS_ESTABLISHED)
4451 0 : (*state)->timeout = PFTM_TCP_OPENING;
4452 0 : else if (src->state >= TCPS_CLOSING ||
4453 0 : dst->state >= TCPS_CLOSING)
4454 0 : (*state)->timeout = PFTM_TCP_CLOSING;
4455 : else
4456 0 : (*state)->timeout = PFTM_TCP_ESTABLISHED;
4457 :
4458 : /* Fall through to PASS packet */
4459 0 : } else if ((dst->state < TCPS_SYN_SENT ||
4460 0 : dst->state >= TCPS_FIN_WAIT_2 ||
4461 0 : src->state >= TCPS_FIN_WAIT_2) &&
4462 0 : SEQ_GEQ(src->seqhi + MAXACKWINDOW, data_end) &&
4463 : /* Within a window forward of the originating packet */
4464 0 : SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
4465 : /* Within a window backward of the originating packet */
4466 :
4467 : /*
4468 : * This currently handles three situations:
4469 : * 1) Stupid stacks will shotgun SYNs before their peer
4470 : * replies.
4471 : * 2) When PF catches an already established stream (the
4472 : * firewall rebooted, the state table was flushed, routes
4473 : * changed...)
4474 : * 3) Packets get funky immediately after the connection
4475 : * closes (this should catch Solaris spurious ACK|FINs
4476 : * that web servers like to spew after a close)
4477 : *
4478 : * This must be a little more careful than the above code
4479 : * since packet floods will also be caught here. We don't
4480 : * update the TTL here to mitigate the damage of a packet
4481 : * flood and so the same code can handle awkward establishment
4482 : * and a loosened connection close.
4483 : * In the establishment case, a correct peer response will
4484 : * validate the connection, go through the normal state code
4485 : * and keep updating the state TTL.
4486 : */
4487 :
4488 0 : if (pf_status.debug >= LOG_NOTICE) {
4489 0 : log(LOG_NOTICE, "pf: loose state match: ");
4490 0 : pf_print_state(*state);
4491 0 : pf_print_flags(th->th_flags);
4492 0 : addlog(" seq=%u (%u) ack=%u len=%u ackskew=%d "
4493 : "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack,
4494 0 : pd->p_len, ackskew, (*state)->packets[0],
4495 0 : (*state)->packets[1],
4496 0 : pd->dir == PF_IN ? "in" : "out",
4497 0 : pd->dir == (*state)->direction ? "fwd" : "rev");
4498 0 : }
4499 :
4500 0 : if (dst->scrub || src->scrub) {
4501 0 : if (pf_normalize_tcp_stateful(pd, reason, *state, src,
4502 : dst, copyback))
4503 0 : return (PF_DROP);
4504 : }
4505 :
4506 : /* update max window */
4507 0 : if (src->max_win < win)
4508 0 : src->max_win = win;
4509 : /* synchronize sequencing */
4510 0 : if (SEQ_GT(end, src->seqlo))
4511 0 : src->seqlo = end;
4512 : /* slide the window of what the other end can send */
4513 0 : if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
4514 0 : dst->seqhi = ack + MAX((win << sws), 1);
4515 :
4516 : /*
4517 : * Cannot set dst->seqhi here since this could be a shotgunned
4518 : * SYN and not an already established connection.
4519 : */
4520 0 : if (th->th_flags & TH_FIN)
4521 0 : if (src->state < TCPS_CLOSING)
4522 0 : pf_set_protostate(*state, psrc, TCPS_CLOSING);
4523 0 : if (th->th_flags & TH_RST)
4524 0 : pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
4525 :
4526 : /* Fall through to PASS packet */
4527 : } else {
4528 0 : if ((*state)->dst.state == TCPS_SYN_SENT &&
4529 0 : (*state)->src.state == TCPS_SYN_SENT) {
4530 : /* Send RST for state mismatches during handshake */
4531 0 : if (!(th->th_flags & TH_RST))
4532 0 : pf_send_tcp((*state)->rule.ptr, pd->af,
4533 0 : pd->dst, pd->src, th->th_dport,
4534 0 : th->th_sport, ntohl(th->th_ack), 0,
4535 : TH_RST, 0, 0,
4536 0 : (*state)->rule.ptr->return_ttl, 1, 0,
4537 0 : pd->rdomain);
4538 0 : src->seqlo = 0;
4539 0 : src->seqhi = 1;
4540 0 : src->max_win = 1;
4541 0 : } else if (pf_status.debug >= LOG_NOTICE) {
4542 0 : log(LOG_NOTICE, "pf: BAD state: ");
4543 0 : pf_print_state(*state);
4544 0 : pf_print_flags(th->th_flags);
4545 0 : addlog(" seq=%u (%u) ack=%u len=%u ackskew=%d "
4546 : "pkts=%llu:%llu dir=%s,%s\n",
4547 0 : seq, orig_seq, ack, pd->p_len, ackskew,
4548 0 : (*state)->packets[0], (*state)->packets[1],
4549 0 : pd->dir == PF_IN ? "in" : "out",
4550 0 : pd->dir == (*state)->direction ? "fwd" : "rev");
4551 0 : addlog("pf: State failure on: %c %c %c %c | %c %c\n",
4552 0 : SEQ_GEQ(src->seqhi, data_end) ? ' ' : '1',
4553 0 : SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
4554 : ' ': '2',
4555 0 : (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
4556 0 : (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
4557 0 : SEQ_GEQ(src->seqhi + MAXACKWINDOW, data_end) ?
4558 : ' ' :'5',
4559 0 : SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
4560 0 : }
4561 0 : REASON_SET(reason, PFRES_BADSTATE);
4562 0 : return (PF_DROP);
4563 : }
4564 :
4565 0 : return (PF_PASS);
4566 0 : }
4567 :
4568 : int
4569 0 : pf_tcp_track_sloppy(struct pf_pdesc *pd, struct pf_state **state,
4570 : u_short *reason)
4571 : {
4572 0 : struct tcphdr *th = &pd->hdr.tcp;
4573 : struct pf_state_peer *src, *dst;
4574 : u_int8_t psrc, pdst;
4575 :
4576 0 : if (pd->dir == (*state)->direction) {
4577 0 : src = &(*state)->src;
4578 0 : dst = &(*state)->dst;
4579 : psrc = PF_PEER_SRC;
4580 : pdst = PF_PEER_DST;
4581 0 : } else {
4582 0 : src = &(*state)->dst;
4583 0 : dst = &(*state)->src;
4584 : psrc = PF_PEER_DST;
4585 : pdst = PF_PEER_SRC;
4586 : }
4587 :
4588 0 : if (th->th_flags & TH_SYN)
4589 0 : if (src->state < TCPS_SYN_SENT)
4590 0 : pf_set_protostate(*state, psrc, TCPS_SYN_SENT);
4591 0 : if (th->th_flags & TH_FIN)
4592 0 : if (src->state < TCPS_CLOSING)
4593 0 : pf_set_protostate(*state, psrc, TCPS_CLOSING);
4594 0 : if (th->th_flags & TH_ACK) {
4595 0 : if (dst->state == TCPS_SYN_SENT) {
4596 0 : pf_set_protostate(*state, pdst, TCPS_ESTABLISHED);
4597 0 : if (src->state == TCPS_ESTABLISHED &&
4598 0 : !SLIST_EMPTY(&(*state)->src_nodes) &&
4599 0 : pf_src_connlimit(state)) {
4600 0 : REASON_SET(reason, PFRES_SRCLIMIT);
4601 0 : return (PF_DROP);
4602 : }
4603 0 : } else if (dst->state == TCPS_CLOSING) {
4604 0 : pf_set_protostate(*state, pdst, TCPS_FIN_WAIT_2);
4605 0 : } else if (src->state == TCPS_SYN_SENT &&
4606 0 : dst->state < TCPS_SYN_SENT) {
4607 : /*
4608 : * Handle a special sloppy case where we only see one
4609 : * half of the connection. If there is a ACK after
4610 : * the initial SYN without ever seeing a packet from
4611 : * the destination, set the connection to established.
4612 : */
4613 0 : pf_set_protostate(*state, PF_PEER_BOTH,
4614 : TCPS_ESTABLISHED);
4615 0 : if (!SLIST_EMPTY(&(*state)->src_nodes) &&
4616 0 : pf_src_connlimit(state)) {
4617 0 : REASON_SET(reason, PFRES_SRCLIMIT);
4618 0 : return (PF_DROP);
4619 : }
4620 0 : } else if (src->state == TCPS_CLOSING &&
4621 0 : dst->state == TCPS_ESTABLISHED &&
4622 0 : dst->seqlo == 0) {
4623 : /*
4624 : * Handle the closing of half connections where we
4625 : * don't see the full bidirectional FIN/ACK+ACK
4626 : * handshake.
4627 : */
4628 0 : pf_set_protostate(*state, pdst, TCPS_CLOSING);
4629 0 : }
4630 : }
4631 0 : if (th->th_flags & TH_RST)
4632 0 : pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
4633 :
4634 : /* update expire time */
4635 0 : (*state)->expire = time_uptime;
4636 0 : if (src->state >= TCPS_FIN_WAIT_2 &&
4637 0 : dst->state >= TCPS_FIN_WAIT_2)
4638 0 : (*state)->timeout = PFTM_TCP_CLOSED;
4639 0 : else if (src->state >= TCPS_CLOSING &&
4640 0 : dst->state >= TCPS_CLOSING)
4641 0 : (*state)->timeout = PFTM_TCP_FIN_WAIT;
4642 0 : else if (src->state < TCPS_ESTABLISHED ||
4643 0 : dst->state < TCPS_ESTABLISHED)
4644 0 : (*state)->timeout = PFTM_TCP_OPENING;
4645 0 : else if (src->state >= TCPS_CLOSING ||
4646 0 : dst->state >= TCPS_CLOSING)
4647 0 : (*state)->timeout = PFTM_TCP_CLOSING;
4648 : else
4649 0 : (*state)->timeout = PFTM_TCP_ESTABLISHED;
4650 :
4651 0 : return (PF_PASS);
4652 0 : }
4653 :
4654 : static __inline int
4655 0 : pf_synproxy(struct pf_pdesc *pd, struct pf_state **state, u_short *reason)
4656 : {
4657 0 : struct pf_state_key *sk = (*state)->key[pd->didx];
4658 :
4659 0 : if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
4660 0 : struct tcphdr *th = &pd->hdr.tcp;
4661 :
4662 0 : if (pd->dir != (*state)->direction) {
4663 0 : REASON_SET(reason, PFRES_SYNPROXY);
4664 0 : return (PF_SYNPROXY_DROP);
4665 : }
4666 0 : if (th->th_flags & TH_SYN) {
4667 0 : if (ntohl(th->th_seq) != (*state)->src.seqlo) {
4668 0 : REASON_SET(reason, PFRES_SYNPROXY);
4669 0 : return (PF_DROP);
4670 : }
4671 0 : pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4672 0 : pd->src, th->th_dport, th->th_sport,
4673 0 : (*state)->src.seqhi, ntohl(th->th_seq) + 1,
4674 0 : TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
4675 0 : 0, pd->rdomain);
4676 0 : REASON_SET(reason, PFRES_SYNPROXY);
4677 0 : return (PF_SYNPROXY_DROP);
4678 0 : } else if ((th->th_flags & (TH_ACK|TH_RST|TH_FIN)) != TH_ACK ||
4679 0 : (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4680 0 : (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4681 0 : REASON_SET(reason, PFRES_SYNPROXY);
4682 0 : return (PF_DROP);
4683 0 : } else if (!SLIST_EMPTY(&(*state)->src_nodes) &&
4684 0 : pf_src_connlimit(state)) {
4685 0 : REASON_SET(reason, PFRES_SRCLIMIT);
4686 0 : return (PF_DROP);
4687 : } else
4688 0 : pf_set_protostate(*state, PF_PEER_SRC,
4689 : PF_TCPS_PROXY_DST);
4690 0 : }
4691 0 : if ((*state)->src.state == PF_TCPS_PROXY_DST) {
4692 0 : struct tcphdr *th = &pd->hdr.tcp;
4693 :
4694 0 : if (pd->dir == (*state)->direction) {
4695 0 : if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
4696 0 : (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
4697 0 : (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
4698 0 : REASON_SET(reason, PFRES_SYNPROXY);
4699 0 : return (PF_DROP);
4700 : }
4701 0 : (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
4702 0 : if ((*state)->dst.seqhi == 1)
4703 0 : (*state)->dst.seqhi = arc4random();
4704 0 : pf_send_tcp((*state)->rule.ptr, pd->af,
4705 0 : &sk->addr[pd->sidx], &sk->addr[pd->didx],
4706 0 : sk->port[pd->sidx], sk->port[pd->didx],
4707 0 : (*state)->dst.seqhi, 0, TH_SYN, 0,
4708 0 : (*state)->src.mss, 0, 0, (*state)->tag,
4709 0 : sk->rdomain);
4710 0 : REASON_SET(reason, PFRES_SYNPROXY);
4711 0 : return (PF_SYNPROXY_DROP);
4712 0 : } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
4713 0 : (TH_SYN|TH_ACK)) ||
4714 0 : (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
4715 0 : REASON_SET(reason, PFRES_SYNPROXY);
4716 0 : return (PF_DROP);
4717 : } else {
4718 0 : (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
4719 0 : (*state)->dst.seqlo = ntohl(th->th_seq);
4720 0 : pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
4721 0 : pd->src, th->th_dport, th->th_sport,
4722 0 : ntohl(th->th_ack), ntohl(th->th_seq) + 1,
4723 0 : TH_ACK, (*state)->src.max_win, 0, 0, 0,
4724 0 : (*state)->tag, pd->rdomain);
4725 0 : pf_send_tcp((*state)->rule.ptr, pd->af,
4726 0 : &sk->addr[pd->sidx], &sk->addr[pd->didx],
4727 0 : sk->port[pd->sidx], sk->port[pd->didx],
4728 0 : (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
4729 0 : TH_ACK, (*state)->dst.max_win, 0, 0, 1,
4730 0 : 0, sk->rdomain);
4731 0 : (*state)->src.seqdiff = (*state)->dst.seqhi -
4732 0 : (*state)->src.seqlo;
4733 0 : (*state)->dst.seqdiff = (*state)->src.seqhi -
4734 0 : (*state)->dst.seqlo;
4735 0 : (*state)->src.seqhi = (*state)->src.seqlo +
4736 0 : (*state)->dst.max_win;
4737 0 : (*state)->dst.seqhi = (*state)->dst.seqlo +
4738 0 : (*state)->src.max_win;
4739 0 : (*state)->src.wscale = (*state)->dst.wscale = 0;
4740 0 : pf_set_protostate(*state, PF_PEER_BOTH,
4741 : TCPS_ESTABLISHED);
4742 0 : REASON_SET(reason, PFRES_SYNPROXY);
4743 0 : return (PF_SYNPROXY_DROP);
4744 : }
4745 : }
4746 0 : return (PF_PASS);
4747 0 : }
4748 :
4749 : int
4750 0 : pf_test_state(struct pf_pdesc *pd, struct pf_state **state, u_short *reason,
4751 : int syncookie)
4752 : {
4753 0 : struct pf_state_key_cmp key;
4754 0 : int copyback = 0;
4755 : struct pf_state_peer *src, *dst;
4756 : int action;
4757 : struct inpcb *inp;
4758 : u_int8_t psrc, pdst;
4759 :
4760 0 : key.af = pd->af;
4761 0 : key.proto = pd->virtual_proto;
4762 0 : key.rdomain = pd->rdomain;
4763 0 : PF_ACPY(&key.addr[pd->sidx], pd->src, key.af);
4764 0 : PF_ACPY(&key.addr[pd->didx], pd->dst, key.af);
4765 0 : key.port[pd->sidx] = pd->osport;
4766 0 : key.port[pd->didx] = pd->odport;
4767 0 : inp = pd->m->m_pkthdr.pf.inp;
4768 :
4769 0 : action = pf_find_state(pd, &key, state);
4770 0 : if (action != PF_MATCH)
4771 0 : return (action);
4772 :
4773 : action = PF_PASS;
4774 0 : if (pd->dir == (*state)->direction) {
4775 0 : src = &(*state)->src;
4776 0 : dst = &(*state)->dst;
4777 : psrc = PF_PEER_SRC;
4778 : pdst = PF_PEER_DST;
4779 0 : } else {
4780 0 : src = &(*state)->dst;
4781 0 : dst = &(*state)->src;
4782 : psrc = PF_PEER_DST;
4783 : pdst = PF_PEER_SRC;
4784 : }
4785 :
4786 0 : switch (pd->virtual_proto) {
4787 : case IPPROTO_TCP:
4788 0 : if (syncookie) {
4789 0 : pf_set_protostate(*state, PF_PEER_SRC,
4790 : PF_TCPS_PROXY_DST);
4791 0 : (*state)->dst.seqhi = ntohl(pd->hdr.tcp.th_ack) - 1;
4792 0 : }
4793 0 : if ((action = pf_synproxy(pd, state, reason)) != PF_PASS)
4794 0 : return (action);
4795 0 : if ((pd->hdr.tcp.th_flags & (TH_SYN|TH_ACK)) == TH_SYN) {
4796 :
4797 0 : if (dst->state >= TCPS_FIN_WAIT_2 &&
4798 0 : src->state >= TCPS_FIN_WAIT_2) {
4799 0 : if (pf_status.debug >= LOG_NOTICE) {
4800 0 : log(LOG_NOTICE, "pf: state reuse ");
4801 0 : pf_print_state(*state);
4802 0 : pf_print_flags(pd->hdr.tcp.th_flags);
4803 0 : addlog("\n");
4804 0 : }
4805 : /* XXX make sure it's the same direction ?? */
4806 0 : (*state)->timeout = PFTM_PURGE;
4807 0 : *state = NULL;
4808 0 : pf_mbuf_link_inpcb(pd->m, inp);
4809 0 : return (PF_DROP);
4810 0 : } else if (dst->state >= TCPS_ESTABLISHED &&
4811 0 : src->state >= TCPS_ESTABLISHED) {
4812 : /*
4813 : * SYN matches existing state???
4814 : * Typically happens when sender boots up after
4815 : * sudden panic. Certain protocols (NFSv3) are
4816 : * always using same port numbers. Challenge
4817 : * ACK enables all parties (firewall and peers)
4818 : * to get in sync again.
4819 : */
4820 0 : pf_send_challenge_ack(pd, *state, src, dst);
4821 0 : return (PF_DROP);
4822 : }
4823 : }
4824 :
4825 0 : if ((*state)->state_flags & PFSTATE_SLOPPY) {
4826 0 : if (pf_tcp_track_sloppy(pd, state, reason) == PF_DROP)
4827 0 : return (PF_DROP);
4828 : } else {
4829 0 : if (pf_tcp_track_full(pd, state, reason, ©back,
4830 0 : PF_REVERSED_KEY((*state)->key, pd->af)) == PF_DROP)
4831 0 : return (PF_DROP);
4832 : }
4833 : break;
4834 : case IPPROTO_UDP:
4835 : /* update states */
4836 0 : if (src->state < PFUDPS_SINGLE)
4837 0 : pf_set_protostate(*state, psrc, PFUDPS_SINGLE);
4838 0 : if (dst->state == PFUDPS_SINGLE)
4839 0 : pf_set_protostate(*state, pdst, PFUDPS_MULTIPLE);
4840 :
4841 : /* update expire time */
4842 0 : (*state)->expire = time_uptime;
4843 0 : if (src->state == PFUDPS_MULTIPLE &&
4844 0 : dst->state == PFUDPS_MULTIPLE)
4845 0 : (*state)->timeout = PFTM_UDP_MULTIPLE;
4846 : else
4847 0 : (*state)->timeout = PFTM_UDP_SINGLE;
4848 : break;
4849 : default:
4850 : /* update states */
4851 0 : if (src->state < PFOTHERS_SINGLE)
4852 0 : pf_set_protostate(*state, psrc, PFOTHERS_SINGLE);
4853 0 : if (dst->state == PFOTHERS_SINGLE)
4854 0 : pf_set_protostate(*state, pdst, PFOTHERS_MULTIPLE);
4855 :
4856 : /* update expire time */
4857 0 : (*state)->expire = time_uptime;
4858 0 : if (src->state == PFOTHERS_MULTIPLE &&
4859 0 : dst->state == PFOTHERS_MULTIPLE)
4860 0 : (*state)->timeout = PFTM_OTHER_MULTIPLE;
4861 : else
4862 0 : (*state)->timeout = PFTM_OTHER_SINGLE;
4863 : break;
4864 : }
4865 :
4866 : /* translate source/destination address, if necessary */
4867 0 : if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
4868 : struct pf_state_key *nk;
4869 : int afto, sidx, didx;
4870 :
4871 0 : if (PF_REVERSED_KEY((*state)->key, pd->af))
4872 0 : nk = (*state)->key[pd->sidx];
4873 : else
4874 0 : nk = (*state)->key[pd->didx];
4875 :
4876 0 : afto = pd->af != nk->af;
4877 0 : sidx = afto ? pd->didx : pd->sidx;
4878 0 : didx = afto ? pd->sidx : pd->didx;
4879 :
4880 : #ifdef INET6
4881 0 : if (afto) {
4882 0 : PF_ACPY(&pd->nsaddr, &nk->addr[sidx], nk->af);
4883 0 : PF_ACPY(&pd->ndaddr, &nk->addr[didx], nk->af);
4884 0 : pd->naf = nk->af;
4885 : action = PF_AFRT;
4886 0 : }
4887 : #endif /* INET6 */
4888 :
4889 0 : if (!afto)
4890 0 : pf_translate_a(pd, pd->src, &nk->addr[sidx]);
4891 :
4892 0 : if (pd->sport != NULL)
4893 0 : pf_patch_16(pd, pd->sport, nk->port[sidx]);
4894 :
4895 0 : if (afto || PF_ANEQ(pd->dst, &nk->addr[didx], pd->af) ||
4896 0 : pd->rdomain != nk->rdomain)
4897 0 : pd->destchg = 1;
4898 :
4899 0 : if (!afto)
4900 0 : pf_translate_a(pd, pd->dst, &nk->addr[didx]);
4901 :
4902 0 : if (pd->dport != NULL)
4903 0 : pf_patch_16(pd, pd->dport, nk->port[didx]);
4904 :
4905 0 : pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
4906 0 : copyback = 1;
4907 0 : }
4908 :
4909 0 : if (copyback && pd->hdrlen > 0) {
4910 0 : m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
4911 0 : }
4912 :
4913 0 : return (action);
4914 0 : }
4915 :
4916 : int
4917 0 : pf_icmp_state_lookup(struct pf_pdesc *pd, struct pf_state_key_cmp *key,
4918 : struct pf_state **state, u_int16_t icmpid, u_int16_t type,
4919 : int icmp_dir, int *iidx, int multi, int inner)
4920 : {
4921 : int direction, action;
4922 :
4923 0 : key->af = pd->af;
4924 0 : key->proto = pd->proto;
4925 0 : key->rdomain = pd->rdomain;
4926 0 : if (icmp_dir == PF_IN) {
4927 0 : *iidx = pd->sidx;
4928 0 : key->port[pd->sidx] = icmpid;
4929 0 : key->port[pd->didx] = type;
4930 0 : } else {
4931 0 : *iidx = pd->didx;
4932 0 : key->port[pd->sidx] = type;
4933 0 : key->port[pd->didx] = icmpid;
4934 : }
4935 :
4936 0 : if (pf_state_key_addr_setup(pd, key, pd->sidx, pd->src, pd->didx,
4937 0 : pd->dst, pd->af, multi))
4938 0 : return (PF_DROP);
4939 :
4940 0 : action = pf_find_state(pd, key, state);
4941 0 : if (action != PF_MATCH)
4942 0 : return (action);
4943 :
4944 0 : if ((*state)->state_flags & PFSTATE_SLOPPY)
4945 0 : return (-1);
4946 :
4947 : /* Is this ICMP message flowing in right direction? */
4948 0 : if ((*state)->key[PF_SK_WIRE]->af != (*state)->key[PF_SK_STACK]->af)
4949 0 : direction = (pd->af == (*state)->key[PF_SK_WIRE]->af) ?
4950 : PF_IN : PF_OUT;
4951 : else
4952 0 : direction = (*state)->direction;
4953 0 : if ((((!inner && direction == pd->dir) ||
4954 0 : (inner && direction != pd->dir)) ?
4955 0 : PF_IN : PF_OUT) != icmp_dir) {
4956 0 : if (pf_status.debug >= LOG_NOTICE) {
4957 0 : log(LOG_NOTICE,
4958 : "pf: icmp type %d in wrong direction (%d): ",
4959 0 : ntohs(type), icmp_dir);
4960 0 : pf_print_state(*state);
4961 0 : addlog("\n");
4962 0 : }
4963 0 : return (PF_DROP);
4964 : }
4965 0 : return (-1);
4966 0 : }
4967 :
4968 : int
4969 0 : pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
4970 : u_short *reason)
4971 : {
4972 0 : u_int16_t virtual_id, virtual_type;
4973 : u_int8_t icmptype;
4974 0 : int icmp_dir, iidx, ret, copyback = 0;
4975 :
4976 0 : struct pf_state_key_cmp key;
4977 :
4978 0 : switch (pd->proto) {
4979 : case IPPROTO_ICMP:
4980 0 : icmptype = pd->hdr.icmp.icmp_type;
4981 0 : break;
4982 : #ifdef INET6
4983 : case IPPROTO_ICMPV6:
4984 0 : icmptype = pd->hdr.icmp6.icmp6_type;
4985 0 : break;
4986 : #endif /* INET6 */
4987 : default:
4988 0 : panic("unhandled proto %d", pd->proto);
4989 : }
4990 :
4991 0 : if (pf_icmp_mapping(pd, icmptype, &icmp_dir, &virtual_id,
4992 0 : &virtual_type) == 0) {
4993 : /*
4994 : * ICMP query/reply message not related to a TCP/UDP packet.
4995 : * Search for an ICMP state.
4996 : */
4997 0 : ret = pf_icmp_state_lookup(pd, &key, state,
4998 0 : virtual_id, virtual_type, icmp_dir, &iidx,
4999 : 0, 0);
5000 : /* IPv6? try matching a multicast address */
5001 0 : if (ret == PF_DROP && pd->af == AF_INET6 && icmp_dir == PF_OUT)
5002 0 : ret = pf_icmp_state_lookup(pd, &key, state, virtual_id,
5003 0 : virtual_type, icmp_dir, &iidx, 1, 0);
5004 0 : if (ret >= 0)
5005 0 : return (ret);
5006 :
5007 0 : (*state)->expire = time_uptime;
5008 0 : (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
5009 :
5010 : /* translate source/destination address, if necessary */
5011 0 : if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
5012 : struct pf_state_key *nk;
5013 : int afto, sidx, didx;
5014 :
5015 0 : if (PF_REVERSED_KEY((*state)->key, pd->af))
5016 0 : nk = (*state)->key[pd->sidx];
5017 : else
5018 0 : nk = (*state)->key[pd->didx];
5019 :
5020 0 : afto = pd->af != nk->af;
5021 0 : sidx = afto ? pd->didx : pd->sidx;
5022 0 : didx = afto ? pd->sidx : pd->didx;
5023 0 : iidx = afto ? !iidx : iidx;
5024 : #ifdef INET6
5025 0 : if (afto) {
5026 0 : PF_ACPY(&pd->nsaddr, &nk->addr[sidx], nk->af);
5027 0 : PF_ACPY(&pd->ndaddr, &nk->addr[didx], nk->af);
5028 0 : pd->naf = nk->af;
5029 0 : }
5030 : #endif /* INET6 */
5031 0 : if (!afto) {
5032 0 : pf_translate_a(pd, pd->src, &nk->addr[sidx]);
5033 0 : pf_translate_a(pd, pd->dst, &nk->addr[didx]);
5034 0 : }
5035 :
5036 0 : if (pd->rdomain != nk->rdomain)
5037 0 : pd->destchg = 1;
5038 0 : if (!afto && PF_ANEQ(pd->dst,
5039 : &nk->addr[didx], pd->af))
5040 0 : pd->destchg = 1;
5041 0 : pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
5042 :
5043 0 : switch (pd->af) {
5044 : case AF_INET:
5045 : #ifdef INET6
5046 0 : if (afto) {
5047 0 : if (pf_translate_icmp_af(pd, AF_INET6,
5048 0 : &pd->hdr.icmp))
5049 0 : return (PF_DROP);
5050 0 : pd->proto = IPPROTO_ICMPV6;
5051 0 : }
5052 : #endif /* INET6 */
5053 0 : pf_patch_16(pd,
5054 0 : &pd->hdr.icmp.icmp_id, nk->port[iidx]);
5055 :
5056 0 : m_copyback(pd->m, pd->off, ICMP_MINLEN,
5057 0 : &pd->hdr.icmp, M_NOWAIT);
5058 : copyback = 1;
5059 0 : break;
5060 : #ifdef INET6
5061 : case AF_INET6:
5062 0 : if (afto) {
5063 0 : if (pf_translate_icmp_af(pd, AF_INET,
5064 0 : &pd->hdr.icmp6))
5065 0 : return (PF_DROP);
5066 0 : pd->proto = IPPROTO_ICMP;
5067 0 : }
5068 :
5069 0 : pf_patch_16(pd,
5070 0 : &pd->hdr.icmp6.icmp6_id, nk->port[iidx]);
5071 :
5072 0 : m_copyback(pd->m, pd->off,
5073 0 : sizeof(struct icmp6_hdr), &pd->hdr.icmp6,
5074 : M_NOWAIT);
5075 : copyback = 1;
5076 0 : break;
5077 : #endif /* INET6 */
5078 : }
5079 : #ifdef INET6
5080 0 : if (afto)
5081 0 : return (PF_AFRT);
5082 : #endif /* INET6 */
5083 0 : }
5084 : } else {
5085 : /*
5086 : * ICMP error message in response to a TCP/UDP packet.
5087 : * Extract the inner TCP/UDP header and search for that state.
5088 : */
5089 0 : struct pf_pdesc pd2;
5090 0 : struct ip h2;
5091 : #ifdef INET6
5092 0 : struct ip6_hdr h2_6;
5093 : #endif /* INET6 */
5094 : int ipoff2;
5095 :
5096 : /* Initialize pd2 fields valid for both packets with pd. */
5097 0 : memset(&pd2, 0, sizeof(pd2));
5098 0 : pd2.af = pd->af;
5099 0 : pd2.dir = pd->dir;
5100 0 : pd2.kif = pd->kif;
5101 0 : pd2.m = pd->m;
5102 0 : pd2.rdomain = pd->rdomain;
5103 : /* Payload packet is from the opposite direction. */
5104 0 : pd2.sidx = (pd2.dir == PF_IN) ? 1 : 0;
5105 0 : pd2.didx = (pd2.dir == PF_IN) ? 0 : 1;
5106 0 : switch (pd->af) {
5107 : case AF_INET:
5108 : /* offset of h2 in mbuf chain */
5109 0 : ipoff2 = pd->off + ICMP_MINLEN;
5110 :
5111 0 : if (!pf_pull_hdr(pd2.m, ipoff2, &h2, sizeof(h2),
5112 0 : NULL, reason, pd2.af)) {
5113 0 : DPFPRINTF(LOG_NOTICE,
5114 : "ICMP error message too short (ip)");
5115 0 : return (PF_DROP);
5116 : }
5117 : /*
5118 : * ICMP error messages don't refer to non-first
5119 : * fragments
5120 : */
5121 0 : if (h2.ip_off & htons(IP_OFFMASK)) {
5122 0 : REASON_SET(reason, PFRES_FRAG);
5123 0 : return (PF_DROP);
5124 : }
5125 :
5126 : /* offset of protocol header that follows h2 */
5127 0 : pd2.off = ipoff2;
5128 0 : if (pf_walk_header(&pd2, &h2, reason) != PF_PASS)
5129 0 : return (PF_DROP);
5130 :
5131 0 : pd2.tot_len = ntohs(h2.ip_len);
5132 0 : pd2.src = (struct pf_addr *)&h2.ip_src;
5133 0 : pd2.dst = (struct pf_addr *)&h2.ip_dst;
5134 0 : break;
5135 : #ifdef INET6
5136 : case AF_INET6:
5137 0 : ipoff2 = pd->off + sizeof(struct icmp6_hdr);
5138 :
5139 0 : if (!pf_pull_hdr(pd2.m, ipoff2, &h2_6, sizeof(h2_6),
5140 0 : NULL, reason, pd2.af)) {
5141 0 : DPFPRINTF(LOG_NOTICE,
5142 : "ICMP error message too short (ip6)");
5143 0 : return (PF_DROP);
5144 : }
5145 :
5146 0 : pd2.off = ipoff2;
5147 0 : if (pf_walk_header6(&pd2, &h2_6, reason) != PF_PASS)
5148 0 : return (PF_DROP);
5149 :
5150 0 : pd2.tot_len = ntohs(h2_6.ip6_plen) +
5151 : sizeof(struct ip6_hdr);
5152 0 : pd2.src = (struct pf_addr *)&h2_6.ip6_src;
5153 0 : pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
5154 0 : break;
5155 : #endif /* INET6 */
5156 : default:
5157 0 : unhandled_af(pd->af);
5158 : }
5159 :
5160 0 : switch (pd2.proto) {
5161 : case IPPROTO_TCP: {
5162 0 : struct tcphdr *th = &pd2.hdr.tcp;
5163 : u_int32_t seq;
5164 : struct pf_state_peer *src, *dst;
5165 : u_int8_t dws;
5166 : int action;
5167 :
5168 : /*
5169 : * Only the first 8 bytes of the TCP header can be
5170 : * expected. Don't access any TCP header fields after
5171 : * th_seq, an ackskew test is not possible.
5172 : */
5173 0 : if (!pf_pull_hdr(pd2.m, pd2.off, th, 8, NULL, reason,
5174 0 : pd2.af)) {
5175 0 : DPFPRINTF(LOG_NOTICE,
5176 : "ICMP error message too short (tcp)");
5177 0 : return (PF_DROP);
5178 : }
5179 :
5180 0 : key.af = pd2.af;
5181 0 : key.proto = IPPROTO_TCP;
5182 0 : key.rdomain = pd2.rdomain;
5183 0 : PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
5184 0 : PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
5185 0 : key.port[pd2.sidx] = th->th_sport;
5186 0 : key.port[pd2.didx] = th->th_dport;
5187 :
5188 0 : action = pf_find_state(&pd2, &key, state);
5189 0 : if (action != PF_MATCH)
5190 0 : return (action);
5191 :
5192 0 : if (pd2.dir == (*state)->direction) {
5193 0 : if (PF_REVERSED_KEY((*state)->key, pd->af)) {
5194 0 : src = &(*state)->src;
5195 0 : dst = &(*state)->dst;
5196 0 : } else {
5197 0 : src = &(*state)->dst;
5198 0 : dst = &(*state)->src;
5199 : }
5200 : } else {
5201 0 : if (PF_REVERSED_KEY((*state)->key, pd->af)) {
5202 0 : src = &(*state)->dst;
5203 0 : dst = &(*state)->src;
5204 0 : } else {
5205 0 : src = &(*state)->src;
5206 0 : dst = &(*state)->dst;
5207 : }
5208 : }
5209 :
5210 0 : if (src->wscale && dst->wscale)
5211 0 : dws = dst->wscale & PF_WSCALE_MASK;
5212 : else
5213 : dws = 0;
5214 :
5215 : /* Demodulate sequence number */
5216 0 : seq = ntohl(th->th_seq) - src->seqdiff;
5217 0 : if (src->seqdiff) {
5218 0 : pf_patch_32(pd, &th->th_seq, htonl(seq));
5219 : copyback = 1;
5220 0 : }
5221 :
5222 0 : if (!((*state)->state_flags & PFSTATE_SLOPPY) &&
5223 0 : (!SEQ_GEQ(src->seqhi, seq) || !SEQ_GEQ(seq,
5224 : src->seqlo - (dst->max_win << dws)))) {
5225 0 : if (pf_status.debug >= LOG_NOTICE) {
5226 0 : log(LOG_NOTICE,
5227 : "pf: BAD ICMP %d:%d ",
5228 0 : icmptype, pd->hdr.icmp.icmp_code);
5229 0 : pf_print_host(pd->src, 0, pd->af);
5230 0 : addlog(" -> ");
5231 0 : pf_print_host(pd->dst, 0, pd->af);
5232 0 : addlog(" state: ");
5233 0 : pf_print_state(*state);
5234 0 : addlog(" seq=%u\n", seq);
5235 0 : }
5236 0 : REASON_SET(reason, PFRES_BADSTATE);
5237 0 : return (PF_DROP);
5238 : } else {
5239 0 : if (pf_status.debug >= LOG_DEBUG) {
5240 0 : log(LOG_DEBUG,
5241 : "pf: OK ICMP %d:%d ",
5242 0 : icmptype, pd->hdr.icmp.icmp_code);
5243 0 : pf_print_host(pd->src, 0, pd->af);
5244 0 : addlog(" -> ");
5245 0 : pf_print_host(pd->dst, 0, pd->af);
5246 0 : addlog(" state: ");
5247 0 : pf_print_state(*state);
5248 0 : addlog(" seq=%u\n", seq);
5249 0 : }
5250 : }
5251 :
5252 : /* translate source/destination address, if necessary */
5253 0 : if ((*state)->key[PF_SK_WIRE] !=
5254 0 : (*state)->key[PF_SK_STACK]) {
5255 : struct pf_state_key *nk;
5256 : int afto, sidx, didx;
5257 :
5258 0 : if (PF_REVERSED_KEY((*state)->key, pd->af))
5259 0 : nk = (*state)->key[pd->sidx];
5260 : else
5261 0 : nk = (*state)->key[pd->didx];
5262 :
5263 0 : afto = pd->af != nk->af;
5264 0 : sidx = afto ? pd2.didx : pd2.sidx;
5265 0 : didx = afto ? pd2.sidx : pd2.didx;
5266 :
5267 : #ifdef INET6
5268 0 : if (afto) {
5269 0 : if (pf_translate_icmp_af(pd, nk->af,
5270 0 : &pd->hdr.icmp))
5271 0 : return (PF_DROP);
5272 0 : m_copyback(pd->m, pd->off,
5273 : sizeof(struct icmp6_hdr),
5274 0 : &pd->hdr.icmp6, M_NOWAIT);
5275 0 : if (pf_change_icmp_af(pd->m, ipoff2,
5276 0 : pd, &pd2, &nk->addr[sidx],
5277 0 : &nk->addr[didx], pd->af, nk->af))
5278 0 : return (PF_DROP);
5279 0 : if (nk->af == AF_INET)
5280 0 : pd->proto = IPPROTO_ICMP;
5281 : else
5282 0 : pd->proto = IPPROTO_ICMPV6;
5283 0 : pd->m->m_pkthdr.ph_rtableid =
5284 0 : nk->rdomain;
5285 0 : pd->destchg = 1;
5286 0 : PF_ACPY(&pd->nsaddr,
5287 : &nk->addr[pd2.sidx], nk->af);
5288 0 : PF_ACPY(&pd->ndaddr,
5289 : &nk->addr[pd2.didx], nk->af);
5290 0 : pd->naf = nk->af;
5291 :
5292 0 : pf_patch_16(pd,
5293 0 : &th->th_sport, nk->port[sidx]);
5294 0 : pf_patch_16(pd,
5295 0 : &th->th_dport, nk->port[didx]);
5296 :
5297 0 : m_copyback(pd2.m, pd2.off, 8, th,
5298 : M_NOWAIT);
5299 0 : return (PF_AFRT);
5300 : }
5301 : #endif /* INET6 */
5302 0 : if (PF_ANEQ(pd2.src,
5303 0 : &nk->addr[pd2.sidx], pd2.af) ||
5304 0 : nk->port[pd2.sidx] != th->th_sport)
5305 0 : pf_translate_icmp(pd, pd2.src,
5306 0 : &th->th_sport, pd->dst,
5307 0 : &nk->addr[pd2.sidx],
5308 0 : nk->port[pd2.sidx]);
5309 :
5310 0 : if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
5311 0 : pd2.af) || pd2.rdomain != nk->rdomain)
5312 0 : pd->destchg = 1;
5313 0 : pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
5314 :
5315 0 : if (PF_ANEQ(pd2.dst,
5316 0 : &nk->addr[pd2.didx], pd2.af) ||
5317 0 : nk->port[pd2.didx] != th->th_dport)
5318 0 : pf_translate_icmp(pd, pd2.dst,
5319 0 : &th->th_dport, pd->src,
5320 0 : &nk->addr[pd2.didx],
5321 0 : nk->port[pd2.didx]);
5322 : copyback = 1;
5323 0 : }
5324 :
5325 0 : if (copyback) {
5326 0 : switch (pd2.af) {
5327 : case AF_INET:
5328 0 : m_copyback(pd->m, pd->off, ICMP_MINLEN,
5329 0 : &pd->hdr.icmp, M_NOWAIT);
5330 0 : m_copyback(pd2.m, ipoff2, sizeof(h2),
5331 : &h2, M_NOWAIT);
5332 0 : break;
5333 : #ifdef INET6
5334 : case AF_INET6:
5335 0 : m_copyback(pd->m, pd->off,
5336 : sizeof(struct icmp6_hdr),
5337 0 : &pd->hdr.icmp6, M_NOWAIT);
5338 0 : m_copyback(pd2.m, ipoff2, sizeof(h2_6),
5339 : &h2_6, M_NOWAIT);
5340 0 : break;
5341 : #endif /* INET6 */
5342 : }
5343 0 : m_copyback(pd2.m, pd2.off, 8, th, M_NOWAIT);
5344 0 : }
5345 0 : break;
5346 : }
5347 : case IPPROTO_UDP: {
5348 0 : struct udphdr *uh = &pd2.hdr.udp;
5349 : int action;
5350 :
5351 0 : if (!pf_pull_hdr(pd2.m, pd2.off, uh, sizeof(*uh),
5352 0 : NULL, reason, pd2.af)) {
5353 0 : DPFPRINTF(LOG_NOTICE,
5354 : "ICMP error message too short (udp)");
5355 0 : return (PF_DROP);
5356 : }
5357 :
5358 0 : key.af = pd2.af;
5359 0 : key.proto = IPPROTO_UDP;
5360 0 : key.rdomain = pd2.rdomain;
5361 0 : PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
5362 0 : PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
5363 0 : key.port[pd2.sidx] = uh->uh_sport;
5364 0 : key.port[pd2.didx] = uh->uh_dport;
5365 :
5366 0 : action = pf_find_state(&pd2, &key, state);
5367 0 : if (action != PF_MATCH)
5368 0 : return (action);
5369 :
5370 : /* translate source/destination address, if necessary */
5371 0 : if ((*state)->key[PF_SK_WIRE] !=
5372 0 : (*state)->key[PF_SK_STACK]) {
5373 : struct pf_state_key *nk;
5374 : int afto, sidx, didx;
5375 :
5376 0 : if (PF_REVERSED_KEY((*state)->key, pd->af))
5377 0 : nk = (*state)->key[pd->sidx];
5378 : else
5379 0 : nk = (*state)->key[pd->didx];
5380 :
5381 0 : afto = pd->af != nk->af;
5382 0 : sidx = afto ? pd2.didx : pd2.sidx;
5383 0 : didx = afto ? pd2.sidx : pd2.didx;
5384 :
5385 : #ifdef INET6
5386 0 : if (afto) {
5387 0 : if (pf_translate_icmp_af(pd, nk->af,
5388 0 : &pd->hdr.icmp))
5389 0 : return (PF_DROP);
5390 0 : m_copyback(pd->m, pd->off,
5391 : sizeof(struct icmp6_hdr),
5392 0 : &pd->hdr.icmp6, M_NOWAIT);
5393 0 : if (pf_change_icmp_af(pd->m, ipoff2,
5394 0 : pd, &pd2, &nk->addr[sidx],
5395 0 : &nk->addr[didx], pd->af, nk->af))
5396 0 : return (PF_DROP);
5397 0 : if (nk->af == AF_INET)
5398 0 : pd->proto = IPPROTO_ICMP;
5399 : else
5400 0 : pd->proto = IPPROTO_ICMPV6;
5401 0 : pd->m->m_pkthdr.ph_rtableid =
5402 0 : nk->rdomain;
5403 0 : pd->destchg = 1;
5404 0 : PF_ACPY(&pd->nsaddr,
5405 : &nk->addr[pd2.sidx], nk->af);
5406 0 : PF_ACPY(&pd->ndaddr,
5407 : &nk->addr[pd2.didx], nk->af);
5408 0 : pd->naf = nk->af;
5409 :
5410 0 : pf_patch_16(pd,
5411 0 : &uh->uh_sport, nk->port[sidx]);
5412 0 : pf_patch_16(pd,
5413 0 : &uh->uh_dport, nk->port[didx]);
5414 :
5415 0 : m_copyback(pd2.m, pd2.off, sizeof(*uh),
5416 : uh, M_NOWAIT);
5417 0 : return (PF_AFRT);
5418 : }
5419 : #endif /* INET6 */
5420 :
5421 0 : if (PF_ANEQ(pd2.src,
5422 0 : &nk->addr[pd2.sidx], pd2.af) ||
5423 0 : nk->port[pd2.sidx] != uh->uh_sport)
5424 0 : pf_translate_icmp(pd, pd2.src,
5425 0 : &uh->uh_sport, pd->dst,
5426 0 : &nk->addr[pd2.sidx],
5427 0 : nk->port[pd2.sidx]);
5428 :
5429 0 : if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
5430 0 : pd2.af) || pd2.rdomain != nk->rdomain)
5431 0 : pd->destchg = 1;
5432 0 : pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
5433 :
5434 0 : if (PF_ANEQ(pd2.dst,
5435 0 : &nk->addr[pd2.didx], pd2.af) ||
5436 0 : nk->port[pd2.didx] != uh->uh_dport)
5437 0 : pf_translate_icmp(pd, pd2.dst,
5438 0 : &uh->uh_dport, pd->src,
5439 0 : &nk->addr[pd2.didx],
5440 0 : nk->port[pd2.didx]);
5441 :
5442 0 : switch (pd2.af) {
5443 : case AF_INET:
5444 0 : m_copyback(pd->m, pd->off, ICMP_MINLEN,
5445 0 : &pd->hdr.icmp, M_NOWAIT);
5446 0 : m_copyback(pd2.m, ipoff2, sizeof(h2),
5447 : &h2, M_NOWAIT);
5448 0 : break;
5449 : #ifdef INET6
5450 : case AF_INET6:
5451 0 : m_copyback(pd->m, pd->off,
5452 : sizeof(struct icmp6_hdr),
5453 0 : &pd->hdr.icmp6, M_NOWAIT);
5454 0 : m_copyback(pd2.m, ipoff2, sizeof(h2_6),
5455 : &h2_6, M_NOWAIT);
5456 0 : break;
5457 : #endif /* INET6 */
5458 : }
5459 : /* Avoid recomputing quoted UDP checksum.
5460 : * note: udp6 0 csum invalid per rfc2460 p27.
5461 : * but presumed nothing cares in this context */
5462 0 : pf_patch_16(pd, &uh->uh_sum, 0);
5463 0 : m_copyback(pd2.m, pd2.off, sizeof(*uh), uh,
5464 : M_NOWAIT);
5465 : copyback = 1;
5466 0 : }
5467 0 : break;
5468 : }
5469 : case IPPROTO_ICMP: {
5470 0 : struct icmp *iih = &pd2.hdr.icmp;
5471 :
5472 0 : if (pd2.af != AF_INET) {
5473 0 : REASON_SET(reason, PFRES_NORM);
5474 0 : return (PF_DROP);
5475 : }
5476 :
5477 0 : if (!pf_pull_hdr(pd2.m, pd2.off, iih, ICMP_MINLEN,
5478 : NULL, reason, pd2.af)) {
5479 0 : DPFPRINTF(LOG_NOTICE,
5480 : "ICMP error message too short (icmp)");
5481 0 : return (PF_DROP);
5482 : }
5483 :
5484 0 : pf_icmp_mapping(&pd2, iih->icmp_type,
5485 : &icmp_dir, &virtual_id, &virtual_type);
5486 :
5487 0 : ret = pf_icmp_state_lookup(&pd2, &key, state,
5488 0 : virtual_id, virtual_type, icmp_dir, &iidx, 0, 1);
5489 0 : if (ret >= 0)
5490 0 : return (ret);
5491 :
5492 : /* translate source/destination address, if necessary */
5493 0 : if ((*state)->key[PF_SK_WIRE] !=
5494 0 : (*state)->key[PF_SK_STACK]) {
5495 : struct pf_state_key *nk;
5496 : int afto, sidx, didx;
5497 :
5498 0 : if (PF_REVERSED_KEY((*state)->key, pd->af))
5499 0 : nk = (*state)->key[pd->sidx];
5500 : else
5501 0 : nk = (*state)->key[pd->didx];
5502 :
5503 0 : afto = pd->af != nk->af;
5504 0 : sidx = afto ? pd2.didx : pd2.sidx;
5505 0 : didx = afto ? pd2.sidx : pd2.didx;
5506 0 : iidx = afto ? !iidx : iidx;
5507 :
5508 : #ifdef INET6
5509 0 : if (afto) {
5510 0 : if (nk->af != AF_INET6)
5511 0 : return (PF_DROP);
5512 0 : if (pf_translate_icmp_af(pd, nk->af,
5513 0 : &pd->hdr.icmp))
5514 0 : return (PF_DROP);
5515 0 : m_copyback(pd->m, pd->off,
5516 : sizeof(struct icmp6_hdr),
5517 0 : &pd->hdr.icmp6, M_NOWAIT);
5518 0 : if (pf_change_icmp_af(pd->m, ipoff2,
5519 0 : pd, &pd2, &nk->addr[sidx],
5520 0 : &nk->addr[didx], pd->af, nk->af))
5521 0 : return (PF_DROP);
5522 0 : pd->proto = IPPROTO_ICMPV6;
5523 0 : if (pf_translate_icmp_af(pd,
5524 0 : nk->af, iih))
5525 0 : return (PF_DROP);
5526 0 : if (virtual_type == htons(ICMP_ECHO))
5527 0 : pf_patch_16(pd, &iih->icmp_id,
5528 0 : nk->port[iidx]);
5529 0 : m_copyback(pd2.m, pd2.off, ICMP_MINLEN,
5530 : iih, M_NOWAIT);
5531 0 : pd->m->m_pkthdr.ph_rtableid =
5532 0 : nk->rdomain;
5533 0 : pd->destchg = 1;
5534 0 : PF_ACPY(&pd->nsaddr,
5535 : &nk->addr[pd2.sidx], nk->af);
5536 0 : PF_ACPY(&pd->ndaddr,
5537 : &nk->addr[pd2.didx], nk->af);
5538 0 : pd->naf = nk->af;
5539 0 : return (PF_AFRT);
5540 : }
5541 : #endif /* INET6 */
5542 :
5543 0 : if (PF_ANEQ(pd2.src,
5544 0 : &nk->addr[pd2.sidx], pd2.af) ||
5545 0 : (virtual_type == htons(ICMP_ECHO) &&
5546 0 : nk->port[iidx] != iih->icmp_id))
5547 0 : pf_translate_icmp(pd, pd2.src,
5548 0 : (virtual_type == htons(ICMP_ECHO)) ?
5549 0 : &iih->icmp_id : NULL,
5550 0 : pd->dst, &nk->addr[pd2.sidx],
5551 0 : (virtual_type == htons(ICMP_ECHO)) ?
5552 0 : nk->port[iidx] : 0);
5553 :
5554 0 : if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
5555 0 : pd2.af) || pd2.rdomain != nk->rdomain)
5556 0 : pd->destchg = 1;
5557 0 : pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
5558 :
5559 0 : if (PF_ANEQ(pd2.dst,
5560 : &nk->addr[pd2.didx], pd2.af))
5561 0 : pf_translate_icmp(pd, pd2.dst, NULL,
5562 0 : pd->src, &nk->addr[pd2.didx], 0);
5563 :
5564 0 : m_copyback(pd->m, pd->off, ICMP_MINLEN,
5565 0 : &pd->hdr.icmp, M_NOWAIT);
5566 0 : m_copyback(pd2.m, ipoff2, sizeof(h2), &h2,
5567 : M_NOWAIT);
5568 0 : m_copyback(pd2.m, pd2.off, ICMP_MINLEN, iih,
5569 : M_NOWAIT);
5570 : copyback = 1;
5571 0 : }
5572 0 : break;
5573 : }
5574 : #ifdef INET6
5575 : case IPPROTO_ICMPV6: {
5576 0 : struct icmp6_hdr *iih = &pd2.hdr.icmp6;
5577 :
5578 0 : if (pd2.af != AF_INET6) {
5579 0 : REASON_SET(reason, PFRES_NORM);
5580 0 : return (PF_DROP);
5581 : }
5582 :
5583 0 : if (!pf_pull_hdr(pd2.m, pd2.off, iih,
5584 : sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
5585 0 : DPFPRINTF(LOG_NOTICE,
5586 : "ICMP error message too short (icmp6)");
5587 0 : return (PF_DROP);
5588 : }
5589 :
5590 0 : pf_icmp_mapping(&pd2, iih->icmp6_type,
5591 : &icmp_dir, &virtual_id, &virtual_type);
5592 0 : ret = pf_icmp_state_lookup(&pd2, &key, state,
5593 0 : virtual_id, virtual_type, icmp_dir, &iidx, 0, 1);
5594 : /* IPv6? try matching a multicast address */
5595 0 : if (ret == PF_DROP && pd2.af == AF_INET6 &&
5596 0 : icmp_dir == PF_OUT)
5597 0 : ret = pf_icmp_state_lookup(&pd2, &key, state,
5598 0 : virtual_id, virtual_type, icmp_dir, &iidx,
5599 : 1, 1);
5600 0 : if (ret >= 0)
5601 0 : return (ret);
5602 :
5603 : /* translate source/destination address, if necessary */
5604 0 : if ((*state)->key[PF_SK_WIRE] !=
5605 0 : (*state)->key[PF_SK_STACK]) {
5606 : struct pf_state_key *nk;
5607 : int afto, sidx, didx;
5608 :
5609 0 : if (PF_REVERSED_KEY((*state)->key, pd->af))
5610 0 : nk = (*state)->key[pd->sidx];
5611 : else
5612 0 : nk = (*state)->key[pd->didx];
5613 :
5614 0 : afto = pd->af != nk->af;
5615 0 : sidx = afto ? pd2.didx : pd2.sidx;
5616 0 : didx = afto ? pd2.sidx : pd2.didx;
5617 0 : iidx = afto ? !iidx : iidx;
5618 :
5619 0 : if (afto) {
5620 0 : if (nk->af != AF_INET)
5621 0 : return (PF_DROP);
5622 0 : if (pf_translate_icmp_af(pd, nk->af,
5623 0 : &pd->hdr.icmp))
5624 0 : return (PF_DROP);
5625 0 : m_copyback(pd->m, pd->off,
5626 : sizeof(struct icmp6_hdr),
5627 0 : &pd->hdr.icmp6, M_NOWAIT);
5628 0 : if (pf_change_icmp_af(pd->m, ipoff2,
5629 0 : pd, &pd2, &nk->addr[sidx],
5630 0 : &nk->addr[didx], pd->af, nk->af))
5631 0 : return (PF_DROP);
5632 0 : pd->proto = IPPROTO_ICMP;
5633 0 : if (pf_translate_icmp_af(pd,
5634 0 : nk->af, iih))
5635 0 : return (PF_DROP);
5636 0 : if (virtual_type ==
5637 : htons(ICMP6_ECHO_REQUEST))
5638 0 : pf_patch_16(pd, &iih->icmp6_id,
5639 0 : nk->port[iidx]);
5640 0 : m_copyback(pd2.m, pd2.off,
5641 : sizeof(struct icmp6_hdr), iih,
5642 : M_NOWAIT);
5643 0 : pd->m->m_pkthdr.ph_rtableid =
5644 0 : nk->rdomain;
5645 0 : pd->destchg = 1;
5646 0 : PF_ACPY(&pd->nsaddr,
5647 : &nk->addr[pd2.sidx], nk->af);
5648 0 : PF_ACPY(&pd->ndaddr,
5649 : &nk->addr[pd2.didx], nk->af);
5650 0 : pd->naf = nk->af;
5651 0 : return (PF_AFRT);
5652 : }
5653 :
5654 0 : if (PF_ANEQ(pd2.src,
5655 0 : &nk->addr[pd2.sidx], pd2.af) ||
5656 0 : ((virtual_type ==
5657 0 : htons(ICMP6_ECHO_REQUEST)) &&
5658 0 : nk->port[pd2.sidx] != iih->icmp6_id))
5659 0 : pf_translate_icmp(pd, pd2.src,
5660 0 : (virtual_type ==
5661 : htons(ICMP6_ECHO_REQUEST))
5662 0 : ? &iih->icmp6_id : NULL,
5663 0 : pd->dst, &nk->addr[pd2.sidx],
5664 0 : (virtual_type ==
5665 : htons(ICMP6_ECHO_REQUEST))
5666 0 : ? nk->port[iidx] : 0);
5667 :
5668 0 : if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
5669 0 : pd2.af) || pd2.rdomain != nk->rdomain)
5670 0 : pd->destchg = 1;
5671 0 : pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
5672 :
5673 0 : if (PF_ANEQ(pd2.dst,
5674 : &nk->addr[pd2.didx], pd2.af))
5675 0 : pf_translate_icmp(pd, pd2.dst, NULL,
5676 0 : pd->src, &nk->addr[pd2.didx], 0);
5677 :
5678 0 : m_copyback(pd->m, pd->off,
5679 0 : sizeof(struct icmp6_hdr), &pd->hdr.icmp6,
5680 : M_NOWAIT);
5681 0 : m_copyback(pd2.m, ipoff2, sizeof(h2_6), &h2_6,
5682 : M_NOWAIT);
5683 0 : m_copyback(pd2.m, pd2.off,
5684 : sizeof(struct icmp6_hdr), iih, M_NOWAIT);
5685 : copyback = 1;
5686 0 : }
5687 0 : break;
5688 : }
5689 : #endif /* INET6 */
5690 : default: {
5691 : int action;
5692 :
5693 0 : key.af = pd2.af;
5694 0 : key.proto = pd2.proto;
5695 0 : key.rdomain = pd2.rdomain;
5696 0 : PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
5697 0 : PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
5698 0 : key.port[0] = key.port[1] = 0;
5699 :
5700 0 : action = pf_find_state(&pd2, &key, state);
5701 0 : if (action != PF_MATCH)
5702 0 : return (action);
5703 :
5704 : /* translate source/destination address, if necessary */
5705 0 : if ((*state)->key[PF_SK_WIRE] !=
5706 0 : (*state)->key[PF_SK_STACK]) {
5707 : struct pf_state_key *nk =
5708 0 : (*state)->key[pd->didx];
5709 :
5710 0 : if (PF_ANEQ(pd2.src,
5711 : &nk->addr[pd2.sidx], pd2.af))
5712 0 : pf_translate_icmp(pd, pd2.src, NULL,
5713 0 : pd->dst, &nk->addr[pd2.sidx], 0);
5714 :
5715 0 : if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx],
5716 0 : pd2.af) || pd2.rdomain != nk->rdomain)
5717 0 : pd->destchg = 1;
5718 0 : pd->m->m_pkthdr.ph_rtableid = nk->rdomain;
5719 :
5720 0 : if (PF_ANEQ(pd2.dst,
5721 : &nk->addr[pd2.didx], pd2.af))
5722 0 : pf_translate_icmp(pd, pd2.dst, NULL,
5723 0 : pd->src, &nk->addr[pd2.didx], 0);
5724 :
5725 0 : switch (pd2.af) {
5726 : case AF_INET:
5727 0 : m_copyback(pd->m, pd->off, ICMP_MINLEN,
5728 0 : &pd->hdr.icmp, M_NOWAIT);
5729 0 : m_copyback(pd2.m, ipoff2, sizeof(h2),
5730 : &h2, M_NOWAIT);
5731 0 : break;
5732 : #ifdef INET6
5733 : case AF_INET6:
5734 0 : m_copyback(pd->m, pd->off,
5735 : sizeof(struct icmp6_hdr),
5736 0 : &pd->hdr.icmp6, M_NOWAIT);
5737 0 : m_copyback(pd2.m, ipoff2, sizeof(h2_6),
5738 : &h2_6, M_NOWAIT);
5739 0 : break;
5740 : #endif /* INET6 */
5741 : }
5742 : copyback = 1;
5743 0 : }
5744 0 : break;
5745 : }
5746 : }
5747 0 : }
5748 0 : if (copyback) {
5749 0 : m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
5750 0 : }
5751 :
5752 0 : return (PF_PASS);
5753 0 : }
5754 :
5755 : /*
5756 : * ipoff and off are measured from the start of the mbuf chain.
5757 : * h must be at "ipoff" on the mbuf chain.
5758 : */
5759 : void *
5760 0 : pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
5761 : u_short *actionp, u_short *reasonp, sa_family_t af)
5762 : {
5763 : int iplen = 0;
5764 :
5765 0 : switch (af) {
5766 : case AF_INET: {
5767 0 : struct ip *h = mtod(m, struct ip *);
5768 0 : u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
5769 :
5770 0 : if (fragoff) {
5771 0 : if (fragoff >= len)
5772 0 : ACTION_SET(actionp, PF_PASS);
5773 : else {
5774 0 : ACTION_SET(actionp, PF_DROP);
5775 0 : REASON_SET(reasonp, PFRES_FRAG);
5776 : }
5777 0 : return (NULL);
5778 : }
5779 0 : iplen = ntohs(h->ip_len);
5780 0 : break;
5781 : }
5782 : #ifdef INET6
5783 : case AF_INET6: {
5784 0 : struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
5785 :
5786 0 : iplen = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
5787 : break;
5788 : }
5789 : #endif /* INET6 */
5790 : }
5791 0 : if (m->m_pkthdr.len < off + len || iplen < off + len) {
5792 0 : ACTION_SET(actionp, PF_DROP);
5793 0 : REASON_SET(reasonp, PFRES_SHORT);
5794 0 : return (NULL);
5795 : }
5796 0 : m_copydata(m, off, len, p);
5797 0 : return (p);
5798 0 : }
5799 :
5800 : int
5801 0 : pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif,
5802 : int rtableid)
5803 : {
5804 0 : struct sockaddr_storage ss;
5805 : struct sockaddr_in *dst;
5806 : int ret = 1;
5807 : int check_mpath;
5808 : #ifdef INET6
5809 : struct sockaddr_in6 *dst6;
5810 : #endif /* INET6 */
5811 : struct rtentry *rt = NULL;
5812 :
5813 : check_mpath = 0;
5814 0 : memset(&ss, 0, sizeof(ss));
5815 0 : switch (af) {
5816 : case AF_INET:
5817 0 : dst = (struct sockaddr_in *)&ss;
5818 0 : dst->sin_family = AF_INET;
5819 0 : dst->sin_len = sizeof(*dst);
5820 0 : dst->sin_addr = addr->v4;
5821 0 : if (ipmultipath)
5822 0 : check_mpath = 1;
5823 : break;
5824 : #ifdef INET6
5825 : case AF_INET6:
5826 : /*
5827 : * Skip check for addresses with embedded interface scope,
5828 : * as they would always match anyway.
5829 : */
5830 0 : if (IN6_IS_SCOPE_EMBED(&addr->v6))
5831 : goto out;
5832 0 : dst6 = (struct sockaddr_in6 *)&ss;
5833 0 : dst6->sin6_family = AF_INET6;
5834 0 : dst6->sin6_len = sizeof(*dst6);
5835 0 : dst6->sin6_addr = addr->v6;
5836 0 : if (ip6_multipath)
5837 0 : check_mpath = 1;
5838 : break;
5839 : #endif /* INET6 */
5840 : }
5841 :
5842 : /* Skip checks for ipsec interfaces */
5843 0 : if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
5844 : goto out;
5845 :
5846 0 : rt = rtalloc(sstosa(&ss), 0, rtableid);
5847 0 : if (rt != NULL) {
5848 : /* No interface given, this is a no-route check */
5849 0 : if (kif == NULL)
5850 : goto out;
5851 :
5852 0 : if (kif->pfik_ifp == NULL) {
5853 : ret = 0;
5854 : goto out;
5855 : }
5856 :
5857 : /* Perform uRPF check if passed input interface */
5858 : ret = 0;
5859 0 : do {
5860 0 : if (rt->rt_ifidx == kif->pfik_ifp->if_index) {
5861 : ret = 1;
5862 : #if NCARP > 0
5863 0 : } else {
5864 : struct ifnet *ifp;
5865 :
5866 0 : ifp = if_get(rt->rt_ifidx);
5867 0 : if (ifp != NULL && ifp->if_type == IFT_CARP &&
5868 0 : ifp->if_carpdev == kif->pfik_ifp)
5869 0 : ret = 1;
5870 0 : if_put(ifp);
5871 : #endif /* NCARP */
5872 : }
5873 :
5874 0 : rt = rtable_iterate(rt);
5875 0 : } while (check_mpath == 1 && rt != NULL && ret == 0);
5876 : } else
5877 : ret = 0;
5878 : out:
5879 0 : rtfree(rt);
5880 0 : return (ret);
5881 0 : }
5882 :
5883 : int
5884 0 : pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw,
5885 : int rtableid)
5886 : {
5887 0 : struct sockaddr_storage ss;
5888 : struct sockaddr_in *dst;
5889 : #ifdef INET6
5890 : struct sockaddr_in6 *dst6;
5891 : #endif /* INET6 */
5892 : struct rtentry *rt;
5893 : int ret = 0;
5894 :
5895 0 : memset(&ss, 0, sizeof(ss));
5896 0 : switch (af) {
5897 : case AF_INET:
5898 0 : dst = (struct sockaddr_in *)&ss;
5899 0 : dst->sin_family = AF_INET;
5900 0 : dst->sin_len = sizeof(*dst);
5901 0 : dst->sin_addr = addr->v4;
5902 0 : break;
5903 : #ifdef INET6
5904 : case AF_INET6:
5905 0 : dst6 = (struct sockaddr_in6 *)&ss;
5906 0 : dst6->sin6_family = AF_INET6;
5907 0 : dst6->sin6_len = sizeof(*dst6);
5908 0 : dst6->sin6_addr = addr->v6;
5909 0 : break;
5910 : #endif /* INET6 */
5911 : }
5912 :
5913 0 : rt = rtalloc(sstosa(&ss), RT_RESOLVE, rtableid);
5914 0 : if (rt != NULL) {
5915 0 : if (rt->rt_labelid == aw->v.rtlabel)
5916 0 : ret = 1;
5917 0 : rtfree(rt);
5918 0 : }
5919 :
5920 0 : return (ret);
5921 0 : }
5922 :
5923 : /* pf_route() may change pd->m, adjust local copies after calling */
5924 : void
5925 0 : pf_route(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s)
5926 : {
5927 0 : struct mbuf *m0, *m1;
5928 0 : struct sockaddr_in *dst, sin;
5929 : struct rtentry *rt = NULL;
5930 : struct ip *ip;
5931 : struct ifnet *ifp = NULL;
5932 0 : struct pf_addr naddr;
5933 0 : struct pf_src_node *sns[PF_SN_MAX];
5934 : int error = 0;
5935 : unsigned int rtableid;
5936 :
5937 0 : if (pd->m->m_pkthdr.pf.routed++ > 3) {
5938 0 : m_freem(pd->m);
5939 0 : pd->m = NULL;
5940 0 : return;
5941 : }
5942 :
5943 0 : if (r->rt == PF_DUPTO) {
5944 0 : if ((m0 = m_dup_pkt(pd->m, max_linkhdr, M_NOWAIT)) == NULL)
5945 0 : return;
5946 : } else {
5947 0 : if ((r->rt == PF_REPLYTO) == (r->direction == pd->dir))
5948 0 : return;
5949 0 : m0 = pd->m;
5950 : }
5951 :
5952 0 : if (m0->m_len < sizeof(struct ip)) {
5953 0 : DPFPRINTF(LOG_ERR,
5954 : "%s: m0->m_len < sizeof(struct ip)", __func__);
5955 : goto bad;
5956 : }
5957 :
5958 0 : ip = mtod(m0, struct ip *);
5959 :
5960 0 : memset(&sin, 0, sizeof(sin));
5961 : dst = &sin;
5962 0 : dst->sin_family = AF_INET;
5963 0 : dst->sin_len = sizeof(*dst);
5964 0 : dst->sin_addr = ip->ip_dst;
5965 0 : rtableid = m0->m_pkthdr.ph_rtableid;
5966 :
5967 0 : if (pd->dir == PF_IN) {
5968 0 : if (ip->ip_ttl <= IPTTLDEC) {
5969 0 : if (r->rt != PF_DUPTO)
5970 0 : pf_send_icmp(m0, ICMP_TIMXCEED,
5971 : ICMP_TIMXCEED_INTRANS, 0,
5972 0 : pd->af, r, pd->rdomain);
5973 : goto bad;
5974 : }
5975 0 : ip->ip_ttl -= IPTTLDEC;
5976 0 : }
5977 :
5978 0 : if (s == NULL) {
5979 0 : memset(sns, 0, sizeof(sns));
5980 0 : if (pf_map_addr(AF_INET, r,
5981 0 : (struct pf_addr *)&ip->ip_src,
5982 0 : &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) {
5983 0 : DPFPRINTF(LOG_ERR,
5984 : "%s: pf_map_addr() failed", __func__);
5985 : goto bad;
5986 : }
5987 :
5988 0 : if (!PF_AZERO(&naddr, AF_INET))
5989 0 : dst->sin_addr.s_addr = naddr.v4.s_addr;
5990 0 : ifp = r->route.kif ?
5991 0 : r->route.kif->pfik_ifp : NULL;
5992 0 : } else {
5993 0 : if (!PF_AZERO(&s->rt_addr, AF_INET))
5994 0 : dst->sin_addr.s_addr =
5995 0 : s->rt_addr.v4.s_addr;
5996 0 : ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
5997 : }
5998 0 : if (ifp == NULL)
5999 : goto bad;
6000 :
6001 0 : if (pd->kif->pfik_ifp != ifp) {
6002 0 : if (pf_test(AF_INET, PF_OUT, ifp, &m0) != PF_PASS)
6003 : goto bad;
6004 0 : else if (m0 == NULL)
6005 : goto done;
6006 0 : if (m0->m_len < sizeof(struct ip)) {
6007 0 : DPFPRINTF(LOG_ERR,
6008 : "%s: m0->m_len < sizeof(struct ip)", __func__);
6009 : goto bad;
6010 : }
6011 0 : ip = mtod(m0, struct ip *);
6012 0 : }
6013 :
6014 0 : rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid);
6015 0 : if (!rtisvalid(rt)) {
6016 0 : ipstat_inc(ips_noroute);
6017 0 : goto bad;
6018 : }
6019 : /* A locally generated packet may have invalid source address. */
6020 0 : if ((ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
6021 0 : (ifp->if_flags & IFF_LOOPBACK) == 0)
6022 0 : ip->ip_src = ifatoia(rt->rt_ifa)->ia_addr.sin_addr;
6023 :
6024 0 : in_proto_cksum_out(m0, ifp);
6025 :
6026 0 : if (ntohs(ip->ip_len) <= ifp->if_mtu) {
6027 0 : ip->ip_sum = 0;
6028 0 : if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
6029 0 : m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
6030 : else {
6031 0 : ipstat_inc(ips_outswcsum);
6032 0 : ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
6033 : }
6034 0 : error = ifp->if_output(ifp, m0, sintosa(dst), rt);
6035 0 : goto done;
6036 : }
6037 :
6038 : /*
6039 : * Too large for interface; fragment if possible.
6040 : * Must be able to put at least 8 bytes per fragment.
6041 : */
6042 0 : if (ip->ip_off & htons(IP_DF)) {
6043 0 : ipstat_inc(ips_cantfrag);
6044 0 : if (r->rt != PF_DUPTO)
6045 0 : pf_send_icmp(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
6046 0 : ifp->if_mtu, pd->af, r, pd->rdomain);
6047 : goto bad;
6048 : }
6049 :
6050 0 : m1 = m0;
6051 0 : error = ip_fragment(m0, ifp, ifp->if_mtu);
6052 0 : if (error) {
6053 0 : m0 = NULL;
6054 0 : goto bad;
6055 : }
6056 :
6057 0 : for (m0 = m1; m0; m0 = m1) {
6058 0 : m1 = m0->m_nextpkt;
6059 0 : m0->m_nextpkt = 0;
6060 0 : if (error == 0)
6061 0 : error = ifp->if_output(ifp, m0, sintosa(dst), rt);
6062 : else
6063 0 : m_freem(m0);
6064 : }
6065 :
6066 0 : if (error == 0)
6067 0 : ipstat_inc(ips_fragmented);
6068 :
6069 : done:
6070 0 : if (r->rt != PF_DUPTO)
6071 0 : pd->m = NULL;
6072 0 : rtfree(rt);
6073 0 : return;
6074 :
6075 : bad:
6076 0 : m_freem(m0);
6077 0 : goto done;
6078 0 : }
6079 :
6080 : #ifdef INET6
6081 : /* pf_route6() may change pd->m, adjust local copies after calling */
6082 : void
6083 0 : pf_route6(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s)
6084 : {
6085 0 : struct mbuf *m0;
6086 0 : struct sockaddr_in6 *dst, sin6;
6087 : struct rtentry *rt = NULL;
6088 : struct ip6_hdr *ip6;
6089 : struct ifnet *ifp = NULL;
6090 0 : struct pf_addr naddr;
6091 0 : struct pf_src_node *sns[PF_SN_MAX];
6092 : struct m_tag *mtag;
6093 : unsigned int rtableid;
6094 :
6095 0 : if (pd->m->m_pkthdr.pf.routed++ > 3) {
6096 0 : m_freem(pd->m);
6097 0 : pd->m = NULL;
6098 0 : return;
6099 : }
6100 :
6101 0 : if (r->rt == PF_DUPTO) {
6102 0 : if ((m0 = m_dup_pkt(pd->m, max_linkhdr, M_NOWAIT)) == NULL)
6103 0 : return;
6104 : } else {
6105 0 : if ((r->rt == PF_REPLYTO) == (r->direction == pd->dir))
6106 0 : return;
6107 0 : m0 = pd->m;
6108 : }
6109 :
6110 0 : if (m0->m_len < sizeof(struct ip6_hdr)) {
6111 0 : DPFPRINTF(LOG_ERR,
6112 : "%s: m0->m_len < sizeof(struct ip6_hdr)", __func__);
6113 : goto bad;
6114 : }
6115 0 : ip6 = mtod(m0, struct ip6_hdr *);
6116 :
6117 0 : memset(&sin6, 0, sizeof(sin6));
6118 : dst = &sin6;
6119 0 : dst->sin6_family = AF_INET6;
6120 0 : dst->sin6_len = sizeof(*dst);
6121 0 : dst->sin6_addr = ip6->ip6_dst;
6122 0 : rtableid = m0->m_pkthdr.ph_rtableid;
6123 :
6124 0 : if (pd->dir == PF_IN) {
6125 0 : if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
6126 0 : if (r->rt != PF_DUPTO)
6127 0 : pf_send_icmp(m0, ICMP6_TIME_EXCEEDED,
6128 : ICMP6_TIME_EXCEED_TRANSIT, 0,
6129 0 : pd->af, r, pd->rdomain);
6130 : goto bad;
6131 : }
6132 0 : ip6->ip6_hlim -= IPV6_HLIMDEC;
6133 0 : }
6134 :
6135 0 : if (s == NULL) {
6136 0 : memset(sns, 0, sizeof(sns));
6137 0 : if (pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
6138 0 : &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) {
6139 0 : DPFPRINTF(LOG_ERR,
6140 : "%s: pf_map_addr() failed", __func__);
6141 : goto bad;
6142 : }
6143 0 : if (!PF_AZERO(&naddr, AF_INET6))
6144 0 : PF_ACPY((struct pf_addr *)&dst->sin6_addr,
6145 : &naddr, AF_INET6);
6146 0 : ifp = r->route.kif ? r->route.kif->pfik_ifp : NULL;
6147 0 : } else {
6148 0 : if (!PF_AZERO(&s->rt_addr, AF_INET6))
6149 0 : PF_ACPY((struct pf_addr *)&dst->sin6_addr,
6150 : &s->rt_addr, AF_INET6);
6151 0 : ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
6152 : }
6153 0 : if (ifp == NULL)
6154 : goto bad;
6155 :
6156 0 : if (pd->kif->pfik_ifp != ifp) {
6157 0 : if (pf_test(AF_INET6, PF_OUT, ifp, &m0) != PF_PASS)
6158 : goto bad;
6159 0 : else if (m0 == NULL)
6160 : goto done;
6161 0 : if (m0->m_len < sizeof(struct ip6_hdr)) {
6162 0 : DPFPRINTF(LOG_ERR,
6163 : "%s: m0->m_len < sizeof(struct ip6_hdr)", __func__);
6164 : goto bad;
6165 : }
6166 : }
6167 :
6168 0 : if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
6169 0 : dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
6170 0 : rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid);
6171 0 : if (!rtisvalid(rt)) {
6172 0 : ip6stat_inc(ip6s_noroute);
6173 0 : goto bad;
6174 : }
6175 : /* A locally generated packet may have invalid source address. */
6176 0 : if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) &&
6177 0 : (ifp->if_flags & IFF_LOOPBACK) == 0)
6178 0 : ip6->ip6_src = ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
6179 :
6180 0 : in6_proto_cksum_out(m0, ifp);
6181 :
6182 : /*
6183 : * If packet has been reassembled by PF earlier, we have to
6184 : * use pf_refragment6() here to turn it back to fragments.
6185 : */
6186 0 : if ((mtag = m_tag_find(m0, PACKET_TAG_PF_REASSEMBLED, NULL))) {
6187 0 : (void) pf_refragment6(&m0, mtag, dst, ifp, rt);
6188 0 : } else if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
6189 0 : ifp->if_output(ifp, m0, sin6tosa(dst), rt);
6190 : } else {
6191 0 : ip6stat_inc(ip6s_cantfrag);
6192 0 : if (r->rt != PF_DUPTO)
6193 0 : pf_send_icmp(m0, ICMP6_PACKET_TOO_BIG, 0,
6194 0 : ifp->if_mtu, pd->af, r, pd->rdomain);
6195 : goto bad;
6196 : }
6197 :
6198 : done:
6199 0 : if (r->rt != PF_DUPTO)
6200 0 : pd->m = NULL;
6201 0 : rtfree(rt);
6202 0 : return;
6203 :
6204 : bad:
6205 0 : m_freem(m0);
6206 0 : goto done;
6207 0 : }
6208 : #endif /* INET6 */
6209 :
6210 :
6211 : /*
6212 : * check TCP checksum and set mbuf flag
6213 : * off is the offset where the protocol header starts
6214 : * len is the total length of protocol header plus payload
6215 : * returns 0 when the checksum is valid, otherwise returns 1.
6216 : * if the _OUT flag is set the checksum isn't done yet, consider these ok
6217 : */
6218 : int
6219 0 : pf_check_tcp_cksum(struct mbuf *m, int off, int len, sa_family_t af)
6220 : {
6221 : u_int16_t sum;
6222 :
6223 0 : if (m->m_pkthdr.csum_flags &
6224 : (M_TCP_CSUM_IN_OK | M_TCP_CSUM_OUT)) {
6225 0 : return (0);
6226 : }
6227 0 : if (m->m_pkthdr.csum_flags & M_TCP_CSUM_IN_BAD ||
6228 0 : off < sizeof(struct ip) ||
6229 0 : m->m_pkthdr.len < off + len) {
6230 0 : return (1);
6231 : }
6232 :
6233 : /* need to do it in software */
6234 0 : tcpstat_inc(tcps_inswcsum);
6235 :
6236 0 : switch (af) {
6237 : case AF_INET:
6238 0 : if (m->m_len < sizeof(struct ip))
6239 0 : return (1);
6240 :
6241 0 : sum = in4_cksum(m, IPPROTO_TCP, off, len);
6242 0 : break;
6243 : #ifdef INET6
6244 : case AF_INET6:
6245 0 : if (m->m_len < sizeof(struct ip6_hdr))
6246 0 : return (1);
6247 :
6248 0 : sum = in6_cksum(m, IPPROTO_TCP, off, len);
6249 0 : break;
6250 : #endif /* INET6 */
6251 : default:
6252 0 : unhandled_af(af);
6253 : }
6254 0 : if (sum) {
6255 0 : tcpstat_inc(tcps_rcvbadsum);
6256 0 : m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_BAD;
6257 0 : return (1);
6258 : }
6259 :
6260 0 : m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK;
6261 0 : return (0);
6262 0 : }
6263 :
6264 : struct pf_divert *
6265 0 : pf_find_divert(struct mbuf *m)
6266 : {
6267 : struct m_tag *mtag;
6268 :
6269 0 : if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL)
6270 0 : return (NULL);
6271 :
6272 0 : return ((struct pf_divert *)(mtag + 1));
6273 0 : }
6274 :
6275 : struct pf_divert *
6276 0 : pf_get_divert(struct mbuf *m)
6277 : {
6278 : struct m_tag *mtag;
6279 :
6280 0 : if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) {
6281 0 : mtag = m_tag_get(PACKET_TAG_PF_DIVERT, sizeof(struct pf_divert),
6282 : M_NOWAIT);
6283 0 : if (mtag == NULL)
6284 0 : return (NULL);
6285 0 : memset(mtag + 1, 0, sizeof(struct pf_divert));
6286 0 : m_tag_prepend(m, mtag);
6287 0 : }
6288 :
6289 0 : return ((struct pf_divert *)(mtag + 1));
6290 0 : }
6291 :
6292 : int
6293 0 : pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
6294 : {
6295 0 : struct ip6_ext ext;
6296 : u_int32_t hlen, end;
6297 : int hdr_cnt;
6298 :
6299 0 : hlen = h->ip_hl << 2;
6300 0 : if (hlen < sizeof(struct ip) || hlen > ntohs(h->ip_len)) {
6301 0 : REASON_SET(reason, PFRES_SHORT);
6302 0 : return (PF_DROP);
6303 : }
6304 0 : if (hlen != sizeof(struct ip))
6305 0 : pd->badopts++;
6306 0 : end = pd->off + ntohs(h->ip_len);
6307 0 : pd->off += hlen;
6308 0 : pd->proto = h->ip_p;
6309 : /* stop walking over non initial fragments */
6310 0 : if ((h->ip_off & htons(IP_OFFMASK)) != 0)
6311 0 : return (PF_PASS);
6312 :
6313 0 : for (hdr_cnt = 0; hdr_cnt < pf_hdr_limit; hdr_cnt++) {
6314 0 : switch (pd->proto) {
6315 : case IPPROTO_AH:
6316 : /* fragments may be short */
6317 0 : if ((h->ip_off & htons(IP_MF | IP_OFFMASK)) != 0 &&
6318 0 : end < pd->off + sizeof(ext))
6319 0 : return (PF_PASS);
6320 0 : if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext),
6321 : NULL, reason, AF_INET)) {
6322 0 : DPFPRINTF(LOG_NOTICE, "IP short exthdr");
6323 0 : return (PF_DROP);
6324 : }
6325 0 : pd->off += (ext.ip6e_len + 2) * 4;
6326 0 : pd->proto = ext.ip6e_nxt;
6327 : break;
6328 : default:
6329 0 : return (PF_PASS);
6330 : }
6331 : }
6332 0 : DPFPRINTF(LOG_NOTICE, "IPv4 nested authentication header limit");
6333 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6334 0 : return (PF_DROP);
6335 0 : }
6336 :
6337 : #ifdef INET6
6338 : int
6339 0 : pf_walk_option6(struct pf_pdesc *pd, struct ip6_hdr *h, int off, int end,
6340 : u_short *reason)
6341 : {
6342 0 : struct ip6_opt opt;
6343 0 : struct ip6_opt_jumbo jumbo;
6344 :
6345 0 : while (off < end) {
6346 0 : if (!pf_pull_hdr(pd->m, off, &opt.ip6o_type,
6347 : sizeof(opt.ip6o_type), NULL, reason, AF_INET6)) {
6348 0 : DPFPRINTF(LOG_NOTICE, "IPv6 short opt type");
6349 0 : return (PF_DROP);
6350 : }
6351 0 : if (opt.ip6o_type == IP6OPT_PAD1) {
6352 0 : off++;
6353 0 : continue;
6354 : }
6355 0 : if (!pf_pull_hdr(pd->m, off, &opt, sizeof(opt),
6356 : NULL, reason, AF_INET6)) {
6357 0 : DPFPRINTF(LOG_NOTICE, "IPv6 short opt");
6358 0 : return (PF_DROP);
6359 : }
6360 0 : if (off + sizeof(opt) + opt.ip6o_len > end) {
6361 0 : DPFPRINTF(LOG_NOTICE, "IPv6 long opt");
6362 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6363 0 : return (PF_DROP);
6364 : }
6365 0 : switch (opt.ip6o_type) {
6366 : case IP6OPT_JUMBO:
6367 0 : if (pd->jumbolen != 0) {
6368 0 : DPFPRINTF(LOG_NOTICE, "IPv6 multiple jumbo");
6369 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6370 0 : return (PF_DROP);
6371 : }
6372 0 : if (ntohs(h->ip6_plen) != 0) {
6373 0 : DPFPRINTF(LOG_NOTICE, "IPv6 bad jumbo plen");
6374 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6375 0 : return (PF_DROP);
6376 : }
6377 0 : if (!pf_pull_hdr(pd->m, off, &jumbo, sizeof(jumbo),
6378 : NULL, reason, AF_INET6)) {
6379 0 : DPFPRINTF(LOG_NOTICE, "IPv6 short jumbo");
6380 0 : return (PF_DROP);
6381 : }
6382 0 : memcpy(&pd->jumbolen, jumbo.ip6oj_jumbo_len,
6383 : sizeof(pd->jumbolen));
6384 0 : pd->jumbolen = ntohl(pd->jumbolen);
6385 0 : if (pd->jumbolen < IPV6_MAXPACKET) {
6386 0 : DPFPRINTF(LOG_NOTICE, "IPv6 short jumbolen");
6387 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6388 0 : return (PF_DROP);
6389 : }
6390 : break;
6391 : default:
6392 : break;
6393 : }
6394 0 : off += sizeof(opt) + opt.ip6o_len;
6395 : }
6396 :
6397 0 : return (PF_PASS);
6398 0 : }
6399 :
6400 : int
6401 0 : pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
6402 : {
6403 0 : struct ip6_frag frag;
6404 0 : struct ip6_ext ext;
6405 0 : struct ip6_rthdr rthdr;
6406 : u_int32_t end;
6407 : int hdr_cnt, fraghdr_cnt = 0, rthdr_cnt = 0;
6408 :
6409 0 : pd->off += sizeof(struct ip6_hdr);
6410 0 : end = pd->off + ntohs(h->ip6_plen);
6411 0 : pd->fragoff = pd->extoff = pd->jumbolen = 0;
6412 0 : pd->proto = h->ip6_nxt;
6413 :
6414 0 : for (hdr_cnt = 0; hdr_cnt < pf_hdr_limit; hdr_cnt++) {
6415 0 : switch (pd->proto) {
6416 : case IPPROTO_ROUTING:
6417 : case IPPROTO_HOPOPTS:
6418 : case IPPROTO_DSTOPTS:
6419 0 : pd->badopts++;
6420 0 : break;
6421 : }
6422 0 : switch (pd->proto) {
6423 : case IPPROTO_FRAGMENT:
6424 0 : if (fraghdr_cnt++) {
6425 0 : DPFPRINTF(LOG_NOTICE, "IPv6 multiple fragment");
6426 0 : REASON_SET(reason, PFRES_FRAG);
6427 0 : return (PF_DROP);
6428 : }
6429 : /* jumbo payload packets cannot be fragmented */
6430 0 : if (pd->jumbolen != 0) {
6431 0 : DPFPRINTF(LOG_NOTICE, "IPv6 fragmented jumbo");
6432 0 : REASON_SET(reason, PFRES_FRAG);
6433 0 : return (PF_DROP);
6434 : }
6435 0 : if (!pf_pull_hdr(pd->m, pd->off, &frag, sizeof(frag),
6436 : NULL, reason, AF_INET6)) {
6437 0 : DPFPRINTF(LOG_NOTICE, "IPv6 short fragment");
6438 0 : return (PF_DROP);
6439 : }
6440 : /* stop walking over non initial fragments */
6441 0 : if (ntohs((frag.ip6f_offlg & IP6F_OFF_MASK)) != 0) {
6442 0 : pd->fragoff = pd->off;
6443 0 : return (PF_PASS);
6444 : }
6445 : /* RFC6946: reassemble only non atomic fragments */
6446 0 : if (frag.ip6f_offlg & IP6F_MORE_FRAG)
6447 0 : pd->fragoff = pd->off;
6448 0 : pd->off += sizeof(frag);
6449 0 : pd->proto = frag.ip6f_nxt;
6450 0 : break;
6451 : case IPPROTO_ROUTING:
6452 0 : if (rthdr_cnt++) {
6453 0 : DPFPRINTF(LOG_NOTICE, "IPv6 multiple rthdr");
6454 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6455 0 : return (PF_DROP);
6456 : }
6457 : /* fragments may be short */
6458 0 : if (pd->fragoff != 0 && end < pd->off + sizeof(rthdr)) {
6459 0 : pd->off = pd->fragoff;
6460 0 : pd->proto = IPPROTO_FRAGMENT;
6461 0 : return (PF_PASS);
6462 : }
6463 0 : if (!pf_pull_hdr(pd->m, pd->off, &rthdr, sizeof(rthdr),
6464 : NULL, reason, AF_INET6)) {
6465 0 : DPFPRINTF(LOG_NOTICE, "IPv6 short rthdr");
6466 0 : return (PF_DROP);
6467 : }
6468 0 : if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
6469 0 : DPFPRINTF(LOG_NOTICE, "IPv6 rthdr0");
6470 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6471 0 : return (PF_DROP);
6472 : }
6473 : /* FALLTHROUGH */
6474 : case IPPROTO_HOPOPTS:
6475 : /* RFC2460 4.1: Hop-by-Hop only after IPv6 header */
6476 0 : if (pd->proto == IPPROTO_HOPOPTS && hdr_cnt > 0) {
6477 0 : DPFPRINTF(LOG_NOTICE, "IPv6 hopopts not first");
6478 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6479 0 : return (PF_DROP);
6480 : }
6481 : /* FALLTHROUGH */
6482 : case IPPROTO_AH:
6483 : case IPPROTO_DSTOPTS:
6484 : /* fragments may be short */
6485 0 : if (pd->fragoff != 0 && end < pd->off + sizeof(ext)) {
6486 0 : pd->off = pd->fragoff;
6487 0 : pd->proto = IPPROTO_FRAGMENT;
6488 0 : return (PF_PASS);
6489 : }
6490 0 : if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext),
6491 : NULL, reason, AF_INET6)) {
6492 0 : DPFPRINTF(LOG_NOTICE, "IPv6 short exthdr");
6493 0 : return (PF_DROP);
6494 : }
6495 : /* reassembly needs the ext header before the frag */
6496 0 : if (pd->fragoff == 0)
6497 0 : pd->extoff = pd->off;
6498 0 : if (pd->proto == IPPROTO_HOPOPTS && pd->fragoff == 0) {
6499 0 : if (pf_walk_option6(pd, h,
6500 0 : pd->off + sizeof(ext),
6501 0 : pd->off + (ext.ip6e_len + 1) * 8, reason)
6502 0 : != PF_PASS)
6503 0 : return (PF_DROP);
6504 0 : if (ntohs(h->ip6_plen) == 0 &&
6505 0 : pd->jumbolen != 0) {
6506 0 : DPFPRINTF(LOG_NOTICE,
6507 : "IPv6 missing jumbo");
6508 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6509 0 : return (PF_DROP);
6510 : }
6511 : }
6512 0 : if (pd->proto == IPPROTO_AH)
6513 0 : pd->off += (ext.ip6e_len + 2) * 4;
6514 : else
6515 0 : pd->off += (ext.ip6e_len + 1) * 8;
6516 0 : pd->proto = ext.ip6e_nxt;
6517 0 : break;
6518 : case IPPROTO_TCP:
6519 : case IPPROTO_UDP:
6520 : case IPPROTO_ICMPV6:
6521 : /* fragments may be short, ignore inner header then */
6522 0 : if (pd->fragoff != 0 && end < pd->off +
6523 0 : (pd->proto == IPPROTO_TCP ? sizeof(struct tcphdr) :
6524 0 : pd->proto == IPPROTO_UDP ? sizeof(struct udphdr) :
6525 : sizeof(struct icmp6_hdr))) {
6526 0 : pd->off = pd->fragoff;
6527 0 : pd->proto = IPPROTO_FRAGMENT;
6528 0 : }
6529 : /* FALLTHROUGH */
6530 : default:
6531 0 : return (PF_PASS);
6532 : }
6533 : }
6534 0 : DPFPRINTF(LOG_NOTICE, "IPv6 nested extension header limit");
6535 0 : REASON_SET(reason, PFRES_IPOPTIONS);
6536 0 : return (PF_DROP);
6537 0 : }
6538 : #endif /* INET6 */
6539 :
6540 : int
6541 0 : pf_setup_pdesc(struct pf_pdesc *pd, sa_family_t af, int dir,
6542 : struct pfi_kif *kif, struct mbuf *m, u_short *reason)
6543 : {
6544 0 : memset(pd, 0, sizeof(*pd));
6545 0 : pd->dir = dir;
6546 0 : pd->kif = kif; /* kif is NULL when called by pflog */
6547 0 : pd->m = m;
6548 0 : pd->sidx = (dir == PF_IN) ? 0 : 1;
6549 0 : pd->didx = (dir == PF_IN) ? 1 : 0;
6550 0 : pd->af = pd->naf = af;
6551 0 : pd->rdomain = rtable_l2(pd->m->m_pkthdr.ph_rtableid);
6552 :
6553 0 : switch (pd->af) {
6554 : case AF_INET: {
6555 : struct ip *h;
6556 :
6557 : /* Check for illegal packets */
6558 0 : if (pd->m->m_pkthdr.len < (int)sizeof(struct ip)) {
6559 0 : REASON_SET(reason, PFRES_SHORT);
6560 0 : return (PF_DROP);
6561 : }
6562 :
6563 0 : h = mtod(pd->m, struct ip *);
6564 0 : if (pd->m->m_pkthdr.len < ntohs(h->ip_len)) {
6565 0 : REASON_SET(reason, PFRES_SHORT);
6566 0 : return (PF_DROP);
6567 : }
6568 :
6569 0 : if (pf_walk_header(pd, h, reason) != PF_PASS)
6570 0 : return (PF_DROP);
6571 :
6572 0 : pd->src = (struct pf_addr *)&h->ip_src;
6573 0 : pd->dst = (struct pf_addr *)&h->ip_dst;
6574 0 : pd->tot_len = ntohs(h->ip_len);
6575 0 : pd->tos = h->ip_tos & ~IPTOS_ECN_MASK;
6576 0 : pd->ttl = h->ip_ttl;
6577 0 : pd->virtual_proto = (h->ip_off & htons(IP_MF | IP_OFFMASK)) ?
6578 0 : PF_VPROTO_FRAGMENT : pd->proto;
6579 :
6580 0 : break;
6581 : }
6582 : #ifdef INET6
6583 : case AF_INET6: {
6584 : struct ip6_hdr *h;
6585 :
6586 : /* Check for illegal packets */
6587 0 : if (pd->m->m_pkthdr.len < (int)sizeof(struct ip6_hdr)) {
6588 0 : REASON_SET(reason, PFRES_SHORT);
6589 0 : return (PF_DROP);
6590 : }
6591 :
6592 0 : h = mtod(pd->m, struct ip6_hdr *);
6593 0 : if (pd->m->m_pkthdr.len <
6594 0 : sizeof(struct ip6_hdr) + ntohs(h->ip6_plen)) {
6595 0 : REASON_SET(reason, PFRES_SHORT);
6596 0 : return (PF_DROP);
6597 : }
6598 :
6599 0 : if (pf_walk_header6(pd, h, reason) != PF_PASS)
6600 0 : return (PF_DROP);
6601 :
6602 : #if 1
6603 : /*
6604 : * we do not support jumbogram yet. if we keep going, zero
6605 : * ip6_plen will do something bad, so drop the packet for now.
6606 : */
6607 0 : if (pd->jumbolen != 0) {
6608 0 : REASON_SET(reason, PFRES_NORM);
6609 0 : return (PF_DROP);
6610 : }
6611 : #endif /* 1 */
6612 :
6613 0 : pd->src = (struct pf_addr *)&h->ip6_src;
6614 0 : pd->dst = (struct pf_addr *)&h->ip6_dst;
6615 0 : pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
6616 0 : pd->tos = (ntohl(h->ip6_flow) & 0x0fc00000) >> 20;
6617 0 : pd->ttl = h->ip6_hlim;
6618 0 : pd->virtual_proto = (pd->fragoff != 0) ?
6619 0 : PF_VPROTO_FRAGMENT : pd->proto;
6620 :
6621 0 : break;
6622 : }
6623 : #endif /* INET6 */
6624 : default:
6625 0 : panic("pf_setup_pdesc called with illegal af %u", pd->af);
6626 :
6627 : }
6628 :
6629 0 : PF_ACPY(&pd->nsaddr, pd->src, pd->af);
6630 0 : PF_ACPY(&pd->ndaddr, pd->dst, pd->af);
6631 :
6632 0 : switch (pd->virtual_proto) {
6633 : case IPPROTO_TCP: {
6634 0 : struct tcphdr *th = &pd->hdr.tcp;
6635 :
6636 0 : if (!pf_pull_hdr(pd->m, pd->off, th, sizeof(*th),
6637 0 : NULL, reason, pd->af))
6638 0 : return (PF_DROP);
6639 0 : pd->hdrlen = sizeof(*th);
6640 0 : if (pd->off + (th->th_off << 2) > pd->tot_len ||
6641 0 : (th->th_off << 2) < sizeof(struct tcphdr)) {
6642 0 : REASON_SET(reason, PFRES_SHORT);
6643 0 : return (PF_DROP);
6644 : }
6645 0 : pd->p_len = pd->tot_len - pd->off - (th->th_off << 2);
6646 0 : pd->sport = &th->th_sport;
6647 0 : pd->dport = &th->th_dport;
6648 0 : pd->pcksum = &th->th_sum;
6649 0 : break;
6650 : }
6651 : case IPPROTO_UDP: {
6652 0 : struct udphdr *uh = &pd->hdr.udp;
6653 :
6654 0 : if (!pf_pull_hdr(pd->m, pd->off, uh, sizeof(*uh),
6655 0 : NULL, reason, pd->af))
6656 0 : return (PF_DROP);
6657 0 : pd->hdrlen = sizeof(*uh);
6658 0 : if (uh->uh_dport == 0 ||
6659 0 : pd->off + ntohs(uh->uh_ulen) > pd->tot_len ||
6660 0 : ntohs(uh->uh_ulen) < sizeof(struct udphdr)) {
6661 0 : REASON_SET(reason, PFRES_SHORT);
6662 0 : return (PF_DROP);
6663 : }
6664 0 : pd->sport = &uh->uh_sport;
6665 0 : pd->dport = &uh->uh_dport;
6666 0 : pd->pcksum = &uh->uh_sum;
6667 0 : break;
6668 : }
6669 : case IPPROTO_ICMP: {
6670 0 : if (!pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp, ICMP_MINLEN,
6671 0 : NULL, reason, pd->af))
6672 0 : return (PF_DROP);
6673 0 : pd->hdrlen = ICMP_MINLEN;
6674 0 : if (pd->off + pd->hdrlen > pd->tot_len) {
6675 0 : REASON_SET(reason, PFRES_SHORT);
6676 0 : return (PF_DROP);
6677 : }
6678 0 : pd->pcksum = &pd->hdr.icmp.icmp_cksum;
6679 0 : break;
6680 : }
6681 : #ifdef INET6
6682 : case IPPROTO_ICMPV6: {
6683 : size_t icmp_hlen = sizeof(struct icmp6_hdr);
6684 :
6685 0 : if (!pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp6, icmp_hlen,
6686 0 : NULL, reason, pd->af))
6687 0 : return (PF_DROP);
6688 : /* ICMP headers we look further into to match state */
6689 0 : switch (pd->hdr.icmp6.icmp6_type) {
6690 : case MLD_LISTENER_QUERY:
6691 : case MLD_LISTENER_REPORT:
6692 : icmp_hlen = sizeof(struct mld_hdr);
6693 0 : break;
6694 : case ND_NEIGHBOR_SOLICIT:
6695 : case ND_NEIGHBOR_ADVERT:
6696 0 : icmp_hlen = sizeof(struct nd_neighbor_solicit);
6697 : /* FALLTHROUGH */
6698 : case ND_ROUTER_SOLICIT:
6699 : case ND_ROUTER_ADVERT:
6700 : case ND_REDIRECT:
6701 0 : if (pd->ttl != 255) {
6702 0 : REASON_SET(reason, PFRES_NORM);
6703 0 : return (PF_DROP);
6704 : }
6705 : break;
6706 : }
6707 0 : if (icmp_hlen > sizeof(struct icmp6_hdr) &&
6708 0 : !pf_pull_hdr(pd->m, pd->off, &pd->hdr.icmp6, icmp_hlen,
6709 0 : NULL, reason, pd->af))
6710 0 : return (PF_DROP);
6711 0 : pd->hdrlen = icmp_hlen;
6712 0 : if (pd->off + pd->hdrlen > pd->tot_len) {
6713 0 : REASON_SET(reason, PFRES_SHORT);
6714 0 : return (PF_DROP);
6715 : }
6716 0 : pd->pcksum = &pd->hdr.icmp6.icmp6_cksum;
6717 0 : break;
6718 : }
6719 : #endif /* INET6 */
6720 : }
6721 :
6722 0 : if (pd->sport)
6723 0 : pd->osport = pd->nsport = *pd->sport;
6724 0 : if (pd->dport)
6725 0 : pd->odport = pd->ndport = *pd->dport;
6726 :
6727 0 : return (PF_PASS);
6728 0 : }
6729 :
6730 : void
6731 0 : pf_counters_inc(int action, struct pf_pdesc *pd, struct pf_state *s,
6732 : struct pf_rule *r, struct pf_rule *a)
6733 : {
6734 : int dirndx;
6735 0 : pd->kif->pfik_bytes[pd->af == AF_INET6][pd->dir == PF_OUT]
6736 0 : [action != PF_PASS] += pd->tot_len;
6737 0 : pd->kif->pfik_packets[pd->af == AF_INET6][pd->dir == PF_OUT]
6738 0 : [action != PF_PASS]++;
6739 :
6740 0 : if (action == PF_PASS || action == PF_AFRT || r->action == PF_DROP) {
6741 0 : dirndx = (pd->dir == PF_OUT);
6742 0 : r->packets[dirndx]++;
6743 0 : r->bytes[dirndx] += pd->tot_len;
6744 0 : if (a != NULL) {
6745 0 : a->packets[dirndx]++;
6746 0 : a->bytes[dirndx] += pd->tot_len;
6747 0 : }
6748 0 : if (s != NULL) {
6749 : struct pf_rule_item *ri;
6750 : struct pf_sn_item *sni;
6751 :
6752 0 : SLIST_FOREACH(sni, &s->src_nodes, next) {
6753 0 : sni->sn->packets[dirndx]++;
6754 0 : sni->sn->bytes[dirndx] += pd->tot_len;
6755 : }
6756 0 : dirndx = (pd->dir == s->direction) ? 0 : 1;
6757 0 : s->packets[dirndx]++;
6758 0 : s->bytes[dirndx] += pd->tot_len;
6759 :
6760 0 : SLIST_FOREACH(ri, &s->match_rules, entry) {
6761 0 : ri->r->packets[dirndx]++;
6762 0 : ri->r->bytes[dirndx] += pd->tot_len;
6763 :
6764 0 : if (ri->r->src.addr.type == PF_ADDR_TABLE)
6765 0 : pfr_update_stats(ri->r->src.addr.p.tbl,
6766 0 : &s->key[(s->direction == PF_IN)]->
6767 0 : addr[(s->direction == PF_OUT)],
6768 0 : pd, ri->r->action, ri->r->src.neg);
6769 0 : if (ri->r->dst.addr.type == PF_ADDR_TABLE)
6770 0 : pfr_update_stats(ri->r->dst.addr.p.tbl,
6771 0 : &s->key[(s->direction == PF_IN)]->
6772 0 : addr[(s->direction == PF_IN)],
6773 0 : pd, ri->r->action, ri->r->dst.neg);
6774 : }
6775 0 : }
6776 0 : if (r->src.addr.type == PF_ADDR_TABLE)
6777 0 : pfr_update_stats(r->src.addr.p.tbl,
6778 0 : (s == NULL) ? pd->src :
6779 0 : &s->key[(s->direction == PF_IN)]->
6780 0 : addr[(s->direction == PF_OUT)],
6781 0 : pd, r->action, r->src.neg);
6782 0 : if (r->dst.addr.type == PF_ADDR_TABLE)
6783 0 : pfr_update_stats(r->dst.addr.p.tbl,
6784 0 : (s == NULL) ? pd->dst :
6785 0 : &s->key[(s->direction == PF_IN)]->
6786 0 : addr[(s->direction == PF_IN)],
6787 0 : pd, r->action, r->dst.neg);
6788 : }
6789 0 : }
6790 :
6791 : int
6792 0 : pf_test(sa_family_t af, int fwdir, struct ifnet *ifp, struct mbuf **m0)
6793 : {
6794 : struct pfi_kif *kif;
6795 0 : u_short action, reason = 0;
6796 0 : struct pf_rule *a = NULL, *r = &pf_default_rule;
6797 0 : struct pf_state *s = NULL;
6798 0 : struct pf_ruleset *ruleset = NULL;
6799 0 : struct pf_pdesc pd;
6800 0 : int dir = (fwdir == PF_FWD) ? PF_OUT : fwdir;
6801 : u_int32_t qid, pqid = 0;
6802 0 : int have_pf_lock = 0;
6803 :
6804 0 : if (!pf_status.running)
6805 0 : return (PF_PASS);
6806 :
6807 : #if NCARP > 0
6808 0 : if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
6809 0 : kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
6810 : else
6811 : #endif /* NCARP */
6812 0 : kif = (struct pfi_kif *)ifp->if_pf_kif;
6813 :
6814 0 : if (kif == NULL) {
6815 0 : DPFPRINTF(LOG_ERR,
6816 : "%s: kif == NULL, if_xname %s", __func__, ifp->if_xname);
6817 0 : return (PF_DROP);
6818 : }
6819 0 : if (kif->pfik_flags & PFI_IFLAG_SKIP)
6820 0 : return (PF_PASS);
6821 :
6822 : #ifdef DIAGNOSTIC
6823 0 : if (((*m0)->m_flags & M_PKTHDR) == 0)
6824 0 : panic("non-M_PKTHDR is passed to pf_test");
6825 : #endif /* DIAGNOSTIC */
6826 :
6827 0 : if ((*m0)->m_pkthdr.pf.flags & PF_TAG_GENERATED)
6828 0 : return (PF_PASS);
6829 :
6830 0 : if ((*m0)->m_pkthdr.pf.flags & PF_TAG_DIVERTED_PACKET)
6831 0 : return (PF_PASS);
6832 :
6833 0 : if ((*m0)->m_pkthdr.pf.flags & PF_TAG_REFRAGMENTED) {
6834 0 : (*m0)->m_pkthdr.pf.flags &= ~PF_TAG_REFRAGMENTED;
6835 0 : return (PF_PASS);
6836 : }
6837 :
6838 0 : action = pf_setup_pdesc(&pd, af, dir, kif, *m0, &reason);
6839 0 : if (action != PF_PASS) {
6840 : #if NPFLOG > 0
6841 0 : pd.pflog |= PF_LOG_FORCE;
6842 : #endif /* NPFLOG > 0 */
6843 0 : goto done;
6844 : }
6845 :
6846 : /* packet normalization and reassembly */
6847 0 : switch (pd.af) {
6848 : case AF_INET:
6849 0 : action = pf_normalize_ip(&pd, &reason);
6850 0 : break;
6851 : #ifdef INET6
6852 : case AF_INET6:
6853 0 : action = pf_normalize_ip6(&pd, &reason);
6854 0 : break;
6855 : #endif /* INET6 */
6856 : }
6857 0 : *m0 = pd.m;
6858 : /* if packet sits in reassembly queue, return without error */
6859 0 : if (pd.m == NULL)
6860 0 : return PF_PASS;
6861 :
6862 0 : if (action != PF_PASS) {
6863 : #if NPFLOG > 0
6864 0 : pd.pflog |= PF_LOG_FORCE;
6865 : #endif /* NPFLOG > 0 */
6866 0 : goto done;
6867 : }
6868 :
6869 : /* if packet has been reassembled, update packet description */
6870 0 : if (pf_status.reass && pd.virtual_proto == PF_VPROTO_FRAGMENT) {
6871 0 : action = pf_setup_pdesc(&pd, af, dir, kif, pd.m, &reason);
6872 0 : if (action != PF_PASS) {
6873 : #if NPFLOG > 0
6874 0 : pd.pflog |= PF_LOG_FORCE;
6875 : #endif /* NPFLOG > 0 */
6876 0 : goto done;
6877 : }
6878 : }
6879 0 : pd.m->m_pkthdr.pf.flags |= PF_TAG_PROCESSED;
6880 :
6881 : /*
6882 : * Avoid pcb-lookups from the forwarding path. They should never
6883 : * match and would cause MP locking problems.
6884 : */
6885 0 : if (fwdir == PF_FWD) {
6886 0 : pd.lookup.done = -1;
6887 0 : pd.lookup.uid = UID_MAX;
6888 0 : pd.lookup.gid = GID_MAX;
6889 0 : pd.lookup.pid = NO_PID;
6890 0 : }
6891 :
6892 0 : switch (pd.virtual_proto) {
6893 :
6894 : case PF_VPROTO_FRAGMENT: {
6895 : /*
6896 : * handle fragments that aren't reassembled by
6897 : * normalization
6898 : */
6899 : PF_LOCK();
6900 0 : have_pf_lock = 1;
6901 0 : action = pf_test_rule(&pd, &r, &s, &a, &ruleset, &reason);
6902 0 : s = pf_state_ref(s);
6903 0 : if (action != PF_PASS)
6904 0 : REASON_SET(&reason, PFRES_FRAG);
6905 : break;
6906 : }
6907 :
6908 : case IPPROTO_ICMP: {
6909 0 : if (pd.af != AF_INET) {
6910 : action = PF_DROP;
6911 0 : REASON_SET(&reason, PFRES_NORM);
6912 0 : DPFPRINTF(LOG_NOTICE,
6913 : "dropping IPv6 packet with ICMPv4 payload");
6914 : break;
6915 : }
6916 : PF_STATE_ENTER_READ();
6917 0 : action = pf_test_state_icmp(&pd, &s, &reason);
6918 0 : s = pf_state_ref(s);
6919 : PF_STATE_EXIT_READ();
6920 0 : if (action == PF_PASS || action == PF_AFRT) {
6921 : #if NPFSYNC > 0
6922 0 : pfsync_update_state(s, &have_pf_lock);
6923 : #endif /* NPFSYNC > 0 */
6924 0 : r = s->rule.ptr;
6925 0 : a = s->anchor.ptr;
6926 : #if NPFLOG > 0
6927 0 : pd.pflog |= s->log;
6928 : #endif /* NPFLOG > 0 */
6929 0 : } else if (s == NULL) {
6930 : PF_LOCK();
6931 0 : have_pf_lock = 1;
6932 0 : action = pf_test_rule(&pd, &r, &s, &a, &ruleset,
6933 : &reason);
6934 0 : s = pf_state_ref(s);
6935 0 : }
6936 : break;
6937 : }
6938 :
6939 : #ifdef INET6
6940 : case IPPROTO_ICMPV6: {
6941 0 : if (pd.af != AF_INET6) {
6942 : action = PF_DROP;
6943 0 : REASON_SET(&reason, PFRES_NORM);
6944 0 : DPFPRINTF(LOG_NOTICE,
6945 : "dropping IPv4 packet with ICMPv6 payload");
6946 : break;
6947 : }
6948 : PF_STATE_ENTER_READ();
6949 0 : action = pf_test_state_icmp(&pd, &s, &reason);
6950 0 : s = pf_state_ref(s);
6951 : PF_STATE_EXIT_READ();
6952 0 : if (action == PF_PASS || action == PF_AFRT) {
6953 : #if NPFSYNC > 0
6954 0 : pfsync_update_state(s, &have_pf_lock);
6955 : #endif /* NPFSYNC > 0 */
6956 0 : r = s->rule.ptr;
6957 0 : a = s->anchor.ptr;
6958 : #if NPFLOG > 0
6959 0 : pd.pflog |= s->log;
6960 : #endif /* NPFLOG > 0 */
6961 0 : } else if (s == NULL) {
6962 : PF_LOCK();
6963 0 : have_pf_lock = 1;
6964 0 : action = pf_test_rule(&pd, &r, &s, &a, &ruleset,
6965 : &reason);
6966 0 : s = pf_state_ref(s);
6967 0 : }
6968 : break;
6969 : }
6970 : #endif /* INET6 */
6971 :
6972 : default:
6973 0 : if (pd.virtual_proto == IPPROTO_TCP) {
6974 0 : if (pd.dir == PF_IN && (pd.hdr.tcp.th_flags &
6975 0 : (TH_SYN|TH_ACK)) == TH_SYN &&
6976 0 : pf_synflood_check(&pd)) {
6977 : PF_LOCK();
6978 0 : have_pf_lock = 1;
6979 0 : pf_syncookie_send(&pd);
6980 : action = PF_DROP;
6981 0 : break;
6982 : }
6983 0 : if ((pd.hdr.tcp.th_flags & TH_ACK) && pd.p_len == 0)
6984 0 : pqid = 1;
6985 0 : action = pf_normalize_tcp(&pd);
6986 0 : if (action == PF_DROP)
6987 : break;
6988 : }
6989 : PF_STATE_ENTER_READ();
6990 0 : action = pf_test_state(&pd, &s, &reason, 0);
6991 0 : s = pf_state_ref(s);
6992 : PF_STATE_EXIT_READ();
6993 0 : if (s == NULL && action != PF_PASS && action != PF_AFRT &&
6994 0 : pd.dir == PF_IN && pd.virtual_proto == IPPROTO_TCP &&
6995 0 : (pd.hdr.tcp.th_flags & (TH_SYN|TH_ACK|TH_RST)) == TH_ACK &&
6996 0 : pf_syncookie_validate(&pd)) {
6997 0 : struct mbuf *msyn;
6998 0 : msyn = pf_syncookie_recreate_syn(&pd);
6999 0 : if (msyn) {
7000 0 : action = pf_test(af, fwdir, ifp, &msyn);
7001 0 : m_freem(msyn);
7002 0 : if (action == PF_PASS || action == PF_AFRT) {
7003 : PF_STATE_ENTER_READ();
7004 0 : pf_test_state(&pd, &s, &reason, 1);
7005 0 : s = pf_state_ref(s);
7006 : PF_STATE_EXIT_READ();
7007 0 : if (s == NULL)
7008 0 : return (PF_DROP);
7009 0 : s->src.seqhi =
7010 0 : ntohl(pd.hdr.tcp.th_ack) - 1;
7011 0 : s->src.seqlo =
7012 0 : ntohl(pd.hdr.tcp.th_seq) - 1;
7013 0 : pf_set_protostate(s, PF_PEER_SRC,
7014 : PF_TCPS_PROXY_DST);
7015 : PF_LOCK();
7016 0 : have_pf_lock = 1;
7017 0 : action = pf_synproxy(&pd, &s, &reason);
7018 0 : if (action != PF_PASS) {
7019 : PF_UNLOCK();
7020 0 : pf_state_unref(s);
7021 0 : return (action);
7022 : }
7023 : }
7024 : } else
7025 : action = PF_DROP;
7026 0 : }
7027 :
7028 0 : if (action == PF_PASS || action == PF_AFRT) {
7029 : #if NPFSYNC > 0
7030 0 : pfsync_update_state(s, &have_pf_lock);
7031 : #endif /* NPFSYNC > 0 */
7032 0 : r = s->rule.ptr;
7033 0 : a = s->anchor.ptr;
7034 : #if NPFLOG > 0
7035 0 : pd.pflog |= s->log;
7036 : #endif /* NPFLOG > 0 */
7037 0 : } else if (s == NULL) {
7038 : PF_LOCK();
7039 0 : have_pf_lock = 1;
7040 0 : action = pf_test_rule(&pd, &r, &s, &a, &ruleset,
7041 : &reason);
7042 0 : s = pf_state_ref(s);
7043 0 : }
7044 :
7045 0 : if (pd.virtual_proto == IPPROTO_TCP) {
7046 0 : if (s) {
7047 0 : if (s->max_mss)
7048 0 : pf_normalize_mss(&pd, s->max_mss);
7049 0 : } else if (r->max_mss)
7050 0 : pf_normalize_mss(&pd, r->max_mss);
7051 : }
7052 :
7053 : break;
7054 : }
7055 :
7056 0 : if (have_pf_lock != 0)
7057 : PF_UNLOCK();
7058 :
7059 : /*
7060 : * At the moment, we rely on NET_LOCK() to prevent removal of items
7061 : * we've collected above ('r', 'anchor' and 'ruleset'). They'll have
7062 : * to be refcounted when NET_LOCK() is gone.
7063 : */
7064 :
7065 : done:
7066 0 : if (action != PF_DROP) {
7067 0 : if (s) {
7068 : /* The non-state case is handled in pf_test_rule() */
7069 0 : if (action == PF_PASS && pd.badopts &&
7070 0 : !(s->state_flags & PFSTATE_ALLOWOPTS)) {
7071 : action = PF_DROP;
7072 0 : REASON_SET(&reason, PFRES_IPOPTIONS);
7073 : #if NPFLOG > 0
7074 0 : pd.pflog |= PF_LOG_FORCE;
7075 : #endif /* NPFLOG > 0 */
7076 0 : DPFPRINTF(LOG_NOTICE, "dropping packet with "
7077 : "ip/ipv6 options in pf_test()");
7078 : }
7079 :
7080 0 : pf_scrub(pd.m, s->state_flags, pd.af, s->min_ttl,
7081 0 : s->set_tos);
7082 0 : pf_tag_packet(pd.m, s->tag, s->rtableid[pd.didx]);
7083 0 : if (pqid || (pd.tos & IPTOS_LOWDELAY)) {
7084 0 : qid = s->pqid;
7085 0 : if (s->state_flags & PFSTATE_SETPRIO)
7086 0 : pd.m->m_pkthdr.pf.prio = s->set_prio[1];
7087 : } else {
7088 0 : qid = s->qid;
7089 0 : if (s->state_flags & PFSTATE_SETPRIO)
7090 0 : pd.m->m_pkthdr.pf.prio = s->set_prio[0];
7091 : }
7092 0 : pd.m->m_pkthdr.pf.delay = s->delay;
7093 0 : } else {
7094 0 : pf_scrub(pd.m, r->scrub_flags, pd.af, r->min_ttl,
7095 0 : r->set_tos);
7096 0 : if (pqid || (pd.tos & IPTOS_LOWDELAY)) {
7097 0 : qid = r->pqid;
7098 0 : if (r->scrub_flags & PFSTATE_SETPRIO)
7099 0 : pd.m->m_pkthdr.pf.prio = r->set_prio[1];
7100 : } else {
7101 0 : qid = r->qid;
7102 0 : if (r->scrub_flags & PFSTATE_SETPRIO)
7103 0 : pd.m->m_pkthdr.pf.prio = r->set_prio[0];
7104 : }
7105 0 : pd.m->m_pkthdr.pf.delay = r->delay;
7106 : }
7107 : }
7108 :
7109 0 : if (action == PF_PASS && qid)
7110 0 : pd.m->m_pkthdr.pf.qid = qid;
7111 0 : if (pd.dir == PF_IN && s && s->key[PF_SK_STACK])
7112 0 : pf_mbuf_link_state_key(pd.m, s->key[PF_SK_STACK]);
7113 0 : if (pd.dir == PF_OUT &&
7114 0 : pd.m->m_pkthdr.pf.inp && !pd.m->m_pkthdr.pf.inp->inp_pf_sk &&
7115 0 : s && s->key[PF_SK_STACK] && !s->key[PF_SK_STACK]->inp)
7116 0 : pf_state_key_link_inpcb(s->key[PF_SK_STACK],
7117 : pd.m->m_pkthdr.pf.inp);
7118 :
7119 0 : if (s && (pd.m->m_pkthdr.ph_flowid & M_FLOWID_VALID) == 0) {
7120 0 : pd.m->m_pkthdr.ph_flowid = M_FLOWID_VALID |
7121 0 : (M_FLOWID_MASK & bemtoh64(&s->id));
7122 0 : }
7123 :
7124 : /*
7125 : * connections redirected to loopback should not match sockets
7126 : * bound specifically to loopback due to security implications,
7127 : * see in_pcblookup_listen().
7128 : */
7129 0 : if (pd.destchg)
7130 0 : if ((pd.af == AF_INET && (ntohl(pd.dst->v4.s_addr) >>
7131 0 : IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) ||
7132 0 : (pd.af == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)))
7133 0 : pd.m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
7134 : /* We need to redo the route lookup on outgoing routes. */
7135 0 : if (pd.destchg && pd.dir == PF_OUT)
7136 0 : pd.m->m_pkthdr.pf.flags |= PF_TAG_REROUTE;
7137 :
7138 0 : if (pd.dir == PF_IN && action == PF_PASS &&
7139 0 : (r->divert.type == PF_DIVERT_TO ||
7140 0 : r->divert.type == PF_DIVERT_REPLY)) {
7141 : struct pf_divert *divert;
7142 :
7143 0 : if ((divert = pf_get_divert(pd.m))) {
7144 0 : pd.m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED;
7145 0 : divert->addr = r->divert.addr;
7146 0 : divert->port = r->divert.port;
7147 0 : divert->rdomain = pd.rdomain;
7148 0 : divert->type = r->divert.type;
7149 0 : }
7150 0 : }
7151 :
7152 0 : if (action == PF_PASS && r->divert.type == PF_DIVERT_PACKET)
7153 0 : action = PF_DIVERT;
7154 :
7155 : #if NPFLOG > 0
7156 0 : if (pd.pflog) {
7157 : struct pf_rule_item *ri;
7158 :
7159 0 : if (pd.pflog & PF_LOG_FORCE || r->log & PF_LOG_ALL)
7160 0 : pflog_packet(&pd, reason, r, a, ruleset, NULL);
7161 0 : if (s) {
7162 0 : SLIST_FOREACH(ri, &s->match_rules, entry)
7163 0 : if (ri->r->log & PF_LOG_ALL)
7164 0 : pflog_packet(&pd, reason, ri->r, a,
7165 0 : ruleset, NULL);
7166 : }
7167 0 : }
7168 : #endif /* NPFLOG > 0 */
7169 :
7170 0 : pf_counters_inc(action, &pd, s, r, a);
7171 :
7172 0 : switch (action) {
7173 : case PF_SYNPROXY_DROP:
7174 0 : m_freem(pd.m);
7175 : /* FALLTHROUGH */
7176 : case PF_DEFER:
7177 0 : pd.m = NULL;
7178 : action = PF_PASS;
7179 0 : break;
7180 : case PF_DIVERT:
7181 0 : switch (pd.af) {
7182 : case AF_INET:
7183 0 : if (!divert_packet(pd.m, pd.dir, r->divert.port))
7184 0 : pd.m = NULL;
7185 : break;
7186 : #ifdef INET6
7187 : case AF_INET6:
7188 0 : if (!divert6_packet(pd.m, pd.dir, r->divert.port))
7189 0 : pd.m = NULL;
7190 : break;
7191 : #endif /* INET6 */
7192 : }
7193 : action = PF_PASS;
7194 0 : break;
7195 : #ifdef INET6
7196 : case PF_AFRT:
7197 0 : if (pf_translate_af(&pd)) {
7198 : action = PF_DROP;
7199 0 : break;
7200 : }
7201 0 : pd.m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
7202 0 : switch (pd.naf) {
7203 : case AF_INET:
7204 0 : if (pd.dir == PF_IN)
7205 0 : ip_forward(pd.m, ifp, NULL, 1);
7206 : else
7207 0 : ip_output(pd.m, NULL, NULL, 0, NULL, NULL, 0);
7208 : break;
7209 : case AF_INET6:
7210 0 : if (pd.dir == PF_IN)
7211 0 : ip6_forward(pd.m, NULL, 1);
7212 : else
7213 0 : ip6_output(pd.m, NULL, NULL, 0, NULL, NULL);
7214 : break;
7215 : }
7216 0 : pd.m = NULL;
7217 : action = PF_PASS;
7218 0 : break;
7219 : #endif /* INET6 */
7220 : case PF_DROP:
7221 0 : m_freem(pd.m);
7222 0 : pd.m = NULL;
7223 0 : break;
7224 : default:
7225 0 : if (r->rt) {
7226 0 : switch (pd.af) {
7227 : case AF_INET:
7228 0 : pf_route(&pd, r, s);
7229 0 : break;
7230 : #ifdef INET6
7231 : case AF_INET6:
7232 0 : pf_route6(&pd, r, s);
7233 0 : break;
7234 : #endif /* INET6 */
7235 : }
7236 : }
7237 : break;
7238 : }
7239 :
7240 : #ifdef INET6
7241 : /* if reassembled packet passed, create new fragments */
7242 0 : if (pf_status.reass && action == PF_PASS && pd.m && fwdir == PF_FWD &&
7243 0 : pd.af == AF_INET6) {
7244 : struct m_tag *mtag;
7245 :
7246 0 : if ((mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL)))
7247 0 : action = pf_refragment6(&pd.m, mtag, NULL, NULL, NULL);
7248 0 : }
7249 : #endif /* INET6 */
7250 0 : if (s && action != PF_DROP) {
7251 0 : if (!s->if_index_in && dir == PF_IN)
7252 0 : s->if_index_in = ifp->if_index;
7253 0 : else if (!s->if_index_out && dir == PF_OUT)
7254 0 : s->if_index_out = ifp->if_index;
7255 : }
7256 :
7257 0 : *m0 = pd.m;
7258 :
7259 0 : pf_state_unref(s);
7260 :
7261 0 : return (action);
7262 0 : }
7263 :
7264 : int
7265 0 : pf_ouraddr(struct mbuf *m)
7266 : {
7267 : struct pf_state_key *sk;
7268 :
7269 0 : if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED)
7270 0 : return (1);
7271 :
7272 0 : sk = m->m_pkthdr.pf.statekey;
7273 0 : if (sk != NULL) {
7274 0 : if (sk->inp != NULL)
7275 0 : return (1);
7276 : }
7277 :
7278 0 : return (-1);
7279 0 : }
7280 :
7281 : /*
7282 : * must be called whenever any addressing information such as
7283 : * address, port, protocol has changed
7284 : */
7285 : void
7286 0 : pf_pkt_addr_changed(struct mbuf *m)
7287 : {
7288 0 : pf_mbuf_unlink_state_key(m);
7289 0 : pf_mbuf_unlink_inpcb(m);
7290 0 : }
7291 :
7292 : struct inpcb *
7293 0 : pf_inp_lookup(struct mbuf *m)
7294 : {
7295 : struct inpcb *inp = NULL;
7296 0 : struct pf_state_key *sk = m->m_pkthdr.pf.statekey;
7297 :
7298 0 : if (!pf_state_key_isvalid(sk))
7299 0 : pf_mbuf_unlink_state_key(m);
7300 : else
7301 0 : inp = m->m_pkthdr.pf.statekey->inp;
7302 :
7303 0 : if (inp && inp->inp_pf_sk)
7304 0 : KASSERT(m->m_pkthdr.pf.statekey == inp->inp_pf_sk);
7305 :
7306 0 : return (inp);
7307 : }
7308 :
7309 : void
7310 0 : pf_inp_link(struct mbuf *m, struct inpcb *inp)
7311 : {
7312 0 : struct pf_state_key *sk = m->m_pkthdr.pf.statekey;
7313 :
7314 0 : if (!pf_state_key_isvalid(sk)) {
7315 0 : pf_mbuf_unlink_state_key(m);
7316 0 : return;
7317 : }
7318 :
7319 : /*
7320 : * we don't need to grab PF-lock here. At worst case we link inp to
7321 : * state, which might be just being marked as deleted by another
7322 : * thread.
7323 : */
7324 0 : if (inp && !sk->inp && !inp->inp_pf_sk)
7325 0 : pf_state_key_link_inpcb(sk, inp);
7326 :
7327 : /* The statekey has finished finding the inp, it is no longer needed. */
7328 0 : pf_mbuf_unlink_state_key(m);
7329 0 : }
7330 :
7331 : void
7332 0 : pf_inp_unlink(struct inpcb *inp)
7333 : {
7334 0 : pf_inpcb_unlink_state_key(inp);
7335 0 : }
7336 :
7337 : void
7338 0 : pf_state_key_link_reverse(struct pf_state_key *sk, struct pf_state_key *skrev)
7339 : {
7340 : /* Note that sk and skrev may be equal, then we refcount twice. */
7341 0 : KASSERT(sk->reverse == NULL);
7342 0 : KASSERT(skrev->reverse == NULL);
7343 0 : sk->reverse = pf_state_key_ref(skrev);
7344 0 : skrev->reverse = pf_state_key_ref(sk);
7345 0 : }
7346 :
7347 : #if NPFLOG > 0
7348 : void
7349 0 : pf_log_matches(struct pf_pdesc *pd, struct pf_rule *rm, struct pf_rule *am,
7350 : struct pf_ruleset *ruleset, struct pf_rule_slist *matchrules)
7351 : {
7352 : struct pf_rule_item *ri;
7353 :
7354 : /* if this is the log(matches) rule, packet has been logged already */
7355 0 : if (rm->log & PF_LOG_MATCHES)
7356 0 : return;
7357 :
7358 0 : SLIST_FOREACH(ri, matchrules, entry)
7359 0 : if (ri->r->log & PF_LOG_MATCHES)
7360 0 : pflog_packet(pd, PFRES_MATCH, rm, am, ruleset, ri->r);
7361 0 : }
7362 : #endif /* NPFLOG > 0 */
7363 :
7364 : struct pf_state_key *
7365 0 : pf_state_key_ref(struct pf_state_key *sk)
7366 : {
7367 0 : if (sk != NULL)
7368 0 : PF_REF_TAKE(sk->refcnt);
7369 :
7370 0 : return (sk);
7371 : }
7372 :
7373 : void
7374 0 : pf_state_key_unref(struct pf_state_key *sk)
7375 : {
7376 0 : if (PF_REF_RELE(sk->refcnt)) {
7377 : /* state key must be removed from tree */
7378 0 : KASSERT(!pf_state_key_isvalid(sk));
7379 : /* state key must be unlinked from reverse key */
7380 0 : KASSERT(sk->reverse == NULL);
7381 : /* state key must be unlinked from socket */
7382 0 : KASSERT(sk->inp == NULL);
7383 0 : pool_put(&pf_state_key_pl, sk);
7384 0 : }
7385 0 : }
7386 :
7387 : int
7388 0 : pf_state_key_isvalid(struct pf_state_key *sk)
7389 : {
7390 0 : return ((sk != NULL) && (sk->removed == 0));
7391 : }
7392 :
7393 : void
7394 0 : pf_mbuf_link_state_key(struct mbuf *m, struct pf_state_key *sk)
7395 : {
7396 0 : KASSERT(m->m_pkthdr.pf.statekey == NULL);
7397 0 : m->m_pkthdr.pf.statekey = pf_state_key_ref(sk);
7398 0 : }
7399 :
7400 : void
7401 0 : pf_mbuf_unlink_state_key(struct mbuf *m)
7402 : {
7403 0 : struct pf_state_key *sk = m->m_pkthdr.pf.statekey;
7404 :
7405 0 : if (sk != NULL) {
7406 0 : m->m_pkthdr.pf.statekey = NULL;
7407 0 : pf_state_key_unref(sk);
7408 0 : }
7409 0 : }
7410 :
7411 : void
7412 0 : pf_mbuf_link_inpcb(struct mbuf *m, struct inpcb *inp)
7413 : {
7414 0 : KASSERT(m->m_pkthdr.pf.inp == NULL);
7415 0 : m->m_pkthdr.pf.inp = in_pcbref(inp);
7416 0 : }
7417 :
7418 : void
7419 0 : pf_mbuf_unlink_inpcb(struct mbuf *m)
7420 : {
7421 0 : struct inpcb *inp = m->m_pkthdr.pf.inp;
7422 :
7423 0 : if (inp != NULL) {
7424 0 : m->m_pkthdr.pf.inp = NULL;
7425 0 : in_pcbunref(inp);
7426 0 : }
7427 0 : }
7428 :
7429 : void
7430 0 : pf_state_key_link_inpcb(struct pf_state_key *sk, struct inpcb *inp)
7431 : {
7432 0 : KASSERT(sk->inp == NULL);
7433 0 : sk->inp = in_pcbref(inp);
7434 0 : KASSERT(inp->inp_pf_sk == NULL);
7435 0 : inp->inp_pf_sk = pf_state_key_ref(sk);
7436 0 : }
7437 :
7438 : void
7439 0 : pf_inpcb_unlink_state_key(struct inpcb *inp)
7440 : {
7441 0 : struct pf_state_key *sk = inp->inp_pf_sk;
7442 :
7443 0 : if (sk != NULL) {
7444 0 : KASSERT(sk->inp == inp);
7445 0 : sk->inp = NULL;
7446 0 : inp->inp_pf_sk = NULL;
7447 0 : pf_state_key_unref(sk);
7448 0 : in_pcbunref(inp);
7449 0 : }
7450 0 : }
7451 :
7452 : void
7453 0 : pf_state_key_unlink_inpcb(struct pf_state_key *sk)
7454 : {
7455 0 : struct inpcb *inp = sk->inp;
7456 :
7457 0 : if (inp != NULL) {
7458 0 : KASSERT(inp->inp_pf_sk == sk);
7459 0 : sk->inp = NULL;
7460 0 : inp->inp_pf_sk = NULL;
7461 0 : pf_state_key_unref(sk);
7462 0 : in_pcbunref(inp);
7463 0 : }
7464 0 : }
7465 :
7466 : void
7467 0 : pf_state_key_unlink_reverse(struct pf_state_key *sk)
7468 : {
7469 0 : struct pf_state_key *skrev = sk->reverse;
7470 :
7471 : /* Note that sk and skrev may be equal, then we unref twice. */
7472 0 : if (skrev != NULL) {
7473 0 : KASSERT(skrev->reverse == sk);
7474 0 : sk->reverse = NULL;
7475 0 : skrev->reverse = NULL;
7476 0 : pf_state_key_unref(skrev);
7477 0 : pf_state_key_unref(sk);
7478 0 : }
7479 0 : }
7480 :
7481 : struct pf_state *
7482 0 : pf_state_ref(struct pf_state *s)
7483 : {
7484 0 : if (s != NULL)
7485 0 : PF_REF_TAKE(s->refcnt);
7486 0 : return (s);
7487 : }
7488 :
7489 : void
7490 0 : pf_state_unref(struct pf_state *s)
7491 : {
7492 0 : if ((s != NULL) && PF_REF_RELE(s->refcnt)) {
7493 : /* never inserted or removed */
7494 : #if NPFSYNC > 0
7495 0 : KASSERT((TAILQ_NEXT(s, sync_list) == NULL) ||
7496 : ((TAILQ_NEXT(s, sync_list) == _Q_INVALID) &&
7497 : (s->sync_state == PFSYNC_S_NONE)));
7498 : #endif /* NPFSYNC */
7499 0 : KASSERT((TAILQ_NEXT(s, entry_list) == NULL) ||
7500 : (TAILQ_NEXT(s, entry_list) == _Q_INVALID));
7501 0 : KASSERT((s->key[PF_SK_WIRE] == NULL) &&
7502 : (s->key[PF_SK_STACK] == NULL));
7503 :
7504 0 : pool_put(&pf_state_pl, s);
7505 0 : }
7506 0 : }
7507 :
7508 : int
7509 0 : pf_delay_pkt(struct mbuf *m, u_int ifidx)
7510 : {
7511 : struct pf_pktdelay *pdy;
7512 :
7513 0 : if ((pdy = pool_get(&pf_pktdelay_pl, PR_NOWAIT)) == NULL) {
7514 0 : m_freem(m);
7515 0 : return (ENOBUFS);
7516 : }
7517 0 : pdy->ifidx = ifidx;
7518 0 : pdy->m = m;
7519 0 : timeout_set(pdy->to, pf_pktenqueue_delayed, pdy);
7520 0 : timeout_add_msec(pdy->to, m->m_pkthdr.pf.delay);
7521 0 : m->m_pkthdr.pf.delay = 0;
7522 0 : return (0);
7523 0 : }
7524 :
7525 : void
7526 0 : pf_pktenqueue_delayed(void *arg)
7527 : {
7528 0 : struct pf_pktdelay *pdy = arg;
7529 : struct ifnet *ifp;
7530 :
7531 0 : ifp = if_get(pdy->ifidx);
7532 0 : if (ifp != NULL) {
7533 0 : if_enqueue(ifp, pdy->m);
7534 0 : if_put(ifp);
7535 0 : } else
7536 0 : m_freem(pdy->m);
7537 :
7538 0 : pool_put(&pf_pktdelay_pl, pdy);
7539 0 : }
|