1 /* 2 * User Process PPP 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * $Id: main.c,v 1.10 1995/09/18 12:41:52 bde Exp $ 21 * 22 * TODO: 23 * o Add commands for traffic summary, version display, etc. 24 * o Add signal handler for misc controls. 25 */ 26 #include "fsm.h" 27 #include <fcntl.h> 28 #include <paths.h> 29 #include <sys/time.h> 30 #include <termios.h> 31 #include <signal.h> 32 #include <sys/wait.h> 33 #include <errno.h> 34 #include <netdb.h> 35 #include <sys/socket.h> 36 #include <arpa/inet.h> 37 #include "modem.h" 38 #include "os.h" 39 #include "hdlc.h" 40 #include "lcp.h" 41 #include "ipcp.h" 42 #include "vars.h" 43 #include "auth.h" 44 #include "filter.h" 45 46 #define LAUTH_M1 "Warning: No password entry for this host in ppp.secret\n" 47 #define LAUTH_M2 "Warning: All manipulation is allowed by anyone in the world\n" 48 49 #ifndef O_NONBLOCK 50 #ifdef O_NDELAY 51 #define O_NONBLOCK O_NDELAY 52 #endif 53 #endif 54 55 extern void VjInit(), AsyncInit(); 56 extern void AsyncInput(), IpOutput(); 57 extern int SelectSystem(); 58 59 extern void DecodeCommand(), Prompt(); 60 extern int IsInteractive(); 61 extern struct in_addr ifnetmask; 62 static void DoLoop(void); 63 static void TerminalStop(); 64 65 static struct termios oldtio; /* Original tty mode */ 66 static struct termios comtio; /* Command level tty mode */ 67 static int TermMode; 68 static int server, update; 69 struct sockaddr_in ifsin; 70 char pid_filename[128]; 71 72 static void 73 TtyInit() 74 { 75 struct termios newtio; 76 int stat; 77 78 stat = fcntl(0, F_GETFL, 0); 79 stat |= O_NONBLOCK; 80 fcntl(0, F_SETFL, stat); 81 newtio = oldtio; 82 newtio.c_lflag &= ~(ECHO|ISIG|ICANON); 83 newtio.c_iflag = 0; 84 newtio.c_oflag &= ~OPOST; 85 newtio.c_cc[VEOF] = _POSIX_VDISABLE; 86 newtio.c_cc[VINTR] = _POSIX_VDISABLE; 87 newtio.c_cc[VMIN] = 1; 88 newtio.c_cc[VTIME] = 0; 89 newtio.c_cflag |= CS8; 90 tcsetattr(0, TCSADRAIN, &newtio); 91 comtio = newtio; 92 } 93 94 /* 95 * Set tty into command mode. We allow canonical input and echo processing. 96 */ 97 void 98 TtyCommandMode(prompt) 99 int prompt; 100 { 101 struct termios newtio; 102 int stat; 103 104 if (!(mode & MODE_INTER)) 105 return; 106 tcgetattr(0, &newtio); 107 newtio.c_lflag |= (ECHO|ISIG|ICANON); 108 newtio.c_iflag = oldtio.c_iflag; 109 newtio.c_oflag |= OPOST; 110 tcsetattr(0, TCSADRAIN, &newtio); 111 stat = fcntl(0, F_GETFL, 0); 112 stat |= O_NONBLOCK; 113 fcntl(0, F_SETFL, stat); 114 TermMode = 0; 115 if(prompt) Prompt(0); 116 } 117 118 /* 119 * Set tty into terminal mode which is used while we invoke term command. 120 */ 121 void 122 TtyTermMode() 123 { 124 int stat; 125 126 tcsetattr(0, TCSADRAIN, &comtio); 127 stat = fcntl(0, F_GETFL, 0); 128 stat &= ~O_NONBLOCK; 129 fcntl(0, F_SETFL, stat); 130 TermMode = 1; 131 } 132 133 void 134 TtyOldMode() 135 { 136 int stat; 137 138 stat = fcntl(0, F_GETFL, 0); 139 stat &= ~O_NONBLOCK; 140 fcntl(0, F_SETFL, stat); 141 tcsetattr(0, TCSANOW, &oldtio); 142 } 143 144 void 145 Cleanup(excode) 146 int excode; 147 { 148 int stat; 149 150 OsLinkdown(); 151 OsCloseLink(1); 152 sleep(1); 153 if (mode & MODE_AUTO) { 154 DeleteIfRoutes(1); 155 unlink(pid_filename); 156 } 157 OsInterfaceDown(1); 158 LogPrintf(LOG_PHASE, "PPP Terminated.\n"); 159 LogClose(); 160 if (server > 0) 161 close(server); 162 TtyOldMode(); 163 164 exit(excode); 165 } 166 167 static void 168 Hangup() 169 { 170 LogPrintf(LOG_PHASE, "SIGHUP\n"); 171 Cleanup(EX_HANGUP); 172 } 173 174 static void 175 CloseSession() 176 { 177 LogPrintf(LOG_PHASE, "SIGTERM\n"); 178 LcpClose(); 179 Cleanup(EX_TERM); 180 } 181 182 183 static void 184 TerminalCont() 185 { 186 (void)signal(SIGCONT, SIG_DFL); 187 (void)signal(SIGTSTP, TerminalStop); 188 TtyCommandMode(getpgrp() == tcgetpgrp(0)); 189 } 190 191 static void 192 TerminalStop(signo) 193 int signo; 194 { 195 (void)signal(SIGCONT, TerminalCont); 196 TtyOldMode(); 197 signal(SIGTSTP, SIG_DFL); 198 kill(getpid(), signo); 199 } 200 201 202 void 203 Usage() 204 { 205 fprintf(stderr, "Usage: ppp [-auto | -direct | -dedicated] [system]\n"); 206 exit(EX_START); 207 } 208 209 void 210 ProcessArgs(int argc, char **argv) 211 { 212 int optc; 213 char *cp; 214 215 optc = 0; 216 while (argc > 0 && **argv == '-') { 217 cp = *argv + 1; 218 if (strcmp(cp, "auto") == 0) 219 mode |= MODE_AUTO; 220 else if (strcmp(cp, "direct") == 0) 221 mode |= MODE_DIRECT; 222 else if (strcmp(cp, "dedicated") == 0) 223 mode |= MODE_DEDICATED; 224 else 225 Usage(); 226 optc++; 227 argv++; argc--; 228 } 229 if (argc > 1) { 230 fprintf(stderr, "specify only one system label.\n"); 231 exit(EX_START); 232 } 233 if (argc == 1) dstsystem = *argv; 234 235 if (optc > 1) { 236 fprintf(stderr, "specify only one mode.\n"); 237 exit(EX_START); 238 } 239 } 240 241 static void 242 Greetings() 243 { 244 printf("User Process PPP. Written by Toshiharu OHNO.\r\n"); 245 fflush(stdout); 246 } 247 248 void 249 main(argc, argv) 250 int argc; 251 char **argv; 252 { 253 int tunno; 254 int on = 1; 255 256 argc--; argv++; 257 258 mode = MODE_INTER; /* default operation is interactive mode */ 259 netfd = -1; 260 ProcessArgs(argc, argv); 261 Greetings(); 262 GetUid(); 263 IpcpDefAddress(); 264 265 if (SelectSystem("default", CONFFILE) < 0) { 266 fprintf(stderr, "Warning: No default entry is given in config file.\n"); 267 } 268 269 if (LogOpen()) 270 exit(EX_START); 271 272 switch ( LocalAuthInit() ) { 273 case NOT_FOUND: 274 fprintf(stderr,LAUTH_M1); 275 fprintf(stderr,LAUTH_M2); 276 fflush (stderr); 277 /* Fall down */ 278 case VALID: 279 VarLocalAuth = LOCAL_AUTH; 280 break; 281 default: 282 break; 283 } 284 285 if (OpenTunnel(&tunno) < 0) { 286 perror("open_tun"); 287 exit(EX_START); 288 } 289 290 if (mode & (MODE_AUTO|MODE_DIRECT|MODE_DEDICATED)) 291 mode &= ~MODE_INTER; 292 if (mode & MODE_INTER) { 293 printf("Interactive mode\n"); 294 netfd = 0; 295 } else if (mode & MODE_AUTO) { 296 printf("Automatic mode\n"); 297 if (dstsystem == NULL) { 298 fprintf(stderr, "Destination system must be specified in auto mode.\n"); 299 exit(EX_START); 300 } 301 } 302 303 tcgetattr(0, &oldtio); /* Save original tty mode */ 304 305 signal(SIGHUP, Hangup); 306 signal(SIGTERM, CloseSession); 307 signal(SIGINT, CloseSession); 308 signal(SIGQUIT, CloseSession); 309 #ifdef SIGSEGV 310 signal(SIGSEGV, Hangup); 311 #endif 312 #ifdef SIGPIPE 313 signal(SIGPIPE, Hangup); 314 #endif 315 #ifdef SIGALRM 316 signal(SIGALRM, SIG_IGN); 317 #endif 318 if(mode & MODE_INTER) 319 { 320 #ifdef SIGTSTP 321 signal(SIGTSTP, TerminalStop); 322 #endif 323 #ifdef SIGTTIN 324 signal(SIGTTIN, TerminalStop); 325 #endif 326 #ifdef SIGTTOU 327 signal(SIGTTOU, SIG_IGN); 328 #endif 329 } 330 331 if (dstsystem) { 332 if (SelectSystem(dstsystem, CONFFILE) < 0) { 333 fprintf(stderr, "Destination system not found in conf file.\n"); 334 Cleanup(EX_START); 335 } 336 if ((mode & MODE_AUTO) && DefHisAddress.ipaddr.s_addr == INADDR_ANY) { 337 fprintf(stderr, "Must specify dstaddr with auto mode.\n"); 338 Cleanup(EX_START); 339 } 340 } 341 if (mode & MODE_DIRECT) 342 printf("Packet mode enabled.\n"); 343 344 #ifdef notdef 345 if (mode & MODE_AUTO) { 346 OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask); 347 } 348 #endif 349 350 if (!(mode & MODE_INTER)) { 351 int port = SERVER_PORT + tunno; 352 /* 353 * Create server socket and listen at there. 354 */ 355 server = socket(PF_INET, SOCK_STREAM, 0); 356 if (server < 0) { 357 perror("socket"); 358 Cleanup(EX_SOCK); 359 } 360 ifsin.sin_family = AF_INET; 361 ifsin.sin_addr.s_addr = INADDR_ANY; 362 ifsin.sin_port = htons(port); 363 if (bind(server, (struct sockaddr *) &ifsin, sizeof(ifsin)) < 0) { 364 perror("bind"); 365 if (errno == EADDRINUSE) 366 fprintf(stderr, "Wait for a while, then try again.\n"); 367 Cleanup(EX_SOCK); 368 } 369 listen(server, 5); 370 371 DupLog(); 372 if (!(mode & MODE_DIRECT)) { 373 int fd; 374 char pid[32]; 375 376 if (fork()) 377 exit(0); 378 379 snprintf(pid_filename, sizeof (pid_filename), "%s/PPP.%s", 380 _PATH_VARRUN, dstsystem); 381 unlink(pid_filename); 382 sprintf(pid, "%d\n", getpid()); 383 384 if ((fd = open(pid_filename, O_RDWR|O_CREAT, 0666)) != -1) 385 { 386 write(fd, pid, strlen(pid)); 387 close(fd); 388 } 389 } 390 LogPrintf(LOG_PHASE, "Listening at %d.\n", port); 391 #ifdef DOTTYINIT 392 if (mode & (MODE_DIRECT|MODE_DEDICATED)) { /* } */ 393 #else 394 if (mode & MODE_DIRECT) { 395 #endif 396 TtyInit(); 397 } else { 398 setsid(); /* detach control tty */ 399 } 400 } else { 401 server = -1; 402 TtyInit(); 403 TtyCommandMode(1); 404 } 405 LogPrintf(LOG_PHASE, "PPP Started.\n"); 406 407 408 do 409 DoLoop(); 410 while (mode & MODE_DEDICATED); 411 412 Cleanup(EX_DONE); 413 } 414 415 /* 416 * Turn into packet mode, where we speek PPP. 417 */ 418 void 419 PacketMode() 420 { 421 if (RawModem(modem) < 0) { 422 fprintf(stderr, "Not connected.\r\n"); 423 return; 424 } 425 426 AsyncInit(); 427 VjInit(); 428 LcpInit(); 429 IpcpInit(); 430 CcpInit(); 431 LcpUp(); 432 433 if (mode & (MODE_DIRECT|MODE_DEDICATED)) 434 LcpOpen(OPEN_ACTIVE); 435 else 436 LcpOpen(VarOpenMode); 437 if ((mode & (MODE_INTER|MODE_AUTO)) == MODE_INTER) { 438 TtyCommandMode(1); 439 fprintf(stderr, "Packet mode.\r\n"); 440 } 441 } 442 443 static void 444 ShowHelp() 445 { 446 fprintf(stderr, "The following commands are available:\r\n"); 447 fprintf(stderr, " ~p\tEnter to Packet mode\r\n"); 448 fprintf(stderr, " ~.\tTerminate program\r\n"); 449 } 450 451 static void 452 ReadTty() 453 { 454 int n; 455 char ch; 456 static int ttystate; 457 #define MAXLINESIZE 200 458 char linebuff[MAXLINESIZE]; 459 460 #ifdef DEBUG 461 logprintf("termode = %d, netfd = %d, mode = %d\n", TermMode, netfd, mode); 462 #endif 463 if (!TermMode) { 464 n = read(netfd, linebuff, sizeof(linebuff)-1); 465 if (n > 0) { 466 DecodeCommand(linebuff, n, 1); 467 } else { 468 #ifdef DEBUG 469 logprintf("connection closed.\n"); 470 #endif 471 close(netfd); 472 netfd = -1; 473 mode &= ~MODE_INTER; 474 } 475 return; 476 } 477 478 /* 479 * We are in terminal mode, decode special sequences 480 */ 481 n = read(0, &ch, 1); 482 #ifdef DEBUG 483 logprintf("got %d bytes\n", n); 484 #endif 485 486 if (n > 0) { 487 switch (ttystate) { 488 case 0: 489 if (ch == '~') 490 ttystate++; 491 else 492 write(modem, &ch, n); 493 break; 494 case 1: 495 switch (ch) { 496 case '?': 497 ShowHelp(); 498 break; 499 case '-': 500 if (loglevel > 0) { 501 loglevel--; 502 fprintf(stderr, "New loglevel is %d\r\n", loglevel); 503 } 504 break; 505 case '+': 506 loglevel++; 507 fprintf(stderr, "New loglevel is %d\r\n", loglevel); 508 break; 509 #ifdef DEBUG 510 case 'm': 511 ShowMemMap(); 512 break; 513 #endif 514 case 'p': 515 /* 516 * XXX: Should check carrier. 517 */ 518 if (LcpFsm.state <= ST_CLOSED) { 519 VarOpenMode = OPEN_ACTIVE; 520 PacketMode(); 521 } 522 break; 523 #ifdef DEBUG 524 case 't': 525 ShowTimers(); 526 break; 527 #endif 528 case '.': 529 TermMode = 1; 530 TtyCommandMode(1); 531 break; 532 default: 533 if (write(modem, &ch, n) < 0) 534 fprintf(stderr, "err in write.\r\n"); 535 break; 536 } 537 ttystate = 0; 538 break; 539 } 540 } 541 } 542 543 544 /* 545 * Here, we'll try to detect HDLC frame 546 */ 547 548 static char *FrameHeaders[] = { 549 "\176\377\003\300\041", 550 "\176\377\175\043\300\041", 551 "\176\177\175\043\100\041", 552 "\176\175\337\175\043\300\041", 553 "\176\175\137\175\043\100\041", 554 NULL, 555 }; 556 557 u_char * 558 HdlcDetect(cp, n) 559 u_char *cp; 560 int n; 561 { 562 char *ptr, *fp, **hp; 563 564 cp[n] = '\0'; /* be sure to null terminated */ 565 ptr = NULL; 566 for (hp = FrameHeaders; *hp; hp++) { 567 fp = *hp; 568 if (DEV_IS_SYNC) 569 fp++; 570 if (ptr = strstr((char *)cp, fp)) 571 break; 572 } 573 return((u_char *)ptr); 574 } 575 576 static struct pppTimer RedialTimer; 577 578 static void 579 RedialTimeout() 580 { 581 StopTimer(&RedialTimer); 582 LogPrintf(LOG_PHASE, "Redialing timer expired.\n"); 583 } 584 585 static void 586 StartRedialTimer() 587 { 588 StopTimer(&RedialTimer); 589 590 if (VarRedialTimeout) { 591 LogPrintf(LOG_PHASE, "Enter pause for redialing.\n"); 592 RedialTimer.state = TIMER_STOPPED; 593 594 if (VarRedialTimeout > 0) 595 RedialTimer.load = VarRedialTimeout * SECTICKS; 596 else 597 RedialTimer.load = (random() % REDIAL_PERIOD) * SECTICKS; 598 599 RedialTimer.func = RedialTimeout; 600 StartTimer(&RedialTimer); 601 } 602 } 603 604 605 static void 606 DoLoop() 607 { 608 fd_set rfds, wfds, efds; 609 int pri, i, n, wfd; 610 struct sockaddr_in hisaddr; 611 struct timeval timeout, *tp; 612 int ssize = sizeof(hisaddr); 613 u_char *cp; 614 u_char rbuff[MAX_MRU]; 615 int dial_up; 616 int tries; 617 int qlen; 618 pid_t pgroup; 619 620 pgroup = getpgrp(); 621 622 if (mode & MODE_DIRECT) { 623 modem = OpenModem(mode); 624 LogPrintf(LOG_PHASE, "Packet mode enabled\n"); 625 PacketMode(); 626 } else if (mode & MODE_DEDICATED) { 627 if (!modem) 628 modem = OpenModem(mode); 629 } 630 631 fflush(stdout); 632 633 timeout.tv_sec = 0; 634 timeout.tv_usec = 0; 635 636 dial_up = FALSE; /* XXXX */ 637 tries = 0; 638 for (;;) { 639 if ( modem ) 640 IpStartOutput(); 641 FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); 642 643 /* 644 * If Ip packet for output is enqueued and require dial up, 645 * Just do it! 646 */ 647 if ( dial_up && RedialTimer.state != TIMER_RUNNING ) { /* XXX */ 648 #ifdef DEBUG 649 logprintf("going to dial: modem = %d\n", modem); 650 #endif 651 modem = OpenModem(mode); 652 if (modem < 0) { 653 modem = 0; /* Set intial value for next OpenModem */ 654 StartRedialTimer(); 655 } else { 656 tries++; 657 LogPrintf(LOG_CHAT, "Dial attempt %u\n", tries); 658 if (DialModem()) { 659 sleep(1); /* little pause to allow peer starts */ 660 ModemTimeout(); 661 PacketMode(); 662 dial_up = FALSE; 663 tries = 0; 664 } else { 665 CloseModem(); 666 /* Dial failed. Keep quite during redial wait period. */ 667 StartRedialTimer(); 668 669 if (VarDialTries && tries >= VarDialTries) { 670 dial_up = FALSE; 671 tries = 0; 672 } 673 } 674 } 675 } 676 qlen = ModemQlen(); 677 if (modem) { 678 FD_SET(modem, &rfds); 679 FD_SET(modem, &efds); 680 if (qlen > 0) { 681 FD_SET(modem, &wfds); 682 } 683 } 684 if (server > 0) FD_SET(server, &rfds); 685 686 /* *** IMPORTANT *** 687 * 688 * CPU is serviced every TICKUNIT micro seconds. 689 * This value must be chosen with great care. If this values is 690 * too big, it results loss of characters from modem and poor responce. 691 * If this values is too small, ppp process eats many CPU time. 692 */ 693 #ifndef SIGALRM 694 usleep(TICKUNIT); 695 TimerService(); 696 #endif 697 698 /* If there are aren't many packets queued, look for some more. */ 699 if (qlen < 20) 700 FD_SET(tun_in, &rfds); 701 702 if (netfd > -1) { 703 FD_SET(netfd, &rfds); 704 FD_SET(netfd, &efds); 705 } 706 707 #ifndef SIGALRM 708 /* 709 * Normally, select() will not block because modem is writable. 710 * In AUTO mode, select will block until we find packet from tun 711 */ 712 tp = (RedialTimer.state == TIMER_RUNNING)? &timeout : NULL; 713 i = select(tun_in+10, &rfds, &wfds, &efds, tp); 714 #else 715 /* 716 * When SIGALRM timer is running, a select function will be 717 * return -1 and EINTR after a Time Service signal hundler 718 * is done. If the redial timer is not running and we are 719 * trying to dial, poll with a 0 value timer. 720 */ 721 tp = (dial_up && RedialTimer.state != TIMER_RUNNING) ? &timeout : NULL; 722 i = select(tun_in+10, &rfds, &wfds, &efds, tp); 723 #endif 724 if ( i == 0 ) { 725 continue; 726 } 727 728 if ( i < 0 ) { 729 if ( errno == EINTR ) { 730 continue; /* Got SIGALRM, Do check a queue for dialing */ 731 } 732 perror("select"); 733 break; 734 } 735 736 if ((netfd > 0 && FD_ISSET(netfd, &efds)) || FD_ISSET(modem, &efds)) { 737 logprintf("Exception detected.\n"); 738 break; 739 } 740 741 if (server > 0 && FD_ISSET(server, &rfds)) { 742 #ifdef DEBUG 743 logprintf("connected to client.\n"); 744 #endif 745 wfd = accept(server, (struct sockaddr *)&hisaddr, &ssize); 746 if (netfd > 0) { 747 write(wfd, "already in use.\n", 16); 748 close(wfd); 749 continue; 750 } else 751 netfd = wfd; 752 if (dup2(netfd, 1) < 0) 753 perror("dup2"); 754 mode |= MODE_INTER; 755 Greetings(); 756 switch ( LocalAuthInit() ) { 757 case NOT_FOUND: 758 fprintf(stdout,LAUTH_M1); 759 fprintf(stdout,LAUTH_M2); 760 fflush(stdout); 761 /* Fall down */ 762 case VALID: 763 VarLocalAuth = LOCAL_AUTH; 764 break; 765 default: 766 break; 767 } 768 (void) IsInteractive(); 769 Prompt(0); 770 } 771 772 if ((mode & MODE_INTER) && FD_ISSET(netfd, &rfds) && 773 ((mode & MODE_AUTO) || pgroup == tcgetpgrp(0))) { 774 /* something to read from tty */ 775 ReadTty(); 776 } 777 if (modem) { 778 if (FD_ISSET(modem, &wfds)) { /* ready to write into modem */ 779 ModemStartOutput(modem); 780 } 781 if (FD_ISSET(modem, &rfds)) { /* something to read from modem */ 782 if (LcpFsm.state <= ST_CLOSED) 783 usleep(10000); 784 n = read(modem, rbuff, sizeof(rbuff)); 785 if ((mode & MODE_DIRECT) && n <= 0) { 786 DownConnection(); 787 } else 788 LogDumpBuff(LOG_ASYNC, "ReadFromModem", rbuff, n); 789 790 if (LcpFsm.state <= ST_CLOSED) { 791 /* 792 * In dedicated mode, we just discard input until LCP is started. 793 */ 794 if (!(mode & MODE_DEDICATED)) { 795 cp = HdlcDetect(rbuff, n); 796 if (cp) { 797 /* 798 * LCP packet is detected. Turn ourselves into packet mode. 799 */ 800 if (cp != rbuff) { 801 write(1, rbuff, cp - rbuff); 802 write(1, "\r\n", 2); 803 } 804 PacketMode(); 805 #ifdef notdef 806 AsyncInput(cp, n - (cp - rbuff)); 807 #endif 808 } else 809 write(1, rbuff, n); 810 } 811 } else { 812 if (n > 0) 813 AsyncInput(rbuff, n); 814 #ifdef notdef 815 continue; /* THIS LINE RESULT AS POOR PERFORMANCE */ 816 #endif 817 } 818 } 819 } 820 821 if (FD_ISSET(tun_in, &rfds)) { /* something to read from tun */ 822 n = read(tun_in, rbuff, sizeof(rbuff)); 823 if (n < 0) { 824 perror("read from tun"); 825 continue; 826 } 827 /* 828 * Process on-demand dialup. Output packets are queued within tunnel 829 * device until IPCP is opened. 830 */ 831 if (LcpFsm.state <= ST_CLOSED && (mode & MODE_AUTO)) { 832 pri = PacketCheck(rbuff, n, FL_DIAL); 833 if (pri >= 0) { 834 IpEnqueue(pri, rbuff, n); 835 dial_up = TRUE; /* XXX */ 836 } 837 continue; 838 } 839 pri = PacketCheck(rbuff, n, FL_OUT); 840 if (pri >= 0) 841 IpEnqueue(pri, rbuff, n); 842 } 843 } 844 logprintf("job done.\n"); 845 } 846