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

📄 slhc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * 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;		goto uncompressed;		break;	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.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 */	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++;		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++;			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 */		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) {				goto bad;			}			thp->urg_ptr = htons(x);		} else			thp->urg = 0;		if(changes & NEW_W){			if((x = decode(&cp)) == -1) {				goto bad;			}			thp->window = htons( ntohs(thp->window) + x);		}		if(changes & NEW_A){			if((x = decode(&cp)) == -1) {				goto bad;			}			thp->ack_seq = htonl( ntohl(thp->ack_seq) + x);		}		if(changes & NEW_S){			if((x = decode(&cp)) == -1) {				goto bad;			}			thp->seq = htonl( ntohl(thp->seq) + x);		}		break;	}	if(changes & NEW_I){		if((x = decode(&cp)) == -1) {			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;	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;	}	put_unaligned(ip_fast_csum(icp, ip->ihl),		      &((struct iphdr *)icp)->check);	memcpy(cp, thp, 20);	cp += 20;	if (thp->doff > 5) {	  memcpy(cp, cs->cs_tcpopt, ((thp->doff) - 5) * 4);	  cp += ((thp->doff) - 5) * 4;	}	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;	unsigned ihl;	unsigned char index;	if(isize < 20) {		/* The packet is shorter than a legal IP header */		comp->sls_i_runt++;		return slhc_toss( comp );	}	/* Peek at the IP header's IHL field to find its length */	ihl = icp[0] & 0xf;	if(ihl < 20 / 4){		/* The IP header length field is too small */		comp->sls_i_runt++;		return slhc_toss( comp );	}	index = icp[9];	icp[9] = IPPROTO_TCP;	if (ip_fast_csum(icp, ihl)) {		/* Bad IP header checksum; discard */		comp->sls_i_badcheck++;		return slhc_toss( comp );	}	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,icp,20);	memcpy(&cs->cs_tcp,icp + ihl*4,20);	if (ihl > 5)	  memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4);	if (cs->cs_tcp.doff > 5)	  memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);	cs->cs_hsize = ihl*2 + cs->cs_tcp.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%d Cmp, %d Uncmp, %d Bad, %d 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%d Cmp, %d Uncmp, %d AsIs, %d NotTCP\n",			comp->sls_o_compressed,			comp->sls_o_uncompressed,			comp->sls_o_tcp,			comp->sls_o_nontcp);		printk("\t%10d Searches, %10d Misses\n",			comp->sls_o_searches,			comp->sls_o_misses);	}}/* Should this be surrounded with "#ifdef CONFIG_MODULES" ? *//* VJ header compression */EXPORT_SYMBOL(slhc_init);EXPORT_SYMBOL(slhc_free);EXPORT_SYMBOL(slhc_remember);EXPORT_SYMBOL(slhc_compress);EXPORT_SYMBOL(slhc_uncompress);EXPORT_SYMBOL(slhc_toss);#ifdef MODULEint init_module(void){	printk(KERN_INFO "CSLIP: code copyright 1989 Regents of the University of California\n");	return 0;}void cleanup_module(void){	return;}#endif /* MODULE */#else /* CONFIG_INET */intslhc_toss(struct slcompress *comp){  printk(KERN_DEBUG "Called IP function on non IP-system: slhc_toss");  return -EINVAL;}intslhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize){  printk(KERN_DEBUG "Called IP function on non IP-system: slhc_uncompress");  return -EINVAL;}intslhc_compress(struct slcompress *comp, unsigned char *icp, int isize,	unsigned char *ocp, unsigned char **cpp, int compress_cid){  printk(KERN_DEBUG "Called IP function on non IP-system: slhc_compress");  return -EINVAL;}intslhc_remember(struct slcompress *comp, unsigned char *icp, int isize){  printk(KERN_DEBUG "Called IP function on non IP-system: slhc_remember");  return -EINVAL;}voidslhc_free(struct slcompress *comp){  printk(KERN_DEBUG "Called IP function on non IP-system: slhc_free");  return;}struct slcompress *slhc_init(int rslots, int tslots){  printk(KERN_DEBUG "Called IP function on non IP-system: slhc_init");  return NULL;}EXPORT_SYMBOL(slhc_init);EXPORT_SYMBOL(slhc_free);EXPORT_SYMBOL(slhc_remember);EXPORT_SYMBOL(slhc_compress);EXPORT_SYMBOL(slhc_uncompress);EXPORT_SYMBOL(slhc_toss);#endif /* CONFIG_INET */

⌨️ 快捷键说明

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