irnet_ppp.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:30k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * IrNET protocol module : Synchronous PPP over an IrDA socket.
  3.  *
  4.  * Jean II - HPL `00 - <jt@hpl.hp.com>
  5.  *
  6.  * This file implement the PPP interface and /dev/irnet character device.
  7.  * The PPP interface hook to the ppp_generic module, handle all our
  8.  * relationship to the PPP code in the kernel (and by extension to pppd),
  9.  * and exchange PPP frames with this module (send/receive).
  10.  * The /dev/irnet device is used primarily for 2 functions :
  11.  * 1) as a stub for pppd (the ppp daemon), so that we can appropriately
  12.  * generate PPP sessions (we pretend we are a tty).
  13.  * 2) as a control channel (write commands, read events)
  14.  */
  15. #include "irnet_ppp.h" /* Private header */
  16. /* Please put other headers in irnet.h - Thanks */
  17. /************************* CONTROL CHANNEL *************************/
  18. /*
  19.  * When a pppd instance is not active on /dev/irnet, it acts as a control
  20.  * channel.
  21.  * Writting allow to set up the IrDA destination of the IrNET channel,
  22.  * and any application may be read events happening in IrNET...
  23.  */
  24. /*------------------------------------------------------------------*/
  25. /*
  26.  * Write is used to send a command to configure a IrNET channel
  27.  * before it is open by pppd. The syntax is : "command argument"
  28.  * Currently there is only two defined commands :
  29.  * o name : set the requested IrDA nickname of the IrNET peer.
  30.  * o addr : set the requested IrDA address of the IrNET peer.
  31.  * Note : the code is crude, but effective...
  32.  */
  33. static inline ssize_t
  34. irnet_ctrl_write(irnet_socket * ap,
  35.  const char * buf,
  36.  size_t count)
  37. {
  38.   char command[IRNET_MAX_COMMAND];
  39.   char * start; /* Current command beeing processed */
  40.   char * next; /* Next command to process */
  41.   int length; /* Length of current command */
  42.   DENTER(CTRL_TRACE, "(ap=0x%X, count=%d)n", (unsigned int) ap, count);
  43.   /* Check for overflow... */
  44.   DABORT(count >= IRNET_MAX_COMMAND, -ENOMEM,
  45.  CTRL_ERROR, "Too much data !!!n");
  46.   /* Get the data in the driver */
  47.   if(copy_from_user(command, buf, count))
  48.     {
  49.       DERROR(CTRL_ERROR, "Invalid user space pointer.n");
  50.       return -EFAULT;
  51.     }
  52.   /* Safe terminate the string */
  53.   command[count] = '';
  54.   DEBUG(CTRL_INFO, "Command line received is ``%s'' (%d).n",
  55. command, count);
  56.   /* Check every commands in the command line */
  57.   next = command;
  58.   while(next != NULL)
  59.     {
  60.       /* Look at the next command */
  61.       start = next;
  62.       /* Scrap whitespaces before the command */
  63.       while(isspace(*start))
  64. start++;
  65.       /* ',' is our command separator */
  66.       next = strchr(start, ',');
  67.       if(next)
  68. {
  69.   *next = ''; /* Terminate command */
  70.   length = next - start; /* Length */
  71.   next++; /* Skip the '' */
  72. }
  73.       else
  74. length = strlen(start);
  75.       DEBUG(CTRL_INFO, "Found command ``%s'' (%d).n", start, length);
  76.       /* Check if we recognised one of the known command
  77.        * We can't use "switch" with strings, so hack with "continue" */
  78.       
  79.       /* First command : name -> Requested IrDA nickname */
  80.       if(!strncmp(start, "name", 4))
  81. {
  82.   /* Copy the name only if is included and not "any" */
  83.   if((length > 5) && (strcmp(start + 5, "any")))
  84.     {
  85.       /* Strip out trailing whitespaces */
  86.       while(isspace(start[length - 1]))
  87. length--;
  88.       /* Copy the name for later reuse */
  89.       memcpy(ap->rname, start + 5, length - 5);
  90.       ap->rname[length - 5] = '';
  91.     }
  92.   else
  93.     ap->rname[0] = '';
  94.   DEBUG(CTRL_INFO, "Got rname = ``%s''n", ap->rname);
  95.   /* Restart the loop */
  96.   continue;
  97. }
  98.       /* Second command : addr, daddr -> Requested IrDA destination address
  99.        * Also process : saddr -> Requested IrDA source address */
  100.       if((!strncmp(start, "addr", 4)) ||
  101.  (!strncmp(start, "daddr", 5)) ||
  102.  (!strncmp(start, "saddr", 5)))
  103. {
  104.   __u32 addr = DEV_ADDR_ANY;
  105.   /* Copy the address only if is included and not "any" */
  106.   if((length > 5) && (strcmp(start + 5, "any")))
  107.     {
  108.       char * begp = start + 5;
  109.       char * endp;
  110.       /* Scrap whitespaces before the command */
  111.       while(isspace(*begp))
  112. begp++;
  113.       /* Convert argument to a number (last arg is the base) */
  114.       addr = simple_strtoul(begp, &endp, 16);
  115.       /* Has it worked  ? (endp should be start + length) */
  116.       DABORT(endp <= (start + 5), -EINVAL,
  117.      CTRL_ERROR, "Invalid address.n");
  118.     }
  119.   /* Which type of address ? */
  120.   if(start[0] == 's')
  121.     {
  122.       /* Save it */
  123.       ap->rsaddr = addr;
  124.       DEBUG(CTRL_INFO, "Got rsaddr = %08xn", ap->rsaddr);
  125.     }
  126.   else
  127.     {
  128.       /* Save it */
  129.       ap->rdaddr = addr;
  130.       DEBUG(CTRL_INFO, "Got rdaddr = %08xn", ap->rdaddr);
  131.     }
  132.   /* Restart the loop */
  133.   continue;
  134. }
  135.       /* Other possible command : connect N (number of retries) */
  136.       /* No command matched -> Failed... */
  137.       DABORT(1, -EINVAL, CTRL_ERROR, "Not a recognised IrNET command.n");
  138.     }
  139.   /* Success : we have parsed all commands successfully */
  140.   return(count);
  141. }
  142. #ifdef INITIAL_DISCOVERY
  143. /*------------------------------------------------------------------*/
  144. /*
  145.  * Function irnet_read_discovery_log (self)
  146.  *
  147.  *    Read the content on the discovery log
  148.  *
  149.  * This function dump the current content of the discovery log
  150.  * at the startup of the event channel.
  151.  * Return 1 if written on the control channel...
  152.  *
  153.  * State of the ap->disco_XXX variables :
  154.  * at socket creation : disco_index = 0 ; disco_number = 0
  155.  * while reading : disco_index = X ; disco_number = Y
  156.  * After reading : disco_index = Y ; disco_number = -1
  157.  */
  158. static inline int
  159. irnet_read_discovery_log(irnet_socket * ap,
  160.  char * event)
  161. {
  162.   int done_event = 0;
  163.   DENTER(CTRL_TRACE, "(ap=0x%X, event=0x%X)n",
  164.  (unsigned int) ap, (unsigned int) event);
  165.   /* Test if we have some work to do or we have already finished */
  166.   if(ap->disco_number == -1)
  167.     {
  168.       DEBUG(CTRL_INFO, "Already donen");
  169.       return 0;
  170.     }
  171.   /* Test if it's the first time and therefore we need to get the log */
  172.   if(ap->disco_index == 0)
  173.     {
  174.       __u16 mask = irlmp_service_to_hint(S_LAN);
  175.       /* Ask IrLMP for the current discovery log */
  176.       ap->discoveries = irlmp_get_discoveries(&ap->disco_number, mask,
  177.       DISCOVERY_DEFAULT_SLOTS);
  178.       /* Check if the we got some results */
  179.       if(ap->discoveries == NULL)
  180. ap->disco_number = -1;
  181.       DEBUG(CTRL_INFO, "Got the log (0x%X), size is %dn",
  182.     (unsigned int) ap->discoveries, ap->disco_number);
  183.     }
  184.   /* Check if we have more item to dump */
  185.   if(ap->disco_index < ap->disco_number)
  186.     {
  187.       /* Write an event */
  188.       sprintf(event, "Found %08x (%s) behind %08xn",
  189.       ap->discoveries[ap->disco_index].daddr,
  190.       ap->discoveries[ap->disco_index].info,
  191.       ap->discoveries[ap->disco_index].saddr);
  192.       DEBUG(CTRL_INFO, "Writing discovery %d : %sn",
  193.     ap->disco_index, ap->discoveries[ap->disco_index].info);
  194.       /* We have an event */
  195.       done_event = 1;
  196.       /* Next discovery */
  197.       ap->disco_index++;
  198.     }
  199.   /* Check if we have done the last item */
  200.   if(ap->disco_index >= ap->disco_number)
  201.     {
  202.       /* No more items : remove the log and signal termination */
  203.       DEBUG(CTRL_INFO, "Cleaning up log (0x%X)n",
  204.     (unsigned int) ap->discoveries);
  205.       if(ap->discoveries != NULL)
  206. {
  207.   /* Cleanup our copy of the discovery log */
  208.   kfree(ap->discoveries);
  209.   ap->discoveries = NULL;
  210. }
  211.       ap->disco_number = -1;
  212.     }
  213.   return done_event;
  214. }
  215. #endif /* INITIAL_DISCOVERY */
  216. /*------------------------------------------------------------------*/
  217. /*
  218.  * Read is used to get IrNET events
  219.  */
  220. static inline ssize_t
  221. irnet_ctrl_read(irnet_socket * ap,
  222. struct file * file,
  223. char * buf,
  224. size_t count)
  225. {
  226.   DECLARE_WAITQUEUE(wait, current);
  227.   char event[64]; /* Max event is 61 char */
  228.   ssize_t ret = 0;
  229.   DENTER(CTRL_TRACE, "(ap=0x%X, count=%d)n", (unsigned int) ap, count);
  230.   /* Check if we can write an event out in one go */
  231.   DABORT(count < sizeof(event), -EOVERFLOW, CTRL_ERROR, "Buffer to small.n");
  232. #ifdef INITIAL_DISCOVERY
  233.   /* Check if we have read the log */
  234.   if(irnet_read_discovery_log(ap, event))
  235.     {
  236.       /* We have an event !!! Copy it to the user */
  237.       if(copy_to_user(buf, event, strlen(event)))
  238. {
  239.   DERROR(CTRL_ERROR, "Invalid user space pointer.n");
  240.   return -EFAULT;
  241. }
  242.       DEXIT(CTRL_TRACE, "n");
  243.       return(strlen(event));
  244.     }
  245. #endif /* INITIAL_DISCOVERY */
  246.   /* Put ourselves on the wait queue to be woken up */
  247.   add_wait_queue(&irnet_events.rwait, &wait);
  248.   current->state = TASK_INTERRUPTIBLE;
  249.   for(;;)
  250.     {
  251.       /* If there is unread events */
  252.       ret = 0;
  253.       if(ap->event_index != irnet_events.index)
  254. break;
  255.       ret = -EAGAIN;
  256.       if(file->f_flags & O_NONBLOCK)
  257. break;
  258.       ret = -ERESTARTSYS;
  259.       if(signal_pending(current))
  260. break;
  261.       /* Yield and wait to be woken up */
  262.       schedule();
  263.     }
  264.   current->state = TASK_RUNNING;
  265.   remove_wait_queue(&irnet_events.rwait, &wait);
  266.   /* Did we got it ? */
  267.   if(ret != 0)
  268.     {
  269.       /* No, return the error code */
  270.       DEXIT(CTRL_TRACE, " - ret %dn", ret);
  271.       return ret;
  272.     }
  273.   /* Which event is it ? */
  274.   switch(irnet_events.log[ap->event_index].event)
  275.     {
  276.     case IRNET_DISCOVER:
  277.       sprintf(event, "Discovered %08x (%s) behind %08xn",
  278.       irnet_events.log[ap->event_index].daddr,
  279.       irnet_events.log[ap->event_index].name,
  280.       irnet_events.log[ap->event_index].saddr);
  281.       break;
  282.     case IRNET_EXPIRE:
  283.       sprintf(event, "Expired %08x (%s) behind %08xn",
  284.       irnet_events.log[ap->event_index].daddr,
  285.       irnet_events.log[ap->event_index].name,
  286.       irnet_events.log[ap->event_index].saddr);
  287.       break;
  288.     case IRNET_CONNECT_TO:
  289.       sprintf(event, "Connected to %08x (%s) on ppp%dn",
  290.       irnet_events.log[ap->event_index].daddr,
  291.       irnet_events.log[ap->event_index].name,
  292.       irnet_events.log[ap->event_index].unit);
  293.       break;
  294.     case IRNET_CONNECT_FROM:
  295.       sprintf(event, "Connection from %08x (%s) on ppp%dn",
  296.       irnet_events.log[ap->event_index].daddr,
  297.       irnet_events.log[ap->event_index].name,
  298.       irnet_events.log[ap->event_index].unit);
  299.       break;
  300.     case IRNET_REQUEST_FROM:
  301.       sprintf(event, "Request from %08x (%s) behind %08xn",
  302.       irnet_events.log[ap->event_index].daddr,
  303.       irnet_events.log[ap->event_index].name,
  304.       irnet_events.log[ap->event_index].saddr);
  305.       break;
  306.     case IRNET_NOANSWER_FROM:
  307.       sprintf(event, "No-answer from %08x (%s) on ppp%dn",
  308.       irnet_events.log[ap->event_index].daddr,
  309.       irnet_events.log[ap->event_index].name,
  310.       irnet_events.log[ap->event_index].unit);
  311.       break;
  312.     case IRNET_BLOCKED_LINK:
  313.       sprintf(event, "Blocked link with %08x (%s) on ppp%dn",
  314.       irnet_events.log[ap->event_index].daddr,
  315.       irnet_events.log[ap->event_index].name,
  316.       irnet_events.log[ap->event_index].unit);
  317.       break;
  318.     case IRNET_DISCONNECT_FROM:
  319.       sprintf(event, "Disconnection from %08x (%s) on ppp%dn",
  320.       irnet_events.log[ap->event_index].daddr,
  321.       irnet_events.log[ap->event_index].name,
  322.       irnet_events.log[ap->event_index].unit);
  323.       break;
  324.     case IRNET_DISCONNECT_TO:
  325.       sprintf(event, "Disconnected to %08x (%s)n",
  326.       irnet_events.log[ap->event_index].daddr,
  327.       irnet_events.log[ap->event_index].name);
  328.       break;
  329.     default:
  330.       sprintf(event, "Bugn");
  331.     }
  332.   /* Increment our event index */
  333.   ap->event_index = (ap->event_index + 1) % IRNET_MAX_EVENTS;
  334.   DEBUG(CTRL_INFO, "Event is :%s", event);
  335.   /* Copy it to the user */
  336.   if(copy_to_user(buf, event, strlen(event)))
  337.     {
  338.       DERROR(CTRL_ERROR, "Invalid user space pointer.n");
  339.       return -EFAULT;
  340.     }
  341.   DEXIT(CTRL_TRACE, "n");
  342.   return(strlen(event));
  343. }
  344. /*------------------------------------------------------------------*/
  345. /*
  346.  * Poll : called when someone do a select on /dev/irnet.
  347.  * Just check if there are new events...
  348.  */
  349. static inline unsigned int
  350. irnet_ctrl_poll(irnet_socket * ap,
  351. struct file * file,
  352. poll_table * wait)
  353. {
  354.   unsigned int mask;
  355.   DENTER(CTRL_TRACE, "(ap=0x%X)n", (unsigned int) ap);
  356.   poll_wait(file, &irnet_events.rwait, wait);
  357.   mask = POLLOUT | POLLWRNORM;
  358.   /* If there is unread events */
  359.   if(ap->event_index != irnet_events.index)
  360.     mask |= POLLIN | POLLRDNORM;
  361. #ifdef INITIAL_DISCOVERY
  362.   if(ap->disco_number != -1)
  363.     mask |= POLLIN | POLLRDNORM;
  364. #endif /* INITIAL_DISCOVERY */
  365.   DEXIT(CTRL_TRACE, " - mask=0x%Xn", mask);
  366.   return mask;
  367. }
  368. /*********************** FILESYSTEM CALLBACKS ***********************/
  369. /*
  370.  * Implement the usual open, read, write functions that will be called
  371.  * by the file system when some action is performed on /dev/irnet.
  372.  * Most of those actions will in fact be performed by "pppd" or
  373.  * the control channel, we just act as a redirector...
  374.  */
  375. /*------------------------------------------------------------------*/
  376. /*
  377.  * Open : when somebody open /dev/irnet
  378.  * We basically create a new instance of irnet and initialise it.
  379.  */
  380. static int
  381. dev_irnet_open(struct inode * inode,
  382.        struct file * file)
  383. {
  384.   struct irnet_socket * ap;
  385.   int err;
  386.   DENTER(FS_TRACE, "(file=0x%X)n", (unsigned int) file);
  387. #ifdef SECURE_DEVIRNET
  388.   /* This could (should?) be enforced by the permissions on /dev/irnet. */
  389.   if(!capable(CAP_NET_ADMIN))
  390.     return -EPERM;
  391. #endif /* SECURE_DEVIRNET */
  392.   /* Allocate a private structure for this IrNET instance */
  393.   ap = kmalloc(sizeof(*ap), GFP_KERNEL);
  394.   DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...n");
  395.   MOD_INC_USE_COUNT;
  396.   /* initialize the irnet structure */
  397.   memset(ap, 0, sizeof(*ap));
  398.   ap->file = file;
  399.   /* PPP channel setup */
  400.   ap->ppp_open = 0;
  401.   ap->chan.private = ap;
  402.   ap->chan.ops = &irnet_ppp_ops;
  403.   ap->chan.mtu = (2048 - TTP_MAX_HEADER - 2 - PPP_HDRLEN);
  404.   ap->chan.hdrlen = 2 + TTP_MAX_HEADER; /* for A/C + Max IrDA hdr */
  405.   /* PPP parameters */
  406.   ap->mru = (2048 - TTP_MAX_HEADER - 2 - PPP_HDRLEN);
  407.   ap->xaccm[0] = ~0U;
  408.   ap->xaccm[3] = 0x60000000U;
  409.   ap->raccm = ~0U;
  410.   /* Setup the IrDA part... */
  411.   err = irda_irnet_create(ap);
  412.   if(err)
  413.     {
  414.       DERROR(FS_ERROR, "Can't setup IrDA link...n");
  415.       kfree(ap);
  416.       MOD_DEC_USE_COUNT;
  417.       return err;
  418.     }
  419.   /* For the control channel */
  420.   ap->event_index = irnet_events.index; /* Cancel all past events */
  421.   /* Put our stuff where we will be able to find it later */
  422.   file->private_data = ap;
  423.   DEXIT(FS_TRACE, " - ap=0x%Xn", (unsigned int) ap);
  424.   return 0;
  425. }
  426. /*------------------------------------------------------------------*/
  427. /*
  428.  * Close : when somebody close /dev/irnet
  429.  * Destroy the instance of /dev/irnet
  430.  */
  431. static int
  432. dev_irnet_close(struct inode * inode,
  433. struct file * file)
  434. {
  435.   irnet_socket * ap = (struct irnet_socket *) file->private_data;
  436.   DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)n",
  437.  (unsigned int) file, (unsigned int) ap);
  438.   DABORT(ap == NULL, 0, FS_ERROR, "ap is NULL !!!n");
  439.   /* Detach ourselves */
  440.   file->private_data = NULL;
  441.   /* Close IrDA stuff */
  442.   irda_irnet_destroy(ap);
  443.   /* Disconnect from the generic PPP layer if not already done */
  444.   if(ap->ppp_open)
  445.     {
  446.       DERROR(FS_ERROR, "Channel still registered - deregistering !n");
  447.       ppp_unregister_channel(&ap->chan);
  448.       ap->ppp_open = 0;
  449.     }
  450.   kfree(ap);
  451.   MOD_DEC_USE_COUNT;
  452.   DEXIT(FS_TRACE, "n");
  453.   return 0;
  454. }
  455. /*------------------------------------------------------------------*/
  456. /*
  457.  * Write does nothing.
  458.  * (we receive packet from ppp_generic through ppp_irnet_send())
  459.  */
  460. static ssize_t
  461. dev_irnet_write(struct file * file,
  462. const char * buf,
  463. size_t count,
  464. loff_t * ppos)
  465. {
  466.   irnet_socket * ap = (struct irnet_socket *) file->private_data;
  467.   DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)n",
  468. (unsigned int) file, (unsigned int) ap, count);
  469.   DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!n");
  470.   /* If we are connected to ppp_generic, let it handle the job */
  471.   if(ap->ppp_open)
  472.     return -EAGAIN;
  473.   else
  474.     return irnet_ctrl_write(ap, buf, count);
  475. }
  476. /*------------------------------------------------------------------*/
  477. /*
  478.  * Read doesn't do much either.
  479.  * (pppd poll us, but ultimately reads through /dev/ppp)
  480.  */
  481. static ssize_t
  482. dev_irnet_read(struct file * file,
  483.        char * buf,
  484.        size_t count,
  485.        loff_t * ppos)
  486. {
  487.   irnet_socket * ap = (struct irnet_socket *) file->private_data;
  488.   DPASS(FS_TRACE, "(file=0x%X, ap=0x%X, count=%d)n",
  489. (unsigned int) file, (unsigned int) ap, count);
  490.   DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!n");
  491.   /* If we are connected to ppp_generic, let it handle the job */
  492.   if(ap->ppp_open)
  493.     return -EAGAIN;
  494.   else
  495.     return irnet_ctrl_read(ap, file, buf, count);
  496. }
  497. /*------------------------------------------------------------------*/
  498. /*
  499.  * Poll : called when someone do a select on /dev/irnet
  500.  */
  501. static unsigned int
  502. dev_irnet_poll(struct file * file,
  503.        poll_table * wait)
  504. {
  505.   irnet_socket * ap = (struct irnet_socket *) file->private_data;
  506.   unsigned int mask;
  507.   DENTER(FS_TRACE, "(file=0x%X, ap=0x%X)n",
  508.  (unsigned int) file, (unsigned int) ap);
  509.   mask = POLLOUT | POLLWRNORM;
  510.   DABORT(ap == NULL, mask, FS_ERROR, "ap is NULL !!!n");
  511.   /* If we are connected to ppp_generic, let it handle the job */
  512.   if(!ap->ppp_open)
  513.     mask |= irnet_ctrl_poll(ap, file, wait);
  514.   DEXIT(FS_TRACE, " - mask=0x%Xn", mask);
  515.   return(mask);
  516. }
  517. /*------------------------------------------------------------------*/
  518. /*
  519.  * IOCtl : Called when someone does some ioctls on /dev/irnet
  520.  * This is the way pppd configure us and control us while the PPP
  521.  * instance is active.
  522.  */
  523. static int
  524. dev_irnet_ioctl(struct inode * inode,
  525. struct file * file,
  526. unsigned int cmd,
  527. unsigned long arg)
  528. {
  529.   irnet_socket * ap = (struct irnet_socket *) file->private_data;
  530.   int err;
  531.   int val;
  532.   DENTER(FS_TRACE, "(file=0x%X, ap=0x%X, cmd=0x%X)n",
  533.  (unsigned int) file, (unsigned int) ap, cmd);
  534.   /* Basic checks... */
  535.   DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...n");
  536. #ifdef SECURE_DEVIRNET
  537.   if(!capable(CAP_NET_ADMIN))
  538.     return -EPERM;
  539. #endif /* SECURE_DEVIRNET */
  540.   err = -EFAULT;
  541.   switch(cmd)
  542.     {
  543.       /* Set discipline (should be N_SYNC_PPP or N_TTY) */
  544.     case TIOCSETD:
  545.       if(get_user(val, (int *) arg))
  546. break;
  547.       if((val == N_SYNC_PPP) || (val == N_PPP))
  548. {
  549.   DEBUG(FS_INFO, "Entering PPP discipline.n");
  550.   /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/
  551.   err = ppp_register_channel(&ap->chan);
  552.   if(err == 0)
  553.     {
  554.       /* Our ppp side is active */
  555.       ap->ppp_open = 1;
  556.       DEBUG(FS_INFO, "Trying to establish a connection.n");
  557.       /* Setup the IrDA link now - may fail... */
  558.       irda_irnet_connect(ap);
  559.     }
  560.   else
  561.     DERROR(FS_ERROR, "Can't setup PPP channel...n");
  562. }
  563.       else
  564. {
  565.   /* In theory, should be N_TTY */
  566.   DEBUG(FS_INFO, "Exiting PPP discipline.n");
  567.   /* Disconnect from the generic PPP layer */
  568.   if(ap->ppp_open)
  569.     ppp_unregister_channel(&ap->chan);
  570.   else
  571.     DERROR(FS_ERROR, "Channel not registered !n");
  572.   ap->ppp_open = 0;
  573.   err = 0;
  574. }
  575.       break;
  576.       /* Query PPP channel and unit number */
  577.     case PPPIOCGCHAN:
  578.       if(!ap->ppp_open)
  579. break;
  580.       if(put_user(ppp_channel_index(&ap->chan), (int *) arg))
  581. break;
  582.       DEBUG(FS_INFO, "Query channel.n");
  583.       err = 0;
  584.       break;
  585.     case PPPIOCGUNIT:
  586.       if(!ap->ppp_open)
  587. break;
  588.       if(put_user(ppp_unit_number(&ap->chan), (int *) arg))
  589. break;
  590.       DEBUG(FS_INFO, "Query unit number.n");
  591.       err = 0;
  592.       break;
  593.       /* All these ioctls can be passed both directly and from ppp_generic,
  594.        * so we just deal with them in one place...
  595.        */
  596.     case PPPIOCGFLAGS:
  597.     case PPPIOCSFLAGS:
  598.     case PPPIOCGASYNCMAP:
  599.     case PPPIOCSASYNCMAP:
  600.     case PPPIOCGRASYNCMAP:
  601.     case PPPIOCSRASYNCMAP:
  602.     case PPPIOCGXASYNCMAP:
  603.     case PPPIOCSXASYNCMAP:
  604.     case PPPIOCGMRU:
  605.     case PPPIOCSMRU:
  606.       DEBUG(FS_INFO, "Standard PPP ioctl.n");
  607.       if(!capable(CAP_NET_ADMIN))
  608. err = -EPERM;
  609.       else
  610. err = ppp_irnet_ioctl(&ap->chan, cmd, arg);
  611.       break;
  612.       /* TTY IOCTLs : Pretend that we are a tty, to keep pppd happy */
  613.       /* Get termios */
  614.     case TCGETS:
  615.       DEBUG(FS_INFO, "Get termios.n");
  616.       if(kernel_termios_to_user_termios((struct termios *)arg, &ap->termios))
  617. break;
  618.       err = 0;
  619.       break;
  620.       /* Set termios */
  621.     case TCSETSF:
  622.       DEBUG(FS_INFO, "Set termios.n");
  623.       if(user_termios_to_kernel_termios(&ap->termios, (struct termios *) arg))
  624. break;
  625.       err = 0;
  626.       break;
  627.       /* Set DTR/RTS */
  628.     case TIOCMBIS: 
  629.     case TIOCMBIC:
  630.       /* Set exclusive/non-exclusive mode */
  631.     case TIOCEXCL:
  632.     case TIOCNXCL:
  633.       DEBUG(FS_INFO, "TTY compatibility.n");
  634.       err = 0;
  635.       break;
  636.     case TCGETA:
  637.       DEBUG(FS_INFO, "TCGETAn");
  638.       break;
  639.     case TCFLSH:
  640.       DEBUG(FS_INFO, "TCFLSHn");
  641.       /* Note : this will flush buffers in PPP, so it *must* be done
  642.        * We should also worry that we don't accept junk here and that
  643.        * we get rid of our own buffers */
  644. #ifdef FLUSH_TO_PPP
  645.       ppp_output_wakeup(&ap->chan);
  646. #endif /* FLUSH_TO_PPP */
  647.       err = 0;
  648.       break;
  649.     case FIONREAD:
  650.       DEBUG(FS_INFO, "FIONREADn");
  651.       val = 0;
  652.       if(put_user(val, (int *) arg))
  653. break;
  654.       err = 0;
  655.       break;
  656.     default:
  657.       DERROR(FS_ERROR, "Unsupported ioctl (0x%X)n", cmd);
  658.       err = -ENOIOCTLCMD;
  659.     }
  660.   DEXIT(FS_TRACE, " - err = 0x%Xn", err);
  661.   return err;
  662. }
  663. /************************** PPP CALLBACKS **************************/
  664. /*
  665.  * This are the functions that the generic PPP driver in the kernel
  666.  * will call to communicate to us.
  667.  */
  668. /*------------------------------------------------------------------*/
  669. /*
  670.  * Prepare the ppp frame for transmission over the IrDA socket.
  671.  * We make sure that the header space is enough, and we change ppp header
  672.  * according to flags passed by pppd.
  673.  * This is not a callback, but just a helper function used in ppp_irnet_send()
  674.  */
  675. static inline struct sk_buff *
  676. irnet_prepare_skb(irnet_socket * ap,
  677.   struct sk_buff * skb)
  678. {
  679.   unsigned char * data;
  680.   int proto; /* PPP protocol */
  681.   int islcp; /* Protocol == LCP */
  682.   int needaddr; /* Need PPP address */
  683.   DENTER(PPP_TRACE, "(ap=0x%X, skb=0x%X)n",
  684.  (unsigned int) ap, (unsigned int) skb);
  685.   /* Extract PPP protocol from the frame */
  686.   data  = skb->data;
  687.   proto = (data[0] << 8) + data[1];
  688.   /* LCP packets with codes between 1 (configure-request)
  689.    * and 7 (code-reject) must be sent as though no options
  690.    * have been negotiated. */
  691.   islcp = (proto == PPP_LCP) && (1 <= data[2]) && (data[2] <= 7);
  692.   /* compress protocol field if option enabled */
  693.   if((data[0] == 0) && (ap->flags & SC_COMP_PROT) && (!islcp))
  694.     skb_pull(skb,1);
  695.   /* Check if we need address/control fields */
  696.   needaddr = 2*((ap->flags & SC_COMP_AC) == 0 || islcp);
  697.   /* Is the skb headroom large enough to contain all IrDA-headers? */
  698.   if((skb_headroom(skb) < (ap->max_header_size + needaddr)) ||
  699.       (skb_shared(skb)))
  700.     {
  701.       struct sk_buff * new_skb;
  702.       DEBUG(PPP_INFO, "Reallocating skbn");
  703.       /* Create a new skb */
  704.       new_skb = skb_realloc_headroom(skb, ap->max_header_size + needaddr);
  705.       /* We have to free the original skb anyway */
  706.       dev_kfree_skb(skb);
  707.       /* Did the realloc succeed ? */
  708.       DABORT(new_skb == NULL, NULL, PPP_ERROR, "Could not realloc skbn");
  709.       /* Use the new skb instead */
  710.       skb = new_skb;
  711.     }
  712.   /* prepend address/control fields if necessary */
  713.   if(needaddr)
  714.     {
  715.       skb_push(skb, 2);
  716.       skb->data[0] = PPP_ALLSTATIONS;
  717.       skb->data[1] = PPP_UI;
  718.     }
  719.   DEXIT(PPP_TRACE, "n");
  720.   return skb;
  721. }
  722. /*------------------------------------------------------------------*/
  723. /*
  724.  * Send a packet to the peer over the IrTTP connection.
  725.  * Returns 1 iff the packet was accepted.
  726.  * Returns 0 iff packet was not consumed.
  727.  * If the packet was not accepted, we will call ppp_output_wakeup
  728.  * at some later time to reactivate flow control in ppp_generic.
  729.  */
  730. static int
  731. ppp_irnet_send(struct ppp_channel * chan,
  732.        struct sk_buff * skb)
  733. {
  734.   irnet_socket * self = (struct irnet_socket *) chan->private;
  735.   int ret;
  736.   DENTER(PPP_TRACE, "(channel=0x%X, ap/self=0x%X)n",
  737.  (unsigned int) chan, (unsigned int) self);
  738.   /* Check if things are somewhat valid... */
  739.   DASSERT(self != NULL, 0, PPP_ERROR, "Self is NULL !!!n");
  740.   /* Check if we are connected */
  741.   if(!(test_bit(0, &self->ttp_open)))
  742.     {
  743. #ifdef CONNECT_IN_SEND
  744.       /* Let's try to connect one more time... */
  745.       /* Note : we won't be connected after this call, but we should be
  746.        * ready for next packet... */
  747.       /* If we are already connecting, this will fail */
  748.       irda_irnet_connect(self);
  749. #endif /* CONNECT_IN_SEND */
  750.       DEBUG(PPP_INFO, "IrTTP not ready ! (%d-%d)n",
  751.     self->ttp_open, self->ttp_connect);
  752.       /* Note : we can either drop the packet or block the packet.
  753.        *
  754.        * Blocking the packet allow us a better connection time,
  755.        * because by calling ppp_output_wakeup() we can have
  756.        * ppp_generic resending the LCP request immediately to us,
  757.        * rather than waiting for one of pppd periodic transmission of
  758.        * LCP request.
  759.        *
  760.        * On the other hand, if we block all packet, all those periodic
  761.        * transmissions of pppd accumulate in ppp_generic, creating a
  762.        * backlog of LCP request. When we eventually connect later on,
  763.        * we have to transmit all this backlog before we can connect
  764.        * proper (if we don't timeout before).
  765.        *
  766.        * The current strategy is as follow :
  767.        * While we are attempting to connect, we block packets to get
  768.        * a better connection time.
  769.        * If we fail to connect, we drain the queue and start dropping packets
  770.        */
  771. #ifdef BLOCK_WHEN_CONNECT
  772.       /* If we are attempting to connect */
  773.       if(test_bit(0, &self->ttp_connect))
  774. {
  775.   /* Blocking packet, ppp_generic will retry later */
  776.   return 0;
  777. }
  778. #endif /* BLOCK_WHEN_CONNECT */
  779.       /* Dropping packet, pppd will retry later */
  780.       dev_kfree_skb(skb);
  781.       return 1;
  782.     }
  783.   /* Check if the queue can accept any packet, otherwise block */
  784.   if(self->tx_flow != FLOW_START)
  785.     DRETURN(0, PPP_INFO, "IrTTP queue full (%d skbs)...n",
  786.     skb_queue_len(&self->tsap->tx_queue));
  787.   /* Prepare ppp frame for transmission */
  788.   skb = irnet_prepare_skb(self, skb);
  789.   DABORT(skb == NULL, 1, PPP_ERROR, "Prepare skb for Tx failed.n");
  790.   /* Send the packet to IrTTP */
  791.   ret = irttp_data_request(self->tsap, skb);
  792.   if(ret < 0)
  793.     {
  794.       /*   
  795.        * > IrTTPs tx queue is full, so we just have to
  796.        * > drop the frame! You might think that we should
  797.        * > just return -1 and don't deallocate the frame,
  798.        * > but that is dangerous since it's possible that
  799.        * > we have replaced the original skb with a new
  800.        * > one with larger headroom, and that would really
  801.        * > confuse do_dev_queue_xmit() in dev.c! I have
  802.        * > tried :-) DB 
  803.        * Correction : we verify the flow control above (self->tx_flow),
  804.        * so we come here only if IrTTP doesn't like the packet (empty,
  805.        * too large, IrTTP not connected). In those rare cases, it's ok
  806.        * to drop it, we don't want to see it here again...
  807.        * Jean II
  808.        */
  809.       DERROR(PPP_ERROR, "IrTTP doesn't like this packet !!! (0x%X)n", ret);
  810.       dev_kfree_skb(skb);
  811.     }
  812.   DEXIT(PPP_TRACE, "n");
  813.   return 1; /* Packet has been consumed */
  814. }
  815. /*------------------------------------------------------------------*/
  816. /*
  817.  * Take care of the ioctls that ppp_generic doesn't want to deal with...
  818.  * Note : we are also called from dev_irnet_ioctl().
  819.  */
  820. static int
  821. ppp_irnet_ioctl(struct ppp_channel * chan,
  822. unsigned int cmd,
  823. unsigned long arg)
  824. {
  825.   irnet_socket * ap = (struct irnet_socket *) chan->private;
  826.   int err;
  827.   int val;
  828.   u32 accm[8];
  829.   DENTER(PPP_TRACE, "(channel=0x%X, ap=0x%X, cmd=0x%X)n",
  830.  (unsigned int) chan, (unsigned int) ap, cmd);
  831.   /* Basic checks... */
  832.   DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...n");
  833.   err = -EFAULT;
  834.   switch(cmd)
  835.     {
  836.       /* PPP flags */
  837.     case PPPIOCGFLAGS:
  838.       val = ap->flags | ap->rbits;
  839.       if(put_user(val, (int *) arg))
  840. break;
  841.       err = 0;
  842.       break;
  843.     case PPPIOCSFLAGS:
  844.       if(get_user(val, (int *) arg))
  845. break;
  846.       ap->flags = val & ~SC_RCV_BITS;
  847.       ap->rbits = val & SC_RCV_BITS;
  848.       err = 0;
  849.       break;
  850.       /* Async map stuff - all dummy to please pppd */
  851.     case PPPIOCGASYNCMAP:
  852.       if(put_user(ap->xaccm[0], (u32 *) arg))
  853. break;
  854.       err = 0;
  855.       break;
  856.     case PPPIOCSASYNCMAP:
  857.       if(get_user(ap->xaccm[0], (u32 *) arg))
  858. break;
  859.       err = 0;
  860.       break;
  861.     case PPPIOCGRASYNCMAP:
  862.       if(put_user(ap->raccm, (u32 *) arg))
  863. break;
  864.       err = 0;
  865.       break;
  866.     case PPPIOCSRASYNCMAP:
  867.       if(get_user(ap->raccm, (u32 *) arg))
  868. break;
  869.       err = 0;
  870.       break;
  871.     case PPPIOCGXASYNCMAP:
  872.       if(copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm)))
  873. break;
  874.       err = 0;
  875.       break;
  876.     case PPPIOCSXASYNCMAP:
  877.       if(copy_from_user(accm, (void *) arg, sizeof(accm)))
  878. break;
  879.       accm[2] &= ~0x40000000U; /* can't escape 0x5e */
  880.       accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */
  881.       memcpy(ap->xaccm, accm, sizeof(ap->xaccm));
  882.       err = 0;
  883.       break;
  884.       /* Max PPP frame size */
  885.     case PPPIOCGMRU:
  886.       if(put_user(ap->mru, (int *) arg))
  887. break;
  888.       err = 0;
  889.       break;
  890.     case PPPIOCSMRU:
  891.       if(get_user(val, (int *) arg))
  892. break;
  893.       if(val < PPP_MRU)
  894. val = PPP_MRU;
  895.       ap->mru = val;
  896.       err = 0;
  897.       break;
  898.     default:
  899.       DEBUG(PPP_INFO, "Unsupported ioctl (0x%X)n", cmd);
  900.       err = -ENOIOCTLCMD;
  901.     }
  902.   DEXIT(PPP_TRACE, " - err = 0x%Xn", err);
  903.   return err;
  904. }
  905. /************************** INITIALISATION **************************/
  906. /*
  907.  * Module initialisation and all that jazz...
  908.  */
  909. /*------------------------------------------------------------------*/
  910. /*
  911.  * Hook our device callbacks in the filesystem, to connect our code
  912.  * to /dev/irnet
  913.  */
  914. int
  915. ppp_irnet_init(void)
  916. {
  917.   int err = 0;
  918.   DENTER(MODULE_TRACE, "()n");
  919.   /* Allocate ourselves as a minor in the misc range */
  920.   err = misc_register(&irnet_misc_device);
  921.   DEXIT(MODULE_TRACE, "n");
  922.   return err;
  923. }
  924. /*------------------------------------------------------------------*/
  925. /*
  926.  * Cleanup at exit...
  927.  */
  928. void
  929. ppp_irnet_cleanup(void)
  930. {
  931.   DENTER(MODULE_TRACE, "()n");
  932.   /* De-allocate /dev/irnet minor in misc range */
  933.   misc_deregister(&irnet_misc_device);
  934.   DEXIT(MODULE_TRACE, "n");
  935. }
  936. #ifdef MODULE
  937. /*------------------------------------------------------------------*/
  938. /*
  939.  * Module main entry point
  940.  */
  941. int
  942. init_module(void)
  943. {
  944.   int err;
  945.   /* Initialise both parts... */
  946.   err = irda_irnet_init();
  947.   if(!err)
  948.     err = ppp_irnet_init();
  949.   return err;
  950. }
  951. /*------------------------------------------------------------------*/
  952. /*
  953.  * Module exit
  954.  */
  955. void
  956. cleanup_module(void)
  957. {
  958.   irda_irnet_cleanup();
  959.   return ppp_irnet_cleanup();
  960. }
  961. #endif /* MODULE */
  962. MODULE_LICENSE("GPL");