2 * IPCOMP zlib interface code.
3 * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
4 * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 char ipcomp_c_version
[] = "RCSID $Id: ipcomp.c,v 1.2 2004/06/13 19:57:49 as Exp $";
21 #include <linux/config.h>
22 #include <linux/version.h>
24 #define __NO_VERSION__
25 #include <linux/module.h>
26 #include <linux/kernel.h> /* printk() */
28 #include "freeswan/ipsec_param.h"
31 # include <linux/slab.h> /* kmalloc() */
32 #else /* MALLOC_SLAB */
33 # include <linux/malloc.h> /* kmalloc() */
34 #endif /* MALLOC_SLAB */
35 #include <linux/errno.h> /* error codes */
36 #include <linux/types.h>
37 #include <linux/netdevice.h>
39 #include <linux/skbuff.h>
41 #include <linux/netdevice.h> /* struct device, and other headers */
42 #include <linux/etherdevice.h> /* eth_type_trans */
43 #include <linux/ip.h> /* struct iphdr */
44 #include <linux/skbuff.h>
50 # include <asm/uaccess.h>
51 # include <linux/in6.h>
52 # define proto_priv cb
54 #include <asm/checksum.h>
57 #include "freeswan/radij.h"
58 #include "freeswan/ipsec_encap.h"
59 #include "freeswan/ipsec_sa.h"
61 #include "freeswan/ipsec_xform.h"
62 #include "freeswan/ipsec_tunnel.h"
63 #include "freeswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
64 #include "freeswan/ipcomp.h"
65 #include "zlib/zlib.h"
66 #include "zlib/zutil.h"
68 #include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
70 #ifdef CONFIG_IPSEC_DEBUG
71 int sysctl_ipsec_debug_ipcomp
= 0;
72 #endif /* CONFIG_IPSEC_DEBUG */
75 struct sk_buff
*skb_copy_ipcomp(struct sk_buff
*skb
, int data_growth
, int gfp_mask
);
78 voidpf
my_zcalloc(voidpf opaque
, uInt items
, uInt size
)
80 return (voidpf
) kmalloc(items
*size
, GFP_ATOMIC
);
84 void my_zfree(voidpf opaque
, voidpf address
)
89 struct sk_buff
*skb_compress(struct sk_buff
*skb
, struct ipsec_sa
*ips
, unsigned int *flags
)
92 unsigned int iphlen
, pyldsz
, cpyldsz
;
93 unsigned char *buffer
;
97 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
98 "klips_debug:skb_compress: .\n");
101 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
102 "klips_debug:skb_compress: "
103 "passed in NULL skb, returning ERROR.\n");
105 *flags
|= IPCOMP_PARMERROR
;
111 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
112 "klips_debug:skb_compress: "
113 "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
115 *flags
|= IPCOMP_PARMERROR
;
121 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
122 "klips_debug:skb_compress: "
123 "passed in NULL flags, returning ERROR.\n");
124 ipsec_kfree_skb(skb
);
134 switch (iph
->protocol
) {
138 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
139 "klips_debug:skb_compress: "
140 "skipping compression of packet with ip protocol %d.\n",
142 *flags
|= IPCOMP_UNCOMPRESSABLE
;
146 /* Don't compress packets already fragmented */
147 if (iph
->frag_off
& __constant_htons(IP_MF
| IP_OFFSET
)) {
148 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
149 "klips_debug:skb_compress: "
150 "skipping compression of fragmented packet.\n");
151 *flags
|= IPCOMP_UNCOMPRESSABLE
;
155 iphlen
= iph
->ihl
<< 2;
156 pyldsz
= ntohs(iph
->tot_len
) - iphlen
;
158 /* Don't compress less than 90 bytes (rfc 2394) */
160 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
161 "klips_debug:skb_compress: "
162 "skipping compression of tiny packet, len=%d.\n",
164 *flags
|= IPCOMP_UNCOMPRESSABLE
;
168 /* Adaptive decision */
169 if (ips
->ips_comp_adapt_skip
) {
170 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
171 "klips_debug:skb_compress: "
172 "skipping compression: ips_comp_adapt_skip=%d.\n",
173 ips
->ips_comp_adapt_skip
);
174 ips
->ips_comp_adapt_skip
--;
175 *flags
|= IPCOMP_UNCOMPRESSABLE
;
179 zs
.zalloc
= my_zcalloc
;
183 /* We want to use deflateInit2 because we don't want the adler
185 zresult
= deflateInit2(&zs
, Z_DEFAULT_COMPRESSION
, Z_DEFLATED
, -11,
186 DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
);
187 if (zresult
!= Z_OK
) {
188 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
189 "klips_error:skb_compress: "
190 "deflateInit2() returned error %d (%s), "
191 "skipping compression.\n",
193 zs
.msg
? zs
.msg
: zError(zresult
));
194 *flags
|= IPCOMP_COMPRESSIONERROR
;
199 /* Max output size. Result should be max this size.
200 * Implementation specific tweak:
201 * If it's not at least 32 bytes and 6.25% smaller than
202 * the original packet, it's probably not worth wasting
203 * the receiver's CPU cycles decompressing it.
204 * Your mileage may vary.
206 cpyldsz
= pyldsz
- sizeof(struct ipcomphdr
) - (pyldsz
<= 512 ? 32 : pyldsz
>> 4);
208 buffer
= kmalloc(cpyldsz
, GFP_ATOMIC
);
210 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
211 "klips_error:skb_compress: "
212 "unable to kmalloc(%d, GFP_ATOMIC), "
213 "skipping compression.\n",
215 *flags
|= IPCOMP_COMPRESSIONERROR
;
220 #ifdef CONFIG_IPSEC_DEBUG
221 if(sysctl_ipsec_debug_ipcomp
&& sysctl_ipsec_debug_verbose
) {
225 c
= (__u8
*)iph
+ iphlen
;
226 for(i
= 0; i
< pyldsz
; i
++, c
++) {
228 printk(KERN_INFO
"skb_compress: before:");
231 if(!((i
+ 1) % 16)) {
239 #endif /* CONFIG_IPSEC_DEBUG */
241 zs
.next_in
= (char *) iph
+ iphlen
; /* start of payload */
242 zs
.avail_in
= pyldsz
;
243 zs
.next_out
= buffer
; /* start of compressed payload */
244 zs
.avail_out
= cpyldsz
;
246 /* Finish compression in one step */
247 zresult
= deflate(&zs
, Z_FINISH
);
249 /* Free all dynamically allocated buffers */
251 if (zresult
!= Z_STREAM_END
) {
252 *flags
|= IPCOMP_UNCOMPRESSABLE
;
255 /* Adjust adaptive counters */
256 if (++(ips
->ips_comp_adapt_tries
) == IPCOMP_ADAPT_INITIAL_TRIES
) {
257 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
258 "klips_debug:skb_compress: "
259 "first %d packets didn't compress, "
260 "skipping next %d\n",
261 IPCOMP_ADAPT_INITIAL_TRIES
,
262 IPCOMP_ADAPT_INITIAL_SKIP
);
263 ips
->ips_comp_adapt_skip
= IPCOMP_ADAPT_INITIAL_SKIP
;
265 else if (ips
->ips_comp_adapt_tries
== IPCOMP_ADAPT_INITIAL_TRIES
+ IPCOMP_ADAPT_SUBSEQ_TRIES
) {
266 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
267 "klips_debug:skb_compress: "
268 "next %d packets didn't compress, "
269 "skipping next %d\n",
270 IPCOMP_ADAPT_SUBSEQ_TRIES
,
271 IPCOMP_ADAPT_SUBSEQ_SKIP
);
272 ips
->ips_comp_adapt_skip
= IPCOMP_ADAPT_SUBSEQ_SKIP
;
273 ips
->ips_comp_adapt_tries
= IPCOMP_ADAPT_INITIAL_TRIES
;
279 /* resulting compressed size */
280 cpyldsz
-= zs
.avail_out
;
282 /* Insert IPCOMP header */
283 ((struct ipcomphdr
*) ((char*) iph
+ iphlen
))->ipcomp_nh
= iph
->protocol
;
284 ((struct ipcomphdr
*) ((char*) iph
+ iphlen
))->ipcomp_flags
= 0;
285 /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
286 for internal reference only. */
287 ((struct ipcomphdr
*) (((char*)iph
) + iphlen
))->ipcomp_cpi
= htons((__u16
)(ntohl(ips
->ips_said
.spi
) & 0x0000ffff));
288 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
289 "klips_debug:skb_compress: "
290 "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
291 ntohl(ips
->ips_said
.spi
),
292 ntohl(ips
->ips_said
.spi
) & 0x0000ffff,
293 ntohs(((struct ipcomphdr
*)(((char*)iph
)+iphlen
))->ipcomp_cpi
),
297 /* Update IP header */
298 iph
->protocol
= IPPROTO_COMP
;
299 iph
->tot_len
= htons(iphlen
+ sizeof(struct ipcomphdr
) + cpyldsz
);
300 #if 1 /* XXX checksum is done by ipsec_tunnel ? */
302 iph
->check
= ip_fast_csum((char *) iph
, iph
->ihl
);
305 /* Copy compressed payload */
306 memcpy((char *) iph
+ iphlen
+ sizeof(struct ipcomphdr
),
311 /* Update skb length/tail by "unputting" the shrinkage */
313 cpyldsz
+ sizeof(struct ipcomphdr
) - pyldsz
);
315 #ifdef CONFIG_IPSEC_DEBUG
316 if(sysctl_ipsec_debug_ipcomp
&& sysctl_ipsec_debug_verbose
) {
320 c
= (__u8
*)iph
+ iphlen
+ sizeof(struct ipcomphdr
);
321 for(i
= 0; i
< cpyldsz
; i
++, c
++) {
323 printk(KERN_INFO
"skb_compress: result:");
326 if(!((i
+ 1) % 16)) {
334 #endif /* CONFIG_IPSEC_DEBUG */
336 ips
->ips_comp_adapt_skip
= 0;
337 ips
->ips_comp_adapt_tries
= 0;
342 struct sk_buff
*skb_decompress(struct sk_buff
*skb
, struct ipsec_sa
*ips
, unsigned int *flags
)
344 struct sk_buff
*nskb
= NULL
;
346 /* original ip header */
347 struct iphdr
*oiph
, *iph
;
348 unsigned int iphlen
, pyldsz
, cpyldsz
;
352 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
353 "klips_debug:skb_decompress: .\n");
356 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
357 "klips_error:skb_decompress: "
358 "passed in NULL skb, returning ERROR.\n");
359 if (flags
) *flags
|= IPCOMP_PARMERROR
;
363 if(!ips
&& sysctl_ipsec_inbound_policy_check
) {
364 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
365 "klips_error:skb_decompress: "
366 "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
367 if (flags
) *flags
|= IPCOMP_PARMERROR
;
372 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
373 "klips_error:skb_decompress: "
374 "passed in NULL flags, returning ERROR.\n");
375 ipsec_kfree_skb(skb
);
385 iphlen
= oiph
->ihl
<< 2;
387 if (oiph
->protocol
!= IPPROTO_COMP
) {
388 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
389 "klips_error:skb_decompress: "
390 "called with non-IPCOMP packet (protocol=%d),"
391 "skipping decompression.\n",
393 *flags
|= IPCOMP_PARMERROR
;
397 if ( (((struct ipcomphdr
*)((char*) oiph
+ iphlen
))->ipcomp_flags
!= 0)
398 || ((((struct ipcomphdr
*) ((char*) oiph
+ iphlen
))->ipcomp_cpi
399 != htons(SADB_X_CALG_DEFLATE
))
400 && sysctl_ipsec_inbound_policy_check
401 && (!ips
|| (ips
&& (ips
->ips_encalg
!= SADB_X_CALG_DEFLATE
)))) ) {
402 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
403 "klips_error:skb_decompress: "
404 "called with incompatible IPCOMP packet (flags=%d, "
405 "cpi=%d), ips-compalg=%d, skipping decompression.\n",
406 ntohs(((struct ipcomphdr
*) ((char*) oiph
+ iphlen
))->ipcomp_flags
),
407 ntohs(((struct ipcomphdr
*) ((char*) oiph
+ iphlen
))->ipcomp_cpi
),
408 ips
? ips
->ips_encalg
: 0);
409 *flags
|= IPCOMP_PARMERROR
;
414 if (ntohs(oiph
->frag_off
) & ~0x4000) {
415 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
416 "klips_error:skb_decompress: "
417 "called with fragmented IPCOMP packet, "
418 "skipping decompression.\n");
419 *flags
|= IPCOMP_PARMERROR
;
423 /* original compressed payload size */
424 cpyldsz
= ntohs(oiph
->tot_len
) - iphlen
- sizeof(struct ipcomphdr
);
426 zs
.zalloc
= my_zcalloc
;
430 zs
.next_in
= (char *) oiph
+ iphlen
+ sizeof(struct ipcomphdr
);
431 zs
.avail_in
= cpyldsz
;
433 /* Maybe we should be a bit conservative about memory
434 requirements and use inflateInit2 */
435 /* Beware, that this might make us unable to decompress packets
436 from other implementations - HINT: check PGPnet source code */
437 /* We want to use inflateInit2 because we don't want the adler
439 zresult
= inflateInit2(&zs
, -15);
440 if (zresult
!= Z_OK
) {
441 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
442 "klips_error:skb_decompress: "
443 "inflateInit2() returned error %d (%s), "
444 "skipping decompression.\n",
446 zs
.msg
? zs
.msg
: zError(zresult
));
447 *flags
|= IPCOMP_DECOMPRESSIONERROR
;
452 /* We have no way of knowing the exact length of the resulting
453 decompressed output before we have actually done the decompression.
454 For now, we guess that the packet will not be bigger than the
455 attached ipsec device's mtu or 16260, whichever is biggest.
456 This may be wrong, since the sender's mtu may be bigger yet.
457 XXX This must be dealt with later XXX
460 /* max payload size */
461 pyldsz
= skb
->dev
? (skb
->dev
->mtu
< 16260 ? 16260 : skb
->dev
->mtu
)
463 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
464 "klips_debug:skb_decompress: "
465 "max payload size: %d\n", pyldsz
);
467 while (pyldsz
> (cpyldsz
+ sizeof(struct ipcomphdr
)) &&
468 (nskb
= skb_copy_ipcomp(skb
,
469 pyldsz
- cpyldsz
- sizeof(struct ipcomphdr
),
470 GFP_ATOMIC
)) == NULL
) {
471 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
472 "klips_error:skb_decompress: "
473 "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
474 "trying with less payload size.\n",
475 (int)(pyldsz
- cpyldsz
- sizeof(struct ipcomphdr
)));
480 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
481 "klips_error:skb_decompress: "
482 "unable to allocate memory, dropping packet.\n");
483 *flags
|= IPCOMP_DECOMPRESSIONERROR
;
489 #ifdef CONFIG_IPSEC_DEBUG
490 if(sysctl_ipsec_debug_ipcomp
&& sysctl_ipsec_debug_verbose
) {
494 c
= (__u8
*)oiph
+ iphlen
+ sizeof(struct ipcomphdr
);
495 for(i
= 0; i
< cpyldsz
; i
++, c
++) {
497 printk(KERN_INFO
"skb_decompress: before:");
500 if(!((i
+ 1) % 16)) {
508 #endif /* CONFIG_IPSEC_DEBUG */
515 zs
.next_out
= (char *)iph
+ iphlen
;
516 zs
.avail_out
= pyldsz
;
518 zresult
= inflate(&zs
, Z_SYNC_FLUSH
);
520 /* work around a bug in zlib, which sometimes wants to taste an extra
521 * byte when being used in the (undocumented) raw deflate mode.
523 if (zresult
== Z_OK
&& !zs
.avail_in
&& zs
.avail_out
) {
526 zs
.next_in
= &zerostuff
;
528 zresult
= inflate(&zs
, Z_FINISH
);
532 if (zresult
!= Z_STREAM_END
) {
533 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
534 "klips_error:skb_decompress: "
535 "inflate() returned error %d (%s), "
536 "skipping decompression.\n",
538 zs
.msg
? zs
.msg
: zError(zresult
));
539 *flags
|= IPCOMP_DECOMPRESSIONERROR
;
540 ipsec_kfree_skb(nskb
);
545 /* Update IP header */
546 /* resulting decompressed size */
547 pyldsz
-= zs
.avail_out
;
548 iph
->tot_len
= htons(iphlen
+ pyldsz
);
549 iph
->protocol
= ((struct ipcomphdr
*) ((char*) oiph
+ iphlen
))->ipcomp_nh
;
550 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
551 "klips_debug:skb_decompress: "
552 "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
553 ips
? ntohl(ips
->ips_said
.spi
) : 0,
554 ips
? ntohl(ips
->ips_said
.spi
) & 0x0000ffff : 0,
555 ntohs(((struct ipcomphdr
*)(((char*)oiph
)+iphlen
))->ipcomp_cpi
),
560 #if 1 /* XXX checksum is done by ipsec_rcv ? */
562 iph
->check
= ip_fast_csum((char*) iph
, iph
->ihl
);
565 /* Update skb length/tail by "unputting" the unused data area */
566 skb_put(nskb
, -zs
.avail_out
);
568 ipsec_kfree_skb(skb
);
570 if (iph
->protocol
== IPPROTO_COMP
)
572 #ifdef CONFIG_IPSEC_DEBUG
573 if(sysctl_ipsec_debug_ipcomp
)
574 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
575 "klips_debug:skb_decompress: "
576 "Eh? inner packet is also compressed, dropping.\n");
577 #endif /* CONFIG_IPSEC_DEBUG */
579 ipsec_kfree_skb(nskb
);
583 #ifdef CONFIG_IPSEC_DEBUG
584 if(sysctl_ipsec_debug_ipcomp
&& sysctl_ipsec_debug_verbose
) {
588 c
= (__u8
*)iph
+ iphlen
;
589 for(i
= 0; i
< pyldsz
; i
++, c
++) {
591 printk(KERN_INFO
"skb_decompress: result:");
594 if(!((i
+ 1) % 16)) {
602 #endif /* CONFIG_IPSEC_DEBUG */
608 /* this is derived from skb_copy() in linux 2.2.14 */
609 /* May be incompatible with other kernel versions!! */
611 struct sk_buff
*skb_copy_ipcomp(struct sk_buff
*skb
, int data_growth
, int gfp_mask
)
615 unsigned long offset
;
619 KLIPS_PRINT(sysctl_ipsec_debug_ipcomp
,
620 "klips_debug:skb_copy_ipcomp: "
621 "passed in NULL skb, returning NULL.\n");
626 * Allocate the copy buffer
634 if (!iph
) return NULL
;
635 iphlen
= iph
->ihl
<< 2;
637 n
=alloc_skb(skb
->end
- skb
->head
+ data_growth
, gfp_mask
);
642 * Shift between the two data areas in bytes
645 offset
=n
->head
-skb
->head
;
647 /* Set the data pointer */
648 skb_reserve(n
,skb
->data
-skb
->head
);
649 /* Set the tail pointer and length */
650 skb_put(n
,skb
->len
+data_growth
);
651 /* Copy the bytes up to and including the ip header */
654 ((char *)iph
- (char *)skb
->head
) + iphlen
);
661 n
->h
.raw
=skb
->h
.raw
+offset
;
664 n
->protocol
=skb
->protocol
;
667 n
->priority
=skb
->priority
;
668 n
->dst
=dst_clone(skb
->dst
);
669 n
->nh
.raw
=skb
->nh
.raw
+offset
;
672 #endif /* NETDEV_23 */
673 atomic_set(&n
->users
, 1);
674 n
->destructor
= NULL
;
675 n
->security
=skb
->security
;
676 memcpy(n
->cb
, skb
->cb
, sizeof(skb
->cb
));
677 #ifdef CONFIG_IP_FIREWALL
678 n
->fwmark
= skb
->fwmark
;
683 n
->ip_hdr
=(struct iphdr
*)(((char *)skb
->ip_hdr
)+offset
);
688 n
->end_seq
=skb
->end_seq
;
689 n
->ack_seq
=skb
->ack_seq
;
696 memcpy(n
->proto_priv
, skb
->proto_priv
, sizeof(skb
->proto_priv
));
699 n
->mac
.raw
=skb
->mac
.raw
+offset
;
704 #endif /* !NETDEV_23 */
705 n
->pkt_type
=skb
->pkt_type
;
707 n
->pkt_bridged
=skb
->pkt_bridged
;
708 #endif /* NETDEV_23 */
711 #ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
712 #if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
713 n
->shapelatency
=skb
->shapelatency
; /* Latency on frame */
714 n
->shapeclock
=skb
->shapeclock
; /* Time it should go out */
715 n
->shapelen
=skb
->shapelen
; /* Frame length in clocks */
716 n
->shapestamp
=skb
->shapestamp
; /* Stamp for shaper */
717 n
->shapepend
=skb
->shapepend
; /* Pending */
718 #endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
719 #endif /* NETDEV_23 */
721 n
->private.ifield
=skb
->private.ifield
;
722 #endif /* CONFIG_HIPPI */