static int ccp_nakci()

in net/ip/lwip_base/src/netif/ppp/ccp.c [928:1016]


static int ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) {
    ppp_pcb *pcb = f->pcb;
    ccp_options *go = &pcb->ccp_gotoptions;
    ccp_options no;		/* options we've seen already */
    ccp_options try_;		/* options to ask for next time */
    LWIP_UNUSED_ARG(treat_as_reject);
#if !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT
    LWIP_UNUSED_ARG(p);
    LWIP_UNUSED_ARG(len);
#endif /* !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */

    memset(&no, 0, sizeof(no));
    try_ = *go;

#if MPPE_SUPPORT
    if (go->mppe && len >= CILEN_MPPE
	&& p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
	no.mppe = 1;
	/*
	 * Peer wants us to use a different strength or other setting.
	 * Fail if we aren't willing to use his suggestion.
	 */
	MPPE_CI_TO_OPTS(&p[2], try_.mppe);
	if ((try_.mppe & MPPE_OPT_STATEFUL) && pcb->settings.refuse_mppe_stateful) {
	    ppp_error("Refusing MPPE stateful mode offered by peer");
	    try_.mppe = 0;
	} else if (((go->mppe | MPPE_OPT_STATEFUL) & try_.mppe) != try_.mppe) {
	    /* Peer must have set options we didn't request (suggest) */
	    try_.mppe = 0;
	}

	if (!try_.mppe) {
	    ppp_error("MPPE required but peer negotiation failed");
	    lcp_close(pcb, "MPPE required but peer negotiation failed");
	}
    }
#endif /* MPPE_SUPPORT */
#if DEFLATE_SUPPORT
    if (go->deflate && len >= CILEN_DEFLATE
	&& p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
	&& p[1] == CILEN_DEFLATE) {
	no.deflate = 1;
	/*
	 * Peer wants us to use a different code size or something.
	 * Stop asking for Deflate if we don't understand his suggestion.
	 */
	if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
	    || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS
	    || p[3] != DEFLATE_CHK_SEQUENCE)
	    try_.deflate = 0;
	else if (DEFLATE_SIZE(p[2]) < go->deflate_size)
	    try_.deflate_size = DEFLATE_SIZE(p[2]);
	p += CILEN_DEFLATE;
	len -= CILEN_DEFLATE;
	if (go->deflate_correct && go->deflate_draft
	    && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
	    && p[1] == CILEN_DEFLATE) {
	    p += CILEN_DEFLATE;
	    len -= CILEN_DEFLATE;
	}
    }
#endif /* DEFLATE_SUPPORT */
#if BSDCOMPRESS_SUPPORT
    if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
	&& p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
	no.bsd_compress = 1;
	/*
	 * Peer wants us to use a different number of bits
	 * or a different version.
	 */
	if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION)
	    try_.bsd_compress = 0;
	else if (BSD_NBITS(p[2]) < go->bsd_bits)
	    try_.bsd_bits = BSD_NBITS(p[2]);
	p += CILEN_BSD_COMPRESS;
	len -= CILEN_BSD_COMPRESS;
    }
#endif /* BSDCOMPRESS_SUPPORT */

    /*
     * Predictor-1 and 2 have no options, so they can't be Naked.
     *
     * There may be remaining options but we ignore them.
     */

    if (f->state != PPP_FSM_OPENED)
	*go = try_;
    return 1;
}