diff -ur linux-2.4.19-rc3-ac3-mppe-netfilter-htb-noreplace/include/linux/netfilter_ipv4/ipt_string.h linux-2.4.19-rc3-ac3-mppe-netfilter-htb/include/linux/netfilter_ipv4/ipt_string.h --- linux-2.4.19-rc3-ac3-mppe-netfilter-htb-noreplace/include/linux/netfilter_ipv4/ipt_string.h Tue Oct 1 02:20:32 2002 +++ linux-2.4.19-rc3-ac3-mppe-netfilter-htb/include/linux/netfilter_ipv4/ipt_string.h Tue Oct 1 23:44:00 2002 @@ -14,8 +14,10 @@ struct ipt_string_info { char string[BM_MAX_NLEN]; + char replace[BM_MAX_NLEN]; u_int16_t invert; u_int16_t len; + u_int16_t replace_len; }; #endif /* _IPT_STRING_H */ diff -ur linux-2.4.19-rc3-ac3-mppe-netfilter-htb-noreplace/net/ipv4/netfilter/ipt_string.c linux-2.4.19-rc3-ac3-mppe-netfilter-htb/net/ipv4/netfilter/ipt_string.c --- linux-2.4.19-rc3-ac3-mppe-netfilter-htb-noreplace/net/ipv4/netfilter/ipt_string.c Thu Jul 25 20:38:15 2002 +++ linux-2.4.19-rc3-ac3-mppe-netfilter-htb/net/ipv4/netfilter/ipt_string.c Wed Oct 2 01:01:50 2002 @@ -21,7 +21,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -110,7 +113,7 @@ const struct ipt_string_info *info = matchinfo; struct iphdr *ip = skb->nh.iph; int hlen, nlen; - char *needle, *haystack; + char *needle, *haystack, *result; proc_ipt_search search=search_linear; if ( !ip ) return 0; @@ -137,7 +140,22 @@ } } - return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert); + if ((result = search(needle, haystack, nlen, hlen)) != NULL && + info->replace_len > 0) { + struct tcphdr *tcph = (void *)ip + ip->ihl*4; + u_int32_t tcplen = skb->len - ip->ihl*4; + u_int32_t datalen = tcplen - tcph->doff*4; + + memcpy (result, info->replace, min (info->len, info->replace_len)); + + skb->csum = csum_partial((char *)tcph + tcph->doff*4, datalen, 0); + tcph->check = 0; + tcph->check = tcp_v4_check(tcph, tcplen, ip->saddr, ip->daddr, + csum_partial((char *)tcph, tcph->doff*4, skb->csum)); + ip_send_check(ip); + } + + return ((result != NULL) ^ info->invert); } static int