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

📄 if_spppsubr.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	default:		if (debug)			addlog(SPP_FMT "cisco unknown packet type: 0x%lx\n",			       SPP_ARGS(ifp), (u_long)ntohl (h->type));		break;	case CISCO_ADDR_REPLY:		/* Reply on address request, ignore */		break;	case CISCO_KEEPALIVE_REQ:		sp->pp_alivecnt = 0;		sp->pp_rseq = ntohl (h->par1);		if (sp->pp_seq == sp->pp_rseq) {			/* Local and remote sequence numbers are equal.			 * Probably, the line is in loopback mode. */			if (sp->pp_loopcnt >= MAXALIVECNT) {				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);				}			}			++sp->pp_loopcnt;			/* Generate new local sequence number */#if defined(__FreeBSD__) && __FreeBSD__ >= 3			sp->pp_seq = random();#else			sp->pp_seq ^= time.tv_sec ^ time.tv_usec;#endif			break;		}		sp->pp_loopcnt = 0;		if (! (ifp->if_flags & IFF_UP) &&		    (ifp->if_flags & IFF_RUNNING)) {			if_up(ifp);			printf (SPP_FMT "up\n", SPP_ARGS(ifp));		}		break;	case CISCO_ADDR_REQ:		sppp_get_ip_addrs(sp, &me, 0, &mymask);		if (me != 0L)			sppp_cisco_send(sp, CISCO_ADDR_REPLY, me, mymask);		break;	}}/* * Send Cisco keepalive packet. */static voidsppp_cisco_send(struct sppp *sp, int type, long par1, long par2){	STDDCL;	struct ppp_header *h;	struct cisco_packet *ch;	struct mbuf *m;#if defined(__FreeBSD__) && __FreeBSD__ >= 3	struct timeval tv;#else	u_long t = (time.tv_sec - boottime.tv_sec) * 1000;#endif#if defined(__FreeBSD__) && __FreeBSD__ >= 3	getmicrouptime(&tv);#endif		MGETHDR (m, M_DONTWAIT, MT_DATA);	if (! m)		return;	m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + CISCO_PACKET_LEN;	m->m_pkthdr.rcvif = 0;	h = mtod (m, struct ppp_header*);	h->address = CISCO_MULTICAST;	h->control = 0;	h->protocol = htons (CISCO_KEEPALIVE);	ch = (struct cisco_packet*) (h + 1);	ch->type = htonl (type);	ch->par1 = htonl (par1);	ch->par2 = htonl (par2);	ch->rel = -1;#if defined(__FreeBSD__) && __FreeBSD__ >= 3	ch->time0 = htons ((u_short) (tv.tv_sec >> 16));	ch->time1 = htons ((u_short) tv.tv_sec);#else	ch->time0 = htons ((u_short) (t >> 16));	ch->time1 = htons ((u_short) t);#endif	if (debug)		log(LOG_DEBUG,		    SPP_FMT "cisco output: <0x%lx 0x%lx 0x%lx 0x%x 0x%x-0x%x>\n",			SPP_ARGS(ifp), (u_long)ntohl (ch->type), (u_long)ch->par1,			(u_long)ch->par2, (u_int)ch->rel, (u_int)ch->time0, (u_int)ch->time1);	if (IF_QFULL (&sp->pp_cpq)) {		IF_DROP (&sp->pp_fastq);		IF_DROP (&ifp->if_snd);		m_freem (m);	} else		IF_ENQUEUE (&sp->pp_cpq, m);	if (! (ifp->if_flags & IFF_OACTIVE))		(*ifp->if_start) (ifp);	ifp->if_obytes += m->m_pkthdr.len + 3;}/* * PPP protocol implementation. *//* * Send PPP control protocol packet. */static voidsppp_cp_send(struct sppp *sp, u_short proto, u_char type,	     u_char ident, u_short len, void *data){	STDDCL;	struct ppp_header *h;	struct lcp_header *lh;	struct mbuf *m;	if (len > MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN)		len = MHLEN - PPP_HEADER_LEN - LCP_HEADER_LEN;	MGETHDR (m, M_DONTWAIT, MT_DATA);	if (! m)		return;	m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + LCP_HEADER_LEN + len;	m->m_pkthdr.rcvif = 0;	h = mtod (m, struct ppp_header*);	h->address = PPP_ALLSTATIONS;        /* broadcast address */	h->control = PPP_UI;                 /* Unnumbered Info */	h->protocol = htons (proto);         /* Link Control Protocol */	lh = (struct lcp_header*) (h + 1);	lh->type = type;	lh->ident = ident;	lh->len = htons (LCP_HEADER_LEN + len);	if (len)		bcopy (data, lh+1, len);	if (debug) {		log(LOG_DEBUG, SPP_FMT "%s output <%s id=0x%x len=%d",		    SPP_ARGS(ifp),		    sppp_proto_name(proto),		    sppp_cp_type_name (lh->type), lh->ident,		    ntohs (lh->len));		if (len)			sppp_print_bytes ((u_char*) (lh+1), len);		addlog(">\n");	}	if (IF_QFULL (&sp->pp_cpq)) {		IF_DROP (&sp->pp_fastq);		IF_DROP (&ifp->if_snd);		m_freem (m);		++ifp->if_oerrors;	} else		IF_ENQUEUE (&sp->pp_cpq, m);	if (! (ifp->if_flags & IFF_OACTIVE))		(*ifp->if_start) (ifp);	ifp->if_obytes += m->m_pkthdr.len + 3;}/* * Handle incoming PPP control protocol packets. */static voidsppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m){	STDDCL;	struct lcp_header *h;	int len = m->m_pkthdr.len;	int rv;	u_char *p;	if (len < 4) {		if (debug)			log(LOG_DEBUG,			    SPP_FMT "%s invalid packet length: %d bytes\n",			    SPP_ARGS(ifp), cp->name, len);		return;	}	h = mtod (m, struct lcp_header*);	if (debug) {		log(LOG_DEBUG,		    SPP_FMT "%s input(%s): <%s id=0x%x len=%d",		    SPP_ARGS(ifp), cp->name,		    sppp_state_name(sp->state[cp->protoidx]),		    sppp_cp_type_name (h->type), h->ident, ntohs (h->len));		if (len > 4)			sppp_print_bytes ((u_char*) (h+1), len-4);		addlog(">\n");	}	if (len > ntohs (h->len))		len = ntohs (h->len);	p = (u_char *)(h + 1);	switch (h->type) {	case CONF_REQ:		if (len < 4) {			if (debug)				addlog(SPP_FMT "%s invalid conf-req length %d\n",				       SPP_ARGS(ifp), cp->name,				       len);			++ifp->if_ierrors;			break;		}		/* handle states where RCR doesn't get a SCA/SCN */		switch (sp->state[cp->protoidx]) {		case STATE_CLOSING:		case STATE_STOPPING:			return;		case STATE_CLOSED:			sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident,				     0, 0);			return;		}		rv = (cp->RCR)(sp, h, len);		switch (sp->state[cp->protoidx]) {		case STATE_OPENED:			(cp->tld)(sp);			(cp->scr)(sp);			/* fall through... */		case STATE_ACK_SENT:		case STATE_REQ_SENT:			sppp_cp_change_state(cp, sp, rv?					     STATE_ACK_SENT: STATE_REQ_SENT);			break;		case STATE_STOPPED:			sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;			(cp->scr)(sp);			sppp_cp_change_state(cp, sp, rv?					     STATE_ACK_SENT: STATE_REQ_SENT);			break;		case STATE_ACK_RCVD:			if (rv) {				sppp_cp_change_state(cp, sp, STATE_OPENED);				if (debug)					log(LOG_DEBUG, SPP_FMT "%s tlu\n",					    SPP_ARGS(ifp),					    cp->name);				(cp->tlu)(sp);			} else				sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);			break;		default:			printf(SPP_FMT "%s illegal %s in state %s\n",			       SPP_ARGS(ifp), cp->name,			       sppp_cp_type_name(h->type),			       sppp_state_name(sp->state[cp->protoidx]));			++ifp->if_ierrors;		}		break;	case CONF_ACK:		if (h->ident != sp->confid[cp->protoidx]) {			if (debug)				addlog(SPP_FMT "%s id mismatch 0x%x != 0x%x\n",				       SPP_ARGS(ifp), cp->name,				       h->ident, sp->confid[cp->protoidx]);			++ifp->if_ierrors;			break;		}		switch (sp->state[cp->protoidx]) {		case STATE_CLOSED:		case STATE_STOPPED:			sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);			break;		case STATE_CLOSING:		case STATE_STOPPING:			break;		case STATE_REQ_SENT:			sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;			sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);			break;		case STATE_OPENED:			(cp->tld)(sp);			/* fall through */		case STATE_ACK_RCVD:			(cp->scr)(sp);			sppp_cp_change_state(cp, sp, STATE_REQ_SENT);			break;		case STATE_ACK_SENT:			sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;			sppp_cp_change_state(cp, sp, STATE_OPENED);			if (debug)				log(LOG_DEBUG, SPP_FMT "%s tlu\n",				       SPP_ARGS(ifp), cp->name);			(cp->tlu)(sp);			break;		default:			printf(SPP_FMT "%s illegal %s in state %s\n",			       SPP_ARGS(ifp), cp->name,			       sppp_cp_type_name(h->type),			       sppp_state_name(sp->state[cp->protoidx]));			++ifp->if_ierrors;		}		break;	case CONF_NAK:	case CONF_REJ:		if (h->ident != sp->confid[cp->protoidx]) {			if (debug)				addlog(SPP_FMT "%s id mismatch 0x%x != 0x%x\n",				       SPP_ARGS(ifp), cp->name,				       h->ident, sp->confid[cp->protoidx]);			++ifp->if_ierrors;			break;		}		if (h->type == CONF_NAK)			(cp->RCN_nak)(sp, h, len);		else /* CONF_REJ */			(cp->RCN_rej)(sp, h, len);		switch (sp->state[cp->protoidx]) {		case STATE_CLOSED:		case STATE_STOPPED:			sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);			break;		case STATE_REQ_SENT:		case STATE_ACK_SENT:			sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;			(cp->scr)(sp);			break;		case STATE_OPENED:			(cp->tld)(sp);			/* fall through */		case STATE_ACK_RCVD:			sppp_cp_change_state(cp, sp, STATE_ACK_SENT);			(cp->scr)(sp);			break;		case STATE_CLOSING:		case STATE_STOPPING:			break;		default:			printf(SPP_FMT "%s illegal %s in state %s\n",			       SPP_ARGS(ifp), cp->name,			       sppp_cp_type_name(h->type),			       sppp_state_name(sp->state[cp->protoidx]));			++ifp->if_ierrors;		}		break;	case TERM_REQ:		switch (sp->state[cp->protoidx]) {		case STATE_ACK_RCVD:		case STATE_ACK_SENT:			sppp_cp_change_state(cp, sp, STATE_REQ_SENT);			/* fall through */		case STATE_CLOSED:		case STATE_STOPPED:		case STATE_CLOSING:		case STATE_STOPPING:		case STATE_REQ_SENT:		  sta:			/* Send Terminate-Ack packet. */			if (debug)				log(LOG_DEBUG, SPP_FMT "%s send terminate-ack\n",				    SPP_ARGS(ifp), cp->name);			sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);			break;		case STATE_OPENED:			(cp->tld)(sp);			sp->rst_counter[cp->protoidx] = 0;			sppp_cp_change_state(cp, sp, STATE_STOPPING);			goto sta;			break;		default:			printf(SPP_FMT "%s illegal %s in state %s\n",			       SPP_ARGS(ifp), cp->name,			       sppp_cp_type_name(h->type),			       sppp_state_name(sp->state[cp->protoidx]));			++ifp->if_ierrors;		}		break;	case TERM_ACK:		switch (sp->state[cp->protoidx]) {		case STATE_CLOSED:		case STATE_STOPPED:		case STATE_REQ_SENT:		case STATE_ACK_SENT:			break;		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_ACK_RCVD:			sppp_cp_change_state(cp, sp, STATE_REQ_SENT);			break;		case STATE_OPENED:			(cp->tld)(sp);			(cp->scr)(sp);			sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);			break;		default:			printf(SPP_FMT "%s illegal %s in state %s\n",			       SPP_ARGS(ifp), cp->name,			       sppp_cp_type_name(h->type),			       sppp_state_name(sp->state[cp->protoidx]));			++ifp->if_ierrors;		}		break;	case CODE_REJ:	case PROTO_REJ:		/* XXX catastrophic rejects (RXJ-) aren't handled yet. */		log(LOG_INFO,		    SPP_FMT "%s: ignoring RXJ (%s) for proto 0x%x, "		    "danger will robinson\n",		    SPP_ARGS(ifp), cp->name,		    sppp_cp_type_name(h->type), ntohs(*((u_short *)p)));		switch (sp->state[cp->protoidx]) {		case STATE_CLOSED:		case STATE_STOPPED:		case STATE_REQ_SENT:		case STATE_ACK_SENT:		case STATE_CLOSING:		case STATE_STOPPING:		case STATE_OPENED:			break;		case STATE_ACK_RCVD:			sppp_cp_change_state(cp, sp, STATE_REQ_SENT);			break;		default:			printf(SPP_FMT "%s illegal %s in state %s\n",			       SPP_ARGS(ifp), cp->name,			       sppp_cp_type_name(h->type),			       sppp_state_name(sp->state[cp->protoidx]));			++ifp->if_ierrors;		}		break;	case DISC_REQ:		if (cp->proto != PPP_LCP)			goto illegal;		/* Discard the packet. */		break;	case ECHO_REQ:		if (cp->proto != PPP_LCP)			goto illegal;		if (sp->state[cp->protoidx] != STATE_OPENED) {			if (debug)				addlog(SPP_FMT "lcp echo req but lcp closed\n",				       SPP_ARGS(ifp));			++ifp->if_ierrors;			break;		}		if (len < 8) {			if (debug)				addlog(SPP_FMT "invalid lcp echo request "				       "packet length: %d bytes\n",				       SPP_ARGS(ifp), len);			break;		}		if (ntohl (*(long*)(h+1)) == sp->lcp.magic) {			/* Line loopback mode detected. */			printf(SPP_FMT "loopback\n", SPP_ARGS(ifp));			if_down (ifp);			sppp_qflush (&sp->pp_cpq);			/* Shut down the PPP link. */			/* XXX */			lcp.Down(sp);			lcp.Up(sp);			break;		}		*(long*)(h+1) = htonl (sp->lcp.magic);		if (debug)			addlog(SPP_FMT "got lcp echo req, sending echo rep\n",			       SPP_ARGS(ifp));		sppp_cp_send (sp, PPP_LCP, ECHO_REPLY, h->ident, len-4, h+1);		break;	case ECHO_REPLY:		if (cp->proto != PPP_LCP)			goto illegal;		if (h->ident != sp->lcp.echoid) {			++ifp->if_ierrors;			break;		}		if (len < 8) {			if (debug)				addlog(SPP_FMT "lcp invalid echo reply "				       "packet length: %d bytes\n",				       SPP_ARGS(ifp), len);			break;		}		if (debug)			addlog(SPP_FMT "lcp got echo rep\n",			       SPP_ARGS(ifp));		if (ntohl (*(long*)(h+1)) != sp->lcp.magic)			sp->pp_alivecnt = 0;		break;	default:		/* Unknown packet type -- send Code-Reject packet. */	  illegal:		if (debug)			addlog(SPP_FMT "%s send code-rej for 0x%x\n",			       SPP_ARGS(ifp), cp->name, h->type);		sppp_cp_send(sp, cp->proto, CODE_REJ, ++sp->pp_seq,			     m->m_pkthdr.len, h);		++ifp->if_ierrors;	}}/* * The generic part of all Up/Down/Open/Close/TO event handlers. * Basically, the state transition handling in the automaton. */static voidsppp_up_event(const struct cp *cp, struct sppp *sp){	STDDCL;	if (debug)		log(LOG_DEBUG, SPP_FMT "%s up(%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_CLOSED);

⌨️ 快捷键说明

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