vjcomp.c revision 32439
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.14 1997/12/03 10:23:54 brian Exp $ 2142704Swosch * 2242704Swosch * TODO: 2342704Swosch */ 2442704Swosch#include <sys/types.h> 2542704Swosch#include <netinet/in.h> 2642704Swosch#include <netinet/in_systm.h> 2742704Swosch#include <netinet/ip.h> 2842704Swosch 2942704Swosch#include <stdio.h> 3059769Sgrog#include <string.h> 3159769Sgrog 3259769Sgrog#include "command.h" 3359769Sgrog#include "mbuf.h" 3459769Sgrog#include "log.h" 3559769Sgrog#include "defs.h" 3659769Sgrog#include "timer.h" 3759769Sgrog#include "fsm.h" 3859769Sgrog#include "lcpproto.h" 3924424Swosch#include "slcompress.h" 4042704Swosch#include "hdlc.h" 4124424Swosch#include "ipcp.h" 4242704Swosch#include "vjcomp.h" 4324424Swosch 4442704Swosch#define MAX_VJHEADER 16 /* Maximum size of compressed header */ 4524424Swosch 4624424Swoschstruct slcompress cslc; 4724424Swosch 4842704Swoschvoid 4925031SwoschVjInit(int max_state) 5059156Swosch{ 5125031Swosch sl_compress_init(&cslc, max_state); 5225031Swosch} 5324424Swosch 5424424Swoschvoid 5524424SwoschSendPppFrame(struct mbuf * bp) 5624424Swosch{ 5771231Sitojun int type; 5824424Swosch u_short proto; 5971231Sitojun u_short cproto = IpcpInfo.his_compproto >> 16; 6025031Swosch 6171231Sitojun LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto); 6224424Swosch if (((struct ip *) MBUF_CTOP(bp))->ip_p == IPPROTO_TCP 6325031Swosch && cproto == PROTO_VJCOMP) { 6425031Swosch type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp), &cslc, 6571231Sitojun IpcpInfo.his_compproto & 0xff); 6625031Swosch LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type); 6771231Sitojun switch (type) { 6870110Swosch case TYPE_IP: 6970110Swosch proto = PROTO_IP; 7070110Swosch break; 7170110Swosch case TYPE_UNCOMPRESSED_TCP: 7270110Swosch proto = PROTO_VJUNCOMP; 7370110Swosch break; 7470110Swosch case TYPE_COMPRESSED_TCP: 7570110Swosch proto = PROTO_VJCOMP; 7670110Swosch break; 7770110Swosch default: 7870110Swosch LogPrintf(LogERROR, "Unknown frame type %x\n", type); 7980675Sasmodai pfree(bp); 8080675Sasmodai return; 8180675Sasmodai } 8280675Sasmodai } else 8380675Sasmodai proto = PROTO_IP; 8480675Sasmodai HdlcOutput(PRI_NORMAL, proto, bp); 8580675Sasmodai} 8680675Sasmodai 8780675Sasmodaistatic struct mbuf * 8880675SasmodaiVjUncompressTcp(struct mbuf * bp, u_char type) 8980675Sasmodai{ 9080675Sasmodai u_char *bufp; 9180675Sasmodai int len, olen, rlen; 9280675Sasmodai struct mbuf *nbp; 9380675Sasmodai u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */ 9480675Sasmodai 9580675Sasmodai olen = len = plength(bp); 9680675Sasmodai if (type == TYPE_UNCOMPRESSED_TCP) { 9780675Sasmodai 9880675Sasmodai /* 9980675Sasmodai * Uncompressed packet does NOT change its size, so that we can use mbuf 10080675Sasmodai * space for uncompression job. 10180675Sasmodai */ 10280675Sasmodai bufp = MBUF_CTOP(bp); 10380675Sasmodai len = sl_uncompress_tcp(&bufp, len, type, &cslc); 10480675Sasmodai if (len <= 0) { 10580675Sasmodai pfree(bp); 10680675Sasmodai bp = NULLBUFF; 10780675Sasmodai } 10880675Sasmodai return (bp); 10980675Sasmodai } 11080675Sasmodai 11180675Sasmodai /* 11280675Sasmodai * Handle compressed packet. 1) Read upto MAX_VJHEADER bytes into work 11380675Sasmodai * space. 2) Try to uncompress it. 3) Compute amount of necesary space. 4) 11480675Sasmodai * Copy unread data info there. 11580675Sasmodai */ 11680675Sasmodai if (len > MAX_VJHEADER) 11780675Sasmodai len = MAX_VJHEADER; 11880675Sasmodai rlen = len; 11980675Sasmodai bufp = work + MAX_HDR; 12080675Sasmodai bp = mbread(bp, bufp, rlen); 12180675Sasmodai len = sl_uncompress_tcp(&bufp, olen, type, &cslc); 12280675Sasmodai if (len <= 0) { 12380675Sasmodai pfree(bp); 12480675Sasmodai return NULLBUFF; 12580675Sasmodai } 12680675Sasmodai len -= olen; 12780675Sasmodai len += rlen; 12880675Sasmodai nbp = mballoc(len, MB_VJCOMP); 12980675Sasmodai memcpy(MBUF_CTOP(nbp), bufp, len); 13080675Sasmodai nbp->next = bp; 13180675Sasmodai return (nbp); 13280675Sasmodai} 13380675Sasmodai 13480675Sasmodaistruct mbuf * 13580675SasmodaiVjCompInput(struct mbuf * bp, int proto) 13680675Sasmodai{ 13780675Sasmodai u_char type; 138101401Swosch 13980675Sasmodai LogPrintf(LogDEBUG, "VjCompInput: proto %02x\n", proto); 14087200Swosch LogDumpBp(LogDEBUG, "Raw packet info:", bp); 14187200Swosch 14287200Swosch switch (proto) { 14380675Sasmodai case PROTO_VJCOMP: 144104772Smaxim type = TYPE_COMPRESSED_TCP; 145104772Smaxim break; 146104772Smaxim case PROTO_VJUNCOMP: 147104772Smaxim type = TYPE_UNCOMPRESSED_TCP; 148104781Sjhb break; 149104781Sjhb default: 150104781Sjhb LogPrintf(LogERROR, "VjCompInput...???\n"); 151104781Sjhb return (bp); 152104781Sjhb } 153104781Sjhb bp = VjUncompressTcp(bp, type); 154119217Smurray return (bp); 155119217Smurray} 156119217Smurray 157119217Smurrayconst char * 158119217Smurrayvj2asc(u_int32_t val) 159119217Smurray{ 160119217Smurray static char asc[50]; 161132652Sosa 162132652Sosa sprintf(asc, "%d VJ slots %s slot compression", 163132652Sosa (int)((val>>8)&15)+1, val & 1 ? "with" : "without"); 164132652Sosa return asc; 165132652Sosa} 166132652Sosa