netfilter-2.6/patch-o-matic-ng/trunk: net/ipv4/netfilter/ipt_REJECT.c
status
pluto
cvs at pld-linux.org
Thu Jul 28 13:10:40 CEST 2005
Author: pluto
Date: Thu Jul 28 13:10:37 2005
New Revision: 6254
Modified:
netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ipt_REJECT.c
netfilter-2.6/patch-o-matic-ng/trunk/status
Log:
- REJECT (ipv4) updated.
Modified: netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ipt_REJECT.c
==============================================================================
--- netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ipt_REJECT.c (original)
+++ netfilter-2.6/patch-o-matic-ng/trunk/net/ipv4/netfilter/ipt_REJECT.c Thu Jul 28 13:10:37 2005
@@ -213,16 +213,157 @@
nf_ct_attach(nskb, oldskb);
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
- dst_output);
+ ip_finish_output);
return;
free_nskb:
kfree_skb(nskb);
}
-static inline void send_unreach(struct sk_buff *skb_in, int code)
+static void send_unreach(struct sk_buff *skb_in, int code)
{
- icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
+ struct iphdr *iph;
+ struct icmphdr *icmph;
+ struct sk_buff *nskb;
+ u32 saddr;
+ u8 tos;
+ int hh_len, length;
+ struct rtable *rt = (struct rtable*)skb_in->dst;
+ unsigned char *data;
+
+ if (!rt)
+ return;
+
+ /* FIXME: Use sysctl number. --RR */
+ if (!xrlim_allow(&rt->u.dst, 1*HZ))
+ return;
+
+ iph = skb_in->nh.iph;
+
+ /* No replies to physical multicast/broadcast */
+ if (skb_in->pkt_type!=PACKET_HOST)
+ return;
+
+ /* Now check at the protocol level */
+ if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST))
+ return;
+
+ /* Only reply to fragment 0. */
+ if (iph->frag_off&htons(IP_OFFSET))
+ return;
+
+ /* Ensure we have at least 8 bytes of proto header. */
+ if (skb_in->len < skb_in->nh.iph->ihl*4 + 8)
+ return;
+
+ /* If we send an ICMP error to an ICMP error a mess would result.. */
+ if (iph->protocol == IPPROTO_ICMP) {
+ struct icmphdr ihdr;
+
+ icmph = skb_header_pointer(skb_in, skb_in->nh.iph->ihl*4,
+ sizeof(ihdr), &ihdr);
+ if (!icmph)
+ return;
+
+ /* Between echo-reply (0) and timestamp (13),
+ everything except echo-request (8) is an error.
+ Also, anything greater than NR_ICMP_TYPES is
+ unknown, and hence should be treated as an error... */
+ if ((icmph->type < ICMP_TIMESTAMP
+ && icmph->type != ICMP_ECHOREPLY
+ && icmph->type != ICMP_ECHO)
+ || icmph->type > NR_ICMP_TYPES)
+ return;
+ }
+
+ saddr = iph->daddr;
+ if (!(rt->rt_flags & RTCF_LOCAL))
+ saddr = 0;
+
+ tos = (iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL;
+
+ {
+ struct flowi fl = {
+ .nl_u = {
+ .ip4_u = {
+ .daddr = skb_in->nh.iph->saddr,
+ .saddr = saddr,
+ .tos = RT_TOS(tos)
+ }
+ },
+ .proto = IPPROTO_ICMP,
+ .uli_u = {
+ .icmpt = {
+ .type = ICMP_DEST_UNREACH,
+ .code = code
+ }
+ }
+ };
+
+ if (ip_route_output_key(&rt, &fl))
+ return;
+ }
+ /* RFC says return as much as we can without exceeding 576 bytes. */
+ length = skb_in->len + sizeof(struct iphdr) + sizeof(struct icmphdr);
+
+ if (length > dst_mtu(&rt->u.dst))
+ length = dst_mtu(&rt->u.dst);
+ if (length > 576)
+ length = 576;
+
+ hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
+
+ nskb = alloc_skb(hh_len + length, GFP_ATOMIC);
+ if (!nskb) {
+ ip_rt_put(rt);
+ return;
+ }
+
+ nskb->priority = 0;
+ nskb->dst = &rt->u.dst;
+ skb_reserve(nskb, hh_len);
+
+ /* Set up IP header */
+ iph = nskb->nh.iph
+ = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
+ iph->version=4;
+ iph->ihl=5;
+ iph->tos=tos;
+ iph->tot_len = htons(length);
+
+ /* PMTU discovery never applies to ICMP packets. */
+ iph->frag_off = 0;
+
+ iph->ttl = MAXTTL;
+ ip_select_ident(iph, &rt->u.dst, NULL);
+ iph->protocol=IPPROTO_ICMP;
+ iph->saddr=rt->rt_src;
+ iph->daddr=rt->rt_dst;
+ iph->check=0;
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+
+ /* Set up ICMP header. */
+ icmph = nskb->h.icmph
+ = (struct icmphdr *)skb_put(nskb, sizeof(struct icmphdr));
+ icmph->type = ICMP_DEST_UNREACH;
+ icmph->code = code;
+ icmph->un.gateway = 0;
+ icmph->checksum = 0;
+
+ /* Copy as much of original packet as will fit */
+ data = skb_put(nskb,
+ length - sizeof(struct iphdr) - sizeof(struct icmphdr));
+
+ skb_copy_bits(skb_in, 0, data,
+ length - sizeof(struct iphdr) - sizeof(struct icmphdr));
+
+ icmph->checksum = ip_compute_csum((unsigned char *)icmph,
+ length - sizeof(struct iphdr));
+
+ nf_ct_attach(nskb, skb_in);
+
+ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
+ ip_finish_output);
}
static unsigned int reject(struct sk_buff **pskb,
Modified: netfilter-2.6/patch-o-matic-ng/trunk/status
==============================================================================
--- netfilter-2.6/patch-o-matic-ng/trunk/status (original)
+++ netfilter-2.6/patch-o-matic-ng/trunk/status Thu Jul 28 13:10:37 2005
@@ -32,7 +32,7 @@
quota 2005/07/27 added
realm updated
recent updated (v0.3.2)
-REJECT 2005/07/27 updated (ipv6 added)
+REJECT 2005/07/27 added+updated (ipv6 added, ipv4 updated)
ROUTE 2005/07/27 added (ipv6 / not working as a module)
SAME updated
sctp updated
More information about the pld-cvs-commit
mailing list