xref: /freebsd/usr.sbin/ppp/main.c (revision 53c9f6c0c48df668bb8fa282cd0b12cb8690bcce)
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  *
20af57ed9fSAtsushi Murai  * $Id:$
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"
4353c9f6c0SAtsushi Murai 
4453c9f6c0SAtsushi Murai #ifndef O_NONBLOCK
4553c9f6c0SAtsushi Murai #ifdef O_NDELAY
4653c9f6c0SAtsushi Murai #define	O_NONBLOCK O_NDELAY
4753c9f6c0SAtsushi Murai #endif
4853c9f6c0SAtsushi Murai #endif
49af57ed9fSAtsushi Murai 
50af57ed9fSAtsushi Murai extern void VjInit(), AsyncInit();
51af57ed9fSAtsushi Murai extern void AsyncInput(), IpOutput();
52af57ed9fSAtsushi Murai extern int  SelectSystem();
53af57ed9fSAtsushi Murai 
54af57ed9fSAtsushi Murai extern void DecodeCommand(), Prompt();
55af57ed9fSAtsushi Murai extern int IsInteractive();
56af57ed9fSAtsushi Murai extern struct in_addr ifnetmask;
57af57ed9fSAtsushi Murai static void DoLoop(void);
58af57ed9fSAtsushi Murai 
59af57ed9fSAtsushi Murai static struct termios oldtio;		/* Original tty mode */
60af57ed9fSAtsushi Murai static struct termios comtio;		/* Command level tty mode */
61af57ed9fSAtsushi Murai static int TermMode;
62af57ed9fSAtsushi Murai static int server, update;
63af57ed9fSAtsushi Murai struct sockaddr_in ifsin;
64af57ed9fSAtsushi Murai 
65af57ed9fSAtsushi Murai static void
66af57ed9fSAtsushi Murai TtyInit()
67af57ed9fSAtsushi Murai {
68af57ed9fSAtsushi Murai   struct termios newtio;
69af57ed9fSAtsushi Murai   int stat;
70af57ed9fSAtsushi Murai 
71af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
72af57ed9fSAtsushi Murai   stat |= O_NONBLOCK;
73af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
74af57ed9fSAtsushi Murai   newtio = oldtio;
75af57ed9fSAtsushi Murai   newtio.c_lflag &= ~(ECHO|ISIG|ICANON);
76af57ed9fSAtsushi Murai   newtio.c_iflag = 0;
77af57ed9fSAtsushi Murai   newtio.c_oflag &= ~OPOST;
78af57ed9fSAtsushi Murai   newtio.c_cc[VEOF] = _POSIX_VDISABLE;
79af57ed9fSAtsushi Murai   newtio.c_cc[VINTR] = _POSIX_VDISABLE;
80af57ed9fSAtsushi Murai   newtio.c_cc[VMIN] = 1;
81af57ed9fSAtsushi Murai   newtio.c_cc[VTIME] = 0;
82af57ed9fSAtsushi Murai   newtio.c_cflag |= CS8;
8353c9f6c0SAtsushi Murai   tcsetattr(0, TCSADRAIN, &newtio);
84af57ed9fSAtsushi Murai   comtio = newtio;
85af57ed9fSAtsushi Murai }
86af57ed9fSAtsushi Murai 
87af57ed9fSAtsushi Murai /*
88af57ed9fSAtsushi Murai  *  Set tty into command mode. We allow canonical input and echo processing.
89af57ed9fSAtsushi Murai  */
90af57ed9fSAtsushi Murai static void
91af57ed9fSAtsushi Murai TtyCommandMode()
92af57ed9fSAtsushi Murai {
93af57ed9fSAtsushi Murai   struct termios newtio;
94af57ed9fSAtsushi Murai   int stat;
95af57ed9fSAtsushi Murai 
96af57ed9fSAtsushi Murai   if (!(mode & MODE_INTER))
97af57ed9fSAtsushi Murai     return;
9853c9f6c0SAtsushi Murai   tcgetattr(0, &newtio);
99af57ed9fSAtsushi Murai   newtio.c_lflag |= (ECHO|ICANON);
100af57ed9fSAtsushi Murai   newtio.c_iflag = oldtio.c_iflag;
101af57ed9fSAtsushi Murai   newtio.c_oflag |= OPOST;
10253c9f6c0SAtsushi Murai   tcsetattr(0, TCSADRAIN, &newtio);
103af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
104af57ed9fSAtsushi Murai   stat |= O_NONBLOCK;
105af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
106af57ed9fSAtsushi Murai   TermMode = 0;
107af57ed9fSAtsushi Murai   Prompt(0);
108af57ed9fSAtsushi Murai }
109af57ed9fSAtsushi Murai 
110af57ed9fSAtsushi Murai /*
111af57ed9fSAtsushi Murai  * Set tty into terminal mode which is used while we invoke term command.
112af57ed9fSAtsushi Murai  */
113af57ed9fSAtsushi Murai void
114af57ed9fSAtsushi Murai TtyTermMode()
115af57ed9fSAtsushi Murai {
116af57ed9fSAtsushi Murai   int stat;
117af57ed9fSAtsushi Murai 
11853c9f6c0SAtsushi Murai   tcsetattr(0, TCSADRAIN, &comtio);
119af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
120af57ed9fSAtsushi Murai   stat &= ~O_NONBLOCK;
121af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
122af57ed9fSAtsushi Murai   TermMode = 1;
123af57ed9fSAtsushi Murai }
124af57ed9fSAtsushi Murai 
125af57ed9fSAtsushi Murai void
126af57ed9fSAtsushi Murai Cleanup(excode)
127af57ed9fSAtsushi Murai int excode;
128af57ed9fSAtsushi Murai {
129af57ed9fSAtsushi Murai   int stat;
130af57ed9fSAtsushi Murai 
131af57ed9fSAtsushi Murai   OsLinkdown();
13253c9f6c0SAtsushi Murai #ifdef notdef
133af57ed9fSAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
134af57ed9fSAtsushi Murai   stat &= ~O_NONBLOCK;
135af57ed9fSAtsushi Murai   fcntl(0, F_SETFL, stat);
13653c9f6c0SAtsushi Murai   tcsetattr(0, TCSANOW, &oldtio);
13753c9f6c0SAtsushi Murai #endif
138af57ed9fSAtsushi Murai   OsCloseLink(1);
139af57ed9fSAtsushi Murai   sleep(1);
140af57ed9fSAtsushi Murai   if (mode & MODE_AUTO)
141af57ed9fSAtsushi Murai     DeleteIfRoutes(1);
142af57ed9fSAtsushi Murai   OsInterfaceDown(1);
143af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "PPP Terminated.\n");
144af57ed9fSAtsushi Murai   LogClose();
145af57ed9fSAtsushi Murai   if (server > 0)
146af57ed9fSAtsushi Murai     close(server);
14753c9f6c0SAtsushi Murai #ifndef notdef
14853c9f6c0SAtsushi Murai   stat = fcntl(0, F_GETFL, 0);
14953c9f6c0SAtsushi Murai   stat &= ~O_NONBLOCK;
15053c9f6c0SAtsushi Murai   fcntl(0, F_SETFL, stat);
15153c9f6c0SAtsushi Murai   tcsetattr(0, TCSANOW, &oldtio);
15253c9f6c0SAtsushi Murai #endif
153af57ed9fSAtsushi Murai 
154af57ed9fSAtsushi Murai   exit(excode);
155af57ed9fSAtsushi Murai }
156af57ed9fSAtsushi Murai 
157af57ed9fSAtsushi Murai static void
158af57ed9fSAtsushi Murai Hangup()
159af57ed9fSAtsushi Murai {
160af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "SIGHUP\n");
161af57ed9fSAtsushi Murai   signal(SIGHUP, Hangup);
162af57ed9fSAtsushi Murai   Cleanup(EX_HANGUP);
163af57ed9fSAtsushi Murai }
164af57ed9fSAtsushi Murai 
165af57ed9fSAtsushi Murai static void
166af57ed9fSAtsushi Murai CloseSession()
167af57ed9fSAtsushi Murai {
168af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "SIGTERM\n");
169af57ed9fSAtsushi Murai   LcpClose();
170af57ed9fSAtsushi Murai   Cleanup(EX_TERM);
171af57ed9fSAtsushi Murai }
172af57ed9fSAtsushi Murai 
173af57ed9fSAtsushi Murai void
174af57ed9fSAtsushi Murai Usage()
175af57ed9fSAtsushi Murai {
176af57ed9fSAtsushi Murai   fprintf(stderr, "Usage: ppp [-auto | -direct -dedicated] [system]\n");
177af57ed9fSAtsushi Murai   exit(EX_START);
178af57ed9fSAtsushi Murai }
179af57ed9fSAtsushi Murai 
180af57ed9fSAtsushi Murai void
181af57ed9fSAtsushi Murai ProcessArgs(int argc, char **argv)
182af57ed9fSAtsushi Murai {
183af57ed9fSAtsushi Murai   int optc;
184af57ed9fSAtsushi Murai   char *cp;
185af57ed9fSAtsushi Murai 
186af57ed9fSAtsushi Murai   optc = 0;
187af57ed9fSAtsushi Murai   while (argc > 0 && **argv == '-') {
188af57ed9fSAtsushi Murai     cp = *argv + 1;
189af57ed9fSAtsushi Murai     if (strcmp(cp, "auto") == 0)
190af57ed9fSAtsushi Murai       mode |= MODE_AUTO;
191af57ed9fSAtsushi Murai     else if (strcmp(cp, "direct") == 0)
192af57ed9fSAtsushi Murai       mode |= MODE_DIRECT;
193af57ed9fSAtsushi Murai     else if (strcmp(cp, "dedicated") == 0)
194af57ed9fSAtsushi Murai       mode |= MODE_DEDICATED;
195af57ed9fSAtsushi Murai     else
196af57ed9fSAtsushi Murai       Usage();
197af57ed9fSAtsushi Murai     optc++;
198af57ed9fSAtsushi Murai     argv++; argc--;
199af57ed9fSAtsushi Murai   }
200af57ed9fSAtsushi Murai   if (argc > 1) {
201af57ed9fSAtsushi Murai     fprintf(stderr, "specify only one system label.\n");
202af57ed9fSAtsushi Murai     exit(EX_START);
203af57ed9fSAtsushi Murai   }
204af57ed9fSAtsushi Murai   if (argc == 1) dstsystem = *argv;
205af57ed9fSAtsushi Murai 
206af57ed9fSAtsushi Murai   if (optc > 1) {
207af57ed9fSAtsushi Murai     fprintf(stderr, "specify only one mode.\n");
208af57ed9fSAtsushi Murai     exit(EX_START);
209af57ed9fSAtsushi Murai   }
210af57ed9fSAtsushi Murai }
211af57ed9fSAtsushi Murai 
212af57ed9fSAtsushi Murai static void
213af57ed9fSAtsushi Murai Greetings()
214af57ed9fSAtsushi Murai {
215af57ed9fSAtsushi Murai   printf("User Process PPP. Written by Toshiharu OHNO.\r\n");
216af57ed9fSAtsushi Murai   fflush(stdout);
217af57ed9fSAtsushi Murai }
218af57ed9fSAtsushi Murai 
219af57ed9fSAtsushi Murai void
220af57ed9fSAtsushi Murai main(argc, argv)
221af57ed9fSAtsushi Murai int argc;
222af57ed9fSAtsushi Murai char **argv;
223af57ed9fSAtsushi Murai {
224af57ed9fSAtsushi Murai   int tunno;
225af57ed9fSAtsushi Murai   int on = 1;
226af57ed9fSAtsushi Murai 
227af57ed9fSAtsushi Murai   argc--; argv++;
228af57ed9fSAtsushi Murai 
229af57ed9fSAtsushi Murai   mode = MODE_INTER;		/* default operation is interactive mode */
230af57ed9fSAtsushi Murai   netfd = -1;
231af57ed9fSAtsushi Murai   ProcessArgs(argc, argv);
232af57ed9fSAtsushi Murai   Greetings();
233af57ed9fSAtsushi Murai   GetUid();
234af57ed9fSAtsushi Murai   IpcpDefAddress();
235af57ed9fSAtsushi Murai 
236af57ed9fSAtsushi Murai   if (SelectSystem("default", CONFFILE) < 0) {
237af57ed9fSAtsushi Murai     fprintf(stderr, "Warning: No default entry is given in config file.\n");
238af57ed9fSAtsushi Murai   }
239af57ed9fSAtsushi Murai 
240af57ed9fSAtsushi Murai   if (LogOpen())
241af57ed9fSAtsushi Murai     exit(EX_START);
242af57ed9fSAtsushi Murai 
24353c9f6c0SAtsushi Murai   switch ( LocalAuthInit() ) {
24453c9f6c0SAtsushi Murai     case NOT_FOUND:
24553c9f6c0SAtsushi Murai     	fprintf(stderr, "Warning: No password entry in secret file\n");
24653c9f6c0SAtsushi Murai     	fprintf(stderr, "Warning: Anyone is allowd manipulating!!!\n");
24753c9f6c0SAtsushi Murai 	VarLocalAuth = LOCAL_AUTH;
24853c9f6c0SAtsushi Murai 	break;
24953c9f6c0SAtsushi Murai     default:
25053c9f6c0SAtsushi Murai 	break;
25153c9f6c0SAtsushi Murai   }
25253c9f6c0SAtsushi Murai 
253af57ed9fSAtsushi Murai   if (OpenTunnel(&tunno) < 0) {
254af57ed9fSAtsushi Murai     perror("open_tun");
255af57ed9fSAtsushi Murai     exit(EX_START);
256af57ed9fSAtsushi Murai   }
257af57ed9fSAtsushi Murai 
258af57ed9fSAtsushi Murai   if (mode & (MODE_AUTO|MODE_DIRECT|MODE_DEDICATED))
259af57ed9fSAtsushi Murai     mode &= ~MODE_INTER;
260af57ed9fSAtsushi Murai   if (mode & MODE_INTER) {
261af57ed9fSAtsushi Murai     printf("Interactive mode\n");
262af57ed9fSAtsushi Murai     netfd = 0;
263af57ed9fSAtsushi Murai   } else if (mode & MODE_AUTO) {
264af57ed9fSAtsushi Murai     printf("Automatic mode\n");
265af57ed9fSAtsushi Murai     if (dstsystem == NULL) {
266af57ed9fSAtsushi Murai       fprintf(stderr, "Destination system must be specified in auto mode.\n");
267af57ed9fSAtsushi Murai       exit(EX_START);
268af57ed9fSAtsushi Murai     }
269af57ed9fSAtsushi Murai   }
270af57ed9fSAtsushi Murai 
27153c9f6c0SAtsushi Murai   tcgetattr(0, &oldtio);		/* Save original tty mode */
272af57ed9fSAtsushi Murai 
273af57ed9fSAtsushi Murai   signal(SIGHUP, Hangup);
274af57ed9fSAtsushi Murai   signal(SIGTERM, CloseSession);
275af57ed9fSAtsushi Murai   signal(SIGINT, CloseSession);
27653c9f6c0SAtsushi Murai #ifdef SIGSEGV
277af57ed9fSAtsushi Murai   signal(SIGSEGV, Hangup);
27853c9f6c0SAtsushi Murai #endif
27953c9f6c0SAtsushi Murai #ifdef SIGPIPE
28053c9f6c0SAtsushi Murai   signal(SIGPIPE, Hangup);
28153c9f6c0SAtsushi Murai #endif
28253c9f6c0SAtsushi Murai #ifdef SIGALRM
28353c9f6c0SAtsushi Murai   signal(SIGALRM, SIG_IGN);
28453c9f6c0SAtsushi Murai #endif
285af57ed9fSAtsushi Murai 
286af57ed9fSAtsushi Murai   if (dstsystem) {
287af57ed9fSAtsushi Murai     if (SelectSystem(dstsystem, CONFFILE) < 0) {
288af57ed9fSAtsushi Murai       fprintf(stderr, "Destination system not found in conf file.\n");
289af57ed9fSAtsushi Murai       Cleanup(EX_START);
290af57ed9fSAtsushi Murai     }
291af57ed9fSAtsushi Murai     if ((mode & MODE_AUTO) && DefHisAddress.ipaddr.s_addr == INADDR_ANY) {
292af57ed9fSAtsushi Murai       fprintf(stderr, "Must specify dstaddr with auto mode.\n");
293af57ed9fSAtsushi Murai       Cleanup(EX_START);
294af57ed9fSAtsushi Murai     }
295af57ed9fSAtsushi Murai   }
296af57ed9fSAtsushi Murai   if (mode & MODE_DIRECT)
297af57ed9fSAtsushi Murai     printf("Packet mode enabled.\n");
298af57ed9fSAtsushi Murai 
299af57ed9fSAtsushi Murai #ifdef notdef
300af57ed9fSAtsushi Murai   if (mode & MODE_AUTO) {
301af57ed9fSAtsushi Murai     OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask);
302af57ed9fSAtsushi Murai   }
303af57ed9fSAtsushi Murai #endif
304af57ed9fSAtsushi Murai 
305af57ed9fSAtsushi Murai   if (!(mode & MODE_INTER)) {
306af57ed9fSAtsushi Murai      int port = SERVER_PORT + tunno;
307af57ed9fSAtsushi Murai     /*
308af57ed9fSAtsushi Murai      *  Create server socket and listen at there.
309af57ed9fSAtsushi Murai      */
310af57ed9fSAtsushi Murai     server = socket(PF_INET, SOCK_STREAM, 0);
311af57ed9fSAtsushi Murai     if (server < 0) {
312af57ed9fSAtsushi Murai       perror("socket");
313af57ed9fSAtsushi Murai       Cleanup(EX_SOCK);
314af57ed9fSAtsushi Murai     }
315af57ed9fSAtsushi Murai     ifsin.sin_family = AF_INET;
316af57ed9fSAtsushi Murai     ifsin.sin_addr.s_addr = INADDR_ANY;
317af57ed9fSAtsushi Murai     ifsin.sin_port = htons(port);
318af57ed9fSAtsushi Murai     if (bind(server, (struct sockaddr *) &ifsin, sizeof(ifsin)) < 0) {
319af57ed9fSAtsushi Murai       perror("bind");
320af57ed9fSAtsushi Murai       if (errno == EADDRINUSE)
321af57ed9fSAtsushi Murai 	fprintf(stderr, "Wait for a while, then try again.\n");
322af57ed9fSAtsushi Murai       Cleanup(EX_SOCK);
323af57ed9fSAtsushi Murai     }
324af57ed9fSAtsushi Murai     listen(server, 5);
325af57ed9fSAtsushi Murai 
326af57ed9fSAtsushi Murai     DupLog();
327af57ed9fSAtsushi Murai     if (!(mode & MODE_DIRECT)) {
328af57ed9fSAtsushi Murai       if (fork())
329af57ed9fSAtsushi Murai         exit(0);
330af57ed9fSAtsushi Murai     }
331af57ed9fSAtsushi Murai     LogPrintf(LOG_PHASE, "Listening at %d.\n", port);
332af57ed9fSAtsushi Murai #ifdef DOTTYINIT
33353c9f6c0SAtsushi Murai     if (mode & (MODE_DIRECT|MODE_DEDICATED)) { /* } */
334af57ed9fSAtsushi Murai #else
335af57ed9fSAtsushi Murai     if (mode & MODE_DIRECT) {
336af57ed9fSAtsushi Murai #endif
337af57ed9fSAtsushi Murai       TtyInit();
338af57ed9fSAtsushi Murai     } else {
339af57ed9fSAtsushi Murai       setsid();			/* detach control tty */
340af57ed9fSAtsushi Murai     }
341af57ed9fSAtsushi Murai   } else {
342af57ed9fSAtsushi Murai     server = -1;
343af57ed9fSAtsushi Murai     TtyInit();
344af57ed9fSAtsushi Murai     TtyCommandMode();
345af57ed9fSAtsushi Murai   }
346af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "PPP Started.\n");
347af57ed9fSAtsushi Murai 
348af57ed9fSAtsushi Murai 
349af57ed9fSAtsushi Murai   do
350af57ed9fSAtsushi Murai    DoLoop();
351af57ed9fSAtsushi Murai   while (mode & MODE_DEDICATED);
352af57ed9fSAtsushi Murai 
353af57ed9fSAtsushi Murai   Cleanup(EX_DONE);
354af57ed9fSAtsushi Murai }
355af57ed9fSAtsushi Murai 
356af57ed9fSAtsushi Murai /*
357af57ed9fSAtsushi Murai  *  Turn into packet mode, where we speek PPP.
358af57ed9fSAtsushi Murai  */
359af57ed9fSAtsushi Murai void
360af57ed9fSAtsushi Murai PacketMode()
361af57ed9fSAtsushi Murai {
362af57ed9fSAtsushi Murai   if (RawModem(modem) < 0) {
363af57ed9fSAtsushi Murai     fprintf(stderr, "Not connected.\r\n");
364af57ed9fSAtsushi Murai     return;
365af57ed9fSAtsushi Murai   }
366af57ed9fSAtsushi Murai 
367af57ed9fSAtsushi Murai   AsyncInit();
368af57ed9fSAtsushi Murai   VjInit();
369af57ed9fSAtsushi Murai   LcpInit();
370af57ed9fSAtsushi Murai   IpcpInit();
371af57ed9fSAtsushi Murai   CcpInit();
372af57ed9fSAtsushi Murai   LcpUp();
373af57ed9fSAtsushi Murai 
374af57ed9fSAtsushi Murai   if (mode & (MODE_DIRECT|MODE_DEDICATED))
375af57ed9fSAtsushi Murai     LcpOpen(OPEN_ACTIVE);
376af57ed9fSAtsushi Murai   else
377af57ed9fSAtsushi Murai     LcpOpen(VarOpenMode);
378af57ed9fSAtsushi Murai   if ((mode & (MODE_INTER|MODE_AUTO)) == MODE_INTER) {
379af57ed9fSAtsushi Murai     TtyCommandMode();
380af57ed9fSAtsushi Murai     fprintf(stderr, "Packet mode.\r\n");
381af57ed9fSAtsushi Murai   }
382af57ed9fSAtsushi Murai }
383af57ed9fSAtsushi Murai 
384af57ed9fSAtsushi Murai static void
385af57ed9fSAtsushi Murai ShowHelp()
386af57ed9fSAtsushi Murai {
387af57ed9fSAtsushi Murai   fprintf(stderr, "Following commands are available\r\n");
388af57ed9fSAtsushi Murai   fprintf(stderr, " ~p\tEnter to Packet mode\r\n");
389af57ed9fSAtsushi Murai   fprintf(stderr, " ~.\tTerminate program\r\n");
390af57ed9fSAtsushi Murai }
391af57ed9fSAtsushi Murai 
392af57ed9fSAtsushi Murai static void
393af57ed9fSAtsushi Murai ReadTty()
394af57ed9fSAtsushi Murai {
395af57ed9fSAtsushi Murai   int n;
396af57ed9fSAtsushi Murai   char ch;
397af57ed9fSAtsushi Murai   static int ttystate;
398af57ed9fSAtsushi Murai #define MAXLINESIZE 200
399af57ed9fSAtsushi Murai   char linebuff[MAXLINESIZE];
400af57ed9fSAtsushi Murai 
401af57ed9fSAtsushi Murai #ifdef DEBUG
402af57ed9fSAtsushi Murai   logprintf("termode = %d, netfd = %d, mode = %d\n", TermMode, netfd, mode);
403af57ed9fSAtsushi Murai #endif
404af57ed9fSAtsushi Murai   if (!TermMode) {
405af57ed9fSAtsushi Murai     n = read(netfd, linebuff, sizeof(linebuff)-1);
40653c9f6c0SAtsushi Murai     if (n > 0) {
407af57ed9fSAtsushi Murai       DecodeCommand(linebuff, n, 1);
40853c9f6c0SAtsushi Murai     } else {
409af57ed9fSAtsushi Murai #ifdef DEBUG
410af57ed9fSAtsushi Murai       logprintf("connection closed.\n");
411af57ed9fSAtsushi Murai #endif
41253c9f6c0SAtsushi Murai       VarLocalAuth = LOCAL_NO_AUTH;
413af57ed9fSAtsushi Murai       close(netfd);
414af57ed9fSAtsushi Murai       netfd = -1;
415af57ed9fSAtsushi Murai       mode &= ~MODE_INTER;
416af57ed9fSAtsushi Murai     }
417af57ed9fSAtsushi Murai     return;
418af57ed9fSAtsushi Murai   }
419af57ed9fSAtsushi Murai 
420af57ed9fSAtsushi Murai   /*
421af57ed9fSAtsushi Murai    *  We are in terminal mode, decode special sequences
422af57ed9fSAtsushi Murai    */
423af57ed9fSAtsushi Murai   n = read(0, &ch, 1);
424af57ed9fSAtsushi Murai #ifdef DEBUG
425af57ed9fSAtsushi Murai   logprintf("got %d bytes\n", n);
426af57ed9fSAtsushi Murai #endif
427af57ed9fSAtsushi Murai 
428af57ed9fSAtsushi Murai   if (n > 0) {
429af57ed9fSAtsushi Murai     switch (ttystate) {
430af57ed9fSAtsushi Murai     case 0:
431af57ed9fSAtsushi Murai       if (ch == '~')
432af57ed9fSAtsushi Murai 	ttystate++;
433af57ed9fSAtsushi Murai       else
434af57ed9fSAtsushi Murai 	write(modem, &ch, n);
435af57ed9fSAtsushi Murai       break;
436af57ed9fSAtsushi Murai     case 1:
437af57ed9fSAtsushi Murai       switch (ch) {
438af57ed9fSAtsushi Murai       case '?':
439af57ed9fSAtsushi Murai 	ShowHelp();
440af57ed9fSAtsushi Murai 	break;
441af57ed9fSAtsushi Murai       case '-':
442af57ed9fSAtsushi Murai 	if (loglevel > 0) {
443af57ed9fSAtsushi Murai 	  loglevel--;
444af57ed9fSAtsushi Murai 	  fprintf(stderr, "New loglevel is %d\r\n", loglevel);
445af57ed9fSAtsushi Murai 	}
446af57ed9fSAtsushi Murai 	break;
447af57ed9fSAtsushi Murai       case '+':
448af57ed9fSAtsushi Murai 	loglevel++;
449af57ed9fSAtsushi Murai 	fprintf(stderr, "New loglevel is %d\r\n", loglevel);
450af57ed9fSAtsushi Murai 	break;
451af57ed9fSAtsushi Murai #ifdef DEBUG
452af57ed9fSAtsushi Murai       case 'm':
453af57ed9fSAtsushi Murai 	ShowMemMap();
454af57ed9fSAtsushi Murai 	break;
455af57ed9fSAtsushi Murai #endif
456af57ed9fSAtsushi Murai       case 'p':
457af57ed9fSAtsushi Murai 	/*
458af57ed9fSAtsushi Murai 	 * XXX: Should check carrier.
459af57ed9fSAtsushi Murai 	 */
460af57ed9fSAtsushi Murai 	if (LcpFsm.state <= ST_CLOSED) {
461af57ed9fSAtsushi Murai 	  VarOpenMode = OPEN_ACTIVE;
462af57ed9fSAtsushi Murai 	  PacketMode();
463af57ed9fSAtsushi Murai 	}
464af57ed9fSAtsushi Murai 	break;
465af57ed9fSAtsushi Murai #ifdef DEBUG
466af57ed9fSAtsushi Murai       case 't':
467af57ed9fSAtsushi Murai 	ShowTimers();
468af57ed9fSAtsushi Murai 	break;
469af57ed9fSAtsushi Murai #endif
470af57ed9fSAtsushi Murai       case '.':
471af57ed9fSAtsushi Murai 	TermMode = 1;
472af57ed9fSAtsushi Murai 	TtyCommandMode();
473af57ed9fSAtsushi Murai 	break;
474af57ed9fSAtsushi Murai       default:
475af57ed9fSAtsushi Murai 	if (write(modem, &ch, n) < 0)
476af57ed9fSAtsushi Murai 	  fprintf(stderr, "err in write.\r\n");
477af57ed9fSAtsushi Murai 	break;
478af57ed9fSAtsushi Murai       }
479af57ed9fSAtsushi Murai       ttystate = 0;
480af57ed9fSAtsushi Murai       break;
481af57ed9fSAtsushi Murai     }
482af57ed9fSAtsushi Murai   }
483af57ed9fSAtsushi Murai }
484af57ed9fSAtsushi Murai 
485af57ed9fSAtsushi Murai 
486af57ed9fSAtsushi Murai /*
487af57ed9fSAtsushi Murai  *  Here, we'll try to detect HDLC frame
488af57ed9fSAtsushi Murai  */
489af57ed9fSAtsushi Murai 
490af57ed9fSAtsushi Murai static char *FrameHeaders[] = {
49153c9f6c0SAtsushi Murai   "\176\377\003\300\041",
49253c9f6c0SAtsushi Murai   "\176\377\175\043\300\041",
49353c9f6c0SAtsushi Murai   "\176\177\175\043\100\041",
49453c9f6c0SAtsushi Murai   "\176\175\337\175\043\300\041",
49553c9f6c0SAtsushi Murai   "\176\175\137\175\043\100\041",
496af57ed9fSAtsushi Murai   NULL,
497af57ed9fSAtsushi Murai };
498af57ed9fSAtsushi Murai 
499af57ed9fSAtsushi Murai u_char *
500af57ed9fSAtsushi Murai HdlcDetect(cp, n)
501af57ed9fSAtsushi Murai u_char *cp;
502af57ed9fSAtsushi Murai int n;
503af57ed9fSAtsushi Murai {
50453c9f6c0SAtsushi Murai   char *ptr, *fp, **hp;
505af57ed9fSAtsushi Murai 
506af57ed9fSAtsushi Murai   cp[n] = '\0';	/* be sure to null terminated */
507af57ed9fSAtsushi Murai   ptr = NULL;
508af57ed9fSAtsushi Murai   for (hp = FrameHeaders; *hp; hp++) {
50953c9f6c0SAtsushi Murai     fp = *hp;
51053c9f6c0SAtsushi Murai     if (DEV_IS_SYNC)
51153c9f6c0SAtsushi Murai       fp++;
51253c9f6c0SAtsushi Murai     if (ptr = strstr((char *)cp, fp))
513af57ed9fSAtsushi Murai       break;
514af57ed9fSAtsushi Murai   }
515af57ed9fSAtsushi Murai   return((u_char *)ptr);
516af57ed9fSAtsushi Murai }
517af57ed9fSAtsushi Murai 
518af57ed9fSAtsushi Murai static struct pppTimer RedialTimer;
519af57ed9fSAtsushi Murai 
520af57ed9fSAtsushi Murai static void
521af57ed9fSAtsushi Murai RedialTimeout()
522af57ed9fSAtsushi Murai {
523af57ed9fSAtsushi Murai   StopTimer(&RedialTimer);
524af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "Redialing timer expired.\n");
525af57ed9fSAtsushi Murai }
526af57ed9fSAtsushi Murai 
527af57ed9fSAtsushi Murai static void
528af57ed9fSAtsushi Murai StartRedialTimer()
529af57ed9fSAtsushi Murai {
530af57ed9fSAtsushi Murai   LogPrintf(LOG_PHASE, "Enter pause for redialing.\n");
531af57ed9fSAtsushi Murai   StopTimer(&RedialTimer);
532af57ed9fSAtsushi Murai   RedialTimer.state = TIMER_STOPPED;
533af57ed9fSAtsushi Murai   RedialTimer.load = REDIAL_PERIOD * SECTICKS;
534af57ed9fSAtsushi Murai   RedialTimer.func = RedialTimeout;
535af57ed9fSAtsushi Murai   StartTimer(&RedialTimer);
536af57ed9fSAtsushi Murai }
537af57ed9fSAtsushi Murai 
538af57ed9fSAtsushi Murai 
539af57ed9fSAtsushi Murai static void
540af57ed9fSAtsushi Murai DoLoop()
541af57ed9fSAtsushi Murai {
542af57ed9fSAtsushi Murai   fd_set rfds, wfds, efds;
543af57ed9fSAtsushi Murai   int pri, i, n, wfd;
544af57ed9fSAtsushi Murai   struct sockaddr_in hisaddr;
545af57ed9fSAtsushi Murai   struct timeval timeout, *tp;
546af57ed9fSAtsushi Murai   int ssize = sizeof(hisaddr);
547af57ed9fSAtsushi Murai   u_char *cp;
548af57ed9fSAtsushi Murai   u_char rbuff[MAX_MRU];
54953c9f6c0SAtsushi Murai   struct itimerval itimer;
550af57ed9fSAtsushi Murai 
551af57ed9fSAtsushi Murai   if (mode & MODE_DIRECT) {
552af57ed9fSAtsushi Murai     modem = OpenModem(mode);
553af57ed9fSAtsushi Murai     fprintf(stderr, "Packet mode enabled\n");
554af57ed9fSAtsushi Murai     PacketMode();
555af57ed9fSAtsushi Murai   } else if (mode & MODE_DEDICATED) {
556af57ed9fSAtsushi Murai     if (!modem)
557af57ed9fSAtsushi Murai       modem = OpenModem(mode);
558af57ed9fSAtsushi Murai   }
559af57ed9fSAtsushi Murai 
560af57ed9fSAtsushi Murai   fflush(stdout);
561af57ed9fSAtsushi Murai 
562af57ed9fSAtsushi Murai   timeout.tv_sec = 0;;
56353c9f6c0SAtsushi Murai #ifdef SIGALRM
56453c9f6c0SAtsushi Murai   signal(SIGALRM, (void (*)(int))TimerService);
56553c9f6c0SAtsushi Murai   itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0;
56653c9f6c0SAtsushi Murai   itimer.it_interval.tv_usec = itimer.it_value.tv_usec = TICKUNIT;
56753c9f6c0SAtsushi Murai   setitimer(ITIMER_REAL, &itimer, NULL);
56853c9f6c0SAtsushi Murai #else
569af57ed9fSAtsushi Murai   timeout.tv_usec = 0;
57053c9f6c0SAtsushi Murai #endif
571af57ed9fSAtsushi Murai 
572af57ed9fSAtsushi Murai   for (;;) {
573af57ed9fSAtsushi Murai     IpStartOutput();
574af57ed9fSAtsushi Murai     FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
575af57ed9fSAtsushi Murai     FD_SET(tun_in, &rfds);
576af57ed9fSAtsushi Murai     if (server > 0) FD_SET(server, &rfds);
577af57ed9fSAtsushi Murai 
578af57ed9fSAtsushi Murai     /*  *** IMPORTANT ***
579af57ed9fSAtsushi Murai      *
580af57ed9fSAtsushi Murai      *  CPU is serviced every TICKUNIT micro seconds.
581af57ed9fSAtsushi Murai      *	This value must be chosen with great care. If this values is
582af57ed9fSAtsushi Murai      *  too big, it results loss of characters from modem and poor responce.
583af57ed9fSAtsushi Murai      *  If this values is too small, ppp process eats many CPU time.
584af57ed9fSAtsushi Murai      */
58553c9f6c0SAtsushi Murai #ifndef SIGALRM
586af57ed9fSAtsushi Murai     usleep(TICKUNIT);
587af57ed9fSAtsushi Murai     TimerService();
58853c9f6c0SAtsushi Murai #endif
589af57ed9fSAtsushi Murai 
590af57ed9fSAtsushi Murai     if (modem) {
591af57ed9fSAtsushi Murai       FD_SET(modem, &rfds);
592af57ed9fSAtsushi Murai       FD_SET(modem, &efds);
59353c9f6c0SAtsushi Murai       if (ModemQlen() > 0) {
594af57ed9fSAtsushi Murai 	FD_SET(modem, &wfds);
595af57ed9fSAtsushi Murai       }
59653c9f6c0SAtsushi Murai     }
597af57ed9fSAtsushi Murai     if (netfd > -1) {
598af57ed9fSAtsushi Murai       FD_SET(netfd, &rfds);
599af57ed9fSAtsushi Murai       FD_SET(netfd, &efds);
600af57ed9fSAtsushi Murai     }
60153c9f6c0SAtsushi Murai #ifndef SIGALRM
602af57ed9fSAtsushi Murai     /*
603af57ed9fSAtsushi Murai      *  Normally, slect() will not block because modem is writable.
604af57ed9fSAtsushi Murai      *  In AUTO mode, select will block until we find packet from tun.
605af57ed9fSAtsushi Murai      *  However, we have to run ourselves while we are in redial wait state.
606af57ed9fSAtsushi Murai      */
607af57ed9fSAtsushi Murai     tp = (RedialTimer.state == TIMER_RUNNING)? &timeout : NULL;
608af57ed9fSAtsushi Murai     i = select(tun_in+10, &rfds, &wfds, &efds, tp);
60953c9f6c0SAtsushi Murai #else
61053c9f6c0SAtsushi Murai     i = select(tun_in+10, &rfds, &wfds, &efds, NULL);
61153c9f6c0SAtsushi Murai #endif
612af57ed9fSAtsushi Murai     if (i == 0) {
613af57ed9fSAtsushi Murai       continue;
614af57ed9fSAtsushi Murai     }
61553c9f6c0SAtsushi Murai 
616af57ed9fSAtsushi Murai     if (i < 0) {
61753c9f6c0SAtsushi Murai       if (errno == EINTR)
61853c9f6c0SAtsushi Murai 	continue;
619af57ed9fSAtsushi Murai       perror("select");
620af57ed9fSAtsushi Murai       break;
621af57ed9fSAtsushi Murai     }
622af57ed9fSAtsushi Murai     if ((netfd > 0 && FD_ISSET(netfd, &efds)) || FD_ISSET(modem, &efds)) {
623af57ed9fSAtsushi Murai       logprintf("Exception detected.\n");
624af57ed9fSAtsushi Murai       break;
625af57ed9fSAtsushi Murai     }
626af57ed9fSAtsushi Murai 
627af57ed9fSAtsushi Murai     if (server > 0 && FD_ISSET(server, &rfds)) {
628af57ed9fSAtsushi Murai #ifdef DEBUG
629af57ed9fSAtsushi Murai       logprintf("connected to client.\n");
630af57ed9fSAtsushi Murai #endif
631af57ed9fSAtsushi Murai       wfd = accept(server, (struct sockaddr *)&hisaddr, &ssize);
632af57ed9fSAtsushi Murai       if (netfd > 0) {
633af57ed9fSAtsushi Murai 	write(wfd, "already in use.\n", 16);
634af57ed9fSAtsushi Murai 	close(wfd);
635af57ed9fSAtsushi Murai 	continue;
636af57ed9fSAtsushi Murai       } else
637af57ed9fSAtsushi Murai 	netfd = wfd;
638af57ed9fSAtsushi Murai       if (dup2(netfd, 1) < 0)
639af57ed9fSAtsushi Murai 	perror("dup2");
640af57ed9fSAtsushi Murai       mode |= MODE_INTER;
641af57ed9fSAtsushi Murai       Greetings();
642af57ed9fSAtsushi Murai       (void) IsInteractive();
643af57ed9fSAtsushi Murai       Prompt(0);
644af57ed9fSAtsushi Murai     }
645af57ed9fSAtsushi Murai 
646af57ed9fSAtsushi Murai     if ((mode & MODE_INTER) && FD_ISSET(netfd, &rfds)) {
647af57ed9fSAtsushi Murai       /* something to read from tty */
648af57ed9fSAtsushi Murai       ReadTty();
649af57ed9fSAtsushi Murai     }
650af57ed9fSAtsushi Murai     if (modem) {
651af57ed9fSAtsushi Murai       if (FD_ISSET(modem, &wfds)) {	/* ready to write into modem */
652af57ed9fSAtsushi Murai 	 ModemStartOutput(modem);
653af57ed9fSAtsushi Murai       }
654af57ed9fSAtsushi Murai       if (FD_ISSET(modem, &rfds)) {	/* something to read from modem */
65553c9f6c0SAtsushi Murai 	if (LcpFsm.state <= ST_CLOSED)
65653c9f6c0SAtsushi Murai 	  usleep(10000);
657af57ed9fSAtsushi Murai 	n = read(modem, rbuff, sizeof(rbuff));
658af57ed9fSAtsushi Murai 	if ((mode & MODE_DIRECT) && n <= 0) {
659af57ed9fSAtsushi Murai 	  DownConnection();
660af57ed9fSAtsushi Murai 	} else
661af57ed9fSAtsushi Murai           LogDumpBuff(LOG_ASYNC, "ReadFromModem", rbuff, n);
662af57ed9fSAtsushi Murai 
663af57ed9fSAtsushi Murai 	if (LcpFsm.state <= ST_CLOSED) {
664af57ed9fSAtsushi Murai 	  /*
665af57ed9fSAtsushi Murai 	   *  In dedicated mode, we just discard input until LCP is started.
666af57ed9fSAtsushi Murai 	   */
667af57ed9fSAtsushi Murai 	  if (!(mode & MODE_DEDICATED)) {
668af57ed9fSAtsushi Murai 	    cp = HdlcDetect(rbuff, n);
669af57ed9fSAtsushi Murai 	    if (cp) {
670af57ed9fSAtsushi Murai 	      /*
671af57ed9fSAtsushi Murai 	       * LCP packet is detected. Turn ourselves into packet mode.
672af57ed9fSAtsushi Murai 	       */
673af57ed9fSAtsushi Murai 	      if (cp != rbuff) {
674af57ed9fSAtsushi Murai 	        write(1, rbuff, cp - rbuff);
675af57ed9fSAtsushi Murai 	        write(1, "\r\n", 2);
676af57ed9fSAtsushi Murai 	      }
677af57ed9fSAtsushi Murai 	      PacketMode();
678af57ed9fSAtsushi Murai #ifdef notdef
679af57ed9fSAtsushi Murai 	      AsyncInput(cp, n - (cp - rbuff));
680af57ed9fSAtsushi Murai #endif
681af57ed9fSAtsushi Murai 	    } else
682af57ed9fSAtsushi Murai 	      write(1, rbuff, n);
683af57ed9fSAtsushi Murai 	  }
684af57ed9fSAtsushi Murai 	} else {
685af57ed9fSAtsushi Murai 	  if (n > 0)
686af57ed9fSAtsushi Murai 	    AsyncInput(rbuff, n);
687af57ed9fSAtsushi Murai #ifdef notdef
688af57ed9fSAtsushi Murai 	  continue;			/* THIS LINE RESULT AS POOR PERFORMANCE */
689af57ed9fSAtsushi Murai #endif
690af57ed9fSAtsushi Murai 	}
691af57ed9fSAtsushi Murai       }
692af57ed9fSAtsushi Murai     }
693af57ed9fSAtsushi Murai     if (FD_ISSET(tun_in, &rfds)) {	/* something to read from tun */
694af57ed9fSAtsushi Murai       /*
695af57ed9fSAtsushi Murai        *  If there are many packets queued, wait until they are drained.
696af57ed9fSAtsushi Murai        */
697af57ed9fSAtsushi Murai       if (ModemQlen() > 5)
698af57ed9fSAtsushi Murai 	continue;
699af57ed9fSAtsushi Murai 
700af57ed9fSAtsushi Murai       n = read(tun_in, rbuff, sizeof(rbuff));
701af57ed9fSAtsushi Murai       if (n < 0) {
702af57ed9fSAtsushi Murai 	perror("read from tun");
703af57ed9fSAtsushi Murai 	continue;
704af57ed9fSAtsushi Murai       }
705af57ed9fSAtsushi Murai       /*
706af57ed9fSAtsushi Murai        *  Process on-demand dialup. Output packets are queued within tunnel
707af57ed9fSAtsushi Murai        *  device until IPCP is opened.
708af57ed9fSAtsushi Murai        */
709af57ed9fSAtsushi Murai       if (LcpFsm.state <= ST_CLOSED && (mode & MODE_AUTO)) {
710af57ed9fSAtsushi Murai 	pri = PacketCheck(rbuff, n, 2);
711af57ed9fSAtsushi Murai 	if (pri >= 0) {
712af57ed9fSAtsushi Murai 	  if (RedialTimer.state == TIMER_RUNNING) {
713af57ed9fSAtsushi Murai 	    /*
714af57ed9fSAtsushi Murai 	     * We are in redial wait state. Ignore packet.
715af57ed9fSAtsushi Murai 	     */
716af57ed9fSAtsushi Murai 	    continue;
717af57ed9fSAtsushi Murai 	  }
718af57ed9fSAtsushi Murai 	  modem = OpenModem(mode);
719af57ed9fSAtsushi Murai #ifdef DEBUG
720af57ed9fSAtsushi Murai 	  logprintf("going to dial: modem = %d\n", modem);
721af57ed9fSAtsushi Murai #endif
722af57ed9fSAtsushi Murai 	  if (modem < 0) {
723af57ed9fSAtsushi Murai 	    printf("failed to open modem.\n");
724af57ed9fSAtsushi Murai 	    Cleanup(EX_MODEM);
725af57ed9fSAtsushi Murai 	  }
726af57ed9fSAtsushi Murai 
727af57ed9fSAtsushi Murai 	  if (DialModem()) {
728af57ed9fSAtsushi Murai 	    sleep(1);		/* little pause to allow peer starts */
729af57ed9fSAtsushi Murai  	    ModemTimeout();
730af57ed9fSAtsushi Murai 	    PacketMode();
731af57ed9fSAtsushi Murai 	  } else {
732af57ed9fSAtsushi Murai 	    CloseModem();
733af57ed9fSAtsushi Murai 	    /* Dial failed. Keep quite during redial wait period. */
734af57ed9fSAtsushi Murai 	    /* XXX: We shoud implement re-dial */
735af57ed9fSAtsushi Murai 	    StartRedialTimer();
736af57ed9fSAtsushi Murai 	    continue;
737af57ed9fSAtsushi Murai 	  }
738af57ed9fSAtsushi Murai 	  IpEnqueue(pri, rbuff, n);
739af57ed9fSAtsushi Murai 	}
740af57ed9fSAtsushi Murai 	continue;
741af57ed9fSAtsushi Murai       }
742af57ed9fSAtsushi Murai       pri = PacketCheck(rbuff, n, 1);
743af57ed9fSAtsushi Murai       if (pri >= 0)
744af57ed9fSAtsushi Murai 	IpEnqueue(pri, rbuff, n);
745af57ed9fSAtsushi Murai     }
746af57ed9fSAtsushi Murai   }
74753c9f6c0SAtsushi Murai #ifdef SIGALRM
74853c9f6c0SAtsushi Murai   itimer.it_value.tv_usec = itimer.it_value.tv_sec = 0;
74953c9f6c0SAtsushi Murai   setitimer(ITIMER_REAL, &itimer, NULL);
75053c9f6c0SAtsushi Murai   signal(SIGALRM, SIG_DFL);
75153c9f6c0SAtsushi Murai #endif
752af57ed9fSAtsushi Murai   logprintf("job done.\n");
753af57ed9fSAtsushi Murai }
754