patch-pre2.0.7 linux/net/ipv4/icmp.c
Next file: linux/net/ipv4/ip_forward.c
Previous file: linux/net/ipv4/arp.c
Back to the patch index
Back to the overall index
- Lines: 120
- Date:
Mon May 20 08:52:58 1996
- Orig file:
pre2.0.6/linux/net/ipv4/icmp.c
- Orig date:
Fri May 17 15:32:20 1996
diff -u --recursive --new-file pre2.0.6/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
@@ -26,6 +26,7 @@
* Martin Mares : TOS and Precedence set correctly (RFC 1812).
* Martin Mares : Now copying as much data from the original packet
* as we can without exceeding 576 bytes (RFC 1812).
+ * Willy Konynenberg : Transparent proxying support.
*
*
*
@@ -232,6 +233,7 @@
#include <net/protocol.h>
#include <net/icmp.h>
#include <net/tcp.h>
+#include <net/udp.h>
#include <net/snmp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
@@ -768,9 +770,9 @@
*/
#if defined(CONFIG_IP_FORWARD) && !defined(CONFIG_IP_DUMB_ROUTER)
- printk(KERN_INFO "icmp: ICMP redirect ignored. dest = %s, "
- "orig gw = %s, \"new\" gw = %s, device = %s.\n", in_ntoa(ip),
- in_ntoa(source), in_ntoa(icmph->un.gateway), dev->name);
+ NETDEBUG(printk(KERN_INFO "icmp: ICMP redirect ignored. dest = %lX, "
+ "orig gw = %lX, \"new\" gw = %lX, device = %s.\n", ntohl(ip),
+ ntohl(source), ntohl(icmph->un.gateway), dev->name));
#else
switch(icmph->code & 7)
{
@@ -919,6 +921,63 @@
kfree_skb(skb, FREE_READ);
}
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+/*
+ * Check incoming icmp packets not addressed locally, to check whether
+ * they relate to a (proxying) socket on our system.
+ * Needed for transparent proxying.
+ *
+ * This code is presently ugly and needs cleanup.
+ * Probably should add a chkaddr entry to ipprot to call a chk routine
+ * in udp.c or tcp.c...
+ */
+
+int icmp_chkaddr(struct sk_buff *skb)
+{
+ struct icmphdr *icmph=(struct icmphdr *)(skb->h.raw + skb->h.iph->ihl*4);
+ struct iphdr *iph = (struct iphdr *) (icmph + 1);
+ void (*handler)(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len) = icmp_pointers[icmph->type].handler;
+
+ if (handler == icmp_unreach || handler == icmp_redirect) {
+ struct sock *sk;
+
+ switch (iph->protocol) {
+ case IPPROTO_TCP:
+ {
+ struct tcphdr *th = (struct tcphdr *)(((unsigned char *)iph)+(iph->ihl<<2));
+
+ sk = get_sock(&tcp_prot, th->source, iph->daddr,
+ th->dest, iph->saddr, 0, 0);
+ if (!sk) return 0;
+ if (sk->saddr != iph->saddr) return 0;
+ if (sk->daddr != iph->daddr) return 0;
+ if (sk->dummy_th.dest != th->dest) return 0;
+ /*
+ * This packet came from us.
+ */
+ return 1;
+ }
+ case IPPROTO_UDP:
+ {
+ struct udphdr *uh = (struct udphdr *)(((unsigned char *)iph)+(iph->ihl<<2));
+
+ sk = get_sock(&udp_prot, uh->source, iph->daddr,
+ uh->dest, iph->saddr, 0, 0);
+ if (!sk) return 0;
+ if (sk->saddr != iph->saddr && ip_chk_addr(iph->saddr) != IS_MYADDR)
+ return 0;
+ /*
+ * This packet may have come from us.
+ * Assume it did.
+ */
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+#endif
/*
* Deal with incoming ICMP packets.
*/
@@ -928,6 +987,9 @@
__u32 saddr, int redo, struct inet_protocol *protocol)
{
struct icmphdr *icmph=(void *)skb->h.raw;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+ int r;
+#endif
icmp_statistics.IcmpInMsgs++;
/*
@@ -960,7 +1022,16 @@
* Parse the ICMP message
*/
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+ /*
+ * We may get non-local addresses and still want to handle them
+ * locally, due to transparent proxying.
+ * Thus, narrow down the test to what is really meant.
+ */
+ if (daddr!=dev->pa_addr && ((r = ip_chk_addr(daddr)) == IS_BROADCAST || r == IS_MULTICAST))
+#else
if (daddr!=dev->pa_addr && ip_chk_addr(daddr) != IS_MYADDR)
+#endif
{
/*
* RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be silently ignored (we don't as it is used
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this