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

📄 syncppp.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		printk (KERN_WARNING "%s: lcp input(%c): %d bytes <%s id=%xh len=%xh",			dev->name, state, len,			sppp_lcp_type_name (h->type), h->ident, ntohs (h->len));		if (len > 4)			sppp_print_bytes ((u8*) (h+1), len-4);		printk (">\n");	}	if (len > ntohs (h->len))		len = ntohs (h->len);	switch (h->type) {	default:		/* Unknown packet type -- send Code-Reject packet. */		sppp_cp_send (sp, PPP_LCP, LCP_CODE_REJ, ++sp->pp_seq,			skb->len, h);		break;	case LCP_CONF_REQ:		if (len < 4) {			if (sp->pp_flags & PP_DEBUG)				printk (KERN_DEBUG"%s: invalid lcp configure request packet length: %d bytes\n",					dev->name, len);			break;		}		if (len>4 && !sppp_lcp_conf_parse_options (sp, h, len, &rmagic))			goto badreq;		if (rmagic == sp->lcp.magic) {			/* Local and remote magics equal -- loopback? */			if (sp->pp_loopcnt >= MAXALIVECNT*5) {				printk (KERN_WARNING "%s: loopback\n",					dev->name);				sp->pp_loopcnt = 0;				if (dev->flags & IFF_UP) {					if_down (dev);				}			} else if (sp->pp_flags & PP_DEBUG)				printk (KERN_DEBUG "%s: conf req: magic glitch\n",					dev->name);			++sp->pp_loopcnt;			/* MUST send Conf-Nack packet. */			rmagic = ~sp->lcp.magic;			opt[0] = LCP_OPT_MAGIC;			opt[1] = sizeof (opt);			opt[2] = rmagic >> 24;			opt[3] = rmagic >> 16;			opt[4] = rmagic >> 8;			opt[5] = rmagic;			sppp_cp_send (sp, PPP_LCP, LCP_CONF_NAK,				h->ident, sizeof (opt), &opt);badreq:			switch (sp->lcp.state) {			case LCP_STATE_OPENED:				/* Initiate renegotiation. */				sppp_lcp_open (sp);				/* fall through... */			case LCP_STATE_ACK_SENT:				/* Go to closed state. */				sp->lcp.state = LCP_STATE_CLOSED;				sp->ipcp.state = IPCP_STATE_CLOSED;			}			break;		}		/* Send Configure-Ack packet. */		sp->pp_loopcnt = 0;		sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK,				h->ident, len-4, h+1);		/* Change the state. */		switch (sp->lcp.state) {		case LCP_STATE_CLOSED:			sp->lcp.state = LCP_STATE_ACK_SENT;			break;		case LCP_STATE_ACK_RCVD:			sp->lcp.state = LCP_STATE_OPENED;			sppp_ipcp_open (sp);			break;		case LCP_STATE_OPENED:#if 0					/* Remote magic changed -- close session. */			sp->lcp.state = LCP_STATE_CLOSED;			sp->ipcp.state = IPCP_STATE_CLOSED;			/* Initiate renegotiation. */			sppp_lcp_open (sp);			/* An ACK has already been sent. */			sp->lcp.state = LCP_STATE_ACK_SENT;#endif						break;		}		break;	case LCP_CONF_ACK:		if (h->ident != sp->lcp.confid)			break;		sppp_clear_timeout (sp);		if (! (dev->flags & IFF_UP) &&		    (dev->flags & IFF_RUNNING)) {			/* Coming out of loopback mode. */			dev->flags |= IFF_UP;			printk (KERN_INFO "%s: up\n", dev->name);		}		switch (sp->lcp.state) {		case LCP_STATE_CLOSED:			sp->lcp.state = LCP_STATE_ACK_RCVD;			sppp_set_timeout (sp, 5);			break;		case LCP_STATE_ACK_SENT:			sp->lcp.state = LCP_STATE_OPENED;			sppp_ipcp_open (sp);			break;		}		break;	case LCP_CONF_NAK:		if (h->ident != sp->lcp.confid)			break;		p = (u8*) (h+1);		if (len>=10 && p[0] == LCP_OPT_MAGIC && p[1] >= 4) {			rmagic = (u32)p[2] << 24 |				(u32)p[3] << 16 | p[4] << 8 | p[5];			if (rmagic == ~sp->lcp.magic) {				int newmagic;				if (sp->pp_flags & PP_DEBUG)					printk (KERN_DEBUG "%s: conf nak: magic glitch\n",						dev->name);				get_random_bytes(&newmagic, sizeof(newmagic));				sp->lcp.magic += newmagic;			} else				sp->lcp.magic = rmagic;			}		if (sp->lcp.state != LCP_STATE_ACK_SENT) {			/* Go to closed state. */			sp->lcp.state = LCP_STATE_CLOSED;			sp->ipcp.state = IPCP_STATE_CLOSED;		}		/* The link will be renegotiated after timeout,		 * to avoid endless req-nack loop. */		sppp_clear_timeout (sp);		sppp_set_timeout (sp, 2);		break;	case LCP_CONF_REJ:		if (h->ident != sp->lcp.confid)			break;		sppp_clear_timeout (sp);		/* Initiate renegotiation. */		sppp_lcp_open (sp);		if (sp->lcp.state != LCP_STATE_ACK_SENT) {			/* Go to closed state. */			sp->lcp.state = LCP_STATE_CLOSED;			sp->ipcp.state = IPCP_STATE_CLOSED;		}		break;	case LCP_TERM_REQ:		sppp_clear_timeout (sp);		/* Send Terminate-Ack packet. */		sppp_cp_send (sp, PPP_LCP, LCP_TERM_ACK, h->ident, 0, 0);		/* Go to closed state. */		sp->lcp.state = LCP_STATE_CLOSED;		sp->ipcp.state = IPCP_STATE_CLOSED;		/* Initiate renegotiation. */		sppp_lcp_open (sp);		break;	case LCP_TERM_ACK:	case LCP_CODE_REJ:	case LCP_PROTO_REJ:		/* Ignore for now. */		break;	case LCP_DISC_REQ:		/* Discard the packet. */		break;	case LCP_ECHO_REQ:		if (sp->lcp.state != LCP_STATE_OPENED)			break;		if (len < 8) {			if (sp->pp_flags & PP_DEBUG)				printk (KERN_WARNING "%s: invalid lcp echo request packet length: %d bytes\n",					dev->name, len);			break;		}		if (ntohl (*(long*)(h+1)) == sp->lcp.magic) {			/* Line loopback mode detected. */			printk (KERN_WARNING "%s: loopback\n", dev->name);			if_down (dev);			/* Shut down the PPP link. */			sp->lcp.state = LCP_STATE_CLOSED;			sp->ipcp.state = IPCP_STATE_CLOSED;			sppp_clear_timeout (sp);			/* Initiate negotiation. */			sppp_lcp_open (sp);			break;		}		*(long*)(h+1) = htonl (sp->lcp.magic);		sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REPLY, h->ident, len-4, h+1);		break;	case LCP_ECHO_REPLY:		if (h->ident != sp->lcp.echoid)			break;		if (len < 8) {			if (sp->pp_flags & PP_DEBUG)				printk (KERN_WARNING "%s: invalid lcp echo reply packet length: %d bytes\n",					dev->name, len);			break;		}		if (ntohl (*(long*)(h+1)) != sp->lcp.magic)		sp->pp_alivecnt = 0;		break;	}}/* * Handle incoming Cisco keepalive protocol packets. */static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb){	struct cisco_packet *h;	struct device *dev = sp->pp_if;	if (skb->len != CISCO_PACKET_LEN && skb->len != CISCO_BIG_PACKET_LEN) {		if (sp->pp_flags & PP_DEBUG)			printk (KERN_WARNING "%s: invalid cisco packet length: %d bytes\n",				dev->name,  skb->len);		return;	}	h = (struct cisco_packet *)skb->data;	skb_pull(skb, sizeof(struct cisco_packet*));	if (sp->pp_flags & PP_DEBUG)		printk (KERN_WARNING "%s: cisco input: %d bytes <%lxh %xh %xh %xh %xh-%xh>\n",			dev->name,  skb->len,			ntohl (h->type), h->par1, h->par2, h->rel,			h->time0, h->time1);	switch (ntohl (h->type)) {	default:		if (sp->pp_flags & PP_DEBUG)			printk (KERN_WARNING "%s: unknown cisco packet type: 0x%lx\n",				dev->name,  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. */			int newseq;			if (sp->pp_loopcnt >= MAXALIVECNT) {				printk (KERN_WARNING "%s: loopback\n",					dev->name);				sp->pp_loopcnt = 0;				if (dev->flags & IFF_UP) {					if_down (dev);				}			}			++sp->pp_loopcnt;			/* Generate new local sequence number */			get_random_bytes(&newseq, sizeof(newseq));			sp->pp_seq ^= newseq;			break;		}		sp->pp_loopcnt = 0;		if (! (dev->flags & IFF_UP) &&		    (dev->flags & IFF_RUNNING)) {			dev->flags |= IFF_UP;			printk (KERN_INFO "%s: up\n", dev->name);		}		break;	case CISCO_ADDR_REQ:		/* Stolen from net/ipv4/devinet.c -- SIOCGIFADDR ioctl */		{		struct in_device *in_dev;		struct in_ifaddr *ifa, **ifap;		u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */		if ((in_dev=dev->ip_ptr) != NULL)		{			for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL;				ifap=&ifa->ifa_next)				if (strcmp(dev->name, ifa->ifa_label) == 0) 				{					addr = ifa->ifa_local;					mask = ifa->ifa_mask;					break;				}		}		/* I hope both addr and mask are in the net order */		sppp_cisco_send (sp, CISCO_ADDR_REPLY, addr, mask);		break;		}	}}/* * Send PPP LCP packet. */static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,	u8 ident, u16 len, void *data){	struct ppp_header *h;	struct lcp_header *lh;	struct sk_buff *skb;	struct device *dev = sp->pp_if;	skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+LCP_HEADER_LEN+len,		GFP_ATOMIC);	if (skb==NULL)		return;	skb_reserve(skb,dev->hard_header_len);		h = (struct ppp_header *)skb_put(skb, sizeof(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 *)skb_put(skb, sizeof(struct lcp_header));	lh->type = type;	lh->ident = ident;	lh->len = htons (LCP_HEADER_LEN + len);	if (len)		memcpy(skb_put(skb,len),data, len);	if (sp->pp_flags & PP_DEBUG) {		printk (KERN_WARNING "%s: %s output <%s id=%xh len=%xh",			dev->name, 			proto==PPP_LCP ? "lcp" : "ipcp",			proto==PPP_LCP ? sppp_lcp_type_name (lh->type) :			sppp_ipcp_type_name (lh->type), lh->ident,			ntohs (lh->len));		if (len)			sppp_print_bytes ((u8*) (lh+1), len);		printk (">\n");	}	sp->obytes += skb->len;	/* Control is high priority so it doesnt get queued behind data */	skb->priority=1;	skb->dev = dev;	dev_queue_xmit(skb);}/* * Send Cisco keepalive packet. */static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2){	struct ppp_header *h;	struct cisco_packet *ch;	struct sk_buff *skb;	struct device *dev = sp->pp_if;	u32 t = jiffies * 1000/HZ;	skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+CISCO_PACKET_LEN,		GFP_ATOMIC);	if(skb==NULL)		return;			skb_reserve(skb, dev->hard_header_len);	h = (struct ppp_header *)skb_put (skb, sizeof(struct ppp_header));	h->address = CISCO_MULTICAST;	h->control = 0;	h->protocol = htons (CISCO_KEEPALIVE);	ch = (struct cisco_packet*)skb_put(skb, CISCO_PACKET_LEN);	ch->type = htonl (type);	ch->par1 = htonl (par1);	ch->par2 = htonl (par2);	ch->rel = -1;	ch->time0 = htons ((u16) (t >> 16));	ch->time1 = htons ((u16) t);	if (sp->pp_flags & PP_DEBUG)		printk (KERN_WARNING "%s: cisco output: <%lxh %xh %xh %xh %xh-%xh>\n",			dev->name,  ntohl (ch->type), ch->par1,			ch->par2, ch->rel, ch->time0, ch->time1);	sp->obytes += skb->len;	skb->priority=1;	skb->dev = dev;	dev_queue_xmit(skb);}int sppp_close (struct device *dev){	struct sppp *sp = &((struct ppp_device *)dev)->sppp;	dev->flags &= ~IFF_RUNNING;	sp->lcp.state = LCP_STATE_CLOSED;	sp->ipcp.state = IPCP_STATE_CLOSED;	sppp_clear_timeout (sp);	return 0;}EXPORT_SYMBOL(sppp_close);int sppp_open (struct device *dev){	struct sppp *sp = &((struct ppp_device *)dev)->sppp;	sppp_close(dev);	dev->flags |= IFF_RUNNING;	if (!(sp->pp_flags & PP_CISCO))		sppp_lcp_open (sp);	return 0;}EXPORT_SYMBOL(sppp_open);int sppp_reopen (struct device *dev){	struct sppp *sp = &((struct ppp_device *)dev)->sppp;	sppp_close(dev);	dev->flags |= IFF_RUNNING;	if (!(sp->pp_flags & PP_CISCO))	{		sp->lcp.magic = jiffies;		++sp->pp_seq;		sp->lcp.state = LCP_STATE_CLOSED;		sp->ipcp.state = IPCP_STATE_CLOSED;		/* Give it a moment for the line to settle then go */		sppp_set_timeout (sp, 1);	}	return 0;}EXPORT_SYMBOL(sppp_reopen);int sppp_change_mtu(struct device *dev, int new_mtu){	if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))		return -EINVAL;	dev->mtu=new_mtu;	return 0;}EXPORT_SYMBOL(sppp_change_mtu);

⌨️ 快捷键说明

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