示例#1
0
文件: ccp.c 项目: rtemss/rtems
/*
 * ccp_input - process a received CCP packet.
 */
static void
ccp_input(
    int unit,
    u_char *p,
    int len)
{
    fsm *f = &ccp_fsm[unit];
    int oldstate;

    /*
     * Check for a terminate-request so we can print a message.
     */
    oldstate = f->state;
    fsm_input(f, p, len);
    if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED)
        notice("Compression disabled by peer.");

    /*
     * If we get a terminate-ack and we're not asking for compression,
     * close CCP.
     */
    if (oldstate == REQSENT && p[0] == TERMACK
            && !ANY_COMPRESS(ccp_gotoptions[unit]))
        ccp_close(unit, "No compression negotiated");
}
示例#2
0
static void
ccp_input (T_NET_BUF *nbuf)
{
	NET_COUNT_PPP_CCP(net_count_ppp_ccp_in_octets,  nbuf->len);
	NET_COUNT_PPP_CCP(net_count_ppp_ccp_in_packets, 1);
	fsm_input(&ccp_fsm, nbuf);
	}
示例#3
0
/*
 * ccp_input - process a received CCP packet.
 */
void
ccp_input(PPP_IF_VAR_T *pPppIf, u_char *p, int len)
{
    fsm *f = &pPppIf->ccp_fsm;
    int oldstate;

    /*
     * Check for a terminate-request so we can print a message.
     */
    oldstate = f->state;
    fsm_input(f, p, len);
    if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED){
	syslog(SYS_LOG_NOTICE, "Compression disabled by peer.");
	diag_printf("Compression disabled by peer.\n");
#ifdef MPPE
	if (pPppIf->ccp_wantoptions.mppe) {
 	    diag_printf("MPPE disabled, closing LCP\n");
 	    lcp_close(pPppIf);
 	}
#endif /* MPPE */
	}
    /*
     * If we get a terminate-ack and we're not asking for compression,
     * close CCP.
     */
    if (oldstate == REQSENT && p[0] == TERMACK
	&& !ANY_COMPRESS(f->pPppIf->ccp_gotoptions))
	ccp_close(pPppIf);
}
示例#4
0
文件: ipcp.c 项目: AlexShiLucky/rtems
/*
 * ipcp_input - Input IPCP packet.
 */
static void
ipcp_input(
    int unit,
    u_char *p,
    int len)
{
    fsm_input(&ipcp_fsm[unit], p, len);
}
示例#5
0
文件: lcp.c 项目: AoLaD/rtems
/*
 * lcp_input - Input LCP packet.
 */
static void
lcp_input(
    int unit,
    u_char *p,
    int len)
{
    fsm *f = &lcp_fsm[unit];

    fsm_input(f, p, len);
}
示例#6
0
/**
 * Receive the PPP packet.
 * @param	flags	Indicate information of received packet by bit flags.
 *			{@link ::PPP_IO_FLAGS_MPPE_ENCRYPTED} and
 *			{@link ::PPP_IO_FLAGS_DELAYED} may be used.
 * @return	return 0 on success.  return 1 on failure.
 */
static int
ppp_recv_packet(npppd_ppp *_this, unsigned char *pkt, int lpkt, int flags)
{
	u_char *inp, *inp_proto;
	uint16_t proto;

	PPP_ASSERT(_this != NULL);

	inp = pkt;

	if (lpkt < 4) {
		ppp_log(_this, LOG_DEBUG, "%s(): Rcvd short header.", __func__);
		return 0;
	}


	if (_this->has_acf == 0) {
		/* nothing to do */
	} else if (inp[0] == PPP_ALLSTATIONS && inp[1] == PPP_UI) {
		inp += 2;
	} else {
		/*
		 * Address and Control Field Compression
		 */
		if (!psm_opt_is_accepted(&_this->lcp, acfc) &&
		    _this->logged_no_address == 0) {
			/*
			 * On packet loss condition, we may receive ACFC'ed
			 * packets before our LCP is opened because the peer's
			 * LCP is opened already.
			 */
			ppp_log(_this, LOG_INFO,
			    "%s: Rcvd broken frame.  ACFC is not accepted, "
			    "but received ppp frame that has no address.",
			    __func__);
			/*
			 * Log this once because it may be noisy.
			 * For example, Yahama RTX-1000 refuses to use ACFC
			 * but it send PPP frames without the address field.
			 */
			_this->logged_no_address = 1;
		}
	}
	inp_proto = inp;
	if ((inp[0] & 0x01) != 0) {
		/*
		 * Protocol Field Compression
		 */
		if (!psm_opt_is_accepted(&_this->lcp, pfc)) {
			ppp_log(_this, LOG_INFO,
			    "%s: Rcvd broken frame.  No protocol field: "
			    "%02x %02x", __func__, inp[0], inp[1]);
			return 1;
		}
		GETCHAR(proto, inp);
	} else {
		GETSHORT(proto, inp);
	}

	/*
	 * if the PPP frame is reordered, drop it
	 * unless proto is reorder-tolerant
	 */
	if (flags & PPP_IO_FLAGS_DELAYED && proto != PPP_PROTO_IP)
		return 1;

	if (_this->log_dump_in != 0 && debug_get_debugfp() != NULL) {
		char buf[256];

		snprintf(buf, sizeof(buf), "log.%s.in.pktdump",
		    proto_name(proto));
		if (ppp_config_str_equal(_this, buf, "true", 0) != 0)  {
			ppp_log(_this, LOG_DEBUG,
			    "PPP input dump proto=%s(%d/%04x)",
			    proto_name(proto), proto, proto);
			show_hd(debug_get_debugfp(), pkt, lpkt);
		}
	}
#ifdef USE_NPPPD_PIPEX
	if (_this->pipex_enabled != 0 &&
	    _this->tunnel_type == PPP_TUNNEL_PPPOE) {
		switch (proto) {
		case PPP_PROTO_IP:
			return 2;		/* handled by PIPEX */
		case PPP_PROTO_NCP | NCP_CCP:
			if (lpkt - (inp - pkt) < 4)
				break;		/* error but do it on fsm.c */
			if (*inp == 0x0e ||	/* Reset-Request */
			    *inp == 0x0f	/* Reset-Ack */) {
				return 2;	/* handled by PIPEX */
			}
			/* FALLTHROUGH */
		default:
			break;
		}
	}
#endif /* USE_NPPPD_PIPEX */

	switch (proto) {
#ifdef	USE_NPPPD_MPPE
	case PPP_PROTO_IP:
		/* Checks for MPPE */
		if ((flags & PPP_IO_FLAGS_MPPE_ENCRYPTED) == 0) {
			if (MPPE_REQUIRED(_this)) {
				/* MPPE is required but naked ip */

				if (_this->logged_naked_ip == 0) {
					ppp_log(_this, LOG_INFO,
					    "mppe is required but received "
					    "naked IP.");
					/* log this once */
					_this->logged_naked_ip = 1;
				}
				/*
				 * Windows sends naked IP packets in condition
				 * such that MPPE is not opened and IPCP is not
				 * opened(*1).  This occurs at a high
				 * probability when the CCP establishment is
				 * delayed because of packet loss etc.  If we
				 * call ppp_stop() here, Windows on the packet
				 * loss condition etc cannot not connect us.
				 * So we don't call ppp_stop() here.
				 * (*1) At least Microsof Windows 2000
				 * Professional SP4 does.
				 */
				 /*ppp_stop(_this, "Encryption is required.");*/

				return 1;
			}
			if (MPPE_READY(_this)) {
				/* MPPE is opened but naked ip packet */
				ppp_log(_this, LOG_WARNING,
				    "mppe is available but received naked IP.");
			}
		}
		/* else input from MPPE */
		break;
	case PPP_PROTO_MPPE:
#ifdef USE_NPPPD_MPPE
		if (_this->mppe_started == 0)  {
#else
		{
#endif
			ppp_log(_this, LOG_ERR,
			    "mppe packet is received but mppe is stopped.");
			return 1;
		}
		break;
#endif
	}

	switch (proto) {
	case PPP_PROTO_IP:
		npppd_network_output(_this->pppd, _this, AF_INET, inp,
		    lpkt - (inp - pkt));
		goto handled;
	case PPP_PROTO_LCP:
		fsm_input(&_this->lcp.fsm, inp, lpkt - (inp - pkt));
		goto handled;
	case PPP_PROTO_PAP:
		pap_input(&_this->pap, inp, lpkt - (inp - pkt));
		goto handled;
	case PPP_PROTO_CHAP:
		chap_input(&_this->chap, inp, lpkt - (inp - pkt));
		goto handled;
#ifdef USE_NPPPD_EAP_RADIUS
	case PPP_PROTO_EAP:
		eap_input(&_this->eap, inp, lpkt - (inp - pkt));
		goto handled;
#endif
#ifdef	USE_NPPPD_MPPE
	case PPP_PROTO_MPPE:
#ifdef USE_NPPPD_PIPEX
		if (_this->pipex_enabled != 0)
			return -1; /* silent discard */
#endif /* USE_NPPPD_PIPEX */
		mppe_input(&_this->mppe, inp, lpkt - (inp - pkt));
		goto handled;
#endif
	default:
		if ((proto & 0xff00) == PPP_PROTO_NCP) {
			switch (proto & 0xff) {
			case NCP_CCP:	/* Compression */
#ifdef	USE_NPPPD_MPPE
				if (MPPE_MUST_NEGO(_this)) {
					fsm_input(&_this->ccp.fsm, inp,
					    lpkt - (inp - pkt));
					goto handled;
				}
				/* protocol-reject if MPPE is not necessary */
#endif
				break;
			case NCP_IPCP:	/* IPCP */
				fsm_input(&_this->ipcp.fsm, inp,
				    lpkt - (inp - pkt));
				goto handled;
			}
		}
	}
	/* Protocol reject.  Log it with protocol number */
	ppp_log(_this, LOG_INFO, "unhandled protocol %s, %d(%04x)",
	    proto_name(proto), proto, proto);

	if ((flags & PPP_IO_FLAGS_MPPE_ENCRYPTED) != 0) {
		/*
		 * Don't return a protocol-reject for the packet was encrypted,
		 * because lcp protocol-reject is not encrypted by mppe.
		 */
	} else {
		/*
		 * as RFC1661: Rejected-Information MUST be truncated to
		 * comply with the peer's established MRU.
		 */
		lcp_send_protrej(&_this->lcp, inp_proto,
		    MIN(lpkt - (inp_proto - pkt), NPPPD_MIN_MRU - 32));
	}

	return 1;
handled:

	return 0;
}

/** This function is called to output PPP packets */
inline void
ppp_output(npppd_ppp *_this, uint16_t proto, u_char code, u_char id,
    u_char *datap, int ldata)
{
	u_char *outp;
	int outlen, hlen, is_lcp = 0;

	outp = _this->outpacket_buf;

	/* No header compressions for LCP */
	is_lcp = (proto == PPP_PROTO_LCP)? 1 : 0;

	if (_this->has_acf == 0 ||
	    (!is_lcp && psm_peer_opt_is_accepted(&_this->lcp, acfc))) {
		/*
		 * Don't add ACF(Address and Control Field) if ACF is not
		 * needed on this link or ACFC is negotiated.
		 */
	} else {
		PUTCHAR(PPP_ALLSTATIONS, outp);
		PUTCHAR(PPP_UI, outp);
	}
	if (!is_lcp && proto <= 0xff &&
	    psm_peer_opt_is_accepted(&_this->lcp, pfc)) {
		/*
		 * Protocol Field Compression
		 */
		PUTCHAR(proto, outp);
	} else {
		PUTSHORT(proto, outp);
	}
	hlen = outp - _this->outpacket_buf;

	if (_this->mru > 0) {
		if (MRU_PKTLEN(_this->mru, proto) < ldata) {
			PPP_DBG((_this, LOG_ERR, "packet too large %d. mru=%d",
			    ldata , _this->mru));
			_this->oerrors++;
			PPP_ASSERT("NOT REACHED HERE" == NULL);
			return;
		}
	}

	if (code != 0) {
		outlen = ldata + HEADERLEN;

		PUTCHAR(code, outp);
		PUTCHAR(id, outp);
		PUTSHORT(outlen, outp);
	} else {
		outlen = ldata;
	}

	if (outp != datap && ldata > 0)
		memmove(outp, datap, ldata);

	if (_this->log_dump_out != 0 && debug_get_debugfp() != NULL) {
		char buf[256];

		snprintf(buf, sizeof(buf), "log.%s.out.pktdump",
		    proto_name(proto));
		if (ppp_config_str_equal(_this, buf, "true", 0) != 0)  {
			ppp_log(_this, LOG_DEBUG,
			    "PPP output dump proto=%s(%d/%04x)",
			    proto_name(proto), proto, proto);
			show_hd(debug_get_debugfp(),
			    _this->outpacket_buf, outlen + hlen);
		}
	}
	_this->send_packet(_this, _this->outpacket_buf, outlen + hlen, 0);
}