1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * Input/Output VJ Compressed packets 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 20aa8e0519SBrian Somers * $Id: vjcomp.c,v 1.15 1998/01/11 17:50:46 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23af57ed9fSAtsushi Murai */ 2475240ed1SBrian Somers #include <sys/types.h> 2575240ed1SBrian Somers #include <netinet/in.h> 26af57ed9fSAtsushi Murai #include <netinet/in_systm.h> 27af57ed9fSAtsushi Murai #include <netinet/ip.h> 2875240ed1SBrian Somers 295106c671SBrian Somers #include <stdio.h> 3075240ed1SBrian Somers #include <string.h> 3175240ed1SBrian Somers 32b6e82f33SBrian Somers #include "command.h" 3375240ed1SBrian Somers #include "mbuf.h" 3475240ed1SBrian Somers #include "log.h" 3575240ed1SBrian Somers #include "timer.h" 3675240ed1SBrian Somers #include "fsm.h" 3775240ed1SBrian Somers #include "lcpproto.h" 38af57ed9fSAtsushi Murai #include "slcompress.h" 39af57ed9fSAtsushi Murai #include "hdlc.h" 40af57ed9fSAtsushi Murai #include "ipcp.h" 4175240ed1SBrian Somers #include "vjcomp.h" 42af57ed9fSAtsushi Murai 43af57ed9fSAtsushi Murai #define MAX_VJHEADER 16 /* Maximum size of compressed header */ 44af57ed9fSAtsushi Murai 45aa8e0519SBrian Somers static struct slcompress cslc; 46af57ed9fSAtsushi Murai 47af57ed9fSAtsushi Murai void 4803604f35SBrian Somers VjInit(int max_state) 49af57ed9fSAtsushi Murai { 5003604f35SBrian Somers sl_compress_init(&cslc, max_state); 51af57ed9fSAtsushi Murai } 52af57ed9fSAtsushi Murai 53af57ed9fSAtsushi Murai void 54944f7098SBrian Somers SendPppFrame(struct mbuf * bp) 55af57ed9fSAtsushi Murai { 56af57ed9fSAtsushi Murai int type; 570053cc58SBrian Somers u_short proto; 580053cc58SBrian Somers u_short cproto = IpcpInfo.his_compproto >> 16; 59af57ed9fSAtsushi Murai 60927145beSBrian Somers LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto); 612f8fcf44SBrian Somers if (((struct ip *) MBUF_CTOP(bp))->ip_p == IPPROTO_TCP 622f8fcf44SBrian Somers && cproto == PROTO_VJCOMP) { 630053cc58SBrian Somers type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp), &cslc, 640053cc58SBrian Somers IpcpInfo.his_compproto & 0xff); 65927145beSBrian Somers LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type); 66af57ed9fSAtsushi Murai switch (type) { 67af57ed9fSAtsushi Murai case TYPE_IP: 68af57ed9fSAtsushi Murai proto = PROTO_IP; 69af57ed9fSAtsushi Murai break; 70af57ed9fSAtsushi Murai case TYPE_UNCOMPRESSED_TCP: 71af57ed9fSAtsushi Murai proto = PROTO_VJUNCOMP; 72af57ed9fSAtsushi Murai break; 73af57ed9fSAtsushi Murai case TYPE_COMPRESSED_TCP: 74af57ed9fSAtsushi Murai proto = PROTO_VJCOMP; 75af57ed9fSAtsushi Murai break; 76af57ed9fSAtsushi Murai default: 77927145beSBrian Somers LogPrintf(LogERROR, "Unknown frame type %x\n", type); 78af57ed9fSAtsushi Murai pfree(bp); 79af57ed9fSAtsushi Murai return; 80af57ed9fSAtsushi Murai } 81af57ed9fSAtsushi Murai } else 82af57ed9fSAtsushi Murai proto = PROTO_IP; 8376bd0c0aSDoug Rabson HdlcOutput(PRI_NORMAL, proto, bp); 84af57ed9fSAtsushi Murai } 85af57ed9fSAtsushi Murai 86af57ed9fSAtsushi Murai static struct mbuf * 87944f7098SBrian Somers VjUncompressTcp(struct mbuf * bp, u_char type) 88af57ed9fSAtsushi Murai { 89af57ed9fSAtsushi Murai u_char *bufp; 90af57ed9fSAtsushi Murai int len, olen, rlen; 91af57ed9fSAtsushi Murai struct mbuf *nbp; 92af57ed9fSAtsushi Murai u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */ 93af57ed9fSAtsushi Murai 94af57ed9fSAtsushi Murai olen = len = plength(bp); 95af57ed9fSAtsushi Murai if (type == TYPE_UNCOMPRESSED_TCP) { 96944f7098SBrian Somers 97af57ed9fSAtsushi Murai /* 98944f7098SBrian Somers * Uncompressed packet does NOT change its size, so that we can use mbuf 99944f7098SBrian Somers * space for uncompression job. 100af57ed9fSAtsushi Murai */ 101af57ed9fSAtsushi Murai bufp = MBUF_CTOP(bp); 102af57ed9fSAtsushi Murai len = sl_uncompress_tcp(&bufp, len, type, &cslc); 10353c9f6c0SAtsushi Murai if (len <= 0) { 10453c9f6c0SAtsushi Murai pfree(bp); 105aa8e0519SBrian Somers bp = NULL; 10653c9f6c0SAtsushi Murai } 107af57ed9fSAtsushi Murai return (bp); 108af57ed9fSAtsushi Murai } 109944f7098SBrian Somers 110af57ed9fSAtsushi Murai /* 111944f7098SBrian Somers * Handle compressed packet. 1) Read upto MAX_VJHEADER bytes into work 112944f7098SBrian Somers * space. 2) Try to uncompress it. 3) Compute amount of necesary space. 4) 113944f7098SBrian Somers * Copy unread data info there. 114af57ed9fSAtsushi Murai */ 115944f7098SBrian Somers if (len > MAX_VJHEADER) 116944f7098SBrian Somers len = MAX_VJHEADER; 117af57ed9fSAtsushi Murai rlen = len; 118af57ed9fSAtsushi Murai bufp = work + MAX_HDR; 119af57ed9fSAtsushi Murai bp = mbread(bp, bufp, rlen); 120af57ed9fSAtsushi Murai len = sl_uncompress_tcp(&bufp, olen, type, &cslc); 12153c9f6c0SAtsushi Murai if (len <= 0) { 12253c9f6c0SAtsushi Murai pfree(bp); 123aa8e0519SBrian Somers return NULL; 12453c9f6c0SAtsushi Murai } 125af57ed9fSAtsushi Murai len -= olen; 126af57ed9fSAtsushi Murai len += rlen; 127af57ed9fSAtsushi Murai nbp = mballoc(len, MB_VJCOMP); 12875240ed1SBrian Somers memcpy(MBUF_CTOP(nbp), bufp, len); 129af57ed9fSAtsushi Murai nbp->next = bp; 130af57ed9fSAtsushi Murai return (nbp); 131af57ed9fSAtsushi Murai } 132af57ed9fSAtsushi Murai 133af57ed9fSAtsushi Murai struct mbuf * 134944f7098SBrian Somers VjCompInput(struct mbuf * bp, int proto) 135af57ed9fSAtsushi Murai { 136af57ed9fSAtsushi Murai u_char type; 137af57ed9fSAtsushi Murai 138927145beSBrian Somers LogPrintf(LogDEBUG, "VjCompInput: proto %02x\n", proto); 139927145beSBrian Somers LogDumpBp(LogDEBUG, "Raw packet info:", bp); 140af57ed9fSAtsushi Murai 141af57ed9fSAtsushi Murai switch (proto) { 142af57ed9fSAtsushi Murai case PROTO_VJCOMP: 143af57ed9fSAtsushi Murai type = TYPE_COMPRESSED_TCP; 144af57ed9fSAtsushi Murai break; 145af57ed9fSAtsushi Murai case PROTO_VJUNCOMP: 146af57ed9fSAtsushi Murai type = TYPE_UNCOMPRESSED_TCP; 147af57ed9fSAtsushi Murai break; 148af57ed9fSAtsushi Murai default: 149927145beSBrian Somers LogPrintf(LogERROR, "VjCompInput...???\n"); 150af57ed9fSAtsushi Murai return (bp); 151af57ed9fSAtsushi Murai } 152af57ed9fSAtsushi Murai bp = VjUncompressTcp(bp, type); 153af57ed9fSAtsushi Murai return (bp); 154af57ed9fSAtsushi Murai } 1550053cc58SBrian Somers 1560053cc58SBrian Somers const char * 1573a70c9f7SBrian Somers vj2asc(u_int32_t val) 1580053cc58SBrian Somers { 1590053cc58SBrian Somers static char asc[50]; 1600053cc58SBrian Somers 1613a70c9f7SBrian Somers sprintf(asc, "%d VJ slots %s slot compression", 1623a70c9f7SBrian Somers (int)((val>>8)&15)+1, val & 1 ? "with" : "without"); 1630053cc58SBrian Somers return asc; 1640053cc58SBrian Somers } 165