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

📄 ppp.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			return 0;		}		if (current->signal & ~current->blocked) {			kfree (new_data);			return -EINTR;		}	}/* * Ensure that the caller's buffer is valid. */	status = verify_area (VERIFY_READ, data, count);	if (status != 0) {		kfree (new_data);		ppp->tbuf->locked = 0;		return status;	}	memcpy_fromfs (new_data, data, count);/* * Change the LQR frame */	count = send_revise_frame (ppp, new_data, count);/* * Send the data */	ppp_dev_xmit_frame (ppp, ppp->tbuf, new_data, count);	kfree (new_data);	return (int) count;}/* * Process the BSD compression IOCTL event for the tty device. */static intppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp){	struct compressor *cp;	struct ppp_option_data data;	int error;	int nb;	__u8 *ptr;	__u8 ccp_option[CCP_MAX_OPTION_LENGTH];/* * Fetch the compression parameters */	error = verify_area (VERIFY_READ, odp, sizeof (data));	if (error == 0) {		memcpy_fromfs (&data, odp, sizeof (data));		nb  = data.length;		ptr = data.ptr;		if ((__u32) nb >= (__u32)CCP_MAX_OPTION_LENGTH)			nb = CCP_MAX_OPTION_LENGTH;			error = verify_area (VERIFY_READ, ptr, nb);	}	if (error != 0)		return error;	memcpy_fromfs (ccp_option, ptr, nb);	if (ccp_option[1] < 2)	/* preliminary check on the length byte */		return (-EINVAL);	cp = find_compressor ((int) (unsigned int) (__u8) ccp_option[0]);	if (cp != (struct compressor *) 0) {		/*		 * Found a handler for the protocol - try to allocate		 * a compressor or decompressor.		 */		error = 0;		if (data.transmit) {			if (ppp->sc_xc_state != NULL)				(*ppp->sc_xcomp->comp_free)(ppp->sc_xc_state);			ppp->sc_xcomp    = cp;			ppp->sc_xc_state = cp->comp_alloc(ccp_option, nb);			if (ppp->sc_xc_state == NULL) {				if (ppp->flags & SC_DEBUG)					printk("ppp%ld: comp_alloc failed\n",					       ppp2dev (ppp)->base_addr);				error = -ENOBUFS;			}			ppp->flags &= ~SC_COMP_RUN;		} else {			if (ppp->sc_rc_state != NULL)				(*ppp->sc_rcomp->decomp_free)(ppp->sc_rc_state);			ppp->sc_rcomp    = cp;			ppp->sc_rc_state = cp->decomp_alloc(ccp_option, nb);			if (ppp->sc_rc_state == NULL) {				if (ppp->flags & SC_DEBUG)					printk("ppp%ld: decomp_alloc failed\n",					       ppp2dev (ppp)->base_addr);				error = ENOBUFS;			}			ppp->flags &= ~SC_DECOMP_RUN;		}		return (error);	}	if (ppp->flags & SC_DEBUG)		printk(KERN_DEBUG "ppp%ld: no compressor for [%x %x %x], %x\n",		       ppp2dev (ppp)->base_addr, ccp_option[0], ccp_option[1],		       ccp_option[2], nb);	return (-EINVAL);	/* no handler found */}/* * Process the IOCTL event for the tty device. */static intppp_tty_ioctl (struct tty_struct *tty, struct file * file,	       unsigned int param2, unsigned long param3){	struct ppp *ppp = tty2ppp (tty);	register int temp_i = 0;	int error = 0;/* * Verify the status of the PPP device. */	if (!ppp)		return -EBADF;	if (ppp->magic != PPP_MAGIC)		return -EBADF;	CHECK_PPP (-ENXIO);/* * The user must have an euid of root to do these requests. */	if (!suser ())		return -EPERM;/* * Set the MRU value */	switch (param2) {	case PPPIOCSMRU:		error = verify_area (VERIFY_READ, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			temp_i = get_user ((int *) param3);			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO				 "ppp_tty_ioctl: set mru to %x\n", temp_i);			if (ppp->mru != temp_i)				ppp_changedmtu (ppp, ppp2dev (ppp)->mtu, temp_i);		}		break;/* * Fetch the flags */	case PPPIOCGFLAGS:		error = verify_area (VERIFY_WRITE, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			temp_i = (ppp->flags & SC_MASK);#ifndef CHECK_CHARACTERS /* Don't generate errors if we don't check chars. */			temp_i |= SC_RCV_B7_1 | SC_RCV_B7_0 |				  SC_RCV_ODDP | SC_RCV_EVNP;#endif			put_user (temp_i, (int *) param3);			if (ppp->flags & SC_DEBUG)				printk (KERN_DEBUG				"ppp_tty_ioctl: get flags: addr %lx flags "				"%x\n", param3, temp_i);		}		break;/* * Set the flags for the various options */	case PPPIOCSFLAGS:		error = verify_area (VERIFY_READ, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			temp_i  = get_user ((int *) param3) & SC_MASK;			temp_i |= (ppp->flags & ~SC_MASK);			if ((ppp->flags & SC_CCP_OPEN) &&			    (temp_i & SC_CCP_OPEN) == 0)				ppp_ccp_closed (ppp);			if ((ppp->flags | temp_i) & SC_DEBUG)				printk (KERN_INFO			       "ppp_tty_ioctl: set flags to %x\n", temp_i);			ppp->flags = temp_i;		}		break;/* * Set the compression mode */	case PPPIOCSCOMPRESS:		error = ppp_set_compression (ppp,					    (struct ppp_option_data *) param3);		break;/* * Retrieve the transmit async map */	case PPPIOCGASYNCMAP:		error = verify_area (VERIFY_WRITE, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			put_user (ppp->xmit_async_map[0], (int *) param3);			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO				     "ppp_tty_ioctl: get asyncmap: addr "				     "%lx asyncmap %x\n",				     param3,				     ppp->xmit_async_map[0]);		}		break;/* * Set the transmit async map */	case PPPIOCSASYNCMAP:		error = verify_area (VERIFY_READ, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			ppp->xmit_async_map[0] = get_user ((int *) param3);			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO				     "ppp_tty_ioctl: set xmit asyncmap %x\n",				     ppp->xmit_async_map[0]);		}		break;/* * Set the receive async map */	case PPPIOCSRASYNCMAP:		error = verify_area (VERIFY_READ, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			ppp->recv_async_map = get_user ((int *) param3);			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO				     "ppp_tty_ioctl: set rcv asyncmap %x\n",				     ppp->recv_async_map);		}		break;/* * Obtain the unit number for this device. */	case PPPIOCGUNIT:		error = verify_area (VERIFY_WRITE, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			put_user (ppp2dev (ppp)->base_addr, (int *) param3);			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO					"ppp_tty_ioctl: get unit: %ld",					ppp2dev (ppp)->base_addr);		}		break;/* * Set the debug level */	case PPPIOCSDEBUG:		error = verify_area (VERIFY_READ, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			temp_i  = (get_user ((int *) param3) & 0x1F) << 16;			temp_i |= (ppp->flags & ~0x1F0000);			if ((ppp->flags | temp_i) & SC_DEBUG)				printk (KERN_INFO			       "ppp_tty_ioctl: set flags to %x\n", temp_i);			ppp->flags = temp_i;		}		break;/* * Get the debug level */	case PPPIOCGDEBUG:		error = verify_area (VERIFY_WRITE, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			temp_i = (ppp->flags >> 16) & 0x1F;			put_user (temp_i, (int *) param3);			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO					"ppp_tty_ioctl: get debug level %d\n",					temp_i);      		}		break;/* * Get the times since the last send/receive frame operation */	case PPPIOCGIDLE:		error = verify_area (VERIFY_WRITE, (void *) param3,				     sizeof (struct ppp_idle));		if (error == 0) {			struct ppp_idle cur_ddinfo;			__u32 cur_jiffies = jiffies;			/* change absolute times to relative times. */			cur_ddinfo.xmit_idle = (cur_jiffies - ppp->ddinfo.xmit_idle) / HZ;			cur_ddinfo.recv_idle = (cur_jiffies - ppp->ddinfo.recv_idle) / HZ;			memcpy_tofs ((void *) param3, &cur_ddinfo,				     sizeof (cur_ddinfo));			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO				"ppp_tty_ioctl: read demand dial info\n");		}		break;/* * Retrieve the extended async map */	case PPPIOCGXASYNCMAP:		error = verify_area (VERIFY_WRITE,				     (void *) param3,				     sizeof (ppp->xmit_async_map));		if (error == 0) {			memcpy_tofs ((void *) param3,				     ppp->xmit_async_map,				     sizeof (ppp->xmit_async_map));			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO				"ppp_tty_ioctl: get xasyncmap: addr %lx\n",				param3);		}		break;/* * Set the async extended map */	case PPPIOCSXASYNCMAP:		error = verify_area (VERIFY_READ, (void *) param3,				     sizeof (ppp->xmit_async_map));		if (error == 0) {			__u32 temp_tbl[8];			memcpy_fromfs (temp_tbl, (void *) param3,				       sizeof (ppp->xmit_async_map));			temp_tbl[1]  =  0x00000000;			temp_tbl[2] &= ~0x40000000;			temp_tbl[3] |=  0x60000000;			if ((temp_tbl[2] & temp_tbl[3]) != 0 ||			    (temp_tbl[4] & temp_tbl[5]) != 0 ||			    (temp_tbl[6] & temp_tbl[7]) != 0)				error = -EINVAL;			else {				memcpy (ppp->xmit_async_map, temp_tbl,					sizeof (ppp->xmit_async_map));				if (ppp->flags & SC_DEBUG)					printk (KERN_INFO					"ppp_tty_ioctl: set xasyncmap\n");			}		}		break;/* * Set the maximum VJ header compression slot number. */	case PPPIOCSMAXCID:		error = verify_area (VERIFY_READ, (void *) param3,				     sizeof (temp_i));		if (error == 0) {			temp_i = get_user ((int *) param3) + 1;			if (ppp->flags & SC_DEBUG)				printk (KERN_INFO				     "ppp_tty_ioctl: set maxcid to %d\n",				     temp_i);			if (ppp->slcomp != NULL)				slhc_free (ppp->slcomp);			ppp->slcomp = slhc_init (16, temp_i);			if (ppp->slcomp == NULL) {				if (ppp->flags & SC_DEBUG)					printk (KERN_ERR					"ppp: no space for compression buffers!\n");				ppp_release (ppp);				error = -ENOMEM;			}		}		break;	case PPPIOCXFERUNIT:		ppp_tty_close_local (tty, current->pid);		break;	case PPPIOCGNPMODE:	case PPPIOCSNPMODE:		error = verify_area (VERIFY_READ, (void *) param3,					sizeof (struct npioctl));		if (error == 0) {			struct npioctl npi;			memcpy_fromfs (&npi,				       (void *) param3,				       sizeof (npi));			switch (npi.protocol) {			case PPP_IP:				npi.protocol = NP_IP;				break;			default:				error = -EINVAL;			}			if (error != 0)				break;			if (param2 == PPPIOCGNPMODE) {				npi.mode = ppp->sc_npmode[npi.protocol];				error = verify_area (VERIFY_WRITE,						     (void *) param3,						     sizeof (npi));				if (error != 0)					break;				memcpy_tofs ((void *) param3,					     &npi,					     sizeof (npi));				break;			}			if (npi.mode != ppp->sc_npmode[npi.protocol]) {				ppp->sc_npmode[npi.protocol] = npi.mode;				if (npi.mode != NPMODE_QUEUE) {					/* ppp_requeue(ppp); maybe needed */					ppp_tty_wakeup (ppp2tty(ppp));				}			}		}		break;/* * Allow users to read, but not set, the serial port parameters */	case TCGETS:	case TCGETA:		error = n_tty_ioctl (tty, file, param2, param3);		break;	case FIONREAD:		error = verify_area (VERIFY_WRITE,				     (void *) param3,				     sizeof (int));		if (error == 0) {			int count = ppp->ubuf->tail - ppp->ubuf->head;			if (count < 0)				count += (ppp->ubuf->size + 1);			put_user (count, (int *) param3);		}		break;/* *  All other ioctl() events will come here. */	default:		if (ppp->flags & SC_DEBUG)			printk (KERN_ERR				"ppp_tty_ioctl: invalid ioctl: %x, addr %lx\n",				param2,				param3);		error = -ENOIOCTLCMD;		break;	}	return error;}/* * TTY callback. * * Process the select() statement for the PPP device. */static intppp_tty_select (struct tty_struct *tty, struct inode *inode,		struct file *filp, int sel_type, select_table * wait){	struct ppp *ppp = tty2ppp (tty);	int result = 1;/* * Verify the status of the PPP device. */	if (!ppp)		return -EBADF;	if (ppp->magic != PPP_MAGIC)		return -EBADF;	CHECK_PPP (0);/* * Branch on the type of select mode. A read request must lock the user * buffer area. */	switch (sel_type) {	case SEL_IN:		if (set_bit (0, &ppp->ubuf->locked) == 0) {			/* Test for the presence of data in the queue */			if (ppp->ubuf->head != ppp->ubuf->tail) {				clear_bit (0, &ppp->ubuf->locked);				break;			}			clear_bit (0, &ppp->ubuf->locked);		}		/* fall through */		/* * Exceptions or read errors. */	case SEL_EX:		/* Is this a pty link and the remote disconnected? */		if (tty->flags & (1 << TTY_OTHER_CLOSED))			break;		/* Is this a local link and the modem disconnected? */		if (tty_hung_up_p (filp))			break;		select_wait (&ppp->read_wait, wait);		result = 0;		break;/* * Write mode. A write is allowed if there is no current transmission. */	case SEL_OUT:		if (ppp->tbuf->locked != 0) {			select_wait (&ppp->write_wait, wait);			result = 0;		}		break;	}	return result;}/************************************************************* * NETWORK OUTPUT *    This routine accepts requests from the network layer *    and attempts to deliver the packets. *    It also includes various routine

⌨️ 快捷键说明

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