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