]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
Patches and isapplied script for reducing bug reports.
authorRusty Russell <rusty@linuxcare.com.au>
Fri, 14 Jul 2000 07:45:08 +0000 (07:45 +0000)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 14 Jul 2000 07:45:08 +0000 (07:45 +0000)
patch-test3-pre2-sparc-ppc-align [new file with mode: 0644]
patch-test3-pre6-reject-enhancements [new file with mode: 0644]

diff --git a/patch-test3-pre2-sparc-ppc-align b/patch-test3-pre2-sparc-ppc-align
new file mode 100644 (file)
index 0000000..83a1b22
--- /dev/null
@@ -0,0 +1,48 @@
+diff -urN -X /tmp/file5l4Euc --minimal linux-2.4.0-test3-2/include/linux/netfilter_ipv4/ip_tables.h working-2.4.0-test3-2/include/linux/netfilter_ipv4/ip_tables.h
+--- linux-2.4.0-test3-2/include/linux/netfilter_ipv4/ip_tables.h       Thu Jul  6 13:26:32 2000
++++ working-2.4.0-test3-2/include/linux/netfilter_ipv4/ip_tables.h     Fri Jul  7 18:42:41 2000
+@@ -280,7 +280,7 @@
+       unsigned int size;
+       /* The entries. */
+-      unsigned char entries[0];
++      struct ipt_entry entrytable[0];
+ };
+ /* Standard return verdict, or do jump. */
+diff -urN -X /tmp/file5l4Euc --minimal linux-2.4.0-test3-2/include/linux/netfilter_ipv6/ip6_tables.h working-2.4.0-test3-2/include/linux/netfilter_ipv6/ip6_tables.h
+--- linux-2.4.0-test3-2/include/linux/netfilter_ipv6/ip6_tables.h      Thu May 25 12:41:49 2000
++++ working-2.4.0-test3-2/include/linux/netfilter_ipv6/ip6_tables.h    Fri Jul  7 19:08:16 2000
+@@ -286,7 +286,7 @@
+       unsigned int size;
+       /* The entries. */
+-      unsigned char entries[0];
++      struct ip6t_entry entrytable[0];
+ };
+ /* Standard return verdict, or do jump. */
+diff -urN -X /tmp/file5l4Euc --minimal linux-2.4.0-test3-2/net/ipv4/netfilter/ip_tables.c working-2.4.0-test3-2/net/ipv4/netfilter/ip_tables.c
+--- linux-2.4.0-test3-2/net/ipv4/netfilter/ip_tables.c Thu Jun 29 01:26:09 2000
++++ working-2.4.0-test3-2/net/ipv4/netfilter/ip_tables.c       Fri Jul  7 18:43:40 2000
+@@ -1029,7 +1029,7 @@
+                        t->private->number);
+               if (entries->size == t->private->size)
+                       ret = copy_entries_to_user(t->private->size,
+-                                                 t, uptr->entries);
++                                                 t, uptr->entrytable);
+               else {
+                       duprintf("get_entries: I've got %u not %u!\n",
+                                t->private->size,
+diff -urN -X /tmp/file5l4Euc --minimal linux-2.4.0-test3-2/net/ipv6/netfilter/ip6_tables.c working-2.4.0-test3-2/net/ipv6/netfilter/ip6_tables.c
+--- linux-2.4.0-test3-2/net/ipv6/netfilter/ip6_tables.c        Thu Jun 29 01:26:11 2000
++++ working-2.4.0-test3-2/net/ipv6/netfilter/ip6_tables.c      Fri Jul  7 19:15:15 2000
+@@ -1075,7 +1075,7 @@
+                        t->private->number);
+               if (entries->size == t->private->size)
+                       ret = copy_entries_to_user(t->private->size,
+-                                                 t, uptr->entries);
++                                                 t, uptr->entrytable);
+               else {
+                       duprintf("get_entries: I've got %u not %u!\n",
+                                t->private->size,
diff --git a/patch-test3-pre6-reject-enhancements b/patch-test3-pre6-reject-enhancements
new file mode 100644 (file)
index 0000000..a2c679e
--- /dev/null
@@ -0,0 +1,305 @@
+diff -urN -X /tmp/fileVB9oIz --minimal tmp/include/linux/netfilter_ipv4/ipt_REJECT.h working-2.4.0-test3-9/include/linux/netfilter_ipv4/ipt_REJECT.h
+--- tmp/include/linux/netfilter_ipv4/ipt_REJECT.h      Tue Mar 28 04:35:56 2000
++++ working-2.4.0-test3-9/include/linux/netfilter_ipv4/ipt_REJECT.h    Tue Jul 11 17:36:54 2000
+@@ -6,7 +6,10 @@
+       IPT_ICMP_HOST_UNREACHABLE,
+       IPT_ICMP_PROT_UNREACHABLE,
+       IPT_ICMP_PORT_UNREACHABLE,
+-      IPT_ICMP_ECHOREPLY
++      IPT_ICMP_ECHOREPLY,
++      IPT_ICMP_NET_PROHIBITED,
++      IPT_ICMP_HOST_PROHIBITED,
++      IPT_TCP_RESET
+ };
+ struct ipt_reject_info {
+diff -urN -X /tmp/fileVB9oIz --minimal tmp/net/core/netfilter.c working-2.4.0-test3-9/net/core/netfilter.c
+--- tmp/net/core/netfilter.c   Fri Apr 14 10:19:57 2000
++++ working-2.4.0-test3-9/net/core/netfilter.c Wed Jul 12 12:18:42 2000
+@@ -261,11 +261,11 @@
+               if (skb->nf_debug != ((1 << NF_IP_PRE_ROUTING)
+                                     | (1 << NF_IP_FORWARD)
+                                     | (1 << NF_IP_POST_ROUTING))) {
+-                      /* Fragments will have no owners, but still
+-                           may be local */
+-                      if (!(skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET))
+-                          || skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
+-                                               | (1 << NF_IP_POST_ROUTING))){
++                      /* Fragments, entunnelled packets, TCP RSTs
++                           generated by ipt_REJECT will have no
++                           owners, but still may be local */
++                      if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
++                                            | (1 << NF_IP_POST_ROUTING))){
+                               printk("ip_finish_output:"
+                                      " bad unowned skb = %p: ",skb);
+                               debug_print_hooks_ip(skb->nf_debug);
+diff -urN -X /tmp/fileVB9oIz --minimal tmp/net/ipv4/netfilter/ip_conntrack_core.c working-2.4.0-test3-9/net/ipv4/netfilter/ip_conntrack_core.c
+--- tmp/net/ipv4/netfilter/ip_conntrack_core.c Tue Jul 11 12:08:17 2000
++++ working-2.4.0-test3-9/net/ipv4/netfilter/ip_conntrack_core.c       Tue Jul 11 17:12:08 2000
+@@ -551,6 +551,7 @@
+ resolve_normal_ct(struct sk_buff *skb,
+                 struct ip_conntrack_protocol *proto,
+                 int *set_reply,
++                unsigned int hooknum,
+                 enum ip_conntrack_info *ctinfo)
+ {
+       struct ip_conntrack_tuple tuple;
+@@ -573,6 +574,21 @@
+       if (DIRECTION(h) == IP_CT_DIR_REPLY) {
+               /* Reply on unconfirmed connection => unclassifiable */
+               if (!(h->ctrack->status & IPS_CONFIRMED)) {
++                      /* Exception: local TCP RSTs (generated by
++                           REJECT target). */
++                      if (hooknum == NF_IP_LOCAL_OUT
++                          && h->tuple.dst.protonum == IPPROTO_TCP) {
++                              const struct tcphdr *tcph
++                                      = (const struct tcphdr *)
++                                      ((u_int32_t *)skb->nh.iph
++                                       + skb->nh.iph->ihl);
++                              if (tcph->rst) {
++                                      *ctinfo = IP_CT_ESTABLISHED
++                                              + IP_CT_IS_REPLY;
++                                      *set_reply = 0;
++                                      goto set_skb;
++                              }
++                      }
+                       DEBUGP("Reply on unconfirmed connection\n");
+                       ip_conntrack_put(h->ctrack);
+                       return NULL;
+@@ -598,6 +614,7 @@
+               }
+               *set_reply = 0;
+       }
++ set_skb:
+       skb->nfct = &h->ctrack->infos[*ctinfo];
+       return h->ctrack;
+ }
+@@ -669,7 +686,7 @@
+           && icmp_error_track(*pskb, &ctinfo, hooknum))
+               return NF_ACCEPT;
+-      if (!(ct = resolve_normal_ct(*pskb, proto, &set_reply, &ctinfo)))
++      if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo)))
+               /* Not valid part of a connection */
+               return NF_ACCEPT;
+diff -urN -X /tmp/fileVB9oIz --minimal tmp/net/ipv4/netfilter/ip_conntrack_standalone.c working-2.4.0-test3-9/net/ipv4/netfilter/ip_conntrack_standalone.c
+--- tmp/net/ipv4/netfilter/ip_conntrack_standalone.c   Fri Apr 28 08:43:15 2000
++++ working-2.4.0-test3-9/net/ipv4/netfilter/ip_conntrack_standalone.c Tue Jul 11 17:12:08 2000
+@@ -169,11 +169,15 @@
+                              const struct net_device *out,
+                              int (*okfn)(struct sk_buff *))
+ {
+-      /* We've seen it coming out the other side: confirm */
++      /* We've seen it coming out the other side: confirm (only if
++           new packet: REJECT can generate TCP RESET response, or ICMP
++           errors) */
+       if ((*pskb)->nfct) {
+               struct ip_conntrack *ct
+                       = (struct ip_conntrack *)(*pskb)->nfct->master;
+-              if (!(ct->status & IPS_CONFIRMED))
++              /* ctinfo is the index of the nfct inside the conntrack */
++              if ((*pskb)->nfct - ct->infos == IP_CT_NEW
++                  && !(ct->status & IPS_CONFIRMED))
+                       ip_conntrack_confirm(ct);
+       }
+       return NF_ACCEPT;
+@@ -191,7 +195,8 @@
+       if ((*pskb)->nfct) {
+               struct ip_conntrack *ct
+                       = (struct ip_conntrack *)(*pskb)->nfct->master;
+-              if (!(ct->status & IPS_CONFIRMED))
++              if ((*pskb)->nfct - ct->infos == IP_CT_NEW
++                  && !(ct->status & IPS_CONFIRMED))
+                       ip_conntrack_confirm(ct);
+       }
+diff -urN -X /tmp/fileVB9oIz --minimal tmp/net/ipv4/netfilter/ip_fw_compat.c working-2.4.0-test3-9/net/ipv4/netfilter/ip_fw_compat.c
+--- tmp/net/ipv4/netfilter/ip_fw_compat.c      Tue Jul 11 12:08:17 2000
++++ working-2.4.0-test3-9/net/ipv4/netfilter/ip_fw_compat.c    Tue Jul 11 17:12:08 2000
+@@ -71,7 +71,8 @@
+               struct ip_conntrack *ct
+                       = (struct ip_conntrack *)skb->nfct->master;
+-              if (!(ct->status & IPS_CONFIRMED))
++              if (skb->nfct - ct->infos == IP_CT_NEW
++                  && !(ct->status & IPS_CONFIRMED))
+                       ip_conntrack_confirm(ct);
+       }
+ }
+diff -urN -X /tmp/fileVB9oIz --minimal tmp/net/ipv4/netfilter/ipt_REJECT.c working-2.4.0-test3-9/net/ipv4/netfilter/ipt_REJECT.c
+--- tmp/net/ipv4/netfilter/ipt_REJECT.c        Tue Jun 27 14:52:47 2000
++++ working-2.4.0-test3-9/net/ipv4/netfilter/ipt_REJECT.c      Wed Jul 12 17:46:26 2000
+@@ -7,6 +7,7 @@
+ #include <linux/ip.h>
+ #include <net/icmp.h>
+ #include <net/ip.h>
++#include <net/tcp.h>
+ struct in_device;
+ #include <net/route.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+@@ -18,6 +19,113 @@
+ #define DEBUGP(format, args...)
+ #endif
++/* Send RST reply */
++static void send_reset(struct sk_buff *oldskb)
++{
++      struct sk_buff *nskb;
++      struct tcphdr *tcph;
++      struct rtable *rt;
++      unsigned int tcplen;
++      int needs_ack;
++
++      /* Clone skb (skb is about to be dropped, so we don't care) */
++      nskb = skb_clone(oldskb, GFP_ATOMIC);
++      if (!nskb)
++              return;
++
++      /* This packet will not be the same as the other: clear nf fields */
++      nf_conntrack_put(nskb->nfct);
++      nskb->nfct = NULL;
++      nskb->nfcache = 0;
++#ifdef CONFIG_NETFILTER_DEBUG
++      nskb->nf_debug = 0;
++#endif
++
++      /* IP header checks: fragment, too short. */
++      if (nskb->nh.iph->frag_off & htons(IP_OFFSET)
++          || nskb->len < (nskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
++              goto free_nskb;
++
++      tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
++      tcplen = nskb->len - nskb->nh.iph->ihl*4;
++
++      /* Check checksum. */
++      if (tcp_v4_check(tcph, tcplen, nskb->nh.iph->saddr,
++                       nskb->nh.iph->daddr,
++                       csum_partial((char *)tcph, tcplen, 0)) != 0)
++              goto free_nskb;
++
++      /* No RST for RST. */
++      if (tcph->rst)
++              goto free_nskb;
++
++      nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
++      tcph->source = xchg(&tcph->dest, tcph->source);
++
++      /* Truncate to length (no data) */
++      tcph->doff = sizeof(struct tcphdr)/4;
++      skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
++
++      if (tcph->ack) {
++              needs_ack = 0;
++              tcph->seq = tcph->ack_seq;
++              tcph->ack_seq = 0;
++      } else {
++              needs_ack = 1;
++              tcph->seq = 0;
++              tcph->ack_seq = htonl(ntohl(tcph->seq) + tcph->syn + tcph->fin
++                                    + tcplen - (tcph->doff<<2));
++      }
++
++      /* Reset flags */
++      ((u_int8_t *)tcph)[13] = 0;
++      tcph->rst = 1;
++      if (needs_ack)
++              tcph->ack = 1;
++
++      tcph->window = 0;
++      tcph->urg_ptr = 0;
++
++      /* Adjust TCP checksum */
++      tcph->check = 0;
++      tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
++                                 nskb->nh.iph->saddr,
++                                 nskb->nh.iph->daddr,
++                                 csum_partial((char *)tcph,
++                                              sizeof(struct tcphdr), 0));
++
++      /* Adjust IP TTL, DF */
++      nskb->nh.iph->ttl = MAXTTL;
++      /* Set DF, id = 0 */
++      nskb->nh.iph->frag_off = htons(IP_DF);
++      nskb->nh.iph->id = 0;
++
++      /* Adjust IP checksum */
++      nskb->nh.iph->check = 0;
++      nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, 
++                                         nskb->nh.iph->ihl);
++
++      /* Routing */
++      if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
++                          RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
++                          0) != 0)
++              goto free_nskb;
++
++      dst_release(nskb->dst);
++      nskb->dst = &rt->u.dst;
++
++      /* "Never happens" */
++      if (nskb->len > nskb->dst->pmtu)
++              goto free_nskb;
++
++      NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
++              ip_finish_output);
++      return;
++
++ free_nskb:
++      kfree_skb(nskb);
++}
++
+ static unsigned int reject(struct sk_buff **pskb,
+                          unsigned int hooknum,
+                          const struct net_device *in,
+@@ -43,6 +151,12 @@
+       case IPT_ICMP_PORT_UNREACHABLE:
+               icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+               break;
++      case IPT_ICMP_NET_PROHIBITED:
++              icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0);
++              break;
++      case IPT_ICMP_HOST_PROHIBITED:
++              icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
++              break;
+       case IPT_ICMP_ECHOREPLY: {
+               struct icmphdr *icmph  = (struct icmphdr *)
+                       ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
+@@ -64,6 +178,9 @@
+               }
+       }
+       break;
++      case IPT_TCP_RESET:
++              send_reset(*pskb);
++              break;
+       }
+       return NF_DROP;
+@@ -96,7 +213,7 @@
+       /* Only allow these for packet filtering. */
+       if (strcmp(tablename, "filter") != 0) {
+-              DEBUGP("REJECT: bad table `%s'.\n", table);
++              DEBUGP("REJECT: bad table `%s'.\n", tablename);
+               return 0;
+       }
+       if ((hook_mask & ~((1 << NF_IP_LOCAL_IN)
+@@ -116,6 +233,18 @@
+               /* Must contain ICMP match. */
+               if (IPT_MATCH_ITERATE(e, find_ping_match) == 0) {
+                       DEBUGP("REJECT: ECHOREPLY illegal for non-ping\n");
++                      return 0;
++              }
++      } else if (rejinfo->with == IPT_TCP_RESET) {
++              /* Must specify that it's a TCP packet */
++              if (e->ip.proto != IPPROTO_TCP
++                  || (e->ip.invflags & IPT_INV_PROTO)) {
++                      DEBUGP("REJECT: TCP_RESET illegal for non-tcp\n");
++                      return 0;
++              }
++              /* Only for local input.  Rest is too dangerous. */
++              if ((hook_mask & ~(1 << NF_IP_LOCAL_IN)) != 0) {
++                      DEBUGP("REJECT: TCP_RESET only from INPUT\n");
+                       return 0;
+               }
+       }