1 /*
2 * main.c - Point-to-Point Protocol main module
3 *
4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5 * Use is subject to license terms.
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation is hereby granted, provided that the above copyright
9 * notice appears in all copies.
10 *
11 * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
12 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
13 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
15 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
16 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
17 *
18 * Copyright (c) 1989 Carnegie Mellon University.
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms are permitted
22 * provided that the above copyright notice and this paragraph are
23 * duplicated in all such forms and that any documentation,
24 * advertising materials, and other materials related to such
25 * distribution and use acknowledge that the software was developed
26 * by Carnegie Mellon University. The name of the
27 * University may not be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
31 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32 */
33
34 #define RCSID "$Id: main.c,v 1.97 2000/04/24 02:54:16 masputra Exp $"
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <signal.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <syslog.h>
44 #include <netdb.h>
45 #include <pwd.h>
46 #include <setjmp.h>
47 #include <sys/param.h>
48 #include <sys/types.h>
49 #include <sys/wait.h>
50 #include <sys/time.h>
51 #include <sys/resource.h>
52 #include <sys/stat.h>
53 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
56
57 #include "pppd.h"
58 #include "magic.h"
59 #include "fsm.h"
60 #include "lcp.h"
61 #include "ipcp.h"
62 #ifdef INET6
63 #include "ipv6cp.h"
64 #endif
65 #include "upap.h"
66 #include "chap.h"
67 #include "ccp.h"
68 #include "pathnames.h"
69 #include "patchlevel.h"
70
71 #ifdef HAVE_MULTILINK
72 #include "tdb.h"
73 #endif
74
75 #ifdef CBCP_SUPPORT
76 #include "cbcp.h"
77 #endif
78
79 #ifdef IPX_CHANGE
80 #include "ipxcp.h"
81 #endif /* IPX_CHANGE */
82 #ifdef AT_CHANGE
83 #include "atcp.h"
84 #endif
85
86 #if !defined(lint) && !defined(_lint)
87 static const char rcsid[] = RCSID;
88 #endif
89
90 /* interface vars */
91 char ifname[32]; /* Interface name */
92 int ifunit = -1; /* Interface unit number */
93
94 char *progname; /* Name of this program */
95 char hostname[MAXHOSTNAMELEN+1]; /* Our hostname */
96 static char pidfilename[MAXPATHLEN]; /* name of pid file */
97 static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */
98 char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */
99 static uid_t uid; /* Our real user-id */
100 static int conn_running; /* we have a [dis]connector running */
101
102 int ttyfd; /* Serial port file descriptor */
103 mode_t tty_mode = (mode_t)-1; /* Original access permissions to tty */
104 int baud_rate; /* Actual bits/second for serial device */
105 bool hungup; /* terminal has been hung up */
106 bool privileged; /* we're running as real uid root */
107 bool need_holdoff; /* need holdoff period before restarting */
108 bool detached; /* have detached from terminal */
109 struct stat devstat; /* result of stat() on devnam */
110 bool prepass = 0; /* doing prepass to find device name */
111 int devnam_fixed; /* set while in options.ttyxx file */
112 volatile int status; /* exit status for pppd */
113 int unsuccess; /* # unsuccessful connection attempts */
114 int do_callback; /* != 0 if we should do callback next */
115 int doing_callback; /* != 0 if we are doing callback */
116 char *callback_script; /* script for doing callback */
117 #ifdef HAVE_MULTILINK
118 TDB_CONTEXT *pppdb; /* database for storing status etc. */
119 char db_key[32];
120 #endif
121
122 /*
123 * For plug-in usage:
124 *
125 * holdoff_hook - Can be used to change the demand-dial hold-off
126 * time dynamically. This is normally set by the
127 * "holdoff" option, and is 30 seconds by default.
128 *
129 * new_phase_hook - This is called for each change in the PPP
130 * phase (per RFC 1661). This can be used to log
131 * progress.
132 *
133 * check_options_hook - This is called before doing sys_init()
134 * and allows the plugin to verify the selected options.
135 *
136 * updown_script_hook - This is called with the proposed
137 * command-line arguments for any of the
138 * /etc/ppp/{ip,ipv6,ipx,auth}-{up,down} scripts before
139 * fork/exec. It can be used to add or change arguments.
140 *
141 * device_pipe_hook - If this is set, then an extra fd (3) is
142 * passed to the connect/disconnect script. This extra
143 * fd is the write side of a pipe, and the read side is
144 * passed to this routine. This can be used to pass
145 * arbitrary data from the script back to pppd.
146 */
147 int (*holdoff_hook) __P((void)) = NULL;
148 int (*new_phase_hook) __P((int new, int old)) = NULL;
149 int (*check_options_hook) __P((uid_t uid)) = NULL;
150 int (*updown_script_hook) __P((const char ***argsp)) = NULL;
151 void (*device_pipe_hook) __P((int pipefd)) = NULL;
152
153 static int fd_ppp = -1; /* fd for talking PPP */
154 static int fd_loop; /* fd for getting demand-dial packets */
155 static int pty_master; /* fd for master side of pty */
156 int pty_slave = -1; /* fd for slave side of pty */
157 static int real_ttyfd; /* fd for actual serial port (not pty) */
158
159 int phase; /* where the link is at */
160 int kill_link;
161 int open_ccp_flag;
162
163 static int waiting; /* for input from peer or timer expiration */
164 static sigjmp_buf sigjmp;
165
166 char **script_env; /* Env. variable values for scripts */
167 int s_env_nalloc; /* # words avail at script_env */
168
169 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
170 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
171 u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
172
173 static int n_children; /* # child processes still running */
174 static bool got_sigchld; /* set if we have received a SIGCHLD */
175 static sigset_t main_sigmask; /* signals blocked while dispatching */
176
177 static bool locked; /* lock() has succeeded */
178 static bool privopen; /* don't lock, open device as root */
179
180 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
181
182 GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */
183 int ngroups; /* How many groups valid in groups */
184
185 static struct timeval start_time; /* Time when link was started. */
186
187 struct pppd_stats link_stats;
188 int link_connect_time;
189 bool link_stats_valid;
190
191 static pid_t charshunt_pid; /* Process ID for charshunt */
192
193 extern option_t general_options[];
194 extern option_t auth_options[];
195
196 /*
197 * We maintain a list of child process pids and
198 * functions to call when they exit.
199 */
200 struct subprocess {
201 pid_t pid;
202 char *prog;
203 void (*done) __P((void *, int));
204 void *arg;
205 struct subprocess *next;
206 };
207
208 static struct subprocess *children;
209
210 /* Prototypes for procedures local to this file. */
211
212 static void setup_signals __P((void));
213 static void create_pidfile __P((void));
214 static void create_linkpidfile __P((void));
215 static void cleanup __P((void));
216 static void close_tty __P((void));
217 static void get_input __P((void));
218 static void calltimeout __P((void));
219 static struct timeval *timeleft __P((struct timeval *));
220 static void kill_my_pg __P((int));
221 static void hup __P((int));
222 static void term __P((int));
223 static void chld __P((int));
224 static void toggle_debug __P((int));
225 static void open_ccp __P((int));
226 static void bad_signal __P((int));
227 static void holdoff_end __P((void *));
228 static int device_script __P((char *, int, int, int, char *));
229 static int reap_kids __P((int waitfor));
230 static void record_child __P((pid_t, char *, void (*) (void *, int), void *));
231 static int open_socket __P((char *));
232 static int start_charshunt __P((int, int));
233 static void charshunt_done __P((void *, int));
234 static void charshunt __P((int, int, char *));
235 static int record_write __P((FILE *, int code, u_char *buf, int nb,
236 struct timeval *));
237 static void final_reap __P((void));
238
239 #ifdef HAVE_MULTILINK
240 static void update_db_entry __P((void));
241 static void add_db_key __P((const char *));
242 static void delete_db_key __P((const char *));
243 static void cleanup_db __P((void));
244 #endif
245
246 int main __P((int, char *[]));
247
248 #ifdef ultrix
249 #undef O_NONBLOCK
250 #define O_NONBLOCK O_NDELAY
251 #endif
252
253 #ifdef ULTRIX
254 #define setlogmask(x) 0
255 #endif
256
257 /* Backward compatibility for Linux */
258 #ifndef RECMARK_TIMESTART
259 #define RECMARK_STARTSEND 1
260 #define RECMARK_STARTRECV 2
261 #define RECMARK_ENDSEND 3
262 #define RECMARK_ENDRECV 4
263 #define RECMARK_TIMEDELTA32 5
264 #define RECMARK_TIMEDELTA8 6
265 #define RECMARK_TIMESTART 7
266 #endif
267
268 /*
269 * PPP Data Link Layer "protocol" table.
270 * One entry per supported protocol.
271 * The last entry must be NULL.
272 */
273 struct protent *protocols[] = {
274 &lcp_protent,
275 &pap_protent,
276 &chap_protent,
277 #ifdef CBCP_SUPPORT
278 &cbcp_protent,
279 #endif
280 &ipcp_protent,
281 #ifdef INET6
282 &ipv6cp_protent,
283 #endif
284 &ccp_protent,
285 #ifdef IPX_CHANGE
286 &ipxcp_protent,
287 #endif
288 #ifdef AT_CHANGE
289 &atcp_protent,
290 #endif
291 NULL
292 };
293
294 int
main(argc,argv)295 main(argc, argv)
296 int argc;
297 char *argv[];
298 {
299 int i, fdflags, t;
300 char *p, *connector;
301 struct passwd *pw;
302 struct timeval timo;
303 struct protent *protp;
304 struct stat statbuf;
305 char numbuf[16];
306
307 ifname[0] = '\0';
308 new_phase(PHASE_INITIALIZE);
309
310 /*
311 * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
312 * This way we can close 0, 1, 2 in detach() without clobbering
313 * a fd that we are using.
314 */
315 if ((i = open(_PATH_DEVNULL, O_RDWR)) >= 0) {
316 while (0 <= i && i <= 2)
317 i = dup(i);
318 if (i >= 0)
319 (void) close(i);
320 }
321
322 script_env = NULL;
323
324 /* Initialize syslog facilities */
325 reopen_log();
326
327 if (gethostname(hostname, MAXHOSTNAMELEN+1) < 0 ) {
328 option_error("Couldn't get hostname: %m");
329 exit(1);
330 }
331 hostname[MAXHOSTNAMELEN] = '\0';
332
333 /* make sure we don't create world or group writable files. */
334 (void) umask(umask(0777) | 022);
335
336 uid = getuid();
337 privileged = (uid == 0);
338 (void) slprintf(numbuf, sizeof(numbuf), "%d", uid);
339 script_setenv("ORIG_UID", numbuf, 0);
340
341 ngroups = getgroups(NGROUPS_MAX, groups);
342
343 /*
344 * Initialize magic number generator now so that protocols may
345 * use magic numbers in initialization.
346 */
347 magic_init();
348
349 progname = *argv;
350 prepass = 0;
351 /*
352 * Initialize to the standard option set, then parse, in order, the
353 * system options file, the user's options file, the tty's options file,
354 * and the command line arguments. At last, install the options declared
355 * by each protocol into the extra_option list.
356 */
357 for (i = 0; (protp = protocols[i]) != NULL; ++i) {
358 (*protp->init)(0);
359 if (protp->options != NULL) {
360 add_options(protp->options);
361 }
362 }
363
364 /*
365 * Install "generic" options into the extra_options list.
366 */
367 add_options(auth_options);
368 add_options(general_options);
369
370 /* Install any system-specific options (or remove unusable ones) */
371 sys_options();
372
373 if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1)
374 || !options_from_user())
375 exit(EXIT_OPTION_ERROR);
376
377 /* scan command line and options files to find device name */
378 prepass = 1;
379 (void) parse_args(argc-1, argv+1);
380 prepass = 0;
381
382 /*
383 * Work out the device name, if it hasn't already been specified.
384 */
385 using_pty = notty || ptycommand != NULL || pty_socket != NULL;
386 if (!using_pty && default_device && !direct_tty) {
387 char *p;
388
389 if (!isatty(0) || (p = ttyname(0)) == NULL) {
390 option_error("no device specified and stdin is not a tty");
391 exit(EXIT_OPTION_ERROR);
392 }
393 (void) strlcpy(devnam, p, sizeof(devnam));
394 if (stat(devnam, &devstat) < 0)
395 fatal("Couldn't stat default device %s: %m", devnam);
396 }
397
398 /*
399 * Parse the tty options file and the command line.
400 * The per-tty options file should not change
401 * ptycommand, pty_socket, notty or devnam.
402 */
403 devnam_fixed = 1;
404 if (!using_pty && !direct_tty) {
405 if (!options_for_tty())
406 exit(EXIT_OPTION_ERROR);
407 }
408
409 devnam_fixed = 0;
410 if (!parse_args(argc-1, argv+1))
411 exit(EXIT_OPTION_ERROR);
412
413 /*
414 * Check that we are running as root.
415 */
416 if (geteuid() != 0) {
417 option_error("must be root to run %s, since it is not setuid-root",
418 argv[0]);
419 exit(EXIT_NOT_ROOT);
420 }
421
422 if (!ppp_available()) {
423 option_error(no_ppp_msg);
424 exit(EXIT_NO_KERNEL_SUPPORT);
425 }
426
427 /*
428 * Check that the options given are valid and consistent.
429 */
430 if (!sys_check_options())
431 exit(EXIT_OPTION_ERROR);
432 auth_check_options();
433 #ifdef HAVE_MULTILINK
434 mp_check_options();
435 #endif
436 for (i = 0; (protp = protocols[i]) != NULL; ++i)
437 if (protp->enabled_flag && protp->check_options != NULL)
438 (*protp->check_options)();
439 if (demand && (connect_script == NULL)) {
440 option_error("connect script is required for demand-dialling\n");
441 exit(EXIT_OPTION_ERROR);
442 }
443 if (updetach && (nodetach || demand)) {
444 option_error("updetach cannot be used with %s",
445 nodetach ? "nodetach" : "demand");
446 exit(EXIT_OPTION_ERROR);
447 }
448 /* default holdoff to 0 if no connect script has been given */
449 if ((connect_script == NULL) && !holdoff_specified)
450 holdoff = 0;
451
452 if (using_pty || direct_tty) {
453 if (!default_device) {
454 option_error("%s option precludes specifying device name",
455 notty? "notty": "pty");
456 exit(EXIT_OPTION_ERROR);
457 }
458 if (ptycommand != NULL && (notty || direct_tty)) {
459 option_error("pty option is incompatible with notty option");
460 exit(EXIT_OPTION_ERROR);
461 }
462 if (pty_socket != NULL && (ptycommand != NULL || notty ||
463 direct_tty)) {
464 option_error("socket option is incompatible with pty and notty");
465 exit(EXIT_OPTION_ERROR);
466 }
467 default_device = notty || direct_tty;
468 lockflag = 0;
469 modem = 0;
470 if (default_device && log_to_fd <= 1)
471 log_to_fd = -1;
472 } else {
473 /*
474 * If the user has specified a device which is the same as
475 * the one on stdin, pretend they didn't specify any.
476 * If the device is already open read/write on stdin,
477 * we assume we don't need to lock it, and we can open it as root.
478 */
479 if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode)
480 && statbuf.st_rdev == devstat.st_rdev) {
481 default_device = 1;
482 fdflags = fcntl(0, F_GETFL);
483 if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR)
484 privopen = 1;
485 }
486 }
487 if (default_device)
488 nodetach = 1;
489
490 /*
491 * Don't send log messages to the serial port, it tends to
492 * confuse the peer. :-)
493 */
494 if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0
495 && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev)
496 log_to_fd = -1;
497 early_log = 0;
498
499 if (debug)
500 (void) setlogmask(LOG_UPTO(LOG_DEBUG));
501
502 /*
503 * Initialize system-dependent stuff.
504 */
505 if (check_options_hook != NULL &&
506 (*check_options_hook)(uid) == -1) {
507 exit(EXIT_OPTION_ERROR);
508 }
509 sys_init(!devnam_info.priv && !privopen);
510
511 #ifdef HAVE_MULTILINK
512 pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644);
513 if (pppdb != NULL) {
514 (void) slprintf(db_key, sizeof(db_key), "pppd%d", getpid());
515 update_db_entry();
516 } else {
517 warn("Warning: couldn't open ppp database %s", _PATH_PPPDB);
518 if (multilink) {
519 warn("Warning: disabling multilink");
520 multilink = 0;
521 }
522 }
523 #endif
524
525 /*
526 * Detach ourselves from the terminal, if required, and identify
527 * who is running us. Printing to stderr stops here unless
528 * nodetach or updetach is set.
529 */
530 if (!nodetach && !updetach)
531 detach();
532 p = getlogin();
533 if (p == NULL) {
534 pw = getpwuid(uid);
535 if (pw != NULL && pw->pw_name != NULL)
536 p = pw->pw_name;
537 else
538 p = "(unknown)";
539 }
540 syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d",
541 VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid);
542 script_setenv("PPPLOGNAME", p, 0);
543
544 if (devnam[0] != '\0')
545 script_setenv("DEVICE", devnam, 1);
546 (void) slprintf(numbuf, sizeof(numbuf), "%d", getpid());
547 script_setenv("PPPD_PID", numbuf, 1);
548
549 setup_signals();
550
551 waiting = 0;
552
553 create_linkpidfile();
554
555 /*
556 * If we're doing dial-on-demand, set up the interface now.
557 */
558 if (demand) {
559 /*
560 * Open the loopback channel and set it up to be the ppp interface.
561 */
562 #ifdef HAVE_MULTILINK
563 (void) tdb_writelock(pppdb);
564 #endif
565 set_ifunit(1);
566 fd_loop = open_ppp_loopback();
567 #ifdef HAVE_MULTILINK
568 (void) tdb_writeunlock(pppdb);
569 #endif
570
571 /*
572 * Configure the interface and mark it up, etc.
573 */
574 demand_conf();
575 }
576
577 new_phase(PHASE_INITIALIZED);
578 do_callback = 0;
579 for (;;) {
580
581 need_holdoff = 1;
582 ttyfd = -1;
583 real_ttyfd = -1;
584 status = EXIT_OK;
585 ++unsuccess;
586 doing_callback = do_callback;
587 do_callback = 0;
588
589 if (demand && !doing_callback) {
590 /*
591 * Don't do anything until we see some activity.
592 */
593 kill_link = 0;
594 new_phase(PHASE_DORMANT);
595 demand_unblock();
596 add_fd(fd_loop);
597 for (;;) {
598 if (sigsetjmp(sigjmp, 1) == 0) {
599 (void) sigprocmask(SIG_BLOCK, &main_sigmask, NULL);
600 if (kill_link || got_sigchld) {
601 (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
602 } else {
603 waiting = 1;
604 (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
605 wait_input(timeleft(&timo));
606 }
607 }
608 waiting = 0;
609 calltimeout();
610 if (kill_link) {
611 if (!persist)
612 break;
613 kill_link = 0;
614 }
615 if (get_loop_output())
616 break;
617 if (got_sigchld)
618 (void) reap_kids(0);
619 }
620 remove_fd(fd_loop);
621 if (kill_link && !persist)
622 break;
623
624 /*
625 * Now we want to bring up the link.
626 */
627 demand_block();
628 info("Starting link");
629 }
630
631 new_phase(doing_callback ? PHASE_CALLINGBACK : PHASE_SERIALCONN);
632
633 /*
634 * Get a pty master/slave pair if the pty, notty, socket,
635 * or record options were specified.
636 */
637 (void) strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
638 pty_master = -1;
639 pty_slave = -1;
640 if (using_pty || record_file != NULL) {
641 if (!get_pty(&pty_master, &pty_slave, ppp_devnam, uid)) {
642 error("Couldn't allocate pseudo-tty");
643 status = EXIT_FATAL_ERROR;
644 goto fail;
645 }
646 set_up_tty(pty_slave, 1);
647 }
648
649 /*
650 * Lock the device if we've been asked to.
651 */
652 status = EXIT_LOCK_FAILED;
653 if (lockflag && !privopen && !direct_tty) {
654 if (lock(devnam) < 0)
655 goto fail;
656 locked = 1;
657 }
658
659 /*
660 * Open the serial device and set it up to be the ppp interface.
661 * First we open it in non-blocking mode so we can set the
662 * various termios flags appropriately. If we aren't dialling
663 * out and we want to use the modem lines, we reopen it later
664 * in order to wait for the carrier detect signal from the modem.
665 */
666 hungup = 0;
667 kill_link = 0;
668 connector = doing_callback? callback_script: connect_script;
669 if (direct_tty) {
670 ttyfd = 0;
671 } else if (devnam[0] != '\0') {
672 for (;;) {
673 /* If the user specified the device name, become the
674 user before opening it. */
675 int err;
676 if (!devnam_info.priv && !privopen)
677 (void) seteuid(uid);
678 if ((ttyfd = sys_extra_fd()) < 0)
679 ttyfd = open(devnam, O_NONBLOCK | O_RDWR);
680 err = errno;
681 if (!devnam_info.priv && !privopen)
682 (void) seteuid(0);
683 if (ttyfd >= 0)
684 break;
685 errno = err;
686 if (err != EINTR) {
687 error("Failed to open %s: %m", devnam);
688 status = EXIT_OPEN_FAILED;
689 }
690 if (!persist || err != EINTR)
691 goto fail;
692 }
693 if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
694 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
695 warn("Couldn't reset non-blocking mode on device: %m");
696
697 /*
698 * Do the equivalent of `mesg n' to stop broadcast messages.
699 */
700 if (fstat(ttyfd, &statbuf) < 0
701 || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
702 warn("Couldn't restrict write permissions to %s: %m", devnam);
703 } else
704 tty_mode = statbuf.st_mode;
705
706 /*
707 * Set line speed, flow control, etc.
708 * If we have a non-null connection or initializer script,
709 * on most systems we set CLOCAL for now so that we can talk
710 * to the modem before carrier comes up. But this has the
711 * side effect that we might miss it if CD drops before we
712 * get to clear CLOCAL below. On systems where we can talk
713 * successfully to the modem with CLOCAL clear and CD down,
714 * we could clear CLOCAL at this point.
715 */
716 set_up_tty(ttyfd, ((connector != NULL && connector[0] != '\0')
717 || initializer != NULL));
718 real_ttyfd = ttyfd;
719 }
720
721 /*
722 * If the pty, socket, notty and/or record option was specified,
723 * start up the character shunt now.
724 */
725 status = EXIT_PTYCMD_FAILED;
726 if (ptycommand != NULL) {
727 if (record_file != NULL) {
728 int ipipe[2], opipe[2], ok;
729
730 if (pipe(ipipe) < 0 || pipe(opipe) < 0)
731 fatal("Couldn't create pipes for record option: %m");
732 dbglog("starting charshunt for pty option");
733 ok = device_script(ptycommand, opipe[0], ipipe[1], 1,
734 "record") == 0 && start_charshunt(ipipe[0], opipe[1]);
735 (void) close(ipipe[0]);
736 (void) close(ipipe[1]);
737 (void) close(opipe[0]);
738 (void) close(opipe[1]);
739 if (!ok)
740 goto fail;
741 } else {
742 if (device_script(ptycommand, pty_master, pty_master, 1,
743 "pty") < 0)
744 goto fail;
745 ttyfd = pty_slave;
746 (void) close(pty_master);
747 pty_master = -1;
748 }
749 } else if (pty_socket != NULL) {
750 int fd = open_socket(pty_socket);
751 if (fd < 0)
752 goto fail;
753 dbglog("starting charshunt for socket option");
754 if (!start_charshunt(fd, fd))
755 goto fail;
756 } else if (notty) {
757 dbglog("starting charshunt for notty option");
758 if (!start_charshunt(0, 1))
759 goto fail;
760 } else if (record_file != NULL) {
761 dbglog("starting charshunt for record option");
762 if (!start_charshunt(ttyfd, ttyfd))
763 goto fail;
764 }
765
766 /* run connection script */
767 if (((connector != NULL) && (connector[0] != '\0')) || initializer) {
768 if (real_ttyfd != -1) {
769 /* XXX do this if doing_callback == CALLBACK_DIALIN? */
770 if (!default_device && modem && !direct_tty) {
771 setdtr(real_ttyfd, 0); /* in case modem is off hook */
772 (void) sleep(1);
773 setdtr(real_ttyfd, 1);
774 }
775 }
776
777 if ((initializer != NULL) && (initializer[0] != '\0')) {
778 if (device_script(initializer, ttyfd, ttyfd, 0, "init") < 0) {
779 error("Initializer script failed");
780 status = EXIT_INIT_FAILED;
781 goto fail;
782 }
783 if (kill_link)
784 goto disconnect;
785
786 info("Serial port initialized.");
787 }
788
789 if ((connector != NULL) && (connector[0] != '\0')) {
790 if (device_script(connector, ttyfd, ttyfd, 0, "connect") < 0) {
791 error("Connect script failed");
792 status = EXIT_CONNECT_FAILED;
793 goto fail;
794 }
795 if (kill_link)
796 goto disconnect;
797
798 info("Serial connection established.");
799 }
800
801 /*
802 * Clear CLOCAL if modem option -- we now have carrier
803 * established, and we should respect loss of carrier.
804 */
805 if (real_ttyfd != -1)
806 set_up_tty(real_ttyfd, 0);
807
808 if (doing_callback == CALLBACK_DIALIN)
809 connector = NULL;
810 }
811
812 /* reopen tty if necessary to wait for carrier */
813 if (connector == NULL && modem && devnam[0] != '\0' && !direct_tty) {
814 for (;;) {
815 if ((i = open(devnam, O_RDWR)) >= 0)
816 break;
817 if (errno != EINTR) {
818 error("Failed to reopen %s: %m", devnam);
819 status = EXIT_OPEN_FAILED;
820 }
821 if (!persist || errno != EINTR || hungup || kill_link)
822 goto fail;
823 }
824 (void) close(i);
825 }
826
827 (void) slprintf(numbuf, sizeof(numbuf), "%d", baud_rate);
828 script_setenv("SPEED", numbuf, 0);
829
830 /* run welcome script, if any */
831 if ((welcomer != NULL) && (welcomer[0] != '\0')) {
832 if (device_script(welcomer, ttyfd, ttyfd, 0, "welcome") < 0)
833 warn("Welcome script failed");
834 }
835
836 /* set up the serial device as a ppp interface */
837 #ifdef HAVE_MULTILINK
838 (void) tdb_writelock(pppdb);
839 #endif
840 fd_ppp = establish_ppp(ttyfd);
841 if (fd_ppp < 0) {
842 #ifdef HAVE_MULTILINK
843 (void) tdb_writeunlock(pppdb);
844 #endif
845 status = EXIT_FATAL_ERROR;
846 goto disconnect;
847 }
848
849 if (!demand && ifunit >= 0)
850 set_ifunit(1);
851 #ifdef HAVE_MULTILINK
852 (void) tdb_writeunlock(pppdb);
853 #endif
854
855 /*
856 * Start opening the connection and wait for
857 * incoming events (reply, timeout, etc.).
858 */
859 notice("Connect: %s <--> %s", ifname, ppp_devnam);
860 (void) gettimeofday(&start_time, NULL);
861 link_stats_valid = 0;
862 script_unsetenv("CONNECT_TIME");
863 script_unsetenv("BYTES_SENT");
864 script_unsetenv("BYTES_RCVD");
865 lcp_lowerup(0);
866
867 /* Mostly for accounting purposes */
868 new_phase(PHASE_CONNECTED);
869
870 /*
871 * If we are initiating this connection, wait for a short
872 * time for something from the peer. This can avoid bouncing
873 * our packets off his tty before he has it set up.
874 */
875 add_fd(fd_ppp);
876 if (connect_delay != 0 && (connector != NULL || ptycommand != NULL)) {
877 struct timeval t;
878 t.tv_sec = connect_delay / 1000;
879 t.tv_usec = connect_delay % 1000;
880 wait_input(&t);
881 }
882
883 lcp_open(0); /* Start protocol */
884 open_ccp_flag = 0;
885 status = EXIT_NEGOTIATION_FAILED;
886 new_phase(PHASE_ESTABLISH);
887 while (phase != PHASE_DEAD) {
888 if (sigsetjmp(sigjmp, 1) == 0) {
889 (void) sigprocmask(SIG_BLOCK, &main_sigmask, NULL);
890 if (kill_link || open_ccp_flag || got_sigchld) {
891 (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
892 } else {
893 waiting = 1;
894 (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
895 wait_input(timeleft(&timo));
896 }
897 }
898 waiting = 0;
899 calltimeout();
900 get_input();
901 if (kill_link) {
902 lcp_close(0, "User request");
903 kill_link = 0;
904 }
905 if (open_ccp_flag) {
906 if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) {
907 /* Uncloak ourselves. */
908 ccp_fsm[0].flags &= ~OPT_SILENT;
909 (*ccp_protent.open)(0);
910 }
911 open_ccp_flag = 0;
912 }
913 if (got_sigchld)
914 (void) reap_kids(0); /* Don't leave dead kids lying around */
915 }
916
917 /*
918 * Print connect time and statistics.
919 */
920 if (link_stats_valid) {
921 int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */
922 info("Connect time %d.%d minutes.", t/10, t%10);
923 info("Sent %" PPP_COUNTER_F " bytes (%" PPP_COUNTER_F
924 " packets), received %" PPP_COUNTER_F " bytes (%" PPP_COUNTER_F
925 " packets).",
926 link_stats.bytes_out, link_stats.pkts_out,
927 link_stats.bytes_in, link_stats.pkts_in);
928 }
929
930 /*
931 * Delete pid file before disestablishing ppp. Otherwise it
932 * can happen that another pppd gets the same unit and then
933 * we delete its pid file.
934 */
935 if (!demand) {
936 if (pidfilename[0] != '\0'
937 && unlink(pidfilename) < 0 && errno != ENOENT)
938 warn("unable to delete pid file %s: %m", pidfilename);
939 pidfilename[0] = '\0';
940 }
941
942 /*
943 * If we may want to bring the link up again, transfer
944 * the ppp unit back to the loopback. Set the
945 * real serial device back to its normal mode of operation.
946 */
947 remove_fd(fd_ppp);
948 clean_check();
949 if (demand)
950 restore_loop();
951 disestablish_ppp(ttyfd);
952 fd_ppp = -1;
953 if (!hungup)
954 lcp_lowerdown(0);
955 if (!demand)
956 script_unsetenv("IFNAME");
957
958 /*
959 * Run disconnector script, if requested.
960 * XXX we may not be able to do this if the line has hung up!
961 */
962 disconnect:
963 if ((disconnect_script != NULL) && (disconnect_script[0] != '\0') &&
964 !hungup) {
965 new_phase(PHASE_DISCONNECT);
966 if (real_ttyfd >= 0)
967 set_up_tty(real_ttyfd, 1);
968 if (device_script(disconnect_script, ttyfd, ttyfd, 0,
969 "disconnect") < 0) {
970 warn("disconnect script failed");
971 } else {
972 info("Serial link disconnected.");
973 }
974 }
975
976 fail:
977 if (pty_master >= 0)
978 (void) close(pty_master);
979 if (pty_slave >= 0) {
980 (void) close(pty_slave);
981 pty_slave = -1;
982 }
983 if (real_ttyfd >= 0)
984 close_tty();
985 if (locked) {
986 locked = 0;
987 unlock();
988 }
989
990 if (!demand) {
991 if (pidfilename[0] != '\0'
992 && unlink(pidfilename) < 0 && errno != ENOENT)
993 warn("unable to delete pid file %s: %m", pidfilename);
994 pidfilename[0] = '\0';
995 }
996
997 if (!persist || (maxfail > 0 && unsuccess >= maxfail))
998 break;
999
1000 kill_link = 0;
1001 if (demand)
1002 demand_discard();
1003 t = need_holdoff? holdoff: 0;
1004 if (holdoff_hook != NULL)
1005 t = (*holdoff_hook)();
1006 if (t > 0) {
1007 new_phase(PHASE_HOLDOFF);
1008 TIMEOUT(holdoff_end, NULL, t);
1009 do {
1010 if (sigsetjmp(sigjmp, 1) == 0) {
1011 (void) sigprocmask(SIG_BLOCK, &main_sigmask, NULL);
1012 if (kill_link || got_sigchld) {
1013 (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
1014 } else {
1015 waiting = 1;
1016 (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
1017 wait_input(timeleft(&timo));
1018 }
1019 }
1020 waiting = 0;
1021 calltimeout();
1022 if (kill_link) {
1023 kill_link = 0;
1024 new_phase(PHASE_DORMANT); /* allow signal to end holdoff */
1025 }
1026 if (got_sigchld)
1027 (void) reap_kids(0);
1028 } while (phase == PHASE_HOLDOFF);
1029 if (!persist)
1030 break;
1031 }
1032 }
1033
1034 /* Wait for scripts to finish */
1035 final_reap();
1036
1037 die(status);
1038 return (0);
1039 }
1040
1041 /*
1042 * setup_signals - initialize signal handling.
1043 */
1044 static void
setup_signals()1045 setup_signals()
1046 {
1047 struct sigaction sa;
1048
1049 /*
1050 * Compute mask of all interesting signals and install signal handlers
1051 * for each. Only one signal handler may be active at a time. Therefore,
1052 * all other signals should be masked when any handler is executing.
1053 */
1054 (void) sigemptyset(&main_sigmask);
1055 (void) sigaddset(&main_sigmask, SIGHUP);
1056 (void) sigaddset(&main_sigmask, SIGINT);
1057 (void) sigaddset(&main_sigmask, SIGTERM);
1058 (void) sigaddset(&main_sigmask, SIGCHLD);
1059 (void) sigaddset(&main_sigmask, SIGUSR2);
1060
1061 #define SIGNAL(s, handler) if (1) { \
1062 sa.sa_handler = handler; \
1063 if (sigaction(s, &sa, NULL) < 0) \
1064 fatal("Couldn't establish signal handler (%d): %m", s); \
1065 } else ((void)0)
1066
1067 sa.sa_mask = main_sigmask;
1068 sa.sa_flags = 0;
1069 /*CONSTANTCONDITION*/ SIGNAL(SIGHUP, hup); /* Hangup */
1070 /*CONSTANTCONDITION*/ SIGNAL(SIGINT, term); /* Interrupt */
1071 /*CONSTANTCONDITION*/ SIGNAL(SIGTERM, term); /* Terminate */
1072 /*CONSTANTCONDITION*/ SIGNAL(SIGCHLD, chld);
1073
1074 /*CONSTANTCONDITION*/ SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */
1075 /*CONSTANTCONDITION*/ SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */
1076
1077 /*
1078 * Install a handler for other signals which would otherwise
1079 * cause pppd to exit without cleaning up.
1080 */
1081 /*CONSTANTCONDITION*/ SIGNAL(SIGALRM, bad_signal);
1082 /*CONSTANTCONDITION*/ SIGNAL(SIGQUIT, bad_signal);
1083
1084 /* Do not hook any of these signals on Solaris; allow core dump instead */
1085 #ifndef SOL2
1086 /*CONSTANTCONDITION*/ SIGNAL(SIGABRT, bad_signal);
1087 /*CONSTANTCONDITION*/ SIGNAL(SIGFPE, bad_signal);
1088 /*CONSTANTCONDITION*/ SIGNAL(SIGILL, bad_signal);
1089 #ifndef DEBUG
1090 /*CONSTANTCONDITION*/ SIGNAL(SIGSEGV, bad_signal);
1091 #endif
1092 #ifdef SIGBUS
1093 /*CONSTANTCONDITION*/ SIGNAL(SIGBUS, bad_signal);
1094 #endif
1095 #ifdef SIGEMT
1096 /*CONSTANTCONDITION*/ SIGNAL(SIGEMT, bad_signal);
1097 #endif
1098 #ifdef SIGPOLL
1099 /*CONSTANTCONDITION*/ SIGNAL(SIGPOLL, bad_signal);
1100 #endif
1101 #ifdef SIGPROF
1102 /*CONSTANTCONDITION*/ SIGNAL(SIGPROF, bad_signal);
1103 #endif
1104 #ifdef SIGSYS
1105 /*CONSTANTCONDITION*/ SIGNAL(SIGSYS, bad_signal);
1106 #endif
1107 #ifdef SIGTRAP
1108 /*CONSTANTCONDITION*/ SIGNAL(SIGTRAP, bad_signal);
1109 #endif
1110 #ifdef SIGVTALRM
1111 /*CONSTANTCONDITION*/ SIGNAL(SIGVTALRM, bad_signal);
1112 #endif
1113 #ifdef SIGXCPU
1114 /*CONSTANTCONDITION*/ SIGNAL(SIGXCPU, bad_signal);
1115 #endif
1116 #ifdef SIGXFSZ
1117 /*CONSTANTCONDITION*/ SIGNAL(SIGXFSZ, bad_signal);
1118 #endif
1119 #endif
1120
1121 /*
1122 * Apparently we can get a SIGPIPE when we call syslog, if
1123 * syslogd has died and been restarted. Ignoring it seems
1124 * be sufficient.
1125 */
1126 (void) signal(SIGPIPE, SIG_IGN);
1127 }
1128
1129 /*
1130 * set_ifunit - do things we need to do once we know which ppp
1131 * unit we are using.
1132 */
1133 void
set_ifunit(iskey)1134 set_ifunit(iskey)
1135 int iskey;
1136 {
1137 sys_ifname();
1138 info("Using interface %s", ifname);
1139 script_setenv("IFNAME", ifname, iskey);
1140 if (iskey) {
1141 create_pidfile(); /* write pid to file */
1142 create_linkpidfile();
1143 }
1144 }
1145
1146 /*
1147 * detach - detach us from the controlling terminal.
1148 */
1149 void
detach()1150 detach()
1151 {
1152 pid_t pid;
1153 char numbuf[16];
1154
1155 if (detached)
1156 return;
1157 if ((pid = fork()) == (pid_t)-1) {
1158 error("Couldn't detach (fork failed: %m)");
1159 die(1); /* or just return? */
1160 }
1161 if (pid != (pid_t)0) {
1162 /* parent */
1163 if (locked)
1164 (void) relock(pid);
1165 exit(0); /* parent dies */
1166 }
1167 (void) setsid();
1168 /*
1169 * Fork again to relinquish session leadership. This is needed
1170 * to prevent the daemon from acquiring controlling terminal.
1171 */
1172 if ((pid = fork()) == (pid_t)-1) {
1173 error("Couldn't detach (second fork failed: %m)");
1174 die(1); /* or just return? */
1175 }
1176 if (pid != (pid_t)0) {
1177 /* parent */
1178 if (locked)
1179 (void) relock(pid);
1180 exit(0); /* parent dies */
1181 }
1182 (void) chdir("/");
1183 (void) close(0);
1184 (void) close(1);
1185 (void) close(2);
1186 detached = 1;
1187 if (!log_to_file && !log_to_specific_fd)
1188 log_to_fd = -1;
1189 /* update pid files if they have been written already */
1190 if (pidfilename[0] != '\0')
1191 create_pidfile();
1192 if (linkpidfile[0] != '\0')
1193 create_linkpidfile();
1194 (void) slprintf(numbuf, sizeof(numbuf), "%d", getpid());
1195 script_setenv("PPPD_PID", numbuf, 1);
1196 }
1197
1198 /*
1199 * reopen_log - (re)open our connection to syslog.
1200 */
1201 void
reopen_log()1202 reopen_log()
1203 {
1204 #ifdef ULTRIX
1205 openlog("pppd", LOG_PID);
1206 #else
1207 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
1208 (void) setlogmask(LOG_UPTO(LOG_INFO));
1209 #endif
1210 }
1211
1212 /*
1213 * Create a file containing our process ID.
1214 */
1215 static void
create_pidfile()1216 create_pidfile()
1217 {
1218 FILE *pidfile;
1219
1220 (void) slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid",
1221 _PATH_VARRUN, ifname);
1222 if ((pidfile = fopen(pidfilename, "w")) != NULL) {
1223 (void) fprintf(pidfile, "%u\n", (unsigned)getpid());
1224 (void) fclose(pidfile);
1225 } else {
1226 error("Failed to create pid file %s: %m", pidfilename);
1227 pidfilename[0] = '\0';
1228 }
1229 }
1230
1231 static void
create_linkpidfile()1232 create_linkpidfile()
1233 {
1234 FILE *pidfile;
1235
1236 if (linkname[0] == '\0')
1237 return;
1238 script_setenv("LINKNAME", linkname, 1);
1239 (void) slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid",
1240 _PATH_VARRUN, linkname);
1241 if ((pidfile = fopen(linkpidfile, "w")) != NULL) {
1242 (void) fprintf(pidfile, "%u\n", (unsigned)getpid());
1243 if (ifname[0] != '\0')
1244 (void) fprintf(pidfile, "%s\n", ifname);
1245 (void) fclose(pidfile);
1246 } else {
1247 error("Failed to create pid file %s: %m", linkpidfile);
1248 linkpidfile[0] = '\0';
1249 }
1250 }
1251
1252 /*
1253 * holdoff_end - called via a timeout when the holdoff period ends.
1254 */
1255 /*ARGSUSED*/
1256 static void
holdoff_end(arg)1257 holdoff_end(arg)
1258 void *arg;
1259 {
1260 new_phase(PHASE_DORMANT);
1261 }
1262
1263 /* List of protocol names, to make our messages a little more informative. */
1264 struct protocol_list {
1265 u_short proto;
1266 const char *name;
1267 } protocol_list[] = {
1268 { 0x21, "IP" },
1269 { 0x23, "OSI Network Layer" },
1270 { 0x25, "Xerox NS IDP" },
1271 { 0x27, "DECnet Phase IV" },
1272 { 0x29, "Appletalk" },
1273 { 0x2b, "Novell IPX" },
1274 { 0x2d, "VJ compressed TCP/IP" },
1275 { 0x2f, "VJ uncompressed TCP/IP" },
1276 { 0x31, "Bridging PDU" },
1277 { 0x33, "Stream Protocol ST-II" },
1278 { 0x35, "Banyan Vines" },
1279 { 0x37, "Old VJ compressed TCP/IP" },
1280 { 0x39, "AppleTalk EDDP" },
1281 { 0x3b, "AppleTalk SmartBuffered" },
1282 { 0x3d, "Multilink" },
1283 { 0x3f, "NetBIOS Frame" },
1284 { 0x41, "Cisco LAN Extension" },
1285 { 0x43, "Ascom Timeplex" },
1286 { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" },
1287 { 0x47, "DCA Remote Lan" },
1288 { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
1289 { 0x4b, "SNA over 802.2" },
1290 { 0x4d, "SNA" },
1291 { 0x4f, "IP6 Header Compression" },
1292 { 0x51, "KNX Bridging" },
1293 { 0x53, "Encrypted" },
1294 { 0x55, "per-link encrypted" },
1295 { 0x57, "IPv6" },
1296 { 0x59, "PPP Muxing" },
1297 { 0x6f, "Stampede Bridging" },
1298 { 0x73, "MP+" },
1299 { 0xc1, "STMF" },
1300 { 0xfb, "per-link compressed" },
1301 { 0xfd, "compressed datagram" },
1302 { 0x0201, "802.1d Hello Packets" },
1303 { 0x0203, "IBM Source Routing BPDU" },
1304 { 0x0205, "DEC LANBridge100 Spanning Tree" },
1305 { 0x0207, "Cisco Discovery Protocol" },
1306 { 0x0231, "Luxcom" },
1307 { 0x0233, "Sigma Network Systems" },
1308 { 0x0235, "Apple Client Server Protocol" },
1309 { 0x0281, "MPLS Unicast" },
1310 { 0x0283, "MPLS Multicast" },
1311 { 0x0285, "IEEE p1284.4" },
1312 { 0x0287, "ETSI TETRA TNP1" },
1313 { 0x4021, "Stacker LZS" },
1314 { 0x8021, "Internet Protocol Control Protocol" },
1315 { 0x8023, "OSI Network Layer Control Protocol" },
1316 { 0x8025, "Xerox NS IDP Control Protocol" },
1317 { 0x8027, "DECnet Phase IV Control Protocol" },
1318 { 0x8029, "Appletalk Control Protocol" },
1319 { 0x802b, "Novell IPX Control Protocol" },
1320 { 0x8031, "Bridging Control Protocol" },
1321 { 0x8033, "Stream Protocol Control Protocol" },
1322 { 0x8035, "Banyan Vines Control Protocol" },
1323 { 0x803f, "NetBIOS Frames Control Protocol" },
1324 { 0x8041, "Cisco LAN Extension Control Protocol" },
1325 { 0x8043, "Ascom Timeplex Control Protocol" },
1326 { 0x8045, "Fujitsu LBLB Control Protocol" },
1327 { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" },
1328 { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
1329 { 0x804b, "SNA over 802.2 Control Protocol" },
1330 { 0x804d, "SNA Control Protocol" },
1331 { 0x8051, "KNX Bridging Control Protocol" },
1332 { 0x8053, "Encryption Control Protocol" },
1333 { 0x8055, "Per-link Encryption Control Protocol" },
1334 { 0x8057, "IPv6 Control Protocol" },
1335 { 0x806f, "Stampede Bridging Control Protocol" },
1336 { 0x80c1, "STMF Control Protocol" },
1337 { 0x80fb, "Per-link Compression Control Protocol" },
1338 { 0x80fd, "Compression Control Protocol" },
1339 { 0x8207, "Cisco Discovery Control Protocol" },
1340 { 0x8235, "Apple Client Server Control Protocol" },
1341 { 0x8281, "MPLS Control Protocol" },
1342 { 0x8287, "ETSI TETRA TNP1 Control Protocol" },
1343 { 0xc021, "Link Control Protocol" },
1344 { 0xc023, "Password Authentication Protocol" },
1345 { 0xc025, "Link Quality Report" },
1346 { 0xc027, "Shiva Password Authentication Protocol" },
1347 { 0xc029, "CallBack Control Protocol (CBCP)" },
1348 { 0xc02b, "Bandwidth Allocation Control Protocol" },
1349 { 0xc02d, "BAP" },
1350 { 0xc081, "Container Control Protocol" },
1351 { 0xc223, "Challenge Handshake Authentication Protocol" },
1352 { 0xc227, "Extensible Authentication Protocol" },
1353 { 0xc281, "Funk Proprietary Authentication Protocol" },
1354 { 0, NULL },
1355 };
1356
1357 /*
1358 * protocol_name - find a name for a PPP protocol.
1359 */
1360 const char *
protocol_name(proto)1361 protocol_name(proto)
1362 int proto;
1363 {
1364 struct protocol_list *lp;
1365
1366 for (lp = protocol_list; lp->proto != 0; ++lp)
1367 if (proto == lp->proto)
1368 return (lp->name);
1369 return (NULL);
1370 }
1371
1372 static const char *phase_names[] = { PHASE__NAMES };
1373
1374 const char *
phase_name(pval)1375 phase_name(pval)
1376 int pval;
1377 {
1378 static char buf[32];
1379
1380 if (pval < 0 || pval >= Dim(phase_names)) {
1381 (void) slprintf(buf, sizeof (buf), "unknown %d", pval);
1382 return ((const char *)buf);
1383 }
1384 return (phase_names[pval]);
1385 }
1386
1387 /*
1388 * get_input - called when incoming data is available.
1389 */
1390 static void
get_input()1391 get_input()
1392 {
1393 int len, i;
1394 u_char *p;
1395 u_short protocol;
1396 struct protent *protp;
1397 const char *pname;
1398
1399 p = inpacket_buf; /* point to beginning of packet buffer */
1400
1401 len = read_packet(inpacket_buf);
1402 if (len < 0)
1403 return;
1404
1405 if (len == 0) {
1406 notice("Modem hangup");
1407 hungup = 1;
1408 status = EXIT_HANGUP;
1409 lcp_lowerdown(0); /* serial link is no longer available */
1410 link_terminated(0);
1411 return;
1412 }
1413
1414 if (debug /*&& (debugflags & DBG_INPACKET)*/)
1415 dbglog("rcvd %P", p, len);
1416
1417 if (len < PPP_HDRLEN) {
1418 dbglog("Discarded short packet (%d < %d)", len, PPP_HDRLEN);
1419 return;
1420 }
1421
1422 p += 2; /* Skip address and control */
1423 GETSHORT(protocol, p);
1424 len -= PPP_HDRLEN;
1425
1426 pname = debug ? NULL : protocol_name(protocol);
1427
1428 /*
1429 * Toss all non-LCP packets unless LCP is in Opened state and
1430 * discard non-authentication protocols if we're not yet
1431 * authenticated.
1432 */
1433 if ((protocol != PPP_LCP &&
1434 (phase < PHASE_AUTHENTICATE || phase > PHASE_RUNNING)) ||
1435 (phase <= PHASE_AUTHENTICATE &&
1436 !(protocol == PPP_LCP || protocol == PPP_LQR ||
1437 protocol == PPP_PAP || protocol == PPP_CHAP))) {
1438 if (pname == NULL)
1439 dbglog("Discarded proto 0x%x in %s phase",
1440 protocol, phase_name(phase));
1441 else
1442 dbglog("Discarded %s (0x%x) in %s phase",
1443 pname, protocol, phase_name(phase));
1444 return;
1445 }
1446
1447 /*
1448 * Upcall the proper protocol input routine.
1449 */
1450 for (i = 0; (protp = protocols[i]) != NULL; ++i) {
1451 if (protp->protocol == protocol && protp->enabled_flag) {
1452 (*protp->input)(0, p, len);
1453 return;
1454 }
1455 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
1456 && protp->datainput != NULL) {
1457 (*protp->datainput)(0, p, len);
1458 return;
1459 }
1460 }
1461
1462 if (debug) {
1463 if (pname != NULL)
1464 warn("Unsupported protocol '%s' (0x%x) received", pname, protocol);
1465 else
1466 warn("Unsupported protocol 0x%x received", protocol);
1467 }
1468 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
1469 }
1470
1471 /*
1472 * new_phase - signal the start of a new phase of pppd's operation.
1473 */
1474 void
new_phase(p)1475 new_phase(p)
1476 int p;
1477 {
1478 if (new_phase_hook != NULL)
1479 (*new_phase_hook)(p, phase);
1480 phase = p;
1481 }
1482
1483 /*
1484 * die - clean up state and exit with the specified status.
1485 */
1486 void
die(status)1487 die(status)
1488 int status;
1489 {
1490 cleanup();
1491 if (phase != PHASE_EXIT) {
1492 syslog(LOG_INFO, "Exit.");
1493 new_phase(PHASE_EXIT);
1494 }
1495 exit(status);
1496 }
1497
1498 /*
1499 * cleanup - restore anything which needs to be restored before we exit
1500 */
1501 static void
cleanup()1502 cleanup()
1503 {
1504 sys_cleanup(); /* XXX: Need to check if this is okay after close_tty */
1505
1506 if (fd_ppp >= 0) {
1507 fd_ppp = -1;
1508 disestablish_ppp(ttyfd);
1509 }
1510 if (real_ttyfd >= 0)
1511 close_tty();
1512
1513 if (pidfilename[0] != '\0' && unlink(pidfilename) < 0 && errno != ENOENT)
1514 warn("unable to delete pid file %s: %m", pidfilename);
1515 pidfilename[0] = '\0';
1516 if (linkpidfile[0] != '\0' && unlink(linkpidfile) < 0 && errno != ENOENT)
1517 warn("unable to delete pid file %s: %m", linkpidfile);
1518 linkpidfile[0] = '\0';
1519
1520 if (locked) {
1521 locked = 0;
1522 unlock();
1523 }
1524
1525 #ifdef HAVE_MULTILINK
1526 if (pppdb != NULL) {
1527 cleanup_db();
1528 pppdb = NULL;
1529 }
1530 #endif
1531 }
1532
1533 /*
1534 * close_tty - restore the terminal device and close it.
1535 */
1536 static void
close_tty()1537 close_tty()
1538 {
1539 int fd = real_ttyfd;
1540
1541 real_ttyfd = -1;
1542
1543 /* drop dtr to hang up */
1544 if (!default_device && modem) {
1545 setdtr(fd, 0);
1546 /*
1547 * This sleep is in case the serial port has CLOCAL set by default,
1548 * and consequently will reassert DTR when we close the device.
1549 */
1550 (void) sleep(1);
1551 }
1552
1553 restore_tty(fd);
1554
1555 if (tty_mode != (mode_t) -1) {
1556 if (fchmod(fd, tty_mode) != 0) {
1557 /* XXX if devnam is a symlink, this will change the link */
1558 if (chmod(devnam, tty_mode) != 0) {
1559 error("Unable to chmod file %s: %m", devnam);
1560 }
1561 }
1562 }
1563
1564 (void) close(fd);
1565 }
1566
1567 /*
1568 * update_link_stats - get stats at link termination.
1569 */
1570 void
update_link_stats(u)1571 update_link_stats(u)
1572 int u;
1573 {
1574 struct timeval now;
1575 char numbuf[32];
1576
1577 if (gettimeofday(&now, NULL) >= 0) {
1578 link_connect_time = now.tv_sec - start_time.tv_sec;
1579 (void) slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time);
1580 script_setenv("CONNECT_TIME", numbuf, 0);
1581 } else {
1582 link_connect_time = 0;
1583 }
1584
1585 if (get_ppp_stats(u, &link_stats)) {
1586 (void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1587 link_stats.bytes_out);
1588 script_setenv("BYTES_SENT", numbuf, 0);
1589 (void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1590 link_stats.bytes_in);
1591 script_setenv("BYTES_RCVD", numbuf, 0);
1592 (void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1593 link_stats.pkts_in);
1594 script_setenv("PKTS_RCVD", numbuf, 0);
1595 (void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1596 link_stats.pkts_out);
1597 script_setenv("PKTS_SENT", numbuf, 0);
1598 link_stats_valid = 1;
1599 }
1600 }
1601
1602
1603 struct callout {
1604 struct timeval c_time; /* time at which to call routine */
1605 void *c_arg; /* argument to routine */
1606 void (*c_func) __P((void *)); /* routine */
1607 struct callout *c_next;
1608 };
1609
1610 static struct callout *callout = NULL; /* Callout list */
1611 static struct timeval timenow; /* Current time */
1612
1613 /*
1614 * timeout - Schedule a timeout.
1615 *
1616 * Note that this timeout takes the number of seconds, NOT hz (as in
1617 * the kernel).
1618 */
1619 void
1620 timeout(func, arg, time)
1621 void (*func) __P((void *));
1622 void *arg;
1623 int time;
1624 {
1625 struct callout *newp, *p, **pp;
1626
1627 MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time));
1628
1629 /*
1630 * Allocate timeout.
1631 */
1632 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL)
1633 novm("callout structure for timeout.");
1634 newp->c_arg = arg;
1635 newp->c_func = func;
1636 (void) gettimeofday(&timenow, NULL);
1637 newp->c_time.tv_sec = timenow.tv_sec + time;
1638 newp->c_time.tv_usec = timenow.tv_usec;
1639
1640 /*
1641 * Find correct place and link it in.
1642 */
1643 for (pp = &callout; (p = *pp) != NULL; pp = &p->c_next)
1644 if (newp->c_time.tv_sec < p->c_time.tv_sec
1645 || (newp->c_time.tv_sec == p->c_time.tv_sec
1646 && newp->c_time.tv_usec < p->c_time.tv_usec))
1647 break;
1648 newp->c_next = p;
1649 *pp = newp;
1650 }
1651
1652
1653 /*
1654 * untimeout - Unschedule a timeout.
1655 */
1656 void
1657 untimeout(func, arg)
1658 void (*func) __P((void *));
1659 void *arg;
1660 {
1661 struct callout **copp, *freep;
1662
1663 MAINDEBUG(("Untimeout %p:%p.", func, arg));
1664
1665 /*
1666 * Find first matching timeout and remove it from the list.
1667 */
1668 for (copp = &callout; (freep = *copp) != NULL; copp = &freep->c_next)
1669 if (freep->c_func == func && freep->c_arg == arg) {
1670 *copp = freep->c_next;
1671 free((char *) freep);
1672 break;
1673 }
1674 }
1675
1676
1677 /*
1678 * calltimeout - Call any timeout routines which are now due.
1679 */
1680 static void
calltimeout()1681 calltimeout()
1682 {
1683 struct callout *p;
1684
1685 while (callout != NULL) {
1686 p = callout;
1687
1688 if (gettimeofday(&timenow, NULL) < 0)
1689 fatal("Failed to get time of day: %m");
1690 if (!(p->c_time.tv_sec < timenow.tv_sec
1691 || (p->c_time.tv_sec == timenow.tv_sec
1692 && p->c_time.tv_usec <= timenow.tv_usec)))
1693 break; /* no, it's not time yet */
1694
1695 callout = p->c_next;
1696 (*p->c_func)(p->c_arg);
1697
1698 free((char *) p);
1699 }
1700 }
1701
1702
1703 /*
1704 * timeleft - return the length of time until the next timeout is due.
1705 */
1706 static struct timeval *
timeleft(tvp)1707 timeleft(tvp)
1708 struct timeval *tvp;
1709 {
1710 if (callout == NULL)
1711 return (NULL);
1712
1713 (void) gettimeofday(&timenow, NULL);
1714 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
1715 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
1716 if (tvp->tv_usec < 0) {
1717 tvp->tv_usec += 1000000;
1718 tvp->tv_sec -= 1;
1719 }
1720 if (tvp->tv_sec < 0)
1721 tvp->tv_sec = tvp->tv_usec = 0;
1722
1723 return (tvp);
1724 }
1725
1726
1727 /*
1728 * kill_my_pg - send a signal to our process group, and ignore it ourselves.
1729 */
1730 static void
kill_my_pg(sig)1731 kill_my_pg(sig)
1732 int sig;
1733 {
1734 struct sigaction act, oldact;
1735 sigset_t mask;
1736
1737 BZERO(&act, sizeof (act));
1738 act.sa_handler = SIG_IGN;
1739 (void) sigemptyset(&mask);
1740 (void) sigaddset(&mask, sig);
1741 /*
1742 * Ignore signal 'sig' temporarily, before finally re-activating the
1743 * original handler. We need to do it in the following sequence, since
1744 * otherwise the signal handler for 'sig' will be called forever.
1745 */
1746 if (sigaction(sig, &act, &oldact) < 0) {
1747 fatal("kill_my_pg: couldn't establish signal handler (%d): %m", sig);
1748 }
1749 (void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
1750 /*
1751 * Send signal 'sig' to all processes whose process group ID is equal
1752 * to the process group ID of the sender.
1753 */
1754 (void) kill(0, sig);
1755 if (sigaction(sig, &oldact, NULL) < 0) {
1756 fatal("kill_my_pg: couldn't establish signal handler (%d): %m", sig);
1757 }
1758 }
1759
1760
1761 /*
1762 * hup - Catch SIGHUP signal.
1763 *
1764 * Indicates that the physical layer has been disconnected.
1765 * We don't rely on this indication; if the user has sent this
1766 * signal, we just take the link down.
1767 */
1768 static void
hup(sig)1769 hup(sig)
1770 int sig;
1771 {
1772 info("Hangup (SIGHUP)");
1773 kill_link = 1;
1774 if (status != EXIT_HANGUP)
1775 status = EXIT_USER_REQUEST;
1776 if (conn_running > 0)
1777 /* Send the signal to the [dis]connector process(es) also */
1778 kill_my_pg(sig);
1779 if (charshunt_pid)
1780 (void) kill(charshunt_pid, sig);
1781 if (waiting)
1782 siglongjmp(sigjmp, 1);
1783 }
1784
1785
1786 /*
1787 * term - Catch SIGTERM signal and SIGINT signal (^C/del).
1788 *
1789 * Indicates that we should initiate a graceful disconnect and exit.
1790 */
1791 /*ARGSUSED*/
1792 static void
term(sig)1793 term(sig)
1794 int sig;
1795 {
1796 info("Terminating on signal %d.", sig);
1797 persist = 0; /* don't try to restart */
1798 kill_link = 1;
1799 status = EXIT_USER_REQUEST;
1800 if (conn_running > 0)
1801 /* Send the signal to the [dis]connector process(es) also */
1802 kill_my_pg(sig);
1803 if (charshunt_pid)
1804 (void) kill(charshunt_pid, sig);
1805 if (waiting)
1806 siglongjmp(sigjmp, 1);
1807 }
1808
1809
1810 /*
1811 * chld - Catch SIGCHLD signal.
1812 * Sets a flag so we will call reap_kids in the mainline.
1813 */
1814 /*ARGSUSED*/
1815 static void
chld(sig)1816 chld(sig)
1817 int sig;
1818 {
1819 got_sigchld = 1;
1820 if (waiting)
1821 siglongjmp(sigjmp, 1);
1822 }
1823
1824 /*
1825 * toggle_debug - Catch SIGUSR1 signal.
1826 *
1827 * Toggle debug flag.
1828 */
1829 /*ARGSUSED*/
1830 static void
toggle_debug(sig)1831 toggle_debug(sig)
1832 int sig;
1833 {
1834 if (debug) {
1835 print_ncpstate(0, NULL);
1836 dbglog("debug logging disabled");
1837 (void) setlogmask(LOG_UPTO(LOG_WARNING));
1838 debug = 0;
1839 } else {
1840 (void) setlogmask(LOG_UPTO(LOG_DEBUG));
1841 dbglog("debug logging enabled");
1842 print_ncpstate(0, NULL);
1843 debug = 1;
1844 }
1845 }
1846
1847
1848 /*
1849 * open_ccp - Catch SIGUSR2 signal.
1850 *
1851 * Try to (re)negotiate compression.
1852 */
1853 /*ARGSUSED*/
1854 static void
open_ccp(sig)1855 open_ccp(sig)
1856 int sig;
1857 {
1858 open_ccp_flag = 1;
1859 if (waiting)
1860 siglongjmp(sigjmp, 1);
1861 }
1862
1863
1864 /*
1865 * bad_signal - We've caught a fatal signal. Clean up state and exit.
1866 */
1867 static void
bad_signal(sig)1868 bad_signal(sig)
1869 int sig;
1870 {
1871 static int crashed = 0;
1872
1873 if (crashed)
1874 _exit(127);
1875 crashed = 1;
1876 error("Fatal signal %d", sig);
1877 if (conn_running > 0)
1878 kill_my_pg(SIGTERM);
1879 if (charshunt_pid)
1880 (void) kill(charshunt_pid, SIGTERM);
1881 die(127);
1882 }
1883
1884
1885 /*
1886 * device_script - run a program to talk to the serial device
1887 * (e.g. to run the connector or disconnector script).
1888 */
1889 static int
device_script(program,in,out,dont_wait,optname)1890 device_script(program, in, out, dont_wait, optname)
1891 char *program;
1892 int in, out;
1893 int dont_wait;
1894 char *optname;
1895 {
1896 pid_t pid;
1897 int status = -1;
1898 int errfd;
1899 int envpipe[2];
1900
1901 envpipe[0] = envpipe[1] = -1;
1902 if (!dont_wait && device_pipe_hook != NULL && pipe(envpipe) == -1) {
1903 error("Cannot create pipe for child: %m");
1904 return (-1);
1905 }
1906
1907 ++conn_running;
1908 pid = fork();
1909
1910 if (pid == (pid_t)-1) {
1911 --conn_running;
1912 error("Failed to create child process: %m");
1913 return (-1);
1914 }
1915
1916 if (pid == (pid_t)0) {
1917 sys_close();
1918 closelog();
1919 if (envpipe[0] >= 0) {
1920 if (envpipe[1] <= 2)
1921 envpipe[1] = dup(envpipe[1]);
1922 (void) close(envpipe[0]);
1923 }
1924 if (in == 2) {
1925 /* aargh!!! */
1926 int newin = dup(in);
1927 if (in == out)
1928 out = newin;
1929 in = newin;
1930 } else if (out == 2) {
1931 out = dup(out);
1932 }
1933 if (log_to_fd >= 0) {
1934 if (log_to_fd != 2) {
1935 if (dup2(log_to_fd, 2) < 0)
1936 error("dup2(log_to_fd, STDERR) failed: %m");
1937 }
1938 } else {
1939 (void) close(2);
1940 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600);
1941 if (errfd >= 0 && errfd != 2) {
1942 if (dup2(errfd, 2) < 0)
1943 error("dup2(errfd, STDERR) failed: %m");
1944 (void) close(errfd);
1945 }
1946 }
1947 if (in != 0) {
1948 if (out == 0)
1949 out = dup(out);
1950 if (dup2(in, 0) < 0)
1951 error("dup2(in, STDIN) failed: %m");
1952 }
1953 if (out != 1) {
1954 if (dup2(out, 1) < 0)
1955 error("dup2(out, STDOUT) failed: %m");
1956 }
1957 if (envpipe[0] >= 0 && dup2(envpipe[1], 3) < 0)
1958 error("dup2(pipe, pipeout) failed: %m");
1959 if (real_ttyfd > 2)
1960 (void) close(real_ttyfd);
1961 if (pty_master > 2)
1962 (void) close(pty_master);
1963 if (pty_slave > 2) {
1964 (void) close(pty_slave);
1965 pty_slave = -1;
1966 }
1967 (void) setuid(uid);
1968 if (getuid() != uid) {
1969 error("setuid failed");
1970 exit(1);
1971 }
1972 (void) setgid(getgid());
1973 if (script_env != NULL) {
1974 while (*script_env != NULL) {
1975 if (putenv(*script_env) == -1)
1976 warn("unable to set %s for %s: %m", *script_env, program);
1977 script_env++;
1978 }
1979 }
1980 (void) execl("/bin/sh", "sh", "-c", program, (char *)0);
1981 error("could not exec /bin/sh: %m");
1982 exit(99);
1983 /* NOTREACHED */
1984 }
1985
1986 if (debug)
1987 dbglog("%s option: '%s' started (pid %d)", optname, program, pid);
1988 if (dont_wait) {
1989 record_child(pid, program, NULL, NULL);
1990 status = 0;
1991 } else {
1992 if (envpipe[0] >= 0) {
1993 (void) close(envpipe[1]);
1994 (*device_pipe_hook)(envpipe[0]);
1995 }
1996 while (waitpid(pid, &status, 0) < 0) {
1997 if (errno == EINTR)
1998 continue;
1999 fatal("error waiting for (dis)connection process: %m");
2000 }
2001 if (envpipe[0] >= 0)
2002 (void) close(envpipe[0]);
2003 --conn_running;
2004 }
2005
2006 return (status == 0 ? 0 : -1);
2007 }
2008
2009
2010 /*
2011 * run-program - execute a program with given arguments,
2012 * but don't wait for it.
2013 * If the program can't be executed, logs an error unless
2014 * must_exist is 0 and the program file doesn't exist.
2015 * Returns -1 if it couldn't fork, 0 if the file doesn't exist
2016 * or isn't an executable plain file, or the process ID of the child.
2017 * If done != NULL, (*done)(arg, int) will be called later (within
2018 * reap_kids) if this routine returns value > 0.
2019 */
2020 pid_t
run_program(prog,args,must_exist,done,arg)2021 run_program(prog, args, must_exist, done, arg)
2022 char *prog;
2023 char **args;
2024 int must_exist;
2025 void (*done) __P((void *arg, int status));
2026 void *arg;
2027 {
2028 pid_t pid;
2029 struct stat sbuf;
2030 int retv;
2031
2032 /*
2033 * First check if the file exists and is executable.
2034 * We don't use access() because that would use the
2035 * real user-id, which might not be root, and the script
2036 * might be accessible only to root.
2037 */
2038 errno = EINVAL;
2039 if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode)
2040 || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) {
2041 if (must_exist || errno != ENOENT)
2042 warn("Can't execute %s: %m", prog);
2043 return (0);
2044 }
2045
2046 if (updown_script_hook != NULL) {
2047 retv = (*updown_script_hook)((const char ***)&args);
2048 if (retv == -1) {
2049 return (-1);
2050 }
2051 }
2052
2053 pid = fork();
2054 if (pid == (pid_t)-1) {
2055 error("Failed to create child process for %s: %m", prog);
2056 return (-1);
2057 }
2058 if (pid == (pid_t)0) {
2059 int new_fd;
2060
2061 /* Leave the current location */
2062 (void) setsid(); /* No controlling tty. */
2063 (void) umask (S_IRWXG|S_IRWXO);
2064 (void) chdir ("/"); /* no current directory. */
2065 (void) setuid(0); /* set real UID = root */
2066 (void) setgid(getegid());
2067
2068 /* Ensure that nothing of our device environment is inherited. */
2069 sys_close();
2070 closelog();
2071 (void) close(0);
2072 (void) close(1);
2073 (void) close(2);
2074 (void) close(ttyfd); /* tty interface to the ppp device */
2075 if (real_ttyfd >= 0)
2076 (void) close(real_ttyfd);
2077
2078 /* Don't pass handles to the PPP device, even by accident. */
2079 new_fd = open (_PATH_DEVNULL, O_RDWR);
2080 if (new_fd >= 0) {
2081 if (new_fd != 0) {
2082 if (dup2(new_fd, 0) < 0) /* stdin <- /dev/null */
2083 error("dup2(/dev/null, STDIN) failed: %m");
2084 (void) close(new_fd);
2085 }
2086 if (dup2(0, 1) < 0) /* stdout -> /dev/null */
2087 error("dup2(/dev/null, STDOUT) failed: %m");
2088 if (dup2(0, 2) < 0) /* stderr -> /dev/null */
2089 error("dup2(/dev/null, STDERR) failed: %m");
2090 }
2091
2092 #ifdef BSD
2093 /* Force the priority back to zero if pppd is running higher. */
2094 if (setpriority (PRIO_PROCESS, 0, 0) < 0)
2095 warn("can't reset priority to 0: %m");
2096 #endif
2097
2098 /* SysV recommends a second fork at this point. */
2099
2100 /* run the program */
2101 (void) execve(prog, args, script_env);
2102 if (must_exist || errno != ENOENT) {
2103 /* have to reopen the log, there's nowhere else
2104 for the message to go. */
2105 reopen_log();
2106 syslog(LOG_ERR, "Can't execute %s: %m", prog);
2107 closelog();
2108 }
2109 _exit(-1);
2110 }
2111
2112 if (debug)
2113 dbglog("Script %s started (pid %d)", prog, pid);
2114 record_child(pid, prog, done, arg);
2115
2116 return (pid);
2117 }
2118
2119
2120 /*
2121 * record_child - add a child process to the list for reap_kids
2122 * to use.
2123 */
2124 static void
record_child(pid,prog,done,arg)2125 record_child(pid, prog, done, arg)
2126 pid_t pid;
2127 char *prog;
2128 void (*done) __P((void *, int));
2129 void *arg;
2130 {
2131 struct subprocess *chp;
2132
2133 ++n_children;
2134
2135 chp = (struct subprocess *) malloc(sizeof(struct subprocess));
2136 if (chp == NULL) {
2137 warn("losing track of %s process", prog);
2138 } else {
2139 chp->pid = pid;
2140 chp->prog = prog;
2141 chp->done = done;
2142 chp->arg = arg;
2143 chp->next = children;
2144 children = chp;
2145 }
2146 }
2147
2148
2149 /*
2150 * reap_kids - get status from any dead child processes,
2151 * and log a message for abnormal terminations.
2152 */
2153 static int
reap_kids(waitfor)2154 reap_kids(waitfor)
2155 int waitfor;
2156 {
2157 pid_t pid;
2158 int status, i;
2159 struct subprocess *chp, **prevp;
2160
2161 got_sigchld = 0;
2162 if (n_children == 0)
2163 return (0);
2164
2165 /*CONSTANTCONDITION*/
2166 while (1) {
2167 pid = waitpid(-1, &status, (waitfor ? 0 : WNOHANG));
2168 if (pid == 0) {
2169 break; /* return 0 */
2170 } else if (pid == -1) {
2171 if (errno == EINTR)
2172 continue;
2173 if (errno != ECHILD)
2174 error("Error waiting for child process: %m");
2175 return (-1);
2176 } else {
2177 for (prevp = &children; (chp = *prevp) != NULL;
2178 prevp = &chp->next) {
2179 if (chp->pid == pid) {
2180 --n_children;
2181 *prevp = chp->next;
2182 break;
2183 }
2184 }
2185 if (WIFSIGNALED(status) || WIFSTOPPED(status)) {
2186 i = WIFSIGNALED(status) ? WTERMSIG(status) : WSTOPSIG(status);
2187 warn("Child process %s (pid %d) %s with signal %d (%s)",
2188 (chp != NULL ? chp->prog : "??"), pid,
2189 (WIFSIGNALED(status) ? "terminated" : "stopped"),
2190 i, signal_name(i));
2191 } else if (debug) {
2192 dbglog("Child process %s finished (pid %d), status = %d",
2193 (chp != NULL ? chp->prog: "??"), pid,
2194 WEXITSTATUS(status));
2195 }
2196 if ((chp != NULL) && (chp->done != NULL))
2197 (*chp->done)(chp->arg, status);
2198 if (chp != NULL)
2199 free(chp);
2200 }
2201 }
2202 return (0);
2203 }
2204
2205 /*
2206 * infanticide - timeout while waiting for child process.
2207 */
2208 /*ARGSUSED*/
2209 static void
infanticide(sig)2210 infanticide(sig)
2211 int sig;
2212 {
2213 struct subprocess *chp;
2214 static int runcount = 0;
2215
2216 if (runcount < 2) {
2217 for (chp = children; chp != NULL; chp = chp->next)
2218 (void) kill(chp->pid, runcount == 0 ? SIGTERM : SIGKILL);
2219 } else {
2220 kill_my_pg(SIGTERM);
2221 /* Quit and hope for the best. */
2222 n_children = 0;
2223 }
2224 runcount++;
2225 }
2226
2227 /*
2228 * Perform final wait before exiting.
2229 */
2230 static void
final_reap()2231 final_reap()
2232 {
2233 struct sigaction sa;
2234 struct subprocess *chp;
2235
2236 if (n_children > 0 && debug) {
2237 dbglog("Waiting for %d child processes...", n_children);
2238 for (chp = children; chp != NULL; chp = chp->next)
2239 dbglog(" pid %d: %s", chp->pid, chp->prog);
2240 }
2241 BZERO(&sa, sizeof (sa));
2242 /*CONSTANTCONDITION*/ SIGNAL(SIGALRM, infanticide);
2243 while (n_children > 0) {
2244 (void) alarm(7);
2245 if (reap_kids(1) < 0)
2246 break;
2247 }
2248 (void) alarm(0);
2249 }
2250
2251 /*
2252 * novm - log an error message saying we ran out of memory, and die.
2253 */
2254 void
novm(msg)2255 novm(msg)
2256 char *msg;
2257 {
2258 fatal("Virtual memory exhausted allocating %s\n", msg);
2259 }
2260
2261 /*
2262 * script_setenv - set an environment variable value to be used
2263 * for scripts that we run (e.g. ip-up, auth-up, etc.)
2264 */
2265 void
script_setenv(var,value,iskey)2266 script_setenv(var, value, iskey)
2267 const char *var;
2268 const char *value;
2269 int iskey;
2270 {
2271 size_t varl = strlen(var);
2272 size_t vl = varl + strlen(value) + 2;
2273 int i;
2274 char *p, *newstring;
2275
2276 /*
2277 * XXX: Can we assert that a tdb write lock is held here ? It appears that
2278 * Linux's use of tdb is not safe.
2279 */
2280 newstring = (char *) malloc(vl+1);
2281 if (newstring == NULL) {
2282 novm("script environment string");
2283 return;
2284 }
2285 *newstring++ = iskey;
2286 (void) slprintf(newstring, vl, "%s=%s", var, value);
2287
2288 /* check if this variable is already set */
2289 if (script_env != NULL) {
2290 for (i = 0; (p = script_env[i]) != NULL; ++i) {
2291 if (strncmp(p, var, varl) == 0 && p[varl] == '=') {
2292 #ifdef HAVE_MULTILINK
2293 if (p[-1] != '\0' && pppdb != NULL)
2294 delete_db_key(p);
2295 #endif
2296 free(p-1);
2297 script_env[i] = newstring;
2298 #ifdef HAVE_MULTILINK
2299 if (iskey && pppdb != NULL)
2300 add_db_key(newstring);
2301 update_db_entry();
2302 #endif
2303 return;
2304 }
2305 }
2306 } else {
2307 /* no space allocated for script env. ptrs. yet */
2308 i = 0;
2309 script_env = (char **) malloc(16 * sizeof(char *));
2310 if (script_env == NULL) {
2311 novm("script environment variable.");
2312 return;
2313 }
2314 s_env_nalloc = 16;
2315 }
2316
2317 /* reallocate script_env with more space if needed */
2318 if (i + 1 >= s_env_nalloc) {
2319 int new_n = i + 17;
2320 char **newenv = (char **) realloc((void *)script_env,
2321 new_n * sizeof(char *));
2322 if (newenv == NULL) {
2323 novm("expanded script environment variable.");
2324 return;
2325 }
2326 script_env = newenv;
2327 s_env_nalloc = new_n;
2328 }
2329
2330 script_env[i] = newstring;
2331 script_env[i+1] = NULL;
2332
2333 #ifdef HAVE_MULTILINK
2334 if (pppdb != NULL) {
2335 if (iskey)
2336 add_db_key(newstring);
2337 update_db_entry();
2338 }
2339 #endif
2340 }
2341
2342 /*
2343 * script_unsetenv - remove a variable from the environment
2344 * for scripts.
2345 */
2346 void
script_unsetenv(var)2347 script_unsetenv(var)
2348 const char *var;
2349 {
2350 int vl = strlen(var);
2351 int i;
2352 char *p;
2353
2354 /*
2355 * XXX: Can we assert that a tdb write lock is held here ? It appears that
2356 * Linux's use of tdb is not safe.
2357 */
2358 if (script_env == NULL)
2359 return;
2360 for (i = 0; (p = script_env[i]) != NULL; ++i) {
2361 if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
2362 #ifdef HAVE_MULTILINK
2363 if (p[-1] != '\0' && pppdb != NULL)
2364 delete_db_key(p);
2365 #endif
2366 free(p-1);
2367 while ((script_env[i] = script_env[i+1]) != NULL)
2368 ++i;
2369 break;
2370 }
2371 }
2372 #ifdef HAVE_MULTILINK
2373 if ((pppdb != NULL) && (p != NULL))
2374 update_db_entry();
2375 #endif
2376 }
2377
2378 /*
2379 * script_getenv - find a variable in the script environment.
2380 */
2381 const char *
script_getenv(var)2382 script_getenv(var)
2383 const char *var;
2384 {
2385 int vl = strlen(var);
2386 int i;
2387 char *p;
2388
2389 if (script_env == NULL)
2390 return (NULL);
2391 for (i = 0; (p = script_env[i]) != NULL; ++i) {
2392 if (strncmp(p, var, vl) == 0 && p[vl] == '=')
2393 return ((const char *)p+vl+1);
2394 }
2395 return (NULL);
2396 }
2397
2398 #ifdef HAVE_MULTILINK
2399 /*
2400 * update_db_entry - update our entry in the database.
2401 */
2402 static void
update_db_entry()2403 update_db_entry()
2404 {
2405 TDB_DATA key, dbuf;
2406 int vlen, i;
2407 char *p, *q, *vbuf;
2408
2409 if (script_env == NULL)
2410 return;
2411 /*
2412 * vlen needs to be initialized as 1, or otherwise, the last string
2413 * is truncated by slprintf.
2414 */
2415 vlen = 1;
2416 for (i = 0; (p = script_env[i]) != NULL; ++i)
2417 vlen += strlen(p) + 1;
2418 vbuf = malloc(vlen);
2419 if (vbuf == NULL)
2420 novm("database entry");
2421 q = vbuf;
2422 for (i = 0; (p = script_env[i]) != NULL; ++i)
2423 q += slprintf(q, vbuf + vlen - q, "%s;", p);
2424
2425 key.dptr = db_key;
2426 key.dsize = strlen(db_key);
2427 dbuf.dptr = vbuf;
2428 dbuf.dsize = vlen;
2429 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
2430 error("tdb_store failed: %s", tdb_error(pppdb));
2431 }
2432
2433 /*
2434 * add_db_key - add a key that we can use to look up our database entry.
2435 */
2436 static void
add_db_key(str)2437 add_db_key(str)
2438 const char *str;
2439 {
2440 TDB_DATA key, dbuf;
2441
2442 key.dptr = (char *) str;
2443 key.dsize = strlen(str);
2444 dbuf.dptr = db_key;
2445 dbuf.dsize = strlen(db_key);
2446 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
2447 error("tdb_store key failed: %s", tdb_error(pppdb));
2448 }
2449
2450 /*
2451 * delete_db_key - delete a key for looking up our database entry.
2452 */
2453 static void
delete_db_key(str)2454 delete_db_key(str)
2455 const char *str;
2456 {
2457 TDB_DATA key;
2458
2459 key.dptr = (char *) str;
2460 key.dsize = strlen(str);
2461 (void) tdb_delete(pppdb, key);
2462 }
2463
2464 /*
2465 * cleanup_db - delete all the entries we put in the database.
2466 */
2467 static void
cleanup_db()2468 cleanup_db()
2469 {
2470 TDB_DATA key;
2471 int i;
2472 char *p;
2473
2474 key.dptr = db_key;
2475 key.dsize = strlen(db_key);
2476 (void) tdb_delete(pppdb, key);
2477 for (i = 0; (p = script_env[i]) != NULL; ++i)
2478 if (p[-1] != '\0')
2479 delete_db_key(p);
2480 }
2481 #endif /* HAVE_MULTILINK */
2482
2483 /*
2484 * open_socket - establish a stream socket connection to the nominated
2485 * host and port.
2486 * XXX: Need IPv6 support for those systems that support it (use getaddrinfo),
2487 * but requires portability changes.
2488 */
2489 static int
open_socket(dest)2490 open_socket(dest)
2491 char *dest;
2492 {
2493 char *sep, *endp = NULL;
2494 int sock;
2495 int port = -1;
2496 u_int32_t host;
2497 struct hostent *hent = NULL;
2498 struct sockaddr_in sad;
2499 struct servent *se;
2500
2501 /* parse host:port and resolve host to an IP address */
2502 sep = strchr(dest, ':');
2503 if (sep != NULL) {
2504 se = getservbyname((const char *)sep+1, "tcp");
2505 if (se != NULL) {
2506 port = ntohs(se->s_port);
2507 } else {
2508 port = strtol(sep+1, &endp, 10);
2509 if (endp == sep+1 || *endp != '\0') {
2510 error("Can't parse host:port for socket destination");
2511 return (-1);
2512 }
2513 }
2514 }
2515 if (port < 0 || port > 65535 || sep == dest) {
2516 error("Can't parse host:port for socket destination");
2517 return (-1);
2518 }
2519 *sep = '\0';
2520 host = inet_addr(dest);
2521 if (host == (u_int32_t) -1) {
2522 hent = gethostbyname(dest);
2523 if (hent == NULL) {
2524 error("%s: unknown host in socket option", dest);
2525 *sep = ':';
2526 return (-1);
2527 }
2528 BCOPY(hent->h_addr_list[0], &host, sizeof(host));
2529 hent->h_addr_list++;
2530 }
2531 *sep = ':';
2532
2533 for (;;) {
2534 /* get a socket and connect it to the other end */
2535 sock = socket(PF_INET, SOCK_STREAM, 0);
2536 if (sock < 0) {
2537 error("Can't create socket: %m");
2538 return (-1);
2539 }
2540 BZERO(&sad, sizeof(sad));
2541 sad.sin_family = AF_INET;
2542 sad.sin_port = htons(port);
2543 sad.sin_addr.s_addr = host;
2544 if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) >= 0) {
2545 break; /* return sock file descriptor */
2546 }
2547 if ((hent != NULL) && (hent->h_addr_list != NULL)) {
2548 BCOPY(hent->h_addr_list[0], &host, sizeof(host));
2549 hent->h_addr_list++;
2550 (void) close(sock);
2551 continue;
2552 }
2553 error("Can't connect to %s: %m", dest);
2554 (void) close(sock);
2555 return (-1);
2556 }
2557 return (sock);
2558 }
2559
2560 /*
2561 * print_ncpstate - prints out current NCP state.
2562 *
2563 * We're normally called from SIGUSR1 here, but this is safe because
2564 * these signals are blocked unless we're idle waiting for events.
2565 * There's no need to otherwise lock the data structures referenced.
2566 */
2567 void
print_ncpstate(unit,strptr)2568 print_ncpstate(unit, strptr)
2569 int unit;
2570 FILE *strptr;
2571 {
2572 struct protent *protp;
2573 int i;
2574
2575 (void) flprintf(strptr, "In %s phase\n", phase_name(phase));
2576 for (i = 0; (protp = protocols[i]) != NULL; ++i) {
2577 if (protp->print_stat != NULL)
2578 (*protp->print_stat)(unit, strptr);
2579 }
2580 sys_print_state(strptr);
2581 }
2582
2583 /*
2584 * start_charshunt - create a child process to run the character shunt.
2585 */
2586 static int
start_charshunt(ifd,ofd)2587 start_charshunt(ifd, ofd)
2588 int ifd, ofd;
2589 {
2590 pid_t cpid;
2591
2592 cpid = fork();
2593 if (cpid == (pid_t)-1) {
2594 error("Can't fork process for character shunt: %m");
2595 return (0);
2596 }
2597 if (cpid == (pid_t)0) {
2598 /* child */
2599 (void) close(pty_slave);
2600 pty_slave = -1;
2601 (void) setgid(getgid());
2602 (void) setuid(uid);
2603 if (getuid() != uid)
2604 fatal("setuid failed");
2605 if (!nodetach)
2606 log_to_fd = -1;
2607 charshunt(ifd, ofd, record_file);
2608 exit(0);
2609 }
2610 charshunt_pid = cpid;
2611 (void) close(pty_master);
2612 pty_master = -1;
2613 ttyfd = pty_slave;
2614 record_child(cpid, "pppd (charshunt)", charshunt_done, NULL);
2615 return (1);
2616 }
2617
2618 /*ARGSUSED*/
2619 static void
charshunt_done(arg,status)2620 charshunt_done(arg, status)
2621 void *arg;
2622 int status;
2623 {
2624 charshunt_pid = (pid_t)0;
2625 }
2626
2627 static void
reportme(int signo)2628 reportme(int signo)
2629 {
2630 dbglog("charshunt taking signal %d", signo);
2631 exit(1);
2632 }
2633
2634 /*
2635 * charshunt - the character shunt, which passes characters between
2636 * the pty master side and the serial port (or stdin/stdout).
2637 * This runs as the user (not as root).
2638 * (We assume ofd >= ifd which is true the way this gets called. :-).
2639 */
2640 static void
charshunt(ifd,ofd,record_file)2641 charshunt(ifd, ofd, record_file)
2642 int ifd, ofd;
2643 char *record_file;
2644 {
2645 int n, nfds;
2646 fd_set ready, writey;
2647 u_char *ibufp, *obufp;
2648 int nibuf, nobuf;
2649 int flags;
2650 struct timeval lasttime;
2651 FILE *recordf = NULL;
2652 int ilevel, olevel, max_level;
2653 struct timeval levelt, tout, *top;
2654
2655 /*
2656 * Reset signal handlers.
2657 */
2658 (void) signal(SIGHUP, SIG_IGN); /* Hangup */
2659 (void) signal(SIGINT, reportme); /* Interrupt */
2660 (void) signal(SIGTERM, reportme); /* Terminate */
2661 (void) signal(SIGCHLD, reportme);
2662 (void) signal(SIGUSR1, reportme);
2663 (void) signal(SIGUSR2, reportme);
2664 (void) signal(SIGABRT, reportme);
2665 (void) signal(SIGALRM, reportme);
2666 (void) signal(SIGFPE, reportme);
2667 (void) signal(SIGILL, reportme);
2668 (void) signal(SIGPIPE, reportme);
2669 (void) signal(SIGQUIT, reportme);
2670 #ifndef DEBUG
2671 (void) signal(SIGSEGV, reportme);
2672 #endif
2673 #ifdef SIGBUS
2674 (void) signal(SIGBUS, reportme);
2675 #endif
2676 #ifdef SIGEMT
2677 (void) signal(SIGEMT, reportme);
2678 #endif
2679 #ifdef SIGPOLL
2680 (void) signal(SIGPOLL, reportme);
2681 #endif
2682 #ifdef SIGPROF
2683 (void) signal(SIGPROF, reportme);
2684 #endif
2685 #ifdef SIGSYS
2686 (void) signal(SIGSYS, reportme);
2687 #endif
2688 #ifdef SIGTRAP
2689 (void) signal(SIGTRAP, reportme);
2690 #endif
2691 #ifdef SIGVTALRM
2692 (void) signal(SIGVTALRM, reportme);
2693 #endif
2694 #ifdef SIGXCPU
2695 (void) signal(SIGXCPU, reportme);
2696 #endif
2697 #ifdef SIGXFSZ
2698 (void) signal(SIGXFSZ, reportme);
2699 #endif
2700
2701 /*
2702 * Open the record file if required.
2703 */
2704 if (record_file != NULL) {
2705 recordf = fopen(record_file, "a");
2706 if (recordf == NULL)
2707 error("Couldn't create record file %s: %m", record_file);
2708 }
2709
2710 /* set all the fds to non-blocking mode */
2711 flags = fcntl(pty_master, F_GETFL);
2712 if (flags == -1
2713 || fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1)
2714 warn("couldn't set pty master to nonblock: %m");
2715 flags = fcntl(ifd, F_GETFL);
2716 if (flags == -1
2717 || fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1)
2718 warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty"));
2719 if (ofd != ifd) {
2720 flags = fcntl(ofd, F_GETFL);
2721 if (flags == -1
2722 || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1)
2723 warn("couldn't set stdout to nonblock: %m");
2724 }
2725
2726 nibuf = nobuf = 0;
2727 ibufp = obufp = NULL;
2728
2729 ilevel = olevel = 0;
2730 (void) gettimeofday(&levelt, NULL);
2731 if (max_data_rate) {
2732 max_level = max_data_rate / 10;
2733 if (max_level < MAXLEVELMINSIZE)
2734 max_level = MAXLEVELMINSIZE;
2735 } else
2736 max_level = sizeof(inpacket_buf) + 1;
2737
2738 nfds = (ofd > pty_master? ofd: pty_master) + 1;
2739 if (recordf != NULL) {
2740 (void) gettimeofday(&lasttime, NULL);
2741 (void) putc(RECMARK_TIMESTART, recordf); /* put start marker */
2742 (void) putc(lasttime.tv_sec >> 24, recordf);
2743 (void) putc(lasttime.tv_sec >> 16, recordf);
2744 (void) putc(lasttime.tv_sec >> 8, recordf);
2745 (void) putc(lasttime.tv_sec, recordf);
2746 lasttime.tv_usec = 0;
2747 }
2748
2749 while (nibuf != 0 || nobuf != 0 || ofd >= 0 || pty_master >= 0) {
2750 top = 0;
2751 tout.tv_sec = 0;
2752 tout.tv_usec = 10000;
2753 FD_ZERO(&ready);
2754 FD_ZERO(&writey);
2755 if (nibuf != 0) {
2756 if (ilevel >= max_level)
2757 top = &tout;
2758 else if (pty_master >= 0)
2759 FD_SET(pty_master, &writey);
2760 } else if (ifd >= 0)
2761 FD_SET(ifd, &ready);
2762 if (nobuf != 0) {
2763 if (olevel >= max_level)
2764 top = &tout;
2765 else if (ofd >= 0)
2766 FD_SET(ofd, &writey);
2767 } else {
2768 /* Don't read from pty if it's gone or it has closed. */
2769 if (pty_master >= 0 && ofd >= 0)
2770 FD_SET(pty_master, &ready);
2771 }
2772 if (select(nfds, &ready, &writey, NULL, top) < 0) {
2773 if (errno != EINTR)
2774 fatal("select");
2775 continue;
2776 }
2777 if (max_data_rate) {
2778 double dt;
2779 int nbt;
2780 struct timeval now;
2781
2782 (void) gettimeofday(&now, NULL);
2783 dt = (now.tv_sec - levelt.tv_sec
2784 + (now.tv_usec - levelt.tv_usec) / 1e6);
2785 nbt = (int)(dt * max_data_rate);
2786 ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt;
2787 olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt;
2788 levelt = now;
2789 } else
2790 ilevel = olevel = 0;
2791 if (FD_ISSET(ifd, &ready)) {
2792 ibufp = inpacket_buf;
2793 nibuf = read(ifd, ibufp, sizeof(inpacket_buf));
2794 if (nibuf < 0 && errno == EIO)
2795 nibuf = 0;
2796 if (nibuf < 0 || pty_master == -1) {
2797 if (errno != EINTR && errno != EAGAIN) {
2798 error("Error reading standard input: %m");
2799 break;
2800 }
2801 nibuf = 0;
2802 } else if (nibuf == 0) {
2803 /* end of file from stdin */
2804 (void) close(pty_master);
2805 pty_master = -1;
2806 (void) close(ifd);
2807 ifd = -1;
2808 if (recordf)
2809 if (!record_write(recordf, RECMARK_ENDRECV, NULL, 0,
2810 &lasttime))
2811 recordf = NULL;
2812 } else {
2813 FD_SET(pty_master, &writey);
2814 if (recordf)
2815 if (!record_write(recordf, RECMARK_STARTRECV, ibufp, nibuf,
2816 &lasttime))
2817 recordf = NULL;
2818 }
2819 }
2820 if (ofd >= 0 && pty_master >= 0 && FD_ISSET(pty_master, &ready)) {
2821 obufp = outpacket_buf;
2822 nobuf = read(pty_master, obufp, sizeof(outpacket_buf));
2823 if (nobuf < 0 && errno == EIO)
2824 nobuf = 0;
2825 if (nobuf < 0 || ofd == -1) {
2826 if (!(errno == EINTR || errno == EAGAIN)) {
2827 error("Error reading pseudo-tty master: %m");
2828 break;
2829 }
2830 nobuf = 0;
2831 } else if (nobuf == 0) {
2832 /* end of file from the pty - slave side has closed */
2833 nibuf = 0;
2834 (void) close(ofd);
2835 ofd = -1;
2836 if (recordf)
2837 if (!record_write(recordf, RECMARK_ENDSEND, NULL, 0,
2838 &lasttime))
2839 recordf = NULL;
2840 } else {
2841 FD_SET(ofd, &writey);
2842 if (recordf)
2843 if (!record_write(recordf, RECMARK_STARTSEND, obufp, nobuf,
2844 &lasttime))
2845 recordf = NULL;
2846 }
2847 }
2848 if (ofd == -1)
2849 nobuf = 0;
2850 else if (FD_ISSET(ofd, &writey)) {
2851 n = nobuf;
2852 if (olevel + n > max_level)
2853 n = max_level - olevel;
2854 n = write(ofd, obufp, n);
2855 if (n < 0) {
2856 if (errno == EIO) {
2857 (void) close(ofd);
2858 ofd = -1;
2859 nobuf = 0;
2860 } else if (errno != EAGAIN && errno != EINTR) {
2861 error("Error writing standard output: %m");
2862 break;
2863 }
2864 } else {
2865 obufp += n;
2866 nobuf -= n;
2867 olevel += n;
2868 }
2869 }
2870 if (pty_master == -1)
2871 nibuf = 0;
2872 else if (FD_ISSET(pty_master, &writey)) {
2873 n = nibuf;
2874 if (ilevel + n > max_level)
2875 n = max_level - ilevel;
2876 n = write(pty_master, ibufp, n);
2877 if (n < 0) {
2878 if (errno == EAGAIN || errno == EINTR)
2879 continue;
2880 if (errno != EIO) {
2881 error("Error writing pseudo-tty master: %m");
2882 break;
2883 }
2884 (void) close(pty_master);
2885 pty_master = -1;
2886 nibuf = 0;
2887 } else {
2888 ibufp += n;
2889 nibuf -= n;
2890 ilevel += n;
2891 }
2892 }
2893 }
2894 exit(0);
2895 }
2896
2897 static int
record_write(f,code,buf,nb,tp)2898 record_write(f, code, buf, nb, tp)
2899 FILE *f;
2900 int code;
2901 u_char *buf;
2902 int nb;
2903 struct timeval *tp;
2904 {
2905 struct timeval now;
2906 int diff;
2907
2908 (void) gettimeofday(&now, NULL);
2909 now.tv_usec /= 100000; /* actually 1/10 s, not usec now */
2910 diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec);
2911 if (diff > 0) {
2912 if (diff > 255) {
2913 (void) putc(RECMARK_TIMEDELTA32, f);
2914 (void) putc(diff >> 24, f);
2915 (void) putc(diff >> 16, f);
2916 (void) putc(diff >> 8, f);
2917 (void) putc(diff, f);
2918 } else {
2919 (void) putc(RECMARK_TIMEDELTA8, f);
2920 (void) putc(diff, f);
2921 }
2922 *tp = now;
2923 }
2924 (void) putc(code, f);
2925 if (buf != NULL) {
2926 (void) putc(nb >> 8, f);
2927 (void) putc(nb, f);
2928 (void) fwrite(buf, nb, 1, f);
2929 }
2930 (void) fflush(f);
2931 if (ferror(f)) {
2932 error("Error writing record file: %m");
2933 return (0);
2934 }
2935 return (1);
2936 }
2937