xref: /freebsd/usr.sbin/ppp/vjcomp.c (revision aa8e05197cf50f96207ce5e9cc07395ca319f3e0)
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