FreeBSD/sys/netpfil/pf/pf.c
/*
 * Need to modulate the sequence numbers in the TCP SACK option
 * (credits to Krzysztof Pfaff for report and patch)
 */
Need to modulate the sequence numbers in the TCP SACK option
(credits to Krzysztof Pfaff for report and patch)
Need to modulate the sequence numbers in the TCP SACK option ( credits to Krzysztof Pfaff for report and patch )
static int
pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
    struct tcphdr *th, struct pf_state_peer *dst)
{
	int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen;
	u_int8_t opts[TCP_MAXOLEN], *opt = opts;
	int copyback = 0, i, olen;
	struct sackblk sack;
#define	TCPOLEN_SACKLEN	(TCPOLEN_SACK + 2)
	if (hlen < TCPOLEN_SACKLEN ||
	    !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af))
		return 0;
	while (hlen >= TCPOLEN_SACKLEN) {
		olen = opt[1];
		switch (*opt) {
		case TCPOPT_EOL:	
		case TCPOPT_NOP:
			opt++;
			hlen--;
			break;
		case TCPOPT_SACK:
			if (olen > hlen)
				olen = hlen;
			if (olen >= TCPOLEN_SACKLEN) {
				for (i = 2; i + TCPOLEN_SACK <= olen;
				    i += TCPOLEN_SACK) {
					memcpy(&sack, &opt[i], sizeof(sack));
					pf_change_proto_a(m, &sack.start, &th->th_sum,
					    htonl(ntohl(sack.start) - dst->seqdiff), 0);
					pf_change_proto_a(m, &sack.end, &th->th_sum,
					    htonl(ntohl(sack.end) - dst->seqdiff), 0);
					memcpy(&opt[i], &sack, sizeof(sack));
				}
				copyback = 1;
			}
		default:
			if (olen < 2)
				olen = 2;
			hlen -= olen;
			opt += olen;
		}
	}
	if (copyback)
		m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts);
	return (copyback);
}
static int pf_modulate_sack ( struct mbuf * m , int off , struct pf_pdesc * pd , struct tcphdr * th , struct pf_state_peer * dst ) { int hlen = ( th -> th_off << 2 ) - sizeof ( * th ) , thoptlen = hlen ; u_int8_t opts [ TCP_MAXOLEN ] , * opt = opts ; int copyback = 0 , i , olen ; struct sackblk sack ; #define TCPOLEN_SACKLEN 	(TCPOLEN_SACK + 2) if ( hlen < TCPOLEN_SACKLEN || ! pf_pull_hdr ( m , off + sizeof ( * th ) , opts , hlen , NULL , NULL , pd -> af ) ) return 0 ; while ( hlen >= TCPOLEN_SACKLEN ) { olen = opt [ 1 ] ; switch ( * opt ) { case TCPOPT_EOL : case TCPOPT_NOP : opt ++ ; hlen -- ; break ; case TCPOPT_SACK : if ( olen > hlen ) olen = hlen ; if ( olen >= TCPOLEN_SACKLEN ) { for ( i = 2 ; i + TCPOLEN_SACK <= olen ; i += TCPOLEN_SACK ) { memcpy ( & sack , & opt [ i ] , sizeof ( sack ) ) ; pf_change_proto_a ( m , & sack . start , & th -> th_sum , htonl ( ntohl ( sack . start ) - dst -> seqdiff ) , 0 ) ; pf_change_proto_a ( m , & sack . end , & th -> th_sum , htonl ( ntohl ( sack . end ) - dst -> seqdiff ) , 0 ) ; memcpy ( & opt [ i ] , & sack , sizeof ( sack ) ) ; } copyback = 1 ; } default : if ( olen < 2 ) olen = 2 ; hlen -= olen ; opt += olen ; } } if ( copyback ) m_copyback ( m , off + sizeof ( * th ) , thoptlen , ( caddr_t ) opts ) ; return ( copyback ) ; }
Need to modulate the sequence numbers in the TCP SACK option
 (credits to Krzysztof Pfaff for report and patch)
Need to modulate the sequence numbers in the TCP SACK option ( credits to Krzysztof Pfaff for report and patch )
/* FALLTHROUGH */ /* FALLTHROUGH */