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

📄 syncppp.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	NET3:	A (fairly minimal) implementation of synchronous PPP for Linux *		as well as a CISCO HDLC implementation. See the copyright  *		message below for the original source. * *	This program is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License *	as published by the Free Software Foundation; either version *	2 of the license, or (at your option) any later version. * *	Note however. This code is also used in a different form by FreeBSD. *	Therefore when making any non OS specific change please consider *	contributing it back to the original author under the terms *	below in addition. *		-- Alan * *	Port for Linux-2.1 by Jan "Yenya" Kasprzak <kas@fi.muni.cz> *//* * Synchronous PPP/Cisco link level subroutines. * Keepalive protocol implemented in both Cisco and PPP modes. * * Copyright (C) 1994 Cronyx Ltd. * Author: Serge Vakulenko, <vak@zebub.msk.su> * * This software is distributed with NO WARRANTIES, not even the implied * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Authors grant any other persons or organisations permission to use * or modify this software as long as this message is kept with the software, * all derivative works or modified versions. * * Version 1.9, Wed Oct  4 18:58:15 MSK 1995 * * $Id: if_spppsubr.c,v 1.12 1996/06/10 23:17:45 gpalmer Exp $ */#undef DEBUG#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/if_arp.h>#include <linux/skbuff.h>#include <linux/route.h>#include <linux/netdevice.h>#include <linux/inetdevice.h>#include <linux/random.h>#include <asm/byteorder.h>#include "syncppp.h"#define MAXALIVECNT     6               /* max. alive packets */#define PPP_ALLSTATIONS 0xff            /* All-Stations broadcast address */#define PPP_UI          0x03            /* Unnumbered Information */#define PPP_IP          0x0021          /* Internet Protocol */#define PPP_ISO         0x0023          /* ISO OSI Protocol */#define PPP_XNS         0x0025          /* Xerox NS Protocol */#define PPP_IPX         0x002b          /* Novell IPX Protocol */#define PPP_LCP         0xc021          /* Link Control Protocol */#define PPP_IPCP        0x8021          /* Internet Protocol Control Protocol */#define LCP_CONF_REQ    1               /* PPP LCP configure request */#define LCP_CONF_ACK    2               /* PPP LCP configure acknowledge */#define LCP_CONF_NAK    3               /* PPP LCP configure negative ack */#define LCP_CONF_REJ    4               /* PPP LCP configure reject */#define LCP_TERM_REQ    5               /* PPP LCP terminate request */#define LCP_TERM_ACK    6               /* PPP LCP terminate acknowledge */#define LCP_CODE_REJ    7               /* PPP LCP code reject */#define LCP_PROTO_REJ   8               /* PPP LCP protocol reject */#define LCP_ECHO_REQ    9               /* PPP LCP echo request */#define LCP_ECHO_REPLY  10              /* PPP LCP echo reply */#define LCP_DISC_REQ    11              /* PPP LCP discard request */#define LCP_OPT_MRU             1       /* maximum receive unit */#define LCP_OPT_ASYNC_MAP       2       /* async control character map */#define LCP_OPT_AUTH_PROTO      3       /* authentication protocol */#define LCP_OPT_QUAL_PROTO      4       /* quality protocol */#define LCP_OPT_MAGIC           5       /* magic number */#define LCP_OPT_RESERVED        6       /* reserved */#define LCP_OPT_PROTO_COMP      7       /* protocol field compression */#define LCP_OPT_ADDR_COMP       8       /* address/control field compression */#define IPCP_CONF_REQ   LCP_CONF_REQ    /* PPP IPCP configure request */#define IPCP_CONF_ACK   LCP_CONF_ACK    /* PPP IPCP configure acknowledge */#define IPCP_CONF_NAK   LCP_CONF_NAK    /* PPP IPCP configure negative ack */#define IPCP_CONF_REJ   LCP_CONF_REJ    /* PPP IPCP configure reject */#define IPCP_TERM_REQ   LCP_TERM_REQ    /* PPP IPCP terminate request */#define IPCP_TERM_ACK   LCP_TERM_ACK    /* PPP IPCP terminate acknowledge */#define IPCP_CODE_REJ   LCP_CODE_REJ    /* PPP IPCP code reject */#define CISCO_MULTICAST         0x8f    /* Cisco multicast address */#define CISCO_UNICAST           0x0f    /* Cisco unicast address */#define CISCO_KEEPALIVE         0x8035  /* Cisco keepalive protocol */#define CISCO_ADDR_REQ          0       /* Cisco address request */#define CISCO_ADDR_REPLY        1       /* Cisco address reply */#define CISCO_KEEPALIVE_REQ     2       /* Cisco keepalive request */struct ppp_header {	u8 address;	u8 control;	u16 protocol;};#define PPP_HEADER_LEN          sizeof (struct ppp_header)struct lcp_header {	u8 type;	u8 ident;	u16 len;};#define LCP_HEADER_LEN          sizeof (struct lcp_header)struct cisco_packet {	u32 type;	u32 par1;	u32 par2;	u16 rel;	u16 time0;	u16 time1;};#define CISCO_PACKET_LEN 18#define CISCO_BIG_PACKET_LEN 20static struct sppp *spppq;static struct timer_list sppp_keepalive_timer;static void sppp_keepalive (unsigned long dummy);static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,	u8 ident, u16 len, void *data);static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2);static void sppp_lcp_input (struct sppp *sp, struct sk_buff *m);static void sppp_cisco_input (struct sppp *sp, struct sk_buff *m);static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *m);static void sppp_lcp_open (struct sppp *sp);static void sppp_ipcp_open (struct sppp *sp);static int sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h,	int len, u32 *magic);static void sppp_cp_timeout (unsigned long arg);static char *sppp_lcp_type_name (u8 type);static char *sppp_ipcp_type_name (u8 type);static void sppp_print_bytes (u8 *p, u16 len);static int debug = 0;/* *	Interface down stub */	static void if_down(struct device *dev){	;}/* * Timeout routine activations. */static void sppp_set_timeout(struct sppp *p,int s) {	if (! (p->pp_flags & PP_TIMO)) 	{		init_timer(&p->pp_timer);		p->pp_timer.function=sppp_cp_timeout;		p->pp_timer.expires=jiffies+s*HZ;		p->pp_timer.data=(unsigned long)p;		p->pp_flags |= PP_TIMO;		add_timer(&p->pp_timer);	}}static void sppp_clear_timeout(struct sppp *p){	if (p->pp_flags & PP_TIMO) 	{		del_timer(&p->pp_timer);		p->pp_flags &= ~PP_TIMO; 	}}/* * Process the received packet. */ void sppp_input (struct device *dev, struct sk_buff *skb){	struct ppp_header *h;	struct sppp *sp = &((struct ppp_device *)dev)->sppp;		skb->dev=dev;	skb->mac.raw=skb->data;		if (dev->flags & IFF_UP)	{		/* Count received bytes, add FCS and one flag */		sp->ibytes+= skb->len + 3;		sp->ipkts++;	}	if (skb->len <= PPP_HEADER_LEN) {		/* Too small packet, drop it. */		if (sp->pp_flags & PP_DEBUG)			printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n",				dev->name, skb->len);drop:           kfree_skb(skb);		return;	}	/* Get PPP header. */	h = (struct ppp_header *)skb->data;	skb_pull(skb,sizeof(struct ppp_header));	switch (h->address) {	default:        /* Invalid PPP packet. */invalid:        if (sp->pp_flags & PP_DEBUG)			printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n",				dev->name,				h->address, h->control, ntohs (h->protocol));		goto drop;	case PPP_ALLSTATIONS:		if (h->control != PPP_UI)			goto invalid;		if (sp->pp_flags & PP_CISCO) {			if (sp->pp_flags & PP_DEBUG)				printk (KERN_WARNING "%s: PPP packet in Cisco mode <0x%x 0x%x 0x%x>\n",					dev->name,					h->address, h->control, ntohs (h->protocol));			goto drop;		}		switch (ntohs (h->protocol)) {		default:			if (sp->lcp.state == LCP_STATE_OPENED)				sppp_cp_send (sp, PPP_LCP, LCP_PROTO_REJ,					++sp->pp_seq, skb->len + 2,					&h->protocol);			if (sp->pp_flags & PP_DEBUG)				printk (KERN_WARNING "%s: invalid input protocol <0x%x 0x%x 0x%x>\n",					dev->name,					h->address, h->control, ntohs (h->protocol));			goto drop;		case PPP_LCP:			sppp_lcp_input (sp, skb);			kfree_skb(skb);			return;		case PPP_IPCP:			if (sp->lcp.state == LCP_STATE_OPENED)				sppp_ipcp_input (sp, skb);			else				printk(KERN_DEBUG "IPCP when still waiting LCP finish.\n");			kfree_skb(skb);			return;		case PPP_IP:			if (sp->ipcp.state == IPCP_STATE_OPENED) {				if(sp->pp_flags&PP_DEBUG)					printk(KERN_DEBUG "Yow an IP frame.\n");				skb->protocol=htons(ETH_P_IP);				netif_rx(skb);				return;			}			break;#ifdef IPX		case PPP_IPX:			/* IPX IPXCP not implemented yet */			if (sp->lcp.state == LCP_STATE_OPENED) {				skb->protocol=htons(ETH_P_IPX);				netif_rx(skb);				return;			}			break;#endif		}		break;	case CISCO_MULTICAST:	case CISCO_UNICAST:		/* Don't check the control field here (RFC 1547). */		if (! (sp->pp_flags & PP_CISCO)) {			if (sp->pp_flags & PP_DEBUG)				printk (KERN_WARNING "%s: Cisco packet in PPP mode <0x%x 0x%x 0x%x>\n",					dev->name,					h->address, h->control, ntohs (h->protocol));			goto drop;		}		switch (ntohs (h->protocol)) {		default:			goto invalid;		case CISCO_KEEPALIVE:			sppp_cisco_input (sp, skb);			kfree_skb(skb);			return;#ifdef CONFIG_INET		case ETH_P_IP:			skb->protocol=htons(ETH_P_IP);			netif_rx(skb);			return;#endif#ifdef CONFIG_IPX		case ETH_P_IPX:			skb->protocol=htons(ETH_P_IPX);			netif_rx(skb);			return;#endif		}		break;	}	kfree_skb(skb);}EXPORT_SYMBOL(sppp_input);/* *	Handle transmit packets. */ static int sppp_hard_header(struct sk_buff *skb, struct device *dev, __u16 type,		void *daddr, void *saddr, unsigned int len){	struct sppp *sp = &((struct ppp_device *)dev)->sppp;	struct ppp_header *h;	skb_push(skb,sizeof(struct ppp_header));	h=(struct ppp_header *)skb->data;	if(sp->pp_flags&PP_CISCO)	{		h->address = CISCO_MULTICAST;		h->control = 0;	}	else	{		h->address = PPP_ALLSTATIONS;		h->control = PPP_UI;	}	if(sp->pp_flags & PP_CISCO)	{		h->protocol = htons(type);	}	else switch(type)	{		case ETH_P_IP:			h->protocol = htons(PPP_IP);			break;		case ETH_P_IPX:			h->protocol = htons(PPP_IPX);			break;	}	return sizeof(struct ppp_header);}static int sppp_rebuild_header(struct sk_buff *skb){	return 0;}/* * Send keepalive packets, every 10 seconds. */static void sppp_keepalive (unsigned long dummy){	struct sppp *sp;	unsigned long flags;	save_flags(flags);	cli();	for (sp=spppq; sp; sp=sp->pp_next) 	{		struct device *dev = sp->pp_if;		/* Keepalive mode disabled or channel down? */		if (! (sp->pp_flags & PP_KEEPALIVE) ||		    ! (dev->flags & IFF_RUNNING))			continue;		/* No keepalive in PPP mode if LCP not opened yet. */		if (! (sp->pp_flags & PP_CISCO) &&		    sp->lcp.state != LCP_STATE_OPENED)			continue;		if (sp->pp_alivecnt == MAXALIVECNT) {			/* No keepalive packets got.  Stop the interface. */			printk (KERN_WARNING "%s: down\n", dev->name);			if_down (dev);			if (! (sp->pp_flags & PP_CISCO)) {				/* Shut down the PPP link. */				sp->lcp.magic = jiffies;				sp->lcp.state = LCP_STATE_CLOSED;				sp->ipcp.state = IPCP_STATE_CLOSED;				sppp_clear_timeout (sp);				/* Initiate negotiation. */				sppp_lcp_open (sp);			}		}		if (sp->pp_alivecnt <= MAXALIVECNT)			++sp->pp_alivecnt;		if (sp->pp_flags & PP_CISCO)			sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq,				sp->pp_rseq);		else if (sp->lcp.state == LCP_STATE_OPENED) {			long nmagic = htonl (sp->lcp.magic);			sp->lcp.echoid = ++sp->pp_seq;			sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REQ,				sp->lcp.echoid, 4, &nmagic);		}	}	restore_flags(flags);	sppp_keepalive_timer.expires=jiffies+10*HZ;	add_timer(&sppp_keepalive_timer);}/* * Handle incoming PPP Link Control Protocol packets. */ static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb){	struct lcp_header *h;	struct device *dev = sp->pp_if;	int len = skb->len;	u8 *p, opt[6];	u32 rmagic;	if (len < 4) {		if (sp->pp_flags & PP_DEBUG)			printk (KERN_WARNING "%s: invalid lcp packet length: %d bytes\n",				dev->name, len);		return;	}	h = (struct lcp_header *)skb->data;	skb_pull(skb,sizeof(struct lcp_header *));		if (sp->pp_flags & PP_DEBUG) 	{		char state = '?';		switch (sp->lcp.state) {		case LCP_STATE_CLOSED:   state = 'C'; break;		case LCP_STATE_ACK_RCVD: state = 'R'; break;		case LCP_STATE_ACK_SENT: state = 'S'; break;		case LCP_STATE_OPENED:   state = 'O'; break;

⌨️ 快捷键说明

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