1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ppp_deflate.c - interface the zlib procedures for Deflate compression 4 * and decompression (as used by gzip) to the PPP code. 5 * 6 * Copyright 1994-1998 Paul Mackerras. 7 */ 8 9 #include <linux/module.h> 10 #include <linux/slab.h> 11 #include <linux/vmalloc.h> 12 #include <linux/init.h> 13 #include <linux/string.h> 14 15 #include <linux/ppp_defs.h> 16 #include <linux/ppp-comp.h> 17 18 #include <linux/zlib.h> 19 #include <linux/unaligned.h> 20 21 /* 22 * State for a Deflate (de)compressor. 23 */ 24 struct ppp_deflate_state { 25 int seqno; 26 int w_size; 27 int unit; 28 int mru; 29 int debug; 30 z_stream strm; 31 struct compstat stats; 32 }; 33 34 #define DEFLATE_OVHD 2 /* Deflate overhead/packet */ 35 36 static void *z_comp_alloc(unsigned char *options, int opt_len); 37 static void *z_decomp_alloc(unsigned char *options, int opt_len); 38 static void z_comp_free(void *state); 39 static void z_decomp_free(void *state); 40 static int z_comp_init(void *state, unsigned char *options, 41 int opt_len, 42 int unit, int hdrlen, int debug); 43 static int z_decomp_init(void *state, unsigned char *options, 44 int opt_len, 45 int unit, int hdrlen, int mru, int debug); 46 static int z_compress(void *state, unsigned char *rptr, 47 unsigned char *obuf, 48 int isize, int osize); 49 static void z_incomp(void *state, unsigned char *ibuf, int icnt); 50 static int z_decompress(void *state, unsigned char *ibuf, 51 int isize, unsigned char *obuf, int osize); 52 static void z_comp_reset(void *state); 53 static void z_decomp_reset(void *state); 54 static void z_comp_stats(void *state, struct compstat *stats); 55 56 /** 57 * z_comp_free - free the memory used by a compressor 58 * @arg: pointer to the private state for the compressor. 59 */ 60 static void z_comp_free(void *arg) 61 { 62 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 63 64 if (state) { 65 zlib_deflateEnd(&state->strm); 66 vfree(state->strm.workspace); 67 kfree(state); 68 } 69 } 70 71 /** 72 * z_comp_alloc - allocate space for a compressor. 73 * @options: pointer to CCP option data 74 * @opt_len: length of the CCP option at @options. 75 * 76 * The @options pointer points to the a buffer containing the 77 * CCP option data for the compression being negotiated. It is 78 * formatted according to RFC1979, and describes the window 79 * size that the peer is requesting that we use in compressing 80 * data to be sent to it. 81 * 82 * Returns the pointer to the private state for the compressor, 83 * or NULL if we could not allocate enough memory. 84 */ 85 static void *z_comp_alloc(unsigned char *options, int opt_len) 86 { 87 struct ppp_deflate_state *state; 88 int w_size; 89 90 if (opt_len != CILEN_DEFLATE || 91 (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || 92 options[1] != CILEN_DEFLATE || 93 DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || 94 options[3] != DEFLATE_CHK_SEQUENCE) 95 return NULL; 96 w_size = DEFLATE_SIZE(options[2]); 97 if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) 98 return NULL; 99 100 state = kzalloc_obj(*state); 101 if (state == NULL) 102 return NULL; 103 104 state->strm.next_in = NULL; 105 state->w_size = w_size; 106 state->strm.workspace = vmalloc(zlib_deflate_workspacesize(-w_size, 8)); 107 if (state->strm.workspace == NULL) 108 goto out_free; 109 110 if (zlib_deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, 111 DEFLATE_METHOD_VAL, -w_size, 8, Z_DEFAULT_STRATEGY) 112 != Z_OK) 113 goto out_free; 114 return (void *) state; 115 116 out_free: 117 z_comp_free(state); 118 return NULL; 119 } 120 121 /** 122 * z_comp_init - initialize a previously-allocated compressor. 123 * @arg: pointer to the private state for the compressor 124 * @options: pointer to the CCP option data describing the 125 * compression that was negotiated with the peer 126 * @opt_len: length of the CCP option data at @options 127 * @unit: PPP unit number for diagnostic messages 128 * @hdrlen: ignored (present for backwards compatibility) 129 * @debug: debug flag; if non-zero, debug messages are printed. 130 * 131 * The CCP options described by @options must match the options 132 * specified when the compressor was allocated. The compressor 133 * history is reset. Returns 0 for failure (CCP options don't 134 * match) or 1 for success. 135 */ 136 static int z_comp_init(void *arg, unsigned char *options, int opt_len, 137 int unit, int hdrlen, int debug) 138 { 139 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 140 141 if (opt_len < CILEN_DEFLATE || 142 (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || 143 options[1] != CILEN_DEFLATE || 144 DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || 145 DEFLATE_SIZE(options[2]) != state->w_size || 146 options[3] != DEFLATE_CHK_SEQUENCE) 147 return 0; 148 149 state->seqno = 0; 150 state->unit = unit; 151 state->debug = debug; 152 153 zlib_deflateReset(&state->strm); 154 155 return 1; 156 } 157 158 /** 159 * z_comp_reset - reset a previously-allocated compressor. 160 * @arg: pointer to private state for the compressor. 161 * 162 * This clears the history for the compressor and makes it 163 * ready to start emitting a new compressed stream. 164 */ 165 static void z_comp_reset(void *arg) 166 { 167 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 168 169 state->seqno = 0; 170 zlib_deflateReset(&state->strm); 171 } 172 173 /** 174 * z_compress - compress a PPP packet with Deflate compression. 175 * @arg: pointer to private state for the compressor 176 * @rptr: uncompressed packet (input) 177 * @obuf: compressed packet (output) 178 * @isize: size of uncompressed packet 179 * @osize: space available at @obuf 180 * 181 * Returns the length of the compressed packet, or 0 if the 182 * packet is incompressible. 183 */ 184 static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf, 185 int isize, int osize) 186 { 187 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 188 int r, proto, off, olen, oavail; 189 unsigned char *wptr; 190 191 /* 192 * Check that the protocol is in the range we handle. 193 */ 194 proto = PPP_PROTOCOL(rptr); 195 if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) 196 return 0; 197 198 /* Don't generate compressed packets which are larger than 199 the uncompressed packet. */ 200 if (osize > isize) 201 osize = isize; 202 203 wptr = obuf; 204 205 /* 206 * Copy over the PPP header and store the 2-byte sequence number. 207 */ 208 wptr[0] = PPP_ADDRESS(rptr); 209 wptr[1] = PPP_CONTROL(rptr); 210 put_unaligned_be16(PPP_COMP, wptr + 2); 211 wptr += PPP_HDRLEN; 212 put_unaligned_be16(state->seqno, wptr); 213 wptr += DEFLATE_OVHD; 214 olen = PPP_HDRLEN + DEFLATE_OVHD; 215 state->strm.next_out = wptr; 216 state->strm.avail_out = oavail = osize - olen; 217 ++state->seqno; 218 219 off = (proto > 0xff) ? 2 : 3; /* skip 1st proto byte if 0 */ 220 rptr += off; 221 state->strm.next_in = rptr; 222 state->strm.avail_in = (isize - off); 223 224 for (;;) { 225 r = zlib_deflate(&state->strm, Z_PACKET_FLUSH); 226 if (r != Z_OK) { 227 if (state->debug) 228 printk(KERN_ERR 229 "z_compress: deflate returned %d\n", r); 230 break; 231 } 232 if (state->strm.avail_out == 0) { 233 olen += oavail; 234 state->strm.next_out = NULL; 235 state->strm.avail_out = oavail = 1000000; 236 } else { 237 break; /* all done */ 238 } 239 } 240 olen += oavail - state->strm.avail_out; 241 242 /* 243 * See if we managed to reduce the size of the packet. 244 */ 245 if (olen < isize && olen <= osize) { 246 state->stats.comp_bytes += olen; 247 state->stats.comp_packets++; 248 } else { 249 state->stats.inc_bytes += isize; 250 state->stats.inc_packets++; 251 olen = 0; 252 } 253 state->stats.unc_bytes += isize; 254 state->stats.unc_packets++; 255 256 return olen; 257 } 258 259 /** 260 * z_comp_stats - return compression statistics for a compressor 261 * or decompressor. 262 * @arg: pointer to private space for the (de)compressor 263 * @stats: pointer to a struct compstat to receive the result. 264 */ 265 static void z_comp_stats(void *arg, struct compstat *stats) 266 { 267 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 268 269 *stats = state->stats; 270 } 271 272 /** 273 * z_decomp_free - Free the memory used by a decompressor. 274 * @arg: pointer to private space for the decompressor. 275 */ 276 static void z_decomp_free(void *arg) 277 { 278 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 279 280 if (state) { 281 vfree(state->strm.workspace); 282 kfree(state); 283 } 284 } 285 286 /** 287 * z_decomp_alloc - allocate space for a decompressor. 288 * @options: pointer to CCP option data 289 * @opt_len: length of the CCP option at @options. 290 * 291 * The @options pointer points to the a buffer containing the 292 * CCP option data for the compression being negotiated. It is 293 * formatted according to RFC1979, and describes the window 294 * size that we are requesting the peer to use in compressing 295 * data to be sent to us. 296 * 297 * Returns the pointer to the private state for the decompressor, 298 * or NULL if we could not allocate enough memory. 299 */ 300 static void *z_decomp_alloc(unsigned char *options, int opt_len) 301 { 302 struct ppp_deflate_state *state; 303 int w_size; 304 305 if (opt_len != CILEN_DEFLATE || 306 (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || 307 options[1] != CILEN_DEFLATE || 308 DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || 309 options[3] != DEFLATE_CHK_SEQUENCE) 310 return NULL; 311 w_size = DEFLATE_SIZE(options[2]); 312 if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) 313 return NULL; 314 315 state = kzalloc_obj(*state); 316 if (state == NULL) 317 return NULL; 318 319 state->w_size = w_size; 320 state->strm.next_out = NULL; 321 state->strm.workspace = vmalloc(zlib_inflate_workspacesize()); 322 if (state->strm.workspace == NULL) 323 goto out_free; 324 325 if (zlib_inflateInit2(&state->strm, -w_size) != Z_OK) 326 goto out_free; 327 return (void *) state; 328 329 out_free: 330 z_decomp_free(state); 331 return NULL; 332 } 333 334 /** 335 * z_decomp_init - initialize a previously-allocated decompressor. 336 * @arg: pointer to the private state for the decompressor 337 * @options: pointer to the CCP option data describing the 338 * compression that was negotiated with the peer 339 * @opt_len: length of the CCP option data at @options 340 * @unit: PPP unit number for diagnostic messages 341 * @hdrlen: ignored (present for backwards compatibility) 342 * @mru: maximum length of decompressed packets 343 * @debug: debug flag; if non-zero, debug messages are printed. 344 * 345 * The CCP options described by @options must match the options 346 * specified when the decompressor was allocated. The decompressor 347 * history is reset. Returns 0 for failure (CCP options don't 348 * match) or 1 for success. 349 */ 350 static int z_decomp_init(void *arg, unsigned char *options, int opt_len, 351 int unit, int hdrlen, int mru, int debug) 352 { 353 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 354 355 if (opt_len < CILEN_DEFLATE || 356 (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || 357 options[1] != CILEN_DEFLATE || 358 DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || 359 DEFLATE_SIZE(options[2]) != state->w_size || 360 options[3] != DEFLATE_CHK_SEQUENCE) 361 return 0; 362 363 state->seqno = 0; 364 state->unit = unit; 365 state->debug = debug; 366 state->mru = mru; 367 368 zlib_inflateReset(&state->strm); 369 370 return 1; 371 } 372 373 /** 374 * z_decomp_reset - reset a previously-allocated decompressor. 375 * @arg: pointer to private state for the decompressor. 376 * 377 * This clears the history for the decompressor and makes it 378 * ready to receive a new compressed stream. 379 */ 380 static void z_decomp_reset(void *arg) 381 { 382 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 383 384 state->seqno = 0; 385 zlib_inflateReset(&state->strm); 386 } 387 388 /** 389 * z_decompress - decompress a Deflate-compressed packet. 390 * @arg: pointer to private state for the decompressor 391 * @ibuf: pointer to input (compressed) packet data 392 * @isize: length of input packet 393 * @obuf: pointer to space for output (decompressed) packet 394 * @osize: amount of space available at @obuf 395 * 396 * Because of patent problems, we return DECOMP_ERROR for errors 397 * found by inspecting the input data and for system problems, but 398 * DECOMP_FATALERROR for any errors which could possibly be said to 399 * be being detected "after" decompression. For DECOMP_ERROR, 400 * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be 401 * infringing a patent of Motorola's if we do, so we take CCP down 402 * instead. 403 * 404 * Given that the frame has the correct sequence number and a good FCS, 405 * errors such as invalid codes in the input most likely indicate a 406 * bug, so we return DECOMP_FATALERROR for them in order to turn off 407 * compression, even though they are detected by inspecting the input. 408 */ 409 static int z_decompress(void *arg, unsigned char *ibuf, int isize, 410 unsigned char *obuf, int osize) 411 { 412 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 413 int olen, seq, r; 414 int decode_proto, overflow; 415 unsigned char overflow_buf[1]; 416 417 if (isize <= PPP_HDRLEN + DEFLATE_OVHD) { 418 if (state->debug) 419 printk(KERN_DEBUG "z_decompress%d: short pkt (%d)\n", 420 state->unit, isize); 421 return DECOMP_ERROR; 422 } 423 424 /* Check the sequence number. */ 425 seq = get_unaligned_be16(ibuf + PPP_HDRLEN); 426 if (seq != (state->seqno & 0xffff)) { 427 if (state->debug) 428 printk(KERN_DEBUG "z_decompress%d: bad seq # %d, expected %d\n", 429 state->unit, seq, state->seqno & 0xffff); 430 return DECOMP_ERROR; 431 } 432 ++state->seqno; 433 434 /* 435 * Fill in the first part of the PPP header. The protocol field 436 * comes from the decompressed data. 437 */ 438 obuf[0] = PPP_ADDRESS(ibuf); 439 obuf[1] = PPP_CONTROL(ibuf); 440 obuf[2] = 0; 441 442 /* 443 * Set up to call inflate. We set avail_out to 1 initially so we can 444 * look at the first byte of the output and decide whether we have 445 * a 1-byte or 2-byte protocol field. 446 */ 447 state->strm.next_in = ibuf + PPP_HDRLEN + DEFLATE_OVHD; 448 state->strm.avail_in = isize - (PPP_HDRLEN + DEFLATE_OVHD); 449 state->strm.next_out = obuf + 3; 450 state->strm.avail_out = 1; 451 decode_proto = 1; 452 overflow = 0; 453 454 /* 455 * Call inflate, supplying more input or output as needed. 456 */ 457 for (;;) { 458 r = zlib_inflate(&state->strm, Z_PACKET_FLUSH); 459 if (r != Z_OK) { 460 if (state->debug) 461 printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n", 462 state->unit, r, (state->strm.msg? state->strm.msg: "")); 463 return DECOMP_FATALERROR; 464 } 465 if (state->strm.avail_out != 0) 466 break; /* all done */ 467 if (decode_proto) { 468 state->strm.avail_out = osize - PPP_HDRLEN; 469 if ((obuf[3] & 1) == 0) { 470 /* 2-byte protocol field */ 471 obuf[2] = obuf[3]; 472 --state->strm.next_out; 473 ++state->strm.avail_out; 474 } 475 decode_proto = 0; 476 } else if (!overflow) { 477 /* 478 * We've filled up the output buffer; the only way to 479 * find out whether inflate has any more characters 480 * left is to give it another byte of output space. 481 */ 482 state->strm.next_out = overflow_buf; 483 state->strm.avail_out = 1; 484 overflow = 1; 485 } else { 486 if (state->debug) 487 printk(KERN_DEBUG "z_decompress%d: ran out of mru\n", 488 state->unit); 489 return DECOMP_FATALERROR; 490 } 491 } 492 493 if (decode_proto) { 494 if (state->debug) 495 printk(KERN_DEBUG "z_decompress%d: didn't get proto\n", 496 state->unit); 497 return DECOMP_ERROR; 498 } 499 500 olen = osize + overflow - state->strm.avail_out; 501 state->stats.unc_bytes += olen; 502 state->stats.unc_packets++; 503 state->stats.comp_bytes += isize; 504 state->stats.comp_packets++; 505 506 return olen; 507 } 508 509 /** 510 * z_incomp - add incompressible input data to the history. 511 * @arg: pointer to private state for the decompressor 512 * @ibuf: pointer to input packet data 513 * @icnt: length of input data. 514 */ 515 static void z_incomp(void *arg, unsigned char *ibuf, int icnt) 516 { 517 struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; 518 int proto, r; 519 520 /* 521 * Check that the protocol is one we handle. 522 */ 523 proto = PPP_PROTOCOL(ibuf); 524 if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) 525 return; 526 527 ++state->seqno; 528 529 /* 530 * We start at the either the 1st or 2nd byte of the protocol field, 531 * depending on whether the protocol value is compressible. 532 */ 533 state->strm.next_in = ibuf + 3; 534 state->strm.avail_in = icnt - 3; 535 if (proto > 0xff) { 536 --state->strm.next_in; 537 ++state->strm.avail_in; 538 } 539 540 r = zlib_inflateIncomp(&state->strm); 541 if (r != Z_OK) { 542 /* gak! */ 543 if (state->debug) { 544 printk(KERN_DEBUG "z_incomp%d: inflateIncomp returned %d (%s)\n", 545 state->unit, r, (state->strm.msg? state->strm.msg: "")); 546 } 547 return; 548 } 549 550 /* 551 * Update stats. 552 */ 553 state->stats.inc_bytes += icnt; 554 state->stats.inc_packets++; 555 state->stats.unc_bytes += icnt; 556 state->stats.unc_packets++; 557 } 558 559 /************************************************************* 560 * Module interface table 561 *************************************************************/ 562 563 /* These are in ppp_generic.c */ 564 extern int ppp_register_compressor (struct compressor *cp); 565 extern void ppp_unregister_compressor (struct compressor *cp); 566 567 /* 568 * Procedures exported to if_ppp.c. 569 */ 570 static struct compressor ppp_deflate = { 571 .compress_proto = CI_DEFLATE, 572 .comp_alloc = z_comp_alloc, 573 .comp_free = z_comp_free, 574 .comp_init = z_comp_init, 575 .comp_reset = z_comp_reset, 576 .compress = z_compress, 577 .comp_stat = z_comp_stats, 578 .decomp_alloc = z_decomp_alloc, 579 .decomp_free = z_decomp_free, 580 .decomp_init = z_decomp_init, 581 .decomp_reset = z_decomp_reset, 582 .decompress = z_decompress, 583 .incomp = z_incomp, 584 .decomp_stat = z_comp_stats, 585 .owner = THIS_MODULE 586 }; 587 588 static struct compressor ppp_deflate_draft = { 589 .compress_proto = CI_DEFLATE_DRAFT, 590 .comp_alloc = z_comp_alloc, 591 .comp_free = z_comp_free, 592 .comp_init = z_comp_init, 593 .comp_reset = z_comp_reset, 594 .compress = z_compress, 595 .comp_stat = z_comp_stats, 596 .decomp_alloc = z_decomp_alloc, 597 .decomp_free = z_decomp_free, 598 .decomp_init = z_decomp_init, 599 .decomp_reset = z_decomp_reset, 600 .decompress = z_decompress, 601 .incomp = z_incomp, 602 .decomp_stat = z_comp_stats, 603 .owner = THIS_MODULE 604 }; 605 606 static int __init deflate_init(void) 607 { 608 int rc; 609 610 rc = ppp_register_compressor(&ppp_deflate); 611 if (rc) 612 return rc; 613 614 rc = ppp_register_compressor(&ppp_deflate_draft); 615 if (rc) { 616 ppp_unregister_compressor(&ppp_deflate); 617 return rc; 618 } 619 620 pr_info("PPP Deflate Compression module registered\n"); 621 return 0; 622 } 623 624 static void __exit deflate_cleanup(void) 625 { 626 ppp_unregister_compressor(&ppp_deflate); 627 ppp_unregister_compressor(&ppp_deflate_draft); 628 } 629 630 module_init(deflate_init); 631 module_exit(deflate_cleanup); 632 MODULE_DESCRIPTION("PPP Deflate compression module"); 633 MODULE_LICENSE("Dual BSD/GPL"); 634 MODULE_ALIAS("ppp-compress-" __stringify(CI_DEFLATE)); 635 MODULE_ALIAS("ppp-compress-" __stringify(CI_DEFLATE_DRAFT)); 636