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 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 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 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 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 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 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 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 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 * 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 * 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 2620 charshunt_done(arg, status) 2621 void *arg; 2622 int status; 2623 { 2624 charshunt_pid = (pid_t)0; 2625 } 2626 2627 static void 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 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 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