xref: /freebsd/usr.sbin/ppp/vjcomp.c (revision 17ee9d00bc1ae1e598c38f25826f861e4bc6c3ce)
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:$
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 SendPppFlame(pri, bp)
44 int pri;
45 struct mbuf *bp;
46 {
47   int type;
48   int proto;
49   int cproto = IpcpInfo.his_compproto >> 16;
50 
51 #ifdef DEBUG
52   logprintf("SendPppFlame: proto = %x\n", IpcpInfo.his_compproto);
53 #endif
54   if (cproto== PROTO_VJCOMP) {
55     type = sl_compress_tcp(bp, MBUF_CTOP(bp), &cslc, IpcpInfo.his_compproto & 0xff);
56 
57 #ifdef DEBUG
58     logprintf("type = %x\n", type);
59 #endif
60     switch (type) {
61     case TYPE_IP:
62       proto = PROTO_IP;
63       break;
64     case TYPE_UNCOMPRESSED_TCP:
65       proto = PROTO_VJUNCOMP;
66       break;
67     case TYPE_COMPRESSED_TCP:
68       proto = PROTO_VJCOMP;
69       break;
70     default:
71       logprintf("unknown type %x\n", type);
72       pfree(bp);
73       return;
74     }
75   } else
76     proto = PROTO_IP;
77   HdlcOutput(pri, proto, bp);
78 }
79 
80 static struct mbuf *
81 VjUncompressTcp(bp, type)
82 struct mbuf *bp;
83 u_char type;
84 {
85   u_char *bufp;
86   int len, olen, rlen;
87   struct mbuf *nbp;
88   u_char work[MAX_HDR+MAX_VJHEADER];   /* enough to hold TCP/IP header */
89 
90   olen = len = plength(bp);
91   if (type == TYPE_UNCOMPRESSED_TCP) {
92     /*
93      * Uncompressed packet does NOT change its size, so that we can
94      * use mbuf space for uncompression job.
95      */
96     bufp = MBUF_CTOP(bp);
97     len = sl_uncompress_tcp(&bufp, len, type, &cslc);
98     return(bp);
99   }
100   /*
101    *  Handle compressed packet.
102    *    1) Read upto MAX_VJHEADER bytes into work space.
103    *	2) Try to uncompress it.
104    *    3) Compute amount of necesary space.
105    *    4) Copy unread data info there.
106    */
107   if (len > MAX_VJHEADER) len = MAX_VJHEADER;
108   rlen = len;
109   bufp = work + MAX_HDR;
110   bp = mbread(bp, bufp, rlen);
111   len = sl_uncompress_tcp(&bufp, olen, type, &cslc);
112   len -= olen;
113   len += rlen;
114   nbp = mballoc(len, MB_VJCOMP);
115   bcopy(bufp, MBUF_CTOP(nbp), len);
116   nbp->next = bp;
117   return(nbp);
118 }
119 
120 struct mbuf *
121 VjCompInput(bp, proto)
122 struct mbuf *bp;
123 int proto;
124 {
125   u_char type;
126 
127 #ifdef DEBUG
128   logprintf("VjCompInput (%02x):\n", proto);
129   DumpBp(bp);
130 #endif
131 
132   switch (proto) {
133   case PROTO_VJCOMP:
134     type = TYPE_COMPRESSED_TCP;
135     break;
136   case PROTO_VJUNCOMP:
137     type = TYPE_UNCOMPRESSED_TCP;
138     break;
139   default:
140     logprintf("???\n");
141     return(bp);
142   }
143   bp = VjUncompressTcp(bp, type);
144   return(bp);
145 }
146