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