patch-pre2.0.11 linux/net/ipv4/ip_masq.c
Next file: linux/net/ipv4/sysctl_net_ipv4.c
Previous file: linux/net/ipv4/ip_forward.c
Back to the patch index
Back to the overall index
- Lines: 144
- Date:
Mon Jun 3 12:42:41 1996
- Orig file:
pre2.0.10/linux/net/ipv4/ip_masq.c
- Orig date:
Sat Jun 1 20:11:37 1996
diff -u --recursive --new-file pre2.0.10/linux/net/ipv4/ip_masq.c linux/net/ipv4/ip_masq.c
@@ -568,8 +568,108 @@
return 0;
}
+
+/*
+ * Handle ICMP messages in forward direction.
+ * Find any that might be relevant, check against existing connections,
+ * forward to masqueraded host if relevant.
+ * Currently handles error types - unreachable, quench, ttl exceeded
+ */
+
+int ip_fw_masq_icmp(struct sk_buff **skb_p, struct device *dev)
+{
+ struct sk_buff *skb = *skb_p;
+ struct iphdr *iph = skb->h.iph;
+ struct icmphdr *icmph = (struct icmphdr *)((char *)iph + (iph->ihl<<2));
+ struct iphdr *ciph; /* The ip header contained within the ICMP */
+ __u16 *pptr; /* port numbers from TCP/UDP contained header */
+ struct ip_masq *ms;
+ unsigned short len = ntohs(iph->tot_len) - (iph->ihl * 4);
+
+#ifdef DEBUG_CONFIG_IP_MASQUERADE
+ printk("Incoming forward ICMP (%d) %lX -> %lX\n",
+ icmph->type,
+ ntohl(iph->saddr), ntohl(iph->daddr));
+#endif
+
+ /*
+ * Work through seeing if this is for us.
+ * These checks are supposed to be in an order that
+ * means easy things are checked first to speed up
+ * processing.... however this means that some
+ * packets will manage to get a long way down this
+ * stack and then be rejected, but thats life
+ */
+ if ((icmph->type != ICMP_DEST_UNREACH) &&
+ (icmph->type != ICMP_SOURCE_QUENCH) &&
+ (icmph->type != ICMP_TIME_EXCEEDED))
+ return 0;
+
+ /* Now find the contained IP header */
+ ciph = (struct iphdr *) (icmph + 1);
+
+ /* We are only interested ICMPs generated from TCP or UDP packets */
+ if ((ciph->protocol != IPPROTO_UDP) && (ciph->protocol != IPPROTO_TCP))
+ return 0;
+
+ /*
+ * Find the ports involved - this packet was
+ * incoming so the ports are right way round
+ * (but reversed relative to outer IP header!)
+ */
+ pptr = (__u16 *)&(((char *)ciph)[ciph->ihl*4]);
+ if (ntohs(pptr[1]) < PORT_MASQ_BEGIN ||
+ ntohs(pptr[1]) > PORT_MASQ_END)
+ return 0;
+
+ /* Ensure the checksum is correct */
+ if (ip_compute_csum((unsigned char *) icmph, len))
+ {
+ /* Failed checksum! */
+ printk(KERN_INFO "MASQ: forward ICMP: failed checksum from %s!\n",
+ in_ntoa(iph->saddr));
+ return(-1);
+ }
+
+#ifdef DEBUG_CONFIG_IP_MASQUERADE
+ printk("Handling forward ICMP for %lX:%X -> %lX:%X\n",
+ ntohl(ciph->saddr), ntohs(pptr[0]),
+ ntohl(ciph->daddr), ntohs(pptr[1]));
+#endif
+
+ /* This is pretty much what ip_masq_in_get() does */
+ ms = ip_masq_in_get_2(ciph->protocol, ciph->saddr, pptr[0], ciph->daddr, pptr[1]);
+
+ if (ms == NULL)
+ return 0;
+
+ /* Now we do real damage to this packet...! */
+ /* First change the source IP address, and recalc checksum */
+ iph->saddr = ms->maddr;
+ ip_send_check(iph);
+
+ /* Now change the *dest* address in the contained IP */
+ ciph->daddr = ms->maddr;
+ ip_send_check(ciph);
+
+ /* the TCP/UDP dest port - cannot redo check */
+ pptr[1] = ms->mport;
+
+ /* And finally the ICMP checksum */
+ icmph->checksum = 0;
+ icmph->checksum = ip_compute_csum((unsigned char *) icmph, len);
+
+#ifdef DEBUG_CONFIG_IP_MASQUERADE
+ printk("Rewrote forward ICMP to %lX:%X -> %lX:%X\n",
+ ntohl(ciph->saddr), ntohs(pptr[0]),
+ ntohl(ciph->daddr), ntohs(pptr[1]));
+#endif
+
+ return 1;
+}
+
/*
- * Handle ICMP messages.
+ * Handle ICMP messages in reverse (demasquerade) direction.
* Find any that might be relevant, check against existing connections,
* forward to masqueraded host if relevant.
* Currently handles error types - unreachable, quench, ttl exceeded
@@ -586,7 +686,7 @@
unsigned short len = ntohs(iph->tot_len) - (iph->ihl * 4);
#ifdef DEBUG_CONFIG_IP_MASQUERADE
- printk("Incoming ICMP (%d) %lX -> %lX\n",
+ printk("Incoming reverse ICMP (%d) %lX -> %lX\n",
icmph->type,
ntohl(iph->saddr), ntohl(iph->daddr));
#endif
@@ -616,12 +716,13 @@
if (ip_compute_csum((unsigned char *) icmph, len))
{
/* Failed checksum! */
- printk(KERN_INFO "MASQ: ICMP: failed checksum from %s!\n", in_ntoa(iph->saddr));
+ printk(KERN_INFO "MASQ: reverse ICMP: failed checksum from %s!\n",
+ in_ntoa(iph->saddr));
return(-1);
}
#ifdef DEBUG_CONFIG_IP_MASQUERADE
- printk("Handling ICMP for %lX:%X -> %lX:%X\n",
+ printk("Handling reverse ICMP for %lX:%X -> %lX:%X\n",
ntohl(ciph->saddr), ntohs(pptr[0]),
ntohl(ciph->daddr), ntohs(pptr[1]));
#endif
@@ -649,7 +750,7 @@
icmph->checksum = ip_compute_csum((unsigned char *) icmph, len);
#ifdef DEBUG_CONFIG_IP_MASQUERADE
- printk("Rewrote ICMP to %lX:%X -> %lX:%X\n",
+ printk("Rewrote reverse ICMP to %lX:%X -> %lX:%X\n",
ntohl(ciph->saddr), ntohs(pptr[0]),
ntohl(ciph->daddr), ntohs(pptr[1]));
#endif
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