xref: /freebsd/usr.sbin/ppp/main.c (revision 84b8a6ebd11df8e3fc63da33ace8ae1ebbb474f3)
1af57ed9fSAtsushi Murai /*
2af57ed9fSAtsushi Murai  *			User Process PPP
3af57ed9fSAtsushi Murai  *
4af57ed9fSAtsushi Murai  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5af57ed9fSAtsushi Murai  *
6af57ed9fSAtsushi Murai  *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7af57ed9fSAtsushi Murai  *
8af57ed9fSAtsushi Murai  * Redistribution and use in source and binary forms are permitted
9af57ed9fSAtsushi Murai  * provided that the above copyright notice and this paragraph are
10af57ed9fSAtsushi Murai  * duplicated in all such forms and that any documentation,
11af57ed9fSAtsushi Murai  * advertising materials, and other materials related to such
12af57ed9fSAtsushi Murai  * distribution and use acknowledge that the software was developed
13af57ed9fSAtsushi Murai  * by the Internet Initiative Japan, Inc.  The name of the
14af57ed9fSAtsushi Murai  * IIJ may not be used to endorse or promote products derived
15af57ed9fSAtsushi Murai  * from this software without specific prior written permission.
16af57ed9fSAtsushi Murai  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17af57ed9fSAtsushi Murai  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18af57ed9fSAtsushi Murai  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19af57ed9fSAtsushi Murai  *
2084b8a6ebSAtsushi Murai  * $Id: main.c,v 1.3 1995/02/27 10:57:50 amurai Exp $
21af57ed9fSAtsushi Murai  *
22af57ed9fSAtsushi Murai  *	TODO:
23af57ed9fSAtsushi Murai  *		o Add commands for traffic summary, version display, etc.
24af57ed9fSAtsushi Murai  *		o Add signal handler for misc controls.
25af57ed9fSAtsushi Murai  */
26af57ed9fSAtsushi Murai #include "fsm.h"
27af57ed9fSAtsushi Murai #include <fcntl.h>
28af57ed9fSAtsushi Murai #include <sys/time.h>
29af57ed9fSAtsushi Murai #include <termios.h>
30af57ed9fSAtsushi Murai #include <signal.h>
31af57ed9fSAtsushi Murai #include <sys/wait.h>
32af57ed9fSAtsushi Murai #include <errno.h>
33af57ed9fSAtsushi Murai #include <netdb.h>
34af57ed9fSAtsushi Murai #include <sys/socket.h>
35af57ed9fSAtsushi Murai #include <arpa/inet.h>
36af57ed9fSAtsushi Murai #include "modem.h"
37af57ed9fSAtsushi Murai #include "os.h"
38af57ed9fSAtsushi Murai #include "hdlc.h"
39af57ed9fSAtsushi Murai #include "lcp.h"
40af57ed9fSAtsushi Murai #include "ipcp.h"
41af57ed9fSAtsushi Murai #include "vars.h"
4253c9f6c0SAtsushi Murai #include "auth.h"
4384b8a6ebSAtsushi Murai #include "filter.h"
4453c9f6c0SAtsushi Murai 
4541db6564SAtsushi Murai #define LAUTH_M1 "Warning: No password entry for this host in ppp.secret\n"
4641db6564SAtsushi Murai #define LAUTH_M2 "Warning: All manipulation is allowed by anyone in a world\n"
4741db6564SAtsushi Murai 
4853c9f6c0SAtsushi Murai #ifndef O_NONBLOCK
4953c9f6c0SAtsushi Murai #ifdef O_NDELAY
5053c9f6c0SAtsushi Murai #define	O_NONBLOCK O_NDELAY
5153c9f6c0SAtsushi Murai #endif
5253c9f6c0SAtsushi Murai #endif
53af57ed9fSAtsushi Murai 
54af57ed9fSAtsushi Murai extern void VjInit(), AsyncInit();
55af57ed9fSAtsushi Murai extern void AsyncInput(), IpOutput();
56af57ed9fSAtsushi Murai extern int  SelectSystem();
57af57ed9fSAtsushi Murai 
58af57ed9fSAtsushi Murai extern void DecodeCommand(), Prompt();
59af57ed9fSAtsushi Murai extern int IsInteractive();
60af57ed9fSAtsushi Murai extern struct in_addr ifnetmask;
61af57ed9fSAtsushi Murai static void DoLoop(void);
62af57ed9fSAtsushi Murai 
63af57ed9fSAtsushi Murai static struct termios oldtio;		/* Original tty mode */
64af57ed9fSAtsushi Murai static struct termios comtio;		/* Command level tty mode */
65af57ed9fSAtsushi Murai static int TermMode;
66af57ed9fSAtsushi Murai static int server, update;
67af57ed9fSAtsushi Murai struct sockaddr_in ifsin;
68af57ed9fSAtsushi Murai 
69af57ed9fSAtsushi Murai static void
70af57ed9fSAtsushi Murai TtyInit()
71af57ed9fSAtsushi Murai {
72af57ed9fSAtsushi Murai   struct termios newtio;
73af57ed9fSAtsushi Murai   int stat;
74af57ed9fSAtsushi Murai 
75af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
76af57ed9fSAtsushi Murai   stat |= O_NONBLOCK;
77af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
78af57ed9fSAtsushi Murai   newtio = oldtio;
79af57ed9fSAtsushi Murai   newtio.c_lflag &= ~(ECHO|ISIG|ICANON);
80af57ed9fSAtsushi Murai   newtio.c_iflag = 0;
81af57ed9fSAtsushi Murai   newtio.c_oflag &= ~OPOST;
82af57ed9fSAtsushi Murai   newtio.c_cc[VEOF] = _POSIX_VDISABLE;
83af57ed9fSAtsushi Murai   newtio.c_cc[VINTR] = _POSIX_VDISABLE;
84af57ed9fSAtsushi Murai   newtio.c_cc[VMIN] = 1;
85af57ed9fSAtsushi Murai   newtio.c_cc[VTIME] = 0;
86af57ed9fSAtsushi Murai   newtio.c_cflag |= CS8;
8753c9f6c0SAtsushi Murai   tcsetattr(0, TCSADRAIN, &newtio);
88af57ed9fSAtsushi Murai   comtio = newtio;
89af57ed9fSAtsushi Murai }
90af57ed9fSAtsushi Murai 
91af57ed9fSAtsushi Murai /*
92af57ed9fSAtsushi Murai  *  Set tty into command mode. We allow canonical input and echo processing.
93af57ed9fSAtsushi Murai  */
94af57ed9fSAtsushi Murai static void
95af57ed9fSAtsushi Murai TtyCommandMode()
96af57ed9fSAtsushi Murai {
97af57ed9fSAtsushi Murai   struct termios newtio;
98af57ed9fSAtsushi Murai   int stat;
99af57ed9fSAtsushi Murai 
100af57ed9fSAtsushi Murai   if (!(mode & MODE_INTER))
101af57ed9fSAtsushi Murai     return;
10253c9f6c0SAtsushi Murai   tcgetattr(0, &newtio);
103af57ed9fSAtsushi Murai   newtio.c_lflag |= (ECHO|ICANON);
104af57ed9fSAtsushi Murai   newtio.c_iflag = oldtio.c_iflag;
105af57ed9fSAtsushi Murai   newtio.c_oflag |= OPOST;
10653c9f6c0SAtsushi Murai   tcsetattr(0, TCSADRAIN, &newtio);
107af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
108af57ed9fSAtsushi Murai   stat |= O_NONBLOCK;
109af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
110af57ed9fSAtsushi Murai   TermMode = 0;
111af57ed9fSAtsushi Murai   Prompt(0);
112af57ed9fSAtsushi Murai }
113af57ed9fSAtsushi Murai 
114af57ed9fSAtsushi Murai /*
115af57ed9fSAtsushi Murai  * Set tty into terminal mode which is used while we invoke term command.
116af57ed9fSAtsushi Murai  */
117af57ed9fSAtsushi Murai void
118af57ed9fSAtsushi Murai TtyTermMode()
119af57ed9fSAtsushi Murai {
120af57ed9fSAtsushi Murai   int stat;
121af57ed9fSAtsushi Murai 
12253c9f6c0SAtsushi Murai   tcsetattr(0, TCSADRAIN, &comtio);
123af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
124af57ed9fSAtsushi Murai   stat &= ~O_NONBLOCK;
125af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
126af57ed9fSAtsushi Murai   TermMode = 1;
127af57ed9fSAtsushi Murai }
128af57ed9fSAtsushi Murai 
129af57ed9fSAtsushi Murai void
130af57ed9fSAtsushi Murai Cleanup(excode)
131af57ed9fSAtsushi Murai int excode;
132af57ed9fSAtsushi Murai {
133af57ed9fSAtsushi Murai   int stat;
134af57ed9fSAtsushi Murai 
135af57ed9fSAtsushi Murai   OsLinkdown();
13653c9f6c0SAtsushi Murai #ifdef notdef
137af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
138af57ed9fSAtsushi Murai   stat &= ~O_NONBLOCK;
139af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
14053c9f6c0SAtsushi Murai   tcsetattr(0, TCSANOW, &oldtio);
14153c9f6c0SAtsushi Murai #endif
142af57ed9fSAtsushi Murai   OsCloseLink(1);
143af57ed9fSAtsushi Murai   sleep(1);
144af57ed9fSAtsushi Murai   if (mode & MODE_AUTO)
145af57ed9fSAtsushi Murai     DeleteIfRoutes(1);
146af57ed9fSAtsushi Murai   OsInterfaceDown(1);
147af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "PPP Terminated.\n");
148af57ed9fSAtsushi Murai   LogClose();
149af57ed9fSAtsushi Murai   if (server > 0)
150af57ed9fSAtsushi Murai     close(server);
15153c9f6c0SAtsushi Murai #ifndef notdef
15253c9f6c0SAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
15353c9f6c0SAtsushi Murai   stat &= ~O_NONBLOCK;
15453c9f6c0SAtsushi Murai   fcntl(0, F_SETFL, stat);
15553c9f6c0SAtsushi Murai   tcsetattr(0, TCSANOW, &oldtio);
15653c9f6c0SAtsushi Murai #endif
157af57ed9fSAtsushi Murai 
158af57ed9fSAtsushi Murai   exit(excode);
159af57ed9fSAtsushi Murai }
160af57ed9fSAtsushi Murai 
161af57ed9fSAtsushi Murai static void
162af57ed9fSAtsushi Murai Hangup()
163af57ed9fSAtsushi Murai {
164af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "SIGHUP\n");
165af57ed9fSAtsushi Murai   signal(SIGHUP, Hangup);
166af57ed9fSAtsushi Murai   Cleanup(EX_HANGUP);
167af57ed9fSAtsushi Murai }
168af57ed9fSAtsushi Murai 
169af57ed9fSAtsushi Murai static void
170af57ed9fSAtsushi Murai CloseSession()
171af57ed9fSAtsushi Murai {
172af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "SIGTERM\n");
173af57ed9fSAtsushi Murai   LcpClose();
174af57ed9fSAtsushi Murai   Cleanup(EX_TERM);
175af57ed9fSAtsushi Murai }
176af57ed9fSAtsushi Murai 
177af57ed9fSAtsushi Murai void
178af57ed9fSAtsushi Murai Usage()
179af57ed9fSAtsushi Murai {
180af57ed9fSAtsushi Murai   fprintf(stderr, "Usage: ppp [-auto | -direct -dedicated] [system]\n");
181af57ed9fSAtsushi Murai   exit(EX_START);
182af57ed9fSAtsushi Murai }
183af57ed9fSAtsushi Murai 
184af57ed9fSAtsushi Murai void
185af57ed9fSAtsushi Murai ProcessArgs(int argc, char **argv)
186af57ed9fSAtsushi Murai {
187af57ed9fSAtsushi Murai   int optc;
188af57ed9fSAtsushi Murai   char *cp;
189af57ed9fSAtsushi Murai 
190af57ed9fSAtsushi Murai   optc = 0;
191af57ed9fSAtsushi Murai   while (argc > 0 && **argv == '-') {
192af57ed9fSAtsushi Murai     cp = *argv + 1;
193af57ed9fSAtsushi Murai     if (strcmp(cp, "auto") == 0)
194af57ed9fSAtsushi Murai       mode |= MODE_AUTO;
195af57ed9fSAtsushi Murai     else if (strcmp(cp, "direct") == 0)
196af57ed9fSAtsushi Murai       mode |= MODE_DIRECT;
197af57ed9fSAtsushi Murai     else if (strcmp(cp, "dedicated") == 0)
198af57ed9fSAtsushi Murai       mode |= MODE_DEDICATED;
199af57ed9fSAtsushi Murai     else
200af57ed9fSAtsushi Murai       Usage();
201af57ed9fSAtsushi Murai     optc++;
202af57ed9fSAtsushi Murai     argv++; argc--;
203af57ed9fSAtsushi Murai   }
204af57ed9fSAtsushi Murai   if (argc > 1) {
205af57ed9fSAtsushi Murai     fprintf(stderr, "specify only one system label.\n");
206af57ed9fSAtsushi Murai     exit(EX_START);
207af57ed9fSAtsushi Murai   }
208af57ed9fSAtsushi Murai   if (argc == 1) dstsystem = *argv;
209af57ed9fSAtsushi Murai 
210af57ed9fSAtsushi Murai   if (optc > 1) {
211af57ed9fSAtsushi Murai     fprintf(stderr, "specify only one mode.\n");
212af57ed9fSAtsushi Murai     exit(EX_START);
213af57ed9fSAtsushi Murai   }
214af57ed9fSAtsushi Murai }
215af57ed9fSAtsushi Murai 
216af57ed9fSAtsushi Murai static void
217af57ed9fSAtsushi Murai Greetings()
218af57ed9fSAtsushi Murai {
219af57ed9fSAtsushi Murai   printf("User Process PPP. Written by Toshiharu OHNO.\r\n");
220af57ed9fSAtsushi Murai   fflush(stdout);
221af57ed9fSAtsushi Murai }
222af57ed9fSAtsushi Murai 
223af57ed9fSAtsushi Murai void
224af57ed9fSAtsushi Murai main(argc, argv)
225af57ed9fSAtsushi Murai int argc;
226af57ed9fSAtsushi Murai char **argv;
227af57ed9fSAtsushi Murai {
228af57ed9fSAtsushi Murai   int tunno;
229af57ed9fSAtsushi Murai   int on = 1;
230af57ed9fSAtsushi Murai 
231af57ed9fSAtsushi Murai   argc--; argv++;
232af57ed9fSAtsushi Murai 
233af57ed9fSAtsushi Murai   mode = MODE_INTER;		/* default operation is interactive mode */
234af57ed9fSAtsushi Murai   netfd = -1;
235af57ed9fSAtsushi Murai   ProcessArgs(argc, argv);
236af57ed9fSAtsushi Murai   Greetings();
237af57ed9fSAtsushi Murai   GetUid();
238af57ed9fSAtsushi Murai   IpcpDefAddress();
239af57ed9fSAtsushi Murai 
240af57ed9fSAtsushi Murai   if (SelectSystem("default", CONFFILE) < 0) {
241af57ed9fSAtsushi Murai     fprintf(stderr, "Warning: No default entry is given in config file.\n");
242af57ed9fSAtsushi Murai   }
243af57ed9fSAtsushi Murai 
244af57ed9fSAtsushi Murai   if (LogOpen())
245af57ed9fSAtsushi Murai     exit(EX_START);
246af57ed9fSAtsushi Murai 
24753c9f6c0SAtsushi Murai   switch ( LocalAuthInit() ) {
24853c9f6c0SAtsushi Murai     case NOT_FOUND:
24941db6564SAtsushi Murai     	fprintf(stderr,LAUTH_M1);
25041db6564SAtsushi Murai     	fprintf(stderr,LAUTH_M2);
25141db6564SAtsushi Murai 	fflush (stderr);
25241db6564SAtsushi Murai 	/* Fall down */
25341db6564SAtsushi Murai     case VALID:
25453c9f6c0SAtsushi Murai 	VarLocalAuth = LOCAL_AUTH;
25553c9f6c0SAtsushi Murai 	break;
25653c9f6c0SAtsushi Murai     default:
25753c9f6c0SAtsushi Murai 	break;
25853c9f6c0SAtsushi Murai   }
25953c9f6c0SAtsushi Murai 
260af57ed9fSAtsushi Murai   if (OpenTunnel(&tunno) < 0) {
261af57ed9fSAtsushi Murai     perror("open_tun");
262af57ed9fSAtsushi Murai     exit(EX_START);
263af57ed9fSAtsushi Murai   }
264af57ed9fSAtsushi Murai 
265af57ed9fSAtsushi Murai   if (mode & (MODE_AUTO|MODE_DIRECT|MODE_DEDICATED))
266af57ed9fSAtsushi Murai     mode &= ~MODE_INTER;
267af57ed9fSAtsushi Murai   if (mode & MODE_INTER) {
268af57ed9fSAtsushi Murai     printf("Interactive mode\n");
269af57ed9fSAtsushi Murai     netfd = 0;
270af57ed9fSAtsushi Murai   } else if (mode & MODE_AUTO) {
271af57ed9fSAtsushi Murai     printf("Automatic mode\n");
272af57ed9fSAtsushi Murai     if (dstsystem == NULL) {
273af57ed9fSAtsushi Murai       fprintf(stderr, "Destination system must be specified in auto mode.\n");
274af57ed9fSAtsushi Murai       exit(EX_START);
275af57ed9fSAtsushi Murai     }
276af57ed9fSAtsushi Murai   }
277af57ed9fSAtsushi Murai 
27853c9f6c0SAtsushi Murai   tcgetattr(0, &oldtio);		/* Save original tty mode */
279af57ed9fSAtsushi Murai 
280af57ed9fSAtsushi Murai   signal(SIGHUP, Hangup);
281af57ed9fSAtsushi Murai   signal(SIGTERM, CloseSession);
282af57ed9fSAtsushi Murai   signal(SIGINT, CloseSession);
28353c9f6c0SAtsushi Murai #ifdef SIGSEGV
284af57ed9fSAtsushi Murai   signal(SIGSEGV, Hangup);
28553c9f6c0SAtsushi Murai #endif
28653c9f6c0SAtsushi Murai #ifdef SIGPIPE
28753c9f6c0SAtsushi Murai   signal(SIGPIPE, Hangup);
28853c9f6c0SAtsushi Murai #endif
28953c9f6c0SAtsushi Murai #ifdef SIGALRM
29053c9f6c0SAtsushi Murai   signal(SIGALRM, SIG_IGN);
29153c9f6c0SAtsushi Murai #endif
292af57ed9fSAtsushi Murai 
293af57ed9fSAtsushi Murai   if (dstsystem) {
294af57ed9fSAtsushi Murai     if (SelectSystem(dstsystem, CONFFILE) < 0) {
295af57ed9fSAtsushi Murai       fprintf(stderr, "Destination system not found in conf file.\n");
296af57ed9fSAtsushi Murai       Cleanup(EX_START);
297af57ed9fSAtsushi Murai     }
298af57ed9fSAtsushi Murai     if ((mode & MODE_AUTO) && DefHisAddress.ipaddr.s_addr == INADDR_ANY) {
299af57ed9fSAtsushi Murai       fprintf(stderr, "Must specify dstaddr with auto mode.\n");
300af57ed9fSAtsushi Murai       Cleanup(EX_START);
301af57ed9fSAtsushi Murai     }
302af57ed9fSAtsushi Murai   }
303af57ed9fSAtsushi Murai   if (mode & MODE_DIRECT)
304af57ed9fSAtsushi Murai     printf("Packet mode enabled.\n");
305af57ed9fSAtsushi Murai 
306af57ed9fSAtsushi Murai #ifdef notdef
307af57ed9fSAtsushi Murai   if (mode & MODE_AUTO) {
308af57ed9fSAtsushi Murai     OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask);
309af57ed9fSAtsushi Murai   }
310af57ed9fSAtsushi Murai #endif
311af57ed9fSAtsushi Murai 
312af57ed9fSAtsushi Murai   if (!(mode & MODE_INTER)) {
313af57ed9fSAtsushi Murai      int port = SERVER_PORT + tunno;
314af57ed9fSAtsushi Murai     /*
315af57ed9fSAtsushi Murai      *  Create server socket and listen at there.
316af57ed9fSAtsushi Murai      */
317af57ed9fSAtsushi Murai     server = socket(PF_INET, SOCK_STREAM, 0);
318af57ed9fSAtsushi Murai     if (server < 0) {
319af57ed9fSAtsushi Murai       perror("socket");
320af57ed9fSAtsushi Murai       Cleanup(EX_SOCK);
321af57ed9fSAtsushi Murai     }
322af57ed9fSAtsushi Murai     ifsin.sin_family = AF_INET;
323af57ed9fSAtsushi Murai     ifsin.sin_addr.s_addr = INADDR_ANY;
324af57ed9fSAtsushi Murai     ifsin.sin_port = htons(port);
325af57ed9fSAtsushi Murai     if (bind(server, (struct sockaddr *) &ifsin, sizeof(ifsin)) < 0) {
326af57ed9fSAtsushi Murai       perror("bind");
327af57ed9fSAtsushi Murai       if (errno == EADDRINUSE)
328af57ed9fSAtsushi Murai 	fprintf(stderr, "Wait for a while, then try again.\n");
329af57ed9fSAtsushi Murai       Cleanup(EX_SOCK);
330af57ed9fSAtsushi Murai     }
331af57ed9fSAtsushi Murai     listen(server, 5);
332af57ed9fSAtsushi Murai 
333af57ed9fSAtsushi Murai     DupLog();
334af57ed9fSAtsushi Murai     if (!(mode & MODE_DIRECT)) {
335af57ed9fSAtsushi Murai       if (fork())
336af57ed9fSAtsushi Murai         exit(0);
337af57ed9fSAtsushi Murai     }
338af57ed9fSAtsushi Murai     LogPrintf(LOG_PHASE, "Listening at %d.\n", port);
339af57ed9fSAtsushi Murai #ifdef DOTTYINIT
34053c9f6c0SAtsushi Murai     if (mode & (MODE_DIRECT|MODE_DEDICATED)) { /* } */
341af57ed9fSAtsushi Murai #else
342af57ed9fSAtsushi Murai     if (mode & MODE_DIRECT) {
343af57ed9fSAtsushi Murai #endif
344af57ed9fSAtsushi Murai       TtyInit();
345af57ed9fSAtsushi Murai     } else {
346af57ed9fSAtsushi Murai       setsid();			/* detach control tty */
347af57ed9fSAtsushi Murai     }
348af57ed9fSAtsushi Murai   } else {
349af57ed9fSAtsushi Murai     server = -1;
350af57ed9fSAtsushi Murai     TtyInit();
351af57ed9fSAtsushi Murai     TtyCommandMode();
352af57ed9fSAtsushi Murai   }
353af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "PPP Started.\n");
354af57ed9fSAtsushi Murai 
355af57ed9fSAtsushi Murai 
356af57ed9fSAtsushi Murai   do
357af57ed9fSAtsushi Murai    DoLoop();
358af57ed9fSAtsushi Murai   while (mode & MODE_DEDICATED);
359af57ed9fSAtsushi Murai 
360af57ed9fSAtsushi Murai   Cleanup(EX_DONE);
361af57ed9fSAtsushi Murai }
362af57ed9fSAtsushi Murai 
363af57ed9fSAtsushi Murai /*
364af57ed9fSAtsushi Murai  *  Turn into packet mode, where we speek PPP.
365af57ed9fSAtsushi Murai  */
366af57ed9fSAtsushi Murai void
367af57ed9fSAtsushi Murai PacketMode()
368af57ed9fSAtsushi Murai {
369af57ed9fSAtsushi Murai   if (RawModem(modem) < 0) {
370af57ed9fSAtsushi Murai     fprintf(stderr, "Not connected.\r\n");
371af57ed9fSAtsushi Murai     return;
372af57ed9fSAtsushi Murai   }
373af57ed9fSAtsushi Murai 
374af57ed9fSAtsushi Murai   AsyncInit();
375af57ed9fSAtsushi Murai   VjInit();
376af57ed9fSAtsushi Murai   LcpInit();
377af57ed9fSAtsushi Murai   IpcpInit();
378af57ed9fSAtsushi Murai   CcpInit();
379af57ed9fSAtsushi Murai   LcpUp();
380af57ed9fSAtsushi Murai 
381af57ed9fSAtsushi Murai   if (mode & (MODE_DIRECT|MODE_DEDICATED))
382af57ed9fSAtsushi Murai     LcpOpen(OPEN_ACTIVE);
383af57ed9fSAtsushi Murai   else
384af57ed9fSAtsushi Murai     LcpOpen(VarOpenMode);
385af57ed9fSAtsushi Murai   if ((mode & (MODE_INTER|MODE_AUTO)) == MODE_INTER) {
386af57ed9fSAtsushi Murai     TtyCommandMode();
387af57ed9fSAtsushi Murai     fprintf(stderr, "Packet mode.\r\n");
388af57ed9fSAtsushi Murai   }
389af57ed9fSAtsushi Murai }
390af57ed9fSAtsushi Murai 
391af57ed9fSAtsushi Murai static void
392af57ed9fSAtsushi Murai ShowHelp()
393af57ed9fSAtsushi Murai {
394af57ed9fSAtsushi Murai   fprintf(stderr, "Following commands are available\r\n");
395af57ed9fSAtsushi Murai   fprintf(stderr, " ~p\tEnter to Packet mode\r\n");
396af57ed9fSAtsushi Murai   fprintf(stderr, " ~.\tTerminate program\r\n");
397af57ed9fSAtsushi Murai }
398af57ed9fSAtsushi Murai 
399af57ed9fSAtsushi Murai static void
400af57ed9fSAtsushi Murai ReadTty()
401af57ed9fSAtsushi Murai {
402af57ed9fSAtsushi Murai   int n;
403af57ed9fSAtsushi Murai   char ch;
404af57ed9fSAtsushi Murai   static int ttystate;
405af57ed9fSAtsushi Murai #define MAXLINESIZE 200
406af57ed9fSAtsushi Murai   char linebuff[MAXLINESIZE];
407af57ed9fSAtsushi Murai 
408af57ed9fSAtsushi Murai #ifdef DEBUG
409af57ed9fSAtsushi Murai   logprintf("termode = %d, netfd = %d, mode = %d\n", TermMode, netfd, mode);
410af57ed9fSAtsushi Murai #endif
411af57ed9fSAtsushi Murai   if (!TermMode) {
412af57ed9fSAtsushi Murai     n = read(netfd, linebuff, sizeof(linebuff)-1);
41353c9f6c0SAtsushi Murai     if (n > 0) {
414af57ed9fSAtsushi Murai       DecodeCommand(linebuff, n, 1);
41553c9f6c0SAtsushi Murai     } else {
416af57ed9fSAtsushi Murai #ifdef DEBUG
417af57ed9fSAtsushi Murai       logprintf("connection closed.\n");
418af57ed9fSAtsushi Murai #endif
419af57ed9fSAtsushi Murai       close(netfd);
420af57ed9fSAtsushi Murai       netfd = -1;
421af57ed9fSAtsushi Murai       mode &= ~MODE_INTER;
422af57ed9fSAtsushi Murai     }
423af57ed9fSAtsushi Murai     return;
424af57ed9fSAtsushi Murai   }
425af57ed9fSAtsushi Murai 
426af57ed9fSAtsushi Murai   /*
427af57ed9fSAtsushi Murai    *  We are in terminal mode, decode special sequences
428af57ed9fSAtsushi Murai    */
429af57ed9fSAtsushi Murai   n = read(0, &ch, 1);
430af57ed9fSAtsushi Murai #ifdef DEBUG
431af57ed9fSAtsushi Murai   logprintf("got %d bytes\n", n);
432af57ed9fSAtsushi Murai #endif
433af57ed9fSAtsushi Murai 
434af57ed9fSAtsushi Murai   if (n > 0) {
435af57ed9fSAtsushi Murai     switch (ttystate) {
436af57ed9fSAtsushi Murai     case 0:
437af57ed9fSAtsushi Murai       if (ch == '~')
438af57ed9fSAtsushi Murai 	ttystate++;
439af57ed9fSAtsushi Murai       else
440af57ed9fSAtsushi Murai 	write(modem, &ch, n);
441af57ed9fSAtsushi Murai       break;
442af57ed9fSAtsushi Murai     case 1:
443af57ed9fSAtsushi Murai       switch (ch) {
444af57ed9fSAtsushi Murai       case '?':
445af57ed9fSAtsushi Murai 	ShowHelp();
446af57ed9fSAtsushi Murai 	break;
447af57ed9fSAtsushi Murai       case '-':
448af57ed9fSAtsushi Murai 	if (loglevel > 0) {
449af57ed9fSAtsushi Murai 	  loglevel--;
450af57ed9fSAtsushi Murai 	  fprintf(stderr, "New loglevel is %d\r\n", loglevel);
451af57ed9fSAtsushi Murai 	}
452af57ed9fSAtsushi Murai 	break;
453af57ed9fSAtsushi Murai       case '+':
454af57ed9fSAtsushi Murai 	loglevel++;
455af57ed9fSAtsushi Murai 	fprintf(stderr, "New loglevel is %d\r\n", loglevel);
456af57ed9fSAtsushi Murai 	break;
457af57ed9fSAtsushi Murai #ifdef DEBUG
458af57ed9fSAtsushi Murai       case 'm':
459af57ed9fSAtsushi Murai 	ShowMemMap();
460af57ed9fSAtsushi Murai 	break;
461af57ed9fSAtsushi Murai #endif
462af57ed9fSAtsushi Murai       case 'p':
463af57ed9fSAtsushi Murai 	/*
464af57ed9fSAtsushi Murai 	 * XXX: Should check carrier.
465af57ed9fSAtsushi Murai 	 */
466af57ed9fSAtsushi Murai 	if (LcpFsm.state <= ST_CLOSED) {
467af57ed9fSAtsushi Murai 	  VarOpenMode = OPEN_ACTIVE;
468af57ed9fSAtsushi Murai 	  PacketMode();
469af57ed9fSAtsushi Murai 	}
470af57ed9fSAtsushi Murai 	break;
471af57ed9fSAtsushi Murai #ifdef DEBUG
472af57ed9fSAtsushi Murai       case 't':
473af57ed9fSAtsushi Murai 	ShowTimers();
474af57ed9fSAtsushi Murai 	break;
475af57ed9fSAtsushi Murai #endif
476af57ed9fSAtsushi Murai       case '.':
477af57ed9fSAtsushi Murai 	TermMode = 1;
478af57ed9fSAtsushi Murai 	TtyCommandMode();
479af57ed9fSAtsushi Murai 	break;
480af57ed9fSAtsushi Murai       default:
481af57ed9fSAtsushi Murai 	if (write(modem, &ch, n) < 0)
482af57ed9fSAtsushi Murai 	  fprintf(stderr, "err in write.\r\n");
483af57ed9fSAtsushi Murai 	break;
484af57ed9fSAtsushi Murai       }
485af57ed9fSAtsushi Murai       ttystate = 0;
486af57ed9fSAtsushi Murai       break;
487af57ed9fSAtsushi Murai     }
488af57ed9fSAtsushi Murai   }
489af57ed9fSAtsushi Murai }
490af57ed9fSAtsushi Murai 
491af57ed9fSAtsushi Murai 
492af57ed9fSAtsushi Murai /*
493af57ed9fSAtsushi Murai  *  Here, we'll try to detect HDLC frame
494af57ed9fSAtsushi Murai  */
495af57ed9fSAtsushi Murai 
496af57ed9fSAtsushi Murai static char *FrameHeaders[] = {
49753c9f6c0SAtsushi Murai   "\176\377\003\300\041",
49853c9f6c0SAtsushi Murai   "\176\377\175\043\300\041",
49953c9f6c0SAtsushi Murai   "\176\177\175\043\100\041",
50053c9f6c0SAtsushi Murai   "\176\175\337\175\043\300\041",
50153c9f6c0SAtsushi Murai   "\176\175\137\175\043\100\041",
502af57ed9fSAtsushi Murai   NULL,
503af57ed9fSAtsushi Murai };
504af57ed9fSAtsushi Murai 
505af57ed9fSAtsushi Murai u_char *
506af57ed9fSAtsushi Murai HdlcDetect(cp, n)
507af57ed9fSAtsushi Murai u_char *cp;
508af57ed9fSAtsushi Murai int n;
509af57ed9fSAtsushi Murai {
51053c9f6c0SAtsushi Murai   char *ptr, *fp, **hp;
511af57ed9fSAtsushi Murai 
512af57ed9fSAtsushi Murai   cp[n] = '\0';	/* be sure to null terminated */
513af57ed9fSAtsushi Murai   ptr = NULL;
514af57ed9fSAtsushi Murai   for (hp = FrameHeaders; *hp; hp++) {
51553c9f6c0SAtsushi Murai     fp = *hp;
51653c9f6c0SAtsushi Murai     if (DEV_IS_SYNC)
51753c9f6c0SAtsushi Murai       fp++;
51853c9f6c0SAtsushi Murai     if (ptr = strstr((char *)cp, fp))
519af57ed9fSAtsushi Murai       break;
520af57ed9fSAtsushi Murai   }
521af57ed9fSAtsushi Murai   return((u_char *)ptr);
522af57ed9fSAtsushi Murai }
523af57ed9fSAtsushi Murai 
524af57ed9fSAtsushi Murai static struct pppTimer RedialTimer;
525af57ed9fSAtsushi Murai 
526af57ed9fSAtsushi Murai static void
527af57ed9fSAtsushi Murai RedialTimeout()
528af57ed9fSAtsushi Murai {
529af57ed9fSAtsushi Murai   StopTimer(&RedialTimer);
530af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "Redialing timer expired.\n");
531af57ed9fSAtsushi Murai }
532af57ed9fSAtsushi Murai 
533af57ed9fSAtsushi Murai static void
534af57ed9fSAtsushi Murai StartRedialTimer()
535af57ed9fSAtsushi Murai {
536af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "Enter pause for redialing.\n");
537af57ed9fSAtsushi Murai   StopTimer(&RedialTimer);
538af57ed9fSAtsushi Murai   RedialTimer.state = TIMER_STOPPED;
539af57ed9fSAtsushi Murai   RedialTimer.load = REDIAL_PERIOD * SECTICKS;
540af57ed9fSAtsushi Murai   RedialTimer.func = RedialTimeout;
541af57ed9fSAtsushi Murai   StartTimer(&RedialTimer);
542af57ed9fSAtsushi Murai }
543af57ed9fSAtsushi Murai 
544af57ed9fSAtsushi Murai 
545af57ed9fSAtsushi Murai static void
546af57ed9fSAtsushi Murai DoLoop()
547af57ed9fSAtsushi Murai {
548af57ed9fSAtsushi Murai   fd_set rfds, wfds, efds;
549af57ed9fSAtsushi Murai   int pri, i, n, wfd;
550af57ed9fSAtsushi Murai   struct sockaddr_in hisaddr;
551af57ed9fSAtsushi Murai   struct timeval timeout, *tp;
552af57ed9fSAtsushi Murai   int ssize = sizeof(hisaddr);
553af57ed9fSAtsushi Murai   u_char *cp;
554af57ed9fSAtsushi Murai   u_char rbuff[MAX_MRU];
55584b8a6ebSAtsushi Murai   int dial_up;
556af57ed9fSAtsushi Murai 
557af57ed9fSAtsushi Murai   if (mode & MODE_DIRECT) {
558af57ed9fSAtsushi Murai     modem = OpenModem(mode);
559af57ed9fSAtsushi Murai     fprintf(stderr, "Packet mode enabled\n");
560af57ed9fSAtsushi Murai     PacketMode();
561af57ed9fSAtsushi Murai   } else if (mode & MODE_DEDICATED) {
562af57ed9fSAtsushi Murai     if (!modem)
563af57ed9fSAtsushi Murai       modem = OpenModem(mode);
564af57ed9fSAtsushi Murai   }
565af57ed9fSAtsushi Murai 
566af57ed9fSAtsushi Murai   fflush(stdout);
567af57ed9fSAtsushi Murai 
56853c9f6c0SAtsushi Murai #ifdef SIGALRM
56984b8a6ebSAtsushi Murai   timeout.tv_sec = 0;
57053c9f6c0SAtsushi Murai #else
571af57ed9fSAtsushi Murai   timeout.tv_usec = 0;
57253c9f6c0SAtsushi Murai #endif
573af57ed9fSAtsushi Murai 
57484b8a6ebSAtsushi Murai   dial_up = FALSE;			/* XXXX */
575af57ed9fSAtsushi Murai   for (;;) {
57684b8a6ebSAtsushi Murai     if ( modem )
577af57ed9fSAtsushi Murai 	IpStartOutput();
578af57ed9fSAtsushi Murai     FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
57984b8a6ebSAtsushi Murai 
58084b8a6ebSAtsushi Murai    /*
58184b8a6ebSAtsushi Murai     * If Ip packet for output is enqueued and require dial up,
58284b8a6ebSAtsushi Murai     * Just do it!
58384b8a6ebSAtsushi Murai     */
58484b8a6ebSAtsushi Murai     if ( dial_up && RedialTimer.state != TIMER_RUNNING ) { /* XXX */
58584b8a6ebSAtsushi Murai #ifdef DEBUG
58684b8a6ebSAtsushi Murai       logprintf("going to dial: modem = %d\n", modem);
58784b8a6ebSAtsushi Murai #endif
58884b8a6ebSAtsushi Murai        modem = OpenModem(mode);
58984b8a6ebSAtsushi Murai        if (modem < 0) {
59084b8a6ebSAtsushi Murai          modem = 0;	       /* Set intial value for next OpenModem */
59184b8a6ebSAtsushi Murai          StartRedialTimer();
59284b8a6ebSAtsushi Murai        } else {
59384b8a6ebSAtsushi Murai          if (DialModem()) {
59484b8a6ebSAtsushi Murai            sleep(1);	       /* little pause to allow peer starts */
59584b8a6ebSAtsushi Murai            ModemTimeout();
59684b8a6ebSAtsushi Murai            PacketMode();
59784b8a6ebSAtsushi Murai            dial_up = FALSE;
59884b8a6ebSAtsushi Murai          } else {
59984b8a6ebSAtsushi Murai            CloseModem();
60084b8a6ebSAtsushi Murai            /* Dial failed. Keep quite during redial wait period. */
60184b8a6ebSAtsushi Murai            StartRedialTimer();
60284b8a6ebSAtsushi Murai          }
60384b8a6ebSAtsushi Murai        }
60484b8a6ebSAtsushi Murai     }
60584b8a6ebSAtsushi Murai     if (modem) {
60684b8a6ebSAtsushi Murai       FD_SET(modem, &rfds);
60784b8a6ebSAtsushi Murai       FD_SET(modem, &efds);
60884b8a6ebSAtsushi Murai       if (ModemQlen() > 0) {
60984b8a6ebSAtsushi Murai 	FD_SET(modem, &wfds);
61084b8a6ebSAtsushi Murai       }
61184b8a6ebSAtsushi Murai     }
612af57ed9fSAtsushi Murai     if (server > 0) FD_SET(server, &rfds);
613af57ed9fSAtsushi Murai 
614af57ed9fSAtsushi Murai     /*  *** IMPORTANT ***
615af57ed9fSAtsushi Murai      *
616af57ed9fSAtsushi Murai      *  CPU is serviced every TICKUNIT micro seconds.
617af57ed9fSAtsushi Murai      *	This value must be chosen with great care. If this values is
618af57ed9fSAtsushi Murai      *  too big, it results loss of characters from modem and poor responce.
619af57ed9fSAtsushi Murai      *  If this values is too small, ppp process eats many CPU time.
620af57ed9fSAtsushi Murai      */
62153c9f6c0SAtsushi Murai #ifndef SIGALRM
622af57ed9fSAtsushi Murai     usleep(TICKUNIT);
623af57ed9fSAtsushi Murai     TimerService();
62453c9f6c0SAtsushi Murai #endif
625af57ed9fSAtsushi Murai 
62684b8a6ebSAtsushi Murai     FD_SET(tun_in, &rfds);
627af57ed9fSAtsushi Murai     if (netfd > -1) {
628af57ed9fSAtsushi Murai       FD_SET(netfd, &rfds);
629af57ed9fSAtsushi Murai       FD_SET(netfd, &efds);
630af57ed9fSAtsushi Murai     }
63184b8a6ebSAtsushi Murai 
63284b8a6ebSAtsushi Murai 
63353c9f6c0SAtsushi Murai #ifndef SIGALRM
634af57ed9fSAtsushi Murai     /*
63584b8a6ebSAtsushi Murai      *  Normally, select() will not block because modem is writable.
63684b8a6ebSAtsushi Murai      *  In AUTO mode, select will block until we find packet from tun
637af57ed9fSAtsushi Murai      */
638af57ed9fSAtsushi Murai     tp = (RedialTimer.state == TIMER_RUNNING)? &timeout : NULL;
639af57ed9fSAtsushi Murai     i = select(tun_in+10, &rfds, &wfds, &efds, tp);
64053c9f6c0SAtsushi Murai #else
64184b8a6ebSAtsushi Murai     /*
64284b8a6ebSAtsushi Murai      * When SIGALRM timer is running, a select function will be
64384b8a6ebSAtsushi Murai      * return -1 and EINTR after a Time Service signal hundler
64484b8a6ebSAtsushi Murai      * is done.
64584b8a6ebSAtsushi Murai      */
64653c9f6c0SAtsushi Murai     i = select(tun_in+10, &rfds, &wfds, &efds, NULL);
64753c9f6c0SAtsushi Murai #endif
648af57ed9fSAtsushi Murai     if ( i == 0 ) {
649af57ed9fSAtsushi Murai         continue;
650af57ed9fSAtsushi Murai     }
65153c9f6c0SAtsushi Murai 
652af57ed9fSAtsushi Murai     if ( i < 0 ) {
65384b8a6ebSAtsushi Murai        if ( errno == EINTR ) {
65484b8a6ebSAtsushi Murai           continue;            /* Got SIGALRM, Do check a queue for dailing */
65584b8a6ebSAtsushi Murai        }
656af57ed9fSAtsushi Murai        perror("select");
657af57ed9fSAtsushi Murai        break;
658af57ed9fSAtsushi Murai     }
65984b8a6ebSAtsushi Murai 
660af57ed9fSAtsushi Murai     if ((netfd > 0 && FD_ISSET(netfd, &efds)) || FD_ISSET(modem, &efds)) {
661af57ed9fSAtsushi Murai       logprintf("Exception detected.\n");
662af57ed9fSAtsushi Murai       break;
663af57ed9fSAtsushi Murai     }
664af57ed9fSAtsushi Murai 
665af57ed9fSAtsushi Murai     if (server > 0 && FD_ISSET(server, &rfds)) {
666af57ed9fSAtsushi Murai #ifdef DEBUG
667af57ed9fSAtsushi Murai       logprintf("connected to client.\n");
668af57ed9fSAtsushi Murai #endif
669af57ed9fSAtsushi Murai       wfd = accept(server, (struct sockaddr *)&hisaddr, &ssize);
670af57ed9fSAtsushi Murai       if (netfd > 0) {
671af57ed9fSAtsushi Murai 	write(wfd, "already in use.\n", 16);
672af57ed9fSAtsushi Murai 	close(wfd);
673af57ed9fSAtsushi Murai 	continue;
674af57ed9fSAtsushi Murai       } else
675af57ed9fSAtsushi Murai 	netfd = wfd;
676af57ed9fSAtsushi Murai       if (dup2(netfd, 1) < 0)
677af57ed9fSAtsushi Murai 	perror("dup2");
678af57ed9fSAtsushi Murai       mode |= MODE_INTER;
679af57ed9fSAtsushi Murai       Greetings();
68041db6564SAtsushi Murai       switch ( LocalAuthInit() ) {
68141db6564SAtsushi Murai          case NOT_FOUND:
68241db6564SAtsushi Murai     	    fprintf(stdout,LAUTH_M1);
68341db6564SAtsushi Murai     	    fprintf(stdout,LAUTH_M2);
68441db6564SAtsushi Murai             fflush(stdout);
68541db6564SAtsushi Murai 	    /* Fall down */
68641db6564SAtsushi Murai          case VALID:
68741db6564SAtsushi Murai 	    VarLocalAuth = LOCAL_AUTH;
68841db6564SAtsushi Murai 	    break;
68941db6564SAtsushi Murai          default:
69041db6564SAtsushi Murai 	    break;
69141db6564SAtsushi Murai       }
692af57ed9fSAtsushi Murai       (void) IsInteractive();
693af57ed9fSAtsushi Murai       Prompt(0);
694af57ed9fSAtsushi Murai     }
695af57ed9fSAtsushi Murai 
696af57ed9fSAtsushi Murai     if ((mode & MODE_INTER) && FD_ISSET(netfd, &rfds)) {
697af57ed9fSAtsushi Murai       /* something to read from tty */
698af57ed9fSAtsushi Murai       ReadTty();
699af57ed9fSAtsushi Murai     }
700af57ed9fSAtsushi Murai     if (modem) {
701af57ed9fSAtsushi Murai       if (FD_ISSET(modem, &wfds)) {	/* ready to write into modem */
702af57ed9fSAtsushi Murai 	 ModemStartOutput(modem);
703af57ed9fSAtsushi Murai       }
704af57ed9fSAtsushi Murai       if (FD_ISSET(modem, &rfds)) {	/* something to read from modem */
70553c9f6c0SAtsushi Murai 	if (LcpFsm.state <= ST_CLOSED)
70653c9f6c0SAtsushi Murai 	  usleep(10000);
707af57ed9fSAtsushi Murai 	n = read(modem, rbuff, sizeof(rbuff));
708af57ed9fSAtsushi Murai 	if ((mode & MODE_DIRECT) && n <= 0) {
709af57ed9fSAtsushi Murai 	  DownConnection();
710af57ed9fSAtsushi Murai 	} else
711af57ed9fSAtsushi Murai           LogDumpBuff(LOG_ASYNC, "ReadFromModem", rbuff, n);
712af57ed9fSAtsushi Murai 
713af57ed9fSAtsushi Murai 	if (LcpFsm.state <= ST_CLOSED) {
714af57ed9fSAtsushi Murai 	  /*
715af57ed9fSAtsushi Murai 	   *  In dedicated mode, we just discard input until LCP is started.
716af57ed9fSAtsushi Murai 	   */
717af57ed9fSAtsushi Murai 	  if (!(mode & MODE_DEDICATED)) {
718af57ed9fSAtsushi Murai 	    cp = HdlcDetect(rbuff, n);
719af57ed9fSAtsushi Murai 	    if (cp) {
720af57ed9fSAtsushi Murai 	      /*
721af57ed9fSAtsushi Murai 	       * LCP packet is detected. Turn ourselves into packet mode.
722af57ed9fSAtsushi Murai 	       */
723af57ed9fSAtsushi Murai 	      if (cp != rbuff) {
724af57ed9fSAtsushi Murai 	        write(1, rbuff, cp - rbuff);
725af57ed9fSAtsushi Murai 	        write(1, "\r\n", 2);
726af57ed9fSAtsushi Murai 	      }
727af57ed9fSAtsushi Murai 	      PacketMode();
728af57ed9fSAtsushi Murai #ifdef notdef
729af57ed9fSAtsushi Murai 	      AsyncInput(cp, n - (cp - rbuff));
730af57ed9fSAtsushi Murai #endif
731af57ed9fSAtsushi Murai 	    } else
732af57ed9fSAtsushi Murai 	      write(1, rbuff, n);
733af57ed9fSAtsushi Murai 	  }
734af57ed9fSAtsushi Murai 	} else {
735af57ed9fSAtsushi Murai 	  if (n > 0)
736af57ed9fSAtsushi Murai 	    AsyncInput(rbuff, n);
737af57ed9fSAtsushi Murai #ifdef notdef
738af57ed9fSAtsushi Murai 	  continue;			/* THIS LINE RESULT AS POOR PERFORMANCE */
739af57ed9fSAtsushi Murai #endif
740af57ed9fSAtsushi Murai 	}
741af57ed9fSAtsushi Murai       }
742af57ed9fSAtsushi Murai     }
74384b8a6ebSAtsushi Murai 
744af57ed9fSAtsushi Murai     if (FD_ISSET(tun_in, &rfds)) {	/* something to read from tun */
745af57ed9fSAtsushi Murai       /*
746af57ed9fSAtsushi Murai        *  If there are many packets queued, wait until they are drained.
747af57ed9fSAtsushi Murai        */
748af57ed9fSAtsushi Murai       if (ModemQlen() > 5)
749af57ed9fSAtsushi Murai 	continue;
750af57ed9fSAtsushi Murai 
751af57ed9fSAtsushi Murai       n = read(tun_in, rbuff, sizeof(rbuff));
752af57ed9fSAtsushi Murai       if (n < 0) {
753af57ed9fSAtsushi Murai 	perror("read from tun");
754af57ed9fSAtsushi Murai 	continue;
755af57ed9fSAtsushi Murai       }
756af57ed9fSAtsushi Murai       /*
757af57ed9fSAtsushi Murai        *  Process on-demand dialup. Output packets are queued within tunnel
758af57ed9fSAtsushi Murai        *  device until IPCP is opened.
759af57ed9fSAtsushi Murai        */
760af57ed9fSAtsushi Murai       if (LcpFsm.state <= ST_CLOSED && (mode & MODE_AUTO)) {
76184b8a6ebSAtsushi Murai 	pri = PacketCheck(rbuff, n, FL_DIAL);
762af57ed9fSAtsushi Murai 	if (pri >= 0) {
763af57ed9fSAtsushi Murai 	  IpEnqueue(pri, rbuff, n);
76484b8a6ebSAtsushi Murai           dial_up = TRUE;		/* XXX */
765af57ed9fSAtsushi Murai 	}
766af57ed9fSAtsushi Murai 	continue;
767af57ed9fSAtsushi Murai       }
76884b8a6ebSAtsushi Murai       pri = PacketCheck(rbuff, n, FL_OUT);
769af57ed9fSAtsushi Murai       if (pri >= 0)
770af57ed9fSAtsushi Murai 	IpEnqueue(pri, rbuff, n);
771af57ed9fSAtsushi Murai     }
772af57ed9fSAtsushi Murai   }
773af57ed9fSAtsushi Murai   logprintf("job done.\n");
774af57ed9fSAtsushi Murai }
775