Lines Matching +full:max +full:- +full:reason
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
5 * Copyright 2011-2018 Alexander Bluhm <bluhm@openbsd.org>
168 key->frc_src.v4 = ip->ip_src;
169 key->frc_dst.v4 = ip->ip_dst;
170 key->frc_af = AF_INET;
171 key->frc_proto = ip->ip_p;
172 key->frc_id = ip->ip_id;
214 if ((diff = a->fr_id - b->fr_id) != 0)
216 if ((diff = a->fr_proto - b->fr_proto) != 0)
218 if ((diff = a->fr_af - b->fr_af) != 0)
220 if ((diff = pf_addr_cmp(&a->fr_src, &b->fr_src, a->fr_af)) != 0)
222 if ((diff = pf_addr_cmp(&a->fr_dst, &b->fr_dst, a->fr_af)) != 0)
230 u_int32_t expire = time_uptime -
243 if (frag->fr_timeout > expire)
246 DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
290 while ((frent = TAILQ_FIRST(&frag->fr_queue)) != NULL) {
291 TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
293 m_freem(frent->fe_m);
310 frag->fr_timeout = time_uptime;
332 pf_create_fragment(u_short *reason)
343 REASON_SET(reason, PFRES_MEMORY);
366 if (frent->fe_off == 0)
367 holes--;
369 KASSERT(frent->fe_off != 0, ("frent->fe_off != 0"));
370 if (frent->fe_off == prev->fe_off + prev->fe_len)
371 holes--;
374 if (!frent->fe_mff)
375 holes--;
377 KASSERT(frent->fe_mff, ("frent->fe_mff"));
378 if (next->fe_off == frent->fe_off + frent->fe_len)
379 holes--;
394 16 - 1);
395 CTASSERT(((u_int16_t)0xffff >> 3) / PF_FRAG_ENTRY_POINTS == 512 - 1);
397 return frent->fe_off / (0x10000 / PF_FRAG_ENTRY_POINTS);
414 if (frag->fr_entries[index] >= PF_FRAG_ENTRY_LIMIT)
416 frag->fr_entries[index]++;
419 TAILQ_INSERT_HEAD(&frag->fr_queue, frent, fr_next);
421 KASSERT(prev->fe_off + prev->fe_len <= frent->fe_off,
423 TAILQ_INSERT_AFTER(&frag->fr_queue, prev, frent, fr_next);
426 if (frag->fr_firstoff[index] == NULL) {
429 frag->fr_firstoff[index] = frent;
431 if (frent->fe_off < frag->fr_firstoff[index]->fe_off) {
434 frag->fr_firstoff[index] = frent;
442 frag->fr_holes += pf_frent_holes(frent);
456 frag->fr_holes -= pf_frent_holes(frent);
459 KASSERT(frag->fr_firstoff[index] != NULL, ("frent not found"));
460 if (frag->fr_firstoff[index]->fe_off == frent->fe_off) {
462 frag->fr_firstoff[index] = NULL;
464 KASSERT(frent->fe_off + frent->fe_len <= next->fe_off,
467 frag->fr_firstoff[index] = next;
469 frag->fr_firstoff[index] = NULL;
473 KASSERT(frag->fr_firstoff[index]->fe_off < frent->fe_off,
474 ("frag->fr_firstoff[index]->fe_off < frent->fe_off"));
476 KASSERT(prev->fe_off + prev->fe_len <= frent->fe_off,
482 TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
484 KASSERT(frag->fr_entries[index] > 0, ("No fragments remaining"));
485 frag->fr_entries[index]--;
498 prev = TAILQ_LAST(&frag->fr_queue, pf_fragq);
500 if (prev->fe_off <= frent->fe_off)
511 prev = frag->fr_firstoff[index];
522 if (prev->fe_off > frent->fe_off) {
526 KASSERT(prev->fe_off <= frent->fe_off,
527 ("prev->fe_off <= frent->fe_off"));
536 if (next->fe_off > frent->fe_off)
545 u_short *reason)
555 if (frent->fe_len == 0) {
561 if (frent->fe_mff && (frent->fe_len & 0x7)) {
562 DPFPRINTF(("bad fragment: mff and len %d\n", frent->fe_len));
567 if (frent->fe_off + frent->fe_len > IP_MAXPACKET) {
568 DPFPRINTF(("bad fragment: max packet %d\n",
569 frent->fe_off + frent->fe_len));
573 DPFPRINTF((key->frc_af == AF_INET ?
574 "reass frag %d @ %d-%d\n" : "reass frag %#08x @ %d-%d\n",
575 key->frc_id, frent->fe_off, frent->fe_off + frent->fe_len));
587 REASON_SET(reason, PFRES_MEMORY);
593 memset(frag->fr_firstoff, 0, sizeof(frag->fr_firstoff));
594 memset(frag->fr_entries, 0, sizeof(frag->fr_entries));
595 frag->fr_timeout = time_uptime;
596 TAILQ_INIT(&frag->fr_queue);
597 frag->fr_maxlen = frent->fe_len;
598 frag->fr_holes = 1;
609 KASSERT(!TAILQ_EMPTY(&frag->fr_queue), ("!TAILQ_EMPTY()->fr_queue"));
612 if (frent->fe_len > frag->fr_maxlen)
613 frag->fr_maxlen = frent->fe_len;
616 total = TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_off +
617 TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_len;
620 if (frent->fe_off + frent->fe_len < total && !frent->fe_mff)
624 if (!TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_mff) {
625 if (frent->fe_off + frent->fe_len > total ||
626 (frent->fe_off + frent->fe_len == total && frent->fe_mff))
629 if (frent->fe_off + frent->fe_len == total && !frent->fe_mff)
636 after = TAILQ_FIRST(&frag->fr_queue);
642 if (prev != NULL && prev->fe_off + prev->fe_len > frent->fe_off) {
645 if (frag->fr_af == AF_INET6)
648 precut = prev->fe_off + prev->fe_len - frent->fe_off;
649 if (precut >= frent->fe_len) {
654 m_adj(frent->fe_m, precut);
655 frent->fe_off += precut;
656 frent->fe_len -= precut;
659 for (; after != NULL && frent->fe_off + frent->fe_len > after->fe_off;
663 aftercut = frent->fe_off + frent->fe_len - after->fe_off;
665 if (aftercut < after->fe_len) {
666 m_adj(after->fe_m, aftercut);
668 after->fe_off += aftercut;
669 after->fe_len -= aftercut;
675 after->fe_off -= aftercut;
676 after->fe_len += aftercut;
679 after->fe_off += aftercut;
680 after->fe_len -= aftercut;
685 m_freem(after->fe_m);
698 m_freem(after->fe_m);
721 REASON_SET(reason, PFRES_FRAG);
733 frent = TAILQ_FIRST(&frag->fr_queue);
734 TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
736 m = frent->fe_m;
737 m_adj(m, (frent->fe_hdrlen + frent->fe_len) - m->m_pkthdr.len);
739 while ((frent = TAILQ_FIRST(&frag->fr_queue)) != NULL) {
740 TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
742 m2 = frent->fe_m;
744 m_adj(m2, frent->fe_hdrlen);
746 m_adj(m2, frent->fe_len - m2->m_pkthdr.len);
760 pf_reassemble(struct mbuf **m0, int dir, u_short *reason)
774 if ((frent = pf_create_fragment(reason)) == NULL)
777 frent->fe_m = m;
778 frent->fe_hdrlen = ip->ip_hl << 2;
779 frent->fe_extoff = 0;
780 frent->fe_len = ntohs(ip->ip_len) - (ip->ip_hl << 2);
781 frent->fe_off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
782 frent->fe_mff = ntohs(ip->ip_off) & IP_MF;
786 if ((frag = pf_fillup_fragment(&key, frent, reason)) == NULL)
792 if (frag->fr_holes) {
793 DPFPRINTF(("frag %d, holes %d\n", frag->fr_id, frag->fr_holes));
798 frent = TAILQ_FIRST(&frag->fr_queue);
800 total = TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_off +
801 TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_len;
802 hdrlen = frent->fe_hdrlen;
804 maxlen = frag->fr_maxlen;
805 frag_id = frag->fr_id;
809 if (m->m_flags & M_PKTHDR) {
811 for (m = *m0; m; m = m->m_next)
812 plen += m->m_len;
814 m->m_pkthdr.len = plen;
819 REASON_SET(reason, PFRES_SHORT);
824 ftag->ft_hdrlen = hdrlen;
825 ftag->ft_extoff = 0;
826 ftag->ft_maxlen = maxlen;
827 ftag->ft_id = frag_id;
831 ip->ip_sum = pf_cksum_fixup(ip->ip_sum, ip->ip_len,
833 ip->ip_len = htons(hdrlen + total);
834 ip->ip_sum = pf_cksum_fixup(ip->ip_sum, ip->ip_off,
835 ip->ip_off & ~(IP_MF|IP_OFFMASK), 0);
836 ip->ip_off &= ~(IP_MF|IP_OFFMASK);
840 ip->ip_len = 0;
841 REASON_SET(reason, PFRES_SHORT);
846 DPFPRINTF(("complete: %p(%d)\n", m, ntohs(ip->ip_len)));
854 uint16_t hdrlen, uint16_t extoff, u_short *reason)
871 if ((frent = pf_create_fragment(reason)) == NULL) {
876 frent->fe_m = m;
877 frent->fe_hdrlen = hdrlen;
878 frent->fe_extoff = extoff;
879 frent->fe_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - hdrlen;
880 frent->fe_off = ntohs(fraghdr->ip6f_offlg & IP6F_OFF_MASK);
881 frent->fe_mff = fraghdr->ip6f_offlg & IP6F_MORE_FRAG;
883 key.frc_src.v6 = ip6->ip6_src;
884 key.frc_dst.v6 = ip6->ip6_dst;
888 key.frc_id = fraghdr->ip6f_ident;
890 if ((frag = pf_fillup_fragment(&key, frent, reason)) == NULL) {
898 if (frag->fr_holes) {
899 DPFPRINTF(("frag %d, holes %d\n", frag->fr_id,
900 frag->fr_holes));
906 frent = TAILQ_FIRST(&frag->fr_queue);
908 extoff = frent->fe_extoff;
909 maxlen = frag->fr_maxlen;
910 frag_id = frag->fr_id;
911 total = TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_off +
912 TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_len;
913 hdrlen = frent->fe_hdrlen - sizeof(struct ip6_frag);
930 if (m->m_flags & M_PKTHDR) {
932 for (m = *m0; m; m = m->m_next)
933 plen += m->m_len;
935 m->m_pkthdr.len = plen;
942 ftag->ft_hdrlen = hdrlen;
943 ftag->ft_extoff = extoff;
944 ftag->ft_maxlen = maxlen;
945 ftag->ft_id = frag_id;
949 ip6->ip6_plen = htons(hdrlen - sizeof(struct ip6_hdr) + total);
958 ip6->ip6_nxt = proto;
960 if (hdrlen - sizeof(struct ip6_hdr) + total > IPV6_MAXPACKET) {
962 ip6->ip6_plen = 0;
963 REASON_SET(reason, PFRES_SHORT);
968 DPFPRINTF(("complete: %p(%d)\n", m, ntohs(ip6->ip6_plen)));
972 REASON_SET(reason, PFRES_MEMORY);
987 return (m->m_pkthdr.len);
991 return (ftag->ft_maxlen);
1007 hdrlen = ftag->ft_hdrlen;
1008 extoff = ftag->ft_extoff;
1009 maxlen = ftag->ft_maxlen;
1010 frag_id = ftag->ft_id;
1027 proto = hdr->ip6_nxt;
1028 hdr->ip6_nxt = IPPROTO_FRAGMENT;
1031 /* In case of link-local traffic we'll need a scope set. */
1034 in6_setscope(&hdr->ip6_src, ifp, NULL);
1035 in6_setscope(&hdr->ip6_dst, ifp, NULL);
1049 m = (*m0)->m_nextpkt;
1050 (*m0)->m_nextpkt = NULL;
1062 t = m->m_nextpkt;
1063 m->m_nextpkt = NULL;
1064 m->m_flags |= M_SKIP_FIREWALL;
1078 dst.sin6_addr = hdr->ip6_dst;
1082 MPASS(m->m_pkthdr.rcvif != NULL);
1096 pf_normalize_ip(u_short *reason, struct pf_pdesc *pd)
1099 struct ip *h = mtod(pd->m, struct ip *);
1100 int mff = (ntohs(h->ip_off) & IP_MF);
1101 int hlen = h->ip_hl << 2;
1102 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
1103 u_int16_t max;
1105 int tag = -1;
1115 * - enforced packet normalization operation just like in OpenBSD
1116 * - fragment reassembly depends on V_pf_status.reass
1118 * - packet normalization is performed if there is a matching scrub rule
1119 * - fragment reassembly is performed if the matching rule has no
1124 pf_counter_u64_add(&r->evaluations, 1);
1125 if (pfi_kkif_match(r->kif, pd->kif) == r->ifnot)
1126 r = r->skip[PF_SKIP_IFP];
1127 else if (r->direction && r->direction != pd->dir)
1128 r = r->skip[PF_SKIP_DIR];
1129 else if (r->af && r->af != AF_INET)
1130 r = r->skip[PF_SKIP_AF];
1131 else if (r->proto && r->proto != h->ip_p)
1132 r = r->skip[PF_SKIP_PROTO];
1133 else if (PF_MISMATCHAW(&r->src.addr,
1134 (struct pf_addr *)&h->ip_src.s_addr, AF_INET,
1135 r->src.neg, pd->kif, M_GETFIB(pd->m)))
1136 r = r->skip[PF_SKIP_SRC_ADDR];
1137 else if (PF_MISMATCHAW(&r->dst.addr,
1138 (struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
1139 r->dst.neg, NULL, M_GETFIB(pd->m)))
1140 r = r->skip[PF_SKIP_DST_ADDR];
1141 else if (r->match_tag && !pf_match_tag(pd->m, r, &tag,
1142 pd->pf_mtag ? pd->pf_mtag->tag : 0))
1151 if (r == NULL || r->action == PF_NOSCRUB)
1155 pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
1156 pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
1158 pf_rule_to_actions(r, &pd->act);
1163 REASON_SET(reason, PFRES_NORM);
1167 if (hlen > ntohs(h->ip_len)) {
1168 REASON_SET(reason, PFRES_NORM);
1172 /* Clear IP_DF if the rule uses the no-df option or we're in no-df mode */
1174 (r != NULL && r->rule_flag & PFRULE_NODF)) &&
1175 (h->ip_off & htons(IP_DF))
1177 u_int16_t ip_off = h->ip_off;
1179 h->ip_off &= htons(~IP_DF);
1180 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
1189 * no-df above, fine. Otherwise drop it.
1191 if (h->ip_off & htons(IP_DF)) {
1196 ip_len = ntohs(h->ip_len) - hlen;
1206 DPFPRINTF(("max packet %d\n", fragoff + ip_len));
1211 (r != NULL && !(r->rule_flag & PFRULE_FRAGMENT_NOREASS))
1213 max = fragoff + ip_len;
1218 DPFPRINTF(("reass frag %d @ %d-%d\n", h->ip_id, fragoff, max));
1219 verdict = pf_reassemble(&pd->m, pd->dir, reason);
1225 if (pd->m == NULL)
1228 h = mtod(pd->m, struct ip *);
1229 pd->tot_len = htons(h->ip_len);
1233 if (h->ip_off & ~htons(IP_DF)) {
1234 u_int16_t ip_off = h->ip_off;
1236 h->ip_off &= htons(IP_DF);
1237 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
1245 REASON_SET(reason, PFRES_FRAG);
1247 if (r != NULL && r->log)
1248 PFLOG_PACKET(PF_DROP, *reason, r, NULL, NULL, pd, 1);
1256 pf_normalize_ip6(int off, u_short *reason,
1270 * - enforced packet normalization operation just like in OpenBSD
1272 * - packet normalization is performed if there is a matching scrub rule
1277 pf_counter_u64_add(&r->evaluations, 1);
1278 if (pfi_kkif_match(r->kif, pd->kif) == r->ifnot)
1279 r = r->skip[PF_SKIP_IFP];
1280 else if (r->direction && r->direction != pd->dir)
1281 r = r->skip[PF_SKIP_DIR];
1282 else if (r->af && r->af != AF_INET6)
1283 r = r->skip[PF_SKIP_AF];
1284 else if (r->proto && r->proto != pd->proto)
1285 r = r->skip[PF_SKIP_PROTO];
1286 else if (PF_MISMATCHAW(&r->src.addr,
1287 (struct pf_addr *)&pd->src, AF_INET6,
1288 r->src.neg, pd->kif, M_GETFIB(pd->m)))
1289 r = r->skip[PF_SKIP_SRC_ADDR];
1290 else if (PF_MISMATCHAW(&r->dst.addr,
1291 (struct pf_addr *)&pd->dst, AF_INET6,
1292 r->dst.neg, NULL, M_GETFIB(pd->m)))
1293 r = r->skip[PF_SKIP_DST_ADDR];
1301 if (r == NULL || r->action == PF_NOSCRUB)
1305 pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
1306 pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
1308 pf_rule_to_actions(r, &pd->act);
1311 if (!pf_pull_hdr(pd->m, off, &frag, sizeof(frag), NULL, reason, AF_INET6))
1317 if (pd->virtual_proto == PF_VPROTO_FRAGMENT) {
1320 if (pf_reassemble6(&pd->m, &frag, off, pd->extoff, reason) != PF_PASS)
1322 if (pd->m == NULL)
1324 h = mtod(pd->m, struct ip6_hdr *);
1325 pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
1336 struct tcphdr *th = &pd->hdr.tcp;
1338 u_short reason;
1340 sa_family_t af = pd->af;
1350 pf_counter_u64_add(&r->evaluations, 1);
1351 if (pfi_kkif_match(r->kif, pd->kif) == r->ifnot)
1352 r = r->skip[PF_SKIP_IFP];
1353 else if (r->direction && r->direction != pd->dir)
1354 r = r->skip[PF_SKIP_DIR];
1355 else if (r->af && r->af != af)
1356 r = r->skip[PF_SKIP_AF];
1357 else if (r->proto && r->proto != pd->proto)
1358 r = r->skip[PF_SKIP_PROTO];
1359 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
1360 r->src.neg, pd->kif, M_GETFIB(pd->m)))
1361 r = r->skip[PF_SKIP_SRC_ADDR];
1362 else if (r->src.port_op && !pf_match_port(r->src.port_op,
1363 r->src.port[0], r->src.port[1], th->th_sport))
1364 r = r->skip[PF_SKIP_SRC_PORT];
1365 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
1366 r->dst.neg, NULL, M_GETFIB(pd->m)))
1367 r = r->skip[PF_SKIP_DST_ADDR];
1368 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
1369 r->dst.port[0], r->dst.port[1], th->th_dport))
1370 r = r->skip[PF_SKIP_DST_PORT];
1371 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
1373 r->os_fingerprint))
1384 if (rm == NULL || rm->action == PF_NOSCRUB)
1388 pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
1389 pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
1391 pf_rule_to_actions(rm, &pd->act);
1394 if (rm && rm->rule_flag & PFRULE_REASSEMBLE_TCP)
1395 pd->flags |= PFDESC_TCP_NORM;
1418 if (th->th_off < (sizeof(struct tcphdr) >> 2))
1426 ov = *(u_int16_t *)(&th->th_ack + 1);
1429 nv = *(u_int16_t *)(&th->th_ack + 1);
1431 th->th_sum = pf_proto_cksum_fixup(pd->m, th->th_sum, ov, nv, 0);
1436 if (!(flags & TH_URG) && th->th_urp) {
1437 th->th_sum = pf_proto_cksum_fixup(pd->m, th->th_sum, th->th_urp,
1439 th->th_urp = 0;
1445 m_copyback(pd->m, pd->off, sizeof(*th), (caddr_t)th);
1450 REASON_SET(&reason, PFRES_NORM);
1451 if (rm != NULL && r->log)
1452 PFLOG_PACKET(PF_DROP, reason, r, NULL, NULL, pd, 1);
1464 KASSERT((src->scrub == NULL),
1465 ("pf_normalize_tcp_init: src->scrub != NULL"));
1467 src->scrub = uma_zalloc(V_pf_state_scrub_z, M_ZERO | M_NOWAIT);
1468 if (src->scrub == NULL)
1471 switch (pd->af) {
1474 struct ip *h = mtod(pd->m, struct ip *);
1475 src->scrub->pfss_ttl = h->ip_ttl;
1481 struct ip6_hdr *h = mtod(pd->m, struct ip6_hdr *);
1482 src->scrub->pfss_ttl = h->ip6_hlim;
1495 if (th->th_off > (sizeof(struct tcphdr) >> 2) && src->scrub &&
1496 pf_pull_hdr(pd->m, pd->off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
1500 hlen = (th->th_off << 2) - sizeof(struct tcphdr);
1506 hlen--;
1510 src->scrub->pfss_flags |=
1512 src->scrub->pfss_ts_mod =
1520 src->scrub->pfss_tsval0 = ntohl(tsval);
1521 src->scrub->pfss_tsval = ntohl(tsval);
1522 src->scrub->pfss_tsecr = ntohl(tsecr);
1523 getmicrouptime(&src->scrub->pfss_last);
1527 hlen -= MAX(opt[1], 2);
1528 opt += MAX(opt[1], 2);
1541 uma_zfree(V_pf_state_scrub_z, state->src.scrub);
1542 uma_zfree(V_pf_state_scrub_z, state->dst.scrub);
1550 src->scrub = uma_zalloc(V_pf_state_scrub_z, M_ZERO | M_NOWAIT);
1551 if (src->scrub == NULL)
1554 dst->scrub = uma_zalloc(V_pf_state_scrub_z, M_ZERO | M_NOWAIT);
1555 if (dst->scrub == NULL) {
1560 dst->scrub->pfss_v_tag = pd->sctp_initiate_tag;
1567 u_short *reason, struct tcphdr *th, struct pf_kstate *state,
1579 KASSERT((src->scrub || dst->scrub),
1580 ("%s: src->scrub && dst->scrub!", __func__));
1587 switch (pd->af) {
1590 if (src->scrub) {
1591 struct ip *h = mtod(pd->m, struct ip *);
1592 if (h->ip_ttl > src->scrub->pfss_ttl)
1593 src->scrub->pfss_ttl = h->ip_ttl;
1594 h->ip_ttl = src->scrub->pfss_ttl;
1601 if (src->scrub) {
1602 struct ip6_hdr *h = mtod(pd->m, struct ip6_hdr *);
1603 if (h->ip6_hlim > src->scrub->pfss_ttl)
1604 src->scrub->pfss_ttl = h->ip6_hlim;
1605 h->ip6_hlim = src->scrub->pfss_ttl;
1612 if (th->th_off > (sizeof(struct tcphdr) >> 2) &&
1613 ((src->scrub && (src->scrub->pfss_flags & PFSS_TIMESTAMP)) ||
1614 (dst->scrub && (dst->scrub->pfss_flags & PFSS_TIMESTAMP))) &&
1615 pf_pull_hdr(pd->m, pd->off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
1619 hlen = (th->th_off << 2) - sizeof(struct tcphdr);
1621 startoff = opt - (hdr + sizeof(struct tcphdr));
1626 hlen--;
1641 REASON_SET(reason, PFRES_TS);
1647 if (tsval && src->scrub &&
1648 (src->scrub->pfss_flags &
1651 pf_patch_32_unaligned(pd->m,
1652 &th->th_sum,
1655 src->scrub->pfss_ts_mod),
1664 if (tsecr && dst->scrub &&
1665 (dst->scrub->pfss_flags &
1668 - dst->scrub->pfss_ts_mod;
1669 pf_patch_32_unaligned(pd->m,
1670 &th->th_sum,
1681 hlen -= MAX(opt[1], 2);
1682 opt += MAX(opt[1], 2);
1689 m_copyback(pd->m, pd->off + sizeof(struct tcphdr),
1690 (th->th_off << 2) - sizeof(struct tcphdr), hdr +
1706 if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
1707 (uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
1708 time_uptime - (state->creation / 1000) > TS_MAX_CONN)) {
1714 src->scrub->pfss_flags = (src->scrub->pfss_flags & ~PFSS_PAWS)
1717 if (dst->scrub && (dst->scrub->pfss_flags & PFSS_PAWS) &&
1718 uptime.tv_sec - dst->scrub->pfss_last.tv_sec > TS_MAX_IDLE) {
1724 dst->scrub->pfss_flags = (dst->scrub->pfss_flags & ~PFSS_PAWS)
1728 if (got_ts && src->scrub && dst->scrub &&
1729 (src->scrub->pfss_flags & PFSS_PAWS) &&
1730 (dst->scrub->pfss_flags & PFSS_PAWS)) {
1731 /* Validate that the timestamps are "in-window".
1745 * - The timestamp on this packet must be greater than
1751 * - The timestamp will be less than or equal to
1753 * last packet and now. The RFC defines the max
1758 * timestamp <= last timestamp + max ticks
1766 * - The TCP timestamp option must also echo the other
1774 * - The lowerbound on the TS echo is a little more
1777 * network conditions that re-order packets and
1801 if ((ts_fudge = state->rule->timeout[PFTM_TS_DIFF]) == 0)
1804 /* Calculate max ticks since the last timestamp */
1805 #define TS_MAXFREQ 1100 /* RFC max TS freq of 1Khz + 10% skew */
1808 timevalsub(&delta_ts, &src->scrub->pfss_last);
1812 if ((src->state >= TCPS_ESTABLISHED &&
1813 dst->state >= TCPS_ESTABLISHED) &&
1814 (SEQ_LT(tsval, dst->scrub->pfss_tsecr) ||
1815 SEQ_GT(tsval, src->scrub->pfss_tsval + tsval_from_last) ||
1816 (tsecr && (SEQ_GT(tsecr, dst->scrub->pfss_tsval) ||
1817 SEQ_LT(tsecr, dst->scrub->pfss_tsval0))))) {
1820 * - Solaris 2.6 and 2.7 are known to send another ACK
1826 SEQ_LT(tsval, dst->scrub->pfss_tsecr) ? '0' : ' ',
1827 SEQ_GT(tsval, src->scrub->pfss_tsval +
1829 SEQ_GT(tsecr, dst->scrub->pfss_tsval) ? '2' : ' ',
1830 SEQ_LT(tsecr, dst->scrub->pfss_tsval0)? '3' : ' '));
1836 DPFPRINTF((" src->tsval: %u tsecr: %u\n",
1837 src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
1838 DPFPRINTF((" dst->tsval: %u tsecr: %u tsval0: %u"
1839 "\n", dst->scrub->pfss_tsval,
1840 dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
1846 REASON_SET(reason, PFRES_TS);
1853 ((src->state == TCPS_ESTABLISHED && dst->state == TCPS_ESTABLISHED)
1854 || pd->p_len > 0 || (tcp_get_flags(th) & TH_SYN)) &&
1855 src->scrub && dst->scrub &&
1856 (src->scrub->pfss_flags & PFSS_PAWS) &&
1857 (dst->scrub->pfss_flags & PFSS_PAWS)) {
1860 * - connection opening or closing (often not even sent).
1863 * - on a TCP reset. RFC suggests not even looking at TS.
1864 * - on an empty ACK. The TS will not be echoed so it will
1868 * ACKs :-(
1884 if (pd->p_len > 0 && (src->scrub->pfss_flags & PFSS_DATA_TS)) {
1896 REASON_SET(reason, PFRES_TS);
1905 * timestamped. But I think there are middle-man devices that hijack
1909 if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
1912 src->scrub->pfss_flags |= PFSS_DATA_TS;
1914 src->scrub->pfss_flags |= PFSS_DATA_NOTS;
1915 if (V_pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
1916 (dst->scrub->pfss_flags & PFSS_TIMESTAMP)) {
1931 if (got_ts && src->scrub && PFSS_TIMESTAMP == (src->scrub->pfss_flags &
1933 getmicrouptime(&src->scrub->pfss_last);
1934 if (SEQ_GEQ(tsval, src->scrub->pfss_tsval) ||
1935 (src->scrub->pfss_flags & PFSS_PAWS) == 0)
1936 src->scrub->pfss_tsval = tsval;
1939 if (SEQ_GEQ(tsecr, src->scrub->pfss_tsecr) ||
1940 (src->scrub->pfss_flags & PFSS_PAWS) == 0)
1941 src->scrub->pfss_tsecr = tsecr;
1943 if ((src->scrub->pfss_flags & PFSS_PAWS) == 0 &&
1944 (SEQ_LT(tsval, src->scrub->pfss_tsval0) ||
1945 src->scrub->pfss_tsval0 == 0)) {
1947 src->scrub->pfss_tsval0 = tsval;
1951 if ((src->scrub->pfss_flags & PFSS_PAWS) == 0)
1952 src->scrub->pfss_flags |= PFSS_PAWS;
1963 struct tcphdr *th = &pd->hdr.tcp;
1971 thoff = th->th_off << 2;
1972 cnt = thoff - sizeof(struct tcphdr);
1974 if (cnt > 0 && !pf_pull_hdr(pd->m, pd->off + sizeof(*th), opts, cnt,
1975 NULL, NULL, pd->af))
1978 for (; cnt > 0; cnt -= optlen, optp += optlen) {
1979 startoff = optp - opts;
1995 if ((ntohs(*mss)) > pd->act.max_mss) {
1996 pf_patch_16_unaligned(pd->m,
1997 &th->th_sum,
1998 mss, htons(pd->act.max_mss),
2001 m_copyback(pd->m, pd->off + sizeof(*th),
2002 thoff - sizeof(*th), opts);
2003 m_copyback(pd->m, pd->off, sizeof(*th), (caddr_t)th);
2022 while (pd->off + chunk_off < pd->tot_len) {
2023 if (!pf_pull_hdr(pd->m, pd->off + chunk_off, &ch, sizeof(ch), NULL,
2024 NULL, pd->af))
2039 if (!pf_pull_hdr(pd->m, pd->off + chunk_start, &init,
2040 sizeof(init), NULL, NULL, pd->af))
2061 pd->hdr.sctp.v_tag != 0)
2064 pd->sctp_initiate_tag = init.init.initiate_tag;
2067 pd->sctp_flags |= PFDESC_SCTP_INIT;
2069 pd->sctp_flags |= PFDESC_SCTP_INIT_ACK;
2071 ret = pf_multihome_scan_init(pd->off + chunk_start,
2079 pd->sctp_flags |= PFDESC_SCTP_ABORT;
2083 pd->sctp_flags |= PFDESC_SCTP_SHUTDOWN;
2086 pd->sctp_flags |= PFDESC_SCTP_SHUTDOWN_COMPLETE;
2089 pd->sctp_flags |= PFDESC_SCTP_COOKIE;
2092 pd->sctp_flags |= PFDESC_SCTP_COOKIE_ACK;
2095 pd->sctp_flags |= PFDESC_SCTP_DATA;
2098 pd->sctp_flags |= PFDESC_SCTP_HEARTBEAT;
2101 pd->sctp_flags |= PFDESC_SCTP_HEARTBEAT_ACK;
2104 pd->sctp_flags |= PFDESC_SCTP_ASCONF;
2106 ret = pf_multihome_scan_asconf(pd->off + chunk_start,
2112 pd->sctp_flags |= PFDESC_SCTP_OTHER;
2118 if (pd->off + chunk_off != pd->tot_len)
2125 if ((pd->sctp_flags & PFDESC_SCTP_INIT) &&
2126 (pd->sctp_flags & ~PFDESC_SCTP_INIT))
2128 if ((pd->sctp_flags & PFDESC_SCTP_INIT_ACK) &&
2129 (pd->sctp_flags & ~PFDESC_SCTP_INIT_ACK))
2131 if ((pd->sctp_flags & PFDESC_SCTP_SHUTDOWN_COMPLETE) &&
2132 (pd->sctp_flags & ~PFDESC_SCTP_SHUTDOWN_COMPLETE))
2134 if ((pd->sctp_flags & PFDESC_SCTP_ABORT) &&
2135 (pd->sctp_flags & PFDESC_SCTP_DATA)) {
2150 struct sctphdr *sh = &pd->hdr.sctp;
2151 u_short reason;
2152 sa_family_t af = pd->af;
2162 pf_counter_u64_add(&r->evaluations, 1);
2163 if (pfi_kkif_match(r->kif, pd->kif) == r->ifnot)
2164 r = r->skip[PF_SKIP_IFP];
2165 else if (r->direction && r->direction != pd->dir)
2166 r = r->skip[PF_SKIP_DIR];
2167 else if (r->af && r->af != af)
2168 r = r->skip[PF_SKIP_AF];
2169 else if (r->proto && r->proto != pd->proto)
2170 r = r->skip[PF_SKIP_PROTO];
2171 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
2172 r->src.neg, pd->kif, M_GETFIB(pd->m)))
2173 r = r->skip[PF_SKIP_SRC_ADDR];
2174 else if (r->src.port_op && !pf_match_port(r->src.port_op,
2175 r->src.port[0], r->src.port[1], sh->src_port))
2176 r = r->skip[PF_SKIP_SRC_PORT];
2177 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
2178 r->dst.neg, NULL, M_GETFIB(pd->m)))
2179 r = r->skip[PF_SKIP_DST_ADDR];
2180 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
2181 r->dst.port[0], r->dst.port[1], sh->dest_port))
2182 r = r->skip[PF_SKIP_DST_PORT];
2192 if (rm == NULL || rm->action == PF_NOSCRUB)
2196 pf_counter_u64_add_protected(&r->packets[pd->dir == PF_OUT], 1);
2197 pf_counter_u64_add_protected(&r->bytes[pd->dir == PF_OUT], pd->tot_len);
2202 if ((pd->tot_len - pd->off - sizeof(struct sctphdr)) % 4)
2206 if (pd->sctp_flags & PFDESC_SCTP_INIT)
2207 if (pd->sctp_flags & ~PFDESC_SCTP_INIT)
2213 REASON_SET(&reason, PFRES_NORM);
2214 if (rm != NULL && r->log)
2215 PFLOG_PACKET(PF_DROP, reason, r, NULL, NULL, pd,
2226 struct ip *h = mtod(pd->m, struct ip *);
2228 struct ip6_hdr *h6 = mtod(pd->m, struct ip6_hdr *);
2231 /* Clear IP_DF if no-df was requested */
2232 if (pd->af == AF_INET && pd->act.flags & PFSTATE_NODF &&
2233 h->ip_off & htons(IP_DF))
2235 u_int16_t ip_off = h->ip_off;
2237 h->ip_off &= htons(~IP_DF);
2238 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
2242 if (pd->af == AF_INET && pd->act.min_ttl &&
2243 h->ip_ttl < pd->act.min_ttl) {
2244 u_int16_t ip_ttl = h->ip_ttl;
2246 h->ip_ttl = pd->act.min_ttl;
2247 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
2251 if (pd->af == AF_INET6 && pd->act.min_ttl &&
2252 h6->ip6_hlim < pd->act.min_ttl)
2253 h6->ip6_hlim = pd->act.min_ttl;
2256 if (pd->act.flags & PFSTATE_SETTOS) {
2257 switch (pd->af) {
2262 h->ip_tos = pd->act.set_tos | (h->ip_tos & IPTOS_ECN_MASK);
2265 h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
2270 h6->ip6_flow &= IPV6_FLOWLABEL_MASK | IPV6_VERSION_MASK;
2271 h6->ip6_flow |= htonl((pd->act.set_tos | IPV6_ECN(h6)) << 20);
2277 /* random-id, but not for fragments */
2279 if (pd->af == AF_INET &&
2280 pd->act.flags & PFSTATE_RANDOMID && !(h->ip_off & ~htons(IP_DF))) {
2281 uint16_t ip_id = h->ip_id;
2284 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);