main.c revision 1.16
1/* $OpenBSD: main.c,v 1.16 1997/07/25 20:12:16 mickey 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.16 1997/07/25 20:12:16 mickey 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 reap_kids(); 944} 945 946 947/* 948 * toggle_debug - Catch SIGUSR1 signal. 949 * 950 * Toggle debug flag. 951 */ 952/*ARGSUSED*/ 953static void 954toggle_debug(sig) 955 int sig; 956{ 957 debug = !debug; 958 if (debug) { 959 setlogmask(LOG_UPTO(LOG_DEBUG)); 960 } else { 961 setlogmask(LOG_UPTO(LOG_WARNING)); 962 } 963} 964 965 966/* 967 * open_ccp - Catch SIGUSR2 signal. 968 * 969 * Try to (re)negotiate compression. 970 */ 971/*ARGSUSED*/ 972static void 973open_ccp(sig) 974 int sig; 975{ 976 open_ccp_flag = 1; 977} 978 979 980/* 981 * bad_signal - We've caught a fatal signal. Clean up state and exit. 982 */ 983static void 984bad_signal(sig) 985 int sig; 986{ 987 syslog(LOG_ERR, "Fatal signal %d", sig); 988 if (conn_running) 989 kill_my_pg(SIGTERM); 990 die(1); 991} 992 993 994/* 995 * device_script - run a program to connect or disconnect the 996 * serial device. 997 */ 998static int 999device_script(program, in, out) 1000 char *program; 1001 int in, out; 1002{ 1003 int pid; 1004 int status; 1005 int errfd; 1006 1007 conn_running = 1; 1008 pid = fork(); 1009 1010 if (pid < 0) { 1011 conn_running = 0; 1012 syslog(LOG_ERR, "Failed to create child process: %m"); 1013 die(1); 1014 } 1015 1016 if (pid == 0) { 1017 sys_close(); 1018 closelog(); 1019 if (in == out) { 1020 if (in != 0) { 1021 dup2(in, 0); 1022 close(in); 1023 } 1024 dup2(0, 1); 1025 } else { 1026 if (out == 0) 1027 out = dup(out); 1028 if (in != 0) { 1029 dup2(in, 0); 1030 close(in); 1031 } 1032 if (out != 1) { 1033 dup2(out, 1); 1034 close(out); 1035 } 1036 } 1037 if (redirect_stderr) { 1038 close(2); 1039 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); 1040 if (errfd >= 0 && errfd != 2) { 1041 dup2(errfd, 2); 1042 close(errfd); 1043 } 1044 } 1045 /* revoke privs */ 1046 seteuid(getuid()); 1047 setuid(getuid()); 1048 setegid(getgid()); 1049 setgid(getgid()); 1050 execl("/bin/sh", "sh", "-c", program, (char *)0); 1051 syslog(LOG_ERR, "could not exec /bin/sh: %m"); 1052 _exit(99); 1053 /* NOTREACHED */ 1054 } 1055 1056 while (waitpid(pid, &status, 0) < 0) { 1057 if (errno == EINTR) 1058 continue; 1059 syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); 1060 die(1); 1061 } 1062 conn_running = 0; 1063 1064 return (status == 0 ? 0 : -1); 1065} 1066 1067 1068/* 1069 * run-program - execute a program with given arguments, 1070 * but don't wait for it. 1071 * If the program can't be executed, logs an error unless 1072 * must_exist is 0 and the program file doesn't exist. 1073 */ 1074int 1075run_program(prog, args, must_exist) 1076 char *prog; 1077 char **args; 1078 int must_exist; 1079{ 1080 int pid; 1081 char *nullenv[1]; 1082 1083 pid = fork(); 1084 if (pid == -1) { 1085 syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); 1086 return -1; 1087 } 1088 if (pid == 0) { 1089 int new_fd; 1090 1091 /* Leave the current location */ 1092 (void) setsid(); /* No controlling tty. */ 1093 (void) umask (S_IRWXG|S_IRWXO); 1094 (void) chdir ("/"); /* no current directory. */ 1095 setuid(geteuid()); 1096 setgid(getegid()); 1097 1098 /* Ensure that nothing of our device environment is inherited. */ 1099 sys_close(); 1100 closelog(); 1101 close (0); 1102 close (1); 1103 close (2); 1104 close (ttyfd); /* tty interface to the ppp device */ 1105 1106 /* Don't pass handles to the PPP device, even by accident. */ 1107 new_fd = open (_PATH_DEVNULL, O_RDWR); 1108 if (new_fd >= 0) { 1109 if (new_fd != 0) { 1110 dup2 (new_fd, 0); /* stdin <- /dev/null */ 1111 close (new_fd); 1112 } 1113 dup2 (0, 1); /* stdout -> /dev/null */ 1114 dup2 (0, 2); /* stderr -> /dev/null */ 1115 } 1116 1117#ifdef BSD 1118 /* Force the priority back to zero if pppd is running higher. */ 1119 if (setpriority (PRIO_PROCESS, 0, 0) < 0) 1120 syslog (LOG_WARNING, "can't reset priority to 0: %m"); 1121#endif 1122 1123 /* SysV recommends a second fork at this point. */ 1124 1125 /* run the program; give it a null environment */ 1126 nullenv[0] = NULL; 1127 execve(prog, args, nullenv); 1128 if (must_exist || errno != ENOENT) 1129 syslog(LOG_WARNING, "Can't execute %s: %m", prog); 1130 _exit(-1); 1131 } 1132 MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid)); 1133 ++n_children; 1134 return 0; 1135} 1136 1137 1138/* 1139 * reap_kids - get status from any dead child processes, 1140 * and log a message for abnormal terminations. 1141 */ 1142static void 1143reap_kids() 1144{ 1145 int pid, status; 1146 1147 if (n_children == 0) 1148 return; 1149 if ((pid = waitpid(-1, &status, WNOHANG)) == -1) { 1150 if (errno != ECHILD) 1151 syslog(LOG_ERR, "Error waiting for child process: %m"); 1152 return; 1153 } 1154 if (pid > 0) { 1155 --n_children; 1156 if (WIFSIGNALED(status)) { 1157 syslog(LOG_WARNING, "Child process %d terminated with signal %d", 1158 pid, WTERMSIG(status)); 1159 } 1160 } 1161} 1162 1163 1164/* 1165 * log_packet - format a packet and log it. 1166 */ 1167 1168char line[256]; /* line to be logged accumulated here */ 1169char *linep; 1170 1171void 1172log_packet(p, len, prefix) 1173 u_char *p; 1174 int len; 1175 char *prefix; 1176{ 1177 strcpy(line, prefix); 1178 linep = line + strlen(line); 1179 format_packet(p, len, pr_log, NULL); 1180 if (linep != line) 1181 syslog(LOG_DEBUG, "%s", line); 1182} 1183 1184/* 1185 * format_packet - make a readable representation of a packet, 1186 * calling `printer(arg, format, ...)' to output it. 1187 */ 1188void 1189format_packet(p, len, printer, arg) 1190 u_char *p; 1191 int len; 1192 void (*printer) __P((void *, char *, ...)); 1193 void *arg; 1194{ 1195 int i, n; 1196 u_short proto; 1197 u_char x; 1198 struct protent *protp; 1199 1200 if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { 1201 p += 2; 1202 GETSHORT(proto, p); 1203 len -= PPP_HDRLEN; 1204 for (i = 0; (protp = protocols[i]) != NULL; ++i) 1205 if (proto == protp->protocol) 1206 break; 1207 if (protp != NULL) { 1208 printer(arg, "[%s", protp->name); 1209 n = (*protp->printpkt)(p, len, printer, arg); 1210 printer(arg, "]"); 1211 p += n; 1212 len -= n; 1213 } else { 1214 printer(arg, "[proto=0x%x]", proto); 1215 } 1216 } 1217 1218 for (; len > 0; --len) { 1219 GETCHAR(x, p); 1220 printer(arg, " %.2x", x); 1221 } 1222} 1223 1224static void 1225pr_log __V((void *arg, char *fmt, ...)) 1226{ 1227 int n; 1228 va_list pvar; 1229 char buf[256]; 1230 1231#ifdef __STDC__ 1232 va_start(pvar, fmt); 1233#else 1234 void *arg; 1235 char *fmt; 1236 va_start(pvar); 1237 arg = va_arg(pvar, void *); 1238 fmt = va_arg(pvar, char *); 1239#endif 1240 1241 vsprintf(buf, fmt, pvar); 1242 va_end(pvar); 1243 1244 n = strlen(buf); 1245 if (linep + n + 1 > line + sizeof(line)) { 1246 syslog(LOG_DEBUG, "%s", line); 1247 linep = line; 1248 } 1249 strcpy(linep, buf); 1250 linep += n; 1251} 1252 1253/* 1254 * print_string - print a readable representation of a string using 1255 * printer. 1256 */ 1257void 1258print_string(p, len, printer, arg) 1259 char *p; 1260 int len; 1261 void (*printer) __P((void *, char *, ...)); 1262 void *arg; 1263{ 1264 int c; 1265 1266 printer(arg, "\""); 1267 for (; len > 0; --len) { 1268 c = *p++; 1269 if (' ' <= c && c <= '~') { 1270 if (c == '\\' || c == '"') 1271 printer(arg, "\\"); 1272 printer(arg, "%c", c); 1273 } else { 1274 switch (c) { 1275 case '\n': 1276 printer(arg, "\\n"); 1277 break; 1278 case '\r': 1279 printer(arg, "\\r"); 1280 break; 1281 case '\t': 1282 printer(arg, "\\t"); 1283 break; 1284 default: 1285 printer(arg, "\\%.3o", c); 1286 } 1287 } 1288 } 1289 1290 printer(arg, "\""); 1291} 1292 1293/* 1294 * novm - log an error message saying we ran out of memory, and die. 1295 */ 1296void 1297novm(msg) 1298 char *msg; 1299{ 1300 syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg); 1301 die(1); 1302} 1303 1304/* 1305 * fmtmsg - format a message into a buffer. Like sprintf except we 1306 * also specify the length of the output buffer, and we handle 1307 * %r (recursive format), %m (error message) and %I (IP address) formats. 1308 * Doesn't do floating-point formats. 1309 * Returns the number of chars put into buf. 1310 */ 1311int 1312fmtmsg __V((char *buf, int buflen, char *fmt, ...)) 1313{ 1314 va_list args; 1315 int n; 1316 1317#ifdef __STDC__ 1318 va_start(args, fmt); 1319#else 1320 char *buf; 1321 int buflen; 1322 char *fmt; 1323 va_start(args); 1324 buf = va_arg(args, char *); 1325 buflen = va_arg(args, int); 1326 fmt = va_arg(args, char *); 1327#endif 1328 n = vfmtmsg(buf, buflen, fmt, args); 1329 va_end(args); 1330 return n; 1331} 1332 1333/* 1334 * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args. 1335 */ 1336#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) 1337 1338int 1339vfmtmsg(buf, buflen, fmt, args) 1340 char *buf; 1341 int buflen; 1342 char *fmt; 1343 va_list args; 1344{ 1345 int c, i, n; 1346 int width, prec, fillch; 1347 int base, len, neg, quoted; 1348 unsigned long val; 1349 char *str, *f, *buf0; 1350 unsigned char *p; 1351 va_list a; 1352 char num[32]; 1353 time_t t; 1354 static char hexchars[] = "0123456789abcdef"; 1355 1356 buf0 = buf; 1357 --buflen; 1358 while (buflen > 0) { 1359 for (f = fmt; *f != '%' && *f != 0; ++f) 1360 ; 1361 if (f > fmt) { 1362 len = f - fmt; 1363 if (len > buflen) 1364 len = buflen; 1365 memcpy(buf, fmt, len); 1366 buf += len; 1367 buflen -= len; 1368 fmt = f; 1369 } 1370 if (*fmt == 0) 1371 break; 1372 c = *++fmt; 1373 width = prec = 0; 1374 fillch = ' '; 1375 if (c == '0') { 1376 fillch = '0'; 1377 c = *++fmt; 1378 } 1379 if (c == '*') { 1380 width = va_arg(args, int); 1381 c = *++fmt; 1382 } else { 1383 while (isdigit(c)) { 1384 width = width * 10 + c - '0'; 1385 c = *++fmt; 1386 } 1387 } 1388 if (c == '.') { 1389 c = *++fmt; 1390 if (c == '*') { 1391 prec = va_arg(args, int); 1392 c = *++fmt; 1393 } else { 1394 while (isdigit(c)) { 1395 prec = prec * 10 + c - '0'; 1396 c = *++fmt; 1397 } 1398 } 1399 } 1400 str = 0; 1401 base = 0; 1402 neg = 0; 1403 ++fmt; 1404 switch (c) { 1405 case 'd': 1406 i = va_arg(args, int); 1407 if (i < 0) { 1408 neg = 1; 1409 val = -i; 1410 } else 1411 val = i; 1412 base = 10; 1413 break; 1414 case 'o': 1415 val = va_arg(args, unsigned int); 1416 base = 8; 1417 break; 1418 case 'x': 1419 val = va_arg(args, unsigned int); 1420 base = 16; 1421 break; 1422 case 'p': 1423 val = (unsigned long) va_arg(args, void *); 1424 base = 16; 1425 neg = 2; 1426 break; 1427 case 's': 1428 str = va_arg(args, char *); 1429 break; 1430 case 'c': 1431 num[0] = va_arg(args, int); 1432 num[1] = 0; 1433 str = num; 1434 break; 1435 case 'm': 1436 str = strerror(errno); 1437 break; 1438 case 'I': 1439 str = ip_ntoa(va_arg(args, u_int32_t)); 1440 break; 1441 case 'r': 1442 f = va_arg(args, char *); 1443 /* 1444 * XXX We assume a va_list is either a pointer or an array, so 1445 * what gets passed for a va_list is like a void * in some sense. 1446 */ 1447 a = va_arg(args, va_list); 1448 n = vfmtmsg(buf, buflen + 1, f, a); 1449 buf += n; 1450 buflen -= n; 1451 continue; 1452 case 't': 1453 time(&t); 1454 str = ctime(&t); 1455 str += 4; /* chop off the day name */ 1456 str[15] = 0; /* chop off year and newline */ 1457 break; 1458 case 'v': /* "visible" string */ 1459 case 'q': /* quoted string */ 1460 quoted = c == 'q'; 1461 p = va_arg(args, unsigned char *); 1462 if (fillch == '0' && prec > 0) { 1463 n = prec; 1464 } else { 1465 n = strlen((char *)p); 1466 if (prec > 0 && prec < n) 1467 n = prec; 1468 } 1469 while (n > 0 && buflen > 0) { 1470 c = *p++; 1471 --n; 1472 if (!quoted && c >= 0x80) { 1473 OUTCHAR('M'); 1474 OUTCHAR('-'); 1475 c -= 0x80; 1476 } 1477 if (quoted && (c == '"' || c == '\\')) 1478 OUTCHAR('\\'); 1479 if (c < 0x20 || 0x7f <= c && c < 0xa0) { 1480 if (quoted) { 1481 OUTCHAR('\\'); 1482 switch (c) { 1483 case '\t': OUTCHAR('t'); break; 1484 case '\n': OUTCHAR('n'); break; 1485 case '\b': OUTCHAR('b'); break; 1486 case '\f': OUTCHAR('f'); break; 1487 default: 1488 OUTCHAR('x'); 1489 OUTCHAR(hexchars[c >> 4]); 1490 OUTCHAR(hexchars[c & 0xf]); 1491 } 1492 } else { 1493 if (c == '\t') 1494 OUTCHAR(c); 1495 else { 1496 OUTCHAR('^'); 1497 OUTCHAR(c ^ 0x40); 1498 } 1499 } 1500 } else 1501 OUTCHAR(c); 1502 } 1503 continue; 1504 default: 1505 *buf++ = '%'; 1506 if (c != '%') 1507 --fmt; /* so %z outputs %z etc. */ 1508 --buflen; 1509 continue; 1510 } 1511 if (base != 0) { 1512 str = num + sizeof(num); 1513 *--str = 0; 1514 while (str > num + neg) { 1515 *--str = hexchars[val % base]; 1516 val = val / base; 1517 if (--prec <= 0 && val == 0) 1518 break; 1519 } 1520 switch (neg) { 1521 case 1: 1522 *--str = '-'; 1523 break; 1524 case 2: 1525 *--str = 'x'; 1526 *--str = '0'; 1527 break; 1528 } 1529 len = num + sizeof(num) - 1 - str; 1530 } else { 1531 len = strlen(str); 1532 if (prec > 0 && len > prec) 1533 len = prec; 1534 } 1535 if (width > 0) { 1536 if (width > buflen) 1537 width = buflen; 1538 if ((n = width - len) > 0) { 1539 buflen -= n; 1540 for (; n > 0; --n) 1541 *buf++ = fillch; 1542 } 1543 } 1544 if (len > buflen) 1545 len = buflen; 1546 memcpy(buf, str, len); 1547 buf += len; 1548 buflen -= len; 1549 } 1550 *buf = 0; 1551 return buf - buf0; 1552} 1553