vjcomp.c revision 31061
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 * 2031061Sbrian * $Id: vjcomp.c,v 1.11 1997/10/26 01:04:01 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 3230715Sbrian#include "mbuf.h" 3330715Sbrian#include "log.h" 3430715Sbrian#include "defs.h" 3530715Sbrian#include "timer.h" 366059Samurai#include "fsm.h" 376059Samurai#include "lcpproto.h" 386059Samurai#include "slcompress.h" 396059Samurai#include "hdlc.h" 406059Samurai#include "ipcp.h" 4130715Sbrian#include "vjcomp.h" 426059Samurai 4328679Sbrian#define MAX_VJHEADER 16 /* Maximum size of compressed header */ 446059Samurai 456059Samuraistruct slcompress cslc; 466059Samurai 476059Samuraivoid 4830187SbrianVjInit(int max_state) 496059Samurai{ 5030187Sbrian sl_compress_init(&cslc, max_state); 516059Samurai} 526059Samurai 536059Samuraivoid 5428679SbrianSendPppFrame(struct mbuf * bp) 556059Samurai{ 566059Samurai int type; 576059Samurai int proto; 586059Samurai int cproto = IpcpInfo.his_compproto >> 16; 596059Samurai 6026516Sbrian LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto); 6128679Sbrian if (((struct ip *) MBUF_CTOP(bp))->ip_p == IPPROTO_TCP 6228679Sbrian && cproto == PROTO_VJCOMP) { 6328679Sbrian type = sl_compress_tcp(bp, (struct ip *) MBUF_CTOP(bp), &cslc, IpcpInfo.his_compproto & 0xff); 646059Samurai 6526516Sbrian LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type); 666059Samurai switch (type) { 676059Samurai case TYPE_IP: 686059Samurai proto = PROTO_IP; 696059Samurai break; 706059Samurai case TYPE_UNCOMPRESSED_TCP: 716059Samurai proto = PROTO_VJUNCOMP; 726059Samurai break; 736059Samurai case TYPE_COMPRESSED_TCP: 746059Samurai proto = PROTO_VJCOMP; 756059Samurai break; 766059Samurai default: 7726516Sbrian LogPrintf(LogERROR, "Unknown frame type %x\n", type); 786059Samurai pfree(bp); 796059Samurai return; 806059Samurai } 816059Samurai } else 826059Samurai proto = PROTO_IP; 8313733Sdfr HdlcOutput(PRI_NORMAL, proto, bp); 846059Samurai} 856059Samurai 866059Samuraistatic struct mbuf * 8728679SbrianVjUncompressTcp(struct mbuf * bp, u_char type) 886059Samurai{ 896059Samurai u_char *bufp; 906059Samurai int len, olen, rlen; 916059Samurai struct mbuf *nbp; 9228679Sbrian u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */ 936059Samurai 946059Samurai olen = len = plength(bp); 956059Samurai if (type == TYPE_UNCOMPRESSED_TCP) { 9628679Sbrian 976059Samurai /* 9828679Sbrian * Uncompressed packet does NOT change its size, so that we can use mbuf 9928679Sbrian * space for uncompression job. 1006059Samurai */ 1016059Samurai bufp = MBUF_CTOP(bp); 1026059Samurai len = sl_uncompress_tcp(&bufp, len, type, &cslc); 1036735Samurai if (len <= 0) { 1046735Samurai pfree(bp); 1056735Samurai bp = NULLBUFF; 1066735Samurai } 10728679Sbrian return (bp); 1086059Samurai } 10928679Sbrian 1106059Samurai /* 11128679Sbrian * Handle compressed packet. 1) Read upto MAX_VJHEADER bytes into work 11228679Sbrian * space. 2) Try to uncompress it. 3) Compute amount of necesary space. 4) 11328679Sbrian * Copy unread data info there. 1146059Samurai */ 11528679Sbrian if (len > MAX_VJHEADER) 11628679Sbrian len = MAX_VJHEADER; 1176059Samurai rlen = len; 1186059Samurai bufp = work + MAX_HDR; 1196059Samurai bp = mbread(bp, bufp, rlen); 1206059Samurai len = sl_uncompress_tcp(&bufp, olen, type, &cslc); 1216735Samurai if (len <= 0) { 1226735Samurai pfree(bp); 1236735Samurai return NULLBUFF; 1246735Samurai } 1256059Samurai len -= olen; 1266059Samurai len += rlen; 1276059Samurai nbp = mballoc(len, MB_VJCOMP); 12830715Sbrian memcpy(MBUF_CTOP(nbp), bufp, len); 1296059Samurai nbp->next = bp; 13028679Sbrian return (nbp); 1316059Samurai} 1326059Samurai 1336059Samuraistruct mbuf * 13428679SbrianVjCompInput(struct mbuf * bp, int proto) 1356059Samurai{ 1366059Samurai u_char type; 1376059Samurai 13826516Sbrian LogPrintf(LogDEBUG, "VjCompInput: proto %02x\n", proto); 13926516Sbrian LogDumpBp(LogDEBUG, "Raw packet info:", bp); 1406059Samurai 1416059Samurai switch (proto) { 1426059Samurai case PROTO_VJCOMP: 1436059Samurai type = TYPE_COMPRESSED_TCP; 1446059Samurai break; 1456059Samurai case PROTO_VJUNCOMP: 1466059Samurai type = TYPE_UNCOMPRESSED_TCP; 1476059Samurai break; 1486059Samurai default: 14926516Sbrian LogPrintf(LogERROR, "VjCompInput...???\n"); 15028679Sbrian return (bp); 1516059Samurai } 1526059Samurai bp = VjUncompressTcp(bp, type); 15328679Sbrian return (bp); 1546059Samurai} 155