示例#1
0
文件: ppp_comp.c 项目: TARRANUM/ppp
/* -----------------------------------------------------------------------------
Handle a CCP packet.  `rcvd' is 1 if the packet was received,
0 if it is about to be transmitted.
mbuf points to the ccp payload (doesn't include FF03 and 80FD)
----------------------------------------------------------------------------- */
void ppp_comp_ccp(struct ppp_if *wan, mbuf_t m, int rcvd)
{
    u_char 	*p = mbuf_data(m);
    int 	slen;
    
    slen = CCP_LENGTH(p);
    if (slen > mbuf_pkthdr_len(m)) {
        LOGDBG(wan->net, ("ppp_comp_ccp: not enough data in mbuf (expected = %d, got = %d)\n",
		   slen, mbuf_pkthdr_len(m)));
	return;
    }
    
    switch (CCP_CODE(p)) {
    case CCP_CONFREQ:
    case CCP_TERMREQ:
    case CCP_TERMACK:
	/* CCP must be going down - disable compression */
        wan->sc_flags &= ~(rcvd ? SC_COMP_RUN : SC_DECOMP_RUN);
	break;

    case CCP_CONFACK:
	if (wan->sc_flags & SC_CCP_OPEN && !(wan->sc_flags & SC_CCP_UP)
	    && slen >= CCP_HDRLEN + CCP_OPT_MINLEN
	    && slen >= CCP_OPT_LENGTH(p + CCP_HDRLEN) + CCP_HDRLEN) {
	    if (rcvd) {
		/* peer is agreeing to send compressed packets. */
		if (wan->rc_state
		    && (*wan->rcomp->decomp_init)
			(wan->rc_state, p + CCP_HDRLEN, slen - CCP_HDRLEN,
			 ifnet_unit(wan->net), 0, wan->mru, ifnet_flags(wan->net) & IFF_DEBUG)) {
		    wan->sc_flags |= SC_DECOMP_RUN;
		    wan->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR);
		}
	    } else {
		/* we're agreeing to send compressed packets. */
		if (wan->xc_state
		    && (*wan->xcomp->comp_init)
			(wan->xc_state, p + CCP_HDRLEN, slen - CCP_HDRLEN,
			 ifnet_unit(wan->net), 0, ifnet_mtu(wan->net), ifnet_flags(wan->net) & IFF_DEBUG)) {
		    wan->sc_flags |= SC_COMP_RUN;
		}
	    }
	}
	break;

    case CCP_RESETACK:
	if (wan->sc_flags & SC_CCP_UP) {
	    if (rcvd) {
		if (wan->rc_state && (wan->sc_flags & SC_DECOMP_RUN)) {
		    (*wan->rcomp->decomp_reset)(wan->rc_state);
		    wan->sc_flags &= ~SC_DC_ERROR;
		}
	    } else {
		if (wan->xc_state && (wan->sc_flags & SC_COMP_RUN))
		    (*wan->xcomp->comp_reset)(wan->xc_state);
	    }
	}
	break;
    }
}
示例#2
0
void
handle_ccp(struct pkt *cp, u_char *dp, int len)
{
    int clen;
    struct compressor **comp;

    if (len < CCP_HDRLEN)
	return;
    clen = CCP_LENGTH(dp);
    if (clen > len)
	return;

    switch (CCP_CODE(dp)) {
    case CCP_CONFACK:
	cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP);
	if (clen < CCP_HDRLEN + CCP_OPT_MINLEN
	    || clen < CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN))
	    break;
	dp += CCP_HDRLEN;
	clen -= CCP_HDRLEN;
	for (comp = compressors; *comp != NULL; ++comp) {
	    if ((*comp)->compress_proto == dp[0]) {
		if (cp->state != NULL) {
		    (*cp->comp->decomp_free)(cp->state);
		    cp->state = NULL;
		}
		cp->comp = *comp;
		cp->state = (*comp)->decomp_alloc(dp, CCP_OPT_LENGTH(dp));
		cp->flags |= CCP_ISUP;
		if (cp->state != NULL
		    && (*cp->comp->decomp_init)
		        (cp->state, dp, clen, 0, 0, 8192, 1))
		    cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN;
		break;
	    }
	}
	break;

    case CCP_CONFNAK:
    case CCP_CONFREJ:
	cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP);
	break;

    case CCP_RESETACK:
	if (cp->flags & CCP_ISUP) {
	    if (cp->state && (cp->flags & CCP_DECOMP_RUN)) {
		(*cp->comp->decomp_reset)(cp->state);
		cp->flags &= ~CCP_ERROR;
	    }
	}
	break;
    }
}