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