vjcomp.c revision 26516
1222900Snp/* 2222900Snp * Input/Output VJ Compressed packets 3222900Snp * 4222900Snp * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5222900Snp * 6222900Snp * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7222900Snp * 8222900Snp * Redistribution and use in source and binary forms are permitted 9222900Snp * provided that the above copyright notice and this paragraph are 10222900Snp * duplicated in all such forms and that any documentation, 11222900Snp * advertising materials, and other materials related to such 12222900Snp * distribution and use acknowledge that the software was developed 13222900Snp * by the Internet Initiative Japan, Inc. The name of the 14222900Snp * IIJ may not be used to endorse or promote products derived 15222900Snp * from this software without specific prior written permission. 16222900Snp * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17222900Snp * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18222900Snp * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19222900Snp * 20222900Snp * $Id: vjcomp.c,v 1.7 1997/05/07 23:30:50 brian Exp $ 21222900Snp * 22296471Snp * TODO: 23296471Snp */ 24296471Snp#include "fsm.h" 25296471Snp#include "lcpproto.h" 26296471Snp#include <netinet/in_systm.h> 27296471Snp#include <netinet/ip.h> 28296471Snp#include "slcompress.h" 29296471Snp#include "hdlc.h" 30296471Snp#include "ipcp.h" 31296471Snp 32296471Snp#define MAX_VJHEADER 16 /* Maximum size of compressed header */ 33296471Snp 34296471Snpstruct slcompress cslc; 35296471Snp 36296471Snpvoid 37222900SnpVjInit() 38222900Snp{ 39222900Snp sl_compress_init(&cslc); 40222900Snp} 41222900Snp 42222900Snpvoid 43222900SnpSendPppFrame(bp) 44222900Snpstruct mbuf *bp; 45222900Snp{ 46222900Snp int type; 47222900Snp int proto; 48222900Snp int cproto = IpcpInfo.his_compproto >> 16; 49222900Snp 50222900Snp LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto); 51222900Snp if (((struct ip *)MBUF_CTOP(bp))->ip_p == IPPROTO_TCP 52222900Snp && cproto== PROTO_VJCOMP) { 53222900Snp type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp), &cslc, IpcpInfo.his_compproto & 0xff); 54222900Snp 55222900Snp LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type); 56222900Snp switch (type) { 57222900Snp case TYPE_IP: 58222900Snp proto = PROTO_IP; 59222900Snp break; 60222900Snp case TYPE_UNCOMPRESSED_TCP: 61222900Snp proto = PROTO_VJUNCOMP; 62222900Snp break; 63222900Snp case TYPE_COMPRESSED_TCP: 64222900Snp proto = PROTO_VJCOMP; 65222900Snp break; 66222900Snp default: 67222900Snp LogPrintf(LogERROR, "Unknown frame type %x\n", type); 68222900Snp pfree(bp); 69222900Snp return; 70222900Snp } 71222900Snp } else 72222900Snp proto = PROTO_IP; 73222900Snp HdlcOutput(PRI_NORMAL, proto, bp); 74222900Snp} 75222900Snp 76222900Snpstatic struct mbuf * 77222900SnpVjUncompressTcp(bp, type) 78222900Snpstruct mbuf *bp; 79222900Snpu_char type; 80222900Snp{ 81222900Snp u_char *bufp; 82222900Snp int len, olen, rlen; 83222900Snp struct mbuf *nbp; 84222900Snp u_char work[MAX_HDR+MAX_VJHEADER]; /* enough to hold TCP/IP header */ 85222900Snp 86222900Snp olen = len = plength(bp); 87222900Snp if (type == TYPE_UNCOMPRESSED_TCP) { 88296471Snp /* 89296471Snp * Uncompressed packet does NOT change its size, so that we can 90296471Snp * use mbuf space for uncompression job. 91296471Snp */ 92296471Snp bufp = MBUF_CTOP(bp); 93222900Snp len = sl_uncompress_tcp(&bufp, len, type, &cslc); 94222900Snp if (len <= 0) { 95222900Snp pfree(bp); 96222900Snp bp = NULLBUFF; 97296471Snp } 98296471Snp return(bp); 99296471Snp } 100296471Snp /* 101296471Snp * Handle compressed packet. 102296471Snp * 1) Read upto MAX_VJHEADER bytes into work space. 103296471Snp * 2) Try to uncompress it. 104296471Snp * 3) Compute amount of necesary space. 105296471Snp * 4) Copy unread data info there. 106296471Snp */ 107296471Snp if (len > MAX_VJHEADER) len = MAX_VJHEADER; 108296471Snp rlen = len; 109296471Snp bufp = work + MAX_HDR; 110296471Snp bp = mbread(bp, bufp, rlen); 111296471Snp len = sl_uncompress_tcp(&bufp, olen, type, &cslc); 112296471Snp if (len <= 0) { 113296471Snp pfree(bp); 114296471Snp return NULLBUFF; 115296471Snp } 116296471Snp len -= olen; 117296471Snp len += rlen; 118296471Snp nbp = mballoc(len, MB_VJCOMP); 119296471Snp bcopy(bufp, MBUF_CTOP(nbp), len); 120296471Snp nbp->next = bp; 121296471Snp return(nbp); 122296471Snp} 123296471Snp 124296471Snpstruct mbuf * 125296471SnpVjCompInput(bp, proto) 126296471Snpstruct mbuf *bp; 127222900Snpint proto; 128222900Snp{ 129222900Snp u_char type; 130222900Snp 131222900Snp LogPrintf(LogDEBUG, "VjCompInput: proto %02x\n", proto); 132222900Snp LogDumpBp(LogDEBUG, "Raw packet info:", bp); 133222900Snp 134222900Snp switch (proto) { 135296471Snp case PROTO_VJCOMP: 136222900Snp type = TYPE_COMPRESSED_TCP; 137222900Snp break; 138222900Snp case PROTO_VJUNCOMP: 139222900Snp type = TYPE_UNCOMPRESSED_TCP; 140222900Snp break; 141222900Snp default: 142222900Snp LogPrintf(LogERROR, "VjCompInput...???\n"); 143222900Snp return(bp); 144222900Snp } 145222900Snp bp = VjUncompressTcp(bp, type); 146222900Snp return(bp); 147222900Snp} 148222900Snp