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