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