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 --- |