main.c revision 31582
16059Samurai/* 26059Samurai * User Process PPP 36059Samurai * 46059Samurai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 56059Samurai * 66059Samurai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 76059Samurai * 86059Samurai * Redistribution and use in source and binary forms are permitted 96059Samurai * provided that the above copyright notice and this paragraph are 106059Samurai * duplicated in all such forms and that any documentation, 116059Samurai * advertising materials, and other materials related to such 126059Samurai * distribution and use acknowledge that the software was developed 136059Samurai * by the Internet Initiative Japan, Inc. The name of the 146059Samurai * IIJ may not be used to endorse or promote products derived 156059Samurai * from this software without specific prior written permission. 166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 196059Samurai * 2031514Sbrian * $Id: main.c,v 1.105 1997/11/22 03:37:39 brian Exp $ 218857Srgrimes * 226059Samurai * TODO: 236059Samurai * o Add commands for traffic summary, version display, etc. 246059Samurai * o Add signal handler for misc controls. 256059Samurai */ 2630715Sbrian#include <sys/param.h> 2731195Sbrian#include <sys/time.h> 2831195Sbrian#include <sys/select.h> 2930715Sbrian#include <sys/socket.h> 3030715Sbrian#include <netinet/in.h> 3130715Sbrian#include <netinet/in_systm.h> 3230715Sbrian#include <netinet/ip.h> 3330715Sbrian#include <arpa/inet.h> 3430715Sbrian#include <netdb.h> 3531195Sbrian#include <net/if.h> 3631343Sbrian#ifdef __FreeBSD__ 3731195Sbrian#include <net/if_var.h> 3831343Sbrian#endif 3931195Sbrian#include <net/if_tun.h> 4030715Sbrian 4130715Sbrian#include <errno.h> 426059Samurai#include <fcntl.h> 4311336Samurai#include <paths.h> 4430715Sbrian#include <signal.h> 4530715Sbrian#include <stdio.h> 4630715Sbrian#include <stdlib.h> 4730715Sbrian#include <string.h> 486059Samurai#include <sys/time.h> 4930715Sbrian#include <sys/wait.h> 5030715Sbrian#include <sysexits.h> 516059Samurai#include <termios.h> 5218786Sjkh#include <unistd.h> 5330715Sbrian 5431343Sbrian#include "command.h" 5530715Sbrian#include "mbuf.h" 5630715Sbrian#include "log.h" 5730715Sbrian#include "defs.h" 5831061Sbrian#include "id.h" 5930715Sbrian#include "timer.h" 6030715Sbrian#include "fsm.h" 616059Samurai#include "modem.h" 626059Samurai#include "os.h" 636059Samurai#include "hdlc.h" 6431514Sbrian#include "lcp.h" 6513389Sphk#include "ccp.h" 666059Samurai#include "ipcp.h" 6726142Sbrian#include "loadalias.h" 686059Samurai#include "vars.h" 696735Samurai#include "auth.h" 707001Samurai#include "filter.h" 7113389Sphk#include "systems.h" 7213389Sphk#include "ip.h" 7323840Sbrian#include "sig.h" 7426940Sbrian#include "server.h" 7528536Sbrian#include "lcpproto.h" 7630715Sbrian#include "main.h" 7730715Sbrian#include "vjcomp.h" 7830715Sbrian#include "async.h" 7931158Sbrian#include "pathnames.h" 8031195Sbrian#include "tun.h" 8131343Sbrian#include "route.h" 826059Samurai 836735Samurai#ifndef O_NONBLOCK 846735Samurai#ifdef O_NDELAY 856735Samurai#define O_NONBLOCK O_NDELAY 866735Samurai#endif 876735Samurai#endif 886735Samurai 8930715Sbrianint TermMode = 0; 9030715Sbrianint tunno = 0; 916059Samurai 9228679Sbrianstatic struct termios oldtio; /* Original tty mode */ 9328679Sbrianstatic struct termios comtio; /* Command level tty mode */ 9420813Sjkhstatic pid_t BGPid = 0; 9525634Sbrianstatic char pid_filename[MAXPATHLEN]; 9627061Sbrianstatic int dial_up; 976059Samurai 9830715Sbrianstatic void DoLoop(void); 9930715Sbrianstatic void TerminalStop(int); 10031343Sbrianstatic const char *ex_desc(int); 10130715Sbrian 1026059Samuraistatic void 10326858SbrianTtyInit(int DontWantInt) 1046059Samurai{ 1056059Samurai struct termios newtio; 1066059Samurai int stat; 1076059Samurai 1086059Samurai stat = fcntl(0, F_GETFL, 0); 10925630Sbrian if (stat > 0) { 11028679Sbrian stat |= O_NONBLOCK; 11128679Sbrian (void) fcntl(0, F_SETFL, stat); 11225630Sbrian } 1136059Samurai newtio = oldtio; 11428679Sbrian newtio.c_lflag &= ~(ECHO | ISIG | ICANON); 1156059Samurai newtio.c_iflag = 0; 1166059Samurai newtio.c_oflag &= ~OPOST; 1176059Samurai newtio.c_cc[VEOF] = _POSIX_VDISABLE; 11826858Sbrian if (DontWantInt) 11926858Sbrian newtio.c_cc[VINTR] = _POSIX_VDISABLE; 1206059Samurai newtio.c_cc[VMIN] = 1; 1216059Samurai newtio.c_cc[VTIME] = 0; 1226059Samurai newtio.c_cflag |= CS8; 1236735Samurai tcsetattr(0, TCSADRAIN, &newtio); 1246059Samurai comtio = newtio; 1256059Samurai} 1266059Samurai 1276059Samurai/* 1286059Samurai * Set tty into command mode. We allow canonical input and echo processing. 1296059Samurai */ 13010528Samuraivoid 13128679SbrianTtyCommandMode(int prompt) 1326059Samurai{ 1336059Samurai struct termios newtio; 1346059Samurai int stat; 1356059Samurai 1366059Samurai if (!(mode & MODE_INTER)) 1376059Samurai return; 1386735Samurai tcgetattr(0, &newtio); 13928679Sbrian newtio.c_lflag |= (ECHO | ISIG | ICANON); 1406059Samurai newtio.c_iflag = oldtio.c_iflag; 1416059Samurai newtio.c_oflag |= OPOST; 1426735Samurai tcsetattr(0, TCSADRAIN, &newtio); 1436059Samurai stat = fcntl(0, F_GETFL, 0); 14425630Sbrian if (stat > 0) { 14528679Sbrian stat |= O_NONBLOCK; 14628679Sbrian (void) fcntl(0, F_SETFL, stat); 14725630Sbrian } 1486059Samurai TermMode = 0; 14928679Sbrian if (prompt) 15028679Sbrian Prompt(); 1516059Samurai} 1526059Samurai 1536059Samurai/* 1546059Samurai * Set tty into terminal mode which is used while we invoke term command. 1556059Samurai */ 1566059Samuraivoid 1576059SamuraiTtyTermMode() 1586059Samurai{ 1596059Samurai int stat; 1606059Samurai 1616735Samurai tcsetattr(0, TCSADRAIN, &comtio); 1626059Samurai stat = fcntl(0, F_GETFL, 0); 16325630Sbrian if (stat > 0) { 16428679Sbrian stat &= ~O_NONBLOCK; 16528679Sbrian (void) fcntl(0, F_SETFL, stat); 16625630Sbrian } 1676059Samurai TermMode = 1; 1686059Samurai} 1696059Samurai 1706059Samuraivoid 17110528SamuraiTtyOldMode() 1726059Samurai{ 1736059Samurai int stat; 1746059Samurai 1756059Samurai stat = fcntl(0, F_GETFL, 0); 17625630Sbrian if (stat > 0) { 17728679Sbrian stat &= ~O_NONBLOCK; 17828679Sbrian (void) fcntl(0, F_SETFL, stat); 17925630Sbrian } 1806735Samurai tcsetattr(0, TCSANOW, &oldtio); 18110528Samurai} 18210528Samurai 18310528Samuraivoid 18428679SbrianCleanup(int excode) 18510528Samurai{ 18631203Sbrian DropClient(); 18731081Sbrian ServerClose(); 18830825Sbrian OsInterfaceDown(1); 18930825Sbrian HangupModem(1); 19030697Sbrian nointr_sleep(1); 19131121Sbrian DeleteIfRoutes(1); 19231061Sbrian ID0unlink(pid_filename); 19323863Sbrian if (mode & MODE_BACKGROUND && BGFiledes[1] != -1) { 19423863Sbrian char c = EX_ERRDEAD; 19528679Sbrian 19628679Sbrian if (write(BGFiledes[1], &c, 1) == 1) 19728679Sbrian LogPrintf(LogPHASE, "Parent notified of failure.\n"); 19823863Sbrian else 19928679Sbrian LogPrintf(LogPHASE, "Failed to notify parent of failure.\n"); 20023863Sbrian close(BGFiledes[1]); 20123863Sbrian } 20228679Sbrian LogPrintf(LogPHASE, "PPP Terminated (%s).\n", ex_desc(excode)); 20310528Samurai TtyOldMode(); 20431061Sbrian LogClose(); 2056059Samurai 2066059Samurai exit(excode); 2076059Samurai} 2086059Samurai 2096059Samuraistatic void 21028679SbrianCloseConnection(int signo) 2116059Samurai{ 21226858Sbrian /* NOTE, these are manual, we've done a setsid() */ 21331121Sbrian pending_signal(SIGINT, SIG_IGN); 21427157Sbrian LogPrintf(LogPHASE, "Caught signal %d, abort connection\n", signo); 21528679Sbrian reconnectState = RECON_FALSE; 21628684Sbrian reconnectCount = 0; 21728684Sbrian DownConnection(); 21830715Sbrian dial_up = 0; 21931121Sbrian pending_signal(SIGINT, CloseConnection); 2206059Samurai} 2216059Samurai 2226059Samuraistatic void 22328679SbrianCloseSession(int signo) 2246059Samurai{ 22528679Sbrian if (BGPid) { 22628679Sbrian kill(BGPid, SIGINT); 22728679Sbrian exit(EX_TERM); 22828679Sbrian } 22928679Sbrian LogPrintf(LogPHASE, "Signal %d, terminate.\n", signo); 23028679Sbrian reconnect(RECON_FALSE); 23128679Sbrian LcpClose(); 23228679Sbrian Cleanup(EX_TERM); 2336059Samurai} 2346059Samurai 23510528Samuraistatic void 23631343SbrianTerminalCont(int signo) 23710528Samurai{ 23823840Sbrian pending_signal(SIGCONT, SIG_DFL); 23923840Sbrian pending_signal(SIGTSTP, TerminalStop); 24010528Samurai TtyCommandMode(getpgrp() == tcgetpgrp(0)); 24110528Samurai} 24210528Samurai 24310528Samuraistatic void 24428679SbrianTerminalStop(int signo) 24510528Samurai{ 24623840Sbrian pending_signal(SIGCONT, TerminalCont); 24710528Samurai TtyOldMode(); 24823840Sbrian pending_signal(SIGTSTP, SIG_DFL); 24910528Samurai kill(getpid(), signo); 25010528Samurai} 25110528Samurai 25226940Sbrianstatic void 25328679SbrianSetUpServer(int signo) 25426940Sbrian{ 25526940Sbrian int res; 25628679Sbrian 25731081Sbrian VarHaveLocalAuthKey = 0; 25831081Sbrian LocalAuthInit(); 25928679Sbrian if ((res = ServerTcpOpen(SERVER_PORT + tunno)) != 0) 26029083Sbrian LogPrintf(LogERROR, "SIGUSR1: Failed %d to open port %d\n", 26129083Sbrian res, SERVER_PORT + tunno); 26226940Sbrian} 26326940Sbrian 26431081Sbrianstatic void 26531081SbrianBringDownServer(int signo) 26631081Sbrian{ 26731081Sbrian VarHaveLocalAuthKey = 0; 26831081Sbrian LocalAuthInit(); 26931081Sbrian ServerClose(); 27031081Sbrian} 27131081Sbrian 27231343Sbrianstatic const char * 27325908Sbrianex_desc(int ex) 27425908Sbrian{ 27525908Sbrian static char num[12]; 27631343Sbrian static const char *desc[] = { 27731343Sbrian "normal", "start", "sock", "modem", "dial", "dead", "done", 27831343Sbrian "reboot", "errdead", "hangup", "term", "nodial", "nologin" 27931343Sbrian }; 28010528Samurai 28128679Sbrian if (ex >= 0 && ex < sizeof(desc) / sizeof(*desc)) 28225908Sbrian return desc[ex]; 28325908Sbrian snprintf(num, sizeof num, "%d", ex); 28425908Sbrian return num; 28525908Sbrian} 28625908Sbrian 28730715Sbrianstatic void 28831343SbrianUsage(void) 2896059Samurai{ 29020120Snate fprintf(stderr, 29131343Sbrian "Usage: ppp [-auto | -background | -direct | -dedicated | -ddial ]" 29231343Sbrian#ifndef NOALIAS 29331343Sbrian " [ -alias ]" 29431343Sbrian#endif 29531343Sbrian " [system]\n"); 2966059Samurai exit(EX_START); 2976059Samurai} 2986059Samurai 29931197Sbrianstatic char * 3006059SamuraiProcessArgs(int argc, char **argv) 3016059Samurai{ 3026059Samurai int optc; 3036059Samurai char *cp; 3046059Samurai 3056059Samurai optc = 0; 30631121Sbrian mode = MODE_INTER; 3076059Samurai while (argc > 0 && **argv == '-') { 3086059Samurai cp = *argv + 1; 30931121Sbrian if (strcmp(cp, "auto") == 0) { 3106059Samurai mode |= MODE_AUTO; 31131121Sbrian mode &= ~MODE_INTER; 31231121Sbrian } else if (strcmp(cp, "background") == 0) { 31331121Sbrian mode |= MODE_BACKGROUND; 31431121Sbrian mode &= ~MODE_INTER; 31531121Sbrian } else if (strcmp(cp, "direct") == 0) { 3166059Samurai mode |= MODE_DIRECT; 31731121Sbrian mode &= ~MODE_INTER; 31831121Sbrian } else if (strcmp(cp, "dedicated") == 0) { 3196059Samurai mode |= MODE_DEDICATED; 32031121Sbrian mode &= ~MODE_INTER; 32131121Sbrian } else if (strcmp(cp, "ddial") == 0) { 32231121Sbrian mode |= MODE_DDIAL; 32331121Sbrian mode &= ~MODE_INTER; 32431343Sbrian#ifndef NOALIAS 32531121Sbrian } else if (strcmp(cp, "alias") == 0) { 32626142Sbrian if (loadAliasHandlers(&VarAliasHandlers) == 0) 32728679Sbrian mode |= MODE_ALIAS; 32826142Sbrian else 32928679Sbrian LogPrintf(LogWARN, "Cannot load alias library\n"); 33028679Sbrian optc--; /* this option isn't exclusive */ 33131343Sbrian#endif 33228679Sbrian } else 3336059Samurai Usage(); 3346059Samurai optc++; 33528679Sbrian argv++; 33628679Sbrian argc--; 3376059Samurai } 3386059Samurai if (argc > 1) { 3396059Samurai fprintf(stderr, "specify only one system label.\n"); 3406059Samurai exit(EX_START); 3416059Samurai } 3426059Samurai 3436059Samurai if (optc > 1) { 3446059Samurai fprintf(stderr, "specify only one mode.\n"); 3456059Samurai exit(EX_START); 3466059Samurai } 34731197Sbrian 34831197Sbrian return argc == 1 ? *argv : NULL; /* Don't SetLabel yet ! */ 3496059Samurai} 3506059Samurai 3516059Samuraistatic void 35231343SbrianGreetings(void) 3536059Samurai{ 35426516Sbrian if (VarTerm) { 35526516Sbrian fprintf(VarTerm, "User Process PPP. Written by Toshiharu OHNO.\n"); 35626516Sbrian fflush(VarTerm); 35726516Sbrian } 3586059Samurai} 3596059Samurai 36026940Sbrianint 36128679Sbrianmain(int argc, char **argv) 3626059Samurai{ 36325707Sbrian FILE *lockfile; 36431197Sbrian char *name, *label; 36526516Sbrian 36626551Sbrian VarTerm = 0; 36730715Sbrian name = strrchr(argv[0], '/'); 36828679Sbrian LogOpen(name ? name + 1 : argv[0]); 36926516Sbrian 37028679Sbrian argc--; 37128679Sbrian argv++; 37231197Sbrian label = ProcessArgs(argc, argv); 37331121Sbrian if (!(mode & MODE_DIRECT)) 37426551Sbrian VarTerm = stdout; 37531121Sbrian 37631121Sbrian ID0init(); 37731158Sbrian if (ID0realuid() != 0) { 37831158Sbrian char conf[200], *ptr; 37931158Sbrian 38031158Sbrian snprintf(conf, sizeof conf, "%s/%s", _PATH_PPP, CONFFILE); 38131158Sbrian do { 38231158Sbrian if (!access(conf, W_OK)) { 38331158Sbrian LogPrintf(LogALERT, "ppp: Access violation: Please protect %s\n", conf); 38431158Sbrian return -1; 38531158Sbrian } 38631158Sbrian ptr = conf + strlen(conf)-2; 38731158Sbrian while (ptr > conf && *ptr != '/') 38831158Sbrian *ptr-- = '\0'; 38931158Sbrian } while (ptr >= conf); 39031158Sbrian } 39131158Sbrian 39231197Sbrian if (!ValidSystem(label)) { 39331121Sbrian fprintf(stderr, "You may not use ppp in this mode with this label\n"); 39431157Sbrian if (mode & MODE_DIRECT) { 39531157Sbrian const char *l; 39631197Sbrian l = label ? label : "default"; 39731157Sbrian VarTerm = 0; 39831157Sbrian LogPrintf(LogWARN, "Label %s rejected -direct connection\n", l); 39931157Sbrian } 40031157Sbrian LogClose(); 40131121Sbrian return 1; 40229083Sbrian } 40331121Sbrian 40431196Sbrian if (!GetShortHost()) 40531196Sbrian return 1; 40626551Sbrian Greetings(); 4076059Samurai IpcpDefAddress(); 4086059Samurai 40931285Sbrian if (mode & MODE_INTER) 41031285Sbrian VarLocalAuth = LOCAL_AUTH; 41131285Sbrian 41226516Sbrian if (SelectSystem("default", CONFFILE) < 0 && VarTerm) 41326516Sbrian fprintf(VarTerm, "Warning: No default entry is given in config file.\n"); 4146059Samurai 4156059Samurai if (OpenTunnel(&tunno) < 0) { 41626940Sbrian LogPrintf(LogWARN, "open_tun: %s\n", strerror(errno)); 41726940Sbrian return EX_START; 4186059Samurai } 4196059Samurai if (mode & MODE_INTER) { 42026516Sbrian fprintf(VarTerm, "Interactive mode\n"); 42126690Sbrian netfd = STDOUT_FILENO; 42231121Sbrian } else if ((mode & MODE_OUTGOING_DAEMON) && !(mode & MODE_DEDICATED)) 42331197Sbrian if (label == NULL) { 42426516Sbrian if (VarTerm) 42528679Sbrian fprintf(VarTerm, "Destination system must be specified in" 42628679Sbrian " auto, background or ddial mode.\n"); 42726940Sbrian return EX_START; 4286059Samurai } 42931121Sbrian 43028679Sbrian tcgetattr(0, &oldtio); /* Save original tty mode */ 4316059Samurai 43227157Sbrian pending_signal(SIGHUP, CloseSession); 43323840Sbrian pending_signal(SIGTERM, CloseSession); 43427157Sbrian pending_signal(SIGINT, CloseConnection); 43523840Sbrian pending_signal(SIGQUIT, CloseSession); 4366735Samurai#ifdef SIGPIPE 43724753Sache signal(SIGPIPE, SIG_IGN); 4386735Samurai#endif 4396735Samurai#ifdef SIGALRM 44023840Sbrian pending_signal(SIGALRM, SIG_IGN); 4416735Samurai#endif 44228679Sbrian if (mode & MODE_INTER) { 44310528Samurai#ifdef SIGTSTP 44426940Sbrian pending_signal(SIGTSTP, TerminalStop); 44510528Samurai#endif 44610528Samurai#ifdef SIGTTIN 44726940Sbrian pending_signal(SIGTTIN, TerminalStop); 44810528Samurai#endif 44910528Samurai#ifdef SIGTTOU 45026940Sbrian pending_signal(SIGTTOU, SIG_IGN); 45110528Samurai#endif 45226940Sbrian } 45331121Sbrian if (!(mode & MODE_INTER)) { 45426940Sbrian#ifdef SIGUSR1 45526940Sbrian pending_signal(SIGUSR1, SetUpServer); 45626940Sbrian#endif 45731081Sbrian#ifdef SIGUSR2 45831081Sbrian pending_signal(SIGUSR2, BringDownServer); 45931081Sbrian#endif 46031121Sbrian } 4616059Samurai 46231197Sbrian if (label) { 46331197Sbrian if (SelectSystem(label, CONFFILE) < 0) { 46431154Sbrian LogPrintf(LogWARN, "Destination system %s not found in conf file.\n", 46531154Sbrian GetLabel()); 4666059Samurai Cleanup(EX_START); 4676059Samurai } 46831197Sbrian /* 46931197Sbrian * We don't SetLabel() 'till now in case SelectSystem() has an 47031197Sbrian * embeded load "otherlabel" command. 47131197Sbrian */ 47231197Sbrian SetLabel(label); 47331121Sbrian if (mode & MODE_OUTGOING_DAEMON && 47431121Sbrian DefHisAddress.ipaddr.s_addr == INADDR_ANY) { 47531154Sbrian LogPrintf(LogWARN, "You must \"set ifaddr\" in label %s for" 47631197Sbrian " auto, background or ddial mode.\n", label); 4776059Samurai Cleanup(EX_START); 4786059Samurai } 4796059Samurai } 48026940Sbrian 48131121Sbrian if (mode & MODE_DAEMON) { 48220813Sjkh if (mode & MODE_BACKGROUND) { 48328679Sbrian if (pipe(BGFiledes)) { 48428974Sbrian LogPrintf(LogERROR, "pipe: %s\n", strerror(errno)); 48520813Sjkh Cleanup(EX_SOCK); 48620813Sjkh } 4876059Samurai } 4886059Samurai 4896059Samurai if (!(mode & MODE_DIRECT)) { 49020813Sjkh pid_t bgpid; 49111336Samurai 49228679Sbrian bgpid = fork(); 49320813Sjkh if (bgpid == -1) { 49428974Sbrian LogPrintf(LogERROR, "fork: %s\n", strerror(errno)); 49528679Sbrian Cleanup(EX_SOCK); 49620813Sjkh } 49720813Sjkh if (bgpid) { 49820813Sjkh char c = EX_NORMAL; 49911336Samurai 50020813Sjkh if (mode & MODE_BACKGROUND) { 50120813Sjkh /* Wait for our child to close its pipe before we exit. */ 50220813Sjkh BGPid = bgpid; 50328679Sbrian close(BGFiledes[1]); 50425908Sbrian if (read(BGFiledes[0], &c, 1) != 1) { 50526516Sbrian fprintf(VarTerm, "Child exit, no status.\n"); 50628679Sbrian LogPrintf(LogPHASE, "Parent: Child exit, no status.\n"); 50725908Sbrian } else if (c == EX_NORMAL) { 50826516Sbrian fprintf(VarTerm, "PPP enabled.\n"); 50928679Sbrian LogPrintf(LogPHASE, "Parent: PPP enabled.\n"); 51025908Sbrian } else { 51128679Sbrian fprintf(VarTerm, "Child failed (%s).\n", ex_desc((int) c)); 51226516Sbrian LogPrintf(LogPHASE, "Parent: Child failed (%s).\n", 51328679Sbrian ex_desc((int) c)); 51428679Sbrian } 51528679Sbrian close(BGFiledes[0]); 51620813Sjkh } 51728679Sbrian return c; 51823863Sbrian } else if (mode & MODE_BACKGROUND) 51928679Sbrian close(BGFiledes[0]); 52025707Sbrian } 52120813Sjkh 52228679Sbrian VarTerm = 0; /* We know it's currently stdout */ 52329551Sbrian close(1); 52426686Sbrian close(2); 52526551Sbrian 52626686Sbrian if (mode & MODE_DIRECT) 52726858Sbrian TtyInit(1); 52831121Sbrian else if (mode & MODE_DAEMON) { 52926686Sbrian setsid(); 53029551Sbrian close(0); 53126686Sbrian } 5326059Samurai } else { 53326858Sbrian TtyInit(0); 53410528Samurai TtyCommandMode(1); 5356059Samurai } 53629696Sbrian 53729696Sbrian snprintf(pid_filename, sizeof(pid_filename), "%stun%d.pid", 53829696Sbrian _PATH_VARRUN, tunno); 53931061Sbrian lockfile = ID0fopen(pid_filename, "w"); 54031061Sbrian if (lockfile != NULL) { 54129696Sbrian fprintf(lockfile, "%d\n", (int) getpid()); 54229696Sbrian fclose(lockfile); 54329696Sbrian } else 54429696Sbrian LogPrintf(LogALERT, "Warning: Can't create %s: %s\n", 54529696Sbrian pid_filename, strerror(errno)); 54629696Sbrian 54726516Sbrian LogPrintf(LogPHASE, "PPP Started.\n"); 5486059Samurai 5496059Samurai 5506059Samurai do 55128679Sbrian DoLoop(); 5526059Samurai while (mode & MODE_DEDICATED); 5536059Samurai 5546059Samurai Cleanup(EX_DONE); 55526940Sbrian return 0; 5566059Samurai} 5576059Samurai 5586059Samurai/* 55920813Sjkh * Turn into packet mode, where we speak PPP. 5606059Samurai */ 5616059Samuraivoid 5626059SamuraiPacketMode() 5636059Samurai{ 56431034Sbrian if (RawModem() < 0) { 56526516Sbrian LogPrintf(LogWARN, "PacketMode: Not connected.\n"); 5666059Samurai return; 5676059Samurai } 5686059Samurai AsyncInit(); 56930187Sbrian VjInit(15); 5706059Samurai LcpInit(); 5716059Samurai IpcpInit(); 5726059Samurai CcpInit(); 5736059Samurai LcpUp(); 5746059Samurai 57525872Sbrian LcpOpen(VarOpenMode); 57631121Sbrian if (mode & MODE_INTER) 57710528Samurai TtyCommandMode(1); 57831121Sbrian if (VarTerm) { 57931121Sbrian fprintf(VarTerm, "Packet mode.\n"); 58031121Sbrian aft_cmd = 1; 5816059Samurai } 5826059Samurai} 5836059Samurai 5846059Samuraistatic void 58531343SbrianShowHelp(void) 5866059Samurai{ 58726901Sbrian fprintf(stderr, "The following commands are available:\r\n"); 58826901Sbrian fprintf(stderr, " ~p\tEnter Packet mode\r\n"); 58926901Sbrian fprintf(stderr, " ~-\tDecrease log level\r\n"); 59026901Sbrian fprintf(stderr, " ~+\tIncrease log level\r\n"); 59126901Sbrian fprintf(stderr, " ~t\tShow timers (only in \"log debug\" mode)\r\n"); 59226901Sbrian fprintf(stderr, " ~m\tShow memory map (only in \"log debug\" mode)\r\n"); 59326901Sbrian fprintf(stderr, " ~.\tTerminate program\r\n"); 59426901Sbrian fprintf(stderr, " ~?\tThis help\r\n"); 5956059Samurai} 5966059Samurai 5976059Samuraistatic void 59831343SbrianReadTty(void) 5996059Samurai{ 6006059Samurai int n; 6016059Samurai char ch; 6026059Samurai static int ttystate; 60331070Sbrian char linebuff[LINE_LEN]; 60428679Sbrian 60526516Sbrian LogPrintf(LogDEBUG, "termode = %d, netfd = %d, mode = %d\n", 60628679Sbrian TermMode, netfd, mode); 6076059Samurai if (!TermMode) { 60828679Sbrian n = read(netfd, linebuff, sizeof(linebuff) - 1); 6096735Samurai if (n > 0) { 61026516Sbrian aft_cmd = 1; 61130913Sbrian if (linebuff[n-1] == '\n') 61230913Sbrian linebuff[--n] = '\0'; 61331156Sbrian if (n) 61431156Sbrian DecodeCommand(linebuff, n, IsInteractive(0) ? NULL : "Client"); 61531156Sbrian Prompt(); 61631240Sbrian } else if (n <= 0) 61731203Sbrian DropClient(); 6186059Samurai return; 6196059Samurai } 6206059Samurai 6216059Samurai /* 62228679Sbrian * We are in terminal mode, decode special sequences 6236059Samurai */ 62426516Sbrian n = read(fileno(VarTerm), &ch, 1); 62528974Sbrian LogPrintf(LogDEBUG, "Got %d bytes (reading from the terminal)\n", n); 6266059Samurai 6276059Samurai if (n > 0) { 6286059Samurai switch (ttystate) { 6296059Samurai case 0: 6306059Samurai if (ch == '~') 6316059Samurai ttystate++; 6326059Samurai else 6336059Samurai write(modem, &ch, n); 6346059Samurai break; 6356059Samurai case 1: 6366059Samurai switch (ch) { 6376059Samurai case '?': 6386059Samurai ShowHelp(); 6396059Samurai break; 6406059Samurai case 'p': 64128679Sbrian 6426059Samurai /* 6436059Samurai * XXX: Should check carrier. 6446059Samurai */ 6456059Samurai if (LcpFsm.state <= ST_CLOSED) { 6466059Samurai VarOpenMode = OPEN_ACTIVE; 6476059Samurai PacketMode(); 6486059Samurai } 6496059Samurai break; 6506059Samurai case '.': 6516059Samurai TermMode = 1; 65226516Sbrian aft_cmd = 1; 65310528Samurai TtyCommandMode(1); 6546059Samurai break; 65526516Sbrian case 't': 65626516Sbrian if (LogIsKept(LogDEBUG)) { 65726516Sbrian ShowTimers(); 65826516Sbrian break; 65926516Sbrian } 66026516Sbrian case 'm': 66126516Sbrian if (LogIsKept(LogDEBUG)) { 66231343Sbrian ShowMemMap(NULL); 66326516Sbrian break; 66426516Sbrian } 6656059Samurai default: 6666059Samurai if (write(modem, &ch, n) < 0) 66726516Sbrian LogPrintf(LogERROR, "error writing to modem.\n"); 6686059Samurai break; 6696059Samurai } 6706059Samurai ttystate = 0; 6716059Samurai break; 6726059Samurai } 6736059Samurai } 6746059Samurai} 6756059Samurai 6766059Samurai 6776059Samurai/* 6786059Samurai * Here, we'll try to detect HDLC frame 6796059Samurai */ 6806059Samurai 68131343Sbrianstatic const char *FrameHeaders[] = { 6826735Samurai "\176\377\003\300\041", 6836735Samurai "\176\377\175\043\300\041", 6846735Samurai "\176\177\175\043\100\041", 6856735Samurai "\176\175\337\175\043\300\041", 6866735Samurai "\176\175\137\175\043\100\041", 6876059Samurai NULL, 6886059Samurai}; 6896059Samurai 69031343Sbrianstatic const u_char * 69128679SbrianHdlcDetect(u_char * cp, int n) 6926059Samurai{ 69331343Sbrian const char *ptr, *fp, **hp; 6946059Samurai 69528679Sbrian cp[n] = '\0'; /* be sure to null terminated */ 6966059Samurai ptr = NULL; 6976059Samurai for (hp = FrameHeaders; *hp; hp++) { 6986735Samurai fp = *hp; 6996735Samurai if (DEV_IS_SYNC) 7006735Samurai fp++; 70128679Sbrian ptr = strstr((char *) cp, fp); 70213389Sphk if (ptr) 7036059Samurai break; 7046059Samurai } 70531343Sbrian return ((const u_char *) ptr); 7066059Samurai} 7076059Samurai 7086059Samuraistatic struct pppTimer RedialTimer; 7096059Samurai 7106059Samuraistatic void 71131343SbrianRedialTimeout(void *v) 7126059Samurai{ 7136059Samurai StopTimer(&RedialTimer); 71426516Sbrian LogPrintf(LogPHASE, "Redialing timer expired.\n"); 7156059Samurai} 7166059Samurai 7176059Samuraistatic void 71828679SbrianStartRedialTimer(int Timeout) 7196059Samurai{ 7206059Samurai StopTimer(&RedialTimer); 72111336Samurai 72224939Sbrian if (Timeout) { 72311336Samurai RedialTimer.state = TIMER_STOPPED; 72411336Samurai 72524939Sbrian if (Timeout > 0) 72628679Sbrian RedialTimer.load = Timeout * SECTICKS; 72711336Samurai else 72828679Sbrian RedialTimer.load = (random() % REDIAL_PERIOD) * SECTICKS; 72911336Samurai 73026516Sbrian LogPrintf(LogPHASE, "Enter pause (%d) for redialing.\n", 73124939Sbrian RedialTimer.load / SECTICKS); 73224939Sbrian 73311336Samurai RedialTimer.func = RedialTimeout; 73411336Samurai StartTimer(&RedialTimer); 73511336Samurai } 7366059Samurai} 7376059Samurai 7386059Samurai 7396059Samuraistatic void 74031343SbrianDoLoop(void) 7416059Samurai{ 7426059Samurai fd_set rfds, wfds, efds; 74323598Sache int pri, i, n, wfd, nfds; 7446059Samurai struct sockaddr_in hisaddr; 7456059Samurai struct timeval timeout, *tp; 7466059Samurai int ssize = sizeof(hisaddr); 74731343Sbrian const u_char *cp; 74811336Samurai int tries; 7499448Samurai int qlen; 75026858Sbrian int res; 75131195Sbrian struct tun_data tun; 75231195Sbrian#define rbuff tun.data 7536059Samurai 75425908Sbrian if (mode & MODE_DIRECT) { 75526551Sbrian LogPrintf(LogDEBUG, "Opening modem\n"); 75631034Sbrian if (OpenModem() < 0) 75729521Sbrian return; 75826516Sbrian LogPrintf(LogPHASE, "Packet mode enabled\n"); 7596059Samurai PacketMode(); 7606059Samurai } else if (mode & MODE_DEDICATED) { 76123598Sache if (modem < 0) 76231034Sbrian while (OpenModem() < 0) 76330697Sbrian nointr_sleep(VarReconnectTimer); 7646059Samurai } 76526516Sbrian fflush(VarTerm); 7666059Samurai 7677001Samurai timeout.tv_sec = 0; 7686059Samurai timeout.tv_usec = 0; 76926098Sbrian reconnectState = RECON_UNKNOWN; 7706059Samurai 77123863Sbrian if (mode & MODE_BACKGROUND) 77230715Sbrian dial_up = 1; /* Bring the line up */ 77323863Sbrian else 77430715Sbrian dial_up = 0; /* XXXX */ 77511336Samurai tries = 0; 7766059Samurai for (;;) { 77723598Sache nfds = 0; 77828679Sbrian FD_ZERO(&rfds); 77928679Sbrian FD_ZERO(&wfds); 78028679Sbrian FD_ZERO(&efds); 7817001Samurai 78228679Sbrian /* 78328679Sbrian * If the link is down and we're in DDIAL mode, bring it back up. 78420120Snate */ 78520120Snate if (mode & MODE_DDIAL && LcpFsm.state <= ST_CLOSED) 78630715Sbrian dial_up = 1; 78720120Snate 78825067Sbrian /* 78928679Sbrian * If we lost carrier and want to re-establish the connection due to the 79028679Sbrian * "set reconnect" value, we'd better bring the line back up. 79125067Sbrian */ 79225908Sbrian if (LcpFsm.state <= ST_CLOSED) { 79330715Sbrian if (!dial_up && reconnectState == RECON_TRUE) { 79428679Sbrian if (++reconnectCount <= VarReconnectTries) { 79528679Sbrian LogPrintf(LogPHASE, "Connection lost, re-establish (%d/%d)\n", 79628679Sbrian reconnectCount, VarReconnectTries); 79725908Sbrian StartRedialTimer(VarReconnectTimer); 79830715Sbrian dial_up = 1; 79928679Sbrian } else { 80028679Sbrian if (VarReconnectTries) 80128679Sbrian LogPrintf(LogPHASE, "Connection lost, maximum (%d) times\n", 80228679Sbrian VarReconnectTries); 80328679Sbrian reconnectCount = 0; 80428679Sbrian if (mode & MODE_BACKGROUND) 80528679Sbrian Cleanup(EX_DEAD); 80628679Sbrian } 80728679Sbrian reconnectState = RECON_ENVOKED; 80831121Sbrian } else if (mode & MODE_DEDICATED) 80931121Sbrian if (VarOpenMode == OPEN_ACTIVE) 81031121Sbrian PacketMode(); 81125908Sbrian } 81225067Sbrian 81328679Sbrian /* 81428679Sbrian * If Ip packet for output is enqueued and require dial up, Just do it! 81528679Sbrian */ 81628679Sbrian if (dial_up && RedialTimer.state != TIMER_RUNNING) { 81726516Sbrian LogPrintf(LogDEBUG, "going to dial: modem = %d\n", modem); 81831034Sbrian if (OpenModem() < 0) { 81928679Sbrian tries++; 82028679Sbrian if (!(mode & MODE_DDIAL) && VarDialTries) 82128679Sbrian LogPrintf(LogCHAT, "Failed to open modem (attempt %u of %d)\n", 82228679Sbrian tries, VarDialTries); 82328679Sbrian else 82428679Sbrian LogPrintf(LogCHAT, "Failed to open modem (attempt %u)\n", tries); 82526551Sbrian 82626696Sbrian if (!(mode & MODE_DDIAL) && VarDialTries && tries >= VarDialTries) { 82726551Sbrian if (mode & MODE_BACKGROUND) 82828679Sbrian Cleanup(EX_DIAL); /* Can't get the modem */ 82930715Sbrian dial_up = 0; 83028679Sbrian reconnectState = RECON_UNKNOWN; 83128679Sbrian reconnectCount = 0; 83226551Sbrian tries = 0; 83328679Sbrian } else 83426551Sbrian StartRedialTimer(VarRedialTimeout); 83511336Samurai } else { 83628679Sbrian tries++; /* Tries are per number, not per list of 83728679Sbrian * numbers. */ 83828679Sbrian if (!(mode & MODE_DDIAL) && VarDialTries) 83926696Sbrian LogPrintf(LogCHAT, "Dial attempt %u of %d\n", tries, VarDialTries); 84028679Sbrian else 84128679Sbrian LogPrintf(LogCHAT, "Dial attempt %u\n", tries); 84226696Sbrian 84326858Sbrian if ((res = DialModem()) == EX_DONE) { 84430697Sbrian nointr_sleep(1); /* little pause to allow peer starts */ 84531343Sbrian ModemTimeout(NULL); 84611336Samurai PacketMode(); 84730715Sbrian dial_up = 0; 84828679Sbrian reconnectState = RECON_UNKNOWN; 84911336Samurai tries = 0; 85011336Samurai } else { 85124844Sbrian if (mode & MODE_BACKGROUND) { 85226858Sbrian if (VarNextPhone == NULL || res == EX_SIG) 85328679Sbrian Cleanup(EX_DIAL); /* Tried all numbers - no luck */ 85424844Sbrian else 85524939Sbrian /* Try all numbers in background mode */ 85624939Sbrian StartRedialTimer(VarRedialNextTimeout); 85726858Sbrian } else if (!(mode & MODE_DDIAL) && 85828679Sbrian ((VarDialTries && tries >= VarDialTries) || 85928679Sbrian res == EX_SIG)) { 86024843Sbrian /* I give up ! Can't get through :( */ 86124939Sbrian StartRedialTimer(VarRedialTimeout); 86230715Sbrian dial_up = 0; 86328679Sbrian reconnectState = RECON_UNKNOWN; 86428679Sbrian reconnectCount = 0; 86524843Sbrian tries = 0; 86624843Sbrian } else if (VarNextPhone == NULL) 86724843Sbrian /* Dial failed. Keep quite during redial wait period. */ 86824939Sbrian StartRedialTimer(VarRedialTimeout); 86924843Sbrian else 87024939Sbrian StartRedialTimer(VarRedialNextTimeout); 87111336Samurai } 87211336Samurai } 8737001Samurai } 8749448Samurai qlen = ModemQlen(); 87513733Sdfr 87613733Sdfr if (qlen == 0) { 87713733Sdfr IpStartOutput(); 87813733Sdfr qlen = ModemQlen(); 87913733Sdfr } 88023598Sache if (modem >= 0) { 88123598Sache if (modem + 1 > nfds) 88223598Sache nfds = modem + 1; 8837001Samurai FD_SET(modem, &rfds); 8847001Samurai FD_SET(modem, &efds); 8859448Samurai if (qlen > 0) { 8867001Samurai FD_SET(modem, &wfds); 8877001Samurai } 8887001Samurai } 88923598Sache if (server >= 0) { 89023598Sache if (server + 1 > nfds) 89123598Sache nfds = server + 1; 89223598Sache FD_SET(server, &rfds); 89323598Sache } 8946059Samurai 89528679Sbrian /* 89628679Sbrian * *** IMPORTANT *** 89728679Sbrian * 89828679Sbrian * CPU is serviced every TICKUNIT micro seconds. This value must be chosen 89928679Sbrian * with great care. If this values is too big, it results loss of 90028679Sbrian * characters from modem and poor responce. If this values is too small, 90128679Sbrian * ppp process eats many CPU time. 9026059Samurai */ 9036735Samurai#ifndef SIGALRM 90430697Sbrian nointr_usleep(TICKUNIT); 9056059Samurai TimerService(); 90623840Sbrian#else 90723840Sbrian handle_signals(); 9086735Samurai#endif 90910877Sbde 91010877Sbde /* If there are aren't many packets queued, look for some more. */ 91123598Sache if (qlen < 20 && tun_in >= 0) { 91223598Sache if (tun_in + 1 > nfds) 91323598Sache nfds = tun_in + 1; 91410877Sbde FD_SET(tun_in, &rfds); 91523598Sache } 91623598Sache if (netfd >= 0) { 91723598Sache if (netfd + 1 > nfds) 91823598Sache nfds = netfd + 1; 9196059Samurai FD_SET(netfd, &rfds); 9206059Samurai FD_SET(netfd, &efds); 9216059Samurai } 92228679Sbrian#ifndef SIGALRM 9237001Samurai 9246059Samurai /* 92528679Sbrian * Normally, select() will not block because modem is writable. In AUTO 92628679Sbrian * mode, select will block until we find packet from tun 9276059Samurai */ 92828679Sbrian tp = (RedialTimer.state == TIMER_RUNNING) ? &timeout : NULL; 92923598Sache i = select(nfds, &rfds, &wfds, &efds, tp); 9306735Samurai#else 93128679Sbrian 9328857Srgrimes /* 93328679Sbrian * When SIGALRM timer is running, a select function will be return -1 and 93428679Sbrian * EINTR after a Time Service signal hundler is done. If the redial 93528679Sbrian * timer is not running and we are trying to dial, poll with a 0 value 93628679Sbrian * timer. 9377001Samurai */ 93811336Samurai tp = (dial_up && RedialTimer.state != TIMER_RUNNING) ? &timeout : NULL; 93923598Sache i = select(nfds, &rfds, &wfds, &efds, tp); 9406735Samurai#endif 94122074Sbrian 94228679Sbrian if (i == 0) { 94328679Sbrian continue; 9446059Samurai } 94528679Sbrian if (i < 0) { 94628679Sbrian if (errno == EINTR) { 94728679Sbrian handle_signals(); 94828679Sbrian continue; 94928679Sbrian } 95028974Sbrian LogPrintf(LogERROR, "DoLoop: select(): %s\n", strerror(errno)); 95128679Sbrian break; 9528857Srgrimes } 95323598Sache if ((netfd >= 0 && FD_ISSET(netfd, &efds)) || (modem >= 0 && FD_ISSET(modem, &efds))) { 95426516Sbrian LogPrintf(LogALERT, "Exception detected.\n"); 9556059Samurai break; 9566059Samurai } 95723598Sache if (server >= 0 && FD_ISSET(server, &rfds)) { 95826516Sbrian LogPrintf(LogPHASE, "connected to client.\n"); 95928679Sbrian wfd = accept(server, (struct sockaddr *) & hisaddr, &ssize); 96024753Sache if (wfd < 0) { 96128974Sbrian LogPrintf(LogERROR, "DoLoop: accept(): %s\n", strerror(errno)); 96224753Sache continue; 96324753Sache } 96423598Sache if (netfd >= 0) { 9656059Samurai write(wfd, "already in use.\n", 16); 9666059Samurai close(wfd); 9676059Samurai continue; 9686059Samurai } else 9696059Samurai netfd = wfd; 97026516Sbrian VarTerm = fdopen(netfd, "a+"); 97131081Sbrian LocalAuthInit(); 9726059Samurai Greetings(); 97330913Sbrian IsInteractive(1); 97425630Sbrian Prompt(); 9756059Samurai } 97631514Sbrian if (netfd >= 0 && FD_ISSET(netfd, &rfds)) 9776059Samurai /* something to read from tty */ 9786059Samurai ReadTty(); 97931514Sbrian if (modem >= 0 && FD_ISSET(modem, &wfds)) { 98031514Sbrian /* ready to write into modem */ 98131514Sbrian ModemStartOutput(modem); 98231514Sbrian if (modem < 0) 98331514Sbrian dial_up = 1; 9846059Samurai } 98531514Sbrian if (modem >= 0 && FD_ISSET(modem, &rfds)) { 98631514Sbrian /* something to read from modem */ 98731514Sbrian if (LcpFsm.state <= ST_CLOSED) 98831514Sbrian nointr_usleep(10000); 98931514Sbrian n = read(modem, rbuff, sizeof(rbuff)); 99031514Sbrian if ((mode & MODE_DIRECT) && n <= 0) { 99131514Sbrian DownConnection(); 99231514Sbrian } else 99331514Sbrian LogDumpBuff(LogASYNC, "ReadFromModem", rbuff, n); 9946059Samurai 99531514Sbrian if (LcpFsm.state <= ST_CLOSED) { 99631514Sbrian /* 99731514Sbrian * In dedicated mode, we just discard input until LCP is started. 99831514Sbrian */ 99931514Sbrian if (!(mode & MODE_DEDICATED)) { 100031514Sbrian cp = HdlcDetect(rbuff, n); 100131514Sbrian if (cp) { 100231514Sbrian /* 100331514Sbrian * LCP packet is detected. Turn ourselves into packet mode. 100431514Sbrian */ 100531514Sbrian if (cp != rbuff) { 100631514Sbrian write(modem, rbuff, cp - rbuff); 100731514Sbrian write(modem, "\r\n", 2); 100831514Sbrian } 100931514Sbrian PacketMode(); 101031514Sbrian } else 101131514Sbrian write(fileno(VarTerm), rbuff, n); 10126059Samurai } 101331514Sbrian } else { 101431514Sbrian if (n > 0) 101531514Sbrian AsyncInput(rbuff, n); 10166059Samurai } 10176059Samurai } 101828679Sbrian if (tun_in >= 0 && FD_ISSET(tun_in, &rfds)) { /* something to read 101928679Sbrian * from tun */ 102031195Sbrian n = read(tun_in, &tun, sizeof(tun)); 10216059Samurai if (n < 0) { 102228974Sbrian LogPrintf(LogERROR, "read from tun: %s\n", strerror(errno)); 10236059Samurai continue; 10246059Samurai } 102531195Sbrian n -= sizeof(tun)-sizeof(tun.data); 102631195Sbrian if (n <= 0) { 102731195Sbrian LogPrintf(LogERROR, "read from tun: Only %d bytes read\n", n); 102831195Sbrian continue; 102931195Sbrian } 103031195Sbrian if (!tun_check_header(tun, AF_INET)) 103131195Sbrian continue; 103228679Sbrian if (((struct ip *) rbuff)->ip_dst.s_addr == IpcpInfo.want_ipaddr.s_addr) { 103328536Sbrian /* we've been asked to send something addressed *to* us :( */ 103428536Sbrian if (VarLoopback) { 103528536Sbrian pri = PacketCheck(rbuff, n, FL_IN); 103628536Sbrian if (pri >= 0) { 103728536Sbrian struct mbuf *bp; 103828679Sbrian 103931343Sbrian#ifndef NOALIAS 104028536Sbrian if (mode & MODE_ALIAS) { 104128536Sbrian VarPacketAliasIn(rbuff, sizeof rbuff); 104228679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 104328536Sbrian } 104431343Sbrian#endif 104528536Sbrian bp = mballoc(n, MB_IPIN); 104630715Sbrian memcpy(MBUF_CTOP(bp), rbuff, n); 104728536Sbrian IpInput(bp); 104828536Sbrian LogPrintf(LogDEBUG, "Looped back packet addressed to myself\n"); 104928536Sbrian } 105028536Sbrian continue; 105128679Sbrian } else 105228536Sbrian LogPrintf(LogDEBUG, "Oops - forwarding packet addressed to myself\n"); 105328536Sbrian } 105428536Sbrian 10556059Samurai /* 105628679Sbrian * Process on-demand dialup. Output packets are queued within tunnel 105728679Sbrian * device until IPCP is opened. 10586059Samurai */ 10596059Samurai if (LcpFsm.state <= ST_CLOSED && (mode & MODE_AUTO)) { 10607001Samurai pri = PacketCheck(rbuff, n, FL_DIAL); 10616059Samurai if (pri >= 0) { 106231343Sbrian#ifndef NOALIAS 106320365Sjkh if (mode & MODE_ALIAS) { 106426142Sbrian VarPacketAliasOut(rbuff, sizeof rbuff); 106528679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 106620365Sjkh } 106731343Sbrian#endif 10686059Samurai IpEnqueue(pri, rbuff, n); 106930715Sbrian dial_up = 1; /* XXX */ 10706059Samurai } 10716059Samurai continue; 10726059Samurai } 10737001Samurai pri = PacketCheck(rbuff, n, FL_OUT); 107420365Sjkh if (pri >= 0) { 107531343Sbrian#ifndef NOALIAS 107628679Sbrian if (mode & MODE_ALIAS) { 107728679Sbrian VarPacketAliasOut(rbuff, sizeof rbuff); 107828679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 107928679Sbrian } 108031343Sbrian#endif 10816059Samurai IpEnqueue(pri, rbuff, n); 108220365Sjkh } 10836059Samurai } 10846059Samurai } 108526516Sbrian LogPrintf(LogDEBUG, "Job (DoLoop) done.\n"); 10866059Samurai} 1087