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