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

📄 if_spppsubr.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (debug)				addlog(" send conf-nak\n");			sppp_cp_send (sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf);		}		return 0;	} else {		if (debug)			addlog(" send conf-ack\n");		sp->fail_counter[IDX_LCP] = 0;		sp->pp_loopcnt = 0;		sppp_cp_send (sp, PPP_LCP, CONF_ACK,			      h->ident, origlen, h+1);	}	free (buf, M_TEMP);	return (rlen == 0);}/* * Analyze the LCP Configure-Reject option list, and adjust our * negotiation. */static voidsppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len){	STDDCL;	u_char *buf, *p;	len -= 4;	buf = malloc (len, M_TEMP, M_NOWAIT);	if (!buf)		return;	if (debug)		log(LOG_DEBUG, SPP_FMT "lcp rej opts: ",		    SPP_ARGS(ifp));	p = (void*) (h+1);	for (; 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 -- can't use it, use 0 */			sp->lcp.opts &= ~(1 << LCP_OPT_MAGIC);			sp->lcp.magic = 0;			break;		case LCP_OPT_MRU:			/*			 * Should not be rejected anyway, since we only			 * negotiate a MRU if explicitly requested by			 * peer.			 */			sp->lcp.opts &= ~(1 << LCP_OPT_MRU);			break;		case LCP_OPT_AUTH_PROTO:			/*			 * Peer doesn't want to authenticate himself,			 * deny unless this is a dialout call, and			 * AUTHFLAG_NOCALLOUT is set.			 */			if ((sp->pp_flags & PP_CALLIN) == 0 &&			    (sp->hisauth.flags & AUTHFLAG_NOCALLOUT) != 0) {				if (debug)					addlog("[don't insist on auth "					       "for callout]");				sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO);				break;			}			if (debug)				addlog("[access denied]\n");			lcp.Close(sp);			break;		}	}	if (debug)		addlog("\n");	free (buf, M_TEMP);	return;}/* * Analyze the LCP Configure-NAK option list, and adjust our * negotiation. */static voidsppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len){	STDDCL;	u_char *buf, *p;	u_long magic;	len -= 4;	buf = malloc (len, M_TEMP, M_NOWAIT);	if (!buf)		return;	if (debug)		log(LOG_DEBUG, SPP_FMT "lcp nak opts: ",		    SPP_ARGS(ifp));	p = (void*) (h+1);	for (; 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 -- renegotiate */			if ((sp->lcp.opts & (1 << LCP_OPT_MAGIC)) &&			    len >= 6 && p[1] == 6) {				magic = (u_long)p[2] << 24 |					(u_long)p[3] << 16 | p[4] << 8 | p[5];				/*				 * If the remote magic is our negated one,				 * this looks like a loopback problem.				 * Suggest a new magic to make sure.				 */				if (magic == ~sp->lcp.magic) {					if (debug)						addlog("magic glitch ");#if defined(__FreeBSD__) && __FreeBSD__ >= 3					sp->lcp.magic = random();#else					sp->lcp.magic = time.tv_sec + time.tv_usec;#endif				} else {					sp->lcp.magic = magic;					if (debug)						addlog("%lu ", magic);				}			}			break;		case LCP_OPT_MRU:			/*			 * Peer wants to advise us to negotiate an MRU.			 * Agree on it if it's reasonable, or use			 * default otherwise.			 */			if (len >= 4 && p[1] == 4) {				u_int mru = p[2] * 256 + p[3];				if (debug)					addlog("%d ", mru);				if (mru < PP_MTU || mru > PP_MAX_MRU)					mru = PP_MTU;				sp->lcp.mru = mru;				sp->lcp.opts |= (1 << LCP_OPT_MRU);			}			break;		case LCP_OPT_AUTH_PROTO:			/*			 * Peer doesn't like our authentication method,			 * deny.			 */			if (debug)				addlog("[access denied]\n");			lcp.Close(sp);			break;		}	}	if (debug)		addlog("\n");	free (buf, M_TEMP);	return;}static voidsppp_lcp_tlu(struct sppp *sp){	STDDCL;	int i;	u_long mask;	/* XXX ? */	if (! (ifp->if_flags & IFF_UP) &&	    (ifp->if_flags & IFF_RUNNING)) {		/* Coming out of loopback mode. */		if_up(ifp);		printf (SPP_FMT "up\n", SPP_ARGS(ifp));	}	for (i = 0; i < IDX_COUNT; i++)		if ((cps[i])->flags & CP_QUAL)			(cps[i])->Open(sp);	if ((sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0 ||	    (sp->pp_flags & PP_NEEDAUTH) != 0)		sp->pp_phase = PHASE_AUTHENTICATE;	else		sp->pp_phase = PHASE_NETWORK;	if (debug)		log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp),		    sppp_phase_name(sp->pp_phase));	/*	 * Open all authentication protocols.  This is even required	 * if we already proceeded to network phase, since it might be	 * that remote wants us to authenticate, so we might have to	 * send a PAP request.  Undesired authentication protocols	 * don't do anything when they get an Open event.	 */	for (i = 0; i < IDX_COUNT; i++)		if ((cps[i])->flags & CP_AUTH)			(cps[i])->Open(sp);	if (sp->pp_phase == PHASE_NETWORK) {		/* Notify all NCPs. */		for (i = 0; i < IDX_COUNT; i++)			if ((cps[i])->flags & CP_NCP)				(cps[i])->Open(sp);	}	/* Send Up events to all started protos. */	for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1)		if (sp->lcp.protos & mask && ((cps[i])->flags & CP_LCP) == 0)			(cps[i])->Up(sp);	/* notify low-level driver of state change */	if (sp->pp_chg)		sp->pp_chg(sp, (int)sp->pp_phase);		if (sp->pp_phase == PHASE_NETWORK)		/* if no NCP is starting, close down */		sppp_lcp_check_and_close(sp);}static voidsppp_lcp_tld(struct sppp *sp){	STDDCL;	int i;	u_long mask;	sp->pp_phase = PHASE_TERMINATE;	if (debug)		log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp),		    sppp_phase_name(sp->pp_phase));	/*	 * Take upper layers down.  We send the Down event first and	 * the Close second to prevent the upper layers from sending	 * ``a flurry of terminate-request packets'', as the RFC	 * describes it.	 */	for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1)		if (sp->lcp.protos & mask && ((cps[i])->flags & CP_LCP) == 0) {			(cps[i])->Down(sp);			(cps[i])->Close(sp);		}}static voidsppp_lcp_tls(struct sppp *sp){	STDDCL;	sp->pp_phase = PHASE_ESTABLISH;	if (debug)		log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp),		    sppp_phase_name(sp->pp_phase));	/* Notify lower layer if desired. */	if (sp->pp_tls)		(sp->pp_tls)(sp);	else		(sp->pp_up)(sp);}static voidsppp_lcp_tlf(struct sppp *sp){	STDDCL;	sp->pp_phase = PHASE_DEAD;	if (debug)		log(LOG_DEBUG, SPP_FMT "phase %s\n", SPP_ARGS(ifp),		    sppp_phase_name(sp->pp_phase));	/* Notify lower layer if desired. */	if (sp->pp_tlf)		(sp->pp_tlf)(sp);	else		(sp->pp_down)(sp);}static voidsppp_lcp_scr(struct sppp *sp){	char opt[6 /* magicnum */ + 4 /* mru */ + 5 /* chap */];	int i = 0;	u_short authproto;	if (sp->lcp.opts & (1 << LCP_OPT_MAGIC)) {		if (! sp->lcp.magic)#if defined(__FreeBSD__) && __FreeBSD__ >= 3			sp->lcp.magic = random();#else			sp->lcp.magic = time.tv_sec + time.tv_usec;#endif		opt[i++] = LCP_OPT_MAGIC;		opt[i++] = 6;		opt[i++] = sp->lcp.magic >> 24;		opt[i++] = sp->lcp.magic >> 16;		opt[i++] = sp->lcp.magic >> 8;		opt[i++] = sp->lcp.magic;	}	if (sp->lcp.opts & (1 << LCP_OPT_MRU)) {		opt[i++] = LCP_OPT_MRU;		opt[i++] = 4;		opt[i++] = sp->lcp.mru >> 8;		opt[i++] = sp->lcp.mru;	}	if (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) {		authproto = sp->hisauth.proto;		opt[i++] = LCP_OPT_AUTH_PROTO;		opt[i++] = authproto == PPP_CHAP? 5: 4;		opt[i++] = authproto >> 8;		opt[i++] = authproto;		if (authproto == PPP_CHAP)			opt[i++] = CHAP_MD5;	}	sp->confid[IDX_LCP] = ++sp->pp_seq;	sppp_cp_send (sp, PPP_LCP, CONF_REQ, sp->confid[IDX_LCP], i, &opt);}/* * Check the open NCPs, return true if at least one NCP is open. */static intsppp_ncp_check(struct sppp *sp){	int i, mask;	for (i = 0, mask = 1; i < IDX_COUNT; i++, mask <<= 1)		if (sp->lcp.protos & mask && (cps[i])->flags & CP_NCP)			return 1;	return 0;}/* * Re-check the open NCPs and see if we should terminate the link. * Called by the NCPs during their tlf action handling. */static voidsppp_lcp_check_and_close(struct sppp *sp){	if (sp->pp_phase < PHASE_NETWORK)		/* don't bother, we are already going down */		return;	if (sppp_ncp_check(sp))		return;	lcp.Close(sp);}/* *--------------------------------------------------------------------------* *                                                                          * *                        The IPCP implementation.                          * *                                                                          * *--------------------------------------------------------------------------* */static voidsppp_ipcp_init(struct sppp *sp){	sp->ipcp.opts = 0;	sp->ipcp.flags = 0;	sp->state[IDX_IPCP] = STATE_INITIAL;	sp->fail_counter[IDX_IPCP] = 0;#if defined(__FreeBSD__) && __FreeBSD__ >= 3	callout_handle_init(&sp->ch[IDX_IPCP]);#endif}static voidsppp_ipcp_up(struct sppp *sp){	sppp_up_event(&ipcp, sp);}static voidsppp_ipcp_down(struct sppp *sp){	sppp_down_event(&ipcp, sp);}static voidsppp_ipcp_open(struct sppp *sp){	STDDCL;	u_long myaddr, hisaddr;	sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN|IPCP_MYADDR_SEEN|IPCP_MYADDR_DYN);	sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0);	/*	 * If we don't have his address, this probably means our	 * interface doesn't want to talk IP at all.  (This could	 * be the case if somebody wants to speak only IPX, for	 * example.)  Don't open IPCP in this case.	 */	if (hisaddr == 0L) {		/* XXX this message should go away */		if (debug)			log(LOG_DEBUG, SPP_FMT "ipcp_open(): no IP interface\n",			    SPP_ARGS(ifp));		return;	}	if (myaddr == 0L) {		/*		 * I don't have an assigned address, so i need to		 * negotiate my address.		 */		sp->ipcp.flags |= IPCP_MYADDR_DYN;		sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);	} else		sp->ipcp.flags |= IPCP_MYADDR_SEEN;	sppp_open_event(&ipcp, sp);}static voidsppp_ipcp_close(struct sppp *sp){	sppp_close_event(&ipcp, sp);	if (sp->ipcp.flags & IPCP_MYADDR_DYN)		/*		 * My address was dynamic, clear it again.		 */		sppp_set_ip_addr(sp, 0L);}static voidsppp_ipcp_TO(void *cookie){	sppp_to_event(&ipcp, (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_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len){	u_char *buf, *r, *p;	struct ifnet *ifp = &sp->pp_if;	int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;	u_long hisaddr, desiredaddr;	int gotmyaddr = 0;	len -= 4;	origlen = len;	/*	 * Make sure to allocate a buf that can at least hold a	 * conf-nak with an `address' option.  We might need it below.	 */	buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT);	if (! buf)		return (0);	/* pass 1: see if we can recognize them */	if (debug)		log(LOG_DEBUG, SPP_FMT "ipcp parse opts: ",		    SPP_ARGS(ifp));	p = (void*) (h+1);	for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {		if (debug)			addlog(" %s ", sppp_ipcp_opt_name(*p));		switch (*p) {#ifdef notyet		case IPCP_OPT_COMPRESSION:			if (len >= 6 && p[1] >= 6) {				/* correctly formed compress option */				continue;			}			if (debug)				addlog("[invalid] ");			break;#endif		case IPCP_OPT_ADDRESS:			if (len >= 6 && p[1] == 6) {				/* correctly formed address option */				continue;			}			if (debug)				addlog("[invalid] ");			break;		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_IPCP, CONF_REJ, h->ident, rlen, buf);		return 0;	} else if (debug)		addlog("\n");	/* pass 2: parse option values */	sppp_get_ip_addrs(sp, 0, &hisaddr, 0);	if (debug)		log(LOG_DEBUG, SPP_FMT "ipcp 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 (deb

⌨️ 快捷键说明

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