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

📄 vjcompress.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 ((deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack)) > 0) {	if (deltaA > 0xffff)	    goto uncompressed;	ENCODE(deltaA);	changes |= NEW_A;    }    if ((deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq)) > 0) {	if (deltaS > 0xffff)	    goto uncompressed;	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 = 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 = cp - new_seq;    cp = (u_char *)ip;    if (compress_cid == 0 || comp->last_xmit != cs->cs_id) {	comp->last_xmit = cs->cs_id;	hlen -= deltaS + 4;	*vjhdrp = (cp += hlen);	*cp++ = changes | NEW_C;	*cp++ = cs->cs_id;    } else {	hlen -= deltaS + 3;	*vjhdrp = (cp += hlen);	*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. */voidvj_uncompress_err(comp)    struct vjcompress *comp;{    comp->flags |= VJF_TOSS;    INCR(vjs_errorin);}/* * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. */intvj_uncompress_uncomp(buf, buflen, comp)    u_char *buf;    int buflen;    struct vjcompress *comp;{    register u_int hlen;    register struct cstate *cs;    register struct ip *ip;    ip = (struct ip *) buf;    hlen = getip_hl(*ip) << 2;    if (ip->ip_p >= MAX_STATES	|| hlen + sizeof(struct tcphdr) > buflen	|| (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)	    > buflen	|| hlen > MAX_HDR) {	comp->flags |= VJF_TOSS;	INCR(vjs_errorin);	return (0);    }    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 (1);}/* * Uncompress a packet of type TYPE_COMPRESSED_TCP. * The packet starts at buf and is of total length total_len. * The first buflen bytes are at buf; this must include the entire * compressed TCP/IP header.  This procedure returns the length * of the VJ header, with a pointer to the uncompressed IP header * in *hdrp and its length in *hlenp. */intvj_uncompress_tcp(buf, buflen, total_len, comp, hdrp, hlenp)    u_char *buf;    int buflen, total_len;    struct vjcompress *comp;    u_char **hdrp;    u_int *hlenp;{    register u_char *cp;    register u_int hlen, changes;    register struct tcphdr *th;    register struct cstate *cs;    register u_short *bp;    register u_int vjlen;    register u_int32_t tmp;    INCR(vjs_compressedin);    cp = buf;    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_STATES)	    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) {	    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 |= 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 = cp - buf;    buflen -= vjlen;    if (buflen < 0)	/* we must have dropped some characters (crc should detect	 * this but the old slip framing won't) */	goto bad;    total_len += cs->cs_hlen - vjlen;    cs->cs_ip.ip_len = htons(total_len);    /* recompute the ip header checksum */    bp = (u_short *) &cs->cs_ip;    cs->cs_ip.ip_sum = 0;    for (changes = 0; hlen > 0; hlen -= 2)	changes += *bp++;    changes = (changes & 0xffff) + (changes >> 16);    changes = (changes & 0xffff) + (changes >> 16);    cs->cs_ip.ip_sum = ~ changes;    *hdrp = (u_char *) &cs->cs_ip;    *hlenp = cs->cs_hlen;    return vjlen; bad:    comp->flags |= VJF_TOSS;    INCR(vjs_errorin);    return (-1);}

⌨️ 快捷键说明

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