main.c revision 1.56
1/* $OpenBSD: main.c,v 1.56 2023/03/08 04:43:14 guenther Exp $ */ 2 3/* 4 * main.c - Point-to-Point Protocol main module 5 * 6 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name "Carnegie Mellon University" must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. For permission or any legal 23 * details, please contact 24 * Office of Technology Transfer 25 * Carnegie Mellon University 26 * 5000 Forbes Avenue 27 * Pittsburgh, PA 15213-3890 28 * (412) 268-4387, fax: (412) 268-7395 29 * tech-transfer@andrew.cmu.edu 30 * 31 * 4. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by Computing Services 34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 35 * 36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 43 */ 44 45#include <sys/types.h> 46#include <sys/wait.h> 47#include <sys/time.h> 48#include <sys/resource.h> 49#include <sys/stat.h> 50#include <sys/socket.h> 51#include <net/if.h> 52#include <stdio.h> 53#include <ctype.h> 54#include <stdlib.h> 55#include <string.h> 56#include <unistd.h> 57#include <limits.h> 58#include <signal.h> 59#include <errno.h> 60#include <fcntl.h> 61#include <syslog.h> 62#include <netdb.h> 63#include <utmp.h> 64#include <pwd.h> 65 66#include "pppd.h" 67#include "magic.h" 68#include "fsm.h" 69#include "lcp.h" 70#include "ipcp.h" 71#include "upap.h" 72#include "chap.h" 73#include "ccp.h" 74#include "pathnames.h" 75#include "patchlevel.h" 76 77#ifdef CBCP_SUPPORT 78#include "cbcp.h" 79#endif 80 81#if defined(SUNOS4) 82extern char *strerror(); 83#endif 84 85#ifdef AT_CHANGE 86#include "atcp.h" 87#endif 88 89/* interface vars */ 90char ifname[IFNAMSIZ]; /* Interface name */ 91int ifunit; /* Interface unit number */ 92 93char hostname[HOST_NAME_MAX+1]; /* Our hostname */ 94static char default_devnam[PATH_MAX]; /* name of default device */ 95static pid_t pid; /* Our pid */ 96static uid_t uid; /* Our real user-id */ 97static int conn_running; /* we have a [dis]connector running */ 98static int crashed = 0; 99 100int ttyfd = -1; /* Serial port file descriptor */ 101mode_t tty_mode = -1; /* Original access permissions to tty */ 102int baud_rate; /* Actual bits/second for serial device */ 103int hungup; /* terminal has been hung up */ 104int privileged; /* we're running as real uid root */ 105int need_holdoff; /* need holdoff period before restarting */ 106int detached; /* have detached from terminal */ 107 108int phase; /* where the link is at */ 109int kill_link; 110int open_ccp_flag; 111 112char **script_env; /* Env. variable values for scripts */ 113int s_env_nalloc; /* # words avail at script_env */ 114 115u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ 116u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ 117 118static int n_children; /* # child processes still running */ 119 120static int locked; /* lock() has succeeded */ 121 122char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; 123 124/* Prototypes for procedures local to this file. */ 125 126static void cleanup(void); 127static void close_tty(void); 128static void get_input(void); 129static void calltimeout(void); 130static struct timeval *timeleft(struct timeval *); 131static void kill_my_pg(int); 132static void hup(int); 133static void term(int); 134static void chld(int); 135static void toggle_debug(int); 136static void open_ccp(int); 137static void bad_signal(int); 138static void holdoff_end(void *); 139static int device_script(char *, int, int); 140static void reap_kids(void); 141static void pr_log(void *, char *, ...); 142 143extern char *ttyname(int); 144extern char *getlogin(void); 145int main(int, char *[]); 146 147#ifdef ultrix 148#undef O_NONBLOCK 149#define O_NONBLOCK O_NDELAY 150#endif 151 152#ifdef ULTRIX 153#define setlogmask(x) 154#endif 155 156/* 157 * PPP Data Link Layer "protocol" table. 158 * One entry per supported protocol. 159 * The last entry must be NULL. 160 */ 161struct protent *protocols[] = { 162 &lcp_protent, 163 &pap_protent, 164 &chap_protent, 165#ifdef CBCP_SUPPORT 166 &cbcp_protent, 167#endif 168 &ipcp_protent, 169 &ccp_protent, 170#ifdef AT_CHANGE 171 &atcp_protent, 172#endif 173 NULL 174}; 175 176int 177main(argc, argv) 178 int argc; 179 char *argv[]; 180{ 181 int i, fdflags; 182 struct sigaction sa; 183 char *p; 184 struct passwd *pw; 185 struct timeval timo; 186 sigset_t mask; 187 struct protent *protp; 188 struct stat statbuf; 189 char numbuf[16]; 190 191 phase = PHASE_INITIALIZE; 192 p = ttyname(0); 193 if (p) 194 strlcpy(devnam, p, PATH_MAX); 195 strlcpy(default_devnam, devnam, sizeof default_devnam); 196 197 script_env = NULL; 198 199 /* Initialize syslog facilities */ 200#ifdef ULTRIX 201 openlog("pppd", LOG_PID); 202#else 203 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); 204 setlogmask(LOG_UPTO(LOG_INFO)); 205#endif 206 207 if (gethostname(hostname, sizeof hostname) < 0 ) { 208 option_error("Couldn't get hostname: %m"); 209 die(1); 210 } 211 212 uid = getuid(); 213 privileged = uid == 0; 214 snprintf(numbuf, sizeof numbuf, "%u", uid); 215 script_setenv("UID", numbuf); 216 217 /* 218 * Initialize to the standard option set, then parse, in order, 219 * the system options file, the user's options file, 220 * the tty's options file, and the command line arguments. 221 */ 222 for (i = 0; (protp = protocols[i]) != NULL; ++i) 223 (*protp->init)(0); 224 225 if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) 226 || !options_from_user()) 227 exit(1); 228 scan_args(argc-1, argv+1); /* look for tty name on command line */ 229 if (!options_for_tty() 230 || !parse_args(argc-1, argv+1)) 231 exit(1); 232 233 /* 234 * Check that we are running as root. 235 */ 236 if (geteuid() != 0) { 237 option_error("must be root to run %s, since it is not setuid-root", 238 argv[0]); 239 die(1); 240 } 241 242 if (!ppp_available()) { 243 option_error(no_ppp_msg); 244 exit(1); 245 } 246 247 /* 248 * Check that the options given are valid and consistent. 249 */ 250 sys_check_options(); 251 auth_check_options(); 252 for (i = 0; (protp = protocols[i]) != NULL; ++i) 253 if (protp->check_options != NULL) 254 (*protp->check_options)(); 255 if (demand && connector == 0) { 256 option_error("connect script required for demand-dialling\n"); 257 exit(1); 258 } 259 260 script_setenv("DEVICE", devnam); 261 snprintf(numbuf, sizeof numbuf, "%d", baud_rate); 262 script_setenv("SPEED", numbuf); 263 264 /* 265 * If the user has specified the default device name explicitly, 266 * pretend they hadn't. 267 */ 268 if (!default_device && strcmp(devnam, default_devnam) == 0) 269 default_device = 1; 270 if (default_device) 271 nodetach = 1; 272 273 /* 274 * Initialize system-dependent stuff and magic number package. 275 */ 276 sys_init(); 277 magic_init(); 278 if (debug) 279 setlogmask(LOG_UPTO(LOG_DEBUG)); 280 281 /* 282 * Detach ourselves from the terminal, if required, 283 * and identify who is running us. 284 */ 285 if (nodetach == 0) 286 detach(); 287 pid = getpid(); 288 p = getlogin(); 289 if (p == NULL) { 290 pw = getpwuid(uid); 291 if (pw != NULL && pw->pw_name != NULL) 292 p = pw->pw_name; 293 else 294 p = "(unknown)"; 295 } 296 syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %u", 297 VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid); 298 299 /* 300 * Compute mask of all interesting signals and install signal handlers 301 * for each. Only one signal handler may be active at a time. Therefore, 302 * all other signals should be masked when any handler is executing. 303 */ 304 sigemptyset(&mask); 305 sigaddset(&mask, SIGHUP); 306 sigaddset(&mask, SIGINT); 307 sigaddset(&mask, SIGTERM); 308 sigaddset(&mask, SIGCHLD); 309 310#define SIGNAL(s, handler) { \ 311 sa.sa_handler = handler; \ 312 if (sigaction(s, &sa, NULL) < 0) { \ 313 syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ 314 die(1); \ 315 } \ 316 } 317 318 sa.sa_mask = mask; 319 sa.sa_flags = 0; 320 SIGNAL(SIGHUP, hup); /* Hangup */ 321 SIGNAL(SIGINT, term); /* Interrupt */ 322 SIGNAL(SIGTERM, term); /* Terminate */ 323 SIGNAL(SIGCHLD, chld); 324 325 SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ 326 SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ 327 328 /* 329 * Install a handler for other signals which would otherwise 330 * cause pppd to exit without cleaning up. 331 */ 332 SIGNAL(SIGABRT, bad_signal); 333 SIGNAL(SIGALRM, bad_signal); 334 SIGNAL(SIGFPE, bad_signal); 335 SIGNAL(SIGILL, bad_signal); 336 SIGNAL(SIGPIPE, bad_signal); 337 SIGNAL(SIGQUIT, bad_signal); 338#if SIGSEGV_CHECK 339 SIGNAL(SIGSEGV, bad_signal); 340#endif 341#ifdef SIGBUS 342 SIGNAL(SIGBUS, bad_signal); 343#endif 344#ifdef SIGEMT 345 SIGNAL(SIGEMT, bad_signal); 346#endif 347#ifdef SIGPOLL 348 SIGNAL(SIGPOLL, bad_signal); 349#endif 350#ifdef SIGPROF 351 SIGNAL(SIGPROF, bad_signal); 352#endif 353#ifdef SIGSYS 354 SIGNAL(SIGSYS, bad_signal); 355#endif 356#ifdef SIGTRAP 357 SIGNAL(SIGTRAP, bad_signal); 358#endif 359#ifdef SIGVTALRM 360 SIGNAL(SIGVTALRM, bad_signal); 361#endif 362#ifdef SIGXCPU 363 SIGNAL(SIGXCPU, bad_signal); 364#endif 365#ifdef SIGXFSZ 366 SIGNAL(SIGXFSZ, bad_signal); 367#endif 368 369 /* 370 * Apparently we can get a SIGPIPE when we call syslog, if 371 * syslogd has died and been restarted. Ignoring it seems 372 * be sufficient. 373 */ 374 signal(SIGPIPE, SIG_IGN); 375 376 /* 377 * If we're doing dial-on-demand, set up the interface now. 378 */ 379 if (demand) { 380 /* 381 * Open the loopback channel and set it up to be the ppp interface. 382 */ 383 open_ppp_loopback(); 384 385 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 386 (void) snprintf(ifname, sizeof ifname, "ppp%d", ifunit); 387 script_setenv("IFNAME", ifname); 388 389 /* 390 * Configure the interface and mark it up, etc. 391 */ 392 demand_conf(); 393 } 394 395 for (;;) { 396 397 need_holdoff = 1; 398 399 if (demand) { 400 /* 401 * Don't do anything until we see some activity. 402 */ 403 phase = PHASE_DORMANT; 404 kill_link = 0; 405 demand_unblock(); 406 for (;;) { 407 wait_loop_output(timeleft(&timo)); 408 calltimeout(); 409 if (kill_link) { 410 if (!persist) 411 die(0); 412 kill_link = 0; 413 } 414 if (get_loop_output()) 415 break; 416 reap_kids(); 417 } 418 419 /* 420 * Now we want to bring up the link. 421 */ 422 demand_drop(); 423 syslog(LOG_INFO, "Starting link"); 424 } 425 426 /* 427 * Lock the device if we've been asked to. 428 */ 429 if (lockflag && !default_device) { 430 if (lock(devnam) < 0) 431 goto fail; 432 locked = 1; 433 } 434 435 /* 436 * Open the serial device and set it up to be the ppp interface. 437 * First we open it in non-blocking mode so we can set the 438 * various termios flags appropriately. If we aren't dialling 439 * out and we want to use the modem lines, we reopen it later 440 * in order to wait for the carrier detect signal from the modem. 441 */ 442 while ((ttyfd = open(devnam, O_NONBLOCK | O_RDWR)) < 0) { 443 if (errno != EINTR) 444 syslog(LOG_ERR, "Failed to open %s: %m", devnam); 445 if (!persist || errno != EINTR) 446 goto fail; 447 } 448 if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 449 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) 450 syslog(LOG_WARNING, 451 "Couldn't reset non-blocking mode on device: %m"); 452 453 hungup = 0; 454 kill_link = 0; 455 456 /* 457 * Do the equivalent of `mesg n' to stop broadcast messages. 458 */ 459 if (fstat(ttyfd, &statbuf) < 0 460 || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { 461 syslog(LOG_WARNING, 462 "Couldn't restrict write permissions to %s: %m", devnam); 463 } else 464 tty_mode = statbuf.st_mode; 465 466 /* run connection script */ 467 if (connector && connector[0]) { 468 MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); 469 470 /* 471 * Set line speed, flow control, etc. 472 * On most systems we set CLOCAL for now so that we can talk 473 * to the modem before carrier comes up. But this has the 474 * side effect that we might miss it if CD drops before we 475 * get to clear CLOCAL below. On systems where we can talk 476 * successfully to the modem with CLOCAL clear and CD down, 477 * we can clear CLOCAL at this point. 478 */ 479 set_up_tty(ttyfd, (modem_chat == 0)); 480 481 /* drop dtr to hang up in case modem is off hook */ 482 if (!default_device && modem) { 483 setdtr(ttyfd, FALSE); 484 sleep(1); 485 setdtr(ttyfd, TRUE); 486 } 487 488 if (device_script(connector, ttyfd, ttyfd) < 0) { 489 syslog(LOG_ERR, "Connect script failed"); 490 setdtr(ttyfd, FALSE); 491 goto fail; 492 } 493 494 syslog(LOG_INFO, "Serial connection established."); 495 sleep(1); /* give it time to set up its terminal */ 496 } 497 498 set_up_tty(ttyfd, 0); 499 500 /* reopen tty if necessary to wait for carrier */ 501 if (connector == NULL && modem) { 502 while ((i = open(devnam, O_RDWR)) < 0) { 503 if (errno != EINTR) 504 syslog(LOG_ERR, "Failed to reopen %s: %m", devnam); 505 if (!persist || errno != EINTR || hungup || kill_link) 506 goto fail; 507 } 508 close(i); 509 } 510 511 /* run welcome script, if any */ 512 if (welcomer && welcomer[0]) { 513 if (device_script(welcomer, ttyfd, ttyfd) < 0) 514 syslog(LOG_WARNING, "Welcome script failed"); 515 } 516 517 /* set up the serial device as a ppp interface */ 518 establish_ppp(ttyfd); 519 520 if (!demand) { 521 522 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 523 (void) snprintf(ifname, sizeof ifname, "ppp%d", ifunit); 524 script_setenv("IFNAME", ifname); 525 } 526 527 /* 528 * Start opening the connection and wait for 529 * incoming events (reply, timeout, etc.). 530 */ 531 syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); 532 lcp_lowerup(0); 533 lcp_open(0); /* Start protocol */ 534 for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { 535 wait_input(timeleft(&timo)); 536 calltimeout(); 537 get_input(); 538 if (kill_link) { 539 lcp_close(0, "User request"); 540 kill_link = 0; 541 } 542 if (open_ccp_flag) { 543 if (phase == PHASE_NETWORK) { 544 ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ 545 (*ccp_protent.open)(0); 546 } 547 open_ccp_flag = 0; 548 } 549 reap_kids(); /* Don't leave dead kids lying around */ 550 } 551 552 /* 553 * If we may want to bring the link up again, transfer 554 * the ppp unit back to the loopback. Set the 555 * real serial device back to its normal mode of operation. 556 */ 557 clean_check(); 558 if (demand) 559 restore_loop(); 560 disestablish_ppp(ttyfd); 561 562 /* 563 * Run disconnector script, if requested. 564 * XXX we may not be able to do this if the line has hung up! 565 */ 566 if (disconnector && !hungup) { 567 set_up_tty(ttyfd, 1); 568 if (device_script(disconnector, ttyfd, ttyfd) < 0) { 569 syslog(LOG_WARNING, "disconnect script failed"); 570 } else { 571 syslog(LOG_INFO, "Serial link disconnected."); 572 } 573 } 574 575 fail: 576 if (ttyfd >= 0) 577 close_tty(); 578 if (locked) { 579 unlock(); 580 locked = 0; 581 } 582 583 if (!persist) 584 die(1); 585 586 if (holdoff > 0 && need_holdoff) { 587 phase = PHASE_HOLDOFF; 588 TIMEOUT(holdoff_end, NULL, holdoff); 589 do { 590 wait_time(timeleft(&timo)); 591 calltimeout(); 592 if (kill_link) { 593 if (!persist) 594 die(0); 595 kill_link = 0; 596 phase = PHASE_DORMANT; /* allow signal to end holdoff */ 597 } 598 reap_kids(); 599 } while (phase == PHASE_HOLDOFF); 600 } 601 } 602 603 die(0); 604 return 0; 605} 606 607/* 608 * detach - detach us from the controlling terminal. 609 */ 610void 611detach() 612{ 613 if (detached) 614 return; 615 if (daemon(0, 0) < 0) { 616 perror("Couldn't detach from controlling terminal"); 617 die(1); 618 } 619 detached = 1; 620 pid = getpid(); 621} 622 623/* 624 * holdoff_end - called via a timeout when the holdoff period ends. 625 */ 626static void 627holdoff_end(arg) 628 void *arg; 629{ 630 phase = PHASE_DORMANT; 631} 632 633/* 634 * get_input - called when incoming data is available. 635 */ 636static void 637get_input() 638{ 639 int len, i; 640 u_char *p; 641 u_short protocol; 642 struct protent *protp; 643 644 p = inpacket_buf; /* point to beginning of packet buffer */ 645 646 len = read_packet(inpacket_buf); 647 if (len < 0) 648 return; 649 650 if (len == 0) { 651 syslog(LOG_NOTICE, "Modem hangup"); 652 hungup = 1; 653 lcp_lowerdown(0); /* serial link is no longer available */ 654 link_terminated(0); 655 return; 656 } 657 658 if (debug /*&& (debugflags & DBG_INPACKET)*/) 659 log_packet(p, len, "rcvd ", LOG_DEBUG); 660 661 if (len < PPP_HDRLEN) { 662 MAINDEBUG((LOG_INFO, "io(): Received short packet.")); 663 return; 664 } 665 666 p += 2; /* Skip address and control */ 667 GETSHORT(protocol, p); 668 len -= PPP_HDRLEN; 669 670 /* 671 * Toss all non-LCP packets unless LCP is OPEN. 672 */ 673 if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { 674 MAINDEBUG((LOG_INFO, 675 "get_input: Received non-LCP packet when LCP not open.")); 676 return; 677 } 678 679 /* 680 * Until we get past the authentication phase, toss all packets 681 * except LCP, LQR and authentication packets. 682 */ 683 if (phase <= PHASE_AUTHENTICATE 684 && !(protocol == PPP_LCP || protocol == PPP_LQR 685 || protocol == PPP_PAP || protocol == PPP_CHAP)) { 686 MAINDEBUG((LOG_INFO, "get_input: discarding proto 0x%x in phase %d", 687 protocol, phase)); 688 return; 689 } 690 691 /* 692 * Upcall the proper protocol input routine. 693 */ 694 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 695 if (protp->protocol == protocol && protp->enabled_flag) { 696 (*protp->input)(0, p, len); 697 return; 698 } 699 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag 700 && protp->datainput != NULL) { 701 (*protp->datainput)(0, p, len); 702 return; 703 } 704 } 705 706 if (debug) 707 syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); 708 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); 709} 710 711 712/* 713 * quit - Clean up state and exit (with an error indication). 714 */ 715void 716quit() 717{ 718 die(1); 719} 720 721/* 722 * die - like quit, except we can specify an exit status. 723 */ 724void 725die(status) 726 int status; 727{ 728 struct syslog_data sdata = SYSLOG_DATA_INIT; 729 730 cleanup(); 731 syslog_r(LOG_INFO, &sdata, "Exit."); 732 _exit(status); 733} 734 735/* 736 * cleanup - restore anything which needs to be restored before we exit 737 */ 738static void 739cleanup() 740{ 741 sys_cleanup(); 742 743 if (ttyfd >= 0) 744 close_tty(); 745 746 if (locked) 747 unlock(); 748} 749 750/* 751 * close_tty - restore the terminal device and close it. 752 */ 753static void 754close_tty() 755{ 756 disestablish_ppp(ttyfd); 757 758 /* drop dtr to hang up */ 759 if (modem) { 760 setdtr(ttyfd, FALSE); 761 /* 762 * This sleep is in case the serial port has CLOCAL set by default, 763 * and consequently will reassert DTR when we close the device. 764 */ 765 sleep(1); 766 } 767 768 restore_tty(ttyfd); 769 770 if (tty_mode != (mode_t) -1) 771 fchmod(ttyfd, tty_mode); 772 773 close(ttyfd); 774 ttyfd = -1; 775} 776 777 778struct callout { 779 struct timeval c_time; /* time at which to call routine */ 780 void *c_arg; /* argument to routine */ 781 void (*c_func)(void *); /* routine */ 782 struct callout *c_next; 783}; 784 785static struct callout *callout = NULL; /* Callout list */ 786static struct timeval timenow; /* Current time */ 787 788/* 789 * timeout - Schedule a timeout. 790 * 791 * Note that this timeout takes the number of seconds, NOT hz (as in 792 * the kernel). 793 */ 794void 795timeout(func, arg, time) 796 void (*func)(void *); 797 void *arg; 798 int time; 799{ 800 struct callout *newp, *p, **pp; 801 802 MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", 803 (long) func, (long) arg, time)); 804 805 /* 806 * Allocate timeout. 807 */ 808 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { 809 syslog(LOG_ERR, "Out of memory in timeout()!"); 810 die(1); 811 } 812 newp->c_arg = arg; 813 newp->c_func = func; 814 gettimeofday(&timenow, NULL); 815 newp->c_time.tv_sec = timenow.tv_sec + time; 816 newp->c_time.tv_usec = timenow.tv_usec; 817 818 /* 819 * Find correct place and link it in. 820 */ 821 for (pp = &callout; (p = *pp); pp = &p->c_next) 822 if (newp->c_time.tv_sec < p->c_time.tv_sec 823 || (newp->c_time.tv_sec == p->c_time.tv_sec 824 && newp->c_time.tv_usec < p->c_time.tv_sec)) 825 break; 826 newp->c_next = p; 827 *pp = newp; 828} 829 830 831/* 832 * untimeout - Unschedule a timeout. 833 */ 834void 835untimeout(func, arg) 836 void (*func)(void *); 837 void *arg; 838{ 839 struct callout **copp, *freep; 840 841 MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); 842 843 /* 844 * Find first matching timeout and remove it from the list. 845 */ 846 for (copp = &callout; (freep = *copp); copp = &freep->c_next) 847 if (freep->c_func == func && freep->c_arg == arg) { 848 *copp = freep->c_next; 849 (void) free((char *) freep); 850 break; 851 } 852} 853 854 855/* 856 * calltimeout - Call any timeout routines which are now due. 857 */ 858static void 859calltimeout() 860{ 861 struct callout *p; 862 863 while (callout != NULL) { 864 p = callout; 865 866 if (gettimeofday(&timenow, NULL) < 0) { 867 syslog(LOG_ERR, "Failed to get time of day: %m"); 868 die(1); 869 } 870 if (!(p->c_time.tv_sec < timenow.tv_sec 871 || (p->c_time.tv_sec == timenow.tv_sec 872 && p->c_time.tv_usec <= timenow.tv_usec))) 873 break; /* no, it's not time yet */ 874 875 callout = p->c_next; 876 (*p->c_func)(p->c_arg); 877 878 free((char *) p); 879 } 880} 881 882 883/* 884 * timeleft - return the length of time until the next timeout is due. 885 */ 886static struct timeval * 887timeleft(tvp) 888 struct timeval *tvp; 889{ 890 if (callout == NULL) 891 return NULL; 892 893 gettimeofday(&timenow, NULL); 894 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; 895 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; 896 if (tvp->tv_usec < 0) { 897 tvp->tv_usec += 1000000; 898 tvp->tv_sec -= 1; 899 } 900 if (tvp->tv_sec < 0) 901 tvp->tv_sec = tvp->tv_usec = 0; 902 903 return tvp; 904} 905 906 907/* 908 * kill_my_pg - send a signal to our process group, and ignore it ourselves. 909 */ 910static void 911kill_my_pg(sig) 912 int sig; 913{ 914 struct sigaction act, oldact; 915 916 act.sa_handler = SIG_IGN; 917 act.sa_flags = 0; 918 kill(0, sig); 919 sigaction(sig, &act, &oldact); 920 sigaction(sig, &oldact, NULL); 921} 922 923 924/* 925 * hup - Catch SIGHUP signal. 926 * 927 * Indicates that the physical layer has been disconnected. 928 * We don't rely on this indication; if the user has sent this 929 * signal, we just take the link down. 930 */ 931static void 932hup(sig) 933 int sig; 934{ 935 int save_errno = errno; 936 struct syslog_data sdata = SYSLOG_DATA_INIT; 937 938 if (crashed) 939 _exit(127); 940 syslog_r(LOG_INFO, &sdata, "Hangup (SIGHUP)"); 941 kill_link = 1; 942 if (conn_running) 943 /* Send the signal to the [dis]connector process(es) also */ 944 kill_my_pg(sig); 945 errno = save_errno; 946} 947 948 949/* 950 * term - Catch SIGTERM signal and SIGINT signal (^C/del). 951 * 952 * Indicates that we should initiate a graceful disconnect and exit. 953 */ 954static void 955term(sig) 956 int sig; 957{ 958 int save_errno = errno; 959 struct syslog_data sdata = SYSLOG_DATA_INIT; 960 961 if (crashed) 962 _exit(127); 963 syslog_r(LOG_INFO, &sdata, "Terminating on signal %d.", sig); 964 persist = 0; /* don't try to restart */ 965 kill_link = 1; 966 if (conn_running) 967 /* Send the signal to the [dis]connector process(es) also */ 968 kill_my_pg(sig); 969 errno = save_errno; 970} 971 972 973/* 974 * chld - Catch SIGCHLD signal. 975 * Calls reap_kids to get status for any dead kids. 976 */ 977static void 978chld(sig) 979 int sig; 980{ 981 int save_errno = errno; 982 983 reap_kids(); /* XXX somewhat unsafe */ 984 errno = save_errno; 985} 986 987 988/* 989 * toggle_debug - Catch SIGUSR1 signal. 990 * 991 * Toggle debug flag. 992 */ 993static void 994toggle_debug(sig) 995 int sig; 996{ 997 debug = !debug; 998 if (debug) { 999 setlogmask(LOG_UPTO(LOG_DEBUG)); /* XXX safe, but wrong */ 1000 } else { 1001 setlogmask(LOG_UPTO(LOG_WARNING)); /* XXX safe, but wrong */ 1002 } 1003} 1004 1005 1006/* 1007 * open_ccp - Catch SIGUSR2 signal. 1008 * 1009 * Try to (re)negotiate compression. 1010 */ 1011static void 1012open_ccp(sig) 1013 int sig; 1014{ 1015 open_ccp_flag = 1; 1016} 1017 1018 1019/* 1020 * bad_signal - We've caught a fatal signal. Clean up state and exit. 1021 */ 1022static void 1023bad_signal(sig) 1024 int sig; 1025{ 1026 struct syslog_data sdata = SYSLOG_DATA_INIT; 1027 1028 if (crashed) 1029 _exit(127); 1030 crashed = 1; 1031 syslog_r(LOG_ERR, &sdata, "Fatal signal %d", sig); 1032 if (conn_running) 1033 kill_my_pg(SIGTERM); 1034 die(1); /* XXX unsafe! */ 1035} 1036 1037 1038/* 1039 * device_script - run a program to connect or disconnect the 1040 * serial device. 1041 */ 1042static int 1043device_script(program, in, out) 1044 char *program; 1045 int in, out; 1046{ 1047 pid_t pid; 1048 int status; 1049 int errfd; 1050 gid_t gid; 1051 uid_t uid; 1052 1053 conn_running = 1; 1054 pid = fork(); 1055 1056 if (pid < 0) { 1057 conn_running = 0; 1058 syslog(LOG_ERR, "Failed to create child process: %m"); 1059 die(1); 1060 } 1061 1062 if (pid == 0) { 1063 sys_close(); 1064 closelog(); 1065 if (in == out) { 1066 if (in != 0) { 1067 dup2(in, 0); 1068 close(in); 1069 } 1070 dup2(0, 1); 1071 } else { 1072 if (out == 0) 1073 out = dup(out); 1074 if (in != 0) { 1075 dup2(in, 0); 1076 close(in); 1077 } 1078 if (out != 1) { 1079 dup2(out, 1); 1080 close(out); 1081 } 1082 } 1083 if (nodetach == 0) { 1084 close(2); 1085 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); 1086 if (errfd >= 0 && errfd != 2) { 1087 dup2(errfd, 2); 1088 close(errfd); 1089 } 1090 } 1091 1092 /* revoke privs */ 1093 gid = getgid(); 1094 uid = getuid(); 1095 if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) { 1096 syslog(LOG_ERR, "revoke privileges: %s", strerror(errno)); 1097 _exit(1); 1098 } 1099 1100 execl("/bin/sh", "sh", "-c", program, (char *)NULL); 1101 syslog(LOG_ERR, "could not exec /bin/sh: %m"); 1102 _exit(99); 1103 /* NOTREACHED */ 1104 } 1105 1106 while (waitpid(pid, &status, 0) < 0) { 1107 if (errno == EINTR) 1108 continue; 1109 syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); 1110 die(1); 1111 } 1112 conn_running = 0; 1113 1114 return (status == 0 ? 0 : -1); 1115} 1116 1117 1118/* 1119 * run-program - execute a program with given arguments, 1120 * but don't wait for it. 1121 * If the program can't be executed, logs an error unless 1122 * must_exist is 0 and the program file doesn't exist. 1123 */ 1124int 1125run_program(prog, args, must_exist) 1126 char *prog; 1127 char **args; 1128 int must_exist; 1129{ 1130 pid_t pid; 1131 uid_t uid; 1132 gid_t gid; 1133 1134 pid = fork(); 1135 if (pid == -1) { 1136 syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); 1137 return -1; 1138 } 1139 if (pid == 0) { 1140 int new_fd; 1141 1142 /* Leave the current location */ 1143 (void) setsid(); /* No controlling tty. */ 1144 (void) umask (S_IRWXG|S_IRWXO); 1145 (void) chdir ("/"); /* no current directory. */ 1146 1147 /* revoke privs */ 1148 uid = getuid(); 1149 gid = getgid(); 1150 if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) { 1151 syslog(LOG_ERR, "revoke privileges: %s", strerror(errno)); 1152 _exit(1); 1153 } 1154 1155 /* Ensure that nothing of our device environment is inherited. */ 1156 sys_close(); 1157 closelog(); 1158 close (0); 1159 close (1); 1160 close (2); 1161 close (ttyfd); /* tty interface to the ppp device */ 1162 1163 /* Don't pass handles to the PPP device, even by accident. */ 1164 new_fd = open (_PATH_DEVNULL, O_RDWR); 1165 if (new_fd >= 0) { 1166 if (new_fd != 0) { 1167 dup2 (new_fd, 0); /* stdin <- /dev/null */ 1168 close (new_fd); 1169 } 1170 dup2 (0, 1); /* stdout -> /dev/null */ 1171 dup2 (0, 2); /* stderr -> /dev/null */ 1172 } 1173 1174 /* Force the priority back to zero if pppd is running higher. */ 1175 if (setpriority (PRIO_PROCESS, 0, 0) < 0) 1176 syslog (LOG_WARNING, "can't reset priority to 0: %m"); 1177 1178 /* SysV recommends a second fork at this point. */ 1179 1180 /* run the program; give it a null environment */ 1181 execve(prog, args, script_env); 1182 if (must_exist || errno != ENOENT) 1183 syslog(LOG_WARNING, "Can't execute %s: %m", prog); 1184 _exit(1); 1185 } 1186 MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %ld", prog, (long)pid)); 1187 ++n_children; 1188 return 0; 1189} 1190 1191 1192/* 1193 * reap_kids - get status from any dead child processes, 1194 * and log a message for abnormal terminations. 1195 */ 1196static void 1197reap_kids() 1198{ 1199 int status; 1200 pid_t pid; 1201 1202 if (n_children == 0) 1203 return; 1204 if ((pid = waitpid(-1, &status, WNOHANG)) == -1) { 1205 if (errno != ECHILD) 1206 syslog(LOG_ERR, "Error waiting for child process: %m"); 1207 return; 1208 } 1209 if (pid > 0) { 1210 --n_children; 1211 if (WIFSIGNALED(status)) { 1212 syslog(LOG_WARNING, "Child process %ld terminated with signal %d", 1213 (long)pid, WTERMSIG(status)); 1214 } 1215 } 1216} 1217 1218 1219/* 1220 * log_packet - format a packet and log it. 1221 */ 1222 1223char line[256]; /* line to be logged accumulated here */ 1224char *linep; 1225 1226void 1227log_packet(p, len, prefix, level) 1228 u_char *p; 1229 int len; 1230 char *prefix; 1231 int level; 1232{ 1233 strlcpy(line, prefix, sizeof line); 1234 linep = line + strlen(line); 1235 format_packet(p, len, pr_log, NULL); 1236 if (linep != line) 1237 syslog(level, "%s", line); 1238} 1239 1240/* 1241 * format_packet - make a readable representation of a packet, 1242 * calling `printer(arg, format, ...)' to output it. 1243 */ 1244void 1245format_packet(p, len, printer, arg) 1246 u_char *p; 1247 int len; 1248 void (*printer)(void *, char *, ...); 1249 void *arg; 1250{ 1251 int i, n; 1252 u_short proto; 1253 u_char x; 1254 struct protent *protp; 1255 1256 if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { 1257 p += 2; 1258 GETSHORT(proto, p); 1259 len -= PPP_HDRLEN; 1260 for (i = 0; (protp = protocols[i]) != NULL; ++i) 1261 if (proto == protp->protocol) 1262 break; 1263 if (protp != NULL) { 1264 printer(arg, "[%s", protp->name); 1265 n = (*protp->printpkt)(p, len, printer, arg); 1266 printer(arg, "]"); 1267 p += n; 1268 len -= n; 1269 } else { 1270 printer(arg, "[proto=0x%x]", proto); 1271 } 1272 } 1273 1274 for (; len > 0; --len) { 1275 GETCHAR(x, p); 1276 printer(arg, " %.2x", x); 1277 } 1278} 1279 1280static void 1281pr_log(void *arg, char *fmt, ...) 1282{ 1283 int n; 1284 va_list pvar; 1285 char buf[256]; 1286 1287 va_start(pvar, fmt); 1288 1289 n = vfmtmsg(buf, sizeof(buf), fmt, pvar); 1290 va_end(pvar); 1291 1292 if (linep + n + 1 > line + sizeof(line)) { 1293 syslog(LOG_DEBUG, "%s", line); 1294 linep = line; 1295 } 1296 strlcpy(linep, buf, line + sizeof line - linep); 1297 linep += n; 1298} 1299 1300/* 1301 * print_string - print a readable representation of a string using 1302 * printer. 1303 */ 1304void 1305print_string(p, len, printer, arg) 1306 char *p; 1307 int len; 1308 void (*printer)(void *, char *, ...); 1309 void *arg; 1310{ 1311 int c; 1312 1313 printer(arg, "\""); 1314 for (; len > 0; --len) { 1315 c = *p++; 1316 if (' ' <= c && c <= '~') { 1317 if (c == '\\' || c == '"') 1318 printer(arg, "\\"); 1319 printer(arg, "%c", c); 1320 } else { 1321 switch (c) { 1322 case '\n': 1323 printer(arg, "\\n"); 1324 break; 1325 case '\r': 1326 printer(arg, "\\r"); 1327 break; 1328 case '\t': 1329 printer(arg, "\\t"); 1330 break; 1331 default: 1332 printer(arg, "\\%.3o", c); 1333 } 1334 } 1335 } 1336 printer(arg, "\""); 1337} 1338 1339/* 1340 * novm - log an error message saying we ran out of memory, and die. 1341 */ 1342void 1343novm(msg) 1344 char *msg; 1345{ 1346 syslog(LOG_ERR, "Virtual memory exhausted allocating %s", msg); 1347 die(1); 1348} 1349 1350/* 1351 * fmtmsg - format a message into a buffer. Like snprintf except we 1352 * also specify the length of the output buffer, and we handle 1353 * %m (error message) and %I (IP address) formats. 1354 * Doesn't do floating-point formats. 1355 * Returns the number of chars put into buf. 1356 */ 1357int 1358fmtmsg(char *buf, int buflen, char *fmt, ...) 1359{ 1360 va_list args; 1361 int n; 1362 1363 va_start(args, fmt); 1364 n = vfmtmsg(buf, buflen, fmt, args); 1365 va_end(args); 1366 return n; 1367} 1368 1369/* 1370 * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args. 1371 */ 1372#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) 1373 1374int 1375vfmtmsg(buf, buflen, fmt, args) 1376 char *buf; 1377 int buflen; 1378 char *fmt; 1379 va_list args; 1380{ 1381 int c, i, n; 1382 int width, prec, fillch; 1383 int base, len, neg, quoted; 1384 unsigned long val = 0; 1385 char *str, *f, *buf0; 1386 unsigned char *p; 1387 char num[32]; 1388 time_t t; 1389 static char hexchars[] = "0123456789abcdef"; 1390 1391 buf0 = buf; 1392 --buflen; 1393 while (buflen > 0) { 1394 for (f = fmt; *f != '%' && *f != 0; ++f) 1395 ; 1396 if (f > fmt) { 1397 len = f - fmt; 1398 if (len > buflen) 1399 len = buflen; 1400 memcpy(buf, fmt, len); 1401 buf += len; 1402 buflen -= len; 1403 fmt = f; 1404 } 1405 if (*fmt == 0) 1406 break; 1407 c = *++fmt; 1408 width = prec = 0; 1409 fillch = ' '; 1410 if (c == '0') { 1411 fillch = '0'; 1412 c = *++fmt; 1413 } 1414 if (c == '*') { 1415 width = va_arg(args, int); 1416 c = *++fmt; 1417 } else { 1418 while (isdigit(c)) { 1419 width = width * 10 + c - '0'; 1420 c = *++fmt; 1421 } 1422 } 1423 if (c == '.') { 1424 c = *++fmt; 1425 if (c == '*') { 1426 prec = va_arg(args, int); 1427 c = *++fmt; 1428 } else { 1429 while (isdigit(c)) { 1430 prec = prec * 10 + c - '0'; 1431 c = *++fmt; 1432 } 1433 } 1434 } 1435 str = 0; 1436 base = 0; 1437 neg = 0; 1438 ++fmt; 1439 switch (c) { 1440 case 'd': 1441 i = va_arg(args, int); 1442 if (i < 0) { 1443 neg = 1; 1444 val = -i; 1445 } else 1446 val = i; 1447 base = 10; 1448 break; 1449 case 'o': 1450 val = va_arg(args, unsigned int); 1451 base = 8; 1452 break; 1453 case 'x': 1454 val = va_arg(args, unsigned int); 1455 base = 16; 1456 break; 1457 case 'p': 1458 val = (unsigned long) va_arg(args, void *); 1459 base = 16; 1460 neg = 2; 1461 break; 1462 case 's': 1463 str = va_arg(args, char *); 1464 break; 1465 case 'c': 1466 num[0] = va_arg(args, int); 1467 num[1] = 0; 1468 str = num; 1469 break; 1470 case 'm': 1471 str = strerror(errno); 1472 break; 1473 case 'I': 1474 str = ip_ntoa(va_arg(args, u_int32_t)); 1475 break; 1476 case 't': 1477 time(&t); 1478 str = ctime(&t); 1479 str += 4; /* chop off the day name */ 1480 str[15] = 0; /* chop off year and newline */ 1481 break; 1482 case 'v': /* "visible" string */ 1483 case 'q': /* quoted string */ 1484 quoted = c == 'q'; 1485 p = va_arg(args, unsigned char *); 1486 if (fillch == '0' && prec > 0) { 1487 n = prec; 1488 } else { 1489 n = strlen((char *)p); 1490 if (prec > 0 && prec < n) 1491 n = prec; 1492 } 1493 while (n > 0 && buflen > 0) { 1494 c = *p++; 1495 --n; 1496 if (!quoted && c >= 0x80) { 1497 OUTCHAR('M'); 1498 OUTCHAR('-'); 1499 c -= 0x80; 1500 } 1501 if (quoted && (c == '"' || c == '\\')) 1502 OUTCHAR('\\'); 1503 if (c < 0x20 || (0x7f <= c && c < 0xa0)) { 1504 if (quoted) { 1505 OUTCHAR('\\'); 1506 switch (c) { 1507 case '\t': OUTCHAR('t'); break; 1508 case '\n': OUTCHAR('n'); break; 1509 case '\b': OUTCHAR('b'); break; 1510 case '\f': OUTCHAR('f'); break; 1511 default: 1512 OUTCHAR('x'); 1513 OUTCHAR(hexchars[c >> 4]); 1514 OUTCHAR(hexchars[c & 0xf]); 1515 } 1516 } else { 1517 if (c == '\t') 1518 OUTCHAR(c); 1519 else { 1520 OUTCHAR('^'); 1521 OUTCHAR(c ^ 0x40); 1522 } 1523 } 1524 } else 1525 OUTCHAR(c); 1526 } 1527 continue; 1528 default: 1529 *buf++ = '%'; 1530 if (c != '%') 1531 --fmt; /* so %z outputs %z etc. */ 1532 --buflen; 1533 continue; 1534 } 1535 if (base != 0) { 1536 str = num + sizeof(num); 1537 *--str = 0; 1538 while (str > num + neg) { 1539 *--str = hexchars[val % base]; 1540 val = val / base; 1541 if (--prec <= 0 && val == 0) 1542 break; 1543 } 1544 switch (neg) { 1545 case 1: 1546 *--str = '-'; 1547 break; 1548 case 2: 1549 *--str = 'x'; 1550 *--str = '0'; 1551 break; 1552 } 1553 len = num + sizeof(num) - 1 - str; 1554 } else { 1555 len = strlen(str); 1556 if (prec > 0 && len > prec) 1557 len = prec; 1558 } 1559 if (width > 0) { 1560 if (width > buflen) 1561 width = buflen; 1562 if ((n = width - len) > 0) { 1563 buflen -= n; 1564 for (; n > 0; --n) 1565 *buf++ = fillch; 1566 } 1567 } 1568 if (len > buflen) 1569 len = buflen; 1570 memcpy(buf, str, len); 1571 buf += len; 1572 buflen -= len; 1573 } 1574 *buf = 0; 1575 return buf - buf0; 1576} 1577 1578/* 1579 * script_setenv - set an environment variable value to be used 1580 * for scripts that we run (e.g. ip-up, auth-up, etc.) 1581 */ 1582void 1583script_setenv(var, value) 1584 char *var, *value; 1585{ 1586 int vl = strlen(var); 1587 int i; 1588 char *p, *newstring; 1589 1590 if (asprintf(&newstring, "%s=%s", var, value) == -1) 1591 novm("script_setenv"); 1592 1593 /* check if this variable is already set */ 1594 if (script_env != 0) { 1595 for (i = 0; (p = script_env[i]) != 0; ++i) { 1596 if (strncmp(p, var, vl) == 0 && p[vl] == '=') { 1597 free(p); 1598 script_env[i] = newstring; 1599 return; 1600 } 1601 } 1602 } else { 1603 i = 0; 1604 script_env = (char **) calloc(16, sizeof(char *)); 1605 if (script_env == 0) 1606 novm("script_setenv"); 1607 s_env_nalloc = 16; 1608 } 1609 1610 /* reallocate script_env with more space if needed */ 1611 if (i + 1 >= s_env_nalloc) { 1612 int new_n = i + 17; 1613 char **newenv = reallocarray(script_env, 1614 new_n, sizeof(char *)); 1615 if (newenv == 0) 1616 novm("script_setenv"); 1617 script_env = newenv; 1618 s_env_nalloc = new_n; 1619 } 1620 1621 script_env[i] = newstring; 1622 script_env[i+1] = 0; 1623} 1624