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