Deleted Added
full compact
pf_norm.c (133720) pf_norm.c (145836)
1/* $FreeBSD: head/sys/contrib/pf/net/pf_norm.c 133720 2004-08-14 15:32:40Z dwmalone $ */
2/* $OpenBSD: pf_norm.c,v 1.80.2.1 2004/04/30 21:46:33 brad Exp $ */
3/* add $OpenBSD: pf_norm.c,v 1.87 2004/05/11 07:34:11 dhartmei Exp $ */
1/* $FreeBSD: head/sys/contrib/pf/net/pf_norm.c 145836 2005-05-03 16:43:32Z mlaier $ */
2/* $OpenBSD: pf_norm.c,v 1.97 2004/09/21 16:59:12 aaron Exp $ */
4
5/*
6 * Copyright 2001 Niels Provos <provos@citi.umich.edu>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:

--- 162 unchanged lines hidden (view full) ---

174struct pf_fragment *pf_find_fragment(struct ip *, struct pf_frag_tree *);
175struct mbuf *pf_reassemble(struct mbuf **, struct pf_fragment **,
176 struct pf_frent *, int);
177struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
178 struct pf_fragment **, int, int, int *);
179int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
180 struct tcphdr *, int);
181
3
4/*
5 * Copyright 2001 Niels Provos <provos@citi.umich.edu>
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:

--- 162 unchanged lines hidden (view full) ---

173struct pf_fragment *pf_find_fragment(struct ip *, struct pf_frag_tree *);
174struct mbuf *pf_reassemble(struct mbuf **, struct pf_fragment **,
175 struct pf_frent *, int);
176struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
177 struct pf_fragment **, int, int, int *);
178int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
179 struct tcphdr *, int);
180
182#define DPFPRINTF(x) if (pf_status.debug >= PF_DEBUG_MISC) \
183 { printf("%s: ", __func__); printf x ;}
181#define DPFPRINTF(x) do { \
182 if (pf_status.debug >= PF_DEBUG_MISC) { \
183 printf("%s: ", __func__); \
184 printf x ; \
185 } \
186} while(0)
184
185/* Globals */
186#ifdef __FreeBSD__
187uma_zone_t pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
188uma_zone_t pf_state_scrub_pl;
189#else
190struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
191struct pool pf_state_scrub_pl;

--- 57 unchanged lines hidden (view full) ---

249 return (1);
250 return (0);
251}
252
253void
254pf_purge_expired_fragments(void)
255{
256 struct pf_fragment *frag;
187
188/* Globals */
189#ifdef __FreeBSD__
190uma_zone_t pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
191uma_zone_t pf_state_scrub_pl;
192#else
193struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
194struct pool pf_state_scrub_pl;

--- 57 unchanged lines hidden (view full) ---

252 return (1);
253 return (0);
254}
255
256void
257pf_purge_expired_fragments(void)
258{
259 struct pf_fragment *frag;
257#ifdef __FreeBSD__
258 u_int32_t expire = time_second -
260 u_int32_t expire = time_second -
259 pf_default_rule.timeout[PFTM_FRAG];
261 pf_default_rule.timeout[PFTM_FRAG];
260#else
261 u_int32_t expire = time.tv_sec -
262 pf_default_rule.timeout[PFTM_FRAG];
263#endif
264
265 while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
266#ifdef __FreeBSD__
267 KASSERT((BUFFER_FRAGMENTS(frag)),
268 ("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
269#else
270 KASSERT(BUFFER_FRAGMENTS(frag));
271#endif

--- 118 unchanged lines hidden (view full) ---

390 struct pf_fragment key;
391 struct pf_fragment *frag;
392
393 pf_ip2key(&key, ip);
394
395 frag = RB_FIND(pf_frag_tree, tree, &key);
396 if (frag != NULL) {
397 /* XXX Are we sure we want to update the timeout? */
262
263 while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
264#ifdef __FreeBSD__
265 KASSERT((BUFFER_FRAGMENTS(frag)),
266 ("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
267#else
268 KASSERT(BUFFER_FRAGMENTS(frag));
269#endif

--- 118 unchanged lines hidden (view full) ---

388 struct pf_fragment key;
389 struct pf_fragment *frag;
390
391 pf_ip2key(&key, ip);
392
393 frag = RB_FIND(pf_frag_tree, tree, &key);
394 if (frag != NULL) {
395 /* XXX Are we sure we want to update the timeout? */
398#ifdef __FreeBSD__
399 frag->fr_timeout = time_second;
396 frag->fr_timeout = time_second;
400#else
401 frag->fr_timeout = time.tv_sec;
402#endif
403 if (BUFFER_FRAGMENTS(frag)) {
404 TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
405 TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
406 } else {
407 TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
408 TAILQ_INSERT_HEAD(&pf_cachequeue, frag, frag_next);
409 }
410 }

--- 53 unchanged lines hidden (view full) ---

464 }
465
466 (*frag)->fr_flags = 0;
467 (*frag)->fr_max = 0;
468 (*frag)->fr_src = frent->fr_ip->ip_src;
469 (*frag)->fr_dst = frent->fr_ip->ip_dst;
470 (*frag)->fr_p = frent->fr_ip->ip_p;
471 (*frag)->fr_id = frent->fr_ip->ip_id;
397 if (BUFFER_FRAGMENTS(frag)) {
398 TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
399 TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
400 } else {
401 TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
402 TAILQ_INSERT_HEAD(&pf_cachequeue, frag, frag_next);
403 }
404 }

--- 53 unchanged lines hidden (view full) ---

458 }
459
460 (*frag)->fr_flags = 0;
461 (*frag)->fr_max = 0;
462 (*frag)->fr_src = frent->fr_ip->ip_src;
463 (*frag)->fr_dst = frent->fr_ip->ip_dst;
464 (*frag)->fr_p = frent->fr_ip->ip_p;
465 (*frag)->fr_id = frent->fr_ip->ip_id;
472#ifdef __FreeBSD__
473 (*frag)->fr_timeout = time_second;
466 (*frag)->fr_timeout = time_second;
474#else
475 (*frag)->fr_timeout = time.tv_sec;
476#endif
477 LIST_INIT(&(*frag)->fr_queue);
478
479 RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
480 TAILQ_INSERT_HEAD(&pf_fragqueue, *frag, frag_next);
481
482 /* We do not have a previous fragment */
483 frep = NULL;
484 goto insert;

--- 199 unchanged lines hidden (view full) ---

684 pf_ncache++;
685
686 (*frag)->fr_flags = PFFRAG_NOBUFFER;
687 (*frag)->fr_max = 0;
688 (*frag)->fr_src = h->ip_src;
689 (*frag)->fr_dst = h->ip_dst;
690 (*frag)->fr_p = h->ip_p;
691 (*frag)->fr_id = h->ip_id;
467 LIST_INIT(&(*frag)->fr_queue);
468
469 RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
470 TAILQ_INSERT_HEAD(&pf_fragqueue, *frag, frag_next);
471
472 /* We do not have a previous fragment */
473 frep = NULL;
474 goto insert;

--- 199 unchanged lines hidden (view full) ---

674 pf_ncache++;
675
676 (*frag)->fr_flags = PFFRAG_NOBUFFER;
677 (*frag)->fr_max = 0;
678 (*frag)->fr_src = h->ip_src;
679 (*frag)->fr_dst = h->ip_dst;
680 (*frag)->fr_p = h->ip_p;
681 (*frag)->fr_id = h->ip_id;
692#ifdef __FreeBSD__
693 (*frag)->fr_timeout = time_second;
682 (*frag)->fr_timeout = time_second;
694#else
695 (*frag)->fr_timeout = time.tv_sec;
696#endif
697
698 cur->fr_off = off;
699 cur->fr_end = max;
700 LIST_INIT(&(*frag)->fr_cache);
701 LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
702
703 RB_INSERT(pf_frag_tree, &pf_cache_tree, *frag);
704 TAILQ_INSERT_HEAD(&pf_cachequeue, *frag, frag_next);

--- 277 unchanged lines hidden (view full) ---

982 (*frag)->fr_flags |= PFFRAG_DROP;
983 }
984
985 m_freem(m);
986 return (NULL);
987}
988
989int
683
684 cur->fr_off = off;
685 cur->fr_end = max;
686 LIST_INIT(&(*frag)->fr_cache);
687 LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
688
689 RB_INSERT(pf_frag_tree, &pf_cache_tree, *frag);
690 TAILQ_INSERT_HEAD(&pf_cachequeue, *frag, frag_next);

--- 277 unchanged lines hidden (view full) ---

968 (*frag)->fr_flags |= PFFRAG_DROP;
969 }
970
971 m_freem(m);
972 return (NULL);
973}
974
975int
990pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason)
976pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
977 struct pf_pdesc *pd)
991{
992 struct mbuf *m = *m0;
993 struct pf_rule *r;
994 struct pf_frent *frent;
995 struct pf_fragment *frag = NULL;
996 struct ip *h = mtod(m, struct ip *);
997 int mff = (ntohs(h->ip_off) & IP_MF);
998 int hlen = h->ip_hl << 2;

--- 10 unchanged lines hidden (view full) ---

1009 r = r->skip[PF_SKIP_IFP].ptr;
1010 else if (r->direction && r->direction != dir)
1011 r = r->skip[PF_SKIP_DIR].ptr;
1012 else if (r->af && r->af != AF_INET)
1013 r = r->skip[PF_SKIP_AF].ptr;
1014 else if (r->proto && r->proto != h->ip_p)
1015 r = r->skip[PF_SKIP_PROTO].ptr;
1016 else if (PF_MISMATCHAW(&r->src.addr,
978{
979 struct mbuf *m = *m0;
980 struct pf_rule *r;
981 struct pf_frent *frent;
982 struct pf_fragment *frag = NULL;
983 struct ip *h = mtod(m, struct ip *);
984 int mff = (ntohs(h->ip_off) & IP_MF);
985 int hlen = h->ip_hl << 2;

--- 10 unchanged lines hidden (view full) ---

996 r = r->skip[PF_SKIP_IFP].ptr;
997 else if (r->direction && r->direction != dir)
998 r = r->skip[PF_SKIP_DIR].ptr;
999 else if (r->af && r->af != AF_INET)
1000 r = r->skip[PF_SKIP_AF].ptr;
1001 else if (r->proto && r->proto != h->ip_p)
1002 r = r->skip[PF_SKIP_PROTO].ptr;
1003 else if (PF_MISMATCHAW(&r->src.addr,
1017 (struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.not))
1004 (struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.neg))
1018 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1019 else if (PF_MISMATCHAW(&r->dst.addr,
1005 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1006 else if (PF_MISMATCHAW(&r->dst.addr,
1020 (struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.not))
1007 (struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.neg))
1021 r = r->skip[PF_SKIP_DST_ADDR].ptr;
1022 else
1023 break;
1024 }
1025
1026 if (r == NULL)
1027 return (PF_PASS);
1028 else

--- 125 unchanged lines hidden (view full) ---

1154 h->ip_ttl = r->min_ttl;
1155
1156 if (r->rule_flag & PFRULE_RANDOMID) {
1157 u_int16_t ip_id = h->ip_id;
1158
1159 h->ip_id = ip_randomid();
1160 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
1161 }
1008 r = r->skip[PF_SKIP_DST_ADDR].ptr;
1009 else
1010 break;
1011 }
1012
1013 if (r == NULL)
1014 return (PF_PASS);
1015 else

--- 125 unchanged lines hidden (view full) ---

1141 h->ip_ttl = r->min_ttl;
1142
1143 if (r->rule_flag & PFRULE_RANDOMID) {
1144 u_int16_t ip_id = h->ip_id;
1145
1146 h->ip_id = ip_randomid();
1147 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
1148 }
1149 if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
1150 pd->flags |= PFDESC_IP_REAS;
1162
1163 return (PF_PASS);
1164
1165 fragment_pass:
1166 /* Enforce a minimum ttl, may cause endless packet loops */
1167 if (r->min_ttl && h->ip_ttl < r->min_ttl)
1168 h->ip_ttl = r->min_ttl;
1151
1152 return (PF_PASS);
1153
1154 fragment_pass:
1155 /* Enforce a minimum ttl, may cause endless packet loops */
1156 if (r->min_ttl && h->ip_ttl < r->min_ttl)
1157 h->ip_ttl = r->min_ttl;
1169
1158 if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
1159 pd->flags |= PFDESC_IP_REAS;
1170 return (PF_PASS);
1171
1172 no_mem:
1173 REASON_SET(reason, PFRES_MEMORY);
1174 if (r != NULL && r->log)
1175 PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
1176 return (PF_DROP);
1177

--- 15 unchanged lines hidden (view full) ---

1193 PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
1194
1195 return (PF_DROP);
1196}
1197
1198#ifdef INET6
1199int
1200pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
1160 return (PF_PASS);
1161
1162 no_mem:
1163 REASON_SET(reason, PFRES_MEMORY);
1164 if (r != NULL && r->log)
1165 PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
1166 return (PF_DROP);
1167

--- 15 unchanged lines hidden (view full) ---

1183 PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
1184
1185 return (PF_DROP);
1186}
1187
1188#ifdef INET6
1189int
1190pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
1201 u_short *reason)
1191 u_short *reason, struct pf_pdesc *pd)
1202{
1203 struct mbuf *m = *m0;
1204 struct pf_rule *r;
1205 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
1206 int off;
1207 struct ip6_ext ext;
1208 struct ip6_opt opt;
1209 struct ip6_opt_jumbo jumbo;

--- 15 unchanged lines hidden (view full) ---

1225 r = r->skip[PF_SKIP_DIR].ptr;
1226 else if (r->af && r->af != AF_INET6)
1227 r = r->skip[PF_SKIP_AF].ptr;
1228#if 0 /* header chain! */
1229 else if (r->proto && r->proto != h->ip6_nxt)
1230 r = r->skip[PF_SKIP_PROTO].ptr;
1231#endif
1232 else if (PF_MISMATCHAW(&r->src.addr,
1192{
1193 struct mbuf *m = *m0;
1194 struct pf_rule *r;
1195 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
1196 int off;
1197 struct ip6_ext ext;
1198 struct ip6_opt opt;
1199 struct ip6_opt_jumbo jumbo;

--- 15 unchanged lines hidden (view full) ---

1215 r = r->skip[PF_SKIP_DIR].ptr;
1216 else if (r->af && r->af != AF_INET6)
1217 r = r->skip[PF_SKIP_AF].ptr;
1218#if 0 /* header chain! */
1219 else if (r->proto && r->proto != h->ip6_nxt)
1220 r = r->skip[PF_SKIP_PROTO].ptr;
1221#endif
1222 else if (PF_MISMATCHAW(&r->src.addr,
1233 (struct pf_addr *)&h->ip6_src, AF_INET6, r->src.not))
1223 (struct pf_addr *)&h->ip6_src, AF_INET6, r->src.neg))
1234 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1235 else if (PF_MISMATCHAW(&r->dst.addr,
1224 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1225 else if (PF_MISMATCHAW(&r->dst.addr,
1236 (struct pf_addr *)&h->ip6_dst, AF_INET6, r->dst.not))
1226 (struct pf_addr *)&h->ip6_dst, AF_INET6, r->dst.neg))
1237 r = r->skip[PF_SKIP_DST_ADDR].ptr;
1238 else
1239 break;
1240 }
1241
1242 if (r == NULL)
1243 return (PF_PASS);
1244 else

--- 98 unchanged lines hidden (view full) ---

1343
1344 if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6))
1345 goto shortpkt;
1346 fragoff = ntohs(frag.ip6f_offlg & IP6F_OFF_MASK);
1347 if (fragoff + (plen - off - sizeof(frag)) > IPV6_MAXPACKET)
1348 goto badfrag;
1349
1350 /* do something about it */
1227 r = r->skip[PF_SKIP_DST_ADDR].ptr;
1228 else
1229 break;
1230 }
1231
1232 if (r == NULL)
1233 return (PF_PASS);
1234 else

--- 98 unchanged lines hidden (view full) ---

1333
1334 if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6))
1335 goto shortpkt;
1336 fragoff = ntohs(frag.ip6f_offlg & IP6F_OFF_MASK);
1337 if (fragoff + (plen - off - sizeof(frag)) > IPV6_MAXPACKET)
1338 goto badfrag;
1339
1340 /* do something about it */
1341 /* remember to set pd->flags |= PFDESC_IP_REAS */
1351 return (PF_PASS);
1352
1353 shortpkt:
1354 REASON_SET(reason, PFRES_SHORT);
1355 if (r != NULL && r->log)
1356 PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
1357 return (PF_DROP);
1358

--- 4 unchanged lines hidden (view full) ---

1363 return (PF_DROP);
1364
1365 badfrag:
1366 REASON_SET(reason, PFRES_FRAG);
1367 if (r != NULL && r->log)
1368 PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
1369 return (PF_DROP);
1370}
1342 return (PF_PASS);
1343
1344 shortpkt:
1345 REASON_SET(reason, PFRES_SHORT);
1346 if (r != NULL && r->log)
1347 PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
1348 return (PF_DROP);
1349

--- 4 unchanged lines hidden (view full) ---

1354 return (PF_DROP);
1355
1356 badfrag:
1357 REASON_SET(reason, PFRES_FRAG);
1358 if (r != NULL && r->log)
1359 PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
1360 return (PF_DROP);
1361}
1371#endif
1362#endif /* INET6 */
1372
1373int
1374pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
1375 int off, void *h, struct pf_pdesc *pd)
1376{
1377 struct pf_rule *r, *rm = NULL;
1378 struct tcphdr *th = pd->hdr.tcp;
1379 int rewrite = 0;

--- 8 unchanged lines hidden (view full) ---

1388 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
1389 r = r->skip[PF_SKIP_IFP].ptr;
1390 else if (r->direction && r->direction != dir)
1391 r = r->skip[PF_SKIP_DIR].ptr;
1392 else if (r->af && r->af != af)
1393 r = r->skip[PF_SKIP_AF].ptr;
1394 else if (r->proto && r->proto != pd->proto)
1395 r = r->skip[PF_SKIP_PROTO].ptr;
1363
1364int
1365pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
1366 int off, void *h, struct pf_pdesc *pd)
1367{
1368 struct pf_rule *r, *rm = NULL;
1369 struct tcphdr *th = pd->hdr.tcp;
1370 int rewrite = 0;

--- 8 unchanged lines hidden (view full) ---

1379 (r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
1380 r = r->skip[PF_SKIP_IFP].ptr;
1381 else if (r->direction && r->direction != dir)
1382 r = r->skip[PF_SKIP_DIR].ptr;
1383 else if (r->af && r->af != af)
1384 r = r->skip[PF_SKIP_AF].ptr;
1385 else if (r->proto && r->proto != pd->proto)
1386 r = r->skip[PF_SKIP_PROTO].ptr;
1396 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not))
1387 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
1397 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1398 else if (r->src.port_op && !pf_match_port(r->src.port_op,
1399 r->src.port[0], r->src.port[1], th->th_sport))
1400 r = r->skip[PF_SKIP_SRC_PORT].ptr;
1388 r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1389 else if (r->src.port_op && !pf_match_port(r->src.port_op,
1390 r->src.port[0], r->src.port[1], th->th_sport))
1391 r = r->skip[PF_SKIP_SRC_PORT].ptr;
1401 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not))
1392 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
1402 r = r->skip[PF_SKIP_DST_ADDR].ptr;
1403 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
1404 r->dst.port[0], r->dst.port[1], th->th_dport))
1405 r = r->skip[PF_SKIP_DST_PORT].ptr;
1406 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
1407 pf_osfp_fingerprint(pd, m, off, th),
1408 r->os_fingerprint))
1409 r = TAILQ_NEXT(r, entries);
1410 else {
1411 rm = r;
1412 break;
1413 }
1414 }
1415
1393 r = r->skip[PF_SKIP_DST_ADDR].ptr;
1394 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
1395 r->dst.port[0], r->dst.port[1], th->th_dport))
1396 r = r->skip[PF_SKIP_DST_PORT].ptr;
1397 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
1398 pf_osfp_fingerprint(pd, m, off, th),
1399 r->os_fingerprint))
1400 r = TAILQ_NEXT(r, entries);
1401 else {
1402 rm = r;
1403 break;
1404 }
1405 }
1406
1416 if (rm == NULL)
1407 if (rm == NULL || rm->action == PF_NOSCRUB)
1417 return (PF_PASS);
1418 else
1419 r->packets++;
1420
1421 if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
1422 pd->flags |= PFDESC_TCP_NORM;
1423
1424 flags = th->th_flags;

--- 56 unchanged lines hidden (view full) ---

1481 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL);
1482 return (PF_DROP);
1483}
1484
1485int
1486pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
1487 struct tcphdr *th, struct pf_state_peer *src, struct pf_state_peer *dst)
1488{
1408 return (PF_PASS);
1409 else
1410 r->packets++;
1411
1412 if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
1413 pd->flags |= PFDESC_TCP_NORM;
1414
1415 flags = th->th_flags;

--- 56 unchanged lines hidden (view full) ---

1472 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL);
1473 return (PF_DROP);
1474}
1475
1476int
1477pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
1478 struct tcphdr *th, struct pf_state_peer *src, struct pf_state_peer *dst)
1479{
1480 u_int32_t tsval, tsecr;
1489 u_int8_t hdr[60];
1490 u_int8_t *opt;
1491
1492#ifdef __FreeBSD__
1493 KASSERT((src->scrub == NULL),
1494 ("pf_normalize_tcp_init: src->scrub != NULL"));
1495#else
1496 KASSERT(src->scrub == NULL);

--- 42 unchanged lines hidden (view full) ---

1539 case TCPOPT_NOP:
1540 opt++;
1541 hlen--;
1542 break;
1543 case TCPOPT_TIMESTAMP:
1544 if (opt[1] >= TCPOLEN_TIMESTAMP) {
1545 src->scrub->pfss_flags |=
1546 PFSS_TIMESTAMP;
1481 u_int8_t hdr[60];
1482 u_int8_t *opt;
1483
1484#ifdef __FreeBSD__
1485 KASSERT((src->scrub == NULL),
1486 ("pf_normalize_tcp_init: src->scrub != NULL"));
1487#else
1488 KASSERT(src->scrub == NULL);

--- 42 unchanged lines hidden (view full) ---

1531 case TCPOPT_NOP:
1532 opt++;
1533 hlen--;
1534 break;
1535 case TCPOPT_TIMESTAMP:
1536 if (opt[1] >= TCPOLEN_TIMESTAMP) {
1537 src->scrub->pfss_flags |=
1538 PFSS_TIMESTAMP;
1547 src->scrub->pfss_ts_mod = arc4random();
1539 src->scrub->pfss_ts_mod =
1540 htonl(arc4random());
1541
1542 /* note PFSS_PAWS not set yet */
1543 memcpy(&tsval, &opt[2],
1544 sizeof(u_int32_t));
1545 memcpy(&tsecr, &opt[6],
1546 sizeof(u_int32_t));
1547 src->scrub->pfss_tsval0 = ntohl(tsval);
1548 src->scrub->pfss_tsval = ntohl(tsval);
1549 src->scrub->pfss_tsecr = ntohl(tsecr);
1550 getmicrouptime(&src->scrub->pfss_last);
1548 }
1549 /* FALLTHROUGH */
1550 default:
1551 hlen -= MAX(opt[1], 2);
1552 opt += MAX(opt[1], 2);
1553 break;
1554 }
1555 }

--- 10 unchanged lines hidden (view full) ---

1566 if (state->dst.scrub)
1567 pool_put(&pf_state_scrub_pl, state->dst.scrub);
1568
1569 /* Someday... flush the TCP segment reassembly descriptors. */
1570}
1571
1572int
1573pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
1551 }
1552 /* FALLTHROUGH */
1553 default:
1554 hlen -= MAX(opt[1], 2);
1555 opt += MAX(opt[1], 2);
1556 break;
1557 }
1558 }

--- 10 unchanged lines hidden (view full) ---

1569 if (state->dst.scrub)
1570 pool_put(&pf_state_scrub_pl, state->dst.scrub);
1571
1572 /* Someday... flush the TCP segment reassembly descriptors. */
1573}
1574
1575int
1576pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
1574 u_short *reason, struct tcphdr *th, struct pf_state_peer *src,
1575 struct pf_state_peer *dst, int *writeback)
1577 u_short *reason, struct tcphdr *th, struct pf_state *state,
1578 struct pf_state_peer *src, struct pf_state_peer *dst, int *writeback)
1576{
1579{
1580 struct timeval uptime;
1581 u_int32_t tsval, tsecr;
1582 u_int tsval_from_last;
1577 u_int8_t hdr[60];
1578 u_int8_t *opt;
1579 int copyback = 0;
1583 u_int8_t hdr[60];
1584 u_int8_t *opt;
1585 int copyback = 0;
1586 int got_ts = 0;
1580
1581#ifdef __FreeBSD__
1582 KASSERT((src->scrub || dst->scrub),
1583 ("pf_normalize_tcp_statefull: src->scrub && dst->scrub!"));
1584#else
1585 KASSERT(src->scrub || dst->scrub);
1586#endif
1587

--- 42 unchanged lines hidden (view full) ---

1630 opt++;
1631 hlen--;
1632 break;
1633 case TCPOPT_TIMESTAMP:
1634 /* Modulate the timestamps. Can be used for
1635 * NAT detection, OS uptime determination or
1636 * reboot detection.
1637 */
1587
1588#ifdef __FreeBSD__
1589 KASSERT((src->scrub || dst->scrub),
1590 ("pf_normalize_tcp_statefull: src->scrub && dst->scrub!"));
1591#else
1592 KASSERT(src->scrub || dst->scrub);
1593#endif
1594

--- 42 unchanged lines hidden (view full) ---

1637 opt++;
1638 hlen--;
1639 break;
1640 case TCPOPT_TIMESTAMP:
1641 /* Modulate the timestamps. Can be used for
1642 * NAT detection, OS uptime determination or
1643 * reboot detection.
1644 */
1645
1646 if (got_ts) {
1647 /* Huh? Multiple timestamps!? */
1648 if (pf_status.debug >= PF_DEBUG_MISC) {
1649 DPFPRINTF(("multiple TS??"));
1650 pf_print_state(state);
1651 printf("\n");
1652 }
1653 REASON_SET(reason, PFRES_TS);
1654 return (PF_DROP);
1655 }
1638 if (opt[1] >= TCPOLEN_TIMESTAMP) {
1656 if (opt[1] >= TCPOLEN_TIMESTAMP) {
1639 u_int32_t ts_value;
1640 if (src->scrub &&
1657 memcpy(&tsval, &opt[2],
1658 sizeof(u_int32_t));
1659 if (tsval && src->scrub &&
1641 (src->scrub->pfss_flags &
1642 PFSS_TIMESTAMP)) {
1660 (src->scrub->pfss_flags &
1661 PFSS_TIMESTAMP)) {
1643 memcpy(&ts_value, &opt[2],
1644 sizeof(u_int32_t));
1645 ts_value = htonl(ntohl(ts_value)
1646 + src->scrub->pfss_ts_mod);
1662 tsval = ntohl(tsval);
1647 pf_change_a(&opt[2],
1663 pf_change_a(&opt[2],
1648 &th->th_sum, ts_value, 0);
1664 &th->th_sum,
1665 htonl(tsval +
1666 src->scrub->pfss_ts_mod),
1667 0);
1649 copyback = 1;
1650 }
1651
1652 /* Modulate TS reply iff valid (!0) */
1668 copyback = 1;
1669 }
1670
1671 /* Modulate TS reply iff valid (!0) */
1653 memcpy(&ts_value, &opt[6],
1672 memcpy(&tsecr, &opt[6],
1654 sizeof(u_int32_t));
1673 sizeof(u_int32_t));
1655 if (ts_value && dst->scrub &&
1674 if (tsecr && dst->scrub &&
1656 (dst->scrub->pfss_flags &
1657 PFSS_TIMESTAMP)) {
1675 (dst->scrub->pfss_flags &
1676 PFSS_TIMESTAMP)) {
1658 ts_value = htonl(ntohl(ts_value)
1659 - dst->scrub->pfss_ts_mod);
1677 tsecr = ntohl(tsecr)
1678 - dst->scrub->pfss_ts_mod;
1660 pf_change_a(&opt[6],
1679 pf_change_a(&opt[6],
1661 &th->th_sum, ts_value, 0);
1680 &th->th_sum, htonl(tsecr),
1681 0);
1662 copyback = 1;
1663 }
1682 copyback = 1;
1683 }
1684 got_ts = 1;
1664 }
1665 /* FALLTHROUGH */
1666 default:
1667 hlen -= MAX(opt[1], 2);
1668 opt += MAX(opt[1], 2);
1669 break;
1670 }
1671 }
1672 if (copyback) {
1673 /* Copyback the options, caller copys back header */
1674 *writeback = 1;
1675 m_copyback(m, off + sizeof(struct tcphdr),
1676 (th->th_off << 2) - sizeof(struct tcphdr), hdr +
1677 sizeof(struct tcphdr));
1678 }
1679 }
1680
1681
1685 }
1686 /* FALLTHROUGH */
1687 default:
1688 hlen -= MAX(opt[1], 2);
1689 opt += MAX(opt[1], 2);
1690 break;
1691 }
1692 }
1693 if (copyback) {
1694 /* Copyback the options, caller copys back header */
1695 *writeback = 1;
1696 m_copyback(m, off + sizeof(struct tcphdr),
1697 (th->th_off << 2) - sizeof(struct tcphdr), hdr +
1698 sizeof(struct tcphdr));
1699 }
1700 }
1701
1702
1703 /*
1704 * Must invalidate PAWS checks on connections idle for too long.
1705 * The fastest allowed timestamp clock is 1ms. That turns out to
1706 * be about 24 days before it wraps. XXX Right now our lowerbound
1707 * TS echo check only works for the first 12 days of a connection
1708 * when the TS has exhausted half its 32bit space
1709 */
1710#define TS_MAX_IDLE (24*24*60*60)
1711#define TS_MAX_CONN (12*24*60*60) /* XXX remove when better tsecr check */
1712
1713 getmicrouptime(&uptime);
1714 if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
1715 (uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
1716 time_second - state->creation > TS_MAX_CONN)) {
1717 if (pf_status.debug >= PF_DEBUG_MISC) {
1718 DPFPRINTF(("src idled out of PAWS\n"));
1719 pf_print_state(state);
1720 printf("\n");
1721 }
1722 src->scrub->pfss_flags = (src->scrub->pfss_flags & ~PFSS_PAWS)
1723 | PFSS_PAWS_IDLED;
1724 }
1725 if (dst->scrub && (dst->scrub->pfss_flags & PFSS_PAWS) &&
1726 uptime.tv_sec - dst->scrub->pfss_last.tv_sec > TS_MAX_IDLE) {
1727 if (pf_status.debug >= PF_DEBUG_MISC) {
1728 DPFPRINTF(("dst idled out of PAWS\n"));
1729 pf_print_state(state);
1730 printf("\n");
1731 }
1732 dst->scrub->pfss_flags = (dst->scrub->pfss_flags & ~PFSS_PAWS)
1733 | PFSS_PAWS_IDLED;
1734 }
1735
1736 if (got_ts && src->scrub && dst->scrub &&
1737 (src->scrub->pfss_flags & PFSS_PAWS) &&
1738 (dst->scrub->pfss_flags & PFSS_PAWS)) {
1739 /* Validate that the timestamps are "in-window".
1740 * RFC1323 describes TCP Timestamp options that allow
1741 * measurement of RTT (round trip time) and PAWS
1742 * (protection against wrapped sequence numbers). PAWS
1743 * gives us a set of rules for rejecting packets on
1744 * long fat pipes (packets that were somehow delayed
1745 * in transit longer than the time it took to send the
1746 * full TCP sequence space of 4Gb). We can use these
1747 * rules and infer a few others that will let us treat
1748 * the 32bit timestamp and the 32bit echoed timestamp
1749 * as sequence numbers to prevent a blind attacker from
1750 * inserting packets into a connection.
1751 *
1752 * RFC1323 tells us:
1753 * - The timestamp on this packet must be greater than
1754 * or equal to the last value echoed by the other
1755 * endpoint. The RFC says those will be discarded
1756 * since it is a dup that has already been acked.
1757 * This gives us a lowerbound on the timestamp.
1758 * timestamp >= other last echoed timestamp
1759 * - The timestamp will be less than or equal to
1760 * the last timestamp plus the time between the
1761 * last packet and now. The RFC defines the max
1762 * clock rate as 1ms. We will allow clocks to be
1763 * up to 10% fast and will allow a total difference
1764 * or 30 seconds due to a route change. And this
1765 * gives us an upperbound on the timestamp.
1766 * timestamp <= last timestamp + max ticks
1767 * We have to be careful here. Windows will send an
1768 * initial timestamp of zero and then initialize it
1769 * to a random value after the 3whs; presumably to
1770 * avoid a DoS by having to call an expensive RNG
1771 * during a SYN flood. Proof MS has at least one
1772 * good security geek.
1773 *
1774 * - The TCP timestamp option must also echo the other
1775 * endpoints timestamp. The timestamp echoed is the
1776 * one carried on the earliest unacknowledged segment
1777 * on the left edge of the sequence window. The RFC
1778 * states that the host will reject any echoed
1779 * timestamps that were larger than any ever sent.
1780 * This gives us an upperbound on the TS echo.
1781 * tescr <= largest_tsval
1782 * - The lowerbound on the TS echo is a little more
1783 * tricky to determine. The other endpoint's echoed
1784 * values will not decrease. But there may be
1785 * network conditions that re-order packets and
1786 * cause our view of them to decrease. For now the
1787 * only lowerbound we can safely determine is that
1788 * the TS echo will never be less than the orginal
1789 * TS. XXX There is probably a better lowerbound.
1790 * Remove TS_MAX_CONN with better lowerbound check.
1791 * tescr >= other original TS
1792 *
1793 * It is also important to note that the fastest
1794 * timestamp clock of 1ms will wrap its 32bit space in
1795 * 24 days. So we just disable TS checking after 24
1796 * days of idle time. We actually must use a 12d
1797 * connection limit until we can come up with a better
1798 * lowerbound to the TS echo check.
1799 */
1800 struct timeval delta_ts;
1801 int ts_fudge;
1802
1803
1804 /*
1805 * PFTM_TS_DIFF is how many seconds of leeway to allow
1806 * a host's timestamp. This can happen if the previous
1807 * packet got delayed in transit for much longer than
1808 * this packet.
1809 */
1810 if ((ts_fudge = state->rule.ptr->timeout[PFTM_TS_DIFF]) == 0)
1811 ts_fudge = pf_default_rule.timeout[PFTM_TS_DIFF];
1812
1813
1814 /* Calculate max ticks since the last timestamp */
1815#define TS_MAXFREQ 1100 /* RFC max TS freq of 1Khz + 10% skew */
1816#define TS_MICROSECS 1000000 /* microseconds per second */
1817#ifdef __FreeBSD__
1818#ifndef timersub
1819#define timersub(tvp, uvp, vvp) \
1820 do { \
1821 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
1822 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
1823 if ((vvp)->tv_usec < 0) { \
1824 (vvp)->tv_sec--; \
1825 (vvp)->tv_usec += 1000000; \
1826 } \
1827 } while (0)
1828#endif
1829#endif
1830 timersub(&uptime, &src->scrub->pfss_last, &delta_ts);
1831 tsval_from_last = (delta_ts.tv_sec + ts_fudge) * TS_MAXFREQ;
1832 tsval_from_last += delta_ts.tv_usec / (TS_MICROSECS/TS_MAXFREQ);
1833
1834
1835 if ((src->state >= TCPS_ESTABLISHED &&
1836 dst->state >= TCPS_ESTABLISHED) &&
1837 (SEQ_LT(tsval, dst->scrub->pfss_tsecr) ||
1838 SEQ_GT(tsval, src->scrub->pfss_tsval + tsval_from_last) ||
1839 (tsecr && (SEQ_GT(tsecr, dst->scrub->pfss_tsval) ||
1840 SEQ_LT(tsecr, dst->scrub->pfss_tsval0))))) {
1841 /* Bad RFC1323 implementation or an insertion attack.
1842 *
1843 * - Solaris 2.6 and 2.7 are known to send another ACK
1844 * after the FIN,FIN|ACK,ACK closing that carries
1845 * an old timestamp.
1846 */
1847
1848 DPFPRINTF(("Timestamp failed %c%c%c%c\n",
1849 SEQ_LT(tsval, dst->scrub->pfss_tsecr) ? '0' : ' ',
1850 SEQ_GT(tsval, src->scrub->pfss_tsval +
1851 tsval_from_last) ? '1' : ' ',
1852 SEQ_GT(tsecr, dst->scrub->pfss_tsval) ? '2' : ' ',
1853 SEQ_LT(tsecr, dst->scrub->pfss_tsval0)? '3' : ' '));
1854#ifdef __FreeBSD__
1855 DPFPRINTF((" tsval: %u tsecr: %u +ticks: %u "
1856 "idle: %lus %lums\n",
1857 tsval, tsecr, tsval_from_last, delta_ts.tv_sec,
1858 delta_ts.tv_usec / 1000));
1859 DPFPRINTF((" src->tsval: %u tsecr: %u\n",
1860 src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
1861 DPFPRINTF((" dst->tsval: %u tsecr: %u tsval0: %u"
1862 "\n", dst->scrub->pfss_tsval,
1863 dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
1864#else
1865 DPFPRINTF((" tsval: %lu tsecr: %lu +ticks: %lu "
1866 "idle: %lus %lums\n",
1867 tsval, tsecr, tsval_from_last, delta_ts.tv_sec,
1868 delta_ts.tv_usec / 1000));
1869 DPFPRINTF((" src->tsval: %lu tsecr: %lu\n",
1870 src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
1871 DPFPRINTF((" dst->tsval: %lu tsecr: %lu tsval0: %lu"
1872 "\n", dst->scrub->pfss_tsval,
1873 dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
1874#endif
1875 if (pf_status.debug >= PF_DEBUG_MISC) {
1876 pf_print_state(state);
1877 pf_print_flags(th->th_flags);
1878 printf("\n");
1879 }
1880 REASON_SET(reason, PFRES_TS);
1881 return (PF_DROP);
1882 }
1883
1884 /* XXX I'd really like to require tsecr but it's optional */
1885
1886 } else if (!got_ts && (th->th_flags & TH_RST) == 0 &&
1887 ((src->state == TCPS_ESTABLISHED && dst->state == TCPS_ESTABLISHED)
1888 || pd->p_len > 0 || (th->th_flags & TH_SYN)) &&
1889 src->scrub && dst->scrub &&
1890 (src->scrub->pfss_flags & PFSS_PAWS) &&
1891 (dst->scrub->pfss_flags & PFSS_PAWS)) {
1892 /* Didn't send a timestamp. Timestamps aren't really useful
1893 * when:
1894 * - connection opening or closing (often not even sent).
1895 * but we must not let an attacker to put a FIN on a
1896 * data packet to sneak it through our ESTABLISHED check.
1897 * - on a TCP reset. RFC suggests not even looking at TS.
1898 * - on an empty ACK. The TS will not be echoed so it will
1899 * probably not help keep the RTT calculation in sync and
1900 * there isn't as much danger when the sequence numbers
1901 * got wrapped. So some stacks don't include TS on empty
1902 * ACKs :-(
1903 *
1904 * To minimize the disruption to mostly RFC1323 conformant
1905 * stacks, we will only require timestamps on data packets.
1906 *
1907 * And what do ya know, we cannot require timestamps on data
1908 * packets. There appear to be devices that do legitimate
1909 * TCP connection hijacking. There are HTTP devices that allow
1910 * a 3whs (with timestamps) and then buffer the HTTP request.
1911 * If the intermediate device has the HTTP response cache, it
1912 * will spoof the response but not bother timestamping its
1913 * packets. So we can look for the presence of a timestamp in
1914 * the first data packet and if there, require it in all future
1915 * packets.
1916 */
1917
1918 if (pd->p_len > 0 && (src->scrub->pfss_flags & PFSS_DATA_TS)) {
1919 /*
1920 * Hey! Someone tried to sneak a packet in. Or the
1921 * stack changed its RFC1323 behavior?!?!
1922 */
1923 if (pf_status.debug >= PF_DEBUG_MISC) {
1924 DPFPRINTF(("Did not receive expected RFC1323 "
1925 "timestamp\n"));
1926 pf_print_state(state);
1927 pf_print_flags(th->th_flags);
1928 printf("\n");
1929 }
1930 REASON_SET(reason, PFRES_TS);
1931 return (PF_DROP);
1932 }
1933 }
1934
1935
1936 /*
1937 * We will note if a host sends his data packets with or without
1938 * timestamps. And require all data packets to contain a timestamp
1939 * if the first does. PAWS implicitly requires that all data packets be
1940 * timestamped. But I think there are middle-man devices that hijack
1941 * TCP streams immedietly after the 3whs and don't timestamp their
1942 * packets (seen in a WWW accelerator or cache).
1943 */
1944 if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
1945 (PFSS_TIMESTAMP|PFSS_DATA_TS|PFSS_DATA_NOTS)) == PFSS_TIMESTAMP) {
1946 if (got_ts)
1947 src->scrub->pfss_flags |= PFSS_DATA_TS;
1948 else {
1949 src->scrub->pfss_flags |= PFSS_DATA_NOTS;
1950 if (pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
1951 (dst->scrub->pfss_flags & PFSS_TIMESTAMP)) {
1952 /* Don't warn if other host rejected RFC1323 */
1953 DPFPRINTF(("Broken RFC1323 stack did not "
1954 "timestamp data packet. Disabled PAWS "
1955 "security.\n"));
1956 pf_print_state(state);
1957 pf_print_flags(th->th_flags);
1958 printf("\n");
1959 }
1960 }
1961 }
1962
1963
1964 /*
1965 * Update PAWS values
1966 */
1967 if (got_ts && src->scrub && PFSS_TIMESTAMP == (src->scrub->pfss_flags &
1968 (PFSS_PAWS_IDLED|PFSS_TIMESTAMP))) {
1969 getmicrouptime(&src->scrub->pfss_last);
1970 if (SEQ_GEQ(tsval, src->scrub->pfss_tsval) ||
1971 (src->scrub->pfss_flags & PFSS_PAWS) == 0)
1972 src->scrub->pfss_tsval = tsval;
1973
1974 if (tsecr) {
1975 if (SEQ_GEQ(tsecr, src->scrub->pfss_tsecr) ||
1976 (src->scrub->pfss_flags & PFSS_PAWS) == 0)
1977 src->scrub->pfss_tsecr = tsecr;
1978
1979 if ((src->scrub->pfss_flags & PFSS_PAWS) == 0 &&
1980 (SEQ_LT(tsval, src->scrub->pfss_tsval0) ||
1981 src->scrub->pfss_tsval0 == 0)) {
1982 /* tsval0 MUST be the lowest timestamp */
1983 src->scrub->pfss_tsval0 = tsval;
1984 }
1985
1986 /* Only fully initialized after a TS gets echoed */
1987 if ((src->scrub->pfss_flags & PFSS_PAWS) == 0)
1988 src->scrub->pfss_flags |= PFSS_PAWS;
1989 }
1990 }
1991
1682 /* I have a dream.... TCP segment reassembly.... */
1683 return (0);
1684}
1992 /* I have a dream.... TCP segment reassembly.... */
1993 return (0);
1994}
1995
1685int
1686pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
1687 int off)
1688{
1689 u_int16_t *mss;
1690 int thoff;
1691 int opt, cnt, optlen = 0;
1692 int rewrite = 0;

--- 36 unchanged lines hidden ---
1996int
1997pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
1998 int off)
1999{
2000 u_int16_t *mss;
2001 int thoff;
2002 int opt, cnt, optlen = 0;
2003 int rewrite = 0;

--- 36 unchanged lines hidden ---