1/* 2 * Copyright (c) 2003, 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * main.c - Point-to-Point Protocol main module 25 * 26 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 27 * 28 * Redistribution and use in source and binary forms, with or without 29 * modification, are permitted provided that the following conditions 30 * are met: 31 * 32 * 1. Redistributions of source code must retain the above copyright 33 * notice, this list of conditions and the following disclaimer. 34 * 35 * 2. Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in 37 * the documentation and/or other materials provided with the 38 * distribution. 39 * 40 * 3. The name "Carnegie Mellon University" must not be used to 41 * endorse or promote products derived from this software without 42 * prior written permission. For permission or any legal 43 * details, please contact 44 * Office of Technology Transfer 45 * Carnegie Mellon University 46 * 5000 Forbes Avenue 47 * Pittsburgh, PA 15213-3890 48 * (412) 268-4387, fax: (412) 268-7395 49 * tech-transfer@andrew.cmu.edu 50 * 51 * 4. Redistributions of any form whatsoever must retain the following 52 * acknowledgment: 53 * "This product includes software developed by Computing Services 54 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 55 * 56 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 57 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 58 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 59 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 60 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 61 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 62 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 63 */ 64 65#define RCSID "$Id: main.c,v 1.34.20.1 2006/04/17 18:37:15 callie Exp $" 66 67#include <stdio.h> 68#include <ctype.h> 69#include <stdlib.h> 70#include <string.h> 71#include <unistd.h> 72#include <signal.h> 73#include <errno.h> 74#include <fcntl.h> 75#include <syslog.h> 76#include <netdb.h> 77#include <pwd.h> 78#include <setjmp.h> 79#include <sys/param.h> 80#include <sys/types.h> 81#include <sys/wait.h> 82#include <sys/time.h> 83#include <sys/resource.h> 84#include <sys/stat.h> 85#include <sys/socket.h> 86#include <pthread.h> 87#include <netinet/in.h> 88#include <arpa/inet.h> 89 90#include "pppd.h" 91#include "magic.h" 92#include "fsm.h" 93#include "lcp.h" 94#include "ipcp.h" 95#ifdef INET6 96#include "ipv6cp.h" 97#endif 98#ifdef ACSCP 99#include "acscp.h" 100#endif 101#include "upap.h" 102#include "chap-new.h" 103#include "eap.h" 104#include "ccp.h" 105#include "ecp.h" 106#include "pathnames.h" 107 108#ifdef USE_TDB 109#include "tdb.h" 110#endif 111 112#ifdef CBCP_SUPPORT 113#include "cbcp.h" 114#endif 115 116#ifdef IPX_CHANGE 117#include "ipxcp.h" 118#endif /* IPX_CHANGE */ 119#ifdef AT_CHANGE 120#include "atcp.h" 121#endif 122 123#ifndef lint 124static const char rcsid[] = RCSID; 125#endif 126 127/* interface vars */ 128char ifname[32]; /* Interface name */ 129int ifunit; /* Interface unit number */ 130 131struct channel *the_channel; 132 133char *progname; /* Name of this program */ 134char hostname[MAXNAMELEN]; /* Our hostname */ 135static char pidfilename[MAXPATHLEN]; /* name of pid file */ 136static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ 137char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ 138uid_t uid; /* Our real user-id */ 139struct notifier *pidchange = NULL; 140struct notifier *phasechange = NULL; 141struct notifier *exitnotify = NULL; 142struct notifier *sigreceived = NULL; 143struct notifier *fork_notifier = NULL; 144struct notifier *protocolsready_notifier = NULL; 145struct notifier *acspdhcpready_notifier = NULL; 146 147int hungup; /* terminal has been hung up */ 148int do_modem_hungup; /* need to finish disconnection */ 149int privileged; /* we're running as real uid root */ 150int need_holdoff; /* need holdoff period before restarting */ 151int detached; /* have detached from terminal */ 152volatile int status; /* exit status for pppd */ 153#ifdef __APPLE__ 154volatile int devstatus; /* exit device status for pppd */ 155#endif 156int unsuccess; /* # unsuccessful connection attempts */ 157int do_callback; /* != 0 if we should do callback next */ 158int doing_callback; /* != 0 if we are doing callback */ 159int ppp_session_number; /* Session number, for channels with such a 160 concept (eg PPPoE) */ 161#ifdef USE_TDB 162TDB_CONTEXT *pppdb; /* database for storing status etc. */ 163#endif 164 165char db_key[32]; 166 167int (*holdoff_hook) __P((void)) = NULL; 168int (*new_phase_hook) __P((int)) = NULL; 169void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL; 170void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL; 171 172static int conn_running; /* we have a [dis]connector running */ 173static int devfd; /* fd of underlying device */ 174static int fd_ppp = -1; /* fd for talking PPP */ 175static int fd_loop; /* fd for getting demand-dial packets */ 176static int fd_devnull; /* fd for /dev/null */ 177 178int phase; /* where the link is at */ 179int kill_link; 180int open_ccp_flag; 181int listen_time; 182int got_sigusr2; 183int got_sigterm; 184int got_sighup; 185#ifdef __APPLE__ 186int stop_link; 187int cont_link; 188int got_sigtstp; 189int got_sigcont; 190#endif 191 192static int waiting; 193static sigjmp_buf sigjmp; 194 195char **script_env; /* Env. variable values for scripts */ 196int s_env_nalloc; /* # words avail at script_env */ 197 198/* 199 * WCast-align fix - these buffers need to be aligned so that (after the 4 byte ppp header is removed) 200 * the protocol handling routines such as acsp can expect that the data is aligned on a 4 byte boundary 201 */ 202u_char outpacket_buf[PPP_MRU+PPP_HDRLEN] __attribute__ ((aligned (4))); /* buffer for outgoing packet */ 203u_char inpacket_buf[PPP_MRU+PPP_HDRLEN] __attribute__ ((aligned (4))); /* buffer for incoming packet */ 204 205static int n_children; /* # child processes still running */ 206static int got_sigchld; /* set if we have received a SIGCHLD */ 207 208int privopen; /* don't lock, open device as root */ 209 210char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; 211 212GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ 213int ngroups; /* How many groups valid in groups */ 214 215static struct timeval start_time; /* Time when link was started. */ 216 217struct pppd_stats link_stats; 218unsigned link_connect_time; 219int link_stats_valid; 220 221int error_count; 222 223/* 224 * We maintain a list of child process pids and 225 * functions to call when they exit. 226 */ 227struct subprocess { 228 pid_t pid; 229 char *prog; 230 void (*done) __P((void *)); 231 void *arg; 232 struct subprocess *next; 233}; 234 235static struct subprocess *children; 236 237#ifdef __APPLE__ 238static pthread_t mainthread_id = NULL; 239#endif 240 241/* Prototypes for procedures local to this file. */ 242 243static void setup_signals __P((void)); 244static void create_pidfile __P((int pid)); 245static void create_linkpidfile __P((int pid)); 246static void cleanup __P((void)); 247static void get_input __P((void)); 248static void calltimeout __P((void)); 249static struct timeval *timeleft __P((struct timeval *)); 250static void kill_my_pg __P((int)); 251static void hup __P((int)); 252#ifdef __APPLE__ 253static void stop __P((int)); 254static void cont __P((int)); 255#endif 256static void term __P((int)); 257static void chld __P((int)); 258static void toggle_debug __P((int)); 259static void open_ccp __P((int)); 260static void bad_signal __P((int)); 261static void holdoff_end __P((void *)); 262static int reap_kids __P((int waitfor)); 263 264#ifdef USE_TDB 265static void update_db_entry __P((void)); 266static void add_db_key __P((const char *)); 267static void delete_db_key __P((const char *)); 268static void cleanup_db __P((void)); 269#endif 270 271static void handle_events __P((void)); 272static void print_link_stats __P((void)); 273 274extern char *ttyname __P((int)); 275extern char *getlogin __P((void)); 276int main __P((int, char *[])); 277 278#ifdef __APPLE__ 279void (*wait_input_hook) __P((void)) = NULL; 280int (*start_link_hook) __P((void)) = NULL; 281int (*link_up_hook) __P((void)) = NULL; 282bool link_up_done = 0; 283int (*terminal_window_hook) __P((char *, int, int)) = NULL; 284int redialingcount = 0; 285bool redialingalternate = 0; 286struct notifier *connect_started_notify = NULL; 287struct notifier *connect_success_notify = NULL; 288struct notifier *connect_fail_notify = NULL; 289struct notifier *disconnect_started_notify = NULL; 290struct notifier *disconnect_done_notify = NULL; 291struct notifier *stop_notify = NULL; 292struct notifier *cont_notify = NULL; 293struct notifier *system_inited_notify = NULL; 294struct notifier *network_probed_notify = NULL; 295int wait_underlying_interface_up = 0; 296int retry_pre_start_link_check = 0; 297#endif 298 299#ifdef ultrix 300#undef O_NONBLOCK 301#define O_NONBLOCK O_NDELAY 302#endif 303 304#ifdef ULTRIX 305#define setlogmask(x) 306#endif 307 308 309/* 310 * PPP Data Link Layer "protocol" table. 311 * One entry per supported protocol. 312 * The last entry must be NULL. 313 */ 314struct protent *protocols[] = { 315 &lcp_protent, 316 &pap_protent, 317 &chap_protent, 318#ifdef CBCP_SUPPORT 319 &cbcp_protent, 320#endif 321 &ipcp_protent, 322#ifdef INET6 323 &ipv6cp_protent, 324#endif 325#ifdef ACSCP 326 &acscp_protent, 327#endif 328 &ccp_protent, 329 &ecp_protent, 330#ifdef IPX_CHANGE 331 &ipxcp_protent, 332#endif 333#ifdef AT_CHANGE 334 &atcp_protent, 335#endif 336 &eap_protent, 337 NULL 338}; 339 340/* 341 * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. 342 */ 343#if !defined(PPP_DRV_NAME) 344#define PPP_DRV_NAME "ppp" 345#endif /* !defined(PPP_DRV_NAME) */ 346 347int 348main(argc, argv) 349 int argc; 350 char *argv[]; 351{ 352 int i, t = 0; 353 char *p; 354 struct passwd *pw; 355 struct protent *protp; 356 char numbuf[16]; 357 358 /* Initialize syslog facilities */ 359 reopen_log(); 360 361 362#ifdef __APPLE__ 363 mainthread_id = pthread_self(); 364#endif 365 link_stats_valid = 0; 366 new_phase(PHASE_INITIALIZE); 367 368 369 script_env = NULL; 370 371 if (gethostname(hostname, MAXNAMELEN) < 0 ) { 372 option_error("Couldn't get hostname: %m"); 373 exit(1); 374 } 375 hostname[MAXNAMELEN-1] = 0; 376 377 /* make sure we don't create world or group writable files. */ 378 umask(umask(0777) | 022); 379 380 uid = getuid(); 381 privileged = uid == 0; 382#ifdef __APPLE__ 383 if (!privileged) 384 privileged = sys_check_controller(); 385#endif 386 slprintf(numbuf, sizeof(numbuf), "%d", uid); 387 script_setenv("ORIG_UID", numbuf, 0); 388 389 ngroups = getgroups(NGROUPS_MAX, groups); 390 391 /* 392 * Initialize magic number generator now so that protocols may 393 * use magic numbers in initialization. 394 */ 395 magic_init(); 396 397 /* 398 * Initialize each protocol. 399 */ 400 for (i = 0; (protp = protocols[i]) != NULL; ++i) 401 (*protp->init)(0); 402 403 /* 404 * Initialize the default channel. 405 */ 406 tty_init(); 407 408 progname = *argv; 409 410#ifdef __APPLE__ 411 sys_install_options(); 412#endif 413 414 /* 415 * Parse, in order, the system options file, the user's options file, 416 * and the command line arguments. 417 */ 418 if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) 419 || !options_from_user() 420 || !parse_args(argc-1, argv+1) 421#ifdef __APPLE__ 422 || ((controlled) && !options_from_controller()) 423 // options file to add additionnal parameters, after the plugins are loaded 424 // should not be used, except for debugging purpose, or specific behavior override 425 // anything set there will override what is specified as argument by the PPPController 426 // so only the admin should use it... 427 || !options_from_file(_PATH_SYSPOSTOPTIONS, 0, 0, 1) 428#endif 429 ) 430 exit(EXIT_OPTION_ERROR); 431 devnam_fixed = 1; /* can no longer change device name */ 432 433 /* 434 * Work out the device name, if it hasn't already been specified, 435 * and parse the tty's options file. 436 */ 437 if (the_channel->process_extra_options) 438 (*the_channel->process_extra_options)(); 439 440 if (debug) 441 setlogmask(LOG_UPTO(LOG_DEBUG)); 442 443 /* 444 * Check that we are running as root. 445 */ 446 if (geteuid() != 0) { 447 option_error("must be root to run %s, since it is not setuid-root", 448 argv[0]); 449 exit(EXIT_NOT_ROOT); 450 } 451 452 if (!ppp_available()) { 453 option_error("%s", no_ppp_msg); 454 exit(EXIT_NO_KERNEL_SUPPORT); 455 } 456 457 /* 458 * Check that the options given are valid and consistent. 459 */ 460 check_options(); 461 if (!sys_check_options()) 462 exit(EXIT_OPTION_ERROR); 463 auth_check_options(); 464#ifdef HAVE_MULTILINK 465 mp_check_options(); 466#endif 467 for (i = 0; (protp = protocols[i]) != NULL; ++i) 468 if (protp->check_options != NULL) 469 (*protp->check_options)(); 470 if (the_channel->check_options) 471 (*the_channel->check_options)(); 472 473 if (dump_options || dryrun) { 474 init_pr_log(NULL, LOG_INFO); 475 print_options(pr_log, NULL); 476 end_pr_log(); 477 } 478 479 if (dryrun) 480 die(0); 481 482 /* 483 * Initialize system-dependent stuff. 484 */ 485 sys_init(); 486#ifdef __APPLE__ 487 notify(system_inited_notify, 0); 488#endif 489 490 491 /* Make sure fds 0, 1, 2 are open to somewhere. */ 492 fd_devnull = open(_PATH_DEVNULL, O_RDWR); 493 if (fd_devnull < 0) 494 fatal("Couldn't open %s: %m", _PATH_DEVNULL); 495 while (fd_devnull <= 2) { 496 i = dup(fd_devnull); 497 if (i < 0) 498 fatal("Critical shortage of file descriptors: dup failed: %m"); 499 fd_devnull = i; 500 } 501 502#ifdef USE_TDB 503 pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); 504 if (pppdb != NULL) { 505 slprintf(db_key, sizeof(db_key), "pppd%d", getpid()); 506 update_db_entry(); 507 } else { 508 warning("Warning: couldn't open ppp database %s", _PATH_PPPDB); 509 if (multilink) { 510 warning("Warning: disabling multilink"); 511 multilink = 0; 512 } 513 } 514#endif 515 516 /* 517 * Detach ourselves from the terminal, if required, 518 * and identify who is running us. 519 */ 520 if (!nodetach && !updetach) 521 detach(); 522#ifndef __APPLE__ 523 // radar 6153490 524 p = getlogin(); 525 if (p == NULL) { 526#endif 527 pw = getpwuid(uid); 528 if (pw != NULL && pw->pw_name != NULL) 529 p = pw->pw_name; 530 else 531 p = "(unknown)"; 532#ifndef __APPLE__ 533 } 534#endif 535#ifdef __APPLE__ 536 sys_log(LOG_NOTICE, "pppd %s (Apple version %s) started by %s, uid %d", VERSION, PPP_VERSION, p, uid); 537#else 538 sys_log(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid); 539#endif 540 script_setenv("PPPLOGNAME", p, 0); 541 542 if (devnam[0]) 543 script_setenv("DEVICE", devnam, 1); 544 slprintf(numbuf, sizeof(numbuf), "%d", getpid()); 545 script_setenv("PPPD_PID", numbuf, 1); 546 547#if __APPLE__ 548 if (controlfd !=-1) 549 add_fd(controlfd); 550#endif 551 552 setup_signals(); 553 554 waiting = 0; 555 556 /* 557 * If we're doing dial-on-demand, set up the interface now. 558 */ 559 if (demand) { 560 /* 561 * Open the loopback channel and set it up to be the ppp interface. 562 */ 563#ifdef USE_TDB 564 tdb_writelock(pppdb); 565#endif 566 fd_loop = open_ppp_loopback(); 567 set_ifunit(1); 568#ifdef USE_TDB 569 tdb_writeunlock(pppdb); 570#endif 571 /* 572 * Configure the interface and mark it up, etc. 573 */ 574 demand_conf(); 575 create_linkpidfile(getpid()); 576 } 577 578#ifdef __APPLE__ 579 if (holdfirst) { 580 need_holdoff = 1; 581 goto hold; 582 } 583#endif 584 585 do_callback = 0; 586 for (;;) { 587 588 listen_time = 0; 589 need_holdoff = 1; 590 devfd = -1; 591 status = EXIT_OK; 592#ifdef __APPLE__ 593 devstatus = 0; 594#endif 595 ++unsuccess; 596 doing_callback = do_callback; 597 do_callback = 0; 598 599 if (demand && !doing_callback) { 600 /* 601 * Don't do anything until we see some activity. 602 */ 603 new_phase(PHASE_DORMANT); 604 demand_unblock(); 605 add_fd(fd_loop); 606 for (;;) { 607 handle_events(); 608 if (kill_link && !persist) 609 break; 610 if (get_loop_output()) 611 break; 612 } 613 remove_fd(fd_loop); 614 if (kill_link && !persist) 615 break; 616 617 /* 618 * Now we want to bring up the link. 619 */ 620 demand_block(); 621 info("Starting link"); 622 } 623 624#ifdef __APPLE__ 625 if (start_link_hook) { 626 if (the_channel->pre_start_link_check) { 627 int rc = -1; 628 if (retry_pre_start_link_check < 0) 629 retry_pre_start_link_check = 0; 630 for (i = 1 + retry_pre_start_link_check; i > 0; i--) { 631 if (!(rc = the_channel->pre_start_link_check())) { 632 break; 633 } 634 } 635 if (rc) { 636 status = EXIT_PEER_UNREACHABLE; 637 goto end; 638 } 639 } 640 641 t = (*start_link_hook)(); 642 if (t == 0) { 643 // cancelled 644 status = EXIT_USER_REQUEST; 645 goto end; 646 } 647 } 648#endif 649 650#ifdef __APPLE__ 651 sys_publish_remoteaddress(remoteaddress); 652#endif 653 new_phase(PHASE_SERIALCONN); 654 655#ifdef __APPLE__ 656 notify(connect_started_notify, 0); 657 link_up_done = 0; 658 redialingcount = 0; 659 redialingalternate = 0; 660 do { 661 if (redialingcount || redialingalternate) { 662 if (the_channel->cleanup) 663 (*the_channel->cleanup)(); 664 if (redialalternate) 665 sys_publish_remoteaddress(redialingalternate ? altremoteaddress : remoteaddress); 666 } 667 668 if (redialtimer && redialingcount && !redialingalternate) { 669 if (hasbusystate) 670 new_phase(PHASE_WAITONBUSY); 671 sleep(redialtimer); 672 if (hasbusystate) 673 new_phase(PHASE_SERIALCONN); 674 } 675 if (kill_link) 676 break; 677 devfd = the_channel->connect(&t); 678 679 if (redialalternate) 680 redialingalternate = !redialingalternate; 681 if (!redialingalternate) 682 redialingcount++; 683 } 684 while ((busycode != -1) && (t == busycode) && (redialingcount <= redialcount) && !kill_link); 685#else 686 devfd = the_channel->connect(); 687#endif 688 if (devfd < 0) { 689#ifdef __APPLE__ 690 if (devfd == -2) { 691 if (conn_running) 692 /* Send the signal to the [dis]connector process(es) also */ 693 kill_my_pg(SIGHUP); 694 goto disconnect; 695 } 696 else { 697 notify(connect_fail_notify, t); 698#endif 699 goto fail; 700#ifdef __APPLE__ 701 } 702#endif 703 } 704#ifdef __APPLE__ 705 /* 706 link_up_done is there to give a chance to a device to implement 707 a double step connection. 708 For example, the serial connection will call directly link_up_hook 709 between the connection script and terminal script. 710 The link_up_hook hook can be used to ask for a password, that 711 could be used by a terminal script 712 */ 713 if (!link_up_done) { 714 if (link_up_hook) { 715 t = (*link_up_hook)(); 716 if (t == 0) { 717 // cancelled 718 status = EXIT_USER_REQUEST; 719 goto disconnect; 720 } 721 } 722 link_up_done = 1; 723 } 724 notify(connect_success_notify, 0); 725#endif 726 727#ifdef __APPLE__ 728 /* republish the remote address in case the connector has changed it */ 729 sys_publish_remoteaddress(remoteaddress); 730#endif 731 732 /* set up the serial device as a ppp interface */ 733#ifdef USE_TDB 734 tdb_writelock(pppdb); 735#endif 736 fd_ppp = the_channel->establish_ppp(devfd); 737 if (fd_ppp < 0) { 738#ifdef USE_TDB 739 tdb_writeunlock(pppdb); 740#endif 741 status = EXIT_FATAL_ERROR; 742 goto disconnect; 743 } 744 /* create the pid file, now that we've obtained a ppp interface */ 745 if (!demand) 746 create_linkpidfile(getpid()); 747 748 if (!demand && ifunit >= 0) 749 set_ifunit(1); 750#ifdef USE_TDB 751 tdb_writeunlock(pppdb); 752#endif 753 754 /* 755 * Start opening the connection and wait for 756 * incoming events (reply, timeout, etc.). 757 */ 758 if (ifunit >= 0) 759 notice("Connect: %s <--> %s", ifname, ppp_devnam); 760 else 761 notice("Starting negotiation on %s", ppp_devnam); 762 gettimeofday(&start_time, NULL); 763 script_unsetenv("CONNECT_TIME"); 764 script_unsetenv("BYTES_SENT"); 765 script_unsetenv("BYTES_RCVD"); 766 lcp_lowerup(0); 767 768 add_fd(fd_ppp); 769 lcp_open(0); /* Start protocol */ 770 status = EXIT_NEGOTIATION_FAILED; 771 new_phase(PHASE_ESTABLISH); 772 while (phase != PHASE_DEAD) { 773 handle_events(); 774 get_input(); 775#ifdef __APPLE__ 776 if (stop_link) { 777 if (phase == PHASE_RUNNING) { 778 new_phase(PHASE_ONHOLD); 779 ppp_hold(0); 780 auth_hold(0); 781 for (i = 0; (protp = protocols[i]) != NULL; ++i) 782 if (protp->hold != NULL) 783 (*protp->hold)(0); 784 notify(stop_notify, 0); 785 } 786 } 787 if (cont_link) { 788 if (phase == PHASE_ONHOLD) { 789 new_phase(PHASE_RUNNING); 790 ppp_cont(0); 791 auth_cont(0); 792 for (i = 0; (protp = protocols[i]) != NULL; ++i) 793 if (protp->cont != NULL) 794 (*protp->cont)(0); 795 notify(cont_notify, 0); 796 } 797 } 798#endif 799 if (kill_link) { 800#ifdef __APPLE__ 801 if (do_modem_hungup || stop_link || phase == PHASE_ONHOLD) { 802 if (do_modem_hungup) { 803 notice("Modem hangup"); 804 do_modem_hungup = 0; 805 } 806 hungup = 1; 807 lcp_lowerdown(0); 808 link_terminated(0); 809 } 810#endif 811 lcp_close(0, "User request"); 812 } 813 if (open_ccp_flag) { 814 if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { 815 ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ 816 (*ccp_protent.open)(0); 817 } 818 } 819#ifdef __APPLE__ 820 sys_runloop(); 821#endif 822 } 823 824 print_link_stats(); 825 826 /* 827 * Delete pid file before disestablishing ppp. Otherwise it 828 * can happen that another pppd gets the same unit and then 829 * we delete its pid file. 830 */ 831 if (!demand) { 832 if (pidfilename[0] != 0 833 && unlink(pidfilename) < 0 && errno != ENOENT) 834 warning("unable to delete pid file %s: %m", pidfilename); 835 pidfilename[0] = 0; 836 } 837 838 /* 839 * If we may want to bring the link up again, transfer 840 * the ppp unit back to the loopback. Set the 841 * real serial device back to its normal mode of operation. 842 */ 843 remove_fd(fd_ppp); 844 clean_check(); 845 the_channel->disestablish_ppp(devfd); 846 fd_ppp = -1; 847 if (!hungup) 848 lcp_lowerdown(0); 849 if (!demand) 850 script_unsetenv("IFNAME"); 851 852 /* 853 * Run disconnector script, if requested. 854 * XXX we may not be able to do this if the line has hung up! 855 */ 856 disconnect: 857 new_phase(PHASE_DISCONNECT); 858#ifdef __APPLE__ 859 notify(disconnect_started_notify, status); 860#endif 861 if (the_channel->disconnect) 862 the_channel->disconnect(); 863#ifdef __APPLE__ 864 notify(disconnect_done_notify, status); 865#endif 866 fail: 867#ifdef __APPLE__ 868 if (phase != PHASE_DISCONNECT) 869 new_phase(PHASE_DISCONNECT); 870#endif 871 if (the_channel->cleanup) 872 (*the_channel->cleanup)(); 873#ifdef __APPLE__ 874 end: 875#endif 876#ifdef __APPLE__ 877 sys_statusnotify(); 878#endif 879 880 if (!demand) { 881 if (pidfilename[0] != 0 882 && unlink(pidfilename) < 0 && errno != ENOENT) 883 warning("unable to delete pid file %s: %m", pidfilename); 884 pidfilename[0] = 0; 885 } 886 887 if (!persist || (maxfail > 0 && unsuccess >= maxfail)) 888 break; 889 890 if (demand) 891 demand_discard(); 892#ifdef __APPLE__ 893 hold: 894#endif 895 t = need_holdoff? holdoff: 0; 896 if (holdoff_hook) 897 t = (*holdoff_hook)(); 898 if (t > 0) { 899 new_phase(PHASE_HOLDOFF); 900 TIMEOUT(holdoff_end, NULL, t); 901 /* clear kill_link related signal flags */ 902 got_sighup = got_sigterm = 0; 903 do { 904 handle_events(); 905 if (kill_link) { 906 new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ 907 } 908 } while (phase == PHASE_HOLDOFF); 909 if (!persist) 910 break; 911 } 912 } 913 914 /* Wait for scripts to finish */ 915 /* XXX should have a timeout here */ 916 while (n_children > 0) { 917 if (debug) { 918 struct subprocess *chp; 919 dbglog("Waiting for %d child processes...", n_children); 920 for (chp = children; chp != NULL; chp = chp->next) 921 dbglog(" script %s, pid %d", chp->prog, chp->pid); 922 } 923 if (reap_kids(1) < 0) 924 break; 925 } 926 927 die(status); 928 return 0; 929} 930 931/* 932 * control fron controller - Read a string of commandd from controller file descriptor, 933 * and interpret them. 934 */ 935void 936ppp_control() 937{ 938 int newline, c, flags; 939 char cmd[MAXWORDLEN]; 940 941 /* set the file descriptor in non blocking mode */ 942 flags = fcntl(controlfd, F_GETFL); 943 if (flags == -1 944 || fcntl(controlfd, F_SETFL, flags | O_NONBLOCK) == -1) { 945 warning("Couldn't set controlfd to nonblock: %m"); 946 return; 947 } 948 /* skip chars until beginning of next command */ 949 for (;;) { 950 c = getc(controlfile); 951 if (c == EOF) 952 break; 953 if (c == '[') 954 ungetc(c, controlfile); 955 break; 956 } 957 /* reset blocking mode */ 958 fcntl(controlfd, F_SETFL, flags); 959 960 /* we get eof if controller exits */ 961 if (feof(controlfile)) 962 die(1); 963 964 /* clear error */ 965 clearerr(controlfile); 966 967 if (c != '[') 968 return; 969 970 /* now ready to read the command */ 971 while (getword(controlfile, cmd, &newline, "controller")) { 972 973 if (!strcmp(cmd, "[OPTIONS]")) { 974 options_from_controller(); 975 if (dump_options) { 976 init_pr_log(NULL, LOG_INFO); 977 print_options(pr_log, NULL); 978 end_pr_log(); 979 } 980 return; 981 } 982 983 if (!strcmp(cmd, "[DISCONNECT]")) { 984 error("[DISCONNECT]"); 985 hup(SIGHUP); 986 continue; 987 } 988 989 if (!strcmp(cmd, "[TERMINATE]")) { 990 error("[TERMINATE]"); 991 term(SIGTERM); 992 continue; 993 } 994 995#ifdef __APPLE__ 996 if (!strcmp(cmd, "[INSTALL]")) { 997 sys_install(); 998 return; 999 } 1000 1001 if (!strcmp(cmd, "[UNINSTALL]")) { 1002 sys_uninstall(); 1003 return; 1004 } 1005#endif 1006 1007/* 1008 if (!strcmp(cmd, "[SUSPEND]")) { 1009 error("[SUSPEND]"); 1010 stop(SIGTSTP); 1011 continue; 1012 } 1013 1014 if (!strcmp(cmd, "[RESUME]")) { 1015 error("[RESUME]"); 1016 cont(SIGCONT); 1017 continue; 1018 } 1019*/ 1020 1021 if (!strcmp(cmd, "[EOP]")) { 1022 break; 1023 } 1024 1025 } 1026 1027 // got EOF 1028 die(1); 1029} 1030 1031/* 1032 * handle_events - wait for something to happen and respond to it. 1033 */ 1034static void 1035handle_events() 1036{ 1037 struct timeval timo; 1038 sigset_t mask; 1039 1040 1041 kill_link = open_ccp_flag = 0; 1042#ifdef __APPLE__ 1043 stop_link = cont_link = 0; 1044#endif 1045 if (sigsetjmp(sigjmp, 1) == 0) { 1046 sigprocmask(SIG_BLOCK, &mask, NULL); 1047 if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld 1048#ifdef __APPLE__ 1049 || got_sigtstp || got_sigcont 1050#endif 1051 ) { 1052 sigprocmask(SIG_UNBLOCK, &mask, NULL); 1053 } else { 1054 waiting = 1; 1055 sigprocmask(SIG_UNBLOCK, &mask, NULL); 1056 wait_input(timeleft(&timo)); 1057#ifdef __APPLE__ 1058 if (wait_input_hook) 1059 (*wait_input_hook)(); 1060 if (the_channel->wait_input) 1061 the_channel->wait_input(); 1062#endif 1063 } 1064 } 1065#ifdef __APPLE__ 1066 if (controlfd !=-1 && is_ready_fd(controlfd)) { 1067 ppp_control(); 1068 } 1069#endif 1070 waiting = 0; 1071 calltimeout(); 1072#ifdef __APPLE__ 1073 if (got_sigtstp) { 1074 info("Stopping on signal %d.", got_sigtstp); 1075 stop_link = 1; 1076 got_sigtstp = 0; 1077 } 1078 if (got_sigcont) { 1079 info("Resuming on signal %d.", got_sigcont); 1080 cont_link = 1; 1081 got_sigcont = 0; 1082 } 1083#endif 1084 if (got_sighup) { 1085 info("Hangup (SIGHUP)"); 1086 kill_link = 1; 1087 got_sighup = 0; 1088 if (status != EXIT_HANGUP) 1089 status = EXIT_USER_REQUEST; 1090 } 1091 if (got_sigterm) { 1092 info("Terminating on signal %d.", got_sigterm); 1093 kill_link = 1; 1094 persist = 0; 1095 status = EXIT_USER_REQUEST; 1096 got_sigterm = 0; 1097 } 1098 if (got_sigchld) { 1099 reap_kids(0); /* Don't leave dead kids lying around */ 1100 got_sigchld = 0; 1101 } 1102 if (got_sigusr2) { 1103 open_ccp_flag = 1; 1104 got_sigusr2 = 0; 1105 } 1106} 1107 1108/* 1109 * setup_signals - initialize signal handling. 1110 */ 1111static void 1112setup_signals() 1113{ 1114 struct sigaction sa; 1115 sigset_t mask; 1116 1117 /* 1118 * Compute mask of all interesting signals and install signal handlers 1119 * for each. Only one signal handler may be active at a time. Therefore, 1120 * all other signals should be masked when any handler is executing. 1121 */ 1122 sigemptyset(&mask); 1123 sigaddset(&mask, SIGHUP); 1124 sigaddset(&mask, SIGINT); 1125 sigaddset(&mask, SIGTERM); 1126 sigaddset(&mask, SIGCHLD); 1127 sigaddset(&mask, SIGUSR2); 1128#ifdef __APPLE__ 1129 sigaddset(&mask, SIGTSTP); 1130 sigaddset(&mask, SIGCONT); 1131#endif 1132 1133#define SIGNAL(s, handler) do { \ 1134 sa.sa_handler = handler; \ 1135 if (sigaction(s, &sa, NULL) < 0) \ 1136 fatal("Couldn't establish signal handler (%d): %m", s); \ 1137 } while (0) 1138 1139 sa.sa_mask = mask; 1140 sa.sa_flags = 0; 1141 SIGNAL(SIGHUP, hup); /* Hangup */ 1142 SIGNAL(SIGINT, term); /* Interrupt */ 1143 SIGNAL(SIGTERM, term); /* Terminate */ 1144 SIGNAL(SIGCHLD, chld); 1145#ifdef __APPLE__ 1146 SIGNAL(SIGTSTP, stop); /* stop all activity */ 1147 SIGNAL(SIGCONT, cont); /* resume activity */ 1148#endif 1149 1150 SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ 1151 SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ 1152 1153 /* 1154 * Install a handler for other signals which would otherwise 1155 * cause pppd to exit without cleaning up. 1156 */ 1157 SIGNAL(SIGABRT, bad_signal); 1158 SIGNAL(SIGALRM, bad_signal); 1159 SIGNAL(SIGFPE, bad_signal); 1160 SIGNAL(SIGILL, bad_signal); 1161 SIGNAL(SIGPIPE, bad_signal); 1162 SIGNAL(SIGQUIT, bad_signal); 1163 SIGNAL(SIGSEGV, bad_signal); 1164#ifdef SIGBUS 1165 SIGNAL(SIGBUS, bad_signal); 1166#endif 1167#ifdef SIGEMT 1168 SIGNAL(SIGEMT, bad_signal); 1169#endif 1170#ifdef SIGPOLL 1171 SIGNAL(SIGPOLL, bad_signal); 1172#endif 1173#ifdef SIGPROF 1174 SIGNAL(SIGPROF, bad_signal); 1175#endif 1176#ifdef SIGSYS 1177 SIGNAL(SIGSYS, bad_signal); 1178#endif 1179#ifdef SIGTRAP 1180 SIGNAL(SIGTRAP, bad_signal); 1181#endif 1182#ifdef SIGVTALRM 1183 SIGNAL(SIGVTALRM, bad_signal); 1184#endif 1185#ifdef SIGXCPU 1186 SIGNAL(SIGXCPU, bad_signal); 1187#endif 1188#ifdef SIGXFSZ 1189 SIGNAL(SIGXFSZ, bad_signal); 1190#endif 1191 1192 /* 1193 * Apparently we can get a SIGPIPE when we call syslog, if 1194 * syslogd has died and been restarted. Ignoring it seems 1195 * be sufficient. 1196 */ 1197#ifndef __APPLE__ 1198 signal(SIGPIPE, SIG_IGN); 1199#endif 1200} 1201 1202/* 1203 * set_ifunit - do things we need to do once we know which ppp 1204 * unit we are using. 1205 */ 1206void 1207set_ifunit(iskey) 1208 int iskey; 1209{ 1210 info("Using interface %s%d", PPP_DRV_NAME, ifunit); 1211 slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); 1212 script_setenv("IFNAME", ifname, iskey); 1213 if (iskey) { 1214 create_pidfile(getpid()); /* write pid to file */ 1215 create_linkpidfile(getpid()); 1216 } 1217} 1218 1219/* 1220 * detach - detach us from the controlling terminal. 1221 */ 1222void 1223detach() 1224{ 1225 int pid; 1226 char numbuf[16]; 1227 int pipefd[2]; 1228 1229 if (detached) 1230 return; 1231 if (pipe(pipefd) == -1) 1232 pipefd[0] = pipefd[1] = -1; 1233 if ((pid = fork()) < 0) { 1234 error("Couldn't detach (fork failed: %m)"); 1235 die(1); /* or just return? */ 1236 } 1237 if (pid != 0) { 1238 /* parent */ 1239 notify(pidchange, pid); 1240 /* update pid files if they have been written already */ 1241 if (pidfilename[0]) 1242 create_pidfile(pid); 1243 if (linkpidfile[0]) 1244 create_linkpidfile(pid); 1245 exit(0); /* parent dies */ 1246 } 1247 setsid(); 1248 chdir("/"); 1249 dup2(fd_devnull, 0); 1250 dup2(fd_devnull, 1); 1251 dup2(fd_devnull, 2); 1252 detached = 1; 1253 if (log_default) 1254 log_to_fd = -1; 1255 slprintf(numbuf, sizeof(numbuf), "%d", getpid()); 1256 script_setenv("PPPD_PID", numbuf, 1); 1257 1258 /* wait for parent to finish updating pid & lock files and die */ 1259 close(pipefd[1]); 1260 complete_read(pipefd[0], numbuf, 1); 1261 close(pipefd[0]); 1262 1263#ifdef __APPLE__ 1264 sys_reinit(); 1265#endif 1266} 1267 1268/* 1269 * reopen_log - (re)open our connection to syslog. 1270 */ 1271void 1272reopen_log() 1273{ 1274#ifdef ULTRIX 1275 openlog("pppd", LOG_PID); 1276#else 1277 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); 1278 setlogmask(LOG_UPTO(LOG_INFO)); 1279#endif 1280} 1281 1282/* 1283 * Create a file containing our process ID. 1284 */ 1285static void 1286create_pidfile(pid) 1287 int pid; 1288{ 1289 FILE *pidfile; 1290 1291 slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid", 1292 _PATH_VARRUN, ifname); 1293 if ((pidfile = fopen(pidfilename, "w")) != NULL) { 1294 fprintf(pidfile, "%d\n", pid); 1295 (void) fclose(pidfile); 1296 } else { 1297 error("Failed to create pid file %s: %m", pidfilename); 1298 pidfilename[0] = 0; 1299 } 1300} 1301 1302static void 1303create_linkpidfile(pid) 1304 int pid; 1305{ 1306 FILE *pidfile; 1307 1308 if (linkname[0] == 0) 1309 return; 1310 script_setenv("LINKNAME", linkname, 1); 1311 slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", 1312 _PATH_VARRUN, linkname); 1313 if ((pidfile = fopen(linkpidfile, "w")) != NULL) { 1314 fprintf(pidfile, "%d\n", pid); 1315 if (ifname[0]) 1316 fprintf(pidfile, "%s\n", ifname); 1317 (void) fclose(pidfile); 1318 } else { 1319 error("Failed to create pid file %s: %m", linkpidfile); 1320 linkpidfile[0] = 0; 1321 } 1322} 1323 1324/* 1325 * holdoff_end - called via a timeout when the holdoff period ends. 1326 */ 1327static void 1328holdoff_end(arg) 1329 void *arg; 1330{ 1331 new_phase(PHASE_DORMANT); 1332} 1333 1334/* List of protocol names, to make our messages a little more informative. */ 1335struct protocol_list { 1336 u_short proto; 1337 const char *name; 1338} protocol_list[] = { 1339 { 0x21, "IP" }, 1340 { 0x23, "OSI Network Layer" }, 1341 { 0x25, "Xerox NS IDP" }, 1342 { 0x27, "DECnet Phase IV" }, 1343 { 0x29, "Appletalk" }, 1344 { 0x2b, "Novell IPX" }, 1345 { 0x2d, "VJ compressed TCP/IP" }, 1346 { 0x2f, "VJ uncompressed TCP/IP" }, 1347 { 0x31, "Bridging PDU" }, 1348 { 0x33, "Stream Protocol ST-II" }, 1349 { 0x35, "Banyan Vines" }, 1350 { 0x39, "AppleTalk EDDP" }, 1351 { 0x3b, "AppleTalk SmartBuffered" }, 1352 { 0x3d, "Multi-Link" }, 1353 { 0x3f, "NETBIOS Framing" }, 1354 { 0x41, "Cisco Systems" }, 1355 { 0x43, "Ascom Timeplex" }, 1356 { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, 1357 { 0x47, "DCA Remote Lan" }, 1358 { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, 1359 { 0x4b, "SNA over 802.2" }, 1360 { 0x4d, "SNA" }, 1361 { 0x4f, "IP6 Header Compression" }, 1362 { 0x6f, "Stampede Bridging" }, 1363 { 0xfb, "single-link compression" }, 1364 { 0xfd, "1st choice compression" }, 1365 { 0x0201, "802.1d Hello Packets" }, 1366 { 0x0203, "IBM Source Routing BPDU" }, 1367 { 0x0205, "DEC LANBridge100 Spanning Tree" }, 1368 { 0x0231, "Luxcom" }, 1369 { 0x0233, "Sigma Network Systems" }, 1370 { 0x0235, "Apple Client Server Protocol" }, 1371 { 0x8021, "Internet Protocol Control Protocol" }, 1372 { 0x8023, "OSI Network Layer Control Protocol" }, 1373 { 0x8025, "Xerox NS IDP Control Protocol" }, 1374 { 0x8027, "DECnet Phase IV Control Protocol" }, 1375 { 0x8029, "Appletalk Control Protocol" }, 1376 { 0x802b, "Novell IPX Control Protocol" }, 1377 { 0x8031, "Bridging NCP" }, 1378 { 0x8033, "Stream Protocol Control Protocol" }, 1379 { 0x8035, "Banyan Vines Control Protocol" }, 1380 { 0x803d, "Multi-Link Control Protocol" }, 1381 { 0x803f, "NETBIOS Framing Control Protocol" }, 1382 { 0x8041, "Cisco Systems Control Protocol" }, 1383 { 0x8043, "Ascom Timeplex" }, 1384 { 0x8045, "Fujitsu LBLB Control Protocol" }, 1385 { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, 1386 { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, 1387 { 0x804b, "SNA over 802.2 Control Protocol" }, 1388 { 0x804d, "SNA Control Protocol" }, 1389 { 0x804f, "IP6 Header Compression Control Protocol" }, 1390 { 0x006f, "Stampede Bridging Control Protocol" }, 1391 { 0x80fb, "Single Link Compression Control Protocol" }, 1392 { 0x80fd, "Compression Control Protocol" }, 1393 { 0x8235, "Apple Client Server Control Protocol" }, 1394 { 0xc021, "Link Control Protocol" }, 1395 { 0xc023, "Password Authentication Protocol" }, 1396 { 0xc025, "Link Quality Report" }, 1397 { 0xc027, "Shiva Password Authentication Protocol" }, 1398 { 0xc029, "CallBack Control Protocol (CBCP)" }, 1399 { 0xc081, "Container Control Protocol" }, 1400 { 0xc223, "Challenge Handshake Authentication Protocol" }, 1401 { 0xc281, "Proprietary Authentication Protocol" }, 1402 { 0, NULL }, 1403}; 1404 1405/* 1406 * protocol_name - find a name for a PPP protocol. 1407 */ 1408const char * 1409protocol_name(proto) 1410 int proto; 1411{ 1412 struct protocol_list *lp; 1413 1414 for (lp = protocol_list; lp->proto != 0; ++lp) 1415 if (proto == lp->proto) 1416 return lp->name; 1417 return NULL; 1418} 1419 1420/* 1421 * get_input - called when incoming data is available. 1422 */ 1423static void 1424get_input() 1425{ 1426 int len, i; 1427 u_char *p; 1428 u_short protocol; 1429 struct protent *protp; 1430 1431 p = inpacket_buf; /* point to beginning of packet buffer */ 1432 1433 len = read_packet(inpacket_buf); 1434 if (len < 0) 1435 return; 1436 1437 if (len == 0) { 1438 notice("Modem hangup"); 1439 hungup = 1; 1440#ifdef __APPLE__ 1441 if (status != EXIT_USER_REQUEST) 1442#endif 1443 status = EXIT_HANGUP; 1444 lcp_lowerdown(0); /* serial link is no longer available */ 1445 link_terminated(0); 1446 return; 1447 } 1448 1449 if (len < PPP_HDRLEN) { 1450#ifdef __APPLE__ 1451 if (debug > 1) 1452#endif 1453 dbglog("received short packet:%.*B", len, p); 1454 return; 1455 } 1456 1457 dump_packet("rcvd", p, len); 1458 if (snoop_recv_hook) snoop_recv_hook(p, len); 1459 1460 p += 2; /* Skip address and control */ 1461 GETSHORT(protocol, p); 1462 len -= PPP_HDRLEN; 1463 1464 /* 1465 * Toss all non-LCP packets unless LCP is OPEN. 1466 */ 1467 if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { 1468#ifdef __APPLE__ 1469 if (debug > 1) 1470#endif 1471 dbglog("Discarded non-LCP packet when LCP not open"); 1472 return; 1473 } 1474 1475 /* 1476 * Until we get past the authentication phase, toss all packets 1477 * except LCP, LQR and authentication packets. 1478 */ 1479 if (phase <= PHASE_AUTHENTICATE 1480 && !(protocol == PPP_LCP || protocol == PPP_LQR 1481 || protocol == PPP_PAP || protocol == PPP_CHAP || 1482 protocol == PPP_EAP)) { 1483#ifdef __APPLE__ 1484 if (unexpected_network_packet(0, protocol)) { 1485#endif 1486 1487#ifdef __APPLE__ 1488 if (debug > 1) 1489#endif 1490 dbglog("discarding proto 0x%x in phase %d", 1491 protocol, phase); 1492 return; 1493#ifdef __APPLE__ 1494 } 1495#endif 1496 } 1497 1498 /* 1499 * Upcall the proper protocol input routine. 1500 */ 1501 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 1502 if (protp->protocol == protocol && protp->enabled_flag) { 1503 (*protp->input)(0, p, len); 1504 return; 1505 } 1506#ifdef __APPLE__ 1507 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag) { 1508 if (protp->datainput != NULL) { 1509 (*protp->datainput)(0, p, len); 1510 return; 1511 } 1512 if (protp->state != NULL && (protp->state(0) == OPENED)) { 1513 // pppd receives data for a protocol in opened state. 1514 // this can happen if the peer sends packets too fast after its control protocol 1515 // reaches the opened state, pppd hasn't had time yet to process the control protocol 1516 // packet, and the kernel is still configured to reject the data packet. 1517 // in this case, just ignore the packet. 1518 // if this happens for an other reason, then there is probably a bug somewhere 1519 MAINDEBUG(("Data packet of protocol 0x%x received, with control prococol in opened state", protocol)); 1520 return; 1521 } 1522 } 1523#else 1524 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag 1525 && protp->datainput != NULL) { 1526 (*protp->datainput)(0, p, len); 1527 return; 1528 } 1529#endif 1530 } 1531 1532 if (debug) { 1533 const char *pname = protocol_name(protocol); 1534 if (pname != NULL) 1535 warning("Unsupported protocol '%s' (0x%x) received", pname, protocol); 1536 else 1537 warning("Unsupported protocol 0x%x received", protocol); 1538 } 1539 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); 1540} 1541 1542/* 1543 * ppp_send_config - configure the transmit-side characteristics of 1544 * the ppp interface. Returns -1, indicating an error, if the channel 1545 * send_config procedure called error() (or incremented error_count 1546 * itself), otherwise 0. 1547 */ 1548int 1549ppp_send_config(unit, mtu, accm, pcomp, accomp) 1550 int unit, mtu; 1551 u_int32_t accm; 1552 int pcomp, accomp; 1553{ 1554 int errs; 1555 1556 if (the_channel->send_config == NULL) 1557 return 0; 1558 errs = error_count; 1559 (*the_channel->send_config)(mtu, accm, pcomp, accomp); 1560 return (error_count != errs)? -1: 0; 1561} 1562 1563/* 1564 * ppp_recv_config - configure the receive-side characteristics of 1565 * the ppp interface. Returns -1, indicating an error, if the channel 1566 * recv_config procedure called error() (or incremented error_count 1567 * itself), otherwise 0. 1568 */ 1569int 1570ppp_recv_config(unit, mru, accm, pcomp, accomp) 1571 int unit, mru; 1572 u_int32_t accm; 1573 int pcomp, accomp; 1574{ 1575 int errs; 1576 1577 if (the_channel->recv_config == NULL) 1578 return 0; 1579 errs = error_count; 1580 (*the_channel->recv_config)(mru, accm, pcomp, accomp); 1581 return (error_count != errs)? -1: 0; 1582} 1583 1584/* 1585 * new_phase - signal the start of a new phase of pppd's operation. 1586 */ 1587void 1588new_phase(p) 1589 int p; 1590{ 1591 phase = p; 1592 if (new_phase_hook) 1593 (*new_phase_hook)(p); 1594 notify(phasechange, p); 1595} 1596 1597/* 1598 * die - clean up state and exit with the specified status. 1599 */ 1600void 1601die(status) 1602 int status; 1603{ 1604#ifndef __APPLE__ 1605 print_link_stats(); 1606#endif 1607 cleanup(); 1608 notify(exitnotify, status); 1609 sys_log(LOG_INFO, "Exit."); 1610 exit(status); 1611} 1612 1613/* 1614 * cleanup - restore anything which needs to be restored before we exit 1615 */ 1616/* ARGSUSED */ 1617static void 1618cleanup() 1619{ 1620 sys_cleanup(); 1621 1622 if (fd_ppp >= 0) 1623 the_channel->disestablish_ppp(devfd); 1624 if (the_channel->cleanup) 1625 (*the_channel->cleanup)(); 1626 1627 if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) 1628 warning("unable to delete pid file %s: %m", pidfilename); 1629 pidfilename[0] = 0; 1630 if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) 1631 warning("unable to delete pid file %s: %m", linkpidfile); 1632 linkpidfile[0] = 0; 1633 1634#ifdef USE_TDB 1635 if (pppdb != NULL) 1636 cleanup_db(); 1637#endif 1638 1639} 1640 1641void 1642print_link_stats() 1643{ 1644 /* 1645 * Print connect time and statistics. 1646 */ 1647 if (link_stats_valid) { 1648 int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ 1649 info("Connect time %d.%d minutes.", t/10, t%10); 1650 info("Sent %u bytes, received %u bytes.", 1651 link_stats.bytes_out, link_stats.bytes_in); 1652 } 1653} 1654 1655/* 1656 * update_link_stats - get stats at link termination. 1657 */ 1658void 1659update_link_stats(u) 1660 int u; 1661{ 1662 struct timeval now; 1663 char numbuf[32]; 1664 1665 if (!get_ppp_stats(u, &link_stats) 1666 || gettimeofday(&now, NULL) < 0) 1667 return; 1668 link_connect_time = now.tv_sec - start_time.tv_sec; 1669 link_stats_valid = 1; 1670 1671 slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); 1672 script_setenv("CONNECT_TIME", numbuf, 0); 1673 slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out); 1674 script_setenv("BYTES_SENT", numbuf, 0); 1675 slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in); 1676 script_setenv("BYTES_RCVD", numbuf, 0); 1677} 1678 1679 1680struct callout { 1681 struct timeval c_time; /* time at which to call routine */ 1682 void *c_arg; /* argument to routine */ 1683 void (*c_func) __P((void *)); /* routine */ 1684 struct callout *c_next; 1685}; 1686 1687static struct callout *callout = NULL; /* Callout list */ 1688static struct timeval timenow; /* Current time */ 1689 1690/* 1691 * timeout - Schedule a timeout. 1692 */ 1693void 1694timeout(func, arg, secs, usecs) 1695 void (*func) __P((void *)); 1696 void *arg; 1697 int secs, usecs; 1698{ 1699 struct callout *newp, *p, **pp; 1700 1701 MAINDEBUG(("Timeout %p:%p in %d.%03d seconds.", func, arg, 1702 secs, usecs/1000)); 1703 1704 /* 1705 * Allocate timeout. 1706 */ 1707 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) 1708 fatal("Out of memory in timeout()!"); 1709 newp->c_arg = arg; 1710 newp->c_func = func; 1711#ifdef __APPLE__ 1712 // timeout get screwed up if you change the current time of the machine... 1713 // use absolute time instead, as we are just interested in deltas, not actual time. 1714 getabsolutetime(&timenow); 1715#else 1716 gettimeofday(&timenow, NULL); 1717#endif 1718 newp->c_time.tv_sec = timenow.tv_sec + secs; 1719 newp->c_time.tv_usec = timenow.tv_usec + usecs; 1720 if (newp->c_time.tv_usec >= 1000000) { 1721 newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000; 1722 newp->c_time.tv_usec %= 1000000; 1723 } 1724 1725 /* 1726 * Find correct place and link it in. 1727 */ 1728 for (pp = &callout; (p = *pp); pp = &p->c_next) 1729 if (newp->c_time.tv_sec < p->c_time.tv_sec 1730 || (newp->c_time.tv_sec == p->c_time.tv_sec 1731 && newp->c_time.tv_usec < p->c_time.tv_usec)) 1732 break; 1733 newp->c_next = p; 1734 *pp = newp; 1735} 1736 1737 1738/* 1739 * untimeout - Unschedule a timeout. 1740 */ 1741void 1742untimeout(func, arg) 1743 void (*func) __P((void *)); 1744 void *arg; 1745{ 1746 struct callout **copp, *freep; 1747 1748 MAINDEBUG(("Untimeout %p:%p.", func, arg)); 1749 1750 /* 1751 * Find first matching timeout and remove it from the list. 1752 */ 1753 for (copp = &callout; (freep = *copp); copp = &freep->c_next) 1754 if (freep->c_func == func && freep->c_arg == arg) { 1755 *copp = freep->c_next; 1756 free((char *) freep); 1757 break; 1758 } 1759} 1760 1761 1762/* 1763 * calltimeout - Call any timeout routines which are now due. 1764 */ 1765static void 1766calltimeout() 1767{ 1768 struct callout *p; 1769 1770 while (callout != NULL) { 1771 p = callout; 1772 1773#ifdef __APPLE__ 1774 if (getabsolutetime(&timenow) < 0) 1775#else 1776 if (gettimeofday(&timenow, NULL) < 0) 1777#endif 1778 fatal("Failed to get time of day: %m"); 1779 if (!(p->c_time.tv_sec < timenow.tv_sec 1780 || (p->c_time.tv_sec == timenow.tv_sec 1781 && p->c_time.tv_usec <= timenow.tv_usec))) 1782 break; /* no, it's not time yet */ 1783 1784 callout = p->c_next; 1785 (*p->c_func)(p->c_arg); 1786 1787 free((char *) p); 1788 } 1789} 1790 1791 1792/* 1793 * timeleft - return the length of time until the next timeout is due. 1794 */ 1795static struct timeval * 1796timeleft(tvp) 1797 struct timeval *tvp; 1798{ 1799 if (callout == NULL) 1800 return NULL; 1801 1802#ifdef __APPLE__ 1803 getabsolutetime(&timenow); 1804#else 1805 gettimeofday(&timenow, NULL); 1806#endif 1807 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; 1808 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; 1809 if (tvp->tv_usec < 0) { 1810 tvp->tv_usec += 1000000; 1811 tvp->tv_sec -= 1; 1812 } 1813 if (tvp->tv_sec < 0) 1814 tvp->tv_sec = tvp->tv_usec = 0; 1815 1816 return tvp; 1817} 1818 1819 1820/* 1821 * kill_my_pg - send a signal to our process group, and ignore it ourselves. 1822 */ 1823static void 1824kill_my_pg(sig) 1825 int sig; 1826{ 1827 struct sigaction act, oldact; 1828 1829 act.sa_handler = SIG_IGN; 1830 act.sa_flags = 0; 1831 sigaction(sig, &act, &oldact); 1832 kill(0, sig); 1833 sigaction(sig, &oldact, NULL); 1834} 1835 1836 1837/* 1838 * hup - Catch SIGHUP signal. 1839 * 1840 * Indicates that the physical layer has been disconnected. 1841 * We don't rely on this indication; if the user has sent this 1842 * signal, we just take the link down. 1843 */ 1844static void 1845hup(sig) 1846 int sig; 1847{ 1848#ifdef __APPLE__ 1849 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 1850 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 1851 /* <rdar://10258474> */ 1852 return; 1853 } 1854#endif 1855 got_sighup = sig; 1856 1857#ifdef __APPLE__ 1858 // connectors test that flag 1859 // handle event is not called when we are in the connect stage 1860 kill_link = 1; 1861#endif 1862 1863 if (conn_running) 1864 /* Send the signal to the [dis]connector process(es) also */ 1865 kill_my_pg(sig); 1866 notify(sigreceived, sig); 1867#ifdef __APPLE__ 1868 if (!hungup) 1869 status = EXIT_USER_REQUEST; 1870#endif 1871 if (waiting) 1872 siglongjmp(sigjmp, 1); 1873} 1874 1875 1876/* 1877 * term - Catch SIGTERM signal and SIGINT signal (^C/del). 1878 * 1879 * Indicates that we should initiate a graceful disconnect and exit. 1880 */ 1881/*ARGSUSED*/ 1882static void 1883term(sig) 1884 int sig; 1885{ 1886#ifdef __APPLE__ 1887 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 1888 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 1889 /* <rdar://10258474> */ 1890 return; 1891 } 1892#endif 1893 got_sigterm = sig; 1894 1895#ifdef __APPLE__ 1896 // connectors test that flag 1897 // handle event is not called when we are in the connect stage 1898 kill_link = 1; 1899 persist = 0; 1900 status = EXIT_USER_REQUEST; 1901#endif 1902 1903 if (conn_running) 1904 /* Send the signal to the [dis]connector process(es) also */ 1905 kill_my_pg(sig); 1906 notify(sigreceived, sig); 1907 if (waiting) 1908 siglongjmp(sigjmp, 1); 1909} 1910 1911 1912/* 1913 * chld - Catch SIGCHLD signal. 1914 * Sets a flag so we will call reap_kids in the mainline. 1915 */ 1916static void 1917chld(sig) 1918 int sig; 1919{ 1920#ifdef __APPLE__ 1921 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 1922 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 1923 /* <rdar://10258474> */ 1924 return; 1925 } 1926#endif 1927 got_sigchld = 1; 1928 if (waiting) 1929 siglongjmp(sigjmp, 1); 1930} 1931 1932/* 1933 * stop - Catch SIGTSTP signal. 1934 * 1935 * Indicates that the physical is gone "on hold". 1936 * Stop all activity until we get the SIGCONT signal 1937 * or until we take the line down. 1938 */ 1939static void 1940stop(sig) 1941 int sig; 1942{ 1943 1944#ifdef __APPLE__ 1945 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 1946 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 1947 /* <rdar://10258474> */ 1948 return; 1949 } 1950#endif 1951 got_sigtstp = sig; 1952 switch (phase) { 1953 case PHASE_ONHOLD: // already on hold 1954 break; 1955 case PHASE_RUNNING: // needs to stop connection 1956 break; 1957 default: // other states, simulate a sighup 1958 got_sighup = 1; 1959 if (conn_running) 1960 /* Send the signal to the [dis]connector process(es) also */ 1961 kill_my_pg(sig); 1962 } 1963 notify(sigreceived, sig); 1964 if (waiting) 1965 siglongjmp(sigjmp, 1); 1966} 1967 1968/* 1969 * cont - Catch SIGCONT signal. 1970 * 1971 * resume all previously stopped activities. 1972 * 1973 */ 1974static void 1975cont(sig) 1976 int sig; 1977{ 1978#ifdef __APPLE__ 1979 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 1980 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 1981 /* <rdar://10258474> */ 1982 return; 1983 } 1984#endif 1985 got_sigcont = sig; 1986 notify(sigreceived, sig); 1987 if (waiting) 1988 siglongjmp(sigjmp, 1); 1989} 1990 1991/* 1992 * toggle_debug - Catch SIGUSR1 signal. 1993 * 1994 * Toggle debug flag. 1995 */ 1996/*ARGSUSED*/ 1997static void 1998toggle_debug(sig) 1999 int sig; 2000{ 2001#ifdef __APPLE__ 2002 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 2003 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 2004 /* <rdar://10258474> */ 2005 return; 2006 } 2007#endif 2008 debug = !debug; 2009 if (debug) { 2010 setlogmask(LOG_UPTO(LOG_DEBUG)); 2011 } else { 2012 setlogmask(LOG_UPTO(LOG_WARNING)); 2013 } 2014} 2015 2016 2017/* 2018 * open_ccp - Catch SIGUSR2 signal. 2019 * 2020 * Try to (re)negotiate compression. 2021 */ 2022/*ARGSUSED*/ 2023static void 2024open_ccp(sig) 2025 int sig; 2026{ 2027#ifdef __APPLE__ 2028 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 2029 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 2030 /* <rdar://10258474> */ 2031 return; 2032 } 2033#endif 2034 got_sigusr2 = 1; 2035 if (waiting) 2036 siglongjmp(sigjmp, 1); 2037} 2038 2039 2040/* 2041 * bad_signal - We've caught a fatal signal. Clean up state and exit. 2042 */ 2043static void 2044bad_signal(sig) 2045 int sig; 2046{ 2047 static int crashed = 0; 2048 2049#ifdef __APPLE__ 2050 if (mainthread_id && !(pthread_equal(mainthread_id, pthread_self()))){ 2051 /* ignore signals if it's not the main thread, we will be dropping sigals but that's insignificant */ 2052 /* <rdar://10258474> */ 2053 return; 2054 } 2055#endif 2056 if (crashed) 2057 _exit(127); 2058 crashed = 1; 2059 error("Fatal signal %d", sig); 2060 if (conn_running) 2061 kill_my_pg(SIGTERM); 2062 notify(sigreceived, sig); 2063 die(127); 2064} 2065 2066/* 2067 * safe_fork - Create a child process. The child closes all the 2068 * file descriptors that we don't want to leak to a script. 2069 * The parent waits for the child to do this before returning. 2070 */ 2071pid_t 2072safe_fork() 2073{ 2074 pid_t pid; 2075 int pipefd[2]; 2076 char buf[1]; 2077 2078 if (pipe(pipefd) == -1) 2079 pipefd[0] = pipefd[1] = -1; 2080 pid = fork(); 2081 if (pid < 0) 2082 return -1; 2083 if (pid > 0) { 2084 close(pipefd[1]); 2085 /* this read() blocks until the close(pipefd[1]) below */ 2086 complete_read(pipefd[0], buf, 1); 2087 close(pipefd[0]); 2088 return pid; 2089 } 2090 sys_close(); 2091#ifdef __APPLE__ 2092 options_close(); 2093#endif 2094#ifdef USE_TDB 2095 tdb_close(pppdb); 2096#endif 2097 notify(fork_notifier, 0); 2098 close(pipefd[0]); 2099 /* this close unblocks the read() call above in the parent */ 2100 close(pipefd[1]); 2101 return 0; 2102} 2103 2104/* 2105 * device_script - run a program to talk to the specified fds 2106 * (e.g. to run the connector or disconnector script). 2107 * stderr gets connected to the log fd or to the _PATH_CONNERRS file. 2108 */ 2109#ifdef __APPLE__ 2110#define PPP_ARG_FD 3 2111int 2112device_script(program, in, out, dont_wait, program_uid, pipe_args, pipe_args_len) 2113 char *program; 2114 int in, out; 2115 int dont_wait; 2116 uid_t program_uid; 2117 char *pipe_args; 2118 int pipe_args_len; 2119#else 2120int 2121device_script(program, in, out, dont_wait) 2122 char *program; 2123 int in, out; 2124 int dont_wait; 2125#endif 2126{ 2127 int pid; 2128 int status = -1; 2129 int errfd; 2130 int fd; 2131 int fdp[2]; 2132 2133//error("device script '%s'\n", program); 2134 2135 fdp[0] = fdp[1] = -1; 2136 if (pipe_args) { 2137 if (pipe(fdp) == -1) { 2138 error("Failed to setup pipe with device script: %m"); 2139 return -1; 2140 } 2141 } 2142 2143 ++conn_running; 2144 pid = safe_fork(); 2145 2146 if (pid < 0) { 2147 --conn_running; 2148 error("Failed to create child process: %m"); 2149 return -1; 2150 } 2151 2152 if (pid > 0) { 2153 // running in parent 2154 // close read end of the pipe 2155 if (fdp[0] != -1) { 2156 close(fdp[0]); 2157 fdp[0] = -1; 2158 } 2159 // write args on the write end of the pipe, and close it 2160 if (fdp[1] != -1) { 2161 write(fdp[1], pipe_args, pipe_args_len); 2162 close(fdp[1]); 2163 fdp[1] = -1; 2164 } 2165 if (dont_wait) { 2166 record_child(pid, program, NULL, NULL); 2167 status = 0; 2168 } else { 2169 while (waitpid(pid, &status, 0) < 0) { 2170 if (errno == EINTR) 2171 continue; 2172 fatal("error waiting for (dis)connection process: %m"); 2173 } 2174 --conn_running; 2175 } 2176#ifdef __APPLE__ 2177 // return real status code 2178 // Fix me : return only the lowest 8 bits 2179 return WEXITSTATUS(status); 2180#else 2181 return (status == 0 ? 0 : -1); 2182#endif 2183 } 2184 2185 /* here we are executing in the child */ 2186 2187 /* make sure fds 0, 1, 2 are occupied */ 2188 while ((fd = dup(in)) >= 0) { 2189 if (fd > 2) { 2190 close(fd); 2191 break; 2192 } 2193 } 2194 2195 /* dup in and out to fds > 2 */ 2196 { 2197 int fd1 = in, fd2 = out, fd3 = log_to_fd; 2198 2199 in = dup(in); 2200 out = dup(out); 2201 if (log_to_fd >= 0) { 2202 errfd = dup(log_to_fd); 2203 } else { 2204 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); 2205 } 2206 close(fd1); 2207 close(fd2); 2208 close(fd3); 2209 } 2210 2211 /* close fds 0 - 2 and any others we can think of */ 2212 close(0); 2213 close(1); 2214 close(2); 2215 if (the_channel->close) 2216 (*the_channel->close)(); 2217 closelog(); 2218 close(fd_devnull); 2219 if (fdp[1] != -1) { 2220 close(fdp[1]); 2221 fdp[1] = -1; 2222 } 2223 2224 /* dup the in, out, err fds to 0, 1, 2 */ 2225 dup2(in, 0); 2226 close(in); 2227 dup2(out, 1); 2228 close(out); 2229 if (errfd >= 0) { 2230 dup2(errfd, 2); 2231 close(errfd); 2232 } 2233 2234#ifdef __APPLE__ 2235 if (fdp[0] != -1) { 2236 dup2(fdp[0], PPP_ARG_FD); 2237 close(fdp[0]); 2238 fdp[0] = PPP_ARG_FD; 2239 closeallfrom(PPP_ARG_FD + 1); 2240 } else { 2241 /* make sure all fds 3 and above get closed, in case a library leaked */ 2242 closeallfrom(3); 2243 } 2244 2245 if (program_uid == -1) 2246 program_uid = uid; 2247 setuid(program_uid); 2248 if (getuid() != program_uid) { 2249 error("setuid failed"); 2250 exit(1); 2251 } 2252 setgid(getgid()); 2253#else 2254 setuid(uid); 2255 if (getuid() != uid) { 2256 error("setuid failed"); 2257 exit(1); 2258 } 2259 setgid(getgid()); 2260 } 2261#endif 2262 execle("/bin/sh", "sh", "-c", program, (char *)0, (char *)0); 2263 error("could not exec /bin/sh: %m"); 2264 exit(99); 2265 /* NOTREACHED */ 2266} 2267 2268 2269/* 2270 * run-program - execute a program with given arguments, 2271 * but don't wait for it. 2272 * If the program can't be executed, logs an error unless 2273 * must_exist is 0 and the program file doesn't exist. 2274 * Returns -1 if it couldn't fork, 0 if the file doesn't exist 2275 * or isn't an executable plain file, or the process ID of the child. 2276 * If done != NULL, (*done)(arg) will be called later (within 2277 * reap_kids) iff the return value is > 0. 2278 */ 2279pid_t 2280run_program(prog, args, must_exist, done, arg) 2281 char *prog; 2282 char **args; 2283 int must_exist; 2284 void (*done) __P((void *)); 2285 void *arg; 2286{ 2287 int pid; 2288 struct stat sbuf; 2289 2290 /* 2291 * First check if the file exists and is executable. 2292 * We don't use access() because that would use the 2293 * real user-id, which might not be root, and the script 2294 * might be accessible only to root. 2295 */ 2296 errno = EINVAL; 2297 if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) 2298 || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { 2299 if (must_exist || errno != ENOENT) 2300 warning("Can't execute %s: %m", prog); 2301 2302 return 0; 2303 } 2304 2305 pid = safe_fork(); 2306 if (pid == -1) { 2307 error("Failed to create child process for %s: %m", prog); 2308 return -1; 2309 } 2310 if (pid != 0) { 2311 if (debug) 2312 dbglog("Script %s started (pid %d)", prog, pid); 2313 record_child(pid, prog, done, arg); 2314 return pid; 2315 } 2316 2317 /* Leave the current location */ 2318 (void) setsid(); /* No controlling tty. */ 2319 (void) umask (S_IRWXG|S_IRWXO); 2320 (void) chdir ("/"); /* no current directory. */ 2321 setuid(0); /* set real UID = root */ 2322 setgid(getegid()); 2323 2324 /* Ensure that nothing of our device environment is inherited. */ 2325 closelog(); 2326 if (the_channel->close) 2327 (*the_channel->close)(); 2328 2329 /* Don't pass handles to the PPP device, even by accident. */ 2330 dup2(fd_devnull, 0); 2331 dup2(fd_devnull, 1); 2332 dup2(fd_devnull, 2); 2333 close(fd_devnull); 2334 2335 2336#ifdef __APPLE__ 2337 /* make sure all fd 3 and above, in case a library leaked */ 2338 closeallfrom(3); 2339#endif 2340 2341#ifdef BSD 2342 /* Force the priority back to zero if pppd is running higher. */ 2343 if (setpriority (PRIO_PROCESS, 0, 0) < 0) 2344 warning("can't reset priority to 0: %m"); 2345#endif 2346 2347 /* SysV recommends a second fork at this point. */ 2348 2349 /* run the program */ 2350 execve(prog, args, script_env); 2351 if (must_exist || errno != ENOENT) { 2352 /* have to reopen the log, there's nowhere else 2353 for the message to go. */ 2354 reopen_log(); 2355 sys_log(LOG_ERR, "Can't execute %s: %m", prog); 2356 closelog(); 2357 } 2358 _exit(-1); 2359} 2360 2361 2362/* 2363 * record_child - add a child process to the list for reap_kids 2364 * to use. 2365 */ 2366void 2367record_child(pid, prog, done, arg) 2368 int pid; 2369 char *prog; 2370 void (*done) __P((void *)); 2371 void *arg; 2372{ 2373 struct subprocess *chp; 2374 2375 ++n_children; 2376 2377 chp = (struct subprocess *) malloc(sizeof(struct subprocess)); 2378 if (chp == NULL) { 2379 warning("losing track of %s process", prog); 2380 } else { 2381 chp->pid = pid; 2382 chp->prog = prog; 2383 chp->done = done; 2384 chp->arg = arg; 2385 chp->next = children; 2386 children = chp; 2387 } 2388} 2389 2390 2391/* 2392 * reap_kids - get status from any dead child processes, 2393 * and log a message for abnormal terminations. 2394 */ 2395static int 2396reap_kids(waitfor) 2397 int waitfor; 2398{ 2399 int pid, status; 2400 struct subprocess *chp, **prevp; 2401 2402 if (n_children == 0) 2403 return 0; 2404 while ((pid = waitpid(-1, &status, (waitfor? 0: WNOHANG))) != -1 2405 && pid != 0) { 2406 for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) { 2407 if (chp->pid == pid) { 2408 --n_children; 2409 *prevp = chp->next; 2410 break; 2411 } 2412 } 2413 if (WIFSIGNALED(status)) { 2414 warning("Child process %s (pid %d) terminated with signal %d", 2415 (chp? chp->prog: "??"), pid, WTERMSIG(status)); 2416 } else if (debug) 2417 dbglog("Script %s finished (pid %d), status = 0x%x", 2418 (chp? chp->prog: "??"), pid, 2419 WIFEXITED(status) ? WEXITSTATUS(status) : status); 2420 if (chp && chp->done) 2421 (*chp->done)(chp->arg); 2422 if (chp) 2423 free(chp); 2424 } 2425 if (pid == -1) { 2426 if (errno == ECHILD) 2427 return -1; 2428 if (errno != EINTR) 2429 error("Error waiting for child process: %m"); 2430 } 2431 return 0; 2432} 2433 2434/* 2435 * add_notifier - add a new function to be called when something happens. 2436 */ 2437void 2438add_notifier(notif, func, arg) 2439 struct notifier **notif; 2440 notify_func func; 2441 void *arg; 2442{ 2443 struct notifier *np; 2444 2445 np = malloc(sizeof(struct notifier)); 2446 if (np == 0) 2447 novm("notifier struct"); 2448 np->next = *notif; 2449 np->func = func; 2450 np->arg = arg; 2451 *notif = np; 2452} 2453 2454void 2455add_notifier_last(notif, func, arg) 2456 struct notifier **notif; 2457 notify_func func; 2458 void *arg; 2459{ 2460 struct notifier *np; 2461 2462 np = malloc(sizeof(struct notifier)); 2463 if (np == 0) 2464 novm("notifier struct"); 2465 2466 np->next = NULL; 2467 np->func = func; 2468 np->arg = arg; 2469 2470 if (*notif == NULL) 2471 *notif = np; 2472 else { 2473 struct notifier *cur = *notif; 2474 while (cur->next != NULL) 2475 cur = cur->next; 2476 cur->next = np; 2477 } 2478} 2479 2480/* 2481 * remove_notifier - remove a function from the list of things to 2482 * be called when something happens. 2483 */ 2484void 2485remove_notifier(notif, func, arg) 2486 struct notifier **notif; 2487 notify_func func; 2488 void *arg; 2489{ 2490 struct notifier *np; 2491 2492 for (; (np = *notif) != 0; notif = &np->next) { 2493 if (np->func == func && np->arg == arg) { 2494 *notif = np->next; 2495 free(np); 2496 break; 2497 } 2498 } 2499} 2500 2501/* 2502 * notify - call a set of functions registered with add_notifier. 2503 */ 2504void 2505notify(notif, val) 2506 struct notifier *notif; 2507 int val; 2508{ 2509 struct notifier *np; 2510 2511 while ((np = notif) != 0) { 2512 notif = np->next; 2513 (*np->func)(np->arg, val); 2514 } 2515} 2516 2517/* 2518 * notify - call a set of functions registered with add_notifier using a unsigned 64-bit val (e.g a pointer). 2519 */ 2520void 2521notify_with_ptr(notif, val) 2522 struct notifier *notif; 2523 uintptr_t val; 2524{ 2525 struct notifier *np; 2526 2527 while ((np = notif) != 0) { 2528 notif = np->next; 2529 (*np->func)(np->arg, val); 2530 } 2531} 2532 2533/* 2534 * novm - log an error message saying we ran out of memory, and die. 2535 */ 2536void 2537novm(msg) 2538 char *msg; 2539{ 2540 fatal("Virtual memory exhausted allocating %s\n", msg); 2541} 2542 2543/* 2544 * script_setenv - set an environment variable value to be used 2545 * for scripts that we run (e.g. ip-up, auth-up, etc.) 2546 */ 2547void 2548script_setenv(var, value, iskey) 2549 char *var, *value; 2550 int iskey; 2551{ 2552 size_t varl = strlen(var); 2553 size_t vl = varl + strlen(value) + 2; 2554 int i; 2555 char *p, *newstring; 2556 2557 newstring = (char *) malloc(vl+1); 2558 if (newstring == 0) 2559 return; 2560 2561#ifdef USE_TDB 2562 /* 2563 The byte before the string is used to store the "iskey" value. 2564 It will be used later to know if delete_db_key() needs to be called. 2565 By moving the pointer to the actual start of the string, the original 2566 pointer to the allocated memory is "lost", and the string will appear 2567 as leaked in the 'leaks' command. 2568 This could be done better. It is only necessary when TDB is used. 2569 */ 2570 *newstring++ = iskey; 2571#endif 2572 2573 slprintf(newstring, vl, "%s=%s", var, value); 2574 2575 /* check if this variable is already set */ 2576 if (script_env != 0) { 2577 for (i = 0; (p = script_env[i]) != 0; ++i) { 2578 if (strncmp(p, var, varl) == 0 && p[varl] == '=') { 2579#ifdef USE_TDB 2580 if (p[-1] && pppdb != NULL) 2581 delete_db_key(p); 2582#endif 2583#ifdef USE_TDB 2584 /* see comment about how "iskey" is stored */ 2585 free(p-1); 2586#else 2587 free(p); 2588#endif 2589 script_env[i] = newstring; 2590#ifdef USE_TDB 2591 if (iskey && pppdb != NULL) 2592 add_db_key(newstring); 2593 update_db_entry(); 2594#endif 2595 return; 2596 } 2597 } 2598 } else { 2599 /* no space allocated for script env. ptrs. yet */ 2600 i = 0; 2601 script_env = (char **) malloc(16 * sizeof(char *)); 2602 if (script_env == 0) 2603 return; 2604 s_env_nalloc = 16; 2605 } 2606 2607 /* reallocate script_env with more space if needed */ 2608 if (i + 1 >= s_env_nalloc) { 2609 int new_n = i + 17; 2610 char **newenv = (char **) realloc((void *)script_env, 2611 new_n * sizeof(char *)); 2612 if (newenv == 0) 2613 return; 2614 script_env = newenv; 2615 s_env_nalloc = new_n; 2616 } 2617 2618 script_env[i] = newstring; 2619 script_env[i+1] = 0; 2620 2621#ifdef USE_TDB 2622 if (pppdb != NULL) { 2623 if (iskey) 2624 add_db_key(newstring); 2625 update_db_entry(); 2626 } 2627#endif 2628} 2629 2630/* 2631 * script_unsetenv - remove a variable from the environment 2632 * for scripts. 2633 */ 2634void 2635script_unsetenv(var) 2636 char *var; 2637{ 2638 int vl = strlen(var); 2639 int i; 2640 char *p; 2641 2642 if (script_env == 0) 2643 return; 2644 for (i = 0; (p = script_env[i]) != 0; ++i) { 2645 if (strncmp(p, var, vl) == 0 && p[vl] == '=') { 2646#ifdef USE_TDB 2647 if (p[-1] && pppdb != NULL) 2648 delete_db_key(p); 2649#endif 2650#ifdef USE_TDB 2651 /* see comment about how "iskey" is stored */ 2652 free(p-1); 2653#else 2654 free(p); 2655#endif 2656 while ((script_env[i] = script_env[i+1]) != 0) 2657 ++i; 2658 break; 2659 } 2660 } 2661#ifdef USE_TDB 2662 if (pppdb != NULL) 2663 update_db_entry(); 2664#endif 2665} 2666 2667#ifdef USE_TDB 2668/* 2669 * update_db_entry - update our entry in the database. 2670 */ 2671static void 2672update_db_entry() 2673{ 2674 TDB_DATA key, dbuf; 2675 int vlen, i; 2676 char *p, *q, *vbuf; 2677 2678 if (script_env == NULL) 2679 return; 2680 vlen = 0; 2681 for (i = 0; (p = script_env[i]) != 0; ++i) 2682 vlen += strlen(p) + 1; 2683 vbuf = malloc(vlen); 2684 if (vbuf == 0) 2685 novm("database entry"); 2686 q = vbuf; 2687 for (i = 0; (p = script_env[i]) != 0; ++i) 2688 q += slprintf(q, vbuf + vlen - q, "%s;", p); 2689 2690 key.dptr = db_key; 2691 key.dsize = strlen(db_key); 2692 dbuf.dptr = vbuf; 2693 dbuf.dsize = vlen; 2694 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) 2695 error("tdb_store failed: %s", tdb_error(pppdb)); 2696 2697 if (vbuf) 2698 free(vbuf); 2699 2700} 2701 2702/* 2703 * add_db_key - add a key that we can use to look up our database entry. 2704 */ 2705static void 2706add_db_key(str) 2707 const char *str; 2708{ 2709 TDB_DATA key, dbuf; 2710 2711 key.dptr = (char *) str; 2712 key.dsize = strlen(str); 2713 dbuf.dptr = db_key; 2714 dbuf.dsize = strlen(db_key); 2715 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) 2716 error("tdb_store key failed: %s", tdb_error(pppdb)); 2717} 2718 2719/* 2720 * delete_db_key - delete a key for looking up our database entry. 2721 */ 2722static void 2723delete_db_key(str) 2724 const char *str; 2725{ 2726 TDB_DATA key; 2727 2728 key.dptr = (char *) str; 2729 key.dsize = strlen(str); 2730 tdb_delete(pppdb, key); 2731} 2732 2733/* 2734 * cleanup_db - delete all the entries we put in the database. 2735 */ 2736static void 2737cleanup_db() 2738{ 2739 TDB_DATA key; 2740 int i; 2741 char *p; 2742 2743 key.dptr = db_key; 2744 key.dsize = strlen(db_key); 2745 tdb_delete(pppdb, key); 2746 for (i = 0; (p = script_env[i]) != 0; ++i) 2747 if (p[-1]) 2748 delete_db_key(p); 2749} 2750#endif /* USE_TDB */ 2751