main.c revision 31196
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 * 2031196Sbrian * $Id: main.c,v 1.99 1997/11/16 22:15:05 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> 3631195Sbrian#include <net/if_var.h> 3731195Sbrian#include <net/if_tun.h> 3830715Sbrian 3930715Sbrian#include <errno.h> 406059Samurai#include <fcntl.h> 4111336Samurai#include <paths.h> 4230715Sbrian#include <signal.h> 4330715Sbrian#include <stdio.h> 4430715Sbrian#include <stdlib.h> 4530715Sbrian#include <string.h> 466059Samurai#include <sys/time.h> 4730715Sbrian#include <sys/wait.h> 4830715Sbrian#include <sysexits.h> 496059Samurai#include <termios.h> 5018786Sjkh#include <unistd.h> 5130715Sbrian 5230715Sbrian#include "mbuf.h" 5330715Sbrian#include "log.h" 5430715Sbrian#include "defs.h" 5531061Sbrian#include "id.h" 5630715Sbrian#include "timer.h" 5730715Sbrian#include "fsm.h" 586059Samurai#include "modem.h" 596059Samurai#include "os.h" 606059Samurai#include "hdlc.h" 6113389Sphk#include "ccp.h" 626059Samurai#include "lcp.h" 636059Samurai#include "ipcp.h" 6426142Sbrian#include "loadalias.h" 6530715Sbrian#include "command.h" 666059Samurai#include "vars.h" 676735Samurai#include "auth.h" 687001Samurai#include "filter.h" 6913389Sphk#include "systems.h" 7013389Sphk#include "ip.h" 7123840Sbrian#include "sig.h" 7226940Sbrian#include "server.h" 7328536Sbrian#include "lcpproto.h" 7430715Sbrian#include "main.h" 7530715Sbrian#include "vjcomp.h" 7630715Sbrian#include "async.h" 7731158Sbrian#include "pathnames.h" 7831195Sbrian#include "tun.h" 796059Samurai 806735Samurai#ifndef O_NONBLOCK 816735Samurai#ifdef O_NDELAY 826735Samurai#define O_NONBLOCK O_NDELAY 836735Samurai#endif 846735Samurai#endif 856735Samurai 8630715Sbrianint TermMode = 0; 8730715Sbrianint tunno = 0; 886059Samurai 8928679Sbrianstatic struct termios oldtio; /* Original tty mode */ 9028679Sbrianstatic struct termios comtio; /* Command level tty mode */ 9120813Sjkhstatic pid_t BGPid = 0; 9225634Sbrianstatic char pid_filename[MAXPATHLEN]; 9327061Sbrianstatic int dial_up; 946059Samurai 9530715Sbrianstatic void DoLoop(void); 9630715Sbrianstatic void TerminalStop(int); 9730715Sbrianstatic char *ex_desc(int); 9830715Sbrian 996059Samuraistatic void 10026858SbrianTtyInit(int DontWantInt) 1016059Samurai{ 1026059Samurai struct termios newtio; 1036059Samurai int stat; 1046059Samurai 1056059Samurai stat = fcntl(0, F_GETFL, 0); 10625630Sbrian if (stat > 0) { 10728679Sbrian stat |= O_NONBLOCK; 10828679Sbrian (void) fcntl(0, F_SETFL, stat); 10925630Sbrian } 1106059Samurai newtio = oldtio; 11128679Sbrian newtio.c_lflag &= ~(ECHO | ISIG | ICANON); 1126059Samurai newtio.c_iflag = 0; 1136059Samurai newtio.c_oflag &= ~OPOST; 1146059Samurai newtio.c_cc[VEOF] = _POSIX_VDISABLE; 11526858Sbrian if (DontWantInt) 11626858Sbrian newtio.c_cc[VINTR] = _POSIX_VDISABLE; 1176059Samurai newtio.c_cc[VMIN] = 1; 1186059Samurai newtio.c_cc[VTIME] = 0; 1196059Samurai newtio.c_cflag |= CS8; 1206735Samurai tcsetattr(0, TCSADRAIN, &newtio); 1216059Samurai comtio = newtio; 1226059Samurai} 1236059Samurai 1246059Samurai/* 1256059Samurai * Set tty into command mode. We allow canonical input and echo processing. 1266059Samurai */ 12710528Samuraivoid 12828679SbrianTtyCommandMode(int prompt) 1296059Samurai{ 1306059Samurai struct termios newtio; 1316059Samurai int stat; 1326059Samurai 1336059Samurai if (!(mode & MODE_INTER)) 1346059Samurai return; 1356735Samurai tcgetattr(0, &newtio); 13628679Sbrian newtio.c_lflag |= (ECHO | ISIG | ICANON); 1376059Samurai newtio.c_iflag = oldtio.c_iflag; 1386059Samurai newtio.c_oflag |= OPOST; 1396735Samurai tcsetattr(0, TCSADRAIN, &newtio); 1406059Samurai stat = fcntl(0, F_GETFL, 0); 14125630Sbrian if (stat > 0) { 14228679Sbrian stat |= O_NONBLOCK; 14328679Sbrian (void) fcntl(0, F_SETFL, stat); 14425630Sbrian } 1456059Samurai TermMode = 0; 14628679Sbrian if (prompt) 14728679Sbrian Prompt(); 1486059Samurai} 1496059Samurai 1506059Samurai/* 1516059Samurai * Set tty into terminal mode which is used while we invoke term command. 1526059Samurai */ 1536059Samuraivoid 1546059SamuraiTtyTermMode() 1556059Samurai{ 1566059Samurai int stat; 1576059Samurai 1586735Samurai tcsetattr(0, TCSADRAIN, &comtio); 1596059Samurai stat = fcntl(0, F_GETFL, 0); 16025630Sbrian if (stat > 0) { 16128679Sbrian stat &= ~O_NONBLOCK; 16228679Sbrian (void) fcntl(0, F_SETFL, stat); 16325630Sbrian } 1646059Samurai TermMode = 1; 1656059Samurai} 1666059Samurai 1676059Samuraivoid 16810528SamuraiTtyOldMode() 1696059Samurai{ 1706059Samurai int stat; 1716059Samurai 1726059Samurai stat = fcntl(0, F_GETFL, 0); 17325630Sbrian if (stat > 0) { 17428679Sbrian stat &= ~O_NONBLOCK; 17528679Sbrian (void) fcntl(0, F_SETFL, stat); 17625630Sbrian } 1776735Samurai tcsetattr(0, TCSANOW, &oldtio); 17810528Samurai} 17910528Samurai 18010528Samuraivoid 18128679SbrianCleanup(int excode) 18210528Samurai{ 18331081Sbrian ServerClose(); 18430825Sbrian OsInterfaceDown(1); 18530825Sbrian HangupModem(1); 18630697Sbrian nointr_sleep(1); 18731121Sbrian DeleteIfRoutes(1); 18831061Sbrian ID0unlink(pid_filename); 18923863Sbrian if (mode & MODE_BACKGROUND && BGFiledes[1] != -1) { 19023863Sbrian char c = EX_ERRDEAD; 19128679Sbrian 19228679Sbrian if (write(BGFiledes[1], &c, 1) == 1) 19328679Sbrian LogPrintf(LogPHASE, "Parent notified of failure.\n"); 19423863Sbrian else 19528679Sbrian LogPrintf(LogPHASE, "Failed to notify parent of failure.\n"); 19623863Sbrian close(BGFiledes[1]); 19723863Sbrian } 19828679Sbrian LogPrintf(LogPHASE, "PPP Terminated (%s).\n", ex_desc(excode)); 19910528Samurai TtyOldMode(); 20031061Sbrian LogClose(); 2016059Samurai 2026059Samurai exit(excode); 2036059Samurai} 2046059Samurai 2056059Samuraistatic void 20628679SbrianCloseConnection(int signo) 2076059Samurai{ 20826858Sbrian /* NOTE, these are manual, we've done a setsid() */ 20931121Sbrian pending_signal(SIGINT, SIG_IGN); 21027157Sbrian LogPrintf(LogPHASE, "Caught signal %d, abort connection\n", signo); 21128679Sbrian reconnectState = RECON_FALSE; 21228684Sbrian reconnectCount = 0; 21328684Sbrian DownConnection(); 21430715Sbrian dial_up = 0; 21531121Sbrian pending_signal(SIGINT, CloseConnection); 2166059Samurai} 2176059Samurai 2186059Samuraistatic void 21928679SbrianCloseSession(int signo) 2206059Samurai{ 22128679Sbrian if (BGPid) { 22228679Sbrian kill(BGPid, SIGINT); 22328679Sbrian exit(EX_TERM); 22428679Sbrian } 22528679Sbrian LogPrintf(LogPHASE, "Signal %d, terminate.\n", signo); 22628679Sbrian reconnect(RECON_FALSE); 22728679Sbrian LcpClose(); 22828679Sbrian Cleanup(EX_TERM); 2296059Samurai} 2306059Samurai 23110528Samuraistatic void 23210528SamuraiTerminalCont() 23310528Samurai{ 23423840Sbrian pending_signal(SIGCONT, SIG_DFL); 23523840Sbrian pending_signal(SIGTSTP, TerminalStop); 23610528Samurai TtyCommandMode(getpgrp() == tcgetpgrp(0)); 23710528Samurai} 23810528Samurai 23910528Samuraistatic void 24028679SbrianTerminalStop(int signo) 24110528Samurai{ 24223840Sbrian pending_signal(SIGCONT, TerminalCont); 24310528Samurai TtyOldMode(); 24423840Sbrian pending_signal(SIGTSTP, SIG_DFL); 24510528Samurai kill(getpid(), signo); 24610528Samurai} 24710528Samurai 24826940Sbrianstatic void 24928679SbrianSetUpServer(int signo) 25026940Sbrian{ 25126940Sbrian int res; 25228679Sbrian 25331081Sbrian VarHaveLocalAuthKey = 0; 25431081Sbrian LocalAuthInit(); 25528679Sbrian if ((res = ServerTcpOpen(SERVER_PORT + tunno)) != 0) 25629083Sbrian LogPrintf(LogERROR, "SIGUSR1: Failed %d to open port %d\n", 25729083Sbrian res, SERVER_PORT + tunno); 25826940Sbrian} 25926940Sbrian 26031081Sbrianstatic void 26131081SbrianBringDownServer(int signo) 26231081Sbrian{ 26331081Sbrian VarHaveLocalAuthKey = 0; 26431081Sbrian LocalAuthInit(); 26531081Sbrian ServerClose(); 26631081Sbrian} 26731081Sbrian 26825908Sbrianstatic char * 26925908Sbrianex_desc(int ex) 27025908Sbrian{ 27125908Sbrian static char num[12]; 27228679Sbrian static char *desc[] = {"normal", "start", "sock", 27325908Sbrian "modem", "dial", "dead", "done", "reboot", "errdead", 27428679Sbrian "hangup", "term", "nodial", "nologin"}; 27510528Samurai 27628679Sbrian if (ex >= 0 && ex < sizeof(desc) / sizeof(*desc)) 27725908Sbrian return desc[ex]; 27825908Sbrian snprintf(num, sizeof num, "%d", ex); 27925908Sbrian return num; 28025908Sbrian} 28125908Sbrian 28230715Sbrianstatic void 2836059SamuraiUsage() 2846059Samurai{ 28520120Snate fprintf(stderr, 28628679Sbrian "Usage: ppp [-auto | -background | -direct | -dedicated | -ddial ] [ -alias ] [system]\n"); 2876059Samurai exit(EX_START); 2886059Samurai} 2896059Samurai 29030715Sbrianstatic void 2916059SamuraiProcessArgs(int argc, char **argv) 2926059Samurai{ 2936059Samurai int optc; 2946059Samurai char *cp; 2956059Samurai 2966059Samurai optc = 0; 29731121Sbrian mode = MODE_INTER; 2986059Samurai while (argc > 0 && **argv == '-') { 2996059Samurai cp = *argv + 1; 30031121Sbrian if (strcmp(cp, "auto") == 0) { 3016059Samurai mode |= MODE_AUTO; 30231121Sbrian mode &= ~MODE_INTER; 30331121Sbrian } else if (strcmp(cp, "background") == 0) { 30431121Sbrian mode |= MODE_BACKGROUND; 30531121Sbrian mode &= ~MODE_INTER; 30631121Sbrian } else if (strcmp(cp, "direct") == 0) { 3076059Samurai mode |= MODE_DIRECT; 30831121Sbrian mode &= ~MODE_INTER; 30931121Sbrian } else if (strcmp(cp, "dedicated") == 0) { 3106059Samurai mode |= MODE_DEDICATED; 31131121Sbrian mode &= ~MODE_INTER; 31231121Sbrian } else if (strcmp(cp, "ddial") == 0) { 31331121Sbrian mode |= MODE_DDIAL; 31431121Sbrian mode &= ~MODE_INTER; 31531121Sbrian } else if (strcmp(cp, "alias") == 0) { 31626142Sbrian if (loadAliasHandlers(&VarAliasHandlers) == 0) 31728679Sbrian mode |= MODE_ALIAS; 31826142Sbrian else 31928679Sbrian LogPrintf(LogWARN, "Cannot load alias library\n"); 32028679Sbrian optc--; /* this option isn't exclusive */ 32128679Sbrian } else 3226059Samurai Usage(); 3236059Samurai optc++; 32428679Sbrian argv++; 32528679Sbrian argc--; 3266059Samurai } 3276059Samurai if (argc > 1) { 3286059Samurai fprintf(stderr, "specify only one system label.\n"); 3296059Samurai exit(EX_START); 3306059Samurai } 33128679Sbrian if (argc == 1) 33231121Sbrian SetLabel(*argv); 3336059Samurai 3346059Samurai if (optc > 1) { 3356059Samurai fprintf(stderr, "specify only one mode.\n"); 3366059Samurai exit(EX_START); 3376059Samurai } 3386059Samurai} 3396059Samurai 3406059Samuraistatic void 3416059SamuraiGreetings() 3426059Samurai{ 34326516Sbrian if (VarTerm) { 34426516Sbrian fprintf(VarTerm, "User Process PPP. Written by Toshiharu OHNO.\n"); 34526516Sbrian fflush(VarTerm); 34626516Sbrian } 3476059Samurai} 3486059Samurai 34926940Sbrianint 35028679Sbrianmain(int argc, char **argv) 3516059Samurai{ 35225707Sbrian FILE *lockfile; 35326516Sbrian char *name; 35426516Sbrian 35526551Sbrian VarTerm = 0; 35630715Sbrian name = strrchr(argv[0], '/'); 35728679Sbrian LogOpen(name ? name + 1 : argv[0]); 35826516Sbrian 35928679Sbrian argc--; 36028679Sbrian argv++; 3616059Samurai ProcessArgs(argc, argv); 36231121Sbrian if (!(mode & MODE_DIRECT)) 36326551Sbrian VarTerm = stdout; 36431121Sbrian 36531121Sbrian ID0init(); 36631158Sbrian if (ID0realuid() != 0) { 36731158Sbrian char conf[200], *ptr; 36831158Sbrian 36931158Sbrian snprintf(conf, sizeof conf, "%s/%s", _PATH_PPP, CONFFILE); 37031158Sbrian do { 37131158Sbrian if (!access(conf, W_OK)) { 37231158Sbrian LogPrintf(LogALERT, "ppp: Access violation: Please protect %s\n", conf); 37331158Sbrian return -1; 37431158Sbrian } 37531158Sbrian ptr = conf + strlen(conf)-2; 37631158Sbrian while (ptr > conf && *ptr != '/') 37731158Sbrian *ptr-- = '\0'; 37831158Sbrian } while (ptr >= conf); 37931158Sbrian } 38031158Sbrian 38131121Sbrian if (!ValidSystem(GetLabel())) { 38231121Sbrian fprintf(stderr, "You may not use ppp in this mode with this label\n"); 38331157Sbrian if (mode & MODE_DIRECT) { 38431157Sbrian const char *l; 38531157Sbrian if ((l = GetLabel()) == NULL) 38631157Sbrian l = "default"; 38731157Sbrian VarTerm = 0; 38831157Sbrian LogPrintf(LogWARN, "Label %s rejected -direct connection\n", l); 38931157Sbrian } 39031157Sbrian LogClose(); 39131121Sbrian return 1; 39229083Sbrian } 39331121Sbrian 39431196Sbrian if (!GetShortHost()) 39531196Sbrian return 1; 39626551Sbrian Greetings(); 3976059Samurai IpcpDefAddress(); 3986059Samurai 39926516Sbrian if (SelectSystem("default", CONFFILE) < 0 && VarTerm) 40026516Sbrian fprintf(VarTerm, "Warning: No default entry is given in config file.\n"); 4016059Samurai 4026059Samurai if (OpenTunnel(&tunno) < 0) { 40326940Sbrian LogPrintf(LogWARN, "open_tun: %s\n", strerror(errno)); 40426940Sbrian return EX_START; 4056059Samurai } 4066059Samurai if (mode & MODE_INTER) { 40726516Sbrian fprintf(VarTerm, "Interactive mode\n"); 40826690Sbrian netfd = STDOUT_FILENO; 40931121Sbrian } else if ((mode & MODE_OUTGOING_DAEMON) && !(mode & MODE_DEDICATED)) 41031121Sbrian if (GetLabel() == NULL) { 41126516Sbrian if (VarTerm) 41228679Sbrian fprintf(VarTerm, "Destination system must be specified in" 41328679Sbrian " auto, background or ddial mode.\n"); 41426940Sbrian return EX_START; 4156059Samurai } 41631121Sbrian 41728679Sbrian tcgetattr(0, &oldtio); /* Save original tty mode */ 4186059Samurai 41927157Sbrian pending_signal(SIGHUP, CloseSession); 42023840Sbrian pending_signal(SIGTERM, CloseSession); 42127157Sbrian pending_signal(SIGINT, CloseConnection); 42223840Sbrian pending_signal(SIGQUIT, CloseSession); 4236735Samurai#ifdef SIGPIPE 42424753Sache signal(SIGPIPE, SIG_IGN); 4256735Samurai#endif 4266735Samurai#ifdef SIGALRM 42723840Sbrian pending_signal(SIGALRM, SIG_IGN); 4286735Samurai#endif 42928679Sbrian if (mode & MODE_INTER) { 43010528Samurai#ifdef SIGTSTP 43126940Sbrian pending_signal(SIGTSTP, TerminalStop); 43210528Samurai#endif 43310528Samurai#ifdef SIGTTIN 43426940Sbrian pending_signal(SIGTTIN, TerminalStop); 43510528Samurai#endif 43610528Samurai#ifdef SIGTTOU 43726940Sbrian pending_signal(SIGTTOU, SIG_IGN); 43810528Samurai#endif 43926940Sbrian } 44031121Sbrian if (!(mode & MODE_INTER)) { 44126940Sbrian#ifdef SIGUSR1 44226940Sbrian pending_signal(SIGUSR1, SetUpServer); 44326940Sbrian#endif 44431081Sbrian#ifdef SIGUSR2 44531081Sbrian pending_signal(SIGUSR2, BringDownServer); 44631081Sbrian#endif 44731121Sbrian } 4486059Samurai 44931121Sbrian if (GetLabel()) { 45031121Sbrian if (SelectSystem(GetLabel(), CONFFILE) < 0) { 45131154Sbrian LogPrintf(LogWARN, "Destination system %s not found in conf file.\n", 45231154Sbrian GetLabel()); 4536059Samurai Cleanup(EX_START); 4546059Samurai } 45531121Sbrian if (mode & MODE_OUTGOING_DAEMON && 45631121Sbrian DefHisAddress.ipaddr.s_addr == INADDR_ANY) { 45731154Sbrian LogPrintf(LogWARN, "You must \"set ifaddr\" in label %s for" 45831154Sbrian " auto, background or ddial mode.\n", GetLabel()); 4596059Samurai Cleanup(EX_START); 4606059Samurai } 4616059Samurai } 46226940Sbrian 46331121Sbrian if (mode & MODE_DAEMON) { 46420813Sjkh if (mode & MODE_BACKGROUND) { 46528679Sbrian if (pipe(BGFiledes)) { 46628974Sbrian LogPrintf(LogERROR, "pipe: %s\n", strerror(errno)); 46720813Sjkh Cleanup(EX_SOCK); 46820813Sjkh } 4696059Samurai } 4706059Samurai 4716059Samurai if (!(mode & MODE_DIRECT)) { 47220813Sjkh pid_t bgpid; 47311336Samurai 47428679Sbrian bgpid = fork(); 47520813Sjkh if (bgpid == -1) { 47628974Sbrian LogPrintf(LogERROR, "fork: %s\n", strerror(errno)); 47728679Sbrian Cleanup(EX_SOCK); 47820813Sjkh } 47920813Sjkh if (bgpid) { 48020813Sjkh char c = EX_NORMAL; 48111336Samurai 48220813Sjkh if (mode & MODE_BACKGROUND) { 48320813Sjkh /* Wait for our child to close its pipe before we exit. */ 48420813Sjkh BGPid = bgpid; 48528679Sbrian close(BGFiledes[1]); 48625908Sbrian if (read(BGFiledes[0], &c, 1) != 1) { 48726516Sbrian fprintf(VarTerm, "Child exit, no status.\n"); 48828679Sbrian LogPrintf(LogPHASE, "Parent: Child exit, no status.\n"); 48925908Sbrian } else if (c == EX_NORMAL) { 49026516Sbrian fprintf(VarTerm, "PPP enabled.\n"); 49128679Sbrian LogPrintf(LogPHASE, "Parent: PPP enabled.\n"); 49225908Sbrian } else { 49328679Sbrian fprintf(VarTerm, "Child failed (%s).\n", ex_desc((int) c)); 49426516Sbrian LogPrintf(LogPHASE, "Parent: Child failed (%s).\n", 49528679Sbrian ex_desc((int) c)); 49628679Sbrian } 49728679Sbrian close(BGFiledes[0]); 49820813Sjkh } 49928679Sbrian return c; 50023863Sbrian } else if (mode & MODE_BACKGROUND) 50128679Sbrian close(BGFiledes[0]); 50225707Sbrian } 50320813Sjkh 50428679Sbrian VarTerm = 0; /* We know it's currently stdout */ 50529551Sbrian close(1); 50626686Sbrian close(2); 50726551Sbrian 50826686Sbrian if (mode & MODE_DIRECT) 50926858Sbrian TtyInit(1); 51031121Sbrian else if (mode & MODE_DAEMON) { 51126686Sbrian setsid(); 51229551Sbrian close(0); 51326686Sbrian } 5146059Samurai } else { 51526858Sbrian TtyInit(0); 51610528Samurai TtyCommandMode(1); 5176059Samurai } 51829696Sbrian 51929696Sbrian snprintf(pid_filename, sizeof(pid_filename), "%stun%d.pid", 52029696Sbrian _PATH_VARRUN, tunno); 52131061Sbrian lockfile = ID0fopen(pid_filename, "w"); 52231061Sbrian if (lockfile != NULL) { 52329696Sbrian fprintf(lockfile, "%d\n", (int) getpid()); 52429696Sbrian fclose(lockfile); 52529696Sbrian } else 52629696Sbrian LogPrintf(LogALERT, "Warning: Can't create %s: %s\n", 52729696Sbrian pid_filename, strerror(errno)); 52829696Sbrian 52926516Sbrian LogPrintf(LogPHASE, "PPP Started.\n"); 5306059Samurai 5316059Samurai 5326059Samurai do 53328679Sbrian DoLoop(); 5346059Samurai while (mode & MODE_DEDICATED); 5356059Samurai 5366059Samurai Cleanup(EX_DONE); 53726940Sbrian return 0; 5386059Samurai} 5396059Samurai 5406059Samurai/* 54120813Sjkh * Turn into packet mode, where we speak PPP. 5426059Samurai */ 5436059Samuraivoid 5446059SamuraiPacketMode() 5456059Samurai{ 54631034Sbrian if (RawModem() < 0) { 54726516Sbrian LogPrintf(LogWARN, "PacketMode: Not connected.\n"); 5486059Samurai return; 5496059Samurai } 5506059Samurai AsyncInit(); 55130187Sbrian VjInit(15); 5526059Samurai LcpInit(); 5536059Samurai IpcpInit(); 5546059Samurai CcpInit(); 5556059Samurai LcpUp(); 5566059Samurai 55725872Sbrian LcpOpen(VarOpenMode); 55831121Sbrian if (mode & MODE_INTER) 55910528Samurai TtyCommandMode(1); 56031121Sbrian if (VarTerm) { 56131121Sbrian fprintf(VarTerm, "Packet mode.\n"); 56231121Sbrian aft_cmd = 1; 5636059Samurai } 5646059Samurai} 5656059Samurai 5666059Samuraistatic void 5676059SamuraiShowHelp() 5686059Samurai{ 56926901Sbrian fprintf(stderr, "The following commands are available:\r\n"); 57026901Sbrian fprintf(stderr, " ~p\tEnter Packet mode\r\n"); 57126901Sbrian fprintf(stderr, " ~-\tDecrease log level\r\n"); 57226901Sbrian fprintf(stderr, " ~+\tIncrease log level\r\n"); 57326901Sbrian fprintf(stderr, " ~t\tShow timers (only in \"log debug\" mode)\r\n"); 57426901Sbrian fprintf(stderr, " ~m\tShow memory map (only in \"log debug\" mode)\r\n"); 57526901Sbrian fprintf(stderr, " ~.\tTerminate program\r\n"); 57626901Sbrian fprintf(stderr, " ~?\tThis help\r\n"); 5776059Samurai} 5786059Samurai 5796059Samuraistatic void 5806059SamuraiReadTty() 5816059Samurai{ 5826059Samurai int n; 5836059Samurai char ch; 5846059Samurai static int ttystate; 58526516Sbrian FILE *oVarTerm; 58631070Sbrian char linebuff[LINE_LEN]; 58728679Sbrian 58826516Sbrian LogPrintf(LogDEBUG, "termode = %d, netfd = %d, mode = %d\n", 58928679Sbrian TermMode, netfd, mode); 5906059Samurai if (!TermMode) { 59128679Sbrian n = read(netfd, linebuff, sizeof(linebuff) - 1); 5926735Samurai if (n > 0) { 59326516Sbrian aft_cmd = 1; 59430913Sbrian if (linebuff[n-1] == '\n') 59530913Sbrian linebuff[--n] = '\0'; 59631156Sbrian if (n) 59731156Sbrian DecodeCommand(linebuff, n, IsInteractive(0) ? NULL : "Client"); 59831156Sbrian Prompt(); 5996735Samurai } else { 60026516Sbrian LogPrintf(LogPHASE, "client connection closed.\n"); 60126516Sbrian oVarTerm = VarTerm; 60226516Sbrian VarTerm = 0; 60326516Sbrian if (oVarTerm && oVarTerm != stdout) 60428679Sbrian fclose(oVarTerm); 6056059Samurai close(netfd); 6066059Samurai netfd = -1; 6076059Samurai } 6086059Samurai return; 6096059Samurai } 6106059Samurai 6116059Samurai /* 61228679Sbrian * We are in terminal mode, decode special sequences 6136059Samurai */ 61426516Sbrian n = read(fileno(VarTerm), &ch, 1); 61528974Sbrian LogPrintf(LogDEBUG, "Got %d bytes (reading from the terminal)\n", n); 6166059Samurai 6176059Samurai if (n > 0) { 6186059Samurai switch (ttystate) { 6196059Samurai case 0: 6206059Samurai if (ch == '~') 6216059Samurai ttystate++; 6226059Samurai else 6236059Samurai write(modem, &ch, n); 6246059Samurai break; 6256059Samurai case 1: 6266059Samurai switch (ch) { 6276059Samurai case '?': 6286059Samurai ShowHelp(); 6296059Samurai break; 6306059Samurai case 'p': 63128679Sbrian 6326059Samurai /* 6336059Samurai * XXX: Should check carrier. 6346059Samurai */ 6356059Samurai if (LcpFsm.state <= ST_CLOSED) { 6366059Samurai VarOpenMode = OPEN_ACTIVE; 6376059Samurai PacketMode(); 6386059Samurai } 6396059Samurai break; 6406059Samurai case '.': 6416059Samurai TermMode = 1; 64226516Sbrian aft_cmd = 1; 64310528Samurai TtyCommandMode(1); 6446059Samurai break; 64526516Sbrian case 't': 64626516Sbrian if (LogIsKept(LogDEBUG)) { 64726516Sbrian ShowTimers(); 64826516Sbrian break; 64926516Sbrian } 65026516Sbrian case 'm': 65126516Sbrian if (LogIsKept(LogDEBUG)) { 65226516Sbrian ShowMemMap(); 65326516Sbrian break; 65426516Sbrian } 6556059Samurai default: 6566059Samurai if (write(modem, &ch, n) < 0) 65726516Sbrian LogPrintf(LogERROR, "error writing to modem.\n"); 6586059Samurai break; 6596059Samurai } 6606059Samurai ttystate = 0; 6616059Samurai break; 6626059Samurai } 6636059Samurai } 6646059Samurai} 6656059Samurai 6666059Samurai 6676059Samurai/* 6686059Samurai * Here, we'll try to detect HDLC frame 6696059Samurai */ 6706059Samurai 6716059Samuraistatic char *FrameHeaders[] = { 6726735Samurai "\176\377\003\300\041", 6736735Samurai "\176\377\175\043\300\041", 6746735Samurai "\176\177\175\043\100\041", 6756735Samurai "\176\175\337\175\043\300\041", 6766735Samurai "\176\175\137\175\043\100\041", 6776059Samurai NULL, 6786059Samurai}; 6796059Samurai 68030715Sbrianstatic u_char * 68128679SbrianHdlcDetect(u_char * cp, int n) 6826059Samurai{ 6836735Samurai char *ptr, *fp, **hp; 6846059Samurai 68528679Sbrian cp[n] = '\0'; /* be sure to null terminated */ 6866059Samurai ptr = NULL; 6876059Samurai for (hp = FrameHeaders; *hp; hp++) { 6886735Samurai fp = *hp; 6896735Samurai if (DEV_IS_SYNC) 6906735Samurai fp++; 69128679Sbrian ptr = strstr((char *) cp, fp); 69213389Sphk if (ptr) 6936059Samurai break; 6946059Samurai } 69528679Sbrian return ((u_char *) ptr); 6966059Samurai} 6976059Samurai 6986059Samuraistatic struct pppTimer RedialTimer; 6996059Samurai 7006059Samuraistatic void 7016059SamuraiRedialTimeout() 7026059Samurai{ 7036059Samurai StopTimer(&RedialTimer); 70426516Sbrian LogPrintf(LogPHASE, "Redialing timer expired.\n"); 7056059Samurai} 7066059Samurai 7076059Samuraistatic void 70828679SbrianStartRedialTimer(int Timeout) 7096059Samurai{ 7106059Samurai StopTimer(&RedialTimer); 71111336Samurai 71224939Sbrian if (Timeout) { 71311336Samurai RedialTimer.state = TIMER_STOPPED; 71411336Samurai 71524939Sbrian if (Timeout > 0) 71628679Sbrian RedialTimer.load = Timeout * SECTICKS; 71711336Samurai else 71828679Sbrian RedialTimer.load = (random() % REDIAL_PERIOD) * SECTICKS; 71911336Samurai 72026516Sbrian LogPrintf(LogPHASE, "Enter pause (%d) for redialing.\n", 72124939Sbrian RedialTimer.load / SECTICKS); 72224939Sbrian 72311336Samurai RedialTimer.func = RedialTimeout; 72411336Samurai StartTimer(&RedialTimer); 72511336Samurai } 7266059Samurai} 7276059Samurai 7286059Samurai 7296059Samuraistatic void 7306059SamuraiDoLoop() 7316059Samurai{ 7326059Samurai fd_set rfds, wfds, efds; 73323598Sache int pri, i, n, wfd, nfds; 7346059Samurai struct sockaddr_in hisaddr; 7356059Samurai struct timeval timeout, *tp; 7366059Samurai int ssize = sizeof(hisaddr); 7376059Samurai u_char *cp; 73811336Samurai int tries; 7399448Samurai int qlen; 74026858Sbrian int res; 74110528Samurai pid_t pgroup; 74231195Sbrian struct tun_data tun; 74331195Sbrian#define rbuff tun.data 7446059Samurai 74510528Samurai pgroup = getpgrp(); 74610528Samurai 74725908Sbrian if (mode & MODE_DIRECT) { 74826551Sbrian LogPrintf(LogDEBUG, "Opening modem\n"); 74931034Sbrian if (OpenModem() < 0) 75029521Sbrian return; 75126516Sbrian LogPrintf(LogPHASE, "Packet mode enabled\n"); 7526059Samurai PacketMode(); 7536059Samurai } else if (mode & MODE_DEDICATED) { 75423598Sache if (modem < 0) 75531034Sbrian while (OpenModem() < 0) 75630697Sbrian nointr_sleep(VarReconnectTimer); 7576059Samurai } 75826516Sbrian fflush(VarTerm); 7596059Samurai 7607001Samurai timeout.tv_sec = 0; 7616059Samurai timeout.tv_usec = 0; 76226098Sbrian reconnectState = RECON_UNKNOWN; 7636059Samurai 76423863Sbrian if (mode & MODE_BACKGROUND) 76530715Sbrian dial_up = 1; /* Bring the line up */ 76623863Sbrian else 76730715Sbrian dial_up = 0; /* XXXX */ 76811336Samurai tries = 0; 7696059Samurai for (;;) { 77023598Sache nfds = 0; 77128679Sbrian FD_ZERO(&rfds); 77228679Sbrian FD_ZERO(&wfds); 77328679Sbrian FD_ZERO(&efds); 7747001Samurai 77528679Sbrian /* 77628679Sbrian * If the link is down and we're in DDIAL mode, bring it back up. 77720120Snate */ 77820120Snate if (mode & MODE_DDIAL && LcpFsm.state <= ST_CLOSED) 77930715Sbrian dial_up = 1; 78020120Snate 78125067Sbrian /* 78228679Sbrian * If we lost carrier and want to re-establish the connection due to the 78328679Sbrian * "set reconnect" value, we'd better bring the line back up. 78425067Sbrian */ 78525908Sbrian if (LcpFsm.state <= ST_CLOSED) { 78630715Sbrian if (!dial_up && reconnectState == RECON_TRUE) { 78728679Sbrian if (++reconnectCount <= VarReconnectTries) { 78828679Sbrian LogPrintf(LogPHASE, "Connection lost, re-establish (%d/%d)\n", 78928679Sbrian reconnectCount, VarReconnectTries); 79025908Sbrian StartRedialTimer(VarReconnectTimer); 79130715Sbrian dial_up = 1; 79228679Sbrian } else { 79328679Sbrian if (VarReconnectTries) 79428679Sbrian LogPrintf(LogPHASE, "Connection lost, maximum (%d) times\n", 79528679Sbrian VarReconnectTries); 79628679Sbrian reconnectCount = 0; 79728679Sbrian if (mode & MODE_BACKGROUND) 79828679Sbrian Cleanup(EX_DEAD); 79928679Sbrian } 80028679Sbrian reconnectState = RECON_ENVOKED; 80131121Sbrian } else if (mode & MODE_DEDICATED) 80231121Sbrian if (VarOpenMode == OPEN_ACTIVE) 80331121Sbrian PacketMode(); 80425908Sbrian } 80525067Sbrian 80628679Sbrian /* 80728679Sbrian * If Ip packet for output is enqueued and require dial up, Just do it! 80828679Sbrian */ 80928679Sbrian if (dial_up && RedialTimer.state != TIMER_RUNNING) { 81026516Sbrian LogPrintf(LogDEBUG, "going to dial: modem = %d\n", modem); 81131034Sbrian if (OpenModem() < 0) { 81228679Sbrian tries++; 81328679Sbrian if (!(mode & MODE_DDIAL) && VarDialTries) 81428679Sbrian LogPrintf(LogCHAT, "Failed to open modem (attempt %u of %d)\n", 81528679Sbrian tries, VarDialTries); 81628679Sbrian else 81728679Sbrian LogPrintf(LogCHAT, "Failed to open modem (attempt %u)\n", tries); 81826551Sbrian 81926696Sbrian if (!(mode & MODE_DDIAL) && VarDialTries && tries >= VarDialTries) { 82026551Sbrian if (mode & MODE_BACKGROUND) 82128679Sbrian Cleanup(EX_DIAL); /* Can't get the modem */ 82230715Sbrian dial_up = 0; 82328679Sbrian reconnectState = RECON_UNKNOWN; 82428679Sbrian reconnectCount = 0; 82526551Sbrian tries = 0; 82628679Sbrian } else 82726551Sbrian StartRedialTimer(VarRedialTimeout); 82811336Samurai } else { 82928679Sbrian tries++; /* Tries are per number, not per list of 83028679Sbrian * numbers. */ 83128679Sbrian if (!(mode & MODE_DDIAL) && VarDialTries) 83226696Sbrian LogPrintf(LogCHAT, "Dial attempt %u of %d\n", tries, VarDialTries); 83328679Sbrian else 83428679Sbrian LogPrintf(LogCHAT, "Dial attempt %u\n", tries); 83526696Sbrian 83626858Sbrian if ((res = DialModem()) == EX_DONE) { 83730697Sbrian nointr_sleep(1); /* little pause to allow peer starts */ 83811336Samurai ModemTimeout(); 83911336Samurai PacketMode(); 84030715Sbrian dial_up = 0; 84128679Sbrian reconnectState = RECON_UNKNOWN; 84211336Samurai tries = 0; 84311336Samurai } else { 84424844Sbrian if (mode & MODE_BACKGROUND) { 84526858Sbrian if (VarNextPhone == NULL || res == EX_SIG) 84628679Sbrian Cleanup(EX_DIAL); /* Tried all numbers - no luck */ 84724844Sbrian else 84824939Sbrian /* Try all numbers in background mode */ 84924939Sbrian StartRedialTimer(VarRedialNextTimeout); 85026858Sbrian } else if (!(mode & MODE_DDIAL) && 85128679Sbrian ((VarDialTries && tries >= VarDialTries) || 85228679Sbrian res == EX_SIG)) { 85324843Sbrian /* I give up ! Can't get through :( */ 85424939Sbrian StartRedialTimer(VarRedialTimeout); 85530715Sbrian dial_up = 0; 85628679Sbrian reconnectState = RECON_UNKNOWN; 85728679Sbrian reconnectCount = 0; 85824843Sbrian tries = 0; 85924843Sbrian } else if (VarNextPhone == NULL) 86024843Sbrian /* Dial failed. Keep quite during redial wait period. */ 86124939Sbrian StartRedialTimer(VarRedialTimeout); 86224843Sbrian else 86324939Sbrian StartRedialTimer(VarRedialNextTimeout); 86411336Samurai } 86511336Samurai } 8667001Samurai } 8679448Samurai qlen = ModemQlen(); 86813733Sdfr 86913733Sdfr if (qlen == 0) { 87013733Sdfr IpStartOutput(); 87113733Sdfr qlen = ModemQlen(); 87213733Sdfr } 87323598Sache if (modem >= 0) { 87423598Sache if (modem + 1 > nfds) 87523598Sache nfds = modem + 1; 8767001Samurai FD_SET(modem, &rfds); 8777001Samurai FD_SET(modem, &efds); 8789448Samurai if (qlen > 0) { 8797001Samurai FD_SET(modem, &wfds); 8807001Samurai } 8817001Samurai } 88223598Sache if (server >= 0) { 88323598Sache if (server + 1 > nfds) 88423598Sache nfds = server + 1; 88523598Sache FD_SET(server, &rfds); 88623598Sache } 8876059Samurai 88828679Sbrian /* 88928679Sbrian * *** IMPORTANT *** 89028679Sbrian * 89128679Sbrian * CPU is serviced every TICKUNIT micro seconds. This value must be chosen 89228679Sbrian * with great care. If this values is too big, it results loss of 89328679Sbrian * characters from modem and poor responce. If this values is too small, 89428679Sbrian * ppp process eats many CPU time. 8956059Samurai */ 8966735Samurai#ifndef SIGALRM 89730697Sbrian nointr_usleep(TICKUNIT); 8986059Samurai TimerService(); 89923840Sbrian#else 90023840Sbrian handle_signals(); 9016735Samurai#endif 90210877Sbde 90310877Sbde /* If there are aren't many packets queued, look for some more. */ 90423598Sache if (qlen < 20 && tun_in >= 0) { 90523598Sache if (tun_in + 1 > nfds) 90623598Sache nfds = tun_in + 1; 90710877Sbde FD_SET(tun_in, &rfds); 90823598Sache } 90923598Sache if (netfd >= 0) { 91023598Sache if (netfd + 1 > nfds) 91123598Sache nfds = netfd + 1; 9126059Samurai FD_SET(netfd, &rfds); 9136059Samurai FD_SET(netfd, &efds); 9146059Samurai } 91528679Sbrian#ifndef SIGALRM 9167001Samurai 9176059Samurai /* 91828679Sbrian * Normally, select() will not block because modem is writable. In AUTO 91928679Sbrian * mode, select will block until we find packet from tun 9206059Samurai */ 92128679Sbrian tp = (RedialTimer.state == TIMER_RUNNING) ? &timeout : NULL; 92223598Sache i = select(nfds, &rfds, &wfds, &efds, tp); 9236735Samurai#else 92428679Sbrian 9258857Srgrimes /* 92628679Sbrian * When SIGALRM timer is running, a select function will be return -1 and 92728679Sbrian * EINTR after a Time Service signal hundler is done. If the redial 92828679Sbrian * timer is not running and we are trying to dial, poll with a 0 value 92928679Sbrian * timer. 9307001Samurai */ 93111336Samurai tp = (dial_up && RedialTimer.state != TIMER_RUNNING) ? &timeout : NULL; 93223598Sache i = select(nfds, &rfds, &wfds, &efds, tp); 9336735Samurai#endif 93422074Sbrian 93528679Sbrian if (i == 0) { 93628679Sbrian continue; 9376059Samurai } 93828679Sbrian if (i < 0) { 93928679Sbrian if (errno == EINTR) { 94028679Sbrian handle_signals(); 94128679Sbrian continue; 94228679Sbrian } 94328974Sbrian LogPrintf(LogERROR, "DoLoop: select(): %s\n", strerror(errno)); 94428679Sbrian break; 9458857Srgrimes } 94623598Sache if ((netfd >= 0 && FD_ISSET(netfd, &efds)) || (modem >= 0 && FD_ISSET(modem, &efds))) { 94726516Sbrian LogPrintf(LogALERT, "Exception detected.\n"); 9486059Samurai break; 9496059Samurai } 95023598Sache if (server >= 0 && FD_ISSET(server, &rfds)) { 95126516Sbrian LogPrintf(LogPHASE, "connected to client.\n"); 95228679Sbrian wfd = accept(server, (struct sockaddr *) & hisaddr, &ssize); 95324753Sache if (wfd < 0) { 95428974Sbrian LogPrintf(LogERROR, "DoLoop: accept(): %s\n", strerror(errno)); 95524753Sache continue; 95624753Sache } 95723598Sache if (netfd >= 0) { 9586059Samurai write(wfd, "already in use.\n", 16); 9596059Samurai close(wfd); 9606059Samurai continue; 9616059Samurai } else 9626059Samurai netfd = wfd; 96326516Sbrian VarTerm = fdopen(netfd, "a+"); 96431081Sbrian LocalAuthInit(); 9656059Samurai Greetings(); 96630913Sbrian IsInteractive(1); 96725630Sbrian Prompt(); 9686059Samurai } 96931121Sbrian if (netfd >= 0 && FD_ISSET(netfd, &rfds) && 97031121Sbrian ((mode & MODE_OUTGOING_DAEMON) || pgroup == tcgetpgrp(0))) { 9716059Samurai /* something to read from tty */ 9726059Samurai ReadTty(); 9736059Samurai } 97423598Sache if (modem >= 0) { 9756059Samurai if (FD_ISSET(modem, &wfds)) { /* ready to write into modem */ 97628679Sbrian ModemStartOutput(modem); 9776059Samurai } 9786059Samurai if (FD_ISSET(modem, &rfds)) { /* something to read from modem */ 9796735Samurai if (LcpFsm.state <= ST_CLOSED) 98030697Sbrian nointr_usleep(10000); 9816059Samurai n = read(modem, rbuff, sizeof(rbuff)); 9826059Samurai if ((mode & MODE_DIRECT) && n <= 0) { 9836059Samurai DownConnection(); 9846059Samurai } else 98528679Sbrian LogDumpBuff(LogASYNC, "ReadFromModem", rbuff, n); 9866059Samurai 9876059Samurai if (LcpFsm.state <= ST_CLOSED) { 98828679Sbrian 9896059Samurai /* 99028679Sbrian * In dedicated mode, we just discard input until LCP is started. 9916059Samurai */ 9926059Samurai if (!(mode & MODE_DEDICATED)) { 9936059Samurai cp = HdlcDetect(rbuff, n); 9946059Samurai if (cp) { 99528679Sbrian 9966059Samurai /* 9976059Samurai * LCP packet is detected. Turn ourselves into packet mode. 9986059Samurai */ 9996059Samurai if (cp != rbuff) { 100028679Sbrian write(modem, rbuff, cp - rbuff); 100128679Sbrian write(modem, "\r\n", 2); 10026059Samurai } 10036059Samurai PacketMode(); 10046059Samurai } else 100526516Sbrian write(fileno(VarTerm), rbuff, n); 10066059Samurai } 10076059Samurai } else { 10086059Samurai if (n > 0) 10096059Samurai AsyncInput(rbuff, n); 10106059Samurai } 10116059Samurai } 10126059Samurai } 101328679Sbrian if (tun_in >= 0 && FD_ISSET(tun_in, &rfds)) { /* something to read 101428679Sbrian * from tun */ 101531195Sbrian n = read(tun_in, &tun, sizeof(tun)); 10166059Samurai if (n < 0) { 101728974Sbrian LogPrintf(LogERROR, "read from tun: %s\n", strerror(errno)); 10186059Samurai continue; 10196059Samurai } 102031195Sbrian n -= sizeof(tun)-sizeof(tun.data); 102131195Sbrian if (n <= 0) { 102231195Sbrian LogPrintf(LogERROR, "read from tun: Only %d bytes read\n", n); 102331195Sbrian continue; 102431195Sbrian } 102531195Sbrian if (!tun_check_header(tun, AF_INET)) 102631195Sbrian continue; 102728679Sbrian if (((struct ip *) rbuff)->ip_dst.s_addr == IpcpInfo.want_ipaddr.s_addr) { 102828536Sbrian /* we've been asked to send something addressed *to* us :( */ 102928536Sbrian if (VarLoopback) { 103028536Sbrian pri = PacketCheck(rbuff, n, FL_IN); 103128536Sbrian if (pri >= 0) { 103228536Sbrian struct mbuf *bp; 103328679Sbrian 103428536Sbrian if (mode & MODE_ALIAS) { 103528536Sbrian VarPacketAliasIn(rbuff, sizeof rbuff); 103628679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 103728536Sbrian } 103828536Sbrian bp = mballoc(n, MB_IPIN); 103930715Sbrian memcpy(MBUF_CTOP(bp), rbuff, n); 104028536Sbrian IpInput(bp); 104128536Sbrian LogPrintf(LogDEBUG, "Looped back packet addressed to myself\n"); 104228536Sbrian } 104328536Sbrian continue; 104428679Sbrian } else 104528536Sbrian LogPrintf(LogDEBUG, "Oops - forwarding packet addressed to myself\n"); 104628536Sbrian } 104728536Sbrian 10486059Samurai /* 104928679Sbrian * Process on-demand dialup. Output packets are queued within tunnel 105028679Sbrian * device until IPCP is opened. 10516059Samurai */ 10526059Samurai if (LcpFsm.state <= ST_CLOSED && (mode & MODE_AUTO)) { 10537001Samurai pri = PacketCheck(rbuff, n, FL_DIAL); 10546059Samurai if (pri >= 0) { 105520365Sjkh if (mode & MODE_ALIAS) { 105626142Sbrian VarPacketAliasOut(rbuff, sizeof rbuff); 105728679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 105820365Sjkh } 10596059Samurai IpEnqueue(pri, rbuff, n); 106030715Sbrian dial_up = 1; /* XXX */ 10616059Samurai } 10626059Samurai continue; 10636059Samurai } 10647001Samurai pri = PacketCheck(rbuff, n, FL_OUT); 106520365Sjkh if (pri >= 0) { 106628679Sbrian if (mode & MODE_ALIAS) { 106728679Sbrian VarPacketAliasOut(rbuff, sizeof rbuff); 106828679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 106928679Sbrian } 10706059Samurai IpEnqueue(pri, rbuff, n); 107120365Sjkh } 10726059Samurai } 10736059Samurai } 107426516Sbrian LogPrintf(LogDEBUG, "Job (DoLoop) done.\n"); 10756059Samurai} 1076