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

📄 isdn_net.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
					case 9:					case 10:					case 12:						if (lp->dialstate <= 6) {							dev->usage[idx] |= ISDN_USAGE_OUTGOING;							isdn_info_update();						} else							dev->rx_netdev[idx] = p;						lp->dialstate = 0;						isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);						if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)							isdn_net_ciscohdlck_connected(lp);						if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {							if (lp->master) { /* is lp a slave? */								isdn_net_dev *nd = ((isdn_net_local *)lp->master->priv)->netdev;								isdn_net_add_to_bundle(nd, lp);							}						}						printk(KERN_INFO "isdn_net: %s connected\n", lp->name);						/* If first Chargeinfo comes before B-Channel connect,						 * we correct the timestamp here.						 */						lp->chargetime = jiffies;						/* reset dial-timeout */						lp->dialstarted = 0;						lp->dialwait_timer = 0;#ifdef CONFIG_ISDN_PPP						if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)							isdn_ppp_wakeup_daemon(lp);#endif#ifdef CONFIG_ISDN_X25						/* try if there are generic concap receiver routines */						if( pops )							if( pops->connect_ind)								pops->connect_ind(cprot);#endif /* CONFIG_ISDN_X25 */						/* ppp needs to do negotiations first */						if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)							isdn_net_device_wake_queue(lp);						return 1;				}				break;			case ISDN_STAT_NODCH:				/* No D-Channel avail. */				if (lp->dialstate == 4) {					lp->dialstate--;					return 1;				}				break;			case ISDN_STAT_CINF:				/* Charge-info from TelCo. Calculate interval between				 * charge-infos and set timestamp for last info for				 * usage by isdn_net_autohup()				 */				lp->charge++;				if (lp->hupflags & ISDN_HAVECHARGE) {					lp->hupflags &= ~ISDN_WAITCHARGE;					lp->chargeint = jiffies - lp->chargetime - (2 * HZ);				}				if (lp->hupflags & ISDN_WAITCHARGE)					lp->hupflags |= ISDN_HAVECHARGE;				lp->chargetime = jiffies;				printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",				       lp->name, lp->chargetime);				return 1;		}	}	return 0;}/* * Perform dialout for net-interfaces and timeout-handling for * D-Channel-up and B-Channel-up Messages. * This function is initially called from within isdn_net_start_xmit() or * or isdn_net_find_icall() after initializing the dialstate for an * interface. If further calls are needed, the function schedules itself * for a timer-callback via isdn_timer_function(). * The dialstate is also affected by incoming status-messages from * the ISDN-Channel which are handled in isdn_net_stat_callback() above. */voidisdn_net_dial(void){	isdn_net_dev *p = dev->netdev;	int anymore = 0;	int i;	isdn_ctrl cmd;        u_char *phone_number;	while (p) {		isdn_net_local *lp = p->local;#ifdef ISDN_DEBUG_NET_DIAL		if (lp->dialstate)			printk(KERN_DEBUG "%s: dialstate=%d\n", lp->name, lp->dialstate);#endif		switch (lp->dialstate) {			case 0:				/* Nothing to do for this interface */				break;			case 1:				/* Initiate dialout. Set phone-number-pointer to first number				 * of interface.				 */				lp->dial = lp->phone[1];				if (!lp->dial) {					printk(KERN_WARNING "%s: phone number deleted?\n",					       lp->name);					isdn_net_hangup(&p->dev);					break;				}				anymore = 1;				if(lp->dialtimeout > 0)					if(lp->dialstarted == 0 || time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait)) {						lp->dialstarted = jiffies;						lp->dialwait_timer = 0;					}				lp->dialstate++;				/* Fall through */			case 2:				/* Prepare dialing. Clear EAZ, then set EAZ. */				cmd.driver = lp->isdn_device;				cmd.arg = lp->isdn_channel;				cmd.command = ISDN_CMD_CLREAZ;				isdn_command(&cmd);				sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(lp->msn, cmd.driver));				cmd.command = ISDN_CMD_SETEAZ;				isdn_command(&cmd);				lp->dialretry = 0;				anymore = 1;				lp->dialstate++;				/* Fall through */			case 3:				/* Setup interface, dial current phone-number, switch to next number.				 * If list of phone-numbers is exhausted, increment				 * retry-counter.				 */				if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {					char *s;					if (dev->global_flags & ISDN_GLOBAL_STOPPED)						s = "dial suppressed: isdn system stopped";					else						s = "dial suppressed: dialmode `off'";					isdn_net_unreachable(&p->dev, NULL, s);					isdn_net_hangup(&p->dev);					break;				}				cmd.driver = lp->isdn_device;				cmd.command = ISDN_CMD_SETL2;				cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);				isdn_command(&cmd);				cmd.driver = lp->isdn_device;				cmd.command = ISDN_CMD_SETL3;				cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);				isdn_command(&cmd);				cmd.driver = lp->isdn_device;				cmd.arg = lp->isdn_channel;				if (!lp->dial) {					printk(KERN_WARNING "%s: phone number deleted?\n",					       lp->name);					isdn_net_hangup(&p->dev);					break;				}				if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {					lp->dialstate = 4;					printk(KERN_INFO "%s: Open leased line ...\n", lp->name);				} else {					if(lp->dialtimeout > 0)						if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {							lp->dialwait_timer = jiffies + lp->dialwait;							lp->dialstarted = 0;							isdn_net_unreachable(&p->dev, NULL, "dial: timed out");							isdn_net_hangup(&p->dev);							break;						}					cmd.driver = lp->isdn_device;					cmd.command = ISDN_CMD_DIAL;					cmd.parm.setup.si2 = 0;                                        /* check for DOV */                                        phone_number = lp->dial->num;                                        if ((*phone_number == 'v') ||					    (*phone_number == 'V')) { /* DOV call */                                                cmd.parm.setup.si1 = 1;                                        } else { /* DATA call */                                                cmd.parm.setup.si1 = 7;					}					strcpy(cmd.parm.setup.phone, phone_number);					/*					 * Switch to next number or back to start if at end of list.					 */					if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {						lp->dial = lp->phone[1];						lp->dialretry++;						if (lp->dialretry > lp->dialmax) {							if (lp->dialtimeout == 0) {								lp->dialwait_timer = jiffies + lp->dialwait;								lp->dialstarted = 0;								isdn_net_unreachable(&p->dev, NULL, "dial: tried all numbers dialmax times");							}							isdn_net_hangup(&p->dev);							break;						}					}					sprintf(cmd.parm.setup.eazmsn, "%s",						isdn_map_eaz2msn(lp->msn, cmd.driver));					i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel);					if (i >= 0) {						strcpy(dev->num[i], cmd.parm.setup.phone);						dev->usage[i] |= ISDN_USAGE_OUTGOING;						isdn_info_update();					}					printk(KERN_INFO "%s: dialing %d %s... %s\n", lp->name,					       lp->dialretry, cmd.parm.setup.phone,					       (cmd.parm.setup.si1 == 1) ? "DOV" : "");					lp->dtimer = 0;#ifdef ISDN_DEBUG_NET_DIAL					printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,					       lp->isdn_channel);#endif					isdn_command(&cmd);				}				lp->huptimer = 0;				lp->outgoing = 1;				if (lp->chargeint) {					lp->hupflags |= ISDN_HAVECHARGE;					lp->hupflags &= ~ISDN_WAITCHARGE;				} else {					lp->hupflags |= ISDN_WAITCHARGE;					lp->hupflags &= ~ISDN_HAVECHARGE;				}				anymore = 1;				lp->dialstate =				    (lp->cbdelay &&				     (lp->flags & ISDN_NET_CBOUT)) ? 12 : 4;				break;			case 4:				/* Wait for D-Channel-connect.				 * If timeout, switch back to state 3.				 * Dialmax-handling moved to state 3.				 */				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)					lp->dialstate = 3;				anymore = 1;				break;			case 5:				/* Got D-Channel-Connect, send B-Channel-request */				cmd.driver = lp->isdn_device;				cmd.arg = lp->isdn_channel;				cmd.command = ISDN_CMD_ACCEPTB;				anymore = 1;				lp->dtimer = 0;				lp->dialstate++;				isdn_command(&cmd);				break;			case 6:				/* Wait for B- or D-Channel-connect. If timeout,				 * switch back to state 3.				 */#ifdef ISDN_DEBUG_NET_DIAL				printk(KERN_DEBUG "dialtimer2: %d\n", lp->dtimer);#endif				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)					lp->dialstate = 3;				anymore = 1;				break;			case 7:				/* Got incoming Call, setup L2 and L3 protocols,				 * then wait for D-Channel-connect				 */#ifdef ISDN_DEBUG_NET_DIAL				printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);#endif				cmd.driver = lp->isdn_device;				cmd.command = ISDN_CMD_SETL2;				cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);				isdn_command(&cmd);				cmd.driver = lp->isdn_device;				cmd.command = ISDN_CMD_SETL3;				cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);				isdn_command(&cmd);				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT15)					isdn_net_hangup(&p->dev);				else {					anymore = 1;					lp->dialstate++;				}				break;			case 9:				/* Got incoming D-Channel-Connect, send B-Channel-request */				cmd.driver = lp->isdn_device;				cmd.arg = lp->isdn_channel;				cmd.command = ISDN_CMD_ACCEPTB;				isdn_command(&cmd);				anymore = 1;				lp->dtimer = 0;				lp->dialstate++;				break;			case 8:			case 10:				/*  Wait for B- or D-channel-connect */#ifdef ISDN_DEBUG_NET_DIAL				printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);#endif				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)					isdn_net_hangup(&p->dev);				else					anymore = 1;				break;			case 11:				/* Callback Delay */				if (lp->dtimer++ > lp->cbdelay)					lp->dialstate = 1;				anymore = 1;				break;			case 12:				/* Remote does callback. Hangup after cbdelay, then wait for incoming				 * call (in state 4).				 */				if (lp->dtimer++ > lp->cbdelay)				{					printk(KERN_INFO "%s: hangup waiting for callback ...\n", lp->name);					lp->dtimer = 0;					lp->dialstate = 4;					cmd.driver = lp->isdn_device;					cmd.command = ISDN_CMD_HANGUP;					cmd.arg = lp->isdn_channel;					isdn_command(&cmd);					isdn_all_eaz(lp->isdn_device, lp->isdn_channel);				}				anymore = 1;				break;			default:				printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",				       lp->dialstate, lp->name);		}		p = (isdn_net_dev *) p->next;	}	isdn_timer_ctrl(ISDN_TIMER_NETDIAL, anymore);}/* * Perform hangup for a net-interface. */voidisdn_net_hangup(struct net_device *d){	isdn_net_local *lp = (isdn_net_local *) d->priv;	isdn_ctrl cmd;#ifdef CONFIG_ISDN_X25	struct concap_proto *cprot = lp->netdev->cprot;	struct concap_proto_ops *pops = cprot ? cprot->pops : NULL;#endif	if (lp->flags & ISDN_NET_CONNECTED) {		if (lp->slave != NULL) {			isdn_net_local *slp = (isdn_net_local *)lp->slave->priv;			if (slp->flags & ISDN_NET_CONNECTED) {				printk(KERN_INFO					"isdn_net: hang up slave %s before %s\n",					slp->name, lp->name);				isdn_net_hangup(lp->slave);			}		}		printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);#ifdef CONFIG_ISDN_PPP		if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)			isdn_ppp_free(lp);#endif		isdn_net_lp_disconnected(lp);#ifdef CONFIG_ISDN_X25		/* try if there are generic encap protocol		   receiver routines and signal the closure of		   the link */		if( pops && pops -> disconn_ind )		  pops -> disconn_ind(cprot);#endif /* CONFIG_ISDN_X25 */		cmd.driver = lp->isdn_device;		cmd.command = ISDN_CMD_HANGUP;		cmd.arg = lp->isdn_channel;		isdn_command(&cmd);		printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);		isdn_all_eaz(lp->isdn_device, lp->isdn_channel);	}	isdn_net_unbind_channel(lp);}typedef struct {	unsigned short source;	unsigned short dest;} ip_ports;static voidisdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp){	u_char *p = skb->nh.raw; /* hopefully, this was set correctly */	unsigned short proto = ntohs(skb->protocol);	int data_ofs;	ip_ports *ipp;	char addinfo[100];	addinfo[0] = '\0';	/* This check stolen from 2.1.72 dev_queue_xmit_nit() */	if (skb->nh.raw < skb->data || skb->nh.raw >= skb->tail) {		/* fall back to old isdn_net_log_packet method() */		char * buf = skb->data;		printk(KERN_DEBUG "isdn_net: protocol %04x is buggy, dev %s\n", skb->protocol, lp->name);		p = buf;		proto = ETH_P_IP;		switch (lp->p_encap) {			case ISDN_NET_ENCAP_IPTYP:				proto = ntohs(*(unsigned short *) &buf[0]);				p = &buf[2];				break;			case ISDN_NET_ENCAP_ETHER:				proto = ntohs(*(unsigned short *) &buf[12]);				p = &buf[14];				break;			case ISDN_NET_ENCAP_CISCOHDLC:				proto = ntohs(*(unsigned short *) &buf[2]);				p = &buf[4];				break;#ifdef CONFIG_ISDN_PPP			case ISDN_NET_ENCAP_SYNCPPP:				proto = ntohs(skb->protocol);				p = &buf[IPPP_MAX_HEADER];				break;#endif		}	}	data_ofs = ((p[0] & 15) * 4);	switch (proto) {		case ETH_P_IP:			switch (p[9]) {				case 1:					strcpy(addinfo, " ICMP");					break;				case 2:					strcpy(addinfo, " IGMP");					break;				case 4:					strcpy(addinfo, " IPIP");					break;				case 6:					ipp = (ip_ports *) (&p[data_ofs]);					sprintf(addinfo, " TCP, port: %d -> %d", ntohs(ipp->source),						ntohs(ipp->dest));					break;				case 8:					strcpy(addinfo, " EGP");					break;				case 12:					strcpy(addinfo, " PUP");					break;				case 17:					ipp = (ip_ports *) (&p[data_ofs]);					sprintf(addinfo, " UDP, port: %d -> %d", ntohs(ipp->source),						ntohs(ipp->dest));					break;				case 22:					strcpy(addinfo, " IDP");					break;			}

⌨️ 快捷键说明

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