vjcomp.c revision 31514
16059Samurai/* 26059Samurai * Input/Output VJ Compressed packets 36059Samurai * 46059Samurai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 56059Samurai * 66059Samurai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 76059Samurai * 86059Samurai * Redistribution and use in source and binary forms are permitted 96059Samurai * provided that the above copyright notice and this paragraph are 106059Samurai * duplicated in all such forms and that any documentation, 116059Samurai * advertising materials, and other materials related to such 126059Samurai * distribution and use acknowledge that the software was developed 136059Samurai * by the Internet Initiative Japan, Inc. The name of the 146059Samurai * IIJ may not be used to endorse or promote products derived 156059Samurai * from this software without specific prior written permission. 166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 196059Samurai * 2031514Sbrian * $Id: vjcomp.c,v 1.13 1997/11/22 03:37:54 brian Exp $ 218857Srgrimes * 226059Samurai * TODO: 236059Samurai */ 2430715Sbrian#include <sys/types.h> 2530715Sbrian#include <netinet/in.h> 2630715Sbrian#include <netinet/in_systm.h> 2730715Sbrian#include <netinet/ip.h> 2830715Sbrian 2931061Sbrian#include <stdio.h> 3030715Sbrian#include <string.h> 3130715Sbrian 3231343Sbrian#include "command.h" 3330715Sbrian#include "mbuf.h" 3430715Sbrian#include "log.h" 3530715Sbrian#include "defs.h" 3630715Sbrian#include "timer.h" 376059Samurai#include "fsm.h" 386059Samurai#include "lcpproto.h" 396059Samurai#include "slcompress.h" 406059Samurai#include "hdlc.h" 416059Samurai#include "ipcp.h" 4230715Sbrian#include "vjcomp.h" 436059Samurai 4428679Sbrian#define MAX_VJHEADER 16 /* Maximum size of compressed header */ 456059Samurai 466059Samuraistruct slcompress cslc; 476059Samurai 486059Samuraivoid 4930187SbrianVjInit(int max_state) 506059Samurai{ 5130187Sbrian sl_compress_init(&cslc, max_state); 526059Samurai} 536059Samurai 546059Samuraivoid 5528679SbrianSendPppFrame(struct mbuf * bp) 566059Samurai{ 576059Samurai int type; 5831514Sbrian u_short proto; 5931514Sbrian u_short cproto = IpcpInfo.his_compproto >> 16; 606059Samurai 6126516Sbrian LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto); 6228679Sbrian if (((struct ip *) MBUF_CTOP(bp))->ip_p == IPPROTO_TCP 6328679Sbrian && cproto == PROTO_VJCOMP) { 6431514Sbrian type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp), &cslc, 6531514Sbrian IpcpInfo.his_compproto & 0xff); 6626516Sbrian LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type); 676059Samurai switch (type) { 686059Samurai case TYPE_IP: 696059Samurai proto = PROTO_IP; 706059Samurai break; 716059Samurai case TYPE_UNCOMPRESSED_TCP: 726059Samurai proto = PROTO_VJUNCOMP; 736059Samurai break; 746059Samurai case TYPE_COMPRESSED_TCP: 756059Samurai proto = PROTO_VJCOMP; 766059Samurai break; 776059Samurai default: 7826516Sbrian LogPrintf(LogERROR, "Unknown frame type %x\n", type); 796059Samurai pfree(bp); 806059Samurai return; 816059Samurai } 826059Samurai } else 836059Samurai proto = PROTO_IP; 8413733Sdfr HdlcOutput(PRI_NORMAL, proto, bp); 856059Samurai} 866059Samurai 876059Samuraistatic struct mbuf * 8828679SbrianVjUncompressTcp(struct mbuf * bp, u_char type) 896059Samurai{ 906059Samurai u_char *bufp; 916059Samurai int len, olen, rlen; 926059Samurai struct mbuf *nbp; 9328679Sbrian u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */ 946059Samurai 956059Samurai olen = len = plength(bp); 966059Samurai if (type == TYPE_UNCOMPRESSED_TCP) { 9728679Sbrian 986059Samurai /* 9928679Sbrian * Uncompressed packet does NOT change its size, so that we can use mbuf 10028679Sbrian * space for uncompression job. 1016059Samurai */ 1026059Samurai bufp = MBUF_CTOP(bp); 1036059Samurai len = sl_uncompress_tcp(&bufp, len, type, &cslc); 1046735Samurai if (len <= 0) { 1056735Samurai pfree(bp); 1066735Samurai bp = NULLBUFF; 1076735Samurai } 10828679Sbrian return (bp); 1096059Samurai } 11028679Sbrian 1116059Samurai /* 11228679Sbrian * Handle compressed packet. 1) Read upto MAX_VJHEADER bytes into work 11328679Sbrian * space. 2) Try to uncompress it. 3) Compute amount of necesary space. 4) 11428679Sbrian * Copy unread data info there. 1156059Samurai */ 11628679Sbrian if (len > MAX_VJHEADER) 11728679Sbrian len = MAX_VJHEADER; 1186059Samurai rlen = len; 1196059Samurai bufp = work + MAX_HDR; 1206059Samurai bp = mbread(bp, bufp, rlen); 1216059Samurai len = sl_uncompress_tcp(&bufp, olen, type, &cslc); 1226735Samurai if (len <= 0) { 1236735Samurai pfree(bp); 1246735Samurai return NULLBUFF; 1256735Samurai } 1266059Samurai len -= olen; 1276059Samurai len += rlen; 1286059Samurai nbp = mballoc(len, MB_VJCOMP); 12930715Sbrian memcpy(MBUF_CTOP(nbp), bufp, len); 1306059Samurai nbp->next = bp; 13128679Sbrian return (nbp); 1326059Samurai} 1336059Samurai 1346059Samuraistruct mbuf * 13528679SbrianVjCompInput(struct mbuf * bp, int proto) 1366059Samurai{ 1376059Samurai u_char type; 1386059Samurai 13926516Sbrian LogPrintf(LogDEBUG, "VjCompInput: proto %02x\n", proto); 14026516Sbrian LogDumpBp(LogDEBUG, "Raw packet info:", bp); 1416059Samurai 1426059Samurai switch (proto) { 1436059Samurai case PROTO_VJCOMP: 1446059Samurai type = TYPE_COMPRESSED_TCP; 1456059Samurai break; 1466059Samurai case PROTO_VJUNCOMP: 1476059Samurai type = TYPE_UNCOMPRESSED_TCP; 1486059Samurai break; 1496059Samurai default: 15026516Sbrian LogPrintf(LogERROR, "VjCompInput...???\n"); 15128679Sbrian return (bp); 1526059Samurai } 1536059Samurai bp = VjUncompressTcp(bp, type); 15428679Sbrian return (bp); 1556059Samurai} 15631514Sbrian 15731514Sbrianconst char * 15831514Sbrianvj2asc(u_long val) 15931514Sbrian{ 16031514Sbrian static char asc[50]; 16131514Sbrian 16231514Sbrian sprintf(asc, "%ld VJ slots %s slot compression", 16331514Sbrian ((val>>8)&15)+1, val & 1 ? "with" : "without"); 16431514Sbrian return asc; 16531514Sbrian} 166