⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slhc.c

📁 一百多个例子很好的verilog 学习资料
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * in case the other side missed the compressed version.
		 */
		if(iph.length != cs->cs_ip.length && cs->cs_ip.length == hlen)
			break;
		goto uncompressed;
	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 == cs->cs_ip.length - hlen){
			/* special case for echoed terminal traffic */
			changes = SPECIAL_I;
			cp = new_seq;
		}
		break;
	case NEW_S:
		if(deltaS == cs->cs_ip.length - hlen){
			/* special case for data xfer */
			changes = SPECIAL_D;
			cp = new_seq;
		}
		break;
	}
	deltaS = iph.id - cs->cs_ip.id;
	if(deltaS != 1){
		cp = encode(cp,deltaS);
		changes |= NEW_I;
	}
	if(th.flags.psh)
		changes |= TCP_PUSH_BIT;
	/* Grab the cksum before we overwrite it below.  Then update our
	 * state with this packet's header.
	 */
	deltaA = th.checksum;
	ASSIGN(cs->cs_ip,iph);
	ASSIGN(cs->cs_tcp,th);
	/* 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.
	 */
	deltaS = cp - new_seq;
	pullup(bpp,NULL,hlen);		/* Strip TCP/IP headers */
	if(compress_cid == 0 || comp->xmit_current != cs->this){
		pushdown(bpp,NULL,deltaS + 4);
		cp = (*bpp)->data;
		*cp++ = changes | NEW_C;
		*cp++ = cs->this;
		comp->xmit_current = cs->this;
	} else {
		pushdown(bpp,NULL,deltaS + 3);
		cp = (*bpp)->data;
		*cp++ = changes;
	}
	cp = put16(cp,deltaA);	/* Write TCP checksum */
	memcpy(cp,new_seq,deltaS);	/* Write list of deltas */
	comp->sls_o_compressed++;
	return SL_TYPE_COMPRESSED_TCP;

	/* Update connection state cs & send uncompressed packet (i.e.,
	 * a regular ip/tcp packet but with the 'conversation id' we hope
	 * to use on future compressed packets in the protocol field).
	 */
uncompressed:
	iph.protocol = cs->this;
	ASSIGN(cs->cs_ip,iph);
	ASSIGN(cs->cs_tcp,th);
	comp->xmit_current = cs->this;
	comp->sls_o_uncompressed++;
	pullup(bpp,NULL,iplen);	/* Strip old IP header */
	htonip(&iph,bpp,IP_CS_OLD);	/* replace with new one */
	return SL_TYPE_UNCOMPRESSED_TCP;
}


int
slhc_uncompress(comp, bpp)
struct slcompress *comp;
struct mbuf **bpp;
{
	int changes;
	long x;
	struct tcp *thp;
	struct cstate *cs;
	int len;

	if(bpp == NULL){
		comp->sls_i_error++;
		return 0;
	}
	/* We've got a compressed packet; read the change byte */
	comp->sls_i_compressed++;
	if(len_p(*bpp) < 3){
		comp->sls_i_error++;
		return 0;
	}
	changes = PULLCHAR(bpp);	/* "Can't fail" */
	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.
		 */
		x = PULLCHAR(bpp);	/* Read conn index */
		if(x < 0 || x > comp->rslot_limit)
			goto bad;

		comp->flags &=~ SLF_TOSS;
		comp->recv_current = x;
	} 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 & SLF_TOSS){
			comp->sls_i_tossed++;
			return 0;
		}
	}
	cs = &comp->rstate[comp->recv_current];
	thp = &cs->cs_tcp;

	if((x = pull16(bpp)) == -1)	/* Read the TCP checksum */
		goto bad;
	thp->checksum = x;

	thp->flags.psh = (changes & TCP_PUSH_BIT) ? 1 : 0;

	switch(changes & SPECIALS_MASK){
	case SPECIAL_I:		/* Echoed terminal traffic */
		{
		uint i;
		i = cs->cs_ip.length;
		i -= (cs->cs_ip.optlen + IPLEN + TCPLEN);
		thp->ack += i;
		thp->seq += i;
		}
		break;

	case SPECIAL_D:			/* Unidirectional data */
		thp->seq += cs->cs_ip.length - (cs->cs_ip.optlen +IPLEN + TCPLEN);
		break;

	default:
		if(changes & NEW_U){
			thp->flags.urg = 1;
			if((x = decode(bpp)) == -1)
				goto bad;
			thp->up = x;
		} else
			thp->flags.urg = 0;
		if(changes & NEW_W){
			if((x = decode(bpp)) == -1)
				goto bad;
			thp->wnd += x;
		}
		if(changes & NEW_A){
			if((x = decode(bpp)) == -1)
				goto bad;
			thp->ack += x;
		}
		if(changes & NEW_S){
			if((x = decode(bpp)) == -1)
				goto bad;
			thp->seq += x;
		}
		break;
	}
	if(changes & NEW_I){
		if((x = decode(bpp)) == -1)
			goto bad;
		cs->cs_ip.id += x;
	} else
		cs->cs_ip.id++;

	/*
	 * At this point, bpp points to the first byte of data in the
	 * packet.  Put the reconstructed TCP and IP headers back on the
	 * packet.  Recalculate IP checksum (but not TCP checksum).
	 */
	len = len_p(*bpp) + IPLEN + TCPLEN + cs->cs_ip.optlen;
	cs->cs_ip.length = len;

	htontcp(thp,bpp,0,0);
	htonip(&cs->cs_ip,bpp,IP_CS_NEW);
	return len;
bad:
	comp->sls_i_error++;
	return slhc_toss( comp );
}


int
slhc_remember(comp, bpp)
struct slcompress *comp;
struct mbuf **bpp;
{
	struct cstate *cs;
	struct ip iph;
	struct tcp th;
	uint len;
	uint hdrlen;
	int slot;

	if(bpp == NULL){
		comp->sls_i_error++;
		return slhc_toss(comp);
	}

	/* Sneak a peek at the IP header's IHL field to find its length */
	hdrlen = ((*bpp)->data[0] & 0xf) << 2;
	if(hdrlen < IPLEN){
		/* The IP header length field is too small to be valid */
		comp->sls_i_error++;
		return slhc_toss(comp);
	}
	len = len_p(*bpp);	/* Actual length of whole packet */
	ntohip(&iph,bpp);	/* Extract IP header */
	/* Verify indicated length <= actual length */
	if(iph.length > len){
		/* Packet has been truncated, or header is garbage */
		comp->sls_i_error++;
		return slhc_toss(comp);
	}
	/* Verify conn ID */
	slot = iph.protocol;
	if(slot > comp->rslot_limit){
		/* Out of range */
		comp->sls_i_error++;
		return slhc_toss(comp);
	}
	iph.protocol = TCP_PTCL;	/* Replace conn ID with TCP_PTCL */

	/* Extract TCP header and replace both headers
	 * Neither header checksum is recalculated
	 */
	ntohtcp(&th,bpp);
	htontcp(&th,bpp,0,0);
	htonip(&iph,bpp,IP_CS_OLD);

	/* Checksum IP header (now that protocol field is TCP again) */
	if(cksum(NULL,*bpp,hdrlen) != 0){
		/* Bad IP header checksum; discard */
		comp->sls_i_error++;
		return slhc_toss(comp);
	}
	/* Update local state */
	comp->recv_current = slot;
	cs = &comp->rstate[slot];
	comp->flags &=~ SLF_TOSS;

	ASSIGN(cs->cs_ip,iph);
	ASSIGN(cs->cs_tcp,th);
	comp->sls_i_uncompressed++;
	return len;
}


int
slhc_toss(comp)
struct slcompress *comp;
{
	if ( comp == NULL )
		return 0;

	comp->flags |= SLF_TOSS;
	return 0;
}

void
slhc_i_status(comp)
struct slcompress *comp;
{
	if (comp != NULL) {
		printf("\t%10ld Cmp,"
			" %10ld Uncmp,"
			" %10ld Bad, "
			" %10ld Tossed\n",
			comp->sls_i_compressed,
			comp->sls_i_uncompressed,
			comp->sls_i_error,
			comp->sls_i_tossed);
	}
}


void
slhc_o_status(comp)
struct slcompress *comp;
{
	if (comp != NULL) {
		printf("\t%10ld Cmp,"
			" %10ld Uncmp,"
			" %10ld AsIs,"
			" %10ld NotTCP\n",
			comp->sls_o_compressed,
			comp->sls_o_uncompressed,
			comp->sls_o_tcp,
			comp->sls_o_nontcp);
		printf("\t%10ld Searches,"
			" %10ld Misses\n",
			comp->sls_o_searches,
			comp->sls_o_misses);
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -