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