2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
4 * Internet Initiative Japan, Inc (IIJ)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/usr.sbin/ppp/vjcomp.c,v 1.35.2.2 2002/09/01 02:12:32 brian Exp $
29 * $DragonFly: src/usr.sbin/ppp/vjcomp.c,v 1.2 2003/06/17 04:30:01 dillon Exp $
32 #include <sys/param.h>
33 #include <netinet/in.h>
34 #include <netinet/in_systm.h>
35 #include <netinet/ip.h>
36 #include <sys/socket.h>
40 #include <string.h> /* strlen/memcpy */
49 #include "slcompress.h"
54 #include "throughput.h"
61 #include "descriptor.h"
71 #define MAX_VJHEADER 16 /* Maximum size of compressed header */
74 vj_LayerPush(struct bundle
*bundle
, struct link
*l
, struct mbuf
*bp
, int pri
,
79 u_short cproto
= bundle
->ncp
.ipcp
.peer_compproto
>> 16;
82 pip
= (struct ip
*)MBUF_CTOP(bp
);
83 if (*proto
== PROTO_IP
&& pip
->ip_p
== IPPROTO_TCP
&&
84 cproto
== PROTO_VJCOMP
) {
85 type
= sl_compress_tcp(bp
, pip
, &bundle
->ncp
.ipcp
.vj
.cslc
,
86 &bundle
->ncp
.ipcp
.vj
.slstat
,
87 bundle
->ncp
.ipcp
.peer_compproto
& 0xff);
88 log_Printf(LogDEBUG
, "vj_LayerWrite: type = %x\n", type
);
93 case TYPE_UNCOMPRESSED_TCP
:
94 *proto
= PROTO_VJUNCOMP
;
95 log_Printf(LogDEBUG
, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n");
96 m_settype(bp
, MB_VJOUT
);
99 case TYPE_COMPRESSED_TCP
:
100 *proto
= PROTO_VJCOMP
;
101 log_Printf(LogDEBUG
, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n");
102 m_settype(bp
, MB_VJOUT
);
106 log_Printf(LogERROR
, "vj_LayerPush: Unknown frame type %x\n", type
);
116 VjUncompressTcp(struct ipcp
*ipcp
, struct mbuf
*bp
, u_char type
)
120 u_char work
[MAX_HDR
+ MAX_VJHEADER
]; /* enough to hold TCP/IP header */
123 olen
= len
= m_length(bp
);
124 if (type
== TYPE_UNCOMPRESSED_TCP
) {
126 * Uncompressed packet does NOT change its size, so that we can use mbuf
127 * space for uncompression job.
129 bufp
= MBUF_CTOP(bp
);
130 len
= sl_uncompress_tcp(&bufp
, len
, type
, &ipcp
->vj
.cslc
, &ipcp
->vj
.slstat
,
131 (ipcp
->my_compproto
>> 8) & 255);
136 m_settype(bp
, MB_VJIN
);
141 * Handle compressed packet. 1) Read upto MAX_VJHEADER bytes into work
142 * space. 2) Try to uncompress it. 3) Compute amount of necessary space. 4)
143 * Copy unread data info there.
145 if (len
> MAX_VJHEADER
)
148 bufp
= work
+ MAX_HDR
;
149 bp
= mbuf_Read(bp
, bufp
, rlen
);
150 len
= sl_uncompress_tcp(&bufp
, olen
, type
, &ipcp
->vj
.cslc
, &ipcp
->vj
.slstat
,
151 (ipcp
->my_compproto
>> 8) & 255);
159 bp
= m_prepend(bp
, bufp
, len
, 0);
160 m_settype(bp
, MB_VJIN
);
166 vj_LayerPull(struct bundle
*bundle
, struct link
*l
, struct mbuf
*bp
,
173 type
= TYPE_COMPRESSED_TCP
;
174 log_Printf(LogDEBUG
, "vj_LayerPull: PROTO_VJCOMP -> PROTO_IP\n");
177 type
= TYPE_UNCOMPRESSED_TCP
;
178 log_Printf(LogDEBUG
, "vj_LayerPull: PROTO_VJUNCOMP -> PROTO_IP\n");
185 return VjUncompressTcp(&bundle
->ncp
.ipcp
, bp
, type
);
189 vj2asc(u_int32_t val
)
191 static char asc
[50]; /* The return value is used immediately */
194 snprintf(asc
, sizeof asc
, "%d VJ slots with%s slot compression",
195 (int)((val
>>8)&15)+1, val
& 1 ? "" : "out");
197 strcpy(asc
, "VJ disabled");
201 struct layer vjlayer
= { LAYER_VJ
, "vj", vj_LayerPush
, vj_LayerPull
};