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

📄 netvj.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 & TH_PUSH)

	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;

		nb->chainLen -= hlen;

		nb->len -= hlen;

		nb->data += hlen;

		cp = nBUFTOPTR(nb, char *);

		*cp++ = changes | NEW_C;

		*cp++ = cs->cs_id;

	} else {

		hlen -= deltaS + 3;

		nb->chainLen -= hlen;

		nb->len -= hlen;

		nb->data += hlen;

		cp = nBUFTOPTR(nb, char *);

		*cp++ = changes;

	}

	*cp++ = deltaA >> 8;

	*cp++ = (unsigned char)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(

	NBuf *nb,

	struct vjcompress *comp

)

{

	register u_int hlen;

	register struct cstate *cs;

	register struct ip *ip;

	

	ip = nBUFTOPTR(nb, struct ip *);

	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, TL_PPP, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d", 

					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(

	NBuf **nb,

	struct vjcompress *comp

)

{

	u_char *cp;

	struct tcphdr *th;

	struct cstate *cs;

	u_short *bp;

	NBuf *n0 = *nb;

	u_int32_t tmp;

	u_int vjlen, hlen, changes;

	

	INCR(vjs_compressedin);

	cp = nBUFTOPTR(n0, u_char *);

	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, TL_PPP, "vj_uncompress_tcp: bad cid=%d", *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, TL_PPP, "vj_uncompress_tcp: tossing"));

			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((unsigned short)((*cp << 8) | cp[1]));

	cp += 2;

	if (changes & TCP_PUSH_BIT)

		th->th_flags |= TH_PUSH;

	else

		th->th_flags &=~ TH_PUSH;

	

	switch (changes & SPECIALS_MASK) {

	case SPECIAL_I:

		{

			register u_int32_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 |= TH_URG;

			DECODEU(th->th_urp);

		} else

			th->th_flags &=~ TH_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 - nBUFTOPTR(n0, u_char *));

	if (n0->len < vjlen) {

		/* 

		 * We must have dropped some characters (crc should detect

		 * this but the old slip framing won't) 

		 */

		PPPDEBUG((LOG_INFO, TL_PPP, "vj_uncompress_tcp: head buffer %d too short %d", 

				  n0->len, vjlen));

		goto bad;

	}

	

	cs->cs_ip.ip_len = n0->chainLen - vjlen + cs->cs_hlen;

	HTONS(cs->cs_ip.ip_len);

	

	/* 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. */

	n0->data += vjlen;

	n0->len -= vjlen;

	n0->chainLen -= vjlen;

	nPREPEND(n0, &cs->cs_ip, cs->cs_hlen);

	if (n0) {

		*nb = n0;

	} else {

		PPPDEBUG((LOG_WARNING, TL_PPP, "vj_uncompress_tcp: prepend failed"));

		*nb = NULL;

		goto bad;

	}

	

	return vjlen;

	

bad:

	comp->flags |= VJF_TOSS;

	INCR(vjs_errorin);

	return (-1);

}



#endif





//#pragma warning (pop)

////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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