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

📄 irnet_ppp.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    default:      sprintf(event, "Bug\n");    }  /* Increment our event index */  ap->event_index = (ap->event_index + 1) % IRNET_MAX_EVENTS;  DEBUG(CTRL_INFO, "Event is :%s", event);  /* Copy it to the user */  if(copy_to_user(buf, event, strlen(event)))    {      DERROR(CTRL_ERROR, "Invalid user space pointer.\n");      return -EFAULT;    }  DEXIT(CTRL_TRACE, "\n");  return(strlen(event));}/*------------------------------------------------------------------*//* * Poll : called when someone do a select on /dev/irnet. * Just check if there are new events... */static inline unsigned intirnet_ctrl_poll(irnet_socket *	ap,		struct file *	file,		poll_table *	wait){  unsigned int mask;  DENTER(CTRL_TRACE, "(ap=0x%X)\n", (unsigned int) ap);  poll_wait(file, &irnet_events.rwait, wait);  mask = POLLOUT | POLLWRNORM;  /* If there is unread events */  if(ap->event_index != irnet_events.index)    mask |= POLLIN | POLLRDNORM;#ifdef INITIAL_DISCOVERY  if(ap->disco_number != -1)    mask |= POLLIN | POLLRDNORM;#endif /* INITIAL_DISCOVERY */  DEXIT(CTRL_TRACE, " - mask=0x%X\n", mask);  return mask;}/*********************** FILESYSTEM CALLBACKS ***********************//* * Implement the usual open, read, write functions that will be called * by the file system when some action is performed on /dev/irnet. * Most of those actions will in fact be performed by "pppd" or * the control channel, we just act as a redirector... *//*------------------------------------------------------------------*//* * Open : when somebody open /dev/irnet * We basically create a new instance of irnet and initialise it. */static intdev_irnet_open(struct inode *	inode,	       struct file *	file){  struct irnet_socket *	ap;  int			err;  DENTER(FS_TRACE, "(file=0x%X)\n", (unsigned int) file);#ifdef SECURE_DEVIRNET  /* This could (should?) be enforced by the permissions on /dev/irnet. */  if(!capable(CAP_NET_ADMIN))    return -EPERM;#endif /* SECURE_DEVIRNET */  /* Allocate a private structure for this IrNET instance */  ap = kmalloc(sizeof(*ap), GFP_KERNEL);  DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n");  MOD_INC_USE_COUNT;  /* initialize the irnet structure */  memset(ap, 0, sizeof(*ap));  ap->file = file;  /* PPP channel setup */  ap->ppp_open = 0;  ap->chan.private = ap;  ap->chan.ops = &irnet_ppp_ops;  ap->chan.mtu = (2048 - TTP_MAX_HEADER - 2 - PPP_HDRLEN);  ap->chan.hdrlen = 2 + TTP_MAX_HEADER;		/* for A/C + Max IrDA hdr */  /* PPP parameters */  ap->mru = (2048 - TTP_MAX_HEADER - 2 - PPP_HDRLEN);  ap->xaccm[0] = ~0U;  ap->xaccm[3] = 0x60000000U;  ap->raccm = ~0U;  /* Setup the IrDA part... */  err = irda_irnet_create(ap);  if(err)    {      DERROR(FS_ERROR, "Can't setup IrDA link...\n");      kfree(ap);      MOD_DEC_USE_COUNT;      return err;    }  /* For the control channel */  ap->event_index = irnet_events.index;	/* Cancel all past events */  /* Put our stuff where we will be able to find it later */  file->private_data = ap;  DEXIT(FS_TRACE, " - ap=0x%X\n", (unsigned int) ap);  return 0;}/*------------------------------------------------------------------*//* * Close : when somebody close /dev/irnet * Destroy the instance of /dev/irnet */static intdev_irnet_close(struct inode *	inode,		struct file *	file){  irnet_socket *	ap = (struct irnet_socket *) file->private_data;  DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)\n",	 (unsigned int) file, (unsigned int) ap);  DABORT(ap == NULL, 0, FS_ERROR, "ap is NULL !!!\n");  /* Detach ourselves */  file->private_data = NULL;  /* Close IrDA stuff */  irda_irnet_destroy(ap);  /* Disconnect from the generic PPP layer if not already done */  if(ap->ppp_open)    {      DERROR(FS_ERROR, "Channel still registered - deregistering !\n");      ppp_unregister_channel(&ap->chan);      ap->ppp_open = 0;    }  kfree(ap);  MOD_DEC_USE_COUNT;  DEXIT(FS_TRACE, "\n");  return 0;}/*------------------------------------------------------------------*//* * Write does nothing. * (we receive packet from ppp_generic through ppp_irnet_send()) */static ssize_tdev_irnet_write(struct file *	file,		const char *	buf,		size_t		count,		loff_t *	ppos){  irnet_socket *	ap = (struct irnet_socket *) file->private_data;  DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)\n",	(unsigned int) file, (unsigned int) ap, count);  DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n");  /* If we are connected to ppp_generic, let it handle the job */  if(ap->ppp_open)    return -EAGAIN;  else    return irnet_ctrl_write(ap, buf, count);}/*------------------------------------------------------------------*//* * Read doesn't do much either. * (pppd poll us, but ultimately reads through /dev/ppp) */static ssize_tdev_irnet_read(struct file *	file,	       char *		buf,	       size_t		count,	       loff_t *		ppos){  irnet_socket *	ap = (struct irnet_socket *) file->private_data;  DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)\n",	(unsigned int) file, (unsigned int) ap, count);  DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n");  /* If we are connected to ppp_generic, let it handle the job */  if(ap->ppp_open)    return -EAGAIN;  else    return irnet_ctrl_read(ap, file, buf, count);}/*------------------------------------------------------------------*//* * Poll : called when someone do a select on /dev/irnet */static unsigned intdev_irnet_poll(struct file *	file,	       poll_table *	wait){  irnet_socket *	ap = (struct irnet_socket *) file->private_data;  unsigned int		mask;  DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)\n",	 (unsigned int) file, (unsigned int) ap);  mask = POLLOUT | POLLWRNORM;  DABORT(ap == NULL, mask, FS_ERROR, "ap is NULL !!!\n");  /* If we are connected to ppp_generic, let it handle the job */  if(!ap->ppp_open)    mask |= irnet_ctrl_poll(ap, file, wait);  DEXIT(FS_TRACE, " - mask=0x%X\n", mask);  return(mask);}/*------------------------------------------------------------------*//* * IOCtl : Called when someone does some ioctls on /dev/irnet * This is the way pppd configure us and control us while the PPP * instance is active. */static intdev_irnet_ioctl(struct inode *	inode,		struct file *	file,		unsigned int	cmd,		unsigned long	arg){  irnet_socket *	ap = (struct irnet_socket *) file->private_data;  int			err;  int			val;  DENTER(FS_TRACE, "(file=0x%X, ap=0x%X, cmd=0x%X)\n",	 (unsigned int) file, (unsigned int) ap, cmd);  /* Basic checks... */  DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...\n");#ifdef SECURE_DEVIRNET  if(!capable(CAP_NET_ADMIN))    return -EPERM;#endif /* SECURE_DEVIRNET */  err = -EFAULT;  switch(cmd)    {      /* Set discipline (should be N_SYNC_PPP or N_TTY) */    case TIOCSETD:      if(get_user(val, (int *) arg))	break;      if((val == N_SYNC_PPP) || (val == N_PPP))	{	  DEBUG(FS_INFO, "Entering PPP discipline.\n");	  /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/	  err = ppp_register_channel(&ap->chan);	  if(err == 0)	    {	      /* Our ppp side is active */	      ap->ppp_open = 1;	      DEBUG(FS_INFO, "Trying to establish a connection.\n");	      /* Setup the IrDA link now - may fail... */	      irda_irnet_connect(ap);	    }	  else	    DERROR(FS_ERROR, "Can't setup PPP channel...\n");	}      else	{	  /* In theory, should be N_TTY */	  DEBUG(FS_INFO, "Exiting PPP discipline.\n");	  /* Disconnect from the generic PPP layer */	  if(ap->ppp_open)	    ppp_unregister_channel(&ap->chan);	  else	    DERROR(FS_ERROR, "Channel not registered !\n");	  ap->ppp_open = 0;	  err = 0;	}      break;      /* Query PPP channel and unit number */    case PPPIOCGCHAN:      if(!ap->ppp_open)	break;      if(put_user(ppp_channel_index(&ap->chan), (int *) arg))	break;      DEBUG(FS_INFO, "Query channel.\n");      err = 0;      break;    case PPPIOCGUNIT:      if(!ap->ppp_open)	break;      if(put_user(ppp_unit_number(&ap->chan), (int *) arg))	break;      DEBUG(FS_INFO, "Query unit number.\n");      err = 0;      break;      /* All these ioctls can be passed both directly and from ppp_generic,       * so we just deal with them in one place...       */    case PPPIOCGFLAGS:    case PPPIOCSFLAGS:    case PPPIOCGASYNCMAP:    case PPPIOCSASYNCMAP:    case PPPIOCGRASYNCMAP:    case PPPIOCSRASYNCMAP:    case PPPIOCGXASYNCMAP:    case PPPIOCSXASYNCMAP:    case PPPIOCGMRU:    case PPPIOCSMRU:      DEBUG(FS_INFO, "Standard PPP ioctl.\n");      if(!capable(CAP_NET_ADMIN))	err = -EPERM;      else	err = ppp_irnet_ioctl(&ap->chan, cmd, arg);      break;      /* TTY IOCTLs : Pretend that we are a tty, to keep pppd happy */      /* Get termios */    case TCGETS:      DEBUG(FS_INFO, "Get termios.\n");      if(kernel_termios_to_user_termios((struct termios *)arg, &ap->termios))	break;      err = 0;      break;      /* Set termios */    case TCSETSF:      DEBUG(FS_INFO, "Set termios.\n");      if(user_termios_to_kernel_termios(&ap->termios, (struct termios *) arg))	break;      err = 0;      break;      /* Set DTR/RTS */    case TIOCMBIS:     case TIOCMBIC:      /* Set exclusive/non-exclusive mode */    case TIOCEXCL:    case TIOCNXCL:      DEBUG(FS_INFO, "TTY compatibility.\n");      err = 0;      break;    case TCGETA:      DEBUG(FS_INFO, "TCGETA\n");      break;    case TCFLSH:      DEBUG(FS_INFO, "TCFLSH\n");      /* Note : this will flush buffers in PPP, so it *must* be done       * We should also worry that we don't accept junk here and that       * we get rid of our own buffers */#ifdef FLUSH_TO_PPP      ppp_output_wakeup(&ap->chan);

⌨️ 快捷键说明

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