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