netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Update SNMP basic for full IP address NAT
@ 2006-11-02 17:38 zze-Ganesh KERDONCUFF G ext RD-MAPS-REN
  2006-11-03 10:23 ` Patrick McHardy
  0 siblings, 1 reply; 2+ messages in thread
From: zze-Ganesh KERDONCUFF G ext RD-MAPS-REN @ 2006-11-02 17:38 UTC (permalink / raw)
  To: netdev

All,

This patch applies to the netfilter file   nat_ip_snmp_basic.c

The algorithm now applies NAT to the complete IP address (and not only
the first byte)
It also recomputes the UDP checksum accordingly.

Please apply this patch to the 2.6.18.1 official release.

Many thanks to Remy Harel for his early contributions on this code.

Gilles Kerdoncuff

---

--- linux-2.6.18.1/net/ipv4/netfilter/ip_nat_snmp_basic.c
2006-10-14 05:34:03.000000000 +0200
+++ linux/net/ipv4/netfilter/ip_nat_snmp_basic.c	2006-11-02
17:02:24.000000000 +0100
@@ -70,14 +70,12 @@
 static DEFINE_SPINLOCK(snmp_lock);
 
 /* 
- * Application layer address mapping mimics the NAT mapping, but 
- * only for the first octet in this case (a more flexible system
- * can be implemented if needed).
+ * Application layer address mapping (complete IP)
  */
-struct oct1_map
+struct ip_map
 {
-	u_int8_t from;
-	u_int8_t to;
+	u_int32_t from;
+	u_int32_t to;
 };
 
                                   
@@ -612,7 +610,7 @@
 
 static inline void mangle_address(unsigned char *begin,
                                   unsigned char *addr,
-                                  const struct oct1_map *map,
+                                  const struct ip_map *map,
                                   u_int16_t *check);
 struct snmp_cnv
 {
@@ -907,6 +905,23 @@
 	csum[1] = x & 0xFF;
 }
 
+/* Fast checksum update on 16 bits */
+static void update_csum(u_int16_t *csum,
+                        u_int16_t *old_addr,
+                        u_int16_t *new_addr,
+                        int       odd)
+{
+	/* The idea is to call 4 times the fast csum function which
recalculate the new
+	 * csum according to the new ip address in the payload
+	 */
+	int i;
+	for (i=0;i<4;i++) {
+		fast_csum((unsigned char*)csum, ((const unsigned
char*)(old_addr))+i, ((const unsigned char*)(new_addr))+i,(odd+i)%2 );
+	}
+}
+
+
+
 /* 
  * Mangle IP address.
  * 	- begin points to the start of the snmp messgae
@@ -914,24 +929,22 @@
  */
 static inline void mangle_address(unsigned char *begin,
                                   unsigned char *addr,
-                                  const struct oct1_map *map,
+                                  const struct ip_map *map,
                                   u_int16_t *check)
 {
-	if (map->from == NOCT1(*addr)) {
-		u_int32_t old;
-		
-		if (debug)
-			memcpy(&old, (unsigned char *)addr,
sizeof(old));
-			
-		*addr = map->to;
-		
+	u_int32_t old;
+
+	memcpy(&old, (unsigned char *)addr, sizeof(old));
+
+	if (map->from == old) {
+		*((u_int32_t*) addr) = map->to;
+
 		/* Update UDP checksum if being used */
 		if (*check) {
 			unsigned char odd = !((addr - begin) % 2);
 			
-			fast_csum((unsigned char *)check,
-			          &map->from, &map->to, odd);
-			          
+			update_csum(check, (u_int16_t*)&old,
(u_int16_t*)addr, odd);
+
 		}
 		
 		if (debug)
@@ -942,7 +955,7 @@
 
 static unsigned char snmp_trap_decode(struct asn1_ctx *ctx,
                                       struct snmp_v1_trap *trap,
-                                      const struct oct1_map *map,
+                                      const struct ip_map *map,
                                       u_int16_t *check)
 {
 	unsigned int cls, con, tag, len;
@@ -1036,7 +1049,7 @@
  */
 static int snmp_parse_mangle(unsigned char *msg,
                              u_int16_t len,
-                             const struct oct1_map *map,
+                             const struct ip_map *map,
                              u_int16_t *check)
 {
 	unsigned char *eoc, *end;
@@ -1215,7 +1228,7 @@
 	u_int16_t udplen = ntohs(udph->len);
 	u_int16_t paylen = udplen - sizeof(struct udphdr);
 	int dir = CTINFO2DIR(ctinfo);
-	struct oct1_map map;
+	struct ip_map map;
 
 	/*
 	 * Determine mappping for application layer addresses based
@@ -1223,12 +1236,12 @@
 	 */
 	if (dir == IP_CT_DIR_ORIGINAL) {
 		/* SNAT traps */
-		map.from =
NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip);
-		map.to =
NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip);
+		map.from =
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+		map.to = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
 	} else {
 		/* DNAT replies */
-		map.from =
NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
-		map.to =
NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip);
+		map.from = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
+		map.to = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
 	}
 	
 	if (map.from == map.to)



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

* Re: [PATCH] Update SNMP basic for full IP address NAT
  2006-11-02 17:38 [PATCH] Update SNMP basic for full IP address NAT zze-Ganesh KERDONCUFF G ext RD-MAPS-REN
@ 2006-11-03 10:23 ` Patrick McHardy
  0 siblings, 0 replies; 2+ messages in thread
From: Patrick McHardy @ 2006-11-03 10:23 UTC (permalink / raw)
  To: zze-Ganesh KERDONCUFF G ext RD-MAPS-REN; +Cc: netdev

zze-Ganesh KERDONCUFF G ext RD-MAPS-REN wrote:
> The algorithm now applies NAT to the complete IP address (and not only
> the first byte)
> It also recomputes the UDP checksum accordingly.

I'm not too familiar with SNMP NAT, please send this to
netfilter-devel@lists.netfilter.org so other netfilter
developers get a chance to look at it.


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

end of thread, other threads:[~2006-11-03 10:23 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-02 17:38 [PATCH] Update SNMP basic for full IP address NAT zze-Ganesh KERDONCUFF G ext RD-MAPS-REN
2006-11-03 10:23 ` Patrick McHardy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).