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

📄 if_spppsubr.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		break;	case STATE_STARTING:		sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;		(cp->scr)(sp);		sppp_cp_change_state(cp, sp, STATE_REQ_SENT);		break;	default:		printf(SPP_FMT "%s illegal up in state %s\n",		       SPP_ARGS(ifp), cp->name,		       sppp_state_name(sp->state[cp->protoidx]));	}}static voidsppp_down_event(const struct cp *cp, struct sppp *sp){	STDDCL;	if (debug)		log(LOG_DEBUG, SPP_FMT "%s down(%s)\n",		    SPP_ARGS(ifp), cp->name,		    sppp_state_name(sp->state[cp->protoidx]));	switch (sp->state[cp->protoidx]) {	case STATE_CLOSED:	case STATE_CLOSING:		sppp_cp_change_state(cp, sp, STATE_INITIAL);		break;	case STATE_STOPPED:		sppp_cp_change_state(cp, sp, STATE_STARTING);		(cp->tls)(sp);		break;	case STATE_STOPPING:	case STATE_REQ_SENT:	case STATE_ACK_RCVD:	case STATE_ACK_SENT:		sppp_cp_change_state(cp, sp, STATE_STARTING);		break;	case STATE_OPENED:		(cp->tld)(sp);		sppp_cp_change_state(cp, sp, STATE_STARTING);		break;	default:		printf(SPP_FMT "%s illegal down in state %s\n",		       SPP_ARGS(ifp), cp->name,		       sppp_state_name(sp->state[cp->protoidx]));	}}static voidsppp_open_event(const struct cp *cp, struct sppp *sp){	STDDCL;	if (debug)		log(LOG_DEBUG, SPP_FMT "%s open(%s)\n",		    SPP_ARGS(ifp), cp->name,		    sppp_state_name(sp->state[cp->protoidx]));	switch (sp->state[cp->protoidx]) {	case STATE_INITIAL:		sppp_cp_change_state(cp, sp, STATE_STARTING);		(cp->tls)(sp);		break;	case STATE_STARTING:		break;	case STATE_CLOSED:		sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;		(cp->scr)(sp);		sppp_cp_change_state(cp, sp, STATE_REQ_SENT);		break;	case STATE_STOPPED:	case STATE_STOPPING:	case STATE_REQ_SENT:	case STATE_ACK_RCVD:	case STATE_ACK_SENT:	case STATE_OPENED:		break;	case STATE_CLOSING:		sppp_cp_change_state(cp, sp, STATE_STOPPING);		break;	}}static voidsppp_close_event(const struct cp *cp, struct sppp *sp){	STDDCL;	if (debug)		log(LOG_DEBUG, SPP_FMT "%s close(%s)\n",		    SPP_ARGS(ifp), cp->name,		    sppp_state_name(sp->state[cp->protoidx]));	switch (sp->state[cp->protoidx]) {	case STATE_INITIAL:	case STATE_CLOSED:	case STATE_CLOSING:		break;	case STATE_STARTING:		sppp_cp_change_state(cp, sp, STATE_INITIAL);		(cp->tlf)(sp);		break;	case STATE_STOPPED:		sppp_cp_change_state(cp, sp, STATE_CLOSED);		break;	case STATE_STOPPING:		sppp_cp_change_state(cp, sp, STATE_CLOSING);		break;	case STATE_OPENED:		(cp->tld)(sp);		/* fall through */	case STATE_REQ_SENT:	case STATE_ACK_RCVD:	case STATE_ACK_SENT:		sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate;		sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq, 0, 0);		sppp_cp_change_state(cp, sp, STATE_CLOSING);		break;	}}static voidsppp_to_event(const struct cp *cp, struct sppp *sp){	STDDCL;	int s;	s = splimp();	if (debug)		log(LOG_DEBUG, SPP_FMT "%s TO(%s) rst_counter = %d\n",		    SPP_ARGS(ifp), cp->name,		    sppp_state_name(sp->state[cp->protoidx]),		    sp->rst_counter[cp->protoidx]);	if (--sp->rst_counter[cp->protoidx] < 0)		/* TO- event */		switch (sp->state[cp->protoidx]) {		case STATE_CLOSING:			sppp_cp_change_state(cp, sp, STATE_CLOSED);			(cp->tlf)(sp);			break;		case STATE_STOPPING:			sppp_cp_change_state(cp, sp, STATE_STOPPED);			(cp->tlf)(sp);			break;		case STATE_REQ_SENT:		case STATE_ACK_RCVD:		case STATE_ACK_SENT:			sppp_cp_change_state(cp, sp, STATE_STOPPED);			(cp->tlf)(sp);			break;		}	else		/* TO+ event */		switch (sp->state[cp->protoidx]) {		case STATE_CLOSING:		case STATE_STOPPING:			sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq,				     0, 0);			TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout, 			    sp->ch[cp->protoidx]);			break;		case STATE_REQ_SENT:		case STATE_ACK_RCVD:			(cp->scr)(sp);			/* sppp_cp_change_state() will restart the timer */			sppp_cp_change_state(cp, sp, STATE_REQ_SENT);			break;		case STATE_ACK_SENT:			(cp->scr)(sp);			TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout,			    sp->ch[cp->protoidx]);			break;		}	splx(s);}/* * Change the state of a control protocol in the state automaton. * Takes care of starting/stopping the restart timer. */voidsppp_cp_change_state(const struct cp *cp, struct sppp *sp, int newstate){	sp->state[cp->protoidx] = newstate;	UNTIMEOUT(cp->TO, (void *)sp, sp->ch[cp->protoidx]);	switch (newstate) {	case STATE_INITIAL:	case STATE_STARTING:	case STATE_CLOSED:	case STATE_STOPPED:	case STATE_OPENED:		break;	case STATE_CLOSING:	case STATE_STOPPING:	case STATE_REQ_SENT:	case STATE_ACK_RCVD:	case STATE_ACK_SENT:		TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout, 		    sp->ch[cp->protoidx]);		break;	}}/* *--------------------------------------------------------------------------* *                                                                          * *                         The LCP implementation.                          * *                                                                          * *--------------------------------------------------------------------------* */static voidsppp_lcp_init(struct sppp *sp){	sp->lcp.opts = (1 << LCP_OPT_MAGIC);	sp->lcp.magic = 0;	sp->state[IDX_LCP] = STATE_INITIAL;	sp->fail_counter[IDX_LCP] = 0;	sp->lcp.protos = 0;	sp->lcp.mru = sp->lcp.their_mru = PP_MTU;	/*	 * Initialize counters and timeout values.  Note that we don't	 * use the 3 seconds suggested in RFC 1661 since we are likely	 * running on a fast link.  XXX We should probably implement	 * the exponential backoff option.  Note that these values are	 * relevant for all control protocols, not just LCP only.	 */	sp->lcp.timeout = 1 * hz;	sp->lcp.max_terminate = 2;	sp->lcp.max_configure = 10;	sp->lcp.max_failure = 10;#if defined(__FreeBSD__) && __FreeBSD__ >= 3	callout_handle_init(&sp->ch[IDX_LCP]);#endif}static voidsppp_lcp_up(struct sppp *sp){	STDDCL;	/*	 * If this interface is passive or dial-on-demand, and we are	 * still in Initial state, it means we've got an incoming	 * call.  Activate the interface.	 */	if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) != 0) {		if (debug)			log(LOG_DEBUG,			    SPP_FMT "Up event", SPP_ARGS(ifp));		ifp->if_flags |= IFF_RUNNING;		if (sp->state[IDX_LCP] == STATE_INITIAL) {			if (debug)				addlog("(incoming call)\n");			sp->pp_flags |= PP_CALLIN;			lcp.Open(sp);		} else if (debug)			addlog("\n");	}	sppp_up_event(&lcp, sp);}static voidsppp_lcp_down(struct sppp *sp){	STDDCL;	sppp_down_event(&lcp, sp);	/*	 * If this is neither a dial-on-demand nor a passive	 * interface, simulate an ``ifconfig down'' action, so the	 * administrator can force a redial by another ``ifconfig	 * up''.  XXX For leased line operation, should we immediately	 * try to reopen the connection here?	 */	if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0) {		log(LOG_INFO,		    SPP_FMT "Down event, taking interface down.\n",		    SPP_ARGS(ifp));		if_down(ifp);	} else {		if (debug)			log(LOG_DEBUG,			    SPP_FMT "Down event (carrier loss)\n",			    SPP_ARGS(ifp));	}	sp->pp_flags &= ~PP_CALLIN;	if (sp->state[IDX_LCP] != STATE_INITIAL)		lcp.Close(sp);	ifp->if_flags &= ~IFF_RUNNING;}static voidsppp_lcp_open(struct sppp *sp){	/*	 * If we are authenticator, negotiate LCP_AUTH	 */	if (sp->hisauth.proto != 0)		sp->lcp.opts |= (1 << LCP_OPT_AUTH_PROTO);	else		sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO);	sp->pp_flags &= ~PP_NEEDAUTH;	sppp_open_event(&lcp, sp);}static voidsppp_lcp_close(struct sppp *sp){	sppp_close_event(&lcp, sp);}static voidsppp_lcp_TO(void *cookie){	sppp_to_event(&lcp, (struct sppp *)cookie);}/* * Analyze a configure request.  Return true if it was agreeable, and * caused action sca, false if it has been rejected or nak'ed, and * caused action scn.  (The return value is used to make the state * transition decision in the state automaton.) */static intsppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len){	STDDCL;	u_char *buf, *r, *p;	int origlen, rlen;	u_long nmagic;	u_short authproto;	len -= 4;	origlen = len;	buf = r = malloc (len, M_TEMP, M_NOWAIT);	if (! buf)		return (0);	if (debug)		log(LOG_DEBUG, SPP_FMT "lcp parse opts: ",		    SPP_ARGS(ifp));	/* pass 1: check for things that need to be rejected */	p = (void*) (h+1);	for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {		if (debug)			addlog(" %s ", sppp_lcp_opt_name(*p));		switch (*p) {		case LCP_OPT_MAGIC:			/* Magic number. */			/* fall through, both are same length */		case LCP_OPT_ASYNC_MAP:			/* Async control character map. */			if (len >= 6 || p[1] == 6)				continue;			if (debug)				addlog("[invalid] ");			break;		case LCP_OPT_MRU:			/* Maximum receive unit. */			if (len >= 4 && p[1] == 4)				continue;			if (debug)				addlog("[invalid] ");			break;		case LCP_OPT_AUTH_PROTO:			if (len < 4) {				if (debug)					addlog("[invalid] ");				break;			}			authproto = (p[2] << 8) + p[3];			if (authproto == PPP_CHAP && p[1] != 5) {				if (debug)					addlog("[invalid chap len] ");				break;			}			if (sp->myauth.proto == 0) {				/* we are not configured to do auth */				if (debug)					addlog("[not configured] ");				break;			}			/*			 * Remote want us to authenticate, remember this,			 * so we stay in PHASE_AUTHENTICATE after LCP got			 * up.			 */			sp->pp_flags |= PP_NEEDAUTH;			continue;		default:			/* Others not supported. */			if (debug)				addlog("[rej] ");			break;		}		/* Add the option to rejected list. */		bcopy (p, r, p[1]);		r += p[1];		rlen += p[1];	}	if (rlen) {		if (debug)			addlog(" send conf-rej\n");		sppp_cp_send (sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf);		return 0;	} else if (debug)		addlog("\n");	/*	 * pass 2: check for option values that are unacceptable and	 * thus require to be nak'ed.	 */	if (debug)		log(LOG_DEBUG, SPP_FMT "lcp parse opt values: ",		    SPP_ARGS(ifp));	p = (void*) (h+1);	len = origlen;	for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {		if (debug)			addlog(" %s ", sppp_lcp_opt_name(*p));		switch (*p) {		case LCP_OPT_MAGIC:			/* Magic number -- extract. */			nmagic = (u_long)p[2] << 24 |				(u_long)p[3] << 16 | p[4] << 8 | p[5];			if (nmagic != sp->lcp.magic) {				if (debug)					addlog("0x%lx ", nmagic);				continue;			}			/*			 * Local and remote magics equal -- loopback?			 */			if (sp->pp_loopcnt >= MAXALIVECNT*5) {				printf (SPP_FMT "loopback\n",					SPP_ARGS(ifp));				sp->pp_loopcnt = 0;				if (ifp->if_flags & IFF_UP) {					if_down(ifp);					sppp_qflush(&sp->pp_cpq);					/* XXX ? */					lcp.Down(sp);					lcp.Up(sp);				}			} else if (debug)				addlog("[glitch] ");			++sp->pp_loopcnt;			/*			 * We negate our magic here, and NAK it.  If			 * we see it later in an NAK packet, we			 * suggest a new one.			 */			nmagic = ~sp->lcp.magic;			/* Gonna NAK it. */			p[2] = nmagic >> 24;			p[3] = nmagic >> 16;			p[4] = nmagic >> 8;			p[5] = nmagic;			break;		case LCP_OPT_ASYNC_MAP:			/* Async control character map -- check to be zero. */			if (! p[2] && ! p[3] && ! p[4] && ! p[5]) {				if (debug)					addlog("[empty] ");				continue;			}			if (debug)				addlog("[non-empty] ");			/* suggest a zero one */			p[2] = p[3] = p[4] = p[5] = 0;			break;		case LCP_OPT_MRU:			/*			 * Maximum receive unit.  Always agreeable,			 * but ignored by now.			 */			sp->lcp.their_mru = p[2] * 256 + p[3];			if (debug)				addlog("%lu ", sp->lcp.their_mru);			continue;		case LCP_OPT_AUTH_PROTO:			authproto = (p[2] << 8) + p[3];			if (sp->myauth.proto != authproto) {				/* not agreed, nak */				if (debug)					addlog("[mine %s != his %s] ",					       sppp_proto_name(sp->hisauth.proto),					       sppp_proto_name(authproto));				p[2] = sp->myauth.proto >> 8;				p[3] = sp->myauth.proto;				break;			}			if (authproto == PPP_CHAP && p[4] != CHAP_MD5) {				if (debug)					addlog("[chap not MD5] ");				p[4] = CHAP_MD5;				break;			}			continue;		}		/* Add the option to nak'ed list. */		bcopy (p, r, p[1]);		r += p[1];		rlen += p[1];	}	if (rlen) {		if (++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) {			if (debug)				addlog(" max_failure (%d) exceeded, "				       "send conf-rej\n",				       sp->lcp.max_failure);			sppp_cp_send(sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf);		} else {

⌨️ 快捷键说明

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