main.c revision 28684
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 * 2028684Sbrian * $Id: main.c,v 1.71 1997/08/25 00:29:19 brian Exp $ 218857Srgrimes * 226059Samurai * TODO: 236059Samurai * o Add commands for traffic summary, version display, etc. 246059Samurai * o Add signal handler for misc controls. 256059Samurai */ 266059Samurai#include "fsm.h" 276059Samurai#include <fcntl.h> 2811336Samurai#include <paths.h> 296059Samurai#include <sys/time.h> 306059Samurai#include <termios.h> 3123114Sbrian#include <signal.h> 326059Samurai#include <sys/wait.h> 336059Samurai#include <errno.h> 346059Samurai#include <netdb.h> 3518786Sjkh#include <unistd.h> 366059Samurai#include <sys/socket.h> 376059Samurai#include <arpa/inet.h> 3820365Sjkh#include <netinet/in_systm.h> 3920365Sjkh#include <netinet/ip.h> 406059Samurai#include "modem.h" 416059Samurai#include "os.h" 426059Samurai#include "hdlc.h" 4313389Sphk#include "ccp.h" 446059Samurai#include "lcp.h" 456059Samurai#include "ipcp.h" 4626142Sbrian#include "loadalias.h" 476059Samurai#include "vars.h" 486735Samurai#include "auth.h" 497001Samurai#include "filter.h" 5013389Sphk#include "systems.h" 5113389Sphk#include "ip.h" 5223840Sbrian#include "sig.h" 5326940Sbrian#include "server.h" 5428536Sbrian#include "lcpproto.h" 556059Samurai 566764Samurai#define LAUTH_M1 "Warning: No password entry for this host in ppp.secret\n" 5726516Sbrian#define LAUTH_M2 "Warning: Manipulation is allowed by anyone\n" 586764Samurai 596735Samurai#ifndef O_NONBLOCK 606735Samurai#ifdef O_NDELAY 616735Samurai#define O_NONBLOCK O_NDELAY 626735Samurai#endif 636735Samurai#endif 646735Samurai 656059Samuraiextern void VjInit(), AsyncInit(); 6625630Sbrianextern void AsyncInput(); 6728679Sbrianextern int SelectSystem(); 686059Samurai 696059Samuraiextern void DecodeCommand(), Prompt(); 7018885Sjkhextern int aft_cmd; 716059Samuraiextern int IsInteractive(); 726059Samuraistatic void DoLoop(void); 7310528Samuraistatic void TerminalStop(); 7425908Sbrianstatic char *ex_desc(); 756059Samurai 7628679Sbrianstatic struct termios oldtio; /* Original tty mode */ 7728679Sbrianstatic struct termios comtio; /* Command level tty mode */ 7814418Sacheint TermMode; 7920813Sjkhstatic pid_t BGPid = 0; 8025634Sbrianstatic char pid_filename[MAXPATHLEN]; 8125634Sbrianstatic char if_filename[MAXPATHLEN]; 8225445Sacheint tunno; 8327061Sbrianstatic int dial_up; 846059Samurai 856059Samuraistatic void 8626858SbrianTtyInit(int DontWantInt) 876059Samurai{ 886059Samurai struct termios newtio; 896059Samurai int stat; 906059Samurai 916059Samurai stat = fcntl(0, F_GETFL, 0); 9225630Sbrian if (stat > 0) { 9328679Sbrian stat |= O_NONBLOCK; 9428679Sbrian (void) fcntl(0, F_SETFL, stat); 9525630Sbrian } 966059Samurai newtio = oldtio; 9728679Sbrian newtio.c_lflag &= ~(ECHO | ISIG | ICANON); 986059Samurai newtio.c_iflag = 0; 996059Samurai newtio.c_oflag &= ~OPOST; 1006059Samurai newtio.c_cc[VEOF] = _POSIX_VDISABLE; 10126858Sbrian if (DontWantInt) 10226858Sbrian newtio.c_cc[VINTR] = _POSIX_VDISABLE; 1036059Samurai newtio.c_cc[VMIN] = 1; 1046059Samurai newtio.c_cc[VTIME] = 0; 1056059Samurai newtio.c_cflag |= CS8; 1066735Samurai tcsetattr(0, TCSADRAIN, &newtio); 1076059Samurai comtio = newtio; 1086059Samurai} 1096059Samurai 1106059Samurai/* 1116059Samurai * Set tty into command mode. We allow canonical input and echo processing. 1126059Samurai */ 11310528Samuraivoid 11428679SbrianTtyCommandMode(int prompt) 1156059Samurai{ 1166059Samurai struct termios newtio; 1176059Samurai int stat; 1186059Samurai 1196059Samurai if (!(mode & MODE_INTER)) 1206059Samurai return; 1216735Samurai tcgetattr(0, &newtio); 12228679Sbrian newtio.c_lflag |= (ECHO | ISIG | ICANON); 1236059Samurai newtio.c_iflag = oldtio.c_iflag; 1246059Samurai newtio.c_oflag |= OPOST; 1256735Samurai tcsetattr(0, TCSADRAIN, &newtio); 1266059Samurai stat = fcntl(0, F_GETFL, 0); 12725630Sbrian if (stat > 0) { 12828679Sbrian stat |= O_NONBLOCK; 12928679Sbrian (void) fcntl(0, F_SETFL, stat); 13025630Sbrian } 1316059Samurai TermMode = 0; 13228679Sbrian if (prompt) 13328679Sbrian Prompt(); 1346059Samurai} 1356059Samurai 1366059Samurai/* 1376059Samurai * Set tty into terminal mode which is used while we invoke term command. 1386059Samurai */ 1396059Samuraivoid 1406059SamuraiTtyTermMode() 1416059Samurai{ 1426059Samurai int stat; 1436059Samurai 1446735Samurai tcsetattr(0, TCSADRAIN, &comtio); 1456059Samurai stat = fcntl(0, F_GETFL, 0); 14625630Sbrian if (stat > 0) { 14728679Sbrian stat &= ~O_NONBLOCK; 14828679Sbrian (void) fcntl(0, F_SETFL, stat); 14925630Sbrian } 1506059Samurai TermMode = 1; 1516059Samurai} 1526059Samurai 1536059Samuraivoid 15410528SamuraiTtyOldMode() 1556059Samurai{ 1566059Samurai int stat; 1576059Samurai 1586059Samurai stat = fcntl(0, F_GETFL, 0); 15925630Sbrian if (stat > 0) { 16028679Sbrian stat &= ~O_NONBLOCK; 16128679Sbrian (void) fcntl(0, F_SETFL, stat); 16225630Sbrian } 1636735Samurai tcsetattr(0, TCSANOW, &oldtio); 16410528Samurai} 16510528Samurai 16610528Samuraivoid 16728679SbrianCleanup(int excode) 16810528Samurai{ 16910528Samurai 17010528Samurai OsLinkdown(); 1716059Samurai OsCloseLink(1); 1726059Samurai sleep(1); 17325908Sbrian if (mode & MODE_AUTO) 1746059Samurai DeleteIfRoutes(1); 17528679Sbrian (void) unlink(pid_filename); 17628679Sbrian (void) unlink(if_filename); 1776059Samurai OsInterfaceDown(1); 17823863Sbrian if (mode & MODE_BACKGROUND && BGFiledes[1] != -1) { 17923863Sbrian char c = EX_ERRDEAD; 18028679Sbrian 18128679Sbrian if (write(BGFiledes[1], &c, 1) == 1) 18228679Sbrian LogPrintf(LogPHASE, "Parent notified of failure.\n"); 18323863Sbrian else 18428679Sbrian LogPrintf(LogPHASE, "Failed to notify parent of failure.\n"); 18523863Sbrian close(BGFiledes[1]); 18623863Sbrian } 18728679Sbrian LogPrintf(LogPHASE, "PPP Terminated (%s).\n", ex_desc(excode)); 1886059Samurai LogClose(); 18926940Sbrian ServerClose(); 19010528Samurai TtyOldMode(); 1916059Samurai 1926059Samurai exit(excode); 1936059Samurai} 1946059Samurai 1956059Samuraistatic void 19628679SbrianCloseConnection(int signo) 1976059Samurai{ 19826858Sbrian /* NOTE, these are manual, we've done a setsid() */ 19927157Sbrian LogPrintf(LogPHASE, "Caught signal %d, abort connection\n", signo); 20028679Sbrian reconnectState = RECON_FALSE; 20128684Sbrian reconnectCount = 0; 20228684Sbrian DownConnection(); 20327061Sbrian dial_up = FALSE; 2046059Samurai} 2056059Samurai 2066059Samuraistatic void 20728679SbrianCloseSession(int signo) 2086059Samurai{ 20928679Sbrian if (BGPid) { 21028679Sbrian kill(BGPid, SIGINT); 21128679Sbrian exit(EX_TERM); 21228679Sbrian } 21328679Sbrian LogPrintf(LogPHASE, "Signal %d, terminate.\n", signo); 21428679Sbrian reconnect(RECON_FALSE); 21528679Sbrian LcpClose(); 21628679Sbrian Cleanup(EX_TERM); 2176059Samurai} 2186059Samurai 21910528Samuraistatic void 22010528SamuraiTerminalCont() 22110528Samurai{ 22223840Sbrian pending_signal(SIGCONT, SIG_DFL); 22323840Sbrian pending_signal(SIGTSTP, TerminalStop); 22410528Samurai TtyCommandMode(getpgrp() == tcgetpgrp(0)); 22510528Samurai} 22610528Samurai 22710528Samuraistatic void 22828679SbrianTerminalStop(int signo) 22910528Samurai{ 23023840Sbrian pending_signal(SIGCONT, TerminalCont); 23110528Samurai TtyOldMode(); 23223840Sbrian pending_signal(SIGTSTP, SIG_DFL); 23310528Samurai kill(getpid(), signo); 23410528Samurai} 23510528Samurai 23626940Sbrianstatic void 23728679SbrianSetUpServer(int signo) 23826940Sbrian{ 23926940Sbrian int res; 24028679Sbrian 24128679Sbrian if ((res = ServerTcpOpen(SERVER_PORT + tunno)) != 0) 24228679Sbrian LogPrintf(LogERROR, "Failed %d to open port %d\n", res, SERVER_PORT + tunno); 24326940Sbrian} 24426940Sbrian 24525908Sbrianstatic char * 24625908Sbrianex_desc(int ex) 24725908Sbrian{ 24825908Sbrian static char num[12]; 24928679Sbrian static char *desc[] = {"normal", "start", "sock", 25025908Sbrian "modem", "dial", "dead", "done", "reboot", "errdead", 25128679Sbrian "hangup", "term", "nodial", "nologin"}; 25210528Samurai 25328679Sbrian if (ex >= 0 && ex < sizeof(desc) / sizeof(*desc)) 25425908Sbrian return desc[ex]; 25525908Sbrian snprintf(num, sizeof num, "%d", ex); 25625908Sbrian return num; 25725908Sbrian} 25825908Sbrian 2596059Samuraivoid 2606059SamuraiUsage() 2616059Samurai{ 26220120Snate fprintf(stderr, 26328679Sbrian "Usage: ppp [-auto | -background | -direct | -dedicated | -ddial ] [ -alias ] [system]\n"); 2646059Samurai exit(EX_START); 2656059Samurai} 2666059Samurai 2676059Samuraivoid 2686059SamuraiProcessArgs(int argc, char **argv) 2696059Samurai{ 2706059Samurai int optc; 2716059Samurai char *cp; 2726059Samurai 2736059Samurai optc = 0; 2746059Samurai while (argc > 0 && **argv == '-') { 2756059Samurai cp = *argv + 1; 2766059Samurai if (strcmp(cp, "auto") == 0) 2776059Samurai mode |= MODE_AUTO; 27820813Sjkh else if (strcmp(cp, "background") == 0) 27928679Sbrian mode |= MODE_BACKGROUND | MODE_AUTO; 2806059Samurai else if (strcmp(cp, "direct") == 0) 2816059Samurai mode |= MODE_DIRECT; 2826059Samurai else if (strcmp(cp, "dedicated") == 0) 2836059Samurai mode |= MODE_DEDICATED; 28420120Snate else if (strcmp(cp, "ddial") == 0) 28528679Sbrian mode |= MODE_DDIAL | MODE_AUTO; 28620365Sjkh else if (strcmp(cp, "alias") == 0) { 28726142Sbrian if (loadAliasHandlers(&VarAliasHandlers) == 0) 28828679Sbrian mode |= MODE_ALIAS; 28926142Sbrian else 29028679Sbrian LogPrintf(LogWARN, "Cannot load alias library\n"); 29128679Sbrian optc--; /* this option isn't exclusive */ 29228679Sbrian } else 2936059Samurai Usage(); 2946059Samurai optc++; 29528679Sbrian argv++; 29628679Sbrian argc--; 2976059Samurai } 2986059Samurai if (argc > 1) { 2996059Samurai fprintf(stderr, "specify only one system label.\n"); 3006059Samurai exit(EX_START); 3016059Samurai } 30228679Sbrian if (argc == 1) 30328679Sbrian dstsystem = *argv; 3046059Samurai 3056059Samurai if (optc > 1) { 3066059Samurai fprintf(stderr, "specify only one mode.\n"); 3076059Samurai exit(EX_START); 3086059Samurai } 3096059Samurai} 3106059Samurai 3116059Samuraistatic void 3126059SamuraiGreetings() 3136059Samurai{ 31426516Sbrian if (VarTerm) { 31526516Sbrian fprintf(VarTerm, "User Process PPP. Written by Toshiharu OHNO.\n"); 31626516Sbrian fflush(VarTerm); 31726516Sbrian } 3186059Samurai} 3196059Samurai 32026940Sbrianint 32128679Sbrianmain(int argc, char **argv) 3226059Samurai{ 32325707Sbrian FILE *lockfile; 32426516Sbrian char *name; 32526516Sbrian 32626551Sbrian VarTerm = 0; 32726516Sbrian name = rindex(argv[0], '/'); 32828679Sbrian LogOpen(name ? name + 1 : argv[0]); 32926516Sbrian 33028679Sbrian argc--; 33128679Sbrian argv++; 3326059Samurai mode = MODE_INTER; /* default operation is interactive mode */ 33326940Sbrian netfd = modem = tun_in = -1; 33426940Sbrian server = -2; 3356059Samurai ProcessArgs(argc, argv); 33626328Sbrian if (!(mode & MODE_DIRECT)) 33726551Sbrian VarTerm = stdout; 33826551Sbrian Greetings(); 3396059Samurai GetUid(); 3406059Samurai IpcpDefAddress(); 3416059Samurai 34226516Sbrian if (SelectSystem("default", CONFFILE) < 0 && VarTerm) 34326516Sbrian fprintf(VarTerm, "Warning: No default entry is given in config file.\n"); 3446059Samurai 3456059Samurai if (OpenTunnel(&tunno) < 0) { 34626940Sbrian LogPrintf(LogWARN, "open_tun: %s\n", strerror(errno)); 34726940Sbrian return EX_START; 3486059Samurai } 34928679Sbrian if (mode & (MODE_AUTO | MODE_DIRECT | MODE_DEDICATED)) 3506059Samurai mode &= ~MODE_INTER; 3516059Samurai if (mode & MODE_INTER) { 35226516Sbrian fprintf(VarTerm, "Interactive mode\n"); 35326690Sbrian netfd = STDOUT_FILENO; 3546059Samurai } else if (mode & MODE_AUTO) { 35526516Sbrian fprintf(VarTerm, "Automatic Dialer mode\n"); 3566059Samurai if (dstsystem == NULL) { 35726516Sbrian if (VarTerm) 35828679Sbrian fprintf(VarTerm, "Destination system must be specified in" 35928679Sbrian " auto, background or ddial mode.\n"); 36026940Sbrian return EX_START; 3616059Samurai } 3626059Samurai } 36328679Sbrian tcgetattr(0, &oldtio); /* Save original tty mode */ 3646059Samurai 36527157Sbrian pending_signal(SIGHUP, CloseSession); 36623840Sbrian pending_signal(SIGTERM, CloseSession); 36727157Sbrian pending_signal(SIGINT, CloseConnection); 36823840Sbrian pending_signal(SIGQUIT, CloseSession); 3696735Samurai#ifdef SIGPIPE 37024753Sache signal(SIGPIPE, SIG_IGN); 3716735Samurai#endif 3726735Samurai#ifdef SIGALRM 37323840Sbrian pending_signal(SIGALRM, SIG_IGN); 3746735Samurai#endif 37528679Sbrian if (mode & MODE_INTER) { 37610528Samurai#ifdef SIGTSTP 37726940Sbrian pending_signal(SIGTSTP, TerminalStop); 37810528Samurai#endif 37910528Samurai#ifdef SIGTTIN 38026940Sbrian pending_signal(SIGTTIN, TerminalStop); 38110528Samurai#endif 38210528Samurai#ifdef SIGTTOU 38326940Sbrian pending_signal(SIGTTOU, SIG_IGN); 38410528Samurai#endif 38526940Sbrian } 38626940Sbrian#ifdef SIGUSR1 38726940Sbrian if (mode != MODE_INTER) 38826940Sbrian pending_signal(SIGUSR1, SetUpServer); 38926940Sbrian#endif 3906059Samurai 3916059Samurai if (dstsystem) { 3926059Samurai if (SelectSystem(dstsystem, CONFFILE) < 0) { 39326551Sbrian LogPrintf(LogWARN, "Destination system not found in conf file.\n"); 3946059Samurai Cleanup(EX_START); 3956059Samurai } 3966059Samurai if ((mode & MODE_AUTO) && DefHisAddress.ipaddr.s_addr == INADDR_ANY) { 39726551Sbrian LogPrintf(LogWARN, "Must specify dstaddr with" 39828679Sbrian " auto, background or ddial mode.\n"); 3996059Samurai Cleanup(EX_START); 4006059Samurai } 4016059Samurai } 40226940Sbrian if (ServerType() != NO_SERVER) 40328679Sbrian switch (LocalAuthInit()) { 40428679Sbrian case NOT_FOUND: 40528679Sbrian if (VarTerm) { 40628679Sbrian fprintf(VarTerm, LAUTH_M1); 40728679Sbrian fprintf(VarTerm, LAUTH_M2); 40828679Sbrian fflush(VarTerm); 40928679Sbrian } 41028679Sbrian /* Fall down */ 41128679Sbrian case VALID: 41228679Sbrian VarLocalAuth = LOCAL_AUTH; 41328679Sbrian break; 41428679Sbrian default: 41528679Sbrian break; 41626940Sbrian } 41726940Sbrian 4186059Samurai if (!(mode & MODE_INTER)) { 41920813Sjkh if (mode & MODE_BACKGROUND) { 42028679Sbrian if (pipe(BGFiledes)) { 42128679Sbrian LogPrintf(LogERROR, "pipe: %s", strerror(errno)); 42220813Sjkh Cleanup(EX_SOCK); 42320813Sjkh } 4246059Samurai } 42526940Sbrian /* Create server socket and listen. */ 42626940Sbrian if (server == -2 && ServerTcpOpen(SERVER_PORT + tunno) != 0) 42728679Sbrian Cleanup(EX_SOCK); 4286059Samurai 4296059Samurai if (!(mode & MODE_DIRECT)) { 43020813Sjkh pid_t bgpid; 43111336Samurai 43228679Sbrian bgpid = fork(); 43320813Sjkh if (bgpid == -1) { 43428679Sbrian LogPrintf(LogERROR, "fork: %s", strerror(errno)); 43528679Sbrian Cleanup(EX_SOCK); 43620813Sjkh } 43720813Sjkh if (bgpid) { 43820813Sjkh char c = EX_NORMAL; 43911336Samurai 44020813Sjkh if (mode & MODE_BACKGROUND) { 44120813Sjkh /* Wait for our child to close its pipe before we exit. */ 44220813Sjkh BGPid = bgpid; 44328679Sbrian close(BGFiledes[1]); 44425908Sbrian if (read(BGFiledes[0], &c, 1) != 1) { 44526516Sbrian fprintf(VarTerm, "Child exit, no status.\n"); 44628679Sbrian LogPrintf(LogPHASE, "Parent: Child exit, no status.\n"); 44725908Sbrian } else if (c == EX_NORMAL) { 44826516Sbrian fprintf(VarTerm, "PPP enabled.\n"); 44928679Sbrian LogPrintf(LogPHASE, "Parent: PPP enabled.\n"); 45025908Sbrian } else { 45128679Sbrian fprintf(VarTerm, "Child failed (%s).\n", ex_desc((int) c)); 45226516Sbrian LogPrintf(LogPHASE, "Parent: Child failed (%s).\n", 45328679Sbrian ex_desc((int) c)); 45428679Sbrian } 45528679Sbrian close(BGFiledes[0]); 45620813Sjkh } 45728679Sbrian return c; 45823863Sbrian } else if (mode & MODE_BACKGROUND) 45928679Sbrian close(BGFiledes[0]); 46025707Sbrian } 46128679Sbrian snprintf(pid_filename, sizeof(pid_filename), "%stun%d.pid", 46228679Sbrian _PATH_VARRUN, tunno); 46328679Sbrian (void) unlink(pid_filename); 46420813Sjkh 46525707Sbrian if ((lockfile = fopen(pid_filename, "w")) != NULL) { 46628679Sbrian fprintf(lockfile, "%d\n", (int) getpid()); 46725707Sbrian fclose(lockfile); 46825707Sbrian } else 46926516Sbrian LogPrintf(LogALERT, "Warning: Can't create %s: %s\n", 47028679Sbrian pid_filename, strerror(errno)); 47125634Sbrian 47225707Sbrian snprintf(if_filename, sizeof if_filename, "%s%s.if", 47328679Sbrian _PATH_VARRUN, VarBaseDevice); 47428679Sbrian (void) unlink(if_filename); 47525634Sbrian 47625707Sbrian if ((lockfile = fopen(if_filename, "w")) != NULL) { 47725707Sbrian fprintf(lockfile, "tun%d\n", tunno); 47825707Sbrian fclose(lockfile); 47925707Sbrian } else 48026516Sbrian LogPrintf(LogALERT, "Warning: Can't create %s: %s\n", 48128679Sbrian if_filename, strerror(errno)); 48225707Sbrian 48328679Sbrian VarTerm = 0; /* We know it's currently stdout */ 48426686Sbrian close(0); 48526686Sbrian close(2); 48626551Sbrian 4876059Samurai#ifdef DOTTYINIT 48828679Sbrian if (mode & (MODE_DIRECT | MODE_DEDICATED)) 4896059Samurai#else 49026686Sbrian if (mode & MODE_DIRECT) 4916059Samurai#endif 49226858Sbrian TtyInit(1); 49326686Sbrian else { 49426686Sbrian setsid(); 49526686Sbrian close(1); 49626686Sbrian } 4976059Samurai } else { 49826858Sbrian TtyInit(0); 49910528Samurai TtyCommandMode(1); 5006059Samurai } 50126516Sbrian LogPrintf(LogPHASE, "PPP Started.\n"); 5026059Samurai 5036059Samurai 5046059Samurai do 50528679Sbrian DoLoop(); 5066059Samurai while (mode & MODE_DEDICATED); 5076059Samurai 5086059Samurai Cleanup(EX_DONE); 50926940Sbrian return 0; 5106059Samurai} 5116059Samurai 5126059Samurai/* 51320813Sjkh * Turn into packet mode, where we speak PPP. 5146059Samurai */ 5156059Samuraivoid 5166059SamuraiPacketMode() 5176059Samurai{ 5186059Samurai if (RawModem(modem) < 0) { 51926516Sbrian LogPrintf(LogWARN, "PacketMode: Not connected.\n"); 5206059Samurai return; 5216059Samurai } 5226059Samurai AsyncInit(); 5236059Samurai VjInit(); 5246059Samurai LcpInit(); 5256059Samurai IpcpInit(); 5266059Samurai CcpInit(); 5276059Samurai LcpUp(); 5286059Samurai 52925872Sbrian LcpOpen(VarOpenMode); 53028679Sbrian if ((mode & (MODE_INTER | MODE_AUTO)) == MODE_INTER) { 53110528Samurai TtyCommandMode(1); 53226516Sbrian if (VarTerm) { 53326516Sbrian fprintf(VarTerm, "Packet mode.\n"); 53426516Sbrian aft_cmd = 1; 53526516Sbrian } 5366059Samurai } 5376059Samurai} 5386059Samurai 5396059Samuraistatic void 5406059SamuraiShowHelp() 5416059Samurai{ 54226901Sbrian fprintf(stderr, "The following commands are available:\r\n"); 54326901Sbrian fprintf(stderr, " ~p\tEnter Packet mode\r\n"); 54426901Sbrian fprintf(stderr, " ~-\tDecrease log level\r\n"); 54526901Sbrian fprintf(stderr, " ~+\tIncrease log level\r\n"); 54626901Sbrian fprintf(stderr, " ~t\tShow timers (only in \"log debug\" mode)\r\n"); 54726901Sbrian fprintf(stderr, " ~m\tShow memory map (only in \"log debug\" mode)\r\n"); 54826901Sbrian fprintf(stderr, " ~.\tTerminate program\r\n"); 54926901Sbrian fprintf(stderr, " ~?\tThis help\r\n"); 5506059Samurai} 5516059Samurai 5526059Samuraistatic void 5536059SamuraiReadTty() 5546059Samurai{ 5556059Samurai int n; 5566059Samurai char ch; 5576059Samurai static int ttystate; 55826516Sbrian FILE *oVarTerm; 55928679Sbrian 5606059Samurai#define MAXLINESIZE 200 5616059Samurai char linebuff[MAXLINESIZE]; 5626059Samurai 56326516Sbrian LogPrintf(LogDEBUG, "termode = %d, netfd = %d, mode = %d\n", 56428679Sbrian TermMode, netfd, mode); 5656059Samurai if (!TermMode) { 56628679Sbrian n = read(netfd, linebuff, sizeof(linebuff) - 1); 5676735Samurai if (n > 0) { 56826516Sbrian aft_cmd = 1; 5696059Samurai DecodeCommand(linebuff, n, 1); 5706735Samurai } else { 57126516Sbrian LogPrintf(LogPHASE, "client connection closed.\n"); 57224753Sache VarLocalAuth = LOCAL_NO_AUTH; 57326516Sbrian mode &= ~MODE_INTER; 57426516Sbrian oVarTerm = VarTerm; 57526516Sbrian VarTerm = 0; 57626516Sbrian if (oVarTerm && oVarTerm != stdout) 57728679Sbrian fclose(oVarTerm); 5786059Samurai close(netfd); 5796059Samurai netfd = -1; 5806059Samurai } 5816059Samurai return; 5826059Samurai } 5836059Samurai 5846059Samurai /* 58528679Sbrian * We are in terminal mode, decode special sequences 5866059Samurai */ 58726516Sbrian n = read(fileno(VarTerm), &ch, 1); 58826516Sbrian LogPrintf(LogDEBUG, "Got %d bytes (reading from the terminal)", n); 5896059Samurai 5906059Samurai if (n > 0) { 5916059Samurai switch (ttystate) { 5926059Samurai case 0: 5936059Samurai if (ch == '~') 5946059Samurai ttystate++; 5956059Samurai else 5966059Samurai write(modem, &ch, n); 5976059Samurai break; 5986059Samurai case 1: 5996059Samurai switch (ch) { 6006059Samurai case '?': 6016059Samurai ShowHelp(); 6026059Samurai break; 6036059Samurai case 'p': 60428679Sbrian 6056059Samurai /* 6066059Samurai * XXX: Should check carrier. 6076059Samurai */ 6086059Samurai if (LcpFsm.state <= ST_CLOSED) { 6096059Samurai VarOpenMode = OPEN_ACTIVE; 6106059Samurai PacketMode(); 6116059Samurai } 6126059Samurai break; 6136059Samurai case '.': 6146059Samurai TermMode = 1; 61526516Sbrian aft_cmd = 1; 61610528Samurai TtyCommandMode(1); 6176059Samurai break; 61826516Sbrian case 't': 61926516Sbrian if (LogIsKept(LogDEBUG)) { 62026516Sbrian ShowTimers(); 62126516Sbrian break; 62226516Sbrian } 62326516Sbrian case 'm': 62426516Sbrian if (LogIsKept(LogDEBUG)) { 62526516Sbrian ShowMemMap(); 62626516Sbrian break; 62726516Sbrian } 6286059Samurai default: 6296059Samurai if (write(modem, &ch, n) < 0) 63026516Sbrian LogPrintf(LogERROR, "error writing to modem.\n"); 6316059Samurai break; 6326059Samurai } 6336059Samurai ttystate = 0; 6346059Samurai break; 6356059Samurai } 6366059Samurai } 6376059Samurai} 6386059Samurai 6396059Samurai 6406059Samurai/* 6416059Samurai * Here, we'll try to detect HDLC frame 6426059Samurai */ 6436059Samurai 6446059Samuraistatic char *FrameHeaders[] = { 6456735Samurai "\176\377\003\300\041", 6466735Samurai "\176\377\175\043\300\041", 6476735Samurai "\176\177\175\043\100\041", 6486735Samurai "\176\175\337\175\043\300\041", 6496735Samurai "\176\175\137\175\043\100\041", 6506059Samurai NULL, 6516059Samurai}; 6526059Samurai 6536059Samuraiu_char * 65428679SbrianHdlcDetect(u_char * cp, int n) 6556059Samurai{ 6566735Samurai char *ptr, *fp, **hp; 6576059Samurai 65828679Sbrian cp[n] = '\0'; /* be sure to null terminated */ 6596059Samurai ptr = NULL; 6606059Samurai for (hp = FrameHeaders; *hp; hp++) { 6616735Samurai fp = *hp; 6626735Samurai if (DEV_IS_SYNC) 6636735Samurai fp++; 66428679Sbrian ptr = strstr((char *) cp, fp); 66513389Sphk if (ptr) 6666059Samurai break; 6676059Samurai } 66828679Sbrian return ((u_char *) ptr); 6696059Samurai} 6706059Samurai 6716059Samuraistatic struct pppTimer RedialTimer; 6726059Samurai 6736059Samuraistatic void 6746059SamuraiRedialTimeout() 6756059Samurai{ 6766059Samurai StopTimer(&RedialTimer); 67726516Sbrian LogPrintf(LogPHASE, "Redialing timer expired.\n"); 6786059Samurai} 6796059Samurai 6806059Samuraistatic void 68128679SbrianStartRedialTimer(int Timeout) 6826059Samurai{ 6836059Samurai StopTimer(&RedialTimer); 68411336Samurai 68524939Sbrian if (Timeout) { 68611336Samurai RedialTimer.state = TIMER_STOPPED; 68711336Samurai 68824939Sbrian if (Timeout > 0) 68928679Sbrian RedialTimer.load = Timeout * SECTICKS; 69011336Samurai else 69128679Sbrian RedialTimer.load = (random() % REDIAL_PERIOD) * SECTICKS; 69211336Samurai 69326516Sbrian LogPrintf(LogPHASE, "Enter pause (%d) for redialing.\n", 69424939Sbrian RedialTimer.load / SECTICKS); 69524939Sbrian 69611336Samurai RedialTimer.func = RedialTimeout; 69711336Samurai StartTimer(&RedialTimer); 69811336Samurai } 6996059Samurai} 7006059Samurai 7016059Samurai 7026059Samuraistatic void 7036059SamuraiDoLoop() 7046059Samurai{ 7056059Samurai fd_set rfds, wfds, efds; 70623598Sache int pri, i, n, wfd, nfds; 7076059Samurai struct sockaddr_in hisaddr; 7086059Samurai struct timeval timeout, *tp; 7096059Samurai int ssize = sizeof(hisaddr); 7106059Samurai u_char *cp; 7116059Samurai u_char rbuff[MAX_MRU]; 71211336Samurai int tries; 7139448Samurai int qlen; 71426858Sbrian int res; 71510528Samurai pid_t pgroup; 7166059Samurai 71710528Samurai pgroup = getpgrp(); 71810528Samurai 71925908Sbrian if (mode & MODE_DIRECT) { 72026551Sbrian LogPrintf(LogDEBUG, "Opening modem\n"); 7216059Samurai modem = OpenModem(mode); 72226516Sbrian LogPrintf(LogPHASE, "Packet mode enabled\n"); 7236059Samurai PacketMode(); 7246059Samurai } else if (mode & MODE_DEDICATED) { 72523598Sache if (modem < 0) 7266059Samurai modem = OpenModem(mode); 7276059Samurai } 72826516Sbrian fflush(VarTerm); 7296059Samurai 7307001Samurai timeout.tv_sec = 0; 7316059Samurai timeout.tv_usec = 0; 73226098Sbrian reconnectState = RECON_UNKNOWN; 7336059Samurai 73423863Sbrian if (mode & MODE_BACKGROUND) 73528679Sbrian dial_up = TRUE; /* Bring the line up */ 73623863Sbrian else 73728679Sbrian dial_up = FALSE; /* XXXX */ 73811336Samurai tries = 0; 7396059Samurai for (;;) { 74023598Sache nfds = 0; 74128679Sbrian FD_ZERO(&rfds); 74228679Sbrian FD_ZERO(&wfds); 74328679Sbrian FD_ZERO(&efds); 7447001Samurai 74528679Sbrian /* 74628679Sbrian * If the link is down and we're in DDIAL mode, bring it back up. 74720120Snate */ 74820120Snate if (mode & MODE_DDIAL && LcpFsm.state <= ST_CLOSED) 74928679Sbrian dial_up = TRUE; 75020120Snate 75125067Sbrian /* 75228679Sbrian * If we lost carrier and want to re-establish the connection due to the 75328679Sbrian * "set reconnect" value, we'd better bring the line back up. 75425067Sbrian */ 75525908Sbrian if (LcpFsm.state <= ST_CLOSED) { 75626098Sbrian if (dial_up != TRUE && reconnectState == RECON_TRUE) { 75728679Sbrian if (++reconnectCount <= VarReconnectTries) { 75828679Sbrian LogPrintf(LogPHASE, "Connection lost, re-establish (%d/%d)\n", 75928679Sbrian reconnectCount, VarReconnectTries); 76025908Sbrian StartRedialTimer(VarReconnectTimer); 76128679Sbrian dial_up = TRUE; 76228679Sbrian } else { 76328679Sbrian if (VarReconnectTries) 76428679Sbrian LogPrintf(LogPHASE, "Connection lost, maximum (%d) times\n", 76528679Sbrian VarReconnectTries); 76628679Sbrian reconnectCount = 0; 76728679Sbrian if (mode & MODE_BACKGROUND) 76828679Sbrian Cleanup(EX_DEAD); 76928679Sbrian } 77028679Sbrian reconnectState = RECON_ENVOKED; 77125801Sbrian } 77225908Sbrian } 77325067Sbrian 77428679Sbrian /* 77528679Sbrian * If Ip packet for output is enqueued and require dial up, Just do it! 77628679Sbrian */ 77728679Sbrian if (dial_up && RedialTimer.state != TIMER_RUNNING) { 77826516Sbrian LogPrintf(LogDEBUG, "going to dial: modem = %d\n", modem); 77911336Samurai modem = OpenModem(mode); 78011336Samurai if (modem < 0) { 78128679Sbrian tries++; 78228679Sbrian if (!(mode & MODE_DDIAL) && VarDialTries) 78328679Sbrian LogPrintf(LogCHAT, "Failed to open modem (attempt %u of %d)\n", 78428679Sbrian tries, VarDialTries); 78528679Sbrian else 78628679Sbrian LogPrintf(LogCHAT, "Failed to open modem (attempt %u)\n", tries); 78726551Sbrian 78826696Sbrian if (!(mode & MODE_DDIAL) && VarDialTries && tries >= VarDialTries) { 78926551Sbrian if (mode & MODE_BACKGROUND) 79028679Sbrian Cleanup(EX_DIAL); /* Can't get the modem */ 79126551Sbrian dial_up = FALSE; 79228679Sbrian reconnectState = RECON_UNKNOWN; 79328679Sbrian reconnectCount = 0; 79426551Sbrian tries = 0; 79528679Sbrian } else 79626551Sbrian StartRedialTimer(VarRedialTimeout); 79711336Samurai } else { 79828679Sbrian tries++; /* Tries are per number, not per list of 79928679Sbrian * numbers. */ 80028679Sbrian if (!(mode & MODE_DDIAL) && VarDialTries) 80126696Sbrian LogPrintf(LogCHAT, "Dial attempt %u of %d\n", tries, VarDialTries); 80228679Sbrian else 80328679Sbrian LogPrintf(LogCHAT, "Dial attempt %u\n", tries); 80426696Sbrian 80526858Sbrian if ((res = DialModem()) == EX_DONE) { 80628679Sbrian sleep(1); /* little pause to allow peer starts */ 80711336Samurai ModemTimeout(); 80811336Samurai PacketMode(); 80911336Samurai dial_up = FALSE; 81028679Sbrian reconnectState = RECON_UNKNOWN; 81111336Samurai tries = 0; 81211336Samurai } else { 81311336Samurai CloseModem(); 81424844Sbrian if (mode & MODE_BACKGROUND) { 81526858Sbrian if (VarNextPhone == NULL || res == EX_SIG) 81628679Sbrian Cleanup(EX_DIAL); /* Tried all numbers - no luck */ 81724844Sbrian else 81824939Sbrian /* Try all numbers in background mode */ 81924939Sbrian StartRedialTimer(VarRedialNextTimeout); 82026858Sbrian } else if (!(mode & MODE_DDIAL) && 82128679Sbrian ((VarDialTries && tries >= VarDialTries) || 82228679Sbrian res == EX_SIG)) { 82324843Sbrian /* I give up ! Can't get through :( */ 82424939Sbrian StartRedialTimer(VarRedialTimeout); 82524843Sbrian dial_up = FALSE; 82628679Sbrian reconnectState = RECON_UNKNOWN; 82728679Sbrian reconnectCount = 0; 82824843Sbrian tries = 0; 82924843Sbrian } else if (VarNextPhone == NULL) 83024843Sbrian /* Dial failed. Keep quite during redial wait period. */ 83124939Sbrian StartRedialTimer(VarRedialTimeout); 83224843Sbrian else 83324939Sbrian StartRedialTimer(VarRedialNextTimeout); 83411336Samurai } 83511336Samurai } 8367001Samurai } 8379448Samurai qlen = ModemQlen(); 83813733Sdfr 83913733Sdfr if (qlen == 0) { 84013733Sdfr IpStartOutput(); 84113733Sdfr qlen = ModemQlen(); 84213733Sdfr } 84323598Sache if (modem >= 0) { 84423598Sache if (modem + 1 > nfds) 84523598Sache nfds = modem + 1; 8467001Samurai FD_SET(modem, &rfds); 8477001Samurai FD_SET(modem, &efds); 8489448Samurai if (qlen > 0) { 8497001Samurai FD_SET(modem, &wfds); 8507001Samurai } 8517001Samurai } 85223598Sache if (server >= 0) { 85323598Sache if (server + 1 > nfds) 85423598Sache nfds = server + 1; 85523598Sache FD_SET(server, &rfds); 85623598Sache } 8576059Samurai 85828679Sbrian /* 85928679Sbrian * *** IMPORTANT *** 86028679Sbrian * 86128679Sbrian * CPU is serviced every TICKUNIT micro seconds. This value must be chosen 86228679Sbrian * with great care. If this values is too big, it results loss of 86328679Sbrian * characters from modem and poor responce. If this values is too small, 86428679Sbrian * ppp process eats many CPU time. 8656059Samurai */ 8666735Samurai#ifndef SIGALRM 8676059Samurai usleep(TICKUNIT); 8686059Samurai TimerService(); 86923840Sbrian#else 87023840Sbrian handle_signals(); 8716735Samurai#endif 87210877Sbde 87310877Sbde /* If there are aren't many packets queued, look for some more. */ 87423598Sache if (qlen < 20 && tun_in >= 0) { 87523598Sache if (tun_in + 1 > nfds) 87623598Sache nfds = tun_in + 1; 87710877Sbde FD_SET(tun_in, &rfds); 87823598Sache } 87923598Sache if (netfd >= 0) { 88023598Sache if (netfd + 1 > nfds) 88123598Sache nfds = netfd + 1; 8826059Samurai FD_SET(netfd, &rfds); 8836059Samurai FD_SET(netfd, &efds); 8846059Samurai } 88528679Sbrian#ifndef SIGALRM 8867001Samurai 8876059Samurai /* 88828679Sbrian * Normally, select() will not block because modem is writable. In AUTO 88928679Sbrian * mode, select will block until we find packet from tun 8906059Samurai */ 89128679Sbrian tp = (RedialTimer.state == TIMER_RUNNING) ? &timeout : NULL; 89223598Sache i = select(nfds, &rfds, &wfds, &efds, tp); 8936735Samurai#else 89428679Sbrian 8958857Srgrimes /* 89628679Sbrian * When SIGALRM timer is running, a select function will be return -1 and 89728679Sbrian * EINTR after a Time Service signal hundler is done. If the redial 89828679Sbrian * timer is not running and we are trying to dial, poll with a 0 value 89928679Sbrian * timer. 9007001Samurai */ 90111336Samurai tp = (dial_up && RedialTimer.state != TIMER_RUNNING) ? &timeout : NULL; 90223598Sache i = select(nfds, &rfds, &wfds, &efds, tp); 9036735Samurai#endif 90422074Sbrian 90528679Sbrian if (i == 0) { 90628679Sbrian continue; 9076059Samurai } 90828679Sbrian if (i < 0) { 90928679Sbrian if (errno == EINTR) { 91028679Sbrian handle_signals(); 91128679Sbrian continue; 91228679Sbrian } 91328679Sbrian LogPrintf(LogERROR, "select: %s", strerror(errno)); 91428679Sbrian break; 9158857Srgrimes } 91623598Sache if ((netfd >= 0 && FD_ISSET(netfd, &efds)) || (modem >= 0 && FD_ISSET(modem, &efds))) { 91726516Sbrian LogPrintf(LogALERT, "Exception detected.\n"); 9186059Samurai break; 9196059Samurai } 92023598Sache if (server >= 0 && FD_ISSET(server, &rfds)) { 92126516Sbrian LogPrintf(LogPHASE, "connected to client.\n"); 92228679Sbrian wfd = accept(server, (struct sockaddr *) & hisaddr, &ssize); 92324753Sache if (wfd < 0) { 92428679Sbrian LogPrintf(LogERROR, "accept: %s", strerror(errno)); 92524753Sache continue; 92624753Sache } 92723598Sache if (netfd >= 0) { 9286059Samurai write(wfd, "already in use.\n", 16); 9296059Samurai close(wfd); 9306059Samurai continue; 9316059Samurai } else 9326059Samurai netfd = wfd; 93326516Sbrian VarTerm = fdopen(netfd, "a+"); 9346059Samurai mode |= MODE_INTER; 9356059Samurai Greetings(); 93628679Sbrian switch (LocalAuthInit()) { 93728679Sbrian case NOT_FOUND: 93828679Sbrian if (VarTerm) { 93928679Sbrian fprintf(VarTerm, LAUTH_M1); 94028679Sbrian fprintf(VarTerm, LAUTH_M2); 94128679Sbrian fflush(VarTerm); 94228679Sbrian } 94328679Sbrian /* Fall down */ 94428679Sbrian case VALID: 94528679Sbrian VarLocalAuth = LOCAL_AUTH; 94628679Sbrian break; 94728679Sbrian default: 94828679Sbrian break; 9496764Samurai } 9506059Samurai (void) IsInteractive(); 95125630Sbrian Prompt(); 9526059Samurai } 95323598Sache if ((mode & MODE_INTER) && (netfd >= 0 && FD_ISSET(netfd, &rfds)) && 95410858Samurai ((mode & MODE_AUTO) || pgroup == tcgetpgrp(0))) { 9556059Samurai /* something to read from tty */ 9566059Samurai ReadTty(); 9576059Samurai } 95823598Sache if (modem >= 0) { 9596059Samurai if (FD_ISSET(modem, &wfds)) { /* ready to write into modem */ 96028679Sbrian ModemStartOutput(modem); 9616059Samurai } 9626059Samurai if (FD_ISSET(modem, &rfds)) { /* something to read from modem */ 9636735Samurai if (LcpFsm.state <= ST_CLOSED) 9646735Samurai usleep(10000); 9656059Samurai n = read(modem, rbuff, sizeof(rbuff)); 9666059Samurai if ((mode & MODE_DIRECT) && n <= 0) { 9676059Samurai DownConnection(); 9686059Samurai } else 96928679Sbrian LogDumpBuff(LogASYNC, "ReadFromModem", rbuff, n); 9706059Samurai 9716059Samurai if (LcpFsm.state <= ST_CLOSED) { 97228679Sbrian 9736059Samurai /* 97428679Sbrian * In dedicated mode, we just discard input until LCP is started. 9756059Samurai */ 9766059Samurai if (!(mode & MODE_DEDICATED)) { 9776059Samurai cp = HdlcDetect(rbuff, n); 9786059Samurai if (cp) { 97928679Sbrian 9806059Samurai /* 9816059Samurai * LCP packet is detected. Turn ourselves into packet mode. 9826059Samurai */ 9836059Samurai if (cp != rbuff) { 98428679Sbrian write(modem, rbuff, cp - rbuff); 98528679Sbrian write(modem, "\r\n", 2); 9866059Samurai } 9876059Samurai PacketMode(); 9886059Samurai } else 98926516Sbrian write(fileno(VarTerm), rbuff, n); 9906059Samurai } 9916059Samurai } else { 9926059Samurai if (n > 0) 9936059Samurai AsyncInput(rbuff, n); 9946059Samurai } 9956059Samurai } 9966059Samurai } 99728679Sbrian if (tun_in >= 0 && FD_ISSET(tun_in, &rfds)) { /* something to read 99828679Sbrian * from tun */ 9996059Samurai n = read(tun_in, rbuff, sizeof(rbuff)); 10006059Samurai if (n < 0) { 100128679Sbrian LogPrintf(LogERROR, "read from tun: %s", strerror(errno)); 10026059Samurai continue; 10036059Samurai } 100428679Sbrian if (((struct ip *) rbuff)->ip_dst.s_addr == IpcpInfo.want_ipaddr.s_addr) { 100528536Sbrian /* we've been asked to send something addressed *to* us :( */ 100628536Sbrian if (VarLoopback) { 100728536Sbrian pri = PacketCheck(rbuff, n, FL_IN); 100828536Sbrian if (pri >= 0) { 100928536Sbrian struct mbuf *bp; 101028679Sbrian 101128536Sbrian if (mode & MODE_ALIAS) { 101228536Sbrian VarPacketAliasIn(rbuff, sizeof rbuff); 101328679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 101428536Sbrian } 101528536Sbrian bp = mballoc(n, MB_IPIN); 101628536Sbrian bcopy(rbuff, MBUF_CTOP(bp), n); 101728536Sbrian IpInput(bp); 101828536Sbrian LogPrintf(LogDEBUG, "Looped back packet addressed to myself\n"); 101928536Sbrian } 102028536Sbrian continue; 102128679Sbrian } else 102228536Sbrian LogPrintf(LogDEBUG, "Oops - forwarding packet addressed to myself\n"); 102328536Sbrian } 102428536Sbrian 10256059Samurai /* 102628679Sbrian * Process on-demand dialup. Output packets are queued within tunnel 102728679Sbrian * device until IPCP is opened. 10286059Samurai */ 10296059Samurai if (LcpFsm.state <= ST_CLOSED && (mode & MODE_AUTO)) { 10307001Samurai pri = PacketCheck(rbuff, n, FL_DIAL); 10316059Samurai if (pri >= 0) { 103220365Sjkh if (mode & MODE_ALIAS) { 103326142Sbrian VarPacketAliasOut(rbuff, sizeof rbuff); 103428679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 103520365Sjkh } 10366059Samurai IpEnqueue(pri, rbuff, n); 103728679Sbrian dial_up = TRUE; /* XXX */ 10386059Samurai } 10396059Samurai continue; 10406059Samurai } 10417001Samurai pri = PacketCheck(rbuff, n, FL_OUT); 104220365Sjkh if (pri >= 0) { 104328679Sbrian if (mode & MODE_ALIAS) { 104428679Sbrian VarPacketAliasOut(rbuff, sizeof rbuff); 104528679Sbrian n = ntohs(((struct ip *) rbuff)->ip_len); 104628679Sbrian } 10476059Samurai IpEnqueue(pri, rbuff, n); 104820365Sjkh } 10496059Samurai } 10506059Samurai } 105126516Sbrian LogPrintf(LogDEBUG, "Job (DoLoop) done.\n"); 10526059Samurai} 1053