main.c revision 1.5
1/* $OpenBSD: main.c,v 1.5 1996/03/25 15:55:49 niklas 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.5 1996/03/25 15:55:49 niklas 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 IPX_CHANGE 58#include "ipxcp.h" 59#endif /* IPX_CHANGE */ 60 61/* 62 * If REQ_SYSOPTIONS is defined to 1, pppd will not run unless 63 * /etc/ppp/options exists. 64 */ 65#ifndef REQ_SYSOPTIONS 66#define REQ_SYSOPTIONS 1 67#endif 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 */ 79 80int ttyfd = -1; /* Serial port file descriptor */ 81 82int phase; /* where the link is at */ 83int kill_link; 84int open_ccp_flag; 85 86u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ 87u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ 88 89int hungup; /* terminal has been hung up */ 90static int n_children; /* # child processes still running */ 91 92int baud_rate; /* Actual bits/second for serial device */ 93 94static int locked; /* lock() has succeeded */ 95 96char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; 97 98/* Prototypes for procedures local to this file. */ 99 100static void cleanup __P((void)); 101static void close_tty __P((void)); 102static void get_input __P((void)); 103static void connect_time_expired __P((caddr_t)); 104static void calltimeout __P((void)); 105static struct timeval *timeleft __P((struct timeval *)); 106static void hup __P((int)); 107static void term __P((int)); 108static void chld __P((int)); 109static void toggle_debug __P((int)); 110static void open_ccp __P((int)); 111static void bad_signal __P((int)); 112static void holdoff_end __P((void *)); 113static int device_script __P((char *, int, int)); 114static void reap_kids __P((void)); 115static void pr_log __P((void *, char *, ...)); 116 117extern char *ttyname __P((int)); 118extern char *getlogin __P((void)); 119 120#ifdef ultrix 121#undef O_NONBLOCK 122#define O_NONBLOCK O_NDELAY 123#endif 124 125/* 126 * PPP Data Link Layer "protocol" table. 127 * One entry per supported protocol. 128 * The last entry must be NULL. 129 */ 130struct protent *protocols[] = { 131 &lcp_protent, 132 &pap_protent, 133 &chap_protent, 134 &ipcp_protent, 135 &ccp_protent, 136#ifdef IPX_CHANGE 137 &ipxcp_protent, 138#endif 139 NULL 140}; 141 142void 143main(argc, argv) 144 int argc; 145 char *argv[]; 146{ 147 int i, nonblock, fdflags; 148 struct sigaction sa; 149 FILE *pidfile; 150 char *p; 151 struct passwd *pw; 152 struct timeval timo; 153 sigset_t mask; 154 struct protent *protp; 155 156 p = ttyname(0); 157 if (p) 158 strcpy(devnam, p); 159 strcpy(default_devnam, devnam); 160 161 if (gethostname(hostname, MAXNAMELEN) < 0 ) { 162 perror("couldn't get hostname"); 163 die(1); 164 } 165 hostname[MAXNAMELEN-1] = 0; 166 167 uid = getuid(); 168 169 /* 170 * Initialize to the standard option set, then parse, in order, 171 * the system options file, the user's options file, and the command 172 * line arguments. 173 */ 174 for (i = 0; (protp = protocols[i]) != NULL; ++i) 175 (*protp->init)(0); 176 177 progname = *argv; 178 179 if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0) || 180 !options_for_tty() || 181 !options_from_user() || 182 !parse_args(argc-1, argv+1)) 183 exit(1); 184 185 if (!ppp_available()) { 186 fprintf(stderr, no_ppp_msg); 187 exit(1); 188 } 189 190 /* 191 * Check that the options given are valid and consistent. 192 */ 193 sys_check_options(); 194 auth_check_options(); 195 for (i = 0; (protp = protocols[i]) != NULL; ++i) 196 if (protp->check_options != NULL) 197 (*protp->check_options)(); 198 if (demand && connector == 0) { 199 fprintf(stderr, "%s: connect script required for demand-dialling\n", 200 progname); 201 exit(1); 202 } 203 204 /* 205 * If the user has specified the default device name explicitly, 206 * pretend they hadn't. 207 */ 208 if (!default_device && strcmp(devnam, default_devnam) == 0) 209 default_device = 1; 210 211 /* 212 * Initialize system-dependent stuff and magic number package. 213 */ 214 sys_init(); 215 magic_init(); 216 217 /* 218 * Detach ourselves from the terminal, if required, 219 * and identify who is running us. 220 */ 221 if (!default_device && !nodetach && daemon(0, 0) < 0) { 222 perror("Couldn't detach from controlling terminal"); 223 exit(1); 224 } 225 pid = getpid(); 226 p = getlogin(); 227 if (p == NULL) { 228 pw = getpwuid(uid); 229 if (pw != NULL && pw->pw_name != NULL) 230 p = pw->pw_name; 231 else 232 p = "(unknown)"; 233 } 234 syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d", 235 VERSION, PATCHLEVEL, p, uid); 236 237 /* 238 * Compute mask of all interesting signals and install signal handlers 239 * for each. Only one signal handler may be active at a time. Therefore, 240 * all other signals should be masked when any handler is executing. 241 */ 242 sigemptyset(&mask); 243 sigaddset(&mask, SIGHUP); 244 sigaddset(&mask, SIGINT); 245 sigaddset(&mask, SIGTERM); 246 sigaddset(&mask, SIGCHLD); 247 248#define SIGNAL(s, handler) { \ 249 sa.sa_handler = handler; \ 250 if (sigaction(s, &sa, NULL) < 0) { \ 251 syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ 252 die(1); \ 253 } \ 254 } 255 256 sa.sa_mask = mask; 257 sa.sa_flags = 0; 258 SIGNAL(SIGHUP, hup); /* Hangup */ 259 SIGNAL(SIGINT, term); /* Interrupt */ 260 SIGNAL(SIGTERM, term); /* Terminate */ 261 SIGNAL(SIGCHLD, chld); 262 263 SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ 264 SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ 265 266 /* 267 * Install a handler for other signals which would otherwise 268 * cause pppd to exit without cleaning up. 269 */ 270 SIGNAL(SIGABRT, bad_signal); 271 SIGNAL(SIGALRM, bad_signal); 272 SIGNAL(SIGFPE, bad_signal); 273 SIGNAL(SIGILL, bad_signal); 274 SIGNAL(SIGPIPE, bad_signal); 275 SIGNAL(SIGQUIT, bad_signal); 276 SIGNAL(SIGSEGV, bad_signal); 277#ifdef SIGBUS 278 SIGNAL(SIGBUS, bad_signal); 279#endif 280#ifdef SIGEMT 281 SIGNAL(SIGEMT, bad_signal); 282#endif 283#ifdef SIGPOLL 284 SIGNAL(SIGPOLL, bad_signal); 285#endif 286#ifdef SIGPROF 287 SIGNAL(SIGPROF, bad_signal); 288#endif 289#ifdef SIGSYS 290 SIGNAL(SIGSYS, bad_signal); 291#endif 292#ifdef SIGTRAP 293 SIGNAL(SIGTRAP, bad_signal); 294#endif 295#ifdef SIGVTALRM 296 SIGNAL(SIGVTALRM, bad_signal); 297#endif 298#ifdef SIGXCPU 299 SIGNAL(SIGXCPU, bad_signal); 300#endif 301#ifdef SIGXFSZ 302 SIGNAL(SIGXFSZ, bad_signal); 303#endif 304 305 /* 306 * If we're doing dial-on-demand, set up the interface now. 307 */ 308 if (demand) { 309 /* 310 * Open the loopback channel and set it up to be the ppp interface. 311 */ 312 open_ppp_loopback(); 313 314 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 315 (void) sprintf(ifname, "ppp%d", ifunit); 316 317 /* write pid to file */ 318 (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname); 319 if ((pidfile = fopen(pidfilename, "w")) != NULL) { 320 fprintf(pidfile, "%d\n", pid); 321 (void) fclose(pidfile); 322 } else { 323 syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename); 324 pidfilename[0] = 0; 325 } 326 327 /* 328 * Configure the interface and mark it up, etc. 329 */ 330 demand_conf(); 331 } 332 333 for (;;) { 334 335 if (demand) { 336 /* 337 * Don't do anything until we see some activity. 338 */ 339 phase = PHASE_DORMANT; 340 kill_link = 0; 341 demand_unblock(); 342 for (;;) { 343 wait_loop_output(timeleft(&timo)); 344 calltimeout(); 345 if (kill_link) { 346 if (!persist) 347 die(0); 348 kill_link = 0; 349 } 350 if (get_loop_output()) 351 break; 352 reap_kids(); 353 } 354 355 /* 356 * Now we want to bring up the link. 357 */ 358 demand_block(); 359 syslog(LOG_INFO, "Starting link"); 360 } 361 362 /* 363 * Lock the device if we've been asked to. 364 */ 365 if (lockflag && !default_device) { 366 if (lock(devnam) < 0) 367 goto fail; 368 locked = 1; 369 } 370 371 /* 372 * Open the serial device and set it up to be the ppp interface. 373 * If we're dialling out, or we don't want to use the modem lines, 374 * we open it in non-blocking mode, but then we need to clear 375 * the non-blocking I/O bit. 376 */ 377 nonblock = (connector || !modem)? O_NONBLOCK: 0; 378 if ((ttyfd = open(devnam, nonblock | O_RDWR, 0)) < 0) { 379 syslog(LOG_ERR, "Failed to open %s: %m", devnam); 380 goto fail; 381 } 382 if (nonblock) { 383 if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 384 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) 385 syslog(LOG_WARNING, 386 "Couldn't reset non-blocking mode on device: %m"); 387 } 388 hungup = 0; 389 kill_link = 0; 390 391 /* run connection script */ 392 if (connector && connector[0]) { 393 MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); 394 395 /* set line speed, flow control, etc.; set CLOCAL for now */ 396 set_up_tty(ttyfd, 1); 397 398 /* drop dtr to hang up in case modem is off hook */ 399 if (!default_device && modem) { 400 setdtr(ttyfd, FALSE); 401 sleep(1); 402 setdtr(ttyfd, TRUE); 403 } 404 405 if (device_script(connector, ttyfd, ttyfd) < 0) { 406 syslog(LOG_ERR, "Connect script failed"); 407 setdtr(ttyfd, FALSE); 408 goto fail; 409 } 410 411 syslog(LOG_INFO, "Serial connection established."); 412 sleep(1); /* give it time to set up its terminal */ 413 } 414 415 /* set line speed, flow control, etc.; clear CLOCAL if modem option */ 416 set_up_tty(ttyfd, 0); 417 418 /* run welcome script, if any */ 419 if (welcomer && welcomer[0]) { 420 if (device_script(welcomer, ttyfd, ttyfd) < 0) 421 syslog(LOG_WARNING, "Welcome script failed"); 422 } 423 424 /* set up the serial device as a ppp interface */ 425 establish_ppp(ttyfd); 426 427 if (!demand) { 428 429 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 430 (void) sprintf(ifname, "ppp%d", ifunit); 431 432 /* write pid to file */ 433 (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname); 434 if ((pidfile = fopen(pidfilename, "w")) != NULL) { 435 fprintf(pidfile, "%d\n", pid); 436 (void) fclose(pidfile); 437 } else { 438 syslog(LOG_ERR, "Failed to create pid file %s: %m", 439 pidfilename); 440 pidfilename[0] = 0; 441 } 442 } 443 444 /* 445 * Set a timeout to close the connection once the maximum 446 * connect time has expired. 447 */ 448 if (maxconnect > 0) 449 TIMEOUT(connect_time_expired, 0, maxconnect); 450 451 /* 452 * Start opening the connection and wait for 453 * incoming events (reply, timeout, etc.). 454 */ 455 syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); 456 lcp_lowerup(0); 457 lcp_open(0); /* Start protocol */ 458 for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { 459 wait_input(timeleft(&timo)); 460 calltimeout(); 461 get_input(); 462 if (kill_link) { 463 lcp_close(0, "User request"); 464 phase = PHASE_TERMINATE; 465 kill_link = 0; 466 } 467 if (open_ccp_flag) { 468 if (phase == PHASE_NETWORK) { 469 ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ 470 ccp_open(0); 471 } 472 open_ccp_flag = 0; 473 } 474 reap_kids(); /* Don't leave dead kids lying around */ 475 } 476 477 /* 478 * If we may want to bring the link up again, transfer 479 * the ppp unit back to the loopback. Set the 480 * real serial device back to its normal mode of operation. 481 */ 482 clean_check(); 483 if (demand) 484 restore_loop(); 485 disestablish_ppp(ttyfd); 486 487 /* 488 * Run disconnector script, if requested. 489 * XXX we may not be able to do this if the line has hung up! 490 */ 491 if (disconnector && !hungup) { 492 set_up_tty(ttyfd, 1); 493 if (device_script(disconnector, ttyfd, ttyfd) < 0) { 494 syslog(LOG_WARNING, "disconnect script failed"); 495 } else { 496 syslog(LOG_INFO, "Serial link disconnected."); 497 } 498 } 499 500 fail: 501 close_tty(); 502 if (locked) { 503 unlock(); 504 locked = 0; 505 } 506 507 if (!demand) { 508 if (unlink(pidfilename) < 0 && errno != ENOENT) 509 syslog(LOG_WARNING, "unable to delete pid file: %m"); 510 pidfilename[0] = 0; 511 } 512 513 if (!persist) 514 break; 515 516 if (demand) 517 demand_discard(); 518 if (holdoff > 0) { 519 phase = PHASE_HOLDOFF; 520 TIMEOUT(holdoff_end, NULL, holdoff); 521 do { 522 wait_time(timeleft(&timo)); 523 calltimeout(); 524 if (kill_link) { 525 if (!persist) 526 die(0); 527 kill_link = 0; 528 phase = PHASE_DORMANT; /* allow signal to end holdoff */ 529 } 530 reap_kids(); 531 } while (phase == PHASE_HOLDOFF); 532 } 533 } 534 535 die(0); 536} 537 538/* 539 * holdoff_end - called via a timeout when the holdoff period ends. 540 */ 541static void 542holdoff_end(arg) 543 void *arg; 544{ 545 phase = PHASE_DORMANT; 546} 547 548/* 549 * get_input - called when incoming data is available. 550 */ 551static void 552get_input() 553{ 554 int len, i; 555 u_char *p; 556 u_short protocol; 557 struct protent *protp; 558 559 p = inpacket_buf; /* point to beginning of packet buffer */ 560 561 len = read_packet(inpacket_buf); 562 if (len < 0) 563 return; 564 565 if (len == 0) { 566 syslog(LOG_NOTICE, "Modem hangup"); 567 hungup = 1; 568 lcp_lowerdown(0); /* serial link is no longer available */ 569 link_terminated(0); 570 return; 571 } 572 573 if (debug /*&& (debugflags & DBG_INPACKET)*/) 574 log_packet(p, len, "rcvd "); 575 576 if (len < PPP_HDRLEN) { 577 MAINDEBUG((LOG_INFO, "io(): Received short packet.")); 578 return; 579 } 580 581 p += 2; /* Skip address and control */ 582 GETSHORT(protocol, p); 583 len -= PPP_HDRLEN; 584 585 /* 586 * Toss all non-LCP packets unless LCP is OPEN. 587 */ 588 if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { 589 MAINDEBUG((LOG_INFO, 590 "io(): Received non-LCP packet when LCP not open.")); 591 return; 592 } 593 594 /* 595 * Upcall the proper protocol input routine. 596 */ 597 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 598 if (protp->protocol == protocol && protp->enabled_flag) { 599 (*protp->input)(0, p, len); 600 return; 601 } 602 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag 603 && protp->datainput != NULL) { 604 (*protp->datainput)(0, p, len); 605 return; 606 } 607 } 608 609 if (debug) 610 syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); 611 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); 612} 613 614 615/* 616 * quit - Clean up state and exit (with an error indication). 617 */ 618void 619quit() 620{ 621 die(1); 622} 623 624/* 625 * die - like quit, except we can specify an exit status. 626 */ 627void 628die(status) 629 int status; 630{ 631 cleanup(); 632 syslog(LOG_INFO, "Exit."); 633 exit(status); 634} 635 636/* 637 * connect_time_expired - log a message and close the connection. 638 */ 639static void 640connect_time_expired(arg) 641 caddr_t arg; 642{ 643 syslog(LOG_INFO, "Connect time expired"); 644 645 phase = PHASE_TERMINATE; 646 lcp_close(0, "Connect time expired"); /* Close connection */ 647} 648 649/* 650 * cleanup - restore anything which needs to be restored before we exit 651 */ 652/* ARGSUSED */ 653static void 654cleanup() 655{ 656 sys_cleanup(); 657 658 if (ttyfd >= 0) 659 close_tty(); 660 661 if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) 662 syslog(LOG_WARNING, "unable to delete pid file: %m"); 663 pidfilename[0] = 0; 664 665 if (locked) 666 unlock(); 667} 668 669/* 670 * close_tty - restore the terminal device and close it. 671 */ 672static void 673close_tty() 674{ 675 disestablish_ppp(ttyfd); 676 677 /* drop dtr to hang up */ 678 if (modem) { 679 setdtr(ttyfd, FALSE); 680 /* 681 * This sleep is in case the serial port has CLOCAL set by default, 682 * and consequently will reassert DTR when we close the device. 683 */ 684 sleep(1); 685 } 686 687 restore_tty(ttyfd); 688 689 close(ttyfd); 690 ttyfd = -1; 691} 692 693 694struct callout { 695 struct timeval c_time; /* time at which to call routine */ 696 caddr_t c_arg; /* argument to routine */ 697 void (*c_func)(); /* routine */ 698 struct callout *c_next; 699}; 700 701static struct callout *callout = NULL; /* Callout list */ 702static struct timeval timenow; /* Current time */ 703 704/* 705 * timeout - Schedule a timeout. 706 * 707 * Note that this timeout takes the number of seconds, NOT hz (as in 708 * the kernel). 709 */ 710void 711timeout(func, arg, time) 712 void (*func)(); 713 caddr_t arg; 714 int time; 715{ 716 struct callout *newp, *p, **pp; 717 718 MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", 719 (long) func, (long) arg, time)); 720 721 /* 722 * Allocate timeout. 723 */ 724 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { 725 syslog(LOG_ERR, "Out of memory in timeout()!"); 726 die(1); 727 } 728 newp->c_arg = arg; 729 newp->c_func = func; 730 gettimeofday(&timenow, NULL); 731 newp->c_time.tv_sec = timenow.tv_sec + time; 732 newp->c_time.tv_usec = timenow.tv_usec; 733 734 /* 735 * Find correct place and link it in. 736 */ 737 for (pp = &callout; (p = *pp); pp = &p->c_next) 738 if (newp->c_time.tv_sec < p->c_time.tv_sec 739 || (newp->c_time.tv_sec == p->c_time.tv_sec 740 && newp->c_time.tv_usec < p->c_time.tv_sec)) 741 break; 742 newp->c_next = p; 743 *pp = newp; 744} 745 746 747/* 748 * untimeout - Unschedule a timeout. 749 */ 750void 751untimeout(func, arg) 752 void (*func)(); 753 caddr_t arg; 754{ 755 struct callout **copp, *freep; 756 757 MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); 758 759 /* 760 * Find first matching timeout and remove it from the list. 761 */ 762 for (copp = &callout; (freep = *copp); copp = &freep->c_next) 763 if (freep->c_func == func && freep->c_arg == arg) { 764 *copp = freep->c_next; 765 (void) free((char *) freep); 766 break; 767 } 768} 769 770 771/* 772 * calltimeout - Call any timeout routines which are now due. 773 */ 774static void 775calltimeout() 776{ 777 struct callout *p; 778 779 while (callout != NULL) { 780 p = callout; 781 782 if (gettimeofday(&timenow, NULL) < 0) { 783 syslog(LOG_ERR, "Failed to get time of day: %m"); 784 die(1); 785 } 786 if (!(p->c_time.tv_sec < timenow.tv_sec 787 || (p->c_time.tv_sec == timenow.tv_sec 788 && p->c_time.tv_usec <= timenow.tv_usec))) 789 break; /* no, it's not time yet */ 790 791 callout = p->c_next; 792 (*p->c_func)(p->c_arg); 793 794 free((char *) p); 795 } 796} 797 798 799/* 800 * timeleft - return the length of time until the next timeout is due. 801 */ 802static struct timeval * 803timeleft(tvp) 804 struct timeval *tvp; 805{ 806 if (callout == NULL) 807 return NULL; 808 809 gettimeofday(&timenow, NULL); 810 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; 811 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; 812 if (tvp->tv_usec < 0) { 813 tvp->tv_usec += 1000000; 814 tvp->tv_sec -= 1; 815 } 816 if (tvp->tv_sec < 0) 817 tvp->tv_sec = tvp->tv_usec = 0; 818 819 return tvp; 820} 821 822 823/* 824 * hup - Catch SIGHUP signal. 825 * 826 * Indicates that the physical layer has been disconnected. 827 * We don't rely on this indication; if the user has sent this 828 * signal, we just take the link down. 829 */ 830static void 831hup(sig) 832 int sig; 833{ 834 syslog(LOG_INFO, "Hangup (SIGHUP)"); 835 kill_link = 1; 836} 837 838 839/* 840 * term - Catch SIGTERM signal and SIGINT signal (^C/del). 841 * 842 * Indicates that we should initiate a graceful disconnect and exit. 843 */ 844/*ARGSUSED*/ 845static void 846term(sig) 847 int sig; 848{ 849 syslog(LOG_INFO, "Terminating on signal %d.", sig); 850 persist = 0; /* don't try to restart */ 851 kill_link = 1; 852} 853 854 855/* 856 * chld - Catch SIGCHLD signal. 857 * Calls reap_kids to get status for any dead kids. 858 */ 859static void 860chld(sig) 861 int sig; 862{ 863 reap_kids(); 864} 865 866 867/* 868 * toggle_debug - Catch SIGUSR1 signal. 869 * 870 * Toggle debug flag. 871 */ 872/*ARGSUSED*/ 873static void 874toggle_debug(sig) 875 int sig; 876{ 877 debug = !debug; 878 note_debug_level(); 879} 880 881 882/* 883 * open_ccp - Catch SIGUSR2 signal. 884 * 885 * Try to (re)negotiate compression. 886 */ 887/*ARGSUSED*/ 888static void 889open_ccp(sig) 890 int sig; 891{ 892 open_ccp_flag = 1; 893} 894 895 896/* 897 * bad_signal - We've caught a fatal signal. Clean up state and exit. 898 */ 899static void 900bad_signal(sig) 901 int sig; 902{ 903 syslog(LOG_ERR, "Fatal signal %d", sig); 904 die(1); 905} 906 907 908/* 909 * device_script - run a program to connect or disconnect the 910 * serial device. 911 */ 912static int 913device_script(program, in, out) 914 char *program; 915 int in, out; 916{ 917 int pid; 918 int status; 919 int errfd; 920 921 pid = fork(); 922 923 if (pid < 0) { 924 syslog(LOG_ERR, "Failed to create child process: %m"); 925 die(1); 926 } 927 928 if (pid == 0) { 929 sys_close(); 930 dup2(in, 0); 931 dup2(out, 1); 932 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); 933 if (errfd >= 0) 934 dup2(errfd, 2); 935 setuid(getuid()); 936 setgid(getgid()); 937 execl("/bin/sh", "sh", "-c", program, (char *)0); 938 syslog(LOG_ERR, "could not exec /bin/sh: %m"); 939 _exit(99); 940 /* NOTREACHED */ 941 } 942 943 while (waitpid(pid, &status, 0) < 0) { 944 if (errno == EINTR) 945 continue; 946 syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); 947 die(1); 948 } 949 950 return (status == 0 ? 0 : -1); 951} 952 953 954/* 955 * run-program - execute a program with given arguments, 956 * but don't wait for it. 957 * If the program can't be executed, logs an error unless 958 * must_exist is 0 and the program file doesn't exist. 959 */ 960int 961run_program(prog, args, must_exist) 962 char *prog; 963 char **args; 964 int must_exist; 965{ 966 int pid; 967 968 pid = fork(); 969 if (pid == -1) { 970 syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); 971 return -1; 972 } 973 if (pid == 0) { 974 int new_fd; 975 976 /* Leave the current location */ 977 (void) setsid(); /* No controlling tty. */ 978 (void) umask (S_IRWXG|S_IRWXO); 979 (void) chdir ("/"); /* no current directory. */ 980 setuid(geteuid()); 981 setgid(getegid()); 982 983 /* Ensure that nothing of our device environment is inherited. */ 984 sys_close(); 985 close (0); 986 close (1); 987 close (2); 988 close (ttyfd); /* tty interface to the ppp device */ 989 990 /* Don't pass handles to the PPP device, even by accident. */ 991 new_fd = open (_PATH_DEVNULL, O_RDWR); 992 if (new_fd >= 0) { 993 if (new_fd != 0) { 994 dup2 (new_fd, 0); /* stdin <- /dev/null */ 995 close (new_fd); 996 } 997 dup2 (0, 1); /* stdout -> /dev/null */ 998 dup2 (0, 2); /* stderr -> /dev/null */ 999 } 1000 1001#ifdef BSD 1002 /* Force the priority back to zero if pppd is running higher. */ 1003 if (setpriority (PRIO_PROCESS, 0, 0) < 0) 1004 syslog (LOG_WARNING, "can't reset priority to 0: %m"); 1005#endif 1006 1007 /* SysV recommends a second fork at this point. */ 1008 1009 execve(prog, args); 1010 if (must_exist || errno != ENOENT) 1011 syslog(LOG_WARNING, "Can't execute %s: %m", prog); 1012 _exit(-1); 1013 } 1014 MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid)); 1015 ++n_children; 1016 return 0; 1017} 1018 1019 1020/* 1021 * reap_kids - get status from any dead child processes, 1022 * and log a message for abnormal terminations. 1023 */ 1024static void 1025reap_kids() 1026{ 1027 int pid, status; 1028 1029 if (n_children == 0) 1030 return; 1031 if ((pid = waitpid(-1, &status, WNOHANG)) == -1) { 1032 if (errno != ECHILD) 1033 syslog(LOG_ERR, "Error waiting for child process: %m"); 1034 return; 1035 } 1036 if (pid > 0) { 1037 --n_children; 1038 if (WIFSIGNALED(status)) { 1039 syslog(LOG_WARNING, "Child process %d terminated with signal %d", 1040 pid, WTERMSIG(status)); 1041 } 1042 } 1043} 1044 1045 1046/* 1047 * log_packet - format a packet and log it. 1048 */ 1049 1050char line[256]; /* line to be logged accumulated here */ 1051char *linep; 1052 1053void 1054log_packet(p, len, prefix) 1055 u_char *p; 1056 int len; 1057 char *prefix; 1058{ 1059 strcpy(line, prefix); 1060 linep = line + strlen(line); 1061 format_packet(p, len, pr_log, NULL); 1062 if (linep != line) 1063 syslog(LOG_DEBUG, "%s", line); 1064} 1065 1066/* 1067 * format_packet - make a readable representation of a packet, 1068 * calling `printer(arg, format, ...)' to output it. 1069 */ 1070void 1071format_packet(p, len, printer, arg) 1072 u_char *p; 1073 int len; 1074 void (*printer) __P((void *, char *, ...)); 1075 void *arg; 1076{ 1077 int i, n; 1078 u_short proto; 1079 u_char x; 1080 struct protent *protp; 1081 1082 if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { 1083 p += 2; 1084 GETSHORT(proto, p); 1085 len -= PPP_HDRLEN; 1086 for (i = 0; (protp = protocols[i]) != NULL; ++i) 1087 if (proto == protp->protocol) 1088 break; 1089 if (protp != NULL) { 1090 printer(arg, "[%s", protp->name); 1091 n = (*protp->printpkt)(p, len, printer, arg); 1092 printer(arg, "]"); 1093 p += n; 1094 len -= n; 1095 } else { 1096 printer(arg, "[proto=0x%x]", proto); 1097 } 1098 } 1099 1100 for (; len > 0; --len) { 1101 GETCHAR(x, p); 1102 printer(arg, " %.2x", x); 1103 } 1104} 1105 1106#ifdef __STDC__ 1107#include <stdarg.h> 1108 1109static void 1110pr_log(void *arg, char *fmt, ...) 1111{ 1112 int n; 1113 va_list pvar; 1114 char buf[256]; 1115 1116 va_start(pvar, fmt); 1117 vsprintf(buf, fmt, pvar); 1118 va_end(pvar); 1119 1120 n = strlen(buf); 1121 if (linep + n + 1 > line + sizeof(line)) { 1122 syslog(LOG_DEBUG, "%s", line); 1123 linep = line; 1124 } 1125 strcpy(linep, buf); 1126 linep += n; 1127} 1128 1129#else /* __STDC__ */ 1130#include <varargs.h> 1131 1132static void 1133pr_log(arg, fmt, va_alist) 1134void *arg; 1135char *fmt; 1136va_dcl 1137{ 1138 int n; 1139 va_list pvar; 1140 char buf[256]; 1141 1142 va_start(pvar); 1143 vsprintf(buf, fmt, pvar); 1144 va_end(pvar); 1145 1146 n = strlen(buf); 1147 if (linep + n + 1 > line + sizeof(line)) { 1148 syslog(LOG_DEBUG, "%s", line); 1149 linep = line; 1150 } 1151 strcpy(linep, buf); 1152 linep += n; 1153} 1154#endif 1155 1156/* 1157 * print_string - print a readable representation of a string using 1158 * printer. 1159 */ 1160void 1161print_string(p, len, printer, arg) 1162 char *p; 1163 int len; 1164 void (*printer) __P((void *, char *, ...)); 1165 void *arg; 1166{ 1167 int c; 1168 1169 printer(arg, "\""); 1170 for (; len > 0; --len) { 1171 c = *p++; 1172 if (' ' <= c && c <= '~') 1173 printer(arg, "%c", c); 1174 else 1175 printer(arg, "\\%.3o", c); 1176 } 1177 printer(arg, "\""); 1178} 1179 1180/* 1181 * novm - log an error message saying we ran out of memory, and die. 1182 */ 1183void 1184novm(msg) 1185 char *msg; 1186{ 1187 syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg); 1188 die(1); 1189} 1190