Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 May 1999 18:12:55 +0200 (CEST)
From:      kuebart@mathematik.uni-ulm.de
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   misc/11767: sppp does not implement VJ compression
Message-ID:  <199905181612.SAA00788@yacht.domestic.de>

next in thread | raw e-mail | index | archive | help

>Number:         11767
>Category:       misc
>Synopsis:       sppp does not implement VJ compression
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 18 13:20:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Joachim Kuebart
>Release:        FreeBSD 4.0-CURRENT i386
>Organization:
>Environment:

	FreeBSD-current as of May 13, 1999.

	The patch supplied was tested using i4bisppp(4) over an ISDN
	line.  This code uses the generic sppp(4) driver.

>Description:

	VJ header compression is not implemented in sppp(4).

>How-To-Repeat:

	Connect to any modern ISDN router using a network device
	built upon sppp(4) (e.g. i4bisppp(4)).  The IPCP option
	COMPRESSION is being rejected.

>Fix:
	

Note that the patch below modifies the ioctl's used e.g. by
spppcontrol(8), so you need to recompile this tool, too.  Also,
slcompress.h and along with that some other header files need to
be #include'd by spppcontrol.c and /sys/net/i4b_isppp.c.

cvs diff: Diffing /usr/src/sbin/spppcontrol
Index: /usr/src/sbin/spppcontrol/spppcontrol.c
===================================================================
RCS file: /usr/CVS-Repository/src/sbin/spppcontrol/spppcontrol.c,v
retrieving revision 1.6
diff -u -r1.6 spppcontrol.c
--- spppcontrol.c	1999/02/28 22:19:47	1.6
+++ spppcontrol.c	1999/05/16 23:56:01
@@ -32,10 +32,15 @@
 #include <sys/param.h>
 #include <sys/callout.h>
 #include <sys/ioctl.h>
+#include <sys/mbuf.h>
 #include <sys/socket.h>
 
 #include <net/if.h>
 #include <net/if_var.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <net/slcompress.h>
 #include <net/if_sppp.h>
 
 #include <err.h>
cvs diff: Diffing /sys/i4b/driver
Index: /sys/i4b/driver/i4b_isppp.c
===================================================================
RCS file: /usr/CVS-Repository/src/sys/i4b/driver/i4b_isppp.c,v
retrieving revision 1.2
diff -u -r1.2 i4b_isppp.c
--- i4b_isppp.c	1999/03/07 16:08:13	1.2
+++ i4b_isppp.c	1999/05/16 23:42:16
@@ -63,6 +63,10 @@
 #include <net/if_types.h>
 #include <net/netisr.h>
 #include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <net/slcompress.h>
 #ifdef __FreeBSD__
 #include <net/if_sppp.h>
 #else
cvs diff: Diffing /sys/net
Index: /sys/net/if_sppp.h
===================================================================
RCS file: /usr/CVS-Repository/src/sys/net/if_sppp.h,v
retrieving revision 1.14
diff -u -r1.14 if_sppp.h
--- if_sppp.h	1999/03/30 13:28:26	1.14
+++ if_sppp.h	1999/05/17 15:47:35
@@ -46,6 +46,9 @@
 #define IPCP_HISADDR_SEEN 1	/* have seen his address already */
 #define IPCP_MYADDR_DYN   2	/* my address is dynamically assigned */
 #define IPCP_MYADDR_SEEN  4	/* have seen his address already */
+#define IPCP_VJ		  8	/* We can use VJ compression */
+	int	max_state;	/* Max-Slot-Id */
+	int	compress_cid;	/* Comp-Slot-Id */
 };
 
 #define AUTHNAMELEN	32
@@ -100,6 +103,7 @@
 	struct sipcp ipcp;		/* IPCP params */
 	struct sauth myauth;		/* auth params, i'm peer */
 	struct sauth hisauth;		/* auth params, i'm authenticator */
+	struct slcompress pp_comp;	/* for VJ compession */
 	/*
 	 * These functions are filled in by sppp_attach(), and are
 	 * expected to be used by the lower layer (hardware) drivers
Index: /sys/net/if_spppsubr.c
===================================================================
RCS file: /usr/CVS-Repository/src/sys/net/if_spppsubr.c,v
retrieving revision 1.55
diff -u -r1.55 if_spppsubr.c
--- if_spppsubr.c	1999/03/30 13:28:26	1.55
+++ if_spppsubr.c	1999/05/18 15:43:23
@@ -22,6 +22,8 @@
 
 #include <sys/param.h>
 
+#define SPPP_VJ
+
 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
 #include "opt_inet.h"
 #include "opt_ipx.h"
@@ -55,6 +57,10 @@
 #include <net/netisr.h>
 #include <net/if_types.h>
 #include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <net/slcompress.h>
 
 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
 #include <machine/random.h>
@@ -142,6 +148,8 @@
 #define PPP_ISO		0x0023		/* ISO OSI Protocol */
 #define PPP_XNS		0x0025		/* Xerox NS Protocol */
 #define PPP_IPX		0x002b		/* Novell IPX Protocol */
+#define PPP_VJ_COMP	0x002d		/* VJ compressed TCP/IP */
+#define PPP_VJ_UCOMP	0x002f		/* VJ uncompressed TCP/IP */
 #define PPP_LCP		0xc021		/* Link Control Protocol */
 #define PPP_PAP		0xc023		/* Password Authentication Protocol */
 #define PPP_CHAP	0xc223		/* Challenge-Handshake Auth Protocol */
@@ -172,6 +180,8 @@
 #define IPCP_OPT_COMPRESSION	2	/* IP compression protocol (VJ) */
 #define IPCP_OPT_ADDRESS	3	/* local IP address */
 
+#define IPCP_COMP_VJ		0x2d	/* Code for VJ compression */
+
 #define PAP_REQ			1	/* PAP name/password request */
 #define PAP_ACK			2	/* PAP acknowledge */
 #define PAP_NAK			3	/* PAP fail */
@@ -516,7 +526,35 @@
 				inq = &ipintrq;
 			}
 			break;
+#ifdef SPPP_VJ
+		case PPP_VJ_COMP:
+			if (sp->state[IDX_IPCP] == STATE_OPENED) {
+				int len;
+
+				if ((len = sl_uncompress_tcp(
+				    (u_char **)&m->m_data, m->m_len,
+				    TYPE_COMPRESSED_TCP, &sp->pp_comp)) <= 0)
+					goto drop;
+				m->m_len = m->m_pkthdr.len = len;
+				schednetisr (NETISR_IP);
+				inq = &ipintrq;
+			}
+			break;
+		case PPP_VJ_UCOMP:
+			if (sp->state[IDX_IPCP] == STATE_OPENED) {
+				int len;
+
+				if ((len = sl_uncompress_tcp(
+				    (u_char **)&m->m_data, m->m_len,
+				    TYPE_UNCOMPRESSED_TCP, &sp->pp_comp)) <= 0)
+					goto drop;
+				m->m_len = m->m_pkthdr.len = len;
+				schednetisr (NETISR_IP);
+				inq = &ipintrq;
+			}
+			break;
 #endif
+#endif
 #ifdef IPX
 		case PPP_IPX:
 			/* IPX IPXCP not implemented yet */
@@ -626,6 +664,9 @@
 	struct ppp_header *h;
 	struct ifqueue *ifq;
 	int s, rv = 0;
+#ifdef SPPP_VJ
+	int ipproto = PPP_IP;
+#endif
 	int debug = ifp->if_flags & IFF_DEBUG;
 
 	s = splimp();
@@ -692,6 +733,30 @@
 			ifq = &sp->pp_fastq;
 		else if (INTERACTIVE (ntohs (tcp->th_dport)))
 			ifq = &sp->pp_fastq;
+
+#ifdef SPPP_VJ
+		/*
+		 * Do IP Header compression
+		 */
+		if (sp->pp_mode != IFF_CISCO && (sp->ipcp.flags & IPCP_VJ) &&
+		    ip->ip_p == IPPROTO_TCP)
+			switch (sl_compress_tcp(m, ip, &sp->pp_comp,
+						sp->ipcp.compress_cid)) {
+			case TYPE_COMPRESSED_TCP:
+				ipproto = PPP_VJ_COMP;
+				break;
+			case TYPE_UNCOMPRESSED_TCP:
+				ipproto = PPP_VJ_UCOMP;
+				break;
+			case TYPE_IP:
+				ipproto = PPP_IP;
+				break;
+			default:
+				m_freem(m);
+				splx(s);
+				return (EINVAL);
+			}
+#endif
 	}
 #endif
 
@@ -735,7 +800,11 @@
 			 * not ready to carry IP packets, and return
 			 * ENETDOWN, as opposed to ENOBUFS.
 			 */
+#ifdef SPPP_VJ
+			h->protocol = htons(ipproto);
+#else
 			h->protocol = htons(PPP_IP);
+#endif
 			if (sp->state[IDX_IPCP] != STATE_OPENED)
 				rv = ENETDOWN;
 		}
@@ -823,6 +892,10 @@
 	sp->pp_up = lcp.Up;
 	sp->pp_down = lcp.Down;
 
+#ifdef SPPP_VJ
+	sl_compress_init(&sp->pp_comp, -1);
+#endif
+
 	sppp_lcp_init(sp);
 	sppp_ipcp_init(sp);
 	sppp_pap_init(sp);
@@ -2516,7 +2589,8 @@
 	STDDCL;
 	u_long myaddr, hisaddr;
 
-	sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN|IPCP_MYADDR_SEEN|IPCP_MYADDR_DYN);
+	sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN | IPCP_MYADDR_SEEN |
+			    IPCP_MYADDR_DYN | IPCP_VJ);
 
 	sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0);
 	/*
@@ -2533,6 +2607,11 @@
 		return;
 	}
 
+#ifdef SPPP_VJ
+	sp->ipcp.opts |= (1 << IPCP_OPT_COMPRESSION);
+	sp->ipcp.max_state = MAX_STATES - 1;
+	sp->ipcp.compress_cid = 1;
+#endif
 	if (myaddr == 0L) {
 		/*
 		 * I don't have an assigned address, so i need to
@@ -2576,6 +2655,9 @@
 	int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
 	u_long hisaddr, desiredaddr;
 	int gotmyaddr = 0;
+#ifdef SPPP_VJ
+	int desiredcomp;
+#endif
 
 	len -= 4;
 	origlen = len;
@@ -2596,6 +2678,16 @@
 		if (debug)
 			addlog(" %s ", sppp_ipcp_opt_name(*p));
 		switch (*p) {
+#ifdef SPPP_VJ
+		case IPCP_OPT_COMPRESSION:
+			if (len >= 6 && p[1] == 6) {
+				/* correctly formed compression option */
+				continue;
+			}
+			if (debug)
+				addlog("[invalid] ");
+			break;
+#endif
 		case IPCP_OPT_ADDRESS:
 			if (len >= 6 && p[1] == 6) {
 				/* correctly formed address option */
@@ -2634,6 +2726,25 @@
 		if (debug)
 			addlog(" %s ", sppp_ipcp_opt_name(*p));
 		switch (*p) {
+#ifdef SPPP_VJ
+		case IPCP_OPT_COMPRESSION:
+			desiredcomp = p[2] << 8 | p[3];
+			/* We only support VJ */
+			if (desiredcomp == IPCP_COMP_VJ) {
+				if (debug)
+					addlog("VJ [ack] ");
+				sp->ipcp.flags |= IPCP_VJ;
+				sl_compress_init(&sp->pp_comp, p[4]);
+				sp->ipcp.max_state = p[4];
+				sp->ipcp.compress_cid = p[5];
+				continue;
+			}
+			if (debug)
+				addlog("%#04x [not supported] ", desiredcomp);
+			p[2] = IPCP_COMP_VJ >> 8;
+			p[3] = IPCP_COMP_VJ;
+			break;
+#endif
 		case IPCP_OPT_ADDRESS:
 			/* This is the address he wants in his end */
 			desiredaddr = p[2] << 24 | p[3] << 16 |
@@ -2744,6 +2855,11 @@
 		if (debug)
 			addlog(" %s ", sppp_ipcp_opt_name(*p));
 		switch (*p) {
+#ifdef SPPP_VJ
+		case IPCP_OPT_COMPRESSION:
+			sp->ipcp.opts &= ~(1 << IPCP_OPT_COMPRESSION);
+			break;
+#endif
 		case IPCP_OPT_ADDRESS:
 			/*
 			 * Peer doesn't grok address option.  This is
@@ -2770,6 +2886,9 @@
 	u_char *buf, *p;
 	struct ifnet *ifp = &sp->pp_if;
 	int debug = ifp->if_flags & IFF_DEBUG;
+#ifdef SPPP_VJ
+	int desiredcomp;
+#endif
 	u_long wantaddr;
 
 	len -= 4;
@@ -2786,6 +2905,24 @@
 		if (debug)
 			addlog(" %s ", sppp_ipcp_opt_name(*p));
 		switch (*p) {
+#ifdef SPPP_VJ
+		case IPCP_OPT_COMPRESSION:
+			if (len >= 6 && p[1] == 6) {
+				desiredcomp = p[2] << 8 | p[3];
+				if (debug)
+					addlog("[wantcomp %#04x] ",
+						desiredcomp);
+				if (desiredcomp == IPCP_COMP_VJ) {
+					sl_compress_init(&sp->pp_comp, p[4]);
+					sp->ipcp.max_state = p[4];
+					sp->ipcp.compress_cid = p[5];
+					addlog("[agree] ");
+				} else
+					sp->ipcp.opts &=
+						~(1 << IPCP_OPT_COMPRESSION);
+			}
+			break;
+#endif
 		case IPCP_OPT_ADDRESS:
 			/*
 			 * Peer doesn't like our local IP address.  See
@@ -2857,6 +2994,17 @@
 	char opt[6 /* compression */ + 6 /* address */];
 	u_long ouraddr;
 	int i = 0;
+
+#ifdef SPPP_VJ
+	if (sp->ipcp.opts & (1 << IPCP_OPT_COMPRESSION)) {
+		opt[i++] = IPCP_OPT_COMPRESSION;
+		opt[i++] = 6;
+		opt[i++] = IPCP_COMP_VJ >> 8;
+		opt[i++] = IPCP_COMP_VJ;
+		opt[i++] = sp->ipcp.max_state;
+		opt[i++] = sp->ipcp.compress_cid;
+	}
+#endif
 
 	if (sp->ipcp.opts & (1 << IPCP_OPT_ADDRESS)) {
 		sppp_get_ip_addrs(sp, &ouraddr, 0, 0);

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199905181612.SAA00788>