Commit ee2dea7d authored by Rusty Russell's avatar Rusty Russell Committed by Hideaki Yoshifuji

[NETFILTER]: REJECT nonlinear fixes after sync with 2.4

Harald synced up ipt_REJECT.c from 2.4 route fixes, but it had
changed a fair bit because of the nonlinear fixes.  This repairs it.

1) Copying of tcp header onto stack.
2) ...which also checks length requirement.
3) Skip checksum check: requires linear packet.
parent 8b699049
...@@ -84,45 +84,34 @@ static inline struct rtable *route_reverse(struct sk_buff *skb, int local) ...@@ -84,45 +84,34 @@ static inline struct rtable *route_reverse(struct sk_buff *skb, int local)
static void send_reset(struct sk_buff *oldskb, int local) static void send_reset(struct sk_buff *oldskb, int local)
{ {
struct sk_buff *nskb; struct sk_buff *nskb;
struct tcphdr *otcph, *tcph; struct tcphdr otcph, *tcph;
struct rtable *rt; struct rtable *rt;
unsigned int otcplen;
u_int16_t tmp_port; u_int16_t tmp_port;
u_int32_t tmp_addr; u_int32_t tmp_addr;
int needs_ack; int needs_ack;
int hh_len; int hh_len;
/* IP header checks: fragment, too short. */ /* IP header checks: fragment. */
if (oldskb->nh.iph->frag_off & htons(IP_OFFSET) if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
|| oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
return; return;
otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
if (skb_copy_bits(oldskb, oldskb->nh.iph->ihl*4, if (skb_copy_bits(oldskb, oldskb->nh.iph->ihl*4,
otcph, sizeof(*otcph)) < 0) &otcph, sizeof(otcph)) < 0)
return; return;
/* No RST for RST. */ /* No RST for RST. */
if (otcph->rst) if (otcph.rst)
return;
/* Check checksum. */
if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
oldskb->nh.iph->daddr,
csum_partial((char *)otcph, otcplen, 0)) != 0)
return; return;
/* FIXME: Check checksum --RR */
if ((rt = route_reverse(oldskb, local)) == NULL) if ((rt = route_reverse(oldskb, local)) == NULL)
return; return;
hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15; hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
/* Copy skb (even if skb is about to be dropped, we can't just /* We need a linear, writeable skb. We also need to expand
clone it because there may be other things, such as tcpdump, headroom in case hh_len of incoming interface < hh_len of
interested in it). We also need to expand headroom in case outgoing interface */
hh_len of incoming interface < hh_len of outgoing interface */
nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb), nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
GFP_ATOMIC); GFP_ATOMIC);
if (!nskb) { if (!nskb) {
...@@ -163,12 +152,13 @@ static void send_reset(struct sk_buff *oldskb, int local) ...@@ -163,12 +152,13 @@ static void send_reset(struct sk_buff *oldskb, int local)
if (tcph->ack) { if (tcph->ack) {
needs_ack = 0; needs_ack = 0;
tcph->seq = otcph->ack_seq; tcph->seq = otcph.ack_seq;
tcph->ack_seq = 0; tcph->ack_seq = 0;
} else { } else {
needs_ack = 1; needs_ack = 1;
tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
+ otcplen - (otcph->doff<<2)); + oldskb->len - oldskb->nh.iph->ihl*4
- (otcph.doff<<2));
tcph->seq = 0; tcph->seq = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment