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

📄 slhc.c

📁 linux1.1源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if((deltaA = ntohl(th->ack_seq) - ntohl(oth->ack_seq)) != 0L){		if(deltaA > 0x0000ffff)			goto uncompressed;		cp = encode(cp,deltaA);		changes |= NEW_A;	}	if((deltaS = ntohl(th->seq) - ntohl(oth->seq)) != 0L){		if(deltaS > 0x0000ffff)			goto uncompressed;		cp = encode(cp,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->tot_len != cs->cs_ip.tot_len && 		   ntohs(cs->cs_ip.tot_len) == hlen)			break;		DPRINT(("comp: retrans\n"));		goto uncompressed;		break;	case SPECIAL_I:	case SPECIAL_D:		/* actual changes match one of our special case encodings --		 * send packet uncompressed.		 */		DPRINT(("comp: special\n"));		goto uncompressed;	case NEW_S|NEW_A:		if(deltaS == deltaA &&		    deltaS == ntohs(cs->cs_ip.tot_len) - hlen){			/* special case for echoed terminal traffic */			changes = SPECIAL_I;			cp = new_seq;		}		break;	case NEW_S:		if(deltaS == ntohs(cs->cs_ip.tot_len) - hlen){			/* special case for data xfer */			changes = SPECIAL_D;			cp = new_seq;		}		break;	}	deltaS = ntohs(ip->id) - ntohs(cs->cs_ip.id);	if(deltaS != 1){		cp = encode(cp,deltaS);		changes |= NEW_I;	}	if(th->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->check);	memcpy(&cs->cs_ip,ip,20);	memcpy(&cs->cs_tcp,th,20);	/* 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;	if(compress_cid == 0 || comp->xmit_current != cs->cs_this){		cp = ocp;		*cpp = ocp;		*cp++ = changes | NEW_C;		*cp++ = cs->cs_this;		comp->xmit_current = cs->cs_this;	} else {		cp = ocp;		*cpp = ocp;		*cp++ = changes;	}	cp = put16(cp,(short)deltaA);	/* Write TCP checksum *//* deltaS is now the size of the change section of the compressed header */	DPRINT(("comp: %x %x %x %d %d\n", icp, cp, new_seq, hlen, deltaS));	memcpy(cp,new_seq,deltaS);	/* Write list of deltas */	memcpy(cp+deltaS,icp+hlen,isize-hlen);	comp->sls_o_compressed++;	ocp[0] |= SL_TYPE_COMPRESSED_TCP;	return isize - hlen + deltaS + (cp - ocp);	/* 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:	memcpy(&cs->cs_ip,ip,20);	memcpy(&cs->cs_tcp,th,20);	if (ip->ihl > 5)	  memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4);	if (th->doff > 5)	  memcpy(cs->cs_tcpopt, th+1, ((th->doff) - 5) * 4);	comp->xmit_current = cs->cs_this;	comp->sls_o_uncompressed++;	memcpy(ocp, icp, isize);	*cpp = ocp;	ocp[9] = cs->cs_this;	ocp[0] |= SL_TYPE_UNCOMPRESSED_TCP;	return isize;}intslhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize){	register int changes;	long x;	register struct tcphdr *thp;	register struct iphdr *ip;	register struct cstate *cs;	int len, hdrlen;	unsigned char *cp = icp;	/* We've got a compressed packet; read the change byte */	comp->sls_i_compressed++;	if(isize < 3){		comp->sls_i_error++;		DPRINT(("uncomp: runt\n"));		return 0;	}	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.		 */		x = *cp++;	/* 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++;			DPRINT(("uncomp: toss\n"));			return 0;		}	}	cs = &comp->rstate[comp->recv_current];	thp = &cs->cs_tcp;	ip = &cs->cs_ip;	if((x = pull16(&cp)) == -1) {	/* Read the TCP checksum */		DPRINT(("uncomp: bad tcp chk\n"));		goto bad;        }	thp->check = htons(x);	thp->psh = (changes & TCP_PUSH_BIT) ? 1 : 0;/*  * we can use the same number for the length of the saved header and * the current one, because the packet wouldn't have been sent * as compressed unless the options were the same as the previous one */	hdrlen = ip->ihl * 4 + thp->doff * 4;	switch(changes & SPECIALS_MASK){	case SPECIAL_I:		/* Echoed terminal traffic */		{		register short i;		i = ntohs(ip->tot_len) - hdrlen;		thp->ack_seq = htonl( ntohl(thp->ack_seq) + i);		thp->seq = htonl( ntohl(thp->seq) + i);		}		break;	case SPECIAL_D:			/* Unidirectional data */		thp->seq = htonl( ntohl(thp->seq) +				  ntohs(ip->tot_len) - hdrlen);		break;	default:		if(changes & NEW_U){			thp->urg = 1;			if((x = decode(&cp)) == -1) {				DPRINT(("uncomp: bad U\n"));				goto bad;			}			thp->urg_ptr = htons(x);		} else			thp->urg = 0;		if(changes & NEW_W){			if((x = decode(&cp)) == -1) {				DPRINT(("uncomp: bad W\n"));				goto bad;			}				thp->window = htons( ntohs(thp->window) + x);		}		if(changes & NEW_A){			if((x = decode(&cp)) == -1) {				DPRINT(("uncomp: bad A\n"));				goto bad;			}			thp->ack_seq = htonl( ntohl(thp->ack_seq) + x);		}		if(changes & NEW_S){			if((x = decode(&cp)) == -1) {				DPRINT(("uncomp: bad S\n"));				goto bad;			}			thp->seq = htonl( ntohl(thp->seq) + x);		}		break;	}	if(changes & NEW_I){		if((x = decode(&cp)) == -1) {			DPRINT(("uncomp: bad I\n"));			goto bad;		}		ip->id = htons (ntohs (ip->id) + x);	} else		ip->id = htons (ntohs (ip->id) + 1);	/*	 * At this point, cp 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 = isize - (cp - icp);	if (len < 0)		goto bad;	len += hdrlen;	ip->tot_len = htons(len);	ip->check = 0;	DPRINT(("uncomp: %d %d %d %d\n", cp - icp, hdrlen, isize, len));	memmove(icp + hdrlen, cp, len - hdrlen);	cp = icp;	memcpy(cp, ip, 20);	cp += 20;	if (ip->ihl > 5) {	  memcpy(cp, cs->cs_ipopt, ((ip->ihl) - 5) * 4);	  cp += ((ip->ihl) - 5) * 4;	}	((struct iphdr *)icp)->check = ip_csum((struct iphdr*)icp);	memcpy(cp, thp, 20);	cp += 20;	if (thp->doff > 5) {	  memcpy(cp, cs->cs_tcpopt, ((thp->doff) - 5) * 4);	  cp += ((thp->doff) - 5) * 4;	}if (inet_debug == DBG_SLIP) printk("\runcomp: change %x len %d\n", changes, len);	return len;bad:	comp->sls_i_error++;	return slhc_toss( comp );}intslhc_remember(struct slcompress *comp, unsigned char *icp, int isize){	register struct cstate *cs;	short ip_len;	struct iphdr *ip;	struct tcphdr *thp;	unsigned char index;	if(isize < 20) {		/* The packet is shorter than a legal IP header */		comp->sls_i_runt++;		return slhc_toss( comp );	}	/* Sneak a peek at the IP header's IHL field to find its length */	ip_len = (icp[0] & 0xf) << 2;	if(ip_len < 20){		/* The IP header length field is too small */		comp->sls_i_runt++;		return slhc_toss( comp );	}	index = icp[9];	icp[9] = IPPROTO_TCP;	ip = (struct iphdr *) icp;	if (ip_csum(ip)) {		/* Bad IP header checksum; discard */		comp->sls_i_badcheck++;		return slhc_toss( comp );	}	thp = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4);	if(index > comp->rslot_limit) {		comp->sls_i_error++;		return slhc_toss(comp);	}	/* Update local state */	cs = &comp->rstate[comp->recv_current = index];	comp->flags &=~ SLF_TOSS;	memcpy(&cs->cs_ip,ip,20);	memcpy(&cs->cs_tcp,thp,20);	if (ip->ihl > 5)	  memcpy(cs->cs_ipopt, ip+1, ((ip->ihl) - 5) * 4);	if (thp->doff > 5)	  memcpy(cs->cs_tcpopt, thp+1, ((thp->doff) - 5) * 4);	cs->cs_hsize = ip->ihl*2 + thp->doff*2;	/* Put headers back on packet	 * Neither header checksum is recalculated	 */	comp->sls_i_uncompressed++;	return isize;}intslhc_toss(struct slcompress *comp){	if ( comp == NULLSLCOMPR )		return 0;	comp->flags |= SLF_TOSS;	return 0;}void slhc_i_status(struct slcompress *comp){	if (comp != NULLSLCOMPR) {		printk("\t%ld Cmp, %ld Uncmp, %ld Bad, %ld Tossed\n",			comp->sls_i_compressed,			comp->sls_i_uncompressed,			comp->sls_i_error,			comp->sls_i_tossed);	}}void slhc_o_status(struct slcompress *comp){	if (comp != NULLSLCOMPR) {		printk("\t%ld Cmp, %ld Uncmp, %ld AsIs, %ld NotTCP\n",			comp->sls_o_compressed,			comp->sls_o_uncompressed,			comp->sls_o_tcp,			comp->sls_o_nontcp);		printk("\t%10ld Searches, %10ld Misses\n",			comp->sls_o_searches,			comp->sls_o_misses);	}}

⌨️ 快捷键说明

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