/*
 * Routines to compress and uncompess tcp packets (for transmission
 * over low speed serial lines.
 *
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *	Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
 *	- Initial distribution.
 *
 * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au,
 * so that the entire packet being decompressed doesn't have
 * to be in contiguous memory (just the compressed header).
 *
 * Modified March 1998 by Guy Lancaster, glanca@gesn.com,
 * for a 16 bit processor.
 */

#include <string.h>

#include "ppp.h"
#include "vj.h"
#include "pppdebug.h"

#if VJ_SUPPORT > 0

#if LINK_STATS
#define INCR(counter) ++comp->stats.counter
#else
#define INCR(counter)
#endif

#if defined(NO_CHAR_BITFIELDS)
#define getip_hl(base)	((base).ip_hl_v&0xf)
#define getth_off(base)	(((base).th_x2_off&0xf0)>>4)
#else
#define getip_hl(base)	((base).ip_hl)
#define getth_off(base)	((base).th_off)
#endif

void vj_compress_init(struct vjcompress *comp)
{
	register u_int i;
	register struct cstate *tstate = comp->tstate;
	
#if MAX_SLOTS == 0
	memset((char *)comp, 0, sizeof(*comp));
#endif
	comp->maxSlotIndex = MAX_SLOTS - 1;
	comp->compressSlot = 0;		/* Disable slot ID compression by default. */
	for (i = MAX_SLOTS - 1; i > 0; --i) {
		tstate[i].cs_id = i;
		tstate[i].cs_next = &tstate[i - 1];
	}
	tstate[0].cs_next = &tstate[MAX_SLOTS - 1];
	tstate[0].cs_id = 0;
	comp->last_cs = &tstate[0];
	comp->last_recv = 255;
	comp->last_xmit = 255;
	comp->flags = VJF_TOSS;
}


/* ENCODE encodes a number that is known to be non-zero.  ENCODEZ
 * checks for zero (since zero has to be encoded in the long, 3 byte
 * form).
 */
#define ENCODE(n) { \
	if ((u_short)(n) >= 256) { \
		*cp++ = 0; \
		cp[1] = (n); \
		cp[0] = (n) >> 8; \
		cp += 2; \
	} else { \
		*cp++ = (n); \
	} \
}
#define ENCODEZ(n) { \
	if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
		*cp++ = 0; \
		cp[1] = (n); \
		cp[0] = (n) >> 8; \
		cp += 2; \
	} else { \
		*cp++ = (n); \
	} \
}

#define DECODEL(f) { \
	if (*cp == 0) {\
		u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \
		(f) = htonl(tmp); \
		cp += 3; \
	} else { \
		u32_t tmp = ntohl(f) + (u32_t)*cp++; \
		(f) = htonl(tmp); \
	} \
}

#define DECODES(f) { \
	if (*cp == 0) {\
		u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \
		(f) = htons(tmp); \
		cp += 3; \
	} else { \
		u_short tmp = ntohs(f) + (u_short)*cp++; \
		(f) = htons(tmp); \
	} \
}

#define DECODEU(f) { \
	if (*cp == 0) {\
		(f) = htons(((u_short)cp[1] << 8) | cp[2]); \
		cp += 3; \
	} else { \
		(f) = htons((u_short)*cp++); \
	} \
}

/*
 * vj_compress_tcp - Attempt to do Van Jacobsen header compression on a
 * packet.  This assumes that nb and comp are not null and that the first
 * buffer of the chain contains a valid IP header.
 * Return the VJ type code indicating whether or not the packet was
 * compressed.
 */
u_int vj_compress_tcp(
	struct vjcompress *comp,
	struct pbuf *pb
)
{
	register struct ip *ip = (struct ip *)pb->payload;
	register struct cstate *cs = comp->last_cs->cs_next;
	register u_short hlen = getip_hl(*ip);
	register struct tcphdr *oth;
	register struct tcphdr *th;
	register u_short deltaS, deltaA;
	register u_long deltaL;
	register u_int changes = 0;
	u_char new_seq[16];
	register u_char *cp = new_seq;

	/*	
	 * Check that the packet is IP proto TCP.
	 */
	if (ip->ip_p != IPPROTO_TCP)
		return (TYPE_IP);
		
	/*
	 * Bail if this is an IP fragment or if the TCP packet isn't
	 * `compressible' (i.e., ACK isn't set or some other control bit is
	 * set).  
	 */
	if ((ip->ip_off & htons(0x3fff)) || pb->tot_len < 40)
		return (TYPE_IP);
	th = (struct tcphdr *)&((long *)ip)[hlen];
	if ((th->th_flags & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK)
		return (TYPE_IP);
		
	/*
	 * Packet is compressible -- we're going to send either a
	 * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way we need
	 * to locate (or create) the connection state.  Special case the
	 * most recently used connection since it's most likely to be used
	 * again & we don't have to do any reordering if it's used.
	 */
	INCR(vjs_packets);
	if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr 
			|| ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr 
			|| *(long *)th != ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) {
		/*
		 * Wasn't the first -- search for it.
		 *
		 * States are kept in a circularly linked list with
		 * last_cs pointing to the end of the list.  The
		 * list is kept in lru order by moving a state to the
		 * head of the list whenever it is referenced.  Since
		 * the list is short and, empirically, the connection
		 * we want is almost always near the front, we locate
		 * states via linear search.  If we don't find a state
		 * for the datagram, the oldest state is (re-)used.
		 */
		register struct cstate *lcs;
		register struct cstate *lastcs = comp->last_cs;
		
		do {
			lcs = cs; cs = cs->cs_next;
			INCR(vjs_searches);
			if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
					&& ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
					&& *(long *)th == ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)])
				goto found;
		} while (cs != lastcs);
		
		/*
		 * Didn't find it -- re-use oldest cstate.  Send an
		 * uncompressed packet that tells the other side what
		 * connection number we're using for this conversation.
		 * Note that since the state list is circular, the oldest
		 * state points to the newest and we only need to set
		 * last_cs to update the lru linkage.
		 */
		INCR(vjs_misses);
		comp->last_cs = lcs;
		hlen += getth_off(*th);
		hlen <<= 2;
		/* Check that the IP/TCP headers are contained in the first buffer. */
		if (hlen > pb->len)
			return (TYPE_IP);
		goto uncompressed;
		
		found:
		/*
		 * Found it -- move to the front on the connection list.
		 */
		if (cs == lastcs)
			comp->last_cs = lcs;
		else {
			lcs->cs_next = cs->cs_next;
			cs->cs_next = lastcs->cs_next;
			lastcs->cs_next = cs;
		}
	}
	
	oth = (struct tcphdr *)&((long *)&cs->cs_ip)[hlen];
	deltaS = hlen;
	hlen += getth_off(*th);
	hlen <<= 2;
	/* Check that the IP/TCP headers are contained in the first buffer. */
	if (hlen > pb->len) {
		PPPDEBUG((LOG_INFO, "vj_compress_tcp: header len %d spans buffers\n", 
					hlen));
		return (TYPE_IP);
	}
	
	/*
	 * Make sure that only what we expect to change changed. The first
	 * line of the `if' checks the IP protocol version, header length &
	 * type of service.  The 2nd line checks the "Don't fragment" bit.
	 * The 3rd line checks the time-to-live and protocol (the protocol
	 * check is unnecessary but costless).  The 4th line checks the TCP
	 * header length.  The 5th line checks IP options, if any.  The 6th
	 * line checks TCP options, if any.  If any of these things are
	 * different between the previous & current datagram, we send the
	 * current datagram `uncompressed'.
	 */
	if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] 
			|| ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] 
			|| ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] 
			|| getth_off(*th) != getth_off(*oth) 
			|| (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) 
			|| (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2)))
		goto uncompressed;
	
	/*
	 * Figure out which of the changing fields changed.  The
	 * receiver expects changes in the order: urgent, window,
	 * ack, seq (the order minimizes the number of temporaries
	 * needed in this section of code).
	 */
	if (th->th_flags & TCP_URG) {
		deltaS = ntohs(th->th_urp);
		ENCODEZ(deltaS);
		changes |= NEW_U;
	} else if (th->th_urp != oth->th_urp)
		/* argh! URG not set but urp changed -- a sensible
		 * implementation should never do this but RFC793
		 * doesn't prohibit the change so we have to deal
		 * with it. */
		goto uncompressed;
	
	if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) != 0) {
		ENCODE(deltaS);
		changes |= NEW_W;
	}
	
	if ((deltaL = ntohl(th->th_ack) - ntohl(oth->th_ack)) != 0) {
		if (deltaL > 0xffff)
			goto uncompressed;
		deltaA = (u_short)deltaL;
		ENCODE(deltaA);
		changes |= NEW_A;
	}
	
	if ((deltaL = ntohl(th->th_seq) - ntohl(oth->th_seq)) != 0) {
		if (deltaL > 0xffff)
			goto uncompressed;
		deltaS = (u_short)deltaL;
		ENCODE(deltaS);
		changes |= NEW_S;
	}
	
	switch(changes) {
	
	case 0:
		/*
		 * Nothing changed. If this packet contains data and the
		 * last one didn't, this is probably a data packet following
		 * an ack (normal on an interactive connection) and we send
		 * it compressed.  Otherwise it's probably a retransmit,
		 * retransmitted ack or window probe.  Send it uncompressed
		 * in case the other side missed the compressed version.
		 */
		if (ip->ip_len != cs->cs_ip.ip_len &&
			ntohs(cs->cs_ip.ip_len) == hlen)
		break;
	
	/* (fall through) */
	
	case SPECIAL_I:
	case SPECIAL_D:
		/*
		 * actual changes match one of our special case encodings --
		 * send packet uncompressed.
		 */
		goto uncompressed;
	
	case NEW_S|NEW_A:
		if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
			/* special case for echoed terminal traffic */
			changes = SPECIAL_I;
			cp = new_seq;
		}
		break;
	
	case NEW_S:
		if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
			/* special case for data xfer */
			changes = SPECIAL_D;
			cp = new_seq;
		}
		break;
	}
	
	deltaS = (u_short)(ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id));
	if (deltaS != 1) {
		ENCODEZ(deltaS);
		changes |= NEW_I;
	}
	if (th->th_flags & TCP_PSH)
	changes |= TCP_PUSH_BIT;
	/*
	 * Grab the cksum before we overwrite it below.  Then update our
	 * state with this packet's header.
	 */
	deltaA = ntohs(th->th_sum);
	BCOPY(ip, &cs->cs_ip, hlen);
	
	/*
	 * We want to use the original packet as our compressed packet.
	 * (cp - new_seq) is the number of bytes we need for compressed
	 * sequence numbers.  In addition we need one byte for the change
	 * mask, one for the connection id and two for the tcp checksum.
	 * So, (cp - new_seq) + 4 bytes of header are needed.  hlen is how
	 * many bytes of the original packet to toss so subtract the two to
	 * get the new packet size.
	 */
	deltaS = (u_short)(cp - new_seq);
	if (!comp->compressSlot || comp->last_xmit != cs->cs_id) {
		comp->last_xmit = cs->cs_id;
		hlen -= deltaS + 4;
		pbuf_header(pb, -hlen);
		cp = (u_char *)pb->payload;
		*cp++ = changes | NEW_C;
		*cp++ = cs->cs_id;
	} else {
		hlen -= deltaS + 3;
		pbuf_header(pb, -hlen);
		cp = (u_char *)pb->payload;
		*cp++ = changes;
	}
	*cp++ = deltaA >> 8;
	*cp++ = deltaA;
	BCOPY(new_seq, cp, deltaS);
	INCR(vjs_compressed);
	return (TYPE_COMPRESSED_TCP);

	/*
	 * Update connection state cs & send uncompressed packet (that is,
	 * a regular ip/tcp packet but with the 'conversation id' we hope
	 * to use on future compressed packets in the protocol field).
	 */
uncompressed:
	BCOPY(ip, &cs->cs_ip, hlen);
	ip->ip_p = cs->cs_id;
	comp->last_xmit = cs->cs_id;
	return (TYPE_UNCOMPRESSED_TCP);
}

/*
 * Called when we may have missed a packet.
 */
void vj_uncompress_err(struct vjcompress *comp)
{
    comp->flags |= VJF_TOSS;
	INCR(vjs_errorin);
}

/*
 * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.
 * Return 0 on success, -1 on failure.
 */
int vj_uncompress_uncomp(
	struct pbuf *nb,
	struct vjcompress *comp
)
{
	register u_int hlen;
	register struct cstate *cs;
	register struct ip *ip;
	
	ip = (struct ip *)nb->payload;
	hlen = getip_hl(*ip) << 2;
	if (ip->ip_p >= MAX_SLOTS
			|| hlen + sizeof(struct tcphdr) > nb->len
			|| (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)
			    > nb->len
			|| hlen > MAX_HDR) {
		PPPDEBUG((LOG_INFO, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", 
					ip->ip_p, hlen, nb->len));
		comp->flags |= VJF_TOSS;
		INCR(vjs_errorin);
		return -1;
	}
	cs = &comp->rstate[comp->last_recv = ip->ip_p];
	comp->flags &=~ VJF_TOSS;
	ip->ip_p = IPPROTO_TCP;
	BCOPY(ip, &cs->cs_ip, hlen);
	cs->cs_hlen = hlen;
	INCR(vjs_uncompressedin);
	return 0;
}

/*
 * Uncompress a packet of type TYPE_COMPRESSED_TCP.
 * The packet is composed of a buffer chain and the first buffer
 * must contain an accurate chain length.
 * The first buffer must include the entire compressed TCP/IP header. 
 * This procedure replaces the compressed header with the uncompressed
 * header and returns the length of the VJ header.
 */
int vj_uncompress_tcp(
	struct pbuf **nb,
	struct vjcompress *comp
)
{
	u_char *cp;
	struct tcphdr *th;
	struct cstate *cs;
	u_short *bp;
	struct pbuf *n0 = *nb;
	u32_t tmp;
	u_int vjlen, hlen, changes;
	
	INCR(vjs_compressedin);
	cp = (u_char *)n0->payload;
	changes = *cp++;
	if (changes & NEW_C) {
		/* 
		 * Make sure the state index is in range, then grab the state.
		 * If we have a good state index, clear the 'discard' flag. 
		 */
		if (*cp >= MAX_SLOTS) {
			PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: bad cid=%d\n", *cp));
			goto bad;
		}
		
		comp->flags &=~ VJF_TOSS;
		comp->last_recv = *cp++;
	} else {
		/* 
		 * this packet has an implicit state index.  If we've
		 * had a line error since the last time we got an
		 * explicit state index, we have to toss the packet. 
		 */
		if (comp->flags & VJF_TOSS) {
			PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: tossing\n"));
			INCR(vjs_tossed);
			return (-1);
		}
	}
	cs = &comp->rstate[comp->last_recv];
	hlen = getip_hl(cs->cs_ip) << 2;
	th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
	th->th_sum = htons((*cp << 8) | cp[1]);
	cp += 2;
	if (changes & TCP_PUSH_BIT)
		th->th_flags |= TCP_PSH;
	else
		th->th_flags &=~ TCP_PSH;
	
	switch (changes & SPECIALS_MASK) {
	case SPECIAL_I:
		{
			register u32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
			/* some compilers can't nest inline assembler.. */
			tmp = ntohl(th->th_ack) + i;
			th->th_ack = htonl(tmp);
			tmp = ntohl(th->th_seq) + i;
			th->th_seq = htonl(tmp);
		}
		break;
	
	case SPECIAL_D:
		/* some compilers can't nest inline assembler.. */
		tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
		th->th_seq = htonl(tmp);
		break;
	
	default:
		if (changes & NEW_U) {
			th->th_flags |= TCP_URG;
			DECODEU(th->th_urp);
		} else
			th->th_flags &=~ TCP_URG;
		if (changes & NEW_W)
			DECODES(th->th_win);
		if (changes & NEW_A)
			DECODEL(th->th_ack);
		if (changes & NEW_S)
			DECODEL(th->th_seq);
		break;
	}
	if (changes & NEW_I) {
		DECODES(cs->cs_ip.ip_id);
	} else {
		cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1;
		cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id);
	}
	
	/*
	 * At this point, cp points to the first byte of data in the
	 * packet.  Fill in the IP total length and update the IP
	 * header checksum.
	 */
	vjlen = (u_short)(cp - (u_char*)n0->payload);
	if (n0->len < vjlen) {
		/* 
		 * We must have dropped some characters (crc should detect
		 * this but the old slip framing won't) 
		 */
		PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: head buffer %d too short %d\n", 
				  n0->len, vjlen));
		goto bad;
	}
	
#if BYTE_ORDER == LITTLE_ENDIAN
	tmp = n0->tot_len - vjlen + cs->cs_hlen;
	cs->cs_ip.ip_len = htons(tmp);
#else
	cs->cs_ip.ip_len = htons(n0->tot_len - vjlen + cs->cs_hlen);
#endif
	
	/* recompute the ip header checksum */
	bp = (u_short *) &cs->cs_ip;
	cs->cs_ip.ip_sum = 0;
	for (tmp = 0; hlen > 0; hlen -= 2)
		tmp += *bp++;
	tmp = (tmp & 0xffff) + (tmp >> 16);
	tmp = (tmp & 0xffff) + (tmp >> 16);
	cs->cs_ip.ip_sum = (u_short)(~tmp);
	
	/* Remove the compressed header and prepend the uncompressed header. */
	pbuf_header(n0, -vjlen);

	if(MEM_ALIGN(n0->payload) != n0->payload) {
		struct pbuf *np, *q;
		u8_t *bufptr;

		np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);
		if(!np) {
			PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: realign failed\n"));
			*nb = NULL;
			goto bad;
		}

		pbuf_header(np, -cs->cs_hlen);

		bufptr = n0->payload;
		for(q = np; q != NULL; q = q->next) {
			memcpy(q->payload, bufptr, q->len);
			bufptr += q->len;
		}

		if(n0->next) {
			pbuf_chain(np, n0->next);
			pbuf_dechain(n0);
		}
		pbuf_free(n0);
		n0 = np;
	}

	if(pbuf_header(n0, cs->cs_hlen)) {
		struct pbuf *np;

		LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);
		np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);
		if(!np) {
			PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: prepend failed\n"));
			*nb = NULL;
			goto bad;
		}
		pbuf_cat(np, n0);
		n0 = np;
	}
	LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen);
	memcpy(n0->payload, &cs->cs_ip, cs->cs_hlen);

	*nb = n0;

	return vjlen;
	
bad:
	comp->flags |= VJF_TOSS;
	INCR(vjs_errorin);
	return (-1);
}

#endif


