* Need to modulate the sequence numbers in the TCP SACK option * (credits to Krzysztof Pfaff for report and patch) */
| 2382 | * (credits to Krzysztof Pfaff for report and patch) |
| 2383 | */ |
| 2384 | static int |
| 2385 | pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd, |
| 2386 | struct tcphdr *th, struct pf_state_peer *dst) |
| 2387 | { |
| 2388 | int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen; |
| 2389 | u_int8_t opts[TCP_MAXOLEN], *opt = opts; |
| 2390 | int copyback = 0, i, olen; |
| 2391 | struct sackblk sack; |
| 2392 | |
| 2393 | #define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2) |
| 2394 | if (hlen < TCPOLEN_SACKLEN || |
| 2395 | !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af)) |
| 2396 | return 0; |
| 2397 | |
| 2398 | while (hlen >= TCPOLEN_SACKLEN) { |
| 2399 | size_t startoff = opt - opts; |
| 2400 | olen = opt[1]; |
| 2401 | switch (*opt) { |
| 2402 | case TCPOPT_EOL: /* FALLTHROUGH */ |
| 2403 | case TCPOPT_NOP: |
| 2404 | opt++; |
| 2405 | hlen--; |
| 2406 | break; |
| 2407 | case TCPOPT_SACK: |
| 2408 | if (olen > hlen) |
| 2409 | olen = hlen; |
| 2410 | if (olen >= TCPOLEN_SACKLEN) { |
| 2411 | for (i = 2; i + TCPOLEN_SACK <= olen; |
| 2412 | i += TCPOLEN_SACK) { |
| 2413 | memcpy(&sack, &opt[i], sizeof(sack)); |
| 2414 | pf_patch_32_unaligned(m, |
| 2415 | &th->th_sum, &sack.start, |
| 2416 | htonl(ntohl(sack.start) - dst->seqdiff), |
| 2417 | PF_ALGNMNT(startoff), |
| 2418 | 0); |
| 2419 | pf_patch_32_unaligned(m, &th->th_sum, |
| 2420 | &sack.end, |
| 2421 | htonl(ntohl(sack.end) - dst->seqdiff), |
| 2422 | PF_ALGNMNT(startoff), |
| 2423 | 0); |
| 2424 | memcpy(&opt[i], &sack, sizeof(sack)); |
| 2425 | } |
| 2426 | copyback = 1; |
| 2427 | } |
| 2428 | /* FALLTHROUGH */ |
| 2429 | default: |
| 2430 | if (olen < 2) |
| 2431 | olen = 2; |
| 2432 | hlen -= olen; |
| 2433 | opt += olen; |
| 2434 | } |
| 2435 | } |
| 2436 | |
| 2437 | if (copyback) |
| 2438 | m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts); |
| 2439 | return (copyback); |
| 2440 | } |
| 2441 |
no test coverage detected