vjcomp.c revision 28679
159769Sgrog/* 259769Sgrog * Input/Output VJ Compressed packets 324424Swosch * 424424Swosch * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 524424Swosch * 624424Swosch * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 724424Swosch * 824424Swosch * Redistribution and use in source and binary forms are permitted 924424Swosch * provided that the above copyright notice and this paragraph are 1024424Swosch * duplicated in all such forms and that any documentation, 1124424Swosch * advertising materials, and other materials related to such 1224424Swosch * distribution and use acknowledge that the software was developed 1324424Swosch * by the Internet Initiative Japan, Inc. The name of the 1424424Swosch * IIJ may not be used to endorse or promote products derived 1542704Swosch * from this software without specific prior written permission. 1642704Swosch * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1742704Swosch * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1824424Swosch * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1942704Swosch * 2042704Swosch * $Id: vjcomp.c,v 1.8 1997/06/09 03:27:43 brian Exp $ 2142704Swosch * 2242704Swosch * TODO: 2342704Swosch */ 2442704Swosch#include "fsm.h" 2542704Swosch#include "lcpproto.h" 2642704Swosch#include <netinet/in_systm.h> 2742704Swosch#include <netinet/ip.h> 2842704Swosch#include "slcompress.h" 2942704Swosch#include "hdlc.h" 3059769Sgrog#include "ipcp.h" 3159769Sgrog 3259769Sgrog#define MAX_VJHEADER 16 /* Maximum size of compressed header */ 3359769Sgrog 3459769Sgrogstruct slcompress cslc; 3559769Sgrog 3659769Sgrogvoid 3759769SgrogVjInit() 3859769Sgrog{ 3924424Swosch sl_compress_init(&cslc); 4042704Swosch} 4124424Swosch 4242704Swoschvoid 4324424SwoschSendPppFrame(struct mbuf * bp) 4442704Swosch{ 4524424Swosch int type; 4624424Swosch int proto; 4724424Swosch int cproto = IpcpInfo.his_compproto >> 16; 4842704Swosch 4925031Swosch LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto); 5059156Swosch if (((struct ip *) MBUF_CTOP(bp))->ip_p == IPPROTO_TCP 5125031Swosch && cproto == PROTO_VJCOMP) { 5225031Swosch type = sl_compress_tcp(bp, (struct ip *) MBUF_CTOP(bp), &cslc, IpcpInfo.his_compproto & 0xff); 5324424Swosch 5424424Swosch LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type); 5524424Swosch switch (type) { 5624424Swosch case TYPE_IP: 5771231Sitojun proto = PROTO_IP; 5824424Swosch break; 5971231Sitojun case TYPE_UNCOMPRESSED_TCP: 6025031Swosch proto = PROTO_VJUNCOMP; 6171231Sitojun break; 6224424Swosch case TYPE_COMPRESSED_TCP: 6325031Swosch proto = PROTO_VJCOMP; 6425031Swosch break; 6571231Sitojun default: 6625031Swosch LogPrintf(LogERROR, "Unknown frame type %x\n", type); 6771231Sitojun pfree(bp); 6870110Swosch return; 6970110Swosch } 7070110Swosch } else 7170110Swosch proto = PROTO_IP; 7270110Swosch HdlcOutput(PRI_NORMAL, proto, bp); 7370110Swosch} 7470110Swosch 7570110Swoschstatic struct mbuf * 7670110SwoschVjUncompressTcp(struct mbuf * bp, u_char type) 7770110Swosch{ 7870110Swosch u_char *bufp; 7980675Sasmodai int len, olen, rlen; 8080675Sasmodai struct mbuf *nbp; 8180675Sasmodai u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */ 8280675Sasmodai 8380675Sasmodai olen = len = plength(bp); 8480675Sasmodai if (type == TYPE_UNCOMPRESSED_TCP) { 8580675Sasmodai 8680675Sasmodai /* 8780675Sasmodai * Uncompressed packet does NOT change its size, so that we can use mbuf 8880675Sasmodai * space for uncompression job. 8980675Sasmodai */ 9080675Sasmodai bufp = MBUF_CTOP(bp); 9180675Sasmodai len = sl_uncompress_tcp(&bufp, len, type, &cslc); 9280675Sasmodai if (len <= 0) { 9380675Sasmodai pfree(bp); 9480675Sasmodai bp = NULLBUFF; 9580675Sasmodai } 9680675Sasmodai return (bp); 9780675Sasmodai } 9880675Sasmodai 9980675Sasmodai /* 10080675Sasmodai * Handle compressed packet. 1) Read upto MAX_VJHEADER bytes into work 10180675Sasmodai * space. 2) Try to uncompress it. 3) Compute amount of necesary space. 4) 10280675Sasmodai * Copy unread data info there. 10380675Sasmodai */ 10480675Sasmodai if (len > MAX_VJHEADER) 10580675Sasmodai len = MAX_VJHEADER; 10680675Sasmodai rlen = len; 10780675Sasmodai bufp = work + MAX_HDR; 10880675Sasmodai bp = mbread(bp, bufp, rlen); 10980675Sasmodai len = sl_uncompress_tcp(&bufp, olen, type, &cslc); 11080675Sasmodai if (len <= 0) { 11180675Sasmodai pfree(bp); 11280675Sasmodai return NULLBUFF; 11380675Sasmodai } 11480675Sasmodai len -= olen; 11580675Sasmodai len += rlen; 11680675Sasmodai nbp = mballoc(len, MB_VJCOMP); 11780675Sasmodai bcopy(bufp, MBUF_CTOP(nbp), len); 11880675Sasmodai nbp->next = bp; 11980675Sasmodai return (nbp); 12080675Sasmodai} 12180675Sasmodai 12280675Sasmodaistruct mbuf * 12380675SasmodaiVjCompInput(struct mbuf * bp, int proto) 12480675Sasmodai{ 12580675Sasmodai u_char type; 12680675Sasmodai 12780675Sasmodai LogPrintf(LogDEBUG, "VjCompInput: proto %02x\n", proto); 12880675Sasmodai LogDumpBp(LogDEBUG, "Raw packet info:", bp); 12980675Sasmodai 13080675Sasmodai switch (proto) { 13180675Sasmodai case PROTO_VJCOMP: 13280675Sasmodai type = TYPE_COMPRESSED_TCP; 13380675Sasmodai break; 13480675Sasmodai case PROTO_VJUNCOMP: 13580675Sasmodai type = TYPE_UNCOMPRESSED_TCP; 13680675Sasmodai break; 13780675Sasmodai default: 138101401Swosch LogPrintf(LogERROR, "VjCompInput...???\n"); 13980675Sasmodai return (bp); 140147593Shrs } 14187200Swosch bp = VjUncompressTcp(bp, type); 142147593Shrs return (bp); 14380675Sasmodai} 144104772Smaxim