[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cipe
Subject:    Speed up
From:       Allan Latham <alatham () ibm ! net>
Date:       1998-11-10 20:45:11
[Download RAW message or body]

Hi everyone

I found the old changes I made for shorter packets. I have applied these
to rev 1.0.0 and produced a new patch file. I can't promise these will
work in a live active environment but they are worth a try. I use a
modified cipe which includes this mode and some more changes and it has
been in daily use for many months.

Any feedback is most welcome.

To apply these patches you will need to cut out between the 
*---------------------- 
lines and make the cut out file cipe-patch
Then cd into the directory which contains cipe-1.0.0
Then do patch -p0 <cipe-patch

cd into cipe-1.0.0 then make clean and make.

Restrictions:
1. tos is ignored
2. ttl is hacked
3. you can't have more than 64 address pairs through the cipe link.

(not a big problem for small VPNs)

Best regards

Allan.

P.S. Also added the file as a attachment just in case

A.


*-----------------------------------------------
--- cipe-1.0.0.orig/encaps.c	Tue Apr  7 22:08:50 1998
+++ cipe-1.0.0/encaps.c	Tue Nov 10 17:44:19 1998
@@ -176,8 +176,10 @@
     unsigned char p=7-(((*len)+4)&7);
     /* merge key flag in IV */
     *buf&=0x7F;
-    if (c->haveskey)
+    if (c->haveskey) {
+	dprintk1(DEB_CRYPT, KERN_INFO, "%s: haveskey\n", DEVNAME);
 	*buf|=0x80;
+    }
     /* pad */
     cipe_prnpad(buf+(*len), p);
     (*len)+=p+5;
@@ -196,6 +198,9 @@
 {
     unsigned char p;
 
+    if (c->haverkey)  {
+	dprintk1(DEB_CRYPT, KERN_INFO, "%s: haverkey\n", DEVNAME);
+    }
     if (((*buf)&0x80) && !(c->haverkey)) {
 	cipe_nodynkey(c);
 	return TW_ERROR; /* can't decrypt - no valid key */
@@ -207,7 +212,8 @@
 		 "%s: decrypt CRC error\n", c->dev->name);
 	return TW_ERROR;
     }
-    p=*(buf+(*len)-5);
+    (*len)-=5;
+    p=*(buf+(*len));
     (*len)-=(p>>4)&7;
     cipe_checkrkey(c);
 #define CTLBITS 0x06
--- cipe-1.0.0.orig/ciped.c	Sun Aug 23 01:21:06 1998
+++ cipe-1.0.0/ciped.c	Tue Nov 10 17:49:48 1998
@@ -14,7 +14,8 @@
 
 #define CTLDIR "/etc/cipe"
 
-#include <errno.h>
+// #include <linux/in.h>       /* from 5.3e */
+#include <errno.h>          /* from 5.6  */
 #include <fcntl.h>
 #include <netdb.h>
 #include <stdio.h>
--- cipe-1.0.0.orig/output.c	Sun Aug 23 01:21:06 1998
+++ cipe-1.0.0/output.c	Tue Nov 10 17:45:50 1998
@@ -22,6 +22,11 @@
 #include <linux/socket.h>
 #include <linux/version.h>
 
+#ifdef VER_LITE
+#include "liteprototypes.h"
+#include <linux/ip.h>
+#endif
+
 #ifdef SO_BINDTODEVICE
   #define iproute(t,o,d) ip_rt_route(t,o,d)
 #else
@@ -49,9 +54,15 @@
     __u32          target;		/* The other host's IP address */
     int      max_headroom;		/* The extra header space needed */
     int      max_tailroom;
-    int tos, ttl, length;
+    int      length;
     DEVTOCIPE(dev,c,0);
 
+#ifdef DEBUG
+    if (cipe_debug&DEB_OUT) {
+        printk(KERN_INFO "%s: raw len = %ld\n", dev->name, skb->len);
+    }
+#endif
+
     if (skb == NULL || dev == NULL) {
 	dprintk1(DEB_OUT, KERN_INFO, "%s: nothing to do\n", dev->name);
 	return 0;
@@ -141,17 +152,20 @@
 		/* Free the old packet, we no longer need it */
 		dev_kfree_skb(skb, FREE_WRITE);
 		skb = new_skb;
-    }
+	}
+
+#ifdef VER_LITE
+        liten(c, skb); 
+#endif 
 
-	tos    = skb->ip_hdr->tos;
-	ttl    = skb->ip_hdr->ttl;
-        length = skb->len;
 	if (c->havekey) {
+
 #ifndef VER_SHORT
 	    /* Add an IV */
 	    cipe_cryptpad(skb_push(skb, blockSize));
-	    length+=blockSize;
 #endif
+            length = skb->len;
+
 	    cipe_encrypt(c, skb->data, &length, TW_DATA);
 	    /* This is incorrect - the tail room gets first used and then
 	       reserved. Doesn't matter in the current (2.0.29) implementation
@@ -186,19 +200,8 @@
 
 	iph 			=	skb->h.iph;
 	iph->version		= 	4;
-	iph->tos		=	tos;
-
-	/* In new_tunnel.c, we use the original packet's TTL here.
-	   Setting a new TTL behaves better to the user, and RFC2003
-	   recommends it too. But this doesn't fully protect against
-	   routing loops. So make it configurable via an argument:
-	   "cttl" gives the TTL value; if 0 use the packet's
-	   value. Default should be 64, as with the other protocols
-	   (ip_statistics.IpDefaultTTL, but this variable is not
-	   available for modules). */
-
-	iph->ttl 		=	c->cttl ? c->cttl : ttl;
-
+	iph->tos		=	IPTOS_LOWDELAY | IPTOS_RELIABILITY;
+	iph->ttl		=	32;
 	iph->frag_off		=	0;
 	iph->daddr		=	target;
 	iph->saddr		=	c->myaddr; /* tdev->pa_addr; */
--- cipe-1.0.0.orig/sock.c	Sun Mar 15 17:31:14 1998
+++ cipe-1.0.0/sock.c	Tue Nov 10 17:46:25 1998
@@ -12,12 +12,16 @@
 */
 /* $Id: sock.c,v 1.11 1998/03/15 16:31:14 olaf Exp $ */
 
+#include <net/ip.h>
 #include "cipe.h"
 #include <linux/if.h>
 #include <net/sock.h>
 #include <linux/module.h>
 #include <linux/config.h>
 
+#ifdef VER_LITE
+#include "liteprototypes.h"
+#endif
 
 /* Rewire generic socket operations to our device-specific ones.
    We have new routines for close, sendmsg, recvmsg. */
@@ -137,7 +141,13 @@
     __u32 rsaddr;
     __u16 rsport;
 
-    n=alloc_skb(skb->len, GFP_KERNEL);
+#ifdef VER_LITE
+    length = sizeof(struct iphdr) - PIPHDRLEN
+           + sizeof(struct tcphdr) - CTCPHDRLEN;
+#else
+    length = 0;
+#endif
+    n=alloc_skb(skb->len + length, GFP_KERNEL);
     if (!n) {
 	printk(KERN_WARNING "%s: cipe_decrypt_skb(): out of memory\n",
 	       c->dev->name);
@@ -147,6 +157,8 @@
     n->sk=NULL;
     n->free=1;
     n->dev=c->dev;
+    n->len=skb->len+length;
+    skb_pull(n, length);
 
     length=ntohs(skb->h.uh->len)-sizeof(struct udphdr);
 #if 0 /* UDP should check this */
@@ -211,6 +223,10 @@
 	    n->daddr=c->peeraddr;
 #endif
 	    n->h.uh->check=0;
+
+#ifdef VER_LITE
+            memset(&c->pairs, 0, sizeof(struct pairs));
+#endif
 	    return n;
 	case TW_CTRL:
 	    /* process a control packet - to be implemented */
@@ -224,21 +240,27 @@
 	goto error;
     }
 
+#ifdef VER_LITE
+    litex(c, n, &length, offset);
+#endif    
+
     skb_trim(n, length);
     checkpeer(c, rsaddr, rsport);
-    /* adjust pointers */
     n->h.iph=(struct iphdr *)n->data;
     n->mac.raw=n->data; /* no hardware header */
     memset(n->proto_priv, 0, sizeof(struct options));
     n->protocol = htons(ETH_P_IP);
     n->ip_summed = 0;
+
 #ifdef DEBUG
     if (cipe_debug&DEB_INP) {
-	unsigned char *x=(unsigned char *)&n->h.iph->saddr;
+	unsigned char *x=(unsigned char *)(&n->h.iph->tos - 1);
 	printk(KERN_INFO
-	       "%s: real src %d.%d.%d.%d dst %d.%d.%d.%d len %d\n",
+	       "%s: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x
%x length %d\n",
 	       n->dev->name,
-	       x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], length);
+	       x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9],
+	       x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18],
x[19],
+length);
     }
 #endif
 
--- cipe-1.0.0.orig/Makefile	Sun Aug 23 01:21:06 1998
+++ cipe-1.0.0/Makefile	Tue Nov 10 17:55:56 1998
@@ -23,7 +23,7 @@
 ASM=	i386
 #ASM=
 # Options
-DEFS=	-DDEBUG
+DEFS=	-DDEBUG -DVER_LITE
 
 ### The usual compiler, etc. definitions
 
@@ -90,20 +90,16 @@
 	install -m 644 cipe.info* $(INFODIR)
 	-depmod -a
 
-KOBJS=	device.o sock.o output.o encaps.o
+KOBJS=	device.o sock.o output.o encaps.o lite.o
 ifeq "$(strip $(CRYPTO))" "IDEA"
 KOBJS+=idea0.o
 endif
-ifeq "$(strip $(VERS))" "3"
-COBJS=	crc32.o
-else
-COBJS=	crc.o
-endif
+COBJS=	crc32.o crc.o
 OBJS=	ciped.o ioctl.o socks5.o
 
-SRCS=	cipe.h crypto.h \
+SRCS=	cipe.h crypto.h lite.h \
 	ciped.c ciped.h ioctl.c ioctl.h socks5.c \
-	device.c sock.c output.c encaps.c \
+	device.c sock.c output.c lite.c encaps.c \
 	idea0.h idea0.c bf.h crc.c crc32.c \
 	idea-i386.S bf-i386.S \
 	thruput.c Makefile cipe.lsm
@@ -115,7 +111,7 @@
 $(CIPEM): $(KOBJS) $(COBJS) $(AOBJS)
 	ld $(LDRFLAGS) -o $(CIPEM) $(KOBJS) $(COBJS) $(AOBJS)
 
-ciped:	$(OBJS) $(COBJS)
+ciped:	$(OBJS) $(COBJS) 
 	$(CC) $(LDFLAGS) -o ciped $(OBJS) $(COBJS)
 
 $(AOBJS): %.o: %.S
@@ -166,9 +162,10 @@
 	mv -f Make.tmp Makefile
 
 ### Dependencies
+lite.o: lite.h
 device.o: device.c cipe.h crypto.h idea0.h bf.h
-sock.o: sock.c cipe.h crypto.h idea0.h bf.h
-output.o: output.c cipe.h crypto.h idea0.h bf.h
+sock.o: sock.c cipe.h crypto.h idea0.h bf.h lite.h
+output.o: output.c cipe.h crypto.h idea0.h bf.h lite.h
 encaps.o: encaps.c cipe.h crypto.h idea0.h bf.h
 ciped.o: ciped.c ciped.h cipe.h crypto.h idea0.h bf.h ioctl.h
 ioctl.o: ioctl.c cipe.h crypto.h idea0.h bf.h ioctl.h
--- cipe-1.0.0.orig/cipe.h	Tue Apr  7 22:08:52 1998
+++ cipe-1.0.0/cipe.h	Tue Nov 10 18:16:06 1998
@@ -17,7 +17,6 @@
 
 #include "crypto.h"
 
-
 /*** The kernel/user IOCTL interface ***/
 
 /* ioctls for setup and key exchange */
@@ -166,6 +165,15 @@
      /* Socket interface stuff */
     struct proto    *udp_prot;
     struct proto    cipe_proto;
+
+#ifdef VER_LITE
+#include "lite.h"
+#endif
+
+#ifdef VER_LITE
+    struct pairs      pairs;
+#endif
+
 };
 
 #define MAXBLKS     32767  /* max # blocks to encrypt using one key */
@@ -237,6 +245,9 @@
 #ifdef VER_CRC32
 /* crc32.c */
 extern unsigned long crc32(const unsigned char *s, unsigned int len);
+#ifdef VER_LITE
+extern unsigned short block_crc(unsigned char *d, int len);
+#endif
 #else
 /* crc.c */
 extern unsigned short block_crc(unsigned char *d, int len);
--- cipe-1.0.0.orig/lite.h	Tue Nov 10 18:30:20 1998
+++ cipe-1.0.0/lite.h	Tue Nov 10 16:58:52 1998
@@ -0,0 +1,69 @@
+#ifndef _LITE_H_
+#define _LITE_H_
+
+#define LITE_SEND 0
+#define LITE_RECEIVE 1
+
+#define LITE_NORMAL         0
+#define LITE_SHORT          1
+#define LITE_COMP           2
+/*                 e.g. LITE_TCP + LITE_SHORT -> LITE_TCP_SHORT  */
+#define LITE_ICMP           0
+#define LITE_ICMP_SHORT     1
+#define LITE_UDP            2 
+#define LITE_UDP_SHORT      3
+#define LITE_TCP            5
+#define LITE_TCP_SHORT      6
+#define LITE_TCP_COMP       7
+#define LITE_TCP_SHORT_COMP 8
+
+#define LITE_PAIRS_MAX 64
+    struct pairs {
+        __u32    saddr[LITE_PAIRS_MAX];
+        __u32    daddr[LITE_PAIRS_MAX];
+        __u8     ok[LITE_PAIRS_MAX];
+};
+
+#ifdef _LINUX_IP_H
+
+#include <asm/byteorder.h>
+
+/* this is the compressed IP header */
+
+    struct ciphdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	__u8	ihl:4,
+		version:4;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+	__u8	version:4,
+  		ihl:4;
+#else
+#error	"Please fix <asm/byteorder.h>"
+#endif
+	__u8	pair;
+	__u8 	saddr0;
+	__u8 	saddr1;
+	__u8 	saddr2;
+	__u8 	saddr3;
+	__u8 	raddr0;
+	__u8 	raddr1;
+	__u8 	raddr2;
+	__u8 	raddr3;
+};
+#define CIPHDRLEN 10
+
+#define PIPHDRLEN 2
+
+struct ctcphdr {
+	__u16	source;
+	__u16	dest;
+	__u32	seq;
+	__u32	ack_seq;
+	__u16	check;
+	__u16	winpsh;
+};
+#define CTCPHDRLEN 16
+
+#endif ifdef _LINUX_IP_H
+#endif _LITE_H_
+
--- cipe-1.0.0.orig/liteprototypes.h	Tue Nov 10 18:30:25 1998
+++ cipe-1.0.0/liteprototypes.h	Tue Nov 10 16:58:52 1998
@@ -0,0 +1,2 @@
+void liten(struct cipe*, struct sk_buff*);
+void litex(struct cipe*, struct sk_buff*, int*, int*);
--- cipe-1.0.0.orig/lite.c	Tue Nov 10 20:42:02 1998
+++ cipe-1.0.0/lite.c	Tue Nov 10 20:41:37 1998
@@ -0,0 +1,377 @@
+
+/*
+   CIPE - encrypted IP over UDP tunneling
+
+   lite.c - the compression part of the output routine
+
+   Copyright 1997 Allan Latham <alatham@flexsys-group.com>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version
+   2 of the License, or (at your option) any later version.
+*/
+
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <linux/if_arp.h>
+
+#include "cipe.h"
+#include "liteprototypes.h"
+
+#define EMPTY      0
+#define IKNOW      1
+#define UKNOW      2
+#define IKNOWUKNOW 3
+#define NOTFOUND   127
+#define OKFLAG     128
+
+
+/*-----------------------------------------------------------------*/
+int lite_get_next_free(struct pairs *pairs, __u32 saddr, __u32 daddr)
+{
+ int i;
+
+ for (i=0; i < LITE_PAIRS_MAX; i++)
+ {
+  if ((pairs->saddr[i] == 0) || (pairs->daddr[i] == 0) 
+                             || (pairs->ok[i] == EMPTY))
+  {
+   pairs->saddr[i] = saddr;
+   pairs->daddr[i] = daddr;
+   pairs->ok[i] = IKNOW;
+   return(i);
+  }
+ }
+ return(NOTFOUND);
+}
+
+/*-----------------------------------------------------------------*/
+int lite_get_pair_from_addresses(struct pairs *pairs, __u32 saddr,
+                                                      __u32 daddr, int
sr)
+{
+ __u32 da, sa;
+ int i;
+
+ if (sr == LITE_SEND)
+ { 
+  da = daddr;
+  sa = saddr;
+ }
+ else
+ { 
+  sa = daddr;
+  da = saddr;
+ }
+
+ for (i=0; i < LITE_PAIRS_MAX; i++)
+ {
+  if ((pairs->saddr[i] == sa) && (pairs->daddr[i] == da) 
+                              && (pairs->ok[i] != EMPTY))
+  {
+   return(i);
+  }
+ }
+ return(NOTFOUND);
+}
+
+/*-----------------------------------------------------------------*/
+void liten(struct cipe *cipe, struct sk_buff *skb)
+{
+ struct iphdr  oph;      /* Copy of the old IP header */
+ struct tcphdr otcph;    /* Copy of the old TCP header (if any) */
+ struct ciphdr *ciph;    /* The old IP header (compresed) */
+ struct ctcphdr *ctcph;  /* The old TCP header (compresed) */
+
+ unsigned char ttl, pair, version;
+
+ memcpy(&oph, skb->ip_hdr, sizeof(struct iphdr));
+
+ if (oph.ihl != 5)
+    return;
+ 
+ if ((oph.frag_off & htons(IP_MF|IP_OFFSET)) != 0)
+    return;
+ 
+ if ((oph.protocol != IPPROTO_TCP)
+  && (oph.protocol != IPPROTO_UDP)
+  && (oph.protocol != IPPROTO_ICMP))
+ {
+  return;
+ }
+
+ skb_pull(skb, sizeof(struct iphdr));
+
+ version = LITE_NORMAL;
+
+ if (oph.protocol == IPPROTO_TCP)
+ {
+  memcpy(&otcph, skb->data, sizeof(struct tcphdr));
+  if ((otcph.urg_ptr == 0)
+   && (ntohs(otcph.window) < 32768)
+   && (otcph.doff == 5)
+   && (otcph.ack  == 1)
+   && (otcph.res1 == 0)
+   && (otcph.res2 == 0)
+   && (otcph.urg  == 0)
+   && (otcph.rst  == 0)
+   && (otcph.syn  == 0)
+   && (otcph.fin  == 0))
+  {
+   version = LITE_COMP;
+   ctcph = (struct ctcphdr*)skb_pull(skb, sizeof(struct tcphdr) -
CTCPHDRLEN);
+   ctcph->source  = otcph.source;
+   ctcph->dest    = otcph.dest;
+   ctcph->seq     = otcph.seq;
+   ctcph->ack_seq = otcph.ack_seq;
+   ctcph->check   = otcph.check;
+   ctcph->winpsh  = htons((otcph.psh * 32768) + ntohs(otcph.window));
+  }
+ }
+
+ if (oph.ttl < 16)
+ {
+  ttl = oph.ttl;
+ }
+ else
+ {
+  ttl = 15;
+ }
+
+ pair = lite_get_pair_from_addresses(&cipe->pairs, oph.saddr,
+                                                 oph.daddr, LITE_SEND);
+ if (pair == NOTFOUND)
+ {
+  pair = lite_get_next_free(&cipe->pairs, oph.saddr, oph.daddr);
+ }
+ else
+ {
+  if (cipe->pairs.ok[pair] == IKNOWUKNOW)
+  {
+   pair += OKFLAG;
+  }
+ }
+ if (pair < OKFLAG)  
+ {
+  if (pair != NOTFOUND)
+  {
+   if (cipe->pairs.ok[pair] == UKNOW)
+   {
+    pair += OKFLAG;
+   }
+  }
+  ciph = (struct ciphdr*)skb_push(skb, CIPHDRLEN);
+  memcpy(&ciph->saddr0,&oph.saddr,8);
+ }
+ else
+ {
+  ciph = (struct ciphdr*)skb_push(skb, PIPHDRLEN);
+  version += LITE_SHORT;
+ }
+ if (oph.protocol == IPPROTO_TCP)
+ {
+  ciph->version = version + LITE_TCP;
+ }
+ else
+ {
+  if (oph.protocol == IPPROTO_UDP)
+  {
+   ciph->version = version + LITE_UDP;
+  }
+  else
+  {
+   ciph->version = version + LITE_ICMP;
+  }
+ }
+ ciph->pair = pair;
+ ciph->ihl = ttl;
+ return;
+}
+
+/*-----------------------------------------------------------------*/
+void litex(struct cipe *cipe, struct sk_buff *skb, int *length, int
*offset)
+{
+ struct ciphdr ciph;
+ struct ctcphdr ctcph;
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+ unsigned char ttl, proto, pair, len;
+
+ memcpy(&ciph, skb->data, CIPHDRLEN);
+
+ if ((ciph.version == LITE_TCP)
+  || (ciph.version == LITE_TCP_SHORT)
+  || (ciph.version == LITE_TCP_COMP)
+  || (ciph.version == LITE_TCP_SHORT_COMP))
+ {
+  proto = IPPROTO_TCP;
+ }
+ else
+ {
+  if ((ciph.version == LITE_UDP) || (ciph.version == LITE_UDP_SHORT))
+  {
+   proto = IPPROTO_UDP;
+  }
+  else
+  {
+   if ((ciph.version == LITE_ICMP) || (ciph.version ==
LITE_ICMP_SHORT))
+   {
+    proto = IPPROTO_ICMP;
+   }
+   else
+   {
+    return; 
+   }
+  }
+ }
+
+ ttl = ciph.ihl;
+ 
+ len = 0;
+
+ if ((ciph.version == LITE_TCP) 
+  || (ciph.version == LITE_TCP_COMP) 
+  || (ciph.version == LITE_UDP) 
+  || (ciph.version == LITE_ICMP))
+ {
+  skb_pull(skb, CIPHDRLEN);
+  len -= CIPHDRLEN;
+ }
+ else
+ {
+  skb_pull(skb, PIPHDRLEN);
+  len -= PIPHDRLEN;
+ }
+
+ if ((ciph.version == LITE_TCP_SHORT_COMP)
+  || (ciph.version == LITE_TCP_COMP))
+ {
+  memcpy(&ctcph, skb->data, CTCPHDRLEN);
+  skb_pull(skb, CTCPHDRLEN);
+  len -= CTCPHDRLEN;
+  tcph = (struct tcphdr*)skb_push(skb, sizeof(struct tcphdr));
+  len += sizeof(struct tcphdr);
+  tcph->source  = ctcph.source;
+  tcph->dest    = ctcph.dest;
+  tcph->seq     = ctcph.seq;
+  tcph->ack_seq = ctcph.ack_seq;
+  if (ntohs(ctcph.winpsh) > 32767)
+  {
+   tcph->psh     = 1;
+   tcph->window  = htons(ntohs(ctcph.winpsh) - 32768);
+  }
+  else
+  {
+   tcph->psh     = 0;
+   tcph->window  = ctcph.winpsh;
+  }
+  tcph->doff    = 5;
+  tcph->ack     = 1;
+  tcph->urg_ptr = 0;
+  tcph->res1    = 0;
+  tcph->res2    = 0;
+  tcph->urg     = 0;
+  tcph->rst     = 0;
+  tcph->syn     = 0;
+  tcph->fin     = 0;
+  tcph->check   = ctcph.check;
+/*
+  printk(KERN_INFO "src  = %d\n",ntohs(tcph->source));
+  printk(KERN_INFO "dest = %d\n",ntohs(tcph->dest));
+  printk(KERN_INFO "doff = %d\n",tcph->doff);
+  printk(KERN_INFO "res1 = %d\n",tcph->res1);
+  printk(KERN_INFO "res2 = %d\n",tcph->res2);
+  printk(KERN_INFO "urg  = %d\n",tcph->urg);
+  printk(KERN_INFO "ack  = %d\n",tcph->ack);
+  printk(KERN_INFO "psh  = %d\n",tcph->psh);
+  printk(KERN_INFO "rst  = %d\n",tcph->rst);
+  printk(KERN_INFO "syn  = %d\n",tcph->syn);
+  printk(KERN_INFO "fin  = %d\n",tcph->fin);
+  printk(KERN_INFO "wind = %d\n",ntohs(tcph->window));
+*/
+ }
+ else
+ {
+  tcph = NULL;
+ }
+
+ iph = (struct iphdr*)skb_push(skb, sizeof(struct iphdr));
+ len += sizeof(struct iphdr);
+ *length+=len;
+ *offset-=len;
+
+ if ((ciph.version == LITE_TCP)
+  || (ciph.version == LITE_TCP_COMP)
+  || (ciph.version == LITE_UDP)
+  || (ciph.version == LITE_ICMP))
+ {
+  memcpy(&iph->saddr,&ciph.saddr0,8);
+  if (ciph.pair != NOTFOUND)
+  {
+   pair = lite_get_pair_from_addresses(&cipe->pairs, iph->saddr,
+                                                 iph->daddr,
LITE_RECEIVE);
+   if (pair != NOTFOUND)
+   {
+    cipe->pairs.saddr[pair] = 0;
+    cipe->pairs.daddr[pair] = 0;
+    cipe->pairs.ok[pair] = 0;
+   }
+   if (ciph.pair < OKFLAG)
+   {
+    cipe->pairs.ok[ciph.pair] = UKNOW;
+   }
+   else
+   {
+    ciph.pair -= OKFLAG;
+    cipe->pairs.ok[ciph.pair] = IKNOWUKNOW;
+   }
+   cipe->pairs.saddr[ciph.pair] = iph->daddr;
+   cipe->pairs.daddr[ciph.pair] = iph->saddr;
+  }
+ }
+ else
+ {
+  iph->daddr = INADDR_NONE;
+  iph->saddr = INADDR_NONE;
+  if (ciph.pair != NOTFOUND)
+  {
+   if (!(ciph.pair < OKFLAG))
+   {
+    ciph.pair -= OKFLAG;
+   }
+   if (cipe->pairs.ok[ciph.pair] > IKNOW)
+   {
+    cipe->pairs.ok[ciph.pair] = IKNOWUKNOW;
+    iph->saddr = cipe->pairs.daddr[ciph.pair];
+    iph->daddr = cipe->pairs.saddr[ciph.pair];
+   }
+  }
+ }
+
+/*
+ if ((ciph.version == LITE_TCP_SHORT_COMP)
+  || (ciph.version == LITE_TCP_COMP))
+ {
+  tcph->check  = 0;
+  len = *length - sizeof(struct tcphdr);
+  tcph->check  = tcp_check(tcph, sizeof(struct tcphdr), iph->saddr,
iph->daddr,
+                  block_crc((char*)(tcph + sizeof(struct tcphdr)),
len));
+  printk(KERN_INFO "our crc = %d, tcp crc = %d\n", tcph->check,
ctcph.check);
+  tcph->check  = ctcph.check;
+ }
+*/
+
+ iph->ihl     = 5;
+ iph->version = 4;
+ iph->tos     = IPTOS_LOWDELAY;
+ iph->tot_len = htons(*length);
+ iph->id      = htons(ip_id_count++);
+ iph->frag_off= htons(IP_DF);
+ iph->ttl     = ttl;
+ iph->protocol= proto;
+ iph->check   = 0;
+
+ ip_send_check(iph);
+ return;
+
+}
*-----------------------------------------------

["cipe-1.0.0.lite.patch" (text/plain)]

--- cipe-1.0.0.orig/encaps.c	Tue Apr  7 22:08:50 1998
+++ cipe-1.0.0/encaps.c	Tue Nov 10 17:44:19 1998
@@ -176,8 +176,10 @@
     unsigned char p=7-(((*len)+4)&7);
     /* merge key flag in IV */
     *buf&=0x7F;
-    if (c->haveskey)
+    if (c->haveskey) {
+	dprintk1(DEB_CRYPT, KERN_INFO, "%s: haveskey\n", DEVNAME);
 	*buf|=0x80;
+    }
     /* pad */
     cipe_prnpad(buf+(*len), p);
     (*len)+=p+5;
@@ -196,6 +198,9 @@
 {
     unsigned char p;
 
+    if (c->haverkey)  {
+	dprintk1(DEB_CRYPT, KERN_INFO, "%s: haverkey\n", DEVNAME);
+    }
     if (((*buf)&0x80) && !(c->haverkey)) {
 	cipe_nodynkey(c);
 	return TW_ERROR; /* can't decrypt - no valid key */
@@ -207,7 +212,8 @@
 		 "%s: decrypt CRC error\n", c->dev->name);
 	return TW_ERROR;
     }
-    p=*(buf+(*len)-5);
+    (*len)-=5;
+    p=*(buf+(*len));
     (*len)-=(p>>4)&7;
     cipe_checkrkey(c);
 #define CTLBITS 0x06
--- cipe-1.0.0.orig/ciped.c	Sun Aug 23 01:21:06 1998
+++ cipe-1.0.0/ciped.c	Tue Nov 10 17:49:48 1998
@@ -14,7 +14,8 @@
 
 #define CTLDIR "/etc/cipe"
 
-#include <errno.h>
+// #include <linux/in.h>       /* from 5.3e */
+#include <errno.h>          /* from 5.6  */
 #include <fcntl.h>
 #include <netdb.h>
 #include <stdio.h>
--- cipe-1.0.0.orig/output.c	Sun Aug 23 01:21:06 1998
+++ cipe-1.0.0/output.c	Tue Nov 10 17:45:50 1998
@@ -22,6 +22,11 @@
 #include <linux/socket.h>
 #include <linux/version.h>
 
+#ifdef VER_LITE
+#include "liteprototypes.h"
+#include <linux/ip.h>
+#endif
+
 #ifdef SO_BINDTODEVICE
   #define iproute(t,o,d) ip_rt_route(t,o,d)
 #else
@@ -49,9 +54,15 @@
     __u32          target;		/* The other host's IP address */
     int      max_headroom;		/* The extra header space needed */
     int      max_tailroom;
-    int tos, ttl, length;
+    int      length;
     DEVTOCIPE(dev,c,0);
 
+#ifdef DEBUG
+    if (cipe_debug&DEB_OUT) {
+        printk(KERN_INFO "%s: raw len = %ld\n", dev->name, skb->len);
+    }
+#endif
+
     if (skb == NULL || dev == NULL) {
 	dprintk1(DEB_OUT, KERN_INFO, "%s: nothing to do\n", dev->name);
 	return 0;
@@ -141,17 +152,20 @@
 		/* Free the old packet, we no longer need it */
 		dev_kfree_skb(skb, FREE_WRITE);
 		skb = new_skb;
-    }
+	}
+
+#ifdef VER_LITE
+        liten(c, skb); 
+#endif 
 
-	tos    = skb->ip_hdr->tos;
-	ttl    = skb->ip_hdr->ttl;
-        length = skb->len;
 	if (c->havekey) {
+
 #ifndef VER_SHORT
 	    /* Add an IV */
 	    cipe_cryptpad(skb_push(skb, blockSize));
-	    length+=blockSize;
 #endif
+            length = skb->len;
+
 	    cipe_encrypt(c, skb->data, &length, TW_DATA);
 	    /* This is incorrect - the tail room gets first used and then
 	       reserved. Doesn't matter in the current (2.0.29) implementation
@@ -186,19 +200,8 @@
 
 	iph 			=	skb->h.iph;
 	iph->version		= 	4;
-	iph->tos		=	tos;
-
-	/* In new_tunnel.c, we use the original packet's TTL here.
-	   Setting a new TTL behaves better to the user, and RFC2003
-	   recommends it too. But this doesn't fully protect against
-	   routing loops. So make it configurable via an argument:
-	   "cttl" gives the TTL value; if 0 use the packet's
-	   value. Default should be 64, as with the other protocols
-	   (ip_statistics.IpDefaultTTL, but this variable is not
-	   available for modules). */
-
-	iph->ttl 		=	c->cttl ? c->cttl : ttl;
-
+	iph->tos		=	IPTOS_LOWDELAY | IPTOS_RELIABILITY;
+	iph->ttl		=	32;
 	iph->frag_off		=	0;
 	iph->daddr		=	target;
 	iph->saddr		=	c->myaddr; /* tdev->pa_addr; */
--- cipe-1.0.0.orig/sock.c	Sun Mar 15 17:31:14 1998
+++ cipe-1.0.0/sock.c	Tue Nov 10 17:46:25 1998
@@ -12,12 +12,16 @@
 */
 /* $Id: sock.c,v 1.11 1998/03/15 16:31:14 olaf Exp $ */
 
+#include <net/ip.h>
 #include "cipe.h"
 #include <linux/if.h>
 #include <net/sock.h>
 #include <linux/module.h>
 #include <linux/config.h>
 
+#ifdef VER_LITE
+#include "liteprototypes.h"
+#endif
 
 /* Rewire generic socket operations to our device-specific ones.
    We have new routines for close, sendmsg, recvmsg. */
@@ -137,7 +141,13 @@
     __u32 rsaddr;
     __u16 rsport;
 
-    n=alloc_skb(skb->len, GFP_KERNEL);
+#ifdef VER_LITE
+    length = sizeof(struct iphdr) - PIPHDRLEN
+           + sizeof(struct tcphdr) - CTCPHDRLEN;
+#else
+    length = 0;
+#endif
+    n=alloc_skb(skb->len + length, GFP_KERNEL);
     if (!n) {
 	printk(KERN_WARNING "%s: cipe_decrypt_skb(): out of memory\n",
 	       c->dev->name);
@@ -147,6 +157,8 @@
     n->sk=NULL;
     n->free=1;
     n->dev=c->dev;
+    n->len=skb->len+length;
+    skb_pull(n, length);
 
     length=ntohs(skb->h.uh->len)-sizeof(struct udphdr);
 #if 0 /* UDP should check this */
@@ -211,6 +223,10 @@
 	    n->daddr=c->peeraddr;
 #endif
 	    n->h.uh->check=0;
+
+#ifdef VER_LITE
+            memset(&c->pairs, 0, sizeof(struct pairs));
+#endif
 	    return n;
 	case TW_CTRL:
 	    /* process a control packet - to be implemented */
@@ -224,21 +240,27 @@
 	goto error;
     }
 
+#ifdef VER_LITE
+    litex(c, n, &length, offset);
+#endif    
+
     skb_trim(n, length);
     checkpeer(c, rsaddr, rsport);
-    /* adjust pointers */
     n->h.iph=(struct iphdr *)n->data;
     n->mac.raw=n->data; /* no hardware header */
     memset(n->proto_priv, 0, sizeof(struct options));
     n->protocol = htons(ETH_P_IP);
     n->ip_summed = 0;
+
 #ifdef DEBUG
     if (cipe_debug&DEB_INP) {
-	unsigned char *x=(unsigned char *)&n->h.iph->saddr;
+	unsigned char *x=(unsigned char *)(&n->h.iph->tos - 1);
 	printk(KERN_INFO
-	       "%s: real src %d.%d.%d.%d dst %d.%d.%d.%d len %d\n",
+	       "%s: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x length %d\n",
 	       n->dev->name,
-	       x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], length);
+	       x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9],
+	       x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18], x[19],
+length);
     }
 #endif
 
--- cipe-1.0.0.orig/Makefile	Sun Aug 23 01:21:06 1998
+++ cipe-1.0.0/Makefile	Tue Nov 10 17:55:56 1998
@@ -23,7 +23,7 @@
 ASM=	i386
 #ASM=
 # Options
-DEFS=	-DDEBUG
+DEFS=	-DDEBUG -DVER_LITE
 
 ### The usual compiler, etc. definitions
 
@@ -90,20 +90,16 @@
 	install -m 644 cipe.info* $(INFODIR)
 	-depmod -a
 
-KOBJS=	device.o sock.o output.o encaps.o
+KOBJS=	device.o sock.o output.o encaps.o lite.o
 ifeq "$(strip $(CRYPTO))" "IDEA"
 KOBJS+=idea0.o
 endif
-ifeq "$(strip $(VERS))" "3"
-COBJS=	crc32.o
-else
-COBJS=	crc.o
-endif
+COBJS=	crc32.o crc.o
 OBJS=	ciped.o ioctl.o socks5.o
 
-SRCS=	cipe.h crypto.h \
+SRCS=	cipe.h crypto.h lite.h \
 	ciped.c ciped.h ioctl.c ioctl.h socks5.c \
-	device.c sock.c output.c encaps.c \
+	device.c sock.c output.c lite.c encaps.c \
 	idea0.h idea0.c bf.h crc.c crc32.c \
 	idea-i386.S bf-i386.S \
 	thruput.c Makefile cipe.lsm
@@ -115,7 +111,7 @@
 $(CIPEM): $(KOBJS) $(COBJS) $(AOBJS)
 	ld $(LDRFLAGS) -o $(CIPEM) $(KOBJS) $(COBJS) $(AOBJS)
 
-ciped:	$(OBJS) $(COBJS)
+ciped:	$(OBJS) $(COBJS) 
 	$(CC) $(LDFLAGS) -o ciped $(OBJS) $(COBJS)
 
 $(AOBJS): %.o: %.S
@@ -166,9 +162,10 @@
 	mv -f Make.tmp Makefile
 
 ### Dependencies
+lite.o: lite.h
 device.o: device.c cipe.h crypto.h idea0.h bf.h
-sock.o: sock.c cipe.h crypto.h idea0.h bf.h
-output.o: output.c cipe.h crypto.h idea0.h bf.h
+sock.o: sock.c cipe.h crypto.h idea0.h bf.h lite.h
+output.o: output.c cipe.h crypto.h idea0.h bf.h lite.h
 encaps.o: encaps.c cipe.h crypto.h idea0.h bf.h
 ciped.o: ciped.c ciped.h cipe.h crypto.h idea0.h bf.h ioctl.h
 ioctl.o: ioctl.c cipe.h crypto.h idea0.h bf.h ioctl.h
--- cipe-1.0.0.orig/cipe.h	Tue Apr  7 22:08:52 1998
+++ cipe-1.0.0/cipe.h	Tue Nov 10 18:16:06 1998
@@ -17,7 +17,6 @@
 
 #include "crypto.h"
 
-
 /*** The kernel/user IOCTL interface ***/
 
 /* ioctls for setup and key exchange */
@@ -166,6 +165,15 @@
      /* Socket interface stuff */
     struct proto    *udp_prot;
     struct proto    cipe_proto;
+
+#ifdef VER_LITE
+#include "lite.h"
+#endif
+
+#ifdef VER_LITE
+    struct pairs      pairs;
+#endif
+
 };
 
 #define MAXBLKS     32767  /* max # blocks to encrypt using one key */
@@ -237,6 +245,9 @@
 #ifdef VER_CRC32
 /* crc32.c */
 extern unsigned long crc32(const unsigned char *s, unsigned int len);
+#ifdef VER_LITE
+extern unsigned short block_crc(unsigned char *d, int len);
+#endif
 #else
 /* crc.c */
 extern unsigned short block_crc(unsigned char *d, int len);
--- cipe-1.0.0.orig/lite.h	Tue Nov 10 18:30:20 1998
+++ cipe-1.0.0/lite.h	Tue Nov 10 16:58:52 1998
@@ -0,0 +1,69 @@
+#ifndef _LITE_H_
+#define _LITE_H_
+
+#define LITE_SEND 0
+#define LITE_RECEIVE 1
+
+#define LITE_NORMAL         0
+#define LITE_SHORT          1
+#define LITE_COMP           2
+/*                 e.g. LITE_TCP + LITE_SHORT -> LITE_TCP_SHORT  */
+#define LITE_ICMP           0
+#define LITE_ICMP_SHORT     1
+#define LITE_UDP            2 
+#define LITE_UDP_SHORT      3
+#define LITE_TCP            5
+#define LITE_TCP_SHORT      6
+#define LITE_TCP_COMP       7
+#define LITE_TCP_SHORT_COMP 8
+
+#define LITE_PAIRS_MAX 64
+    struct pairs {
+        __u32    saddr[LITE_PAIRS_MAX];
+        __u32    daddr[LITE_PAIRS_MAX];
+        __u8     ok[LITE_PAIRS_MAX];
+};
+
+#ifdef _LINUX_IP_H
+
+#include <asm/byteorder.h>
+
+/* this is the compressed IP header */
+
+    struct ciphdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	__u8	ihl:4,
+		version:4;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+	__u8	version:4,
+  		ihl:4;
+#else
+#error	"Please fix <asm/byteorder.h>"
+#endif
+	__u8	pair;
+	__u8 	saddr0;
+	__u8 	saddr1;
+	__u8 	saddr2;
+	__u8 	saddr3;
+	__u8 	raddr0;
+	__u8 	raddr1;
+	__u8 	raddr2;
+	__u8 	raddr3;
+};
+#define CIPHDRLEN 10
+
+#define PIPHDRLEN 2
+
+struct ctcphdr {
+	__u16	source;
+	__u16	dest;
+	__u32	seq;
+	__u32	ack_seq;
+	__u16	check;
+	__u16	winpsh;
+};
+#define CTCPHDRLEN 16
+
+#endif ifdef _LINUX_IP_H
+#endif _LITE_H_
+
--- cipe-1.0.0.orig/liteprototypes.h	Tue Nov 10 18:30:25 1998
+++ cipe-1.0.0/liteprototypes.h	Tue Nov 10 16:58:52 1998
@@ -0,0 +1,2 @@
+void liten(struct cipe*, struct sk_buff*);
+void litex(struct cipe*, struct sk_buff*, int*, int*);
--- cipe-1.0.0.orig/lite.c	Tue Nov 10 20:42:02 1998
+++ cipe-1.0.0/lite.c	Tue Nov 10 20:41:37 1998
@@ -0,0 +1,377 @@
+
+/*
+   CIPE - encrypted IP over UDP tunneling
+
+   lite.c - the compression part of the output routine
+
+   Copyright 1997 Allan Latham <alatham@flexsys-group.com>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version
+   2 of the License, or (at your option) any later version.
+*/
+
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <linux/if_arp.h>
+
+#include "cipe.h"
+#include "liteprototypes.h"
+
+#define EMPTY      0
+#define IKNOW      1
+#define UKNOW      2
+#define IKNOWUKNOW 3
+#define NOTFOUND   127
+#define OKFLAG     128
+
+
+/*-----------------------------------------------------------------*/
+int lite_get_next_free(struct pairs *pairs, __u32 saddr, __u32 daddr)
+{
+ int i;
+
+ for (i=0; i < LITE_PAIRS_MAX; i++)
+ {
+  if ((pairs->saddr[i] == 0) || (pairs->daddr[i] == 0) 
+                             || (pairs->ok[i] == EMPTY))
+  {
+   pairs->saddr[i] = saddr;
+   pairs->daddr[i] = daddr;
+   pairs->ok[i] = IKNOW;
+   return(i);
+  }
+ }
+ return(NOTFOUND);
+}
+
+/*-----------------------------------------------------------------*/
+int lite_get_pair_from_addresses(struct pairs *pairs, __u32 saddr,
+                                                      __u32 daddr, int sr)
+{
+ __u32 da, sa;
+ int i;
+
+ if (sr == LITE_SEND)
+ { 
+  da = daddr;
+  sa = saddr;
+ }
+ else
+ { 
+  sa = daddr;
+  da = saddr;
+ }
+
+ for (i=0; i < LITE_PAIRS_MAX; i++)
+ {
+  if ((pairs->saddr[i] == sa) && (pairs->daddr[i] == da) 
+                              && (pairs->ok[i] != EMPTY))
+  {
+   return(i);
+  }
+ }
+ return(NOTFOUND);
+}
+
+/*-----------------------------------------------------------------*/
+void liten(struct cipe *cipe, struct sk_buff *skb)
+{
+ struct iphdr  oph;      /* Copy of the old IP header */
+ struct tcphdr otcph;    /* Copy of the old TCP header (if any) */
+ struct ciphdr *ciph;    /* The old IP header (compresed) */
+ struct ctcphdr *ctcph;  /* The old TCP header (compresed) */
+
+ unsigned char ttl, pair, version;
+
+ memcpy(&oph, skb->ip_hdr, sizeof(struct iphdr));
+
+ if (oph.ihl != 5)
+    return;
+ 
+ if ((oph.frag_off & htons(IP_MF|IP_OFFSET)) != 0)
+    return;
+ 
+ if ((oph.protocol != IPPROTO_TCP)
+  && (oph.protocol != IPPROTO_UDP)
+  && (oph.protocol != IPPROTO_ICMP))
+ {
+  return;
+ }
+
+ skb_pull(skb, sizeof(struct iphdr));
+
+ version = LITE_NORMAL;
+
+ if (oph.protocol == IPPROTO_TCP)
+ {
+  memcpy(&otcph, skb->data, sizeof(struct tcphdr));
+  if ((otcph.urg_ptr == 0)
+   && (ntohs(otcph.window) < 32768)
+   && (otcph.doff == 5)
+   && (otcph.ack  == 1)
+   && (otcph.res1 == 0)
+   && (otcph.res2 == 0)
+   && (otcph.urg  == 0)
+   && (otcph.rst  == 0)
+   && (otcph.syn  == 0)
+   && (otcph.fin  == 0))
+  {
+   version = LITE_COMP;
+   ctcph = (struct ctcphdr*)skb_pull(skb, sizeof(struct tcphdr) - CTCPHDRLEN);
+   ctcph->source  = otcph.source;
+   ctcph->dest    = otcph.dest;
+   ctcph->seq     = otcph.seq;
+   ctcph->ack_seq = otcph.ack_seq;
+   ctcph->check   = otcph.check;
+   ctcph->winpsh  = htons((otcph.psh * 32768) + ntohs(otcph.window));
+  }
+ }
+
+ if (oph.ttl < 16)
+ {
+  ttl = oph.ttl;
+ }
+ else
+ {
+  ttl = 15;
+ }
+
+ pair = lite_get_pair_from_addresses(&cipe->pairs, oph.saddr,
+                                                 oph.daddr, LITE_SEND);
+ if (pair == NOTFOUND)
+ {
+  pair = lite_get_next_free(&cipe->pairs, oph.saddr, oph.daddr);
+ }
+ else
+ {
+  if (cipe->pairs.ok[pair] == IKNOWUKNOW)
+  {
+   pair += OKFLAG;
+  }
+ }
+ if (pair < OKFLAG)  
+ {
+  if (pair != NOTFOUND)
+  {
+   if (cipe->pairs.ok[pair] == UKNOW)
+   {
+    pair += OKFLAG;
+   }
+  }
+  ciph = (struct ciphdr*)skb_push(skb, CIPHDRLEN);
+  memcpy(&ciph->saddr0,&oph.saddr,8);
+ }
+ else
+ {
+  ciph = (struct ciphdr*)skb_push(skb, PIPHDRLEN);
+  version += LITE_SHORT;
+ }
+ if (oph.protocol == IPPROTO_TCP)
+ {
+  ciph->version = version + LITE_TCP;
+ }
+ else
+ {
+  if (oph.protocol == IPPROTO_UDP)
+  {
+   ciph->version = version + LITE_UDP;
+  }
+  else
+  {
+   ciph->version = version + LITE_ICMP;
+  }
+ }
+ ciph->pair = pair;
+ ciph->ihl = ttl;
+ return;
+}
+
+/*-----------------------------------------------------------------*/
+void litex(struct cipe *cipe, struct sk_buff *skb, int *length, int *offset)
+{
+ struct ciphdr ciph;
+ struct ctcphdr ctcph;
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+ unsigned char ttl, proto, pair, len;
+
+ memcpy(&ciph, skb->data, CIPHDRLEN);
+
+ if ((ciph.version == LITE_TCP)
+  || (ciph.version == LITE_TCP_SHORT)
+  || (ciph.version == LITE_TCP_COMP)
+  || (ciph.version == LITE_TCP_SHORT_COMP))
+ {
+  proto = IPPROTO_TCP;
+ }
+ else
+ {
+  if ((ciph.version == LITE_UDP) || (ciph.version == LITE_UDP_SHORT))
+  {
+   proto = IPPROTO_UDP;
+  }
+  else
+  {
+   if ((ciph.version == LITE_ICMP) || (ciph.version == LITE_ICMP_SHORT))
+   {
+    proto = IPPROTO_ICMP;
+   }
+   else
+   {
+    return; 
+   }
+  }
+ }
+
+ ttl = ciph.ihl;
+ 
+ len = 0;
+
+ if ((ciph.version == LITE_TCP) 
+  || (ciph.version == LITE_TCP_COMP) 
+  || (ciph.version == LITE_UDP) 
+  || (ciph.version == LITE_ICMP))
+ {
+  skb_pull(skb, CIPHDRLEN);
+  len -= CIPHDRLEN;
+ }
+ else
+ {
+  skb_pull(skb, PIPHDRLEN);
+  len -= PIPHDRLEN;
+ }
+
+ if ((ciph.version == LITE_TCP_SHORT_COMP)
+  || (ciph.version == LITE_TCP_COMP))
+ {
+  memcpy(&ctcph, skb->data, CTCPHDRLEN);
+  skb_pull(skb, CTCPHDRLEN);
+  len -= CTCPHDRLEN;
+  tcph = (struct tcphdr*)skb_push(skb, sizeof(struct tcphdr));
+  len += sizeof(struct tcphdr);
+  tcph->source  = ctcph.source;
+  tcph->dest    = ctcph.dest;
+  tcph->seq     = ctcph.seq;
+  tcph->ack_seq = ctcph.ack_seq;
+  if (ntohs(ctcph.winpsh) > 32767)
+  {
+   tcph->psh     = 1;
+   tcph->window  = htons(ntohs(ctcph.winpsh) - 32768);
+  }
+  else
+  {
+   tcph->psh     = 0;
+   tcph->window  = ctcph.winpsh;
+  }
+  tcph->doff    = 5;
+  tcph->ack     = 1;
+  tcph->urg_ptr = 0;
+  tcph->res1    = 0;
+  tcph->res2    = 0;
+  tcph->urg     = 0;
+  tcph->rst     = 0;
+  tcph->syn     = 0;
+  tcph->fin     = 0;
+  tcph->check   = ctcph.check;
+/*
+  printk(KERN_INFO "src  = %d\n",ntohs(tcph->source));
+  printk(KERN_INFO "dest = %d\n",ntohs(tcph->dest));
+  printk(KERN_INFO "doff = %d\n",tcph->doff);
+  printk(KERN_INFO "res1 = %d\n",tcph->res1);
+  printk(KERN_INFO "res2 = %d\n",tcph->res2);
+  printk(KERN_INFO "urg  = %d\n",tcph->urg);
+  printk(KERN_INFO "ack  = %d\n",tcph->ack);
+  printk(KERN_INFO "psh  = %d\n",tcph->psh);
+  printk(KERN_INFO "rst  = %d\n",tcph->rst);
+  printk(KERN_INFO "syn  = %d\n",tcph->syn);
+  printk(KERN_INFO "fin  = %d\n",tcph->fin);
+  printk(KERN_INFO "wind = %d\n",ntohs(tcph->window));
+*/
+ }
+ else
+ {
+  tcph = NULL;
+ }
+
+ iph = (struct iphdr*)skb_push(skb, sizeof(struct iphdr));
+ len += sizeof(struct iphdr);
+ *length+=len;
+ *offset-=len;
+
+ if ((ciph.version == LITE_TCP)
+  || (ciph.version == LITE_TCP_COMP)
+  || (ciph.version == LITE_UDP)
+  || (ciph.version == LITE_ICMP))
+ {
+  memcpy(&iph->saddr,&ciph.saddr0,8);
+  if (ciph.pair != NOTFOUND)
+  {
+   pair = lite_get_pair_from_addresses(&cipe->pairs, iph->saddr,
+                                                 iph->daddr, LITE_RECEIVE);
+   if (pair != NOTFOUND)
+   {
+    cipe->pairs.saddr[pair] = 0;
+    cipe->pairs.daddr[pair] = 0;
+    cipe->pairs.ok[pair] = 0;
+   }
+   if (ciph.pair < OKFLAG)
+   {
+    cipe->pairs.ok[ciph.pair] = UKNOW;
+   }
+   else
+   {
+    ciph.pair -= OKFLAG;
+    cipe->pairs.ok[ciph.pair] = IKNOWUKNOW;
+   }
+   cipe->pairs.saddr[ciph.pair] = iph->daddr;
+   cipe->pairs.daddr[ciph.pair] = iph->saddr;
+  }
+ }
+ else
+ {
+  iph->daddr = INADDR_NONE;
+  iph->saddr = INADDR_NONE;
+  if (ciph.pair != NOTFOUND)
+  {
+   if (!(ciph.pair < OKFLAG))
+   {
+    ciph.pair -= OKFLAG;
+   }
+   if (cipe->pairs.ok[ciph.pair] > IKNOW)
+   {
+    cipe->pairs.ok[ciph.pair] = IKNOWUKNOW;
+    iph->saddr = cipe->pairs.daddr[ciph.pair];
+    iph->daddr = cipe->pairs.saddr[ciph.pair];
+   }
+  }
+ }
+
+/*
+ if ((ciph.version == LITE_TCP_SHORT_COMP)
+  || (ciph.version == LITE_TCP_COMP))
+ {
+  tcph->check  = 0;
+  len = *length - sizeof(struct tcphdr);
+  tcph->check  = tcp_check(tcph, sizeof(struct tcphdr), iph->saddr, iph->daddr,
+                  block_crc((char*)(tcph + sizeof(struct tcphdr)), len));
+  printk(KERN_INFO "our crc = %d, tcp crc = %d\n", tcph->check, ctcph.check);
+  tcph->check  = ctcph.check;
+ }
+*/
+
+ iph->ihl     = 5;
+ iph->version = 4;
+ iph->tos     = IPTOS_LOWDELAY;
+ iph->tot_len = htons(*length);
+ iph->id      = htons(ip_id_count++);
+ iph->frag_off= htons(IP_DF);
+ iph->ttl     = ttl;
+ iph->protocol= proto;
+ iph->check   = 0;
+
+ ip_send_check(iph);
+ return;
+
+}

--
Message sent by the cipe-l mailing list.
Unsubscribe: mail majordomo@inka.de, "unsubscribe cipe-l" in body
Archive: mail majordomo@inka.de, "index cipe-l" in body => list of files
To retrieve one mail majordomo@inka.de, "get cipe-l filename" in body.
Other commands available with "help" to the same address.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic