Changes for LZS compression

This commit is contained in:
hipp 1998-07-08 16:48:20 +00:00
parent f394b889e5
commit 0f1e018ffe
4 changed files with 262 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/*
/* -*- mode: c; c-basic-offset: 4 -*-
* ccp.c - PPP Compression Control Protocol.
*
* Copyright (c) 1994 The Australian National University.
@ -25,7 +25,7 @@
* OR MODIFICATIONS.
*/
char ccp_rcsid[] = "$Id: ccp.c,v 1.6 1998/03/25 13:13:35 hipp Exp $";
char ccp_rcsid[] = "$Id: ccp.c,v 1.7 1998/07/08 16:48:20 hipp Exp $";
#include <string.h>
#include <syslog.h>
@ -42,6 +42,8 @@ char ccp_rcsid[] = "$Id: ccp.c,v 1.6 1998/03/25 13:13:35 hipp Exp $";
#include "compressions.h"
#include <linux/isdn_lzscomp.h>
/*
* Protocol entry points from main code.
*/
@ -96,6 +98,15 @@ struct protent ccp_protent = {
NULL
};
/*
* Remember that CCP is negotiating the _decompression_ method the peer
* asking for configuration is willing to do. More exactly spoken, if
* peer A sends a Configure-Request to peer B this request enumerates
* the _decompression_ methods A is willing to use on _receiving_ data
* from B, aka in direction B->A. The RFC does not use clear enough words
* to make this unmisunderstandable IMHO.
*/
fsm ccp_fsm[NUM_PPP];
ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */
ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */
@ -140,7 +151,8 @@ static fsm_callbacks ccp_callbacks = {
* Do we want / did we get any compression?
*/
#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \
|| (opt).predictor_1 || (opt).predictor_2)
|| (opt).predictor_1 || (opt).predictor_2 \
|| (opt).lzs)
/*
* Local state (mainly for handling reset-reqs and reset-acks).
@ -183,6 +195,18 @@ static void ccp_init(int unit)
ccp_allowoptions[unit].bsd_compress = 1;
ccp_allowoptions[unit].bsd_bits = BSD_MAX_BITS;
ccp_allowoptions[unit].predictor_1 = 1;
/* Are these 0/unit mixups intended or just typos ? */
/* What we want to decompress */
ccp_wantoptions[unit].lzs = 1;
ccp_wantoptions[unit].lzs_hists = LZS_DECOMP_DEF_HISTS;
ccp_wantoptions[unit].lzs_cmode = LZS_CMODE_SEQNO;
/* What we allow to compress */
ccp_allowoptions[unit].lzs = 1;
ccp_allowoptions[unit].lzs_hists = LZS_COMP_DEF_HISTS;
ccp_allowoptions[unit].lzs_cmode = LZS_CMODE_SEQNO;
}
int ccp_getunit(int linkunit,int protocol)
@ -300,6 +324,7 @@ static void ccp_l_input(int linkunit,u_char *p,int len)
/*
* Handle a CCP-specific code.
* With the new reset handling in the kernel, this code will become unused.
*/
static int ccp_extcode(fsm *f,int code,int id,u_char *p,int len)
{
@ -383,7 +408,7 @@ static void ccp_resetci(fsm *f)
/*
* Check whether the kernel knows about the various
* compression methods we might request.
* DEcompression methods we might request.
*/
if (go->bsd_compress) {
opt_buf[0] = CI_BSD_COMPRESS;
@ -412,6 +437,18 @@ static void ccp_resetci(fsm *f)
if (ccp_test(unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0)
go->predictor_2 = 0;
}
if(go->lzs) {
opt_buf[0] = CI_LZS_COMPRESS;
opt_buf[1] = CILEN_LZS_COMPRESS;
opt_buf[2] = LZS_HIST_BYTE1(LZS_DECOMP_DEF_HISTS);
opt_buf[3] = LZS_HIST_BYTE2(LZS_DECOMP_DEF_HISTS);
opt_buf[4] = LZS_CMODE_SEQNO;
if(ccp_test(unit, opt_buf, CILEN_LZS_COMPRESS, 0) <= 0) {
go->lzs = 0;
fprintf(stderr, "kernel check for LZS failed\n");
}
}
}
/*
@ -429,7 +466,8 @@ static int ccp_cilen(fsm *f)
return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
+ (go->deflate? CILEN_DEFLATE: 0)
+ (go->predictor_1? CILEN_PREDICTOR_1: 0)
+ (go->predictor_2? CILEN_PREDICTOR_2: 0);
+ (go->predictor_2? CILEN_PREDICTOR_2: 0)
+ (go->lzs? CILEN_LZS_COMPRESS: 0);
}
/*
@ -514,6 +552,20 @@ static void ccp_addci(fsm *f,u_char *p,int *lenp)
p += CILEN_PREDICTOR_2;
}
}
if(go->lzs) {
p[0] = CI_LZS_COMPRESS;
p[1] = CILEN_LZS_COMPRESS;
p[2] = LZS_HIST_BYTE1(go->lzs_hists);
p[3] = LZS_HIST_BYTE2(go->lzs_hists);
p[4] = go->lzs_cmode;
if(p == p0 && ccp_test(unit, p, CILEN_LZS_COMPRESS, 0) <= 0) {
/* TODO: Try less histories and finally try cmode 4 until the
kernel accepts a method before really wiping LZS */
go->lzs = 0;
} else {
p += CILEN_LZS_COMPRESS;
}
}
go->method = (p > p0)? p0[0]: -1;
@ -577,6 +629,17 @@ static int ccp_ackci(fsm *f,u_char *p,int len)
if (p == p0 && len == 0)
return 1;
}
if(go->lzs) {
if(len < CILEN_LZS_COMPRESS
|| p[0] != CI_LZS_COMPRESS || p[1] != CILEN_LZS_COMPRESS
|| LZS_HIST_WORD(p[2], p[3]) != go->lzs_hists
|| p[4] != go->lzs_cmode)
return 0; /* Brocken ack - line noise ? */
p += CILEN_LZS_COMPRESS;
len -= CILEN_LZS_COMPRESS;
if(p == p0 && len == 0)
return 1;
}
if (len != 0)
return 0;
return 1;
@ -592,6 +655,8 @@ static int ccp_nakci(fsm *f,u_char *p,int len)
ccp_options no; /* options we've seen already */
ccp_options try; /* options to ask for next time */
int nb;
if(f->protocol == PPP_CCP)
go = &ccp_gotoptions[lns[f->unit].ccp_unit];
else
@ -633,6 +698,26 @@ static int ccp_nakci(fsm *f,u_char *p,int len)
len -= CILEN_BSD_COMPRESS;
}
if(go->lzs && len >= CILEN_LZS_COMPRESS && p[0] == CI_LZS_COMPRESS
&& p[1] == CILEN_LZS_COMPRESS) {
no.lzs = 1;
/*
* Peer wants us to use a different number of histories or
* a different check mode.
*/
nb = LZS_HIST_WORD(p[2], p[3]);
if(nb != go->lzs_hists) {
if(nb >= 0 && nb <= LZS_DECOMP_MAX_HISTS)
try.lzs_hists = nb;
else
try.lzs = 0;
}
if(p[4] != go->lzs_cmode)
try.lzs_cmode = p[4];
p += CILEN_LZS_COMPRESS;
len -= CILEN_LZS_COMPRESS;
}
/*
* Predictor-1 and 2 have no options, so they can't be Naked.
*
@ -701,6 +786,14 @@ static int ccp_rejci(fsm *f,u_char *p,int len)
p += CILEN_PREDICTOR_2;
len -= CILEN_PREDICTOR_2;
}
if(go->lzs && len >= CILEN_LZS_COMPRESS
&& p[0] == CI_LZS_COMPRESS && p[1] == CILEN_LZS_COMPRESS) {
if(LZS_HIST_WORD(p[2], p[3]) != go->lzs_hists || p[4] != go->lzs_cmode)
return 0;
try.lzs = 0;
p += CILEN_LZS_COMPRESS;
len -= CILEN_LZS_COMPRESS;
}
if (len != 0)
return 0;
@ -857,6 +950,47 @@ static int ccp_reqci(fsm *f,u_char *p,int *lenp,int dont_nak)
}
break;
case CI_LZS_COMPRESS:
if(!ao->lzs || clen != CILEN_LZS_COMPRESS) {
newret = CONFREJ;
break;
}
ho->lzs = 1;
ho->lzs_hists = nb = LZS_HIST_WORD(p[2], p[3]);
ho->lzs_cmode = p[4];
if(nb < 0 || nb > ao->lzs_hists) {
newret = CONFNAK;
if(!dont_nak) {
p[2] = LZS_HIST_BYTE1(ao->lzs_hists);
p[3] = LZS_HIST_BYTE2(ao->lzs_hists);
break;
}
}
if(p[4] != ao->lzs_cmode) {
/* Peer wants another checkmode - accept only EXT for now */
if(p[4] != LZS_CMODE_EXT) {
newret = CONFNAK;
if(!dont_nak)
p[4] = ao->lzs_cmode;
break;
} else {
/* EXT is Ok but requires hists to be 1 */
if(nb != 1) {
newret = CONFNAK;
if(!dont_nak) {
p[2] = LZS_HIST_BYTE1(1);
p[3] = LZS_HIST_BYTE2(1);
}
break;
}
}
}
/* Finally verify the kernel is thinking the same way */
if(p == p0 && ccp_test(unit, p, CILEN_LZS_COMPRESS, 1) <= 0) {
newret = CONFREJ;
}
break;
default:
newret = CONFREJ;
}
@ -915,6 +1049,16 @@ static char *method_name(ccp_options *opt,ccp_options *opt2)
return "Predictor 1";
case CI_PREDICTOR_2:
return "Predictor 2";
case CI_LZS_COMPRESS:
if (opt2 != NULL && (opt2->lzs_hists != opt->lzs_hists ||
opt2->lzs_cmode != opt->lzs_cmode))
sprintf(result, "LZS (hists %d check %d/hists %d check %d)",
opt->lzs_hists, opt->lzs_cmode,
opt2->lzs_hists, opt2->lzs_cmode);
else
sprintf(result, "LZS (hists %d check %d)",
opt->lzs_hists, opt->lzs_cmode);
break;
default:
sprintf(result, "Method %d", opt->method);
}
@ -1054,10 +1198,17 @@ static int ccp_printpkt(u_char *p,int plen,void (*printer)(void*,char*,...),void
p += CILEN_PREDICTOR_2;
}
break;
case CI_LZS_COMPRESS:
if(optlen >= CILEN_LZS_COMPRESS) {
printer(arg, "LZS hists %d check %d",
(p[2] << 16) | p[3], p[4]);
p += CILEN_LZS_COMPRESS;
}
break;
while (p < optend)
printer(arg, " %.2x", *p++);
printer(arg, ">");
}
while (p < optend)
printer(arg, " %.2x", *p++);
printer(arg, ">");
}
break;

View File

@ -24,7 +24,7 @@
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
*
* $Id: ccp.h,v 1.3 1998/03/25 13:13:36 hipp Exp $
* $Id: ccp.h,v 1.4 1998/07/08 16:48:22 hipp Exp $
*/
typedef struct ccp_options {
@ -32,9 +32,12 @@ typedef struct ccp_options {
u_int deflate: 1; /* do Deflate? */
u_int predictor_1: 1; /* do Predictor-1? */
u_int predictor_2: 1; /* do Predictor-2? */
u_int lzs: 1; /* do STAC LZS? */
u_short bsd_bits; /* # bits/code for BSD Compress */
u_short deflate_size; /* lg(window size) for Deflate */
short method; /* code for chosen compression method */
u_short lzs_hists; /* number of hists for LZS */
u_char lzs_cmode; /* check mode for LZS */
short method; /* code for chosen compression method */
unsigned long protos;
} ccp_options;

View File

@ -17,7 +17,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
char options_rcsid[] = "$Id: options.c,v 1.10 1998/05/05 08:51:26 hipp Exp $";
char options_rcsid[] = "$Id: options.c,v 1.11 1998/07/08 16:48:22 hipp Exp $";
#include <stdio.h>
#include <errno.h>
@ -53,6 +53,8 @@ char options_rcsid[] = "$Id: options.c,v 1.10 1998/05/05 08:51:26 hipp Exp $";
#include <linux/ppp-comp.h>
#include <linux/isdn_lzscomp.h>
#define FALSE 0
#define TRUE 1
@ -126,6 +128,7 @@ int refuse_pap = 0; /* Set to say we won't do PAP */
int refuse_chap = 0; /* Set to say we won't do CHAP */
int log_raw_password = 0;
int force_driver = 0;
struct option_info auth_req_info;
struct option_info devnam_info;
@ -221,6 +224,8 @@ static int setlcpechofails __P((int,char **));
static int setbsdcomp __P((int,char **));
static int noccp __P((int));
static int setnobsdcomp __P((int));
static int setlzs __P((int,char **));
static int setnolzs __P((int));
static int setdeflate __P((int,char **));
static int setnodeflate __P((int));
static int setpred1comp __P((int));
@ -259,6 +264,8 @@ static int setnohostroute __P((int));
static int number_option __P((char *, u_int32_t *, int));
static int int_option __P((char *, int *));
static int readable __P((int));
static int setforcedriver(int dummy);
#ifdef RADIUS
char *make_username_realm ( char * );
int __P (radius_init ( void ));
@ -374,6 +381,9 @@ static struct cmd {
{"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */
{"nobsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
{"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */
{"lzs", 1, setlzs}, /* request LZS Compression */
{"nolzs", 0, setnolzs}, /* disable LZS Compression */
{"-lzs", 0, setnolzs}, /* disable LZS Compression */
{"deflate", 1, setdeflate}, /* request Deflate compression */
{"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */
{"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */
@ -418,6 +428,7 @@ static struct cmd {
{"hostroute", 0, sethostroute}, /* Add host route (default) */
{"-hostroute", 0, setnohostroute}, /* Don't add host route */
#endif
{"+force-driver",0,setforcedriver},
{NULL, 0, NULL}
};
@ -2050,6 +2061,78 @@ static int setnobsdcomp(int slot)
return 1;
}
static int setlzs(int ccp_slot,char ** argv)
{
int rhists, rcmode, xhists, xcmode;
char *str, *endp;
rhists = LZS_DECOMP_DEF_HISTS;
xhists = LZS_COMP_DEF_HISTS;
rcmode = xcmode = LZS_CMODE_SEQNO;
str = *argv;
rhists = xhists = strtol(str, &endp, 0);
if (endp != str) {
if(*endp == ':') {
str = endp + 1;
rcmode = xcmode = strtol(str, &endp, 0);
}
if(endp != str) {
if(*endp == ',') {
str = endp + 1;
xhists = strtol(str, &endp, 0);
}
if(endp != str) {
if(*endp == ':') {
str = endp + 1;
xcmode = strtol(str, &endp, 0);
}
}
}
}
if (*endp != 0 || endp == str) {
option_error("invalid parameter '%s' for lzs option", *argv);
return 0;
}
if(rhists < 0 || rhists > LZS_DECOMP_MAX_HISTS) {
option_error("lzs recv hists must be 0 .. %d", LZS_DECOMP_MAX_HISTS);
return 0;
}
if(xhists < 0 || xhists > LZS_COMP_MAX_HISTS) {
option_error("lzs xmit hists must be 0 .. %d", LZS_COMP_MAX_HISTS);
return 0;
}
if(rcmode < 0 || rcmode > 4) {
option_error("lzs recv check mode %d unknown", rcmode);
return 0;
}
if(xcmode < 0 || xcmode > 4) {
option_error("lzs xmit check mode %d unknown", xcmode);
return 0;
}
fprintf(stderr, "LZS: recv hists %d check %d xmit hists %d check %d\n",
rhists, rcmode, xhists, xcmode);
ccp_wantoptions[ccp_slot].lzs = 1;
ccp_wantoptions[ccp_slot].lzs_hists = rhists;
ccp_wantoptions[ccp_slot].lzs_cmode = rcmode;
ccp_allowoptions[ccp_slot].lzs = 1;
ccp_allowoptions[ccp_slot].lzs_hists = xhists;
ccp_allowoptions[ccp_slot].lzs_cmode = xcmode;
return 1;
}
static int setnolzs(int ccp_slot)
{
ccp_wantoptions[ccp_slot].lzs = 0;
ccp_allowoptions[ccp_slot].lzs = 0;
return 1;
}
static int setdeflate(int ccp_slot,char ** argv)
{
int rbits, abits;
@ -2373,4 +2456,10 @@ static int resetipxproto(int slot)
return 1;
}
static int setforcedriver(int dummy)
{
force_driver = 1;
}

View File

@ -22,7 +22,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
char sys_rcsid[] = "$Id: sys-linux.c,v 1.13 1998/04/29 14:29:48 hipp Exp $";
char sys_rcsid[] = "$Id: sys-linux.c,v 1.14 1998/07/08 16:48:24 hipp Exp $";
#define _LINUX_STRING_H_
@ -64,6 +64,8 @@ char sys_rcsid[] = "$Id: sys-linux.c,v 1.13 1998/04/29 14:29:48 hipp Exp $";
# include <linux/if_ether.h>
#endif
#include <linux/isdn_ppp.h>
#include "fsm.h"
#include "ipppd.h"
#include "ipcp.h"
@ -71,6 +73,8 @@ char sys_rcsid[] = "$Id: sys-linux.c,v 1.13 1998/04/29 14:29:48 hipp Exp $";
#include "ccp.h"
#include "lcp.h"
extern int force_driver;
static int prev_kdebugflag = 0;
static int has_default_route = 0;
static int driver_version = 0;
@ -1265,16 +1269,16 @@ int ppp_available(void)
/*
* Validate the version of the driver against the version that we used.
*/
decode_version (PPP_VERSION, &my_version, &my_modification, &my_patch);
decode_version (IPPP_VERSION, &my_version, &my_modification, &my_patch);
/* The version numbers must match and the modification levels must be legal */
if (driver_version != my_version || driver_modification < my_modification)
if ( (driver_version != my_version || driver_modification < my_modification) && !force_driver)
{
extern char *no_ppp_msg;
no_ppp_msg = route_buffer;
sprintf(no_ppp_msg,
"Sorry - PPP driver version %d.%d.%d is out of date.\n"
"Sorry - isdnPPP driver version %d.%d.%d is out of date.\n"
"Maybe ippp0 has no 'syncppp' encapsulation?\n",
driver_version, driver_modification, driver_patch);
return 0;