1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*- 2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 1989, 1993, 1994 3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * The Regents of the University of California. All rights reserved. 4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without 6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions 7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met: 8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright 9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * notice, this list of conditions and the following disclaimer. 10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright 11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * notice, this list of conditions and the following disclaimer in the 12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * documentation and/or other materials provided with the distribution. 13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 3. Neither the name of the University nor the names of its contributors 14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * may be used to endorse or promote products derived from this software 15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * without specific prior written permission. 16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE. 28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * @(#)slcompress.c 8.2 (Berkeley) 4/16/94 30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* 33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Routines to compress and uncompess tcp packets (for transmission 34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * over low speed serial lines. 35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: 37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * - Initial distribution. 38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/slcompress.c,v 1.39.26.1 2010/12/21 17:10:29 kensmith Exp $ 40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/param.h> 43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in_systm.h> 44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in.h> 45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/tcp.h> 46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/ip.h> 47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/socket.h> 48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h> 49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdarg.h> 51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdio.h> 52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h> 53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h> 54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h" 56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h" 57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "command.h" 58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h" 59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h" 60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "slcompress.h" 61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h" 62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "prompt.h" 63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h" 64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h" 65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h" 66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iplist.h" 67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h" 68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h" 69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncpaddr.h" 70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipcp.h" 71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "filter.h" 72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h" 73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h" 74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h" 75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h" 76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS 77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radius.h" 78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipv6cp.h" 80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncp.h" 81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "bundle.h" 82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsl_compress_init(struct slcompress *comp, int max_state) 85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_int i; 87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct cstate *tstate = comp->tstate; 88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(comp, '\0', sizeof *comp); 90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (i = max_state; i > 0; --i) { 91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh tstate[i].cs_id = i; 92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh tstate[i].cs_next = &tstate[i - 1]; 93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh tstate[0].cs_next = &tstate[max_state]; 95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh tstate[0].cs_id = 0; 96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_cs = &tstate[0]; 97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_recv = 255; 98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_xmit = 255; 99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->flags = SLF_TOSS; 100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/* ENCODE encodes a number that is known to be non-zero. ENCODEZ 104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * checks for zero (since zero has to be encoded in the 32-bit, 3 byte 105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * form). 106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define ENCODE(n) { \ 108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((u_short)(n) >= 256) { \ 109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = 0; \ 110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp[1] = (n); \ 111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp[0] = (n) >> 8; \ 112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += 2; \ 113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { \ 114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = (n); \ 115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } \ 116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define ENCODEZ(n) { \ 118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ 119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = 0; \ 120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp[1] = (n); \ 121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp[0] = (n) >> 8; \ 122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += 2; \ 123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { \ 124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = (n); \ 125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } \ 126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define DECODEL(f) { \ 129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (*cp == 0) {\ 130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \ 131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += 3; \ 132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { \ 133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (f) = htonl(ntohl(f) + (u_int32_t)*cp++); \ 134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } \ 135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define DECODES(f) { \ 138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (*cp == 0) {\ 139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \ 140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += 3; \ 141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { \ 142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (f) = htons(ntohs(f) + (u_int32_t)*cp++); \ 143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } \ 144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define DECODEU(f) { \ 147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (*cp == 0) {\ 148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (f) = htons((cp[1] << 8) | cp[2]); \ 149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += 3; \ 150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { \ 151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (f) = htons((u_int32_t)*cp++); \ 152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } \ 153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehu_char 157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsl_compress_tcp(struct mbuf * m, 158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ip * ip, 159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct slcompress *comp, 160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct slstat *slstat, 161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int compress_cid) 162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct cstate *cs = comp->last_cs->cs_next; 164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_int hlen = ip->ip_hl; 165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct tcphdr *oth; 166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct tcphdr *th; 167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_int deltaS, deltaA; 168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_int changes = 0; 169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char new_seq[16]; 170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_char *cp = new_seq; 171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Bail if this is an IP fragment or if the TCP packet isn't `compressible' 174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * (i.e., ACK isn't set or some other control bit is set). (We assume that 175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the caller has already made sure the packet is IP proto TCP). 176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40) { 178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "??? 1 ip_off = %x, m_len = %lu\n", 179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ip->ip_off, (unsigned long)m->m_len); 180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_DumpBp(LogDEBUG, "", m); 181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (TYPE_IP); 182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th = (struct tcphdr *) & ((int *) ip)[hlen]; 184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((th->th_flags & (TH_SYN | TH_FIN | TH_RST | TH_ACK)) != TH_ACK) { 185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "??? 2 th_flags = %x\n", th->th_flags); 186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_DumpBp(LogDEBUG, "", m); 187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (TYPE_IP); 188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Packet is compressible -- we're going to send either a COMPRESSED_TCP or 192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * UNCOMPRESSED_TCP packet. Either way we need to locate (or create) the 193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * connection state. Special case the most recently used connection since 194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * it's most likely to be used again & we don't have to do any reordering 195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * if it's used. 196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_packets++; 198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr || 199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr || 200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *(int *) th != ((int *) &cs->cs_ip)[cs->cs_ip.ip_hl]) { 201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Wasn't the first -- search for it. 204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * States are kept in a circularly linked list with last_cs pointing to the 206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * end of the list. The list is kept in lru order by moving a state to 207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the head of the list whenever it is referenced. Since the list is 208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * short and, empirically, the connection we want is almost always near 209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the front, we locate states via linear search. If we don't find a 210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * state for the datagram, the oldest state is (re-)used. 211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct cstate *lcs; 213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct cstate *lastcs = comp->last_cs; 214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do { 216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcs = cs; 217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs = cs->cs_next; 218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_searches++; 219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr 220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr 221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh && *(int *) th == ((int *) &cs->cs_ip)[cs->cs_ip.ip_hl]) 222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto found; 223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } while (cs != lastcs); 224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Didn't find it -- re-use oldest cstate. Send an uncompressed packet 227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * that tells the other side what connection number we're using for this 228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * conversation. Note that since the state list is circular, the oldest 229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * state points to the newest and we only need to set last_cs to update 230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the lru linkage. 231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_misses++; 233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_cs = lcs; 234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define THOFFSET(th) (th->th_off) 235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen += th->th_off; 236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen <<= 2; 237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (hlen > m->m_len) 238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (TYPE_IP); 239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto uncompressed; 240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehfound: 242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Found it -- move to the front on the connection list. 245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (cs == lastcs) 247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_cs = lcs; 248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else { 249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcs->cs_next = cs->cs_next; 250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs->cs_next = lastcs->cs_next; 251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lastcs->cs_next = cs; 252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Make sure that only what we expect to change changed. The first line of 257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the `if' checks the IP protocol version, header length & type of 258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * service. The 2nd line checks the "Don't fragment" bit. The 3rd line 259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * checks the time-to-live and protocol (the protocol check is unnecessary 260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * but costless). The 4th line checks the TCP header length. The 5th line 261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * checks IP options, if any. The 6th line checks TCP options, if any. If 262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * any of these things are different between the previous & current 263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * datagram, we send the current datagram `uncompressed'. 264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh oth = (struct tcphdr *) & ((int *) &cs->cs_ip)[hlen]; 266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaS = hlen; 267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen += th->th_off; 268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen <<= 2; 269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (hlen > m->m_len) 270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (TYPE_IP); 271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (((u_short *) ip)[0] != ((u_short *) & cs->cs_ip)[0] || 273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ((u_short *) ip)[3] != ((u_short *) & cs->cs_ip)[3] || 274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ((u_short *) ip)[4] != ((u_short *) & cs->cs_ip)[4] || 275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh THOFFSET(th) != THOFFSET(oth) || 276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (deltaS > 5 && 277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcmp(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) || 278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (THOFFSET(th) > 5 && 279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcmp(th + 1, oth + 1, (THOFFSET(th) - 5) << 2))) { 280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto uncompressed; 281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Figure out which of the changing fields changed. The receiver expects 285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * changes in the order: urgent, window, ack, seq (the order minimizes the 286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * number of temporaries needed in this section of code). 287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (th->th_flags & TH_URG) { 289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaS = ntohs(th->th_urp); 290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ENCODEZ(deltaS); 291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes |= NEW_U; 292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (th->th_urp != oth->th_urp) { 293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * argh! URG not set but urp changed -- a sensible implementation should 296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * never do this but RFC793 doesn't prohibit the change so we have to 297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * deal with it. 298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto uncompressed; 300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaS = (u_short) (ntohs(th->th_win) - ntohs(oth->th_win)); 302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaS) { 303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ENCODE(deltaS); 304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes |= NEW_W; 305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack); 307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaA) { 308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaA > 0xffff) { 309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto uncompressed; 310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ENCODE(deltaA); 312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes |= NEW_A; 313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq); 315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaS) { 316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaS > 0xffff) { 317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto uncompressed; 318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ENCODE(deltaS); 320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes |= NEW_S; 321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (changes) { 323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case 0: 325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Nothing changed. If this packet contains data and the last one didn't, 328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * this is probably a data packet following an ack (normal on an 329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * interactive connection) and we send it compressed. Otherwise it's 330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * probably a retransmit, retransmitted ack or window probe. Send it 331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * uncompressed in case the other side missed the compressed version. 332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ip->ip_len != cs->cs_ip.ip_len && 334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ntohs(cs->cs_ip.ip_len) == hlen) 335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* FALLTHROUGH */ 338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case SPECIAL_I: 340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case SPECIAL_D: 341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * actual changes match one of our special case encodings -- send packet 344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * uncompressed. 345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto uncompressed; 347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case NEW_S | NEW_A: 349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaS == deltaA && 350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { 351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* special case for echoed terminal traffic */ 352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes = SPECIAL_I; 353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = new_seq; 354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case NEW_S: 358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { 359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* special case for data xfer */ 360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes = SPECIAL_D; 361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = new_seq; 362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaS = ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id); 367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (deltaS != 1) { 368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ENCODEZ(deltaS); 369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes |= NEW_I; 370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (th->th_flags & TH_PUSH) 372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes |= TCP_PUSH_BIT; 373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Grab the cksum before we overwrite it below. Then update our state with 376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * this packet's header. 377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaA = ntohs(th->th_sum); 379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(&cs->cs_ip, ip, hlen); 380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * We want to use the original packet as our compressed packet. (cp - 383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * new_seq) is the number of bytes we need for compressed sequence numbers. 384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * In addition we need one byte for the change mask, one for the connection 385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * id and two for the tcp checksum. So, (cp - new_seq) + 4 bytes of header 386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are needed. hlen is how many bytes of the original packet to toss so 387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * subtract the two to get the new packet size. 388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh deltaS = cp - new_seq; 390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = (u_char *) ip; 391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Since fastq traffic can jump ahead of the background traffic, we don't 394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * know what order packets will go on the line. In this case, we always 395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * send a "new" connection id so the receiver state stays synchronized. 396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (comp->last_xmit == cs->cs_id && compress_cid) { 398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen -= deltaS + 3; 399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += hlen; 400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = changes; 401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_xmit = cs->cs_id; 403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen -= deltaS + 4; 404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += hlen; 405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = changes | NEW_C; 406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = cs->cs_id; 407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m->m_len -= hlen; 409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m->m_offset += hlen; 410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = deltaA >> 8; 411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp++ = deltaA; 412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(cp, new_seq, deltaS); 413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_compressed++; 414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (TYPE_COMPRESSED_TCP); 415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Update connection state cs & send uncompressed packet ('uncompressed' 418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * means a regular ip/tcp packet but with the 'conversation id' we hope to 419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * use on future compressed packets in the protocol field). 420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehuncompressed: 422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(&cs->cs_ip, ip, hlen); 423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ip->ip_p = cs->cs_id; 424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_xmit = cs->cs_id; 425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (TYPE_UNCOMPRESSED_TCP); 426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp, 431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct slstat *slstat, int max_state) 432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_char *cp; 434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_int hlen, changes; 435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct tcphdr *th; 436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct cstate *cs; 437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register struct ip *ip; 438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_short *bp; 439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (type) { 441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case TYPE_UNCOMPRESSED_TCP: 443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ip = (struct ip *) * bufp; 444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ip->ip_p > max_state) 445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto bad; 446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs = &comp->rstate[comp->last_recv = ip->ip_p]; 447706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->flags &= ~SLF_TOSS; 448706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ip->ip_p = IPPROTO_TCP; 449706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 450706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 451706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Calculate the size of the TCP/IP header and make sure that we don't 452706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * overflow the space we have available for it. 453706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 454706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen = ip->ip_hl << 2; 455706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((int)(hlen + sizeof(struct tcphdr)) > len) 456706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto bad; 457706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th = (struct tcphdr *) & ((char *) ip)[hlen]; 458706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen += THOFFSET(th) << 2; 459706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (hlen > MAX_HDR) 460706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto bad; 461706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(&cs->cs_ip, ip, hlen); 462706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs->cs_hlen = hlen; 463706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_uncompressedin++; 464706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (len); 465706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 466706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 467706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto bad; 468706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 469706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case TYPE_COMPRESSED_TCP: 470706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 471706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 472706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 473706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We've got a compressed packet. */ 474706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_compressedin++; 475706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = *bufp; 476706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes = *cp++; 477706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "compressed: changes = %02x\n", changes); 478706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 479706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (changes & NEW_C) { 480706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 481706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Make sure the state index is in range, then grab the state. If we have 482706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * a good state index, clear the 'discard' flag. 483706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 484706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (*cp > max_state || comp->last_recv == 255) 485706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto bad; 486706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 487706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->flags &= ~SLF_TOSS; 488706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->last_recv = *cp++; 489706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 490706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 491706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * this packet has an implicit state index. If we've had a line error 492706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * since the last time we got an explicit state index, we have to toss 493706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the packet. 494706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 495706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (comp->flags & SLF_TOSS) { 496706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_tossed++; 497706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (0); 498706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 499706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 500706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs = &comp->rstate[comp->last_recv]; 501706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hlen = cs->cs_ip.ip_hl << 2; 502706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th = (struct tcphdr *) & ((u_char *) & cs->cs_ip)[hlen]; 503706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_sum = htons((*cp << 8) | cp[1]); 504706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp += 2; 505706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (changes & TCP_PUSH_BIT) 506706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_flags |= TH_PUSH; 507706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 508706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_flags &= ~TH_PUSH; 509706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 510706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (changes & SPECIALS_MASK) { 511706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case SPECIAL_I: 512706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh { 513706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh register u_int i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; 514706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 515706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_ack = htonl(ntohl(th->th_ack) + i); 516706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_seq = htonl(ntohl(th->th_seq) + i); 517706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 518706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 519706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 520706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case SPECIAL_D: 521706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_seq = htonl(ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) 522706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh - cs->cs_hlen); 523706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 524706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 525706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 526706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (changes & NEW_U) { 527706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_flags |= TH_URG; 528706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh DECODEU(th->th_urp) 529706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 530706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh th->th_flags &= ~TH_URG; 531706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (changes & NEW_W) 532706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh DECODES(th->th_win) 533706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (changes & NEW_A) 534706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh DECODEL(th->th_ack) 535706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (changes & NEW_S) { 536706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "NEW_S: %02x, %02x, %02x\n", 537706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *cp, cp[1], cp[2]); 538706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh DECODEL(th->th_seq) 539706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 540706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 541706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 542706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (changes & NEW_I) { 543706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh DECODES(cs->cs_ip.ip_id) 544706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 545706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs->cs_ip.ip_id = htons(ntohs(cs->cs_ip.ip_id) + 1); 546706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 547706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "Uncompress: id = %04x, seq = %08lx\n", 548706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs->cs_ip.ip_id, (u_long)ntohl(th->th_seq)); 549706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 550706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 551706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * At this point, cp points to the first byte of data in the packet. 552706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Back up cp by the tcp/ip header length to make room for the 553706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * reconstructed header (we assume the packet we were handed has enough 554706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * space to prepend 128 bytes of header). Adjust the length to account 555706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * for the new header & fill in the IP total length. 556706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 557706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len -= (cp - *bufp); 558706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len < 0) 559706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 560706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * we must have dropped some characters (crc should detect this but the 561706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * old slip framing won't) 562706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 563706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto bad; 564706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 565706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *bufp = cp - cs->cs_hlen; 566706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len += cs->cs_hlen; 567706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs->cs_ip.ip_len = htons(len); 568706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 569706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* recompute the ip header checksum */ 570706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs->cs_ip.ip_sum = 0; 571706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = (u_short *)&cs->cs_ip; 572706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (changes = 0; hlen > 0; hlen -= 2) 573706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes += *bp++; 574706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes = (changes & 0xffff) + (changes >> 16); 575706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh changes = (changes & 0xffff) + (changes >> 16); 576706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cs->cs_ip.ip_sum = ~changes; 577706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 578706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* And copy the result into our buffer */ 579706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(*bufp, &cs->cs_ip, cs->cs_hlen); 580706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 581706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (len); 582706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehbad: 583706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh comp->flags |= SLF_TOSS; 584706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh slstat->sls_errorin++; 585706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return (0); 586706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 587706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 588706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 589706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsl_Show(struct cmdargs const *arg) 590706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 591706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "VJ compression statistics:\n"); 592706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Out: %d (compress) / %d (total)", 593706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_compressed, 594706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_packets); 595706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " %d (miss) / %d (search)\n", 596706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_misses, 597706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_searches); 598706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " In: %d (compress), %d (uncompress)", 599706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_compressedin, 600706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_uncompressedin); 601706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " %d (error), %d (tossed)\n", 602706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_errorin, 603706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->bundle->ncp.ipcp.vj.slstat.sls_tossed); 604706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 605706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 606