xref: /freebsd/usr.sbin/ppp/vjcomp.c (revision 05c7a37afb48ddd5ee1bd921a5d46fe59cc70b15)
1 /*
2  *	       Input/Output VJ Compressed packets
3  *
4  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5  *
6  *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the Internet Initiative Japan, Inc.  The name of the
14  * IIJ may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * $Id: vjcomp.c,v 1.3 1995/05/30 03:51:02 rgrimes Exp $
21  *
22  *  TODO:
23  */
24 #include "fsm.h"
25 #include "lcpproto.h"
26 #include <netinet/in_systm.h>
27 #include <netinet/ip.h>
28 #include "slcompress.h"
29 #include "hdlc.h"
30 #include "ipcp.h"
31 
32 #define MAX_VJHEADER 16	/* Maximum size of compressed header */
33 
34 struct slcompress cslc;
35 
36 void
37 VjInit()
38 {
39   sl_compress_init(&cslc);
40 }
41 
42 void
43 SendPppFrame(bp)
44 struct mbuf *bp;
45 {
46   int type;
47   int proto;
48   int cproto = IpcpInfo.his_compproto >> 16;
49 
50 #ifdef DEBUG
51   logprintf("SendPppFrame: proto = %x\n", IpcpInfo.his_compproto);
52 #endif
53   if (cproto== PROTO_VJCOMP) {
54     type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp), &cslc, IpcpInfo.his_compproto & 0xff);
55 
56 #ifdef DEBUG
57     logprintf("type = %x\n", type);
58 #endif
59     switch (type) {
60     case TYPE_IP:
61       proto = PROTO_IP;
62       break;
63     case TYPE_UNCOMPRESSED_TCP:
64       proto = PROTO_VJUNCOMP;
65       break;
66     case TYPE_COMPRESSED_TCP:
67       proto = PROTO_VJCOMP;
68       break;
69     default:
70       logprintf("unknown type %x\n", type);
71       pfree(bp);
72       return;
73     }
74   } else
75     proto = PROTO_IP;
76   HdlcOutput(PRI_NORMAL, proto, bp);
77 }
78 
79 static struct mbuf *
80 VjUncompressTcp(bp, type)
81 struct mbuf *bp;
82 u_char type;
83 {
84   u_char *bufp;
85   int len, olen, rlen;
86   struct mbuf *nbp;
87   u_char work[MAX_HDR+MAX_VJHEADER];   /* enough to hold TCP/IP header */
88 
89   olen = len = plength(bp);
90   if (type == TYPE_UNCOMPRESSED_TCP) {
91     /*
92      * Uncompressed packet does NOT change its size, so that we can
93      * use mbuf space for uncompression job.
94      */
95     bufp = MBUF_CTOP(bp);
96     len = sl_uncompress_tcp(&bufp, len, type, &cslc);
97     if (len <= 0) {
98       pfree(bp);
99       bp = NULLBUFF;
100     }
101     return(bp);
102   }
103   /*
104    *  Handle compressed packet.
105    *    1) Read upto MAX_VJHEADER bytes into work space.
106    *	2) Try to uncompress it.
107    *    3) Compute amount of necesary space.
108    *    4) Copy unread data info there.
109    */
110   if (len > MAX_VJHEADER) len = MAX_VJHEADER;
111   rlen = len;
112   bufp = work + MAX_HDR;
113   bp = mbread(bp, bufp, rlen);
114   len = sl_uncompress_tcp(&bufp, olen, type, &cslc);
115   if (len <= 0) {
116     pfree(bp);
117     return NULLBUFF;
118   }
119   len -= olen;
120   len += rlen;
121   nbp = mballoc(len, MB_VJCOMP);
122   bcopy(bufp, MBUF_CTOP(nbp), len);
123   nbp->next = bp;
124   return(nbp);
125 }
126 
127 struct mbuf *
128 VjCompInput(bp, proto)
129 struct mbuf *bp;
130 int proto;
131 {
132   u_char type;
133 
134 #ifdef DEBUG
135   logprintf("VjCompInput (%02x):\n", proto);
136   DumpBp(bp);
137 #endif
138 
139   switch (proto) {
140   case PROTO_VJCOMP:
141     type = TYPE_COMPRESSED_TCP;
142     break;
143   case PROTO_VJUNCOMP:
144     type = TYPE_UNCOMPRESSED_TCP;
145     break;
146   default:
147     logprintf("???\n");
148     return(bp);
149   }
150   bp = VjUncompressTcp(bp, type);
151   return(bp);
152 }
153