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>