patch-2.2.19 linux/net/ipv4/ip_masq.c

Next file: linux/net/ipv4/ip_masq_app.c
Previous file: linux/net/ipv4/ip_input.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/net/ipv4/ip_masq.c linux/net/ipv4/ip_masq.c
@@ -4,7 +4,7 @@
  *
  * 	Copyright (c) 1994 Pauline Middelink
  *
- *	$Id: ip_masq.c,v 1.34.2.2 1999/08/07 10:56:28 davem Exp $
+ *	$Id: ip_masq.c,v 1.34.2.14 2001/02/02 01:27:08 davem Exp $
  *
  *
  *	See ip_fw.c for original log
@@ -236,7 +236,7 @@
 	
 tcp_state_out:
 	if (new_state!=ms->state)
-		IP_MASQ_DEBUG(1, "%s %s [%c%c%c%c] %08lX:%04X-%08lX:%04X state: %s->%s\n",
+		IP_MASQ_DEBUG(1, "%s %s [%c%c%c%c] %08X:%04X-%08X:%04X state: %s->%s\n",
 				masq_proto_name(ms->protocol),
 				output? "output" : "input ",
 				th->syn? 'S' : '.',
@@ -798,7 +798,7 @@
 	 */
 	atomic_inc(&ms->refcnt);
 
-	IP_MASQ_DEBUG(1, "Masqueraded %s %08lX:%04X expired\n",
+	IP_MASQ_DEBUG(1, "Masqueraded %s %08X:%04X expired\n",
 			masq_proto_name(ms->protocol),
 			ntohl(ms->saddr),ntohs(ms->sport));
 
@@ -846,7 +846,7 @@
 	}
 
 masq_expire_later:
-	IP_MASQ_DEBUG(0, "masq_expire delayed: %s %08lX:%04X->%08lX:%04X masq.refcnt-1=%d masq.n_control=%d\n",
+	IP_MASQ_DEBUG(0, "masq_expire delayed: %s %08X:%04X->%08X:%04X masq.refcnt-1=%d masq.n_control=%d\n",
 		masq_proto_name(ms->protocol),
 		ntohl(ms->saddr), ntohs(ms->sport),
 		ntohl(ms->daddr), ntohs(ms->dport),
@@ -1223,7 +1223,7 @@
 
 	/* h.raw = (char*) iph + iph->ihl * 4; */
 
- 	IP_MASQ_DEBUG(2, "Outgoing %s %08lX:%04X -> %08lX:%04X\n",
+ 	IP_MASQ_DEBUG(2, "Outgoing %s %08X:%04X -> %08X:%04X\n",
   		masq_proto_name(iph->protocol),
   		ntohl(iph->saddr), ntohs(h.portp[0]),
   		ntohl(iph->daddr), ntohs(h.portp[1]));
@@ -1294,6 +1294,8 @@
 					0);
                 if (ms == NULL)
 			return -1;
+		if (!ms->app && skb->fwmark)
+			ip_masq_bind_app_fwmark(ms, skb->fwmark);
  	}
 
 	/*
@@ -1387,7 +1389,7 @@
 	}
 	ip_send_check(iph);
 
-  	IP_MASQ_DEBUG(2, "O-routed from %08lX:%04X with masq.addr %08lX\n",
+  	IP_MASQ_DEBUG(2, "O-routed from %08X:%04X with masq.addr %08X\n",
 		ntohl(ms->maddr),ntohs(ms->mport),ntohl(maddr));
 
 	masq_set_state(ms, 1, iph, h.portp);
@@ -1485,8 +1487,9 @@
 	__u16	        *pptr;	/* port numbers from TCP/UDP contained header */
 	struct ip_masq	*ms;
 	unsigned short   len   = ntohs(iph->tot_len) - (iph->ihl * 4);
+	unsigned short	clen, csize;
 
- 	IP_MASQ_DEBUG(2, "Incoming forward ICMP (%d,%d) %lX -> %lX\n",
+ 	IP_MASQ_DEBUG(2, "Incoming forward ICMP (%d,%d) %X -> %X\n",
 	        icmph->type, ntohs(icmp_id(icmph)),
  		ntohl(iph->saddr), ntohl(iph->daddr));
 
@@ -1496,7 +1499,7 @@
 	    (icmph->type == ICMP_INFO_REQUEST ) ||
 	    (icmph->type == ICMP_ADDRESS )) {
 
-		IP_MASQ_DEBUG(2, "icmp request rcv %lX->%lX  id %d type %d\n",
+		IP_MASQ_DEBUG(2, "icmp request rcv %X->%X  id %d type %d\n",
 		       ntohl(iph->saddr),
 		       ntohl(iph->daddr),
 		       ntohs(icmp_id(icmph)),
@@ -1547,7 +1550,7 @@
 		icmph->checksum = 0;
 		icmph->checksum = ip_compute_csum((unsigned char *)icmph, len);
 
-		IP_MASQ_DEBUG(2, "icmp request rwt %lX->%lX id %d type %d\n",
+		IP_MASQ_DEBUG(2, "icmp request rwt %X->%X id %d type %d\n",
 		       ntohl(iph->saddr),
 		       ntohl(iph->daddr),
 		       ntohs(icmp_id(icmph)),
@@ -1574,18 +1577,24 @@
 		return 0;
 
 	/* Now find the contained IP header */
+	clen = len - sizeof(struct icmphdr);
+	if (clen < sizeof(struct iphdr)) return -1;
 	ciph = (struct iphdr *) (icmph + 1);
+	csize = ciph->ihl << 2;
+	if (clen < csize) return -1;
 
 #ifdef CONFIG_IP_MASQUERADE_ICMP
 	if (ciph->protocol == IPPROTO_ICMP) {
 		/*
 		 * This section handles ICMP errors for ICMP packets
 		 */
-		struct icmphdr  *cicmph = (struct icmphdr *)((char *)ciph + 
-							     (ciph->ihl<<2));
+		struct icmphdr  *cicmph;
 
+		if (clen < csize + sizeof(struct icmphdr)) return -1;
 
-		IP_MASQ_DEBUG(2, "fw icmp/icmp rcv %lX->%lX id %d type %d\n",
+		cicmph = (struct icmphdr *)((char *)ciph + csize);
+
+		IP_MASQ_DEBUG(2, "fw icmp/icmp rcv %X->%X id %d type %d\n",
 		       ntohl(ciph->saddr),
 		       ntohl(ciph->daddr),
 		       ntohs(icmp_id(cicmph)),
@@ -1621,7 +1630,7 @@
 		icmph->checksum = ip_compute_csum((unsigned char *) icmph, len);
 
 
-		IP_MASQ_DEBUG(2, "fw icmp/icmp rwt %lX->%lX id %d type %d\n",
+		IP_MASQ_DEBUG(2, "fw icmp/icmp rwt %X->%X id %d type %d\n",
 		       ntohl(ciph->saddr),
 		       ntohl(ciph->daddr),
 		       ntohs(icmp_id(cicmph)),
@@ -1635,12 +1644,15 @@
 	if ((ciph->protocol != IPPROTO_UDP) && (ciph->protocol != IPPROTO_TCP))
 		return 0;
 
+	/* This is a hack: we need at least the TCP/UDP ports */
+	if (clen < csize + sizeof(struct udphdr)) return -1;
+
 	/*
 	 * 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]);
+	pptr = (__u16 *)&(((char *)ciph)[csize]);
 #if 0
 	if (ntohs(pptr[1]) < PORT_MASQ_BEGIN ||
  	    ntohs(pptr[1]) > PORT_MASQ_END)
@@ -1657,7 +1669,7 @@
 	}
 
 
- 	IP_MASQ_DEBUG(2, "Handling forward ICMP for %08lX:%04X -> %08lX:%04X\n",
+ 	IP_MASQ_DEBUG(2, "Handling forward ICMP for %08X:%04X -> %08X:%04X\n",
 	       ntohl(ciph->saddr), ntohs(pptr[0]),
 	       ntohl(ciph->daddr), ntohs(pptr[1]));
 
@@ -1695,7 +1707,7 @@
 	icmph->checksum = ip_compute_csum((unsigned char *) icmph, len);
 
 
- 	IP_MASQ_DEBUG(2, "Rewrote forward ICMP to %08lX:%04X -> %08lX:%04X\n",
+ 	IP_MASQ_DEBUG(2, "Rewrote forward ICMP to %08X:%04X -> %08X:%04X\n",
 	       ntohl(ciph->saddr), ntohs(pptr[0]),
 	       ntohl(ciph->daddr), ntohs(pptr[1]));
 
@@ -1743,9 +1755,10 @@
 	__u16	        *pptr;	/* port numbers from TCP/UDP contained header */
 	struct ip_masq	*ms;
 	unsigned short   len   = ntohs(iph->tot_len) - (iph->ihl * 4);
+	unsigned short	clen, csize;
 
 
- 	IP_MASQ_DEBUG(2, "icmp in/rev (%d,%d) %lX -> %lX\n",
+ 	IP_MASQ_DEBUG(2, "icmp in/rev (%d,%d) %X -> %X\n",
 	        icmph->type, ntohs(icmp_id(icmph)),
  		ntohl(iph->saddr), ntohl(iph->daddr));
 
@@ -1756,7 +1769,7 @@
 	    (icmph->type == ICMP_INFO_REPLY) ||
 	    (icmph->type == ICMP_ADDRESSREPLY))	{
 
-		IP_MASQ_DEBUG(2, "icmp reply rcv %lX->%lX id %d type %d, req %d\n",
+		IP_MASQ_DEBUG(2, "icmp reply rcv %X->%X id %d type %d, req %d\n",
 		       ntohl(iph->saddr),
 		       ntohl(iph->daddr),
 		       ntohs(icmp_id(icmph)),
@@ -1793,7 +1806,7 @@
 
 
 
-		IP_MASQ_DEBUG(2, "icmp reply rwt %lX->%lX id %d type %d\n",
+		IP_MASQ_DEBUG(2, "icmp reply rwt %X->%X id %d type %d\n",
 		       ntohl(iph->saddr),
 		       ntohl(iph->daddr),
 		       ntohs(icmp_id(icmph)),
@@ -1817,7 +1830,11 @@
 	 * Now find the contained IP header
 	 */
 
+	clen = len - sizeof(struct icmphdr);
+	if (clen < sizeof(struct iphdr)) return -1;
 	ciph = (struct iphdr *) (icmph + 1);
+	csize = ciph->ihl << 2;
+	if (clen < csize) return -1;
 
 #ifdef CONFIG_IP_MASQUERADE_ICMP
 	if (ciph->protocol == IPPROTO_ICMP) {
@@ -1826,11 +1843,13 @@
 		 *
 		 * First get a new ICMP header structure out of the IP packet
 		 */
-		struct icmphdr  *cicmph = (struct icmphdr *)((char *)ciph + 
-							     (ciph->ihl<<2));
+		struct icmphdr  *cicmph;
+
+		if (clen < csize + sizeof(struct icmphdr)) return -1;
 
+		cicmph = (struct icmphdr *)((char *)ciph +  csize);
 
-		IP_MASQ_DEBUG(2, "rv icmp/icmp rcv %lX->%lX id %d type %d\n",
+		IP_MASQ_DEBUG(2, "rv icmp/icmp rcv %X->%X id %d type %d\n",
 		       ntohl(ciph->saddr),
 		       ntohl(ciph->daddr),
 		       ntohs(icmp_id(cicmph)),
@@ -1872,7 +1891,7 @@
 		icmph->checksum = ip_compute_csum((unsigned char *) icmph, len);
 
 
-		IP_MASQ_DEBUG(2, "rv icmp/icmp rwt %lX->%lX id %d type %d\n",
+		IP_MASQ_DEBUG(2, "rv icmp/icmp rwt %X->%X id %d type %d\n",
 		       ntohl(ciph->saddr),
 		       ntohl(ciph->daddr),
 		       ntohs(icmp_id(cicmph)),
@@ -1887,11 +1906,14 @@
 	    (ciph->protocol != IPPROTO_TCP))
 		return 0;
 
+	/* This is a hack: we need at least the TCP/UDP ports */
+	if (clen < csize + sizeof(struct udphdr)) return -1;
+
 	/*
 	 * Find the ports involved - remember this packet was
 	 * *outgoing* so the ports are reversed (and addresses)
 	 */
-	pptr = (__u16 *)&(((char *)ciph)[ciph->ihl*4]);
+	pptr = (__u16 *)&(((char *)ciph)[csize]);
 	if (ntohs(pptr[0]) < PORT_MASQ_BEGIN ||
  	    ntohs(pptr[0]) > PORT_MASQ_END)
  		return 0;
@@ -1906,7 +1928,7 @@
 	}
 
 
- 	IP_MASQ_DEBUG(2, "Handling reverse ICMP for %08lX:%04X -> %08lX:%04X\n",
+ 	IP_MASQ_DEBUG(2, "Handling reverse ICMP for %08X:%04X -> %08X:%04X\n",
 	       ntohl(ciph->saddr), ntohs(pptr[0]),
 	       ntohl(ciph->daddr), ntohs(pptr[1]));
 
@@ -1948,7 +1970,7 @@
 	icmph->checksum = ip_compute_csum((unsigned char *) icmph, len);
 
 
- 	IP_MASQ_DEBUG(2, "Rewrote reverse ICMP to %08lX:%04X -> %08lX:%04X\n",
+ 	IP_MASQ_DEBUG(2, "Rewrote reverse ICMP to %08X:%04X -> %08X:%04X\n",
 	       ntohl(ciph->saddr), ntohs(pptr[0]),
 	       ntohl(ciph->daddr), ntohs(pptr[1]));
 
@@ -2067,7 +2089,7 @@
 
 
 
- 	IP_MASQ_DEBUG(2, "Incoming %s %08lX:%04X -> %08lX:%04X\n",
+ 	IP_MASQ_DEBUG(2, "Incoming %s %08X:%04X -> %08X:%04X\n",
  		masq_proto_name(iph->protocol),
  		ntohl(iph->saddr), ntohs(h.portp[0]),
  		ntohl(iph->daddr), ntohs(h.portp[1]));
@@ -2082,8 +2104,11 @@
  	 * 	Give additional modules a chance to create an entry
 	 */
 #ifdef CONFIG_IP_MASQUERADE_MOD
-	if (!ms) 
+	if (!ms) {
 		ms = ip_masq_mod_in_create(skb, iph, maddr);
+		if (ms && !ms->app && skb->fwmark)
+			ip_masq_bind_app_fwmark(ms, skb->fwmark);
+	}
 
 	/*
  	 * 	Call module's input update hook
@@ -2138,7 +2163,7 @@
 
 			write_unlock(&__ip_masq_lock);
 
-                        IP_MASQ_DEBUG(1, "ip_fw_demasquerade(): filled daddr=%lX\n",
+                        IP_MASQ_DEBUG(1, "ip_fw_demasquerade(): filled daddr=%X\n",
                                ntohl(ms->daddr));
 
                 }
@@ -2208,7 +2233,7 @@
 		}
                 ip_send_check(iph);
 
-                IP_MASQ_DEBUG(2, "I-routed to %08lX:%04X\n",ntohl(iph->daddr),ntohs(h.portp[1]));
+                IP_MASQ_DEBUG(2, "I-routed to %08X:%04X\n",ntohl(iph->daddr),ntohs(h.portp[1]));
 
 		masq_set_state (ms, 0, iph, h.portp);
 		ip_masq_put(ms);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)