All of lore.kernel.org
 help / color / mirror / Atom feed
* mangle MSS via tcp_manip_pkt() in ip_nat_proto_tcp.c [patch]
@ 2003-07-18 14:57 Michael Glaum
  2003-07-18 17:16 ` Filip Sneppe
  2003-07-25 20:50 ` Harald Welte
  0 siblings, 2 replies; 3+ messages in thread
From: Michael Glaum @ 2003-07-18 14:57 UTC (permalink / raw)
  To: netfilter-devel


I just patched ip_nat_proto_tcp.c, below, for a specific application and
are looking for criticism.

We have 2.4.18-3 box whose route onto the internet is via satellite. There
is a cisco box in this route that inelegantly blocks packets larger than
1470. I don't have control over this route.

This 2.4.18-3 box is running iptables in masquerade mode. The private
network machines behind it are windohs boxes. I can't control the MTU
on these boxes so when they surf to www.freebsd.org they hang due to
the 1470 problem above.

I tried several things, e.g. pathMTU, etc but in view of severe time
constraints I decided to HACK tcp_manip_pkt() in ip_nat_proto_tcp.c
so that when it does source and destination address translation it also
drops the MSS on outgoing and incoming packets to be below 1360. This
appears to work. I didn't even bother to check if the packets had
tcphdr->syn ==1 set.

Please advise if there is a more elegant way to do this!

								Michael Glaum
								KVH Industries


cd /usr/src/linux/net/ipv4/netfilter
diff -u ip_nat_proto_tcp.old ip_nat_proto_tcp.c
--- ip_nat_proto_tcp.old	Tue Aug  7 11:30:50 2001
+++ ip_nat_proto_tcp.c	Fri Jul 18 03:57:56 2003
@@ -9,6 +9,8 @@
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
 
+#include <net/tcp.h>
+
 static int
 tcp_in_range(const struct ip_conntrack_tuple *tuple,
 	     enum ip_nat_manip_type maniptype,
@@ -74,6 +76,56 @@
 	return 0;
 }
 
+static u_int16_t
+cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
+{
+u_int32_t diffs[] = { oldvalinv, newval };
+
+	return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
+                         oldcheck^0xFFFF));
+}
+
+static u_int8_t * locate_mss( struct tcphdr * tcp ) {
+u_int8_t *opt;
+int	   i;
+
+    opt = (u_int8_t *)tcp;
+    for (i = sizeof(struct tcphdr); i < tcp->doff * 4; ) {
+        if ((opt[i] == TCPOPT_MSS)
+            && ((tcp->doff * 4 - i) >= TCPOLEN_MSS)
+            && (opt[i+1] == TCPOLEN_MSS)) {
+                return &opt[i+2];
+        } /* if opt==TCPOPT_MSS */
+
+        if (opt[i] < 2) {
+            i++;
+        } else {
+            i += opt[i+1]?:1;
+        }
+    } /* for */
+
+    return NULL;
+} /* locate_mss() */
+
+static void mangle_mss( struct tcphdr * tcp ) {
+u_int8_t * pmss;
+u_int16_t oldmss;
+u_int16_t newmss;
+
+	pmss = locate_mss( tcp );
+	if( pmss == NULL ) {
+		return;
+	}
+	oldmss=  (pmss[0] << 8 ) | pmss[1];
+	if( oldmss > 1360 ) {
+		newmss = 1360;
+		pmss[0] = 5;
+		pmss[1] = 0x50;
+		tcp->check = cheat_check( htons(oldmss)^0xffff,
+				htons(newmss), tcp->check );
+	}
+} /* mangle_mss() */
+
 static void
 tcp_manip_pkt(struct iphdr *iph, size_t len,
 	      const struct ip_conntrack_manip *manip,
@@ -101,6 +153,7 @@
 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
 							   manip->u.tcp.port,
 							   hdr->check));
+		mangle_mss( hdr );
 	}
 
 	*portptr = manip->u.tcp.port;

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2003-07-25 20:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-18 14:57 mangle MSS via tcp_manip_pkt() in ip_nat_proto_tcp.c [patch] Michael Glaum
2003-07-18 17:16 ` Filip Sneppe
2003-07-25 20:50 ` Harald Welte

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.