1 /* NetBSD: main.c,v 1.2 2013/11/28 22:33:42 christos Exp */ 2 3 /* 4 * main.c - Point-to-Point Protocol main module 5 * 6 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name "Carnegie Mellon University" must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. For permission or any legal 23 * details, please contact 24 * Office of Technology Transfer 25 * Carnegie Mellon University 26 * 5000 Forbes Avenue 27 * Pittsburgh, PA 15213-3890 28 * (412) 268-4387, fax: (412) 268-7395 29 * tech-transfer@andrew.cmu.edu 30 * 31 * 4. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by Computing Services 34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 35 * 36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 43 * 44 * Copyright (c) 1999-2024 Paul Mackerras. All rights reserved. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in 55 * the documentation and/or other materials provided with the 56 * distribution. 57 * 58 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 59 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 60 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 61 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 62 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 63 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 64 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 65 */ 66 67 #include <sys/cdefs.h> 68 __RCSID("NetBSD: main.c,v 1.2 2013/11/28 22:33:42 christos Exp "); 69 70 #ifdef HAVE_CONFIG_H 71 #include "config.h" 72 #endif 73 74 #include <stdio.h> 75 #include <ctype.h> 76 #include <stdlib.h> 77 #include <string.h> 78 #include <unistd.h> 79 #include <signal.h> 80 #include <errno.h> 81 #include <fcntl.h> 82 #include <syslog.h> 83 #include <netdb.h> 84 #include <utmp.h> 85 #include <pwd.h> 86 #include <sys/param.h> 87 #include <sys/types.h> 88 #include <sys/wait.h> 89 #include <sys/time.h> 90 #include <sys/resource.h> 91 #include <sys/stat.h> 92 #include <sys/socket.h> 93 #include <netinet/in.h> 94 #include <arpa/inet.h> 95 #include <limits.h> 96 #include <inttypes.h> 97 #include <net/if.h> 98 99 #include "pppd-private.h" 100 #include "options.h" 101 #include "magic.h" 102 #include "fsm.h" 103 #include "lcp.h" 104 #include "ipcp.h" 105 #ifdef PPP_WITH_IPV6CP 106 #include "ipv6cp.h" 107 #endif 108 #include "upap.h" 109 #include "chap.h" 110 #include "eap.h" 111 #include "ccp.h" 112 #include "ecp.h" 113 #include "pathnames.h" 114 #include "crypto.h" 115 #include "multilink.h" 116 117 #ifdef PPP_WITH_TDB 118 #include "tdb.h" 119 #endif 120 121 #ifdef PPP_WITH_CBCP 122 #include "cbcp.h" 123 #endif 124 125 #ifdef AT_CHANGE 126 #include "atcp.h" 127 #endif 128 129 /* interface vars */ 130 char ifname[IFNAMSIZ]; /* Interface name */ 131 int ifunit; /* Interface unit number */ 132 133 struct channel *the_channel; 134 135 char *progname; /* Name of this program */ 136 char hostname[MAXNAMELEN]; /* Our hostname */ 137 static char pidfilename[MAXPATHLEN]; /* name of pid file */ 138 static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ 139 uid_t uid; /* Our real user-id */ 140 struct notifier *pidchange = NULL; 141 struct notifier *phasechange = NULL; 142 struct notifier *exitnotify = NULL; 143 struct notifier *sigreceived = NULL; 144 struct notifier *fork_notifier = NULL; 145 146 int hungup; /* terminal has been hung up */ 147 int privileged; /* we're running as real uid root */ 148 int need_holdoff; /* need holdoff period before restarting */ 149 int detached; /* have detached from terminal */ 150 volatile int code; /* exit status for pppd */ 151 int unsuccess; /* # unsuccessful connection attempts */ 152 int do_callback; /* != 0 if we should do callback next */ 153 int doing_callback; /* != 0 if we are doing callback */ 154 int ppp_session_number; /* Session number, for channels with such a 155 concept (eg PPPoE) */ 156 int childwait_done; /* have timed out waiting for children */ 157 158 #ifdef PPP_WITH_TDB 159 TDB_CONTEXT *pppdb; /* database for storing status etc. */ 160 #endif 161 162 char db_key[32]; 163 164 int (*holdoff_hook)(void) = NULL; 165 int (*new_phase_hook)(int) = NULL; 166 void (*snoop_recv_hook)(unsigned char *p, int len) = NULL; 167 void (*snoop_send_hook)(unsigned char *p, int len) = NULL; 168 169 static int conn_running; /* we have a [dis]connector running */ 170 static int fd_loop; /* fd for getting demand-dial packets */ 171 172 int fd_devnull; /* fd for /dev/null */ 173 int devfd = -1; /* fd of underlying device */ 174 int fd_ppp = -1; /* fd for talking PPP */ 175 ppp_phase_t phase; /* where the link is at */ 176 int kill_link; 177 int asked_to_quit; 178 int open_ccp_flag; 179 int listen_time; 180 int got_sigusr2; 181 int got_sigterm; 182 int got_sighup; 183 184 static sigset_t signals_handled; 185 static int waiting; 186 static int sigpipe[2]; 187 188 char **script_env; /* Env. variable values for scripts */ 189 int s_env_nalloc; /* # words avail at script_env */ 190 191 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ 192 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ 193 194 static int n_children; /* # child processes still running */ 195 static int got_sigchld; /* set if we have received a SIGCHLD */ 196 197 int privopen; /* don't lock, open device as root */ 198 199 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; 200 201 GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ 202 int ngroups; /* How many groups valid in groups */ 203 204 static struct timeval start_time; /* Time when link was started. */ 205 206 static struct pppd_stats old_link_stats; 207 struct pppd_stats link_stats; 208 unsigned link_connect_time; 209 int link_stats_valid; 210 int link_stats_print; 211 212 int error_count; 213 214 bool bundle_eof; 215 bool bundle_terminating; 216 217 /* 218 * We maintain a list of child process pids and 219 * functions to call when they exit. 220 */ 221 struct subprocess { 222 pid_t pid; 223 char *prog; 224 void (*done)(void *); 225 void *arg; 226 int killable; 227 struct subprocess *next; 228 }; 229 230 static struct subprocess *children; 231 232 /* Prototypes for procedures local to this file. */ 233 234 static void setup_signals(void); 235 static void create_pidfile(int pid); 236 static void create_linkpidfile(int pid); 237 static void cleanup(void); 238 static void get_input(void); 239 static void calltimeout(void); 240 static struct timeval *timeleft(struct timeval *); 241 static void kill_my_pg(int); 242 static void hup(int); 243 static void term(int); 244 static void chld(int); 245 static void toggle_debug(int); 246 static void open_ccp(int); 247 static void bad_signal(int); 248 static void holdoff_end(void *); 249 static void forget_child(int pid, int status); 250 static int reap_kids(void); 251 static void childwait_end(void *); 252 static void run_net_script(char* script, int wait); 253 254 #ifdef PPP_WITH_TDB 255 static void update_db_entry(void); 256 static void add_db_key(const char *); 257 static void delete_db_key(const char *); 258 static void cleanup_db(void); 259 #endif 260 261 static void handle_events(void); 262 void print_link_stats(void); 263 264 extern char *getlogin(void); 265 int main(int, char *[]); 266 267 const char *ppp_hostname() 268 { 269 return hostname; 270 } 271 272 bool ppp_signaled(int sig) 273 { 274 if (sig == SIGTERM) 275 return !!got_sigterm; 276 if (sig == SIGUSR2) 277 return !!got_sigusr2; 278 if (sig == SIGHUP) 279 return !!got_sighup; 280 return false; 281 } 282 283 ppp_exit_code_t ppp_status() 284 { 285 return code; 286 } 287 288 void ppp_set_status(ppp_exit_code_t value) 289 { 290 code = value; 291 } 292 293 void ppp_set_session_number(int number) 294 { 295 ppp_session_number = number; 296 } 297 298 int ppp_get_session_number() 299 { 300 return ppp_session_number; 301 } 302 303 const char *ppp_ifname() 304 { 305 return ifname; 306 } 307 308 int ppp_get_ifname(char *buf, size_t bufsz) 309 { 310 if (buf) { 311 return strlcpy(buf, ifname, bufsz); 312 } 313 return false; 314 } 315 316 void ppp_set_ifname(const char *name) 317 { 318 if (name) { 319 strlcpy(ifname, name, sizeof(ifname)); 320 } 321 } 322 323 int ppp_ifunit() 324 { 325 return ifunit; 326 } 327 328 int ppp_get_link_uptime() 329 { 330 return link_connect_time; 331 } 332 333 /* 334 * PPP Data Link Layer "protocol" table. 335 * One entry per supported protocol. 336 * The last entry must be NULL. 337 */ 338 struct protent *protocols[] = { 339 &lcp_protent, 340 &pap_protent, 341 &chap_protent, 342 #ifdef PPP_WITH_CBCP 343 &cbcp_protent, 344 #endif 345 &ipcp_protent, 346 #ifdef PPP_WITH_IPV6CP 347 &ipv6cp_protent, 348 #endif 349 &ccp_protent, 350 &ecp_protent, 351 #ifdef AT_CHANGE 352 &atcp_protent, 353 #endif 354 &eap_protent, 355 NULL 356 }; 357 358 int 359 main(int argc, char *argv[]) 360 { 361 int i, t; 362 char *p; 363 struct passwd *pw; 364 struct protent *protp; 365 char numbuf[16]; 366 367 strlcpy(path_upapfile, PPP_PATH_UPAPFILE, MAXPATHLEN); 368 strlcpy(path_chapfile, PPP_PATH_CHAPFILE, MAXPATHLEN); 369 370 strlcpy(path_net_init, PPP_PATH_NET_INIT, MAXPATHLEN); 371 strlcpy(path_net_preup, PPP_PATH_NET_PREUP, MAXPATHLEN); 372 strlcpy(path_net_down, PPP_PATH_NET_DOWN, MAXPATHLEN); 373 374 strlcpy(path_ipup, PPP_PATH_IPUP, MAXPATHLEN); 375 strlcpy(path_ipdown, PPP_PATH_IPDOWN, MAXPATHLEN); 376 strlcpy(path_ippreup, PPP_PATH_IPPREUP, MAXPATHLEN); 377 378 #ifdef PPP_WITH_IPV6CP 379 strlcpy(path_ipv6up, PPP_PATH_IPV6UP, MAXPATHLEN); 380 strlcpy(path_ipv6down, PPP_PATH_IPV6DOWN, MAXPATHLEN); 381 #endif 382 link_stats_valid = 0; 383 link_stats_print = 1; 384 new_phase(PHASE_INITIALIZE); 385 386 script_env = NULL; 387 388 /* Initialize syslog facilities */ 389 reopen_log(); 390 391 /* Initialize crypto libraries */ 392 if (!PPP_crypto_init()) { 393 exit(1); 394 } 395 396 if (gethostname(hostname, sizeof(hostname)) < 0 ) { 397 ppp_option_error("Couldn't get hostname: %m"); 398 exit(1); 399 } 400 hostname[MAXNAMELEN-1] = 0; 401 402 /* make sure we don't create world or group writable files. */ 403 umask(umask(0777) | 022); 404 405 uid = getuid(); 406 privileged = uid == 0; 407 slprintf(numbuf, sizeof(numbuf), "%d", uid); 408 ppp_script_setenv("ORIG_UID", numbuf, 0); 409 410 ngroups = getgroups(NGROUPS_MAX, groups); 411 412 /* 413 * Initialize magic number generator now so that protocols may 414 * use magic numbers in initialization. 415 */ 416 magic_init(); 417 418 /* 419 * Initialize each protocol. 420 */ 421 for (i = 0; (protp = protocols[i]) != NULL; ++i) 422 (*protp->init)(0); 423 424 /* 425 * Initialize the default channel. 426 */ 427 tty_init(); 428 429 progname = *argv; 430 431 /* 432 * Parse, in order, the system options file, the user's options file, 433 * and the command line arguments. 434 */ 435 if (!ppp_options_from_file(PPP_PATH_SYSOPTIONS, !privileged, 0, 1) 436 || !options_from_user() 437 || !parse_args(argc-1, argv+1)) 438 exit(EXIT_OPTION_ERROR); 439 devnam_fixed = 1; /* can no longer change device name */ 440 441 /* 442 * Work out the device name, if it hasn't already been specified, 443 * and parse the tty's options file. 444 */ 445 if (the_channel->process_extra_options) 446 (*the_channel->process_extra_options)(); 447 448 if (debug) 449 setlogmask(LOG_UPTO(LOG_DEBUG)); 450 451 if (show_options) { 452 showopts(); 453 die(0); 454 } 455 456 /* 457 * Check that we are running as root. 458 */ 459 if (geteuid() != 0) { 460 ppp_option_error("must be root to run %s, since it is not setuid-root", 461 argv[0]); 462 exit(EXIT_NOT_ROOT); 463 } 464 465 if (!ppp_check_kernel_support()) { 466 ppp_option_error("%s", no_ppp_msg); 467 exit(EXIT_NO_KERNEL_SUPPORT); 468 } 469 470 /* 471 * Check that the options given are valid and consistent. 472 */ 473 check_options(); 474 if (!sys_check_options()) 475 exit(EXIT_OPTION_ERROR); 476 auth_check_options(); 477 mp_check_options(); 478 for (i = 0; (protp = protocols[i]) != NULL; ++i) 479 if (protp->check_options != NULL) 480 (*protp->check_options)(); 481 if (the_channel->check_options) 482 (*the_channel->check_options)(); 483 484 485 if (dump_options || dryrun) { 486 init_pr_log(NULL, LOG_INFO); 487 print_options(pr_log, NULL); 488 end_pr_log(); 489 } 490 491 if (dryrun) 492 die(0); 493 494 /* Make sure fds 0, 1, 2 are open to somewhere. */ 495 fd_devnull = open(PPP_DEVNULL, O_RDWR); 496 if (fd_devnull < 0) 497 fatal("Couldn't open %s: %m", PPP_DEVNULL); 498 while (fd_devnull <= 2) { 499 i = dup(fd_devnull); 500 if (i < 0) 501 fatal("Critical shortage of file descriptors: dup failed: %m"); 502 fd_devnull = i; 503 } 504 505 /* 506 * Initialize system-dependent stuff. 507 */ 508 sys_init(); 509 510 #ifdef PPP_WITH_TDB 511 pppdb = tdb_open(PPP_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); 512 if (pppdb != NULL) { 513 slprintf(db_key, sizeof(db_key), "pppd%d", getpid()); 514 update_db_entry(); 515 } else { 516 warn("Warning: couldn't open ppp database %s", PPP_PATH_PPPDB); 517 if (multilink) { 518 warn("Warning: disabling multilink"); 519 multilink = 0; 520 } 521 } 522 #endif 523 524 /* 525 * Detach ourselves from the terminal, if required, 526 * and identify who is running us. 527 */ 528 if (!nodetach && !updetach) 529 detach(); 530 p = getlogin(); 531 if (p == NULL) { 532 pw = getpwuid(uid); 533 if (pw != NULL && pw->pw_name != NULL) 534 p = pw->pw_name; 535 else 536 p = "(unknown)"; 537 } 538 syslog(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid); 539 ppp_script_setenv("PPPLOGNAME", p, 0); 540 541 if (devnam[0]) 542 ppp_script_setenv("DEVICE", devnam, 1); 543 slprintf(numbuf, sizeof(numbuf), "%d", getpid()); 544 ppp_script_setenv("PPPD_PID", numbuf, 1); 545 546 setup_signals(); 547 548 create_linkpidfile(getpid()); 549 550 waiting = 0; 551 552 /* 553 * If we're doing dial-on-demand, set up the interface now. 554 */ 555 if (demand) { 556 /* 557 * Open the loopback channel and set it up to be the ppp interface. 558 */ 559 fd_loop = open_ppp_loopback(); 560 set_ifunit(1); 561 /* 562 * Configure the interface and mark it up, etc. 563 */ 564 demand_conf(); 565 } 566 567 do_callback = 0; 568 for (;;) { 569 570 bundle_eof = 0; 571 bundle_terminating = 0; 572 listen_time = 0; 573 need_holdoff = 1; 574 devfd = -1; 575 code = EXIT_OK; 576 ++unsuccess; 577 doing_callback = do_callback; 578 do_callback = 0; 579 580 if (demand && !doing_callback) { 581 /* 582 * Don't do anything until we see some activity. 583 */ 584 new_phase(PHASE_DORMANT); 585 demand_unblock(); 586 add_fd(fd_loop); 587 for (;;) { 588 handle_events(); 589 if (asked_to_quit) 590 break; 591 if (get_loop_output()) 592 break; 593 } 594 remove_fd(fd_loop); 595 if (asked_to_quit) 596 break; 597 598 /* 599 * Now we want to bring up the link. 600 */ 601 demand_block(); 602 info("Starting link"); 603 } 604 605 ppp_get_time(&start_time); 606 ppp_script_unsetenv("CONNECT_TIME"); 607 ppp_script_unsetenv("BYTES_SENT"); 608 ppp_script_unsetenv("BYTES_RCVD"); 609 610 lcp_open(0); /* Start protocol */ 611 start_link(0); 612 while (phase != PHASE_DEAD) { 613 handle_events(); 614 get_input(); 615 if (kill_link) { 616 lcp_close(0, "User request"); 617 need_holdoff = 0; 618 } 619 if (asked_to_quit) { 620 bundle_terminating = 1; 621 if (phase == PHASE_MASTER) 622 mp_bundle_terminated(); 623 } 624 if (open_ccp_flag) { 625 if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { 626 ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ 627 (*ccp_protent.open)(0); 628 } 629 } 630 } 631 /* restore FSMs to original state */ 632 lcp_close(0, ""); 633 634 if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail)) 635 break; 636 637 if (demand) 638 demand_discard(); 639 t = need_holdoff? holdoff: 0; 640 if (holdoff_hook) 641 t = (*holdoff_hook)(); 642 if (t > 0) { 643 new_phase(PHASE_HOLDOFF); 644 TIMEOUT(holdoff_end, NULL, t); 645 do { 646 handle_events(); 647 if (kill_link) 648 new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ 649 } while (phase == PHASE_HOLDOFF); 650 if (!persist) 651 break; 652 } 653 } 654 655 /* Wait for scripts to finish */ 656 reap_kids(); 657 if (n_children > 0) { 658 if (child_wait > 0) 659 TIMEOUT(childwait_end, NULL, child_wait); 660 if (debug) { 661 struct subprocess *chp; 662 dbglog("Waiting for %d child processes...", n_children); 663 for (chp = children; chp != NULL; chp = chp->next) 664 dbglog(" script %s, pid %d", chp->prog, chp->pid); 665 } 666 while (n_children > 0 && !childwait_done) { 667 handle_events(); 668 if (kill_link && !childwait_done) 669 childwait_end(NULL); 670 } 671 } 672 673 PPP_crypto_deinit(); 674 die(code); 675 return 0; 676 } 677 678 /* 679 * handle_events - wait for something to happen and respond to it. 680 */ 681 static void 682 handle_events(void) 683 { 684 struct timeval timo; 685 unsigned char buf[16]; 686 687 kill_link = open_ccp_flag = 0; 688 689 /* alert via signal pipe */ 690 waiting = 1; 691 /* flush signal pipe */ 692 for (; read(sigpipe[0], buf, sizeof(buf)) > 0; ); 693 add_fd(sigpipe[0]); 694 /* wait if necessary */ 695 if (!(got_sighup || got_sigterm || got_sigusr2 || got_sigchld)) 696 wait_input(timeleft(&timo)); 697 waiting = 0; 698 remove_fd(sigpipe[0]); 699 700 calltimeout(); 701 if (got_sighup) { 702 info("Hangup (SIGHUP)"); 703 kill_link = 1; 704 got_sighup = 0; 705 if (code != EXIT_HANGUP) 706 code = EXIT_USER_REQUEST; 707 } 708 if (got_sigterm) { 709 info("Terminating on signal %d", got_sigterm); 710 kill_link = 1; 711 asked_to_quit = 1; 712 persist = 0; 713 code = EXIT_USER_REQUEST; 714 got_sigterm = 0; 715 } 716 if (got_sigchld) { 717 got_sigchld = 0; 718 reap_kids(); /* Don't leave dead kids lying around */ 719 } 720 if (got_sigusr2) { 721 open_ccp_flag = 1; 722 got_sigusr2 = 0; 723 } 724 } 725 726 /* 727 * setup_signals - initialize signal handling. 728 */ 729 static void 730 setup_signals(void) 731 { 732 struct sigaction sa; 733 734 /* create pipe to wake up event handler from signal handler */ 735 if (pipe(sigpipe) < 0) 736 fatal("Couldn't create signal pipe: %m"); 737 fcntl(sigpipe[0], F_SETFD, fcntl(sigpipe[0], F_GETFD) | FD_CLOEXEC); 738 fcntl(sigpipe[1], F_SETFD, fcntl(sigpipe[1], F_GETFD) | FD_CLOEXEC); 739 fcntl(sigpipe[0], F_SETFL, fcntl(sigpipe[0], F_GETFL) | O_NONBLOCK); 740 fcntl(sigpipe[1], F_SETFL, fcntl(sigpipe[1], F_GETFL) | O_NONBLOCK); 741 742 /* 743 * Compute mask of all interesting signals and install signal handlers 744 * for each. Only one signal handler may be active at a time. Therefore, 745 * all other signals should be masked when any handler is executing. 746 */ 747 sigemptyset(&signals_handled); 748 sigaddset(&signals_handled, SIGHUP); 749 sigaddset(&signals_handled, SIGINT); 750 sigaddset(&signals_handled, SIGTERM); 751 sigaddset(&signals_handled, SIGCHLD); 752 sigaddset(&signals_handled, SIGUSR2); 753 754 #define SIGNAL(s, handler) do { \ 755 sa.sa_handler = handler; \ 756 if (sigaction(s, &sa, NULL) < 0) \ 757 fatal("Couldn't establish signal handler (%d): %m", s); \ 758 } while (0) 759 760 sa.sa_mask = signals_handled; 761 sa.sa_flags = 0; 762 SIGNAL(SIGHUP, hup); /* Hangup */ 763 SIGNAL(SIGINT, term); /* Interrupt */ 764 SIGNAL(SIGTERM, term); /* Terminate */ 765 SIGNAL(SIGCHLD, chld); 766 767 SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ 768 SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ 769 770 /* 771 * Install a handler for other signals which would otherwise 772 * cause pppd to exit without cleaning up. 773 */ 774 SIGNAL(SIGABRT, bad_signal); 775 SIGNAL(SIGALRM, bad_signal); 776 SIGNAL(SIGFPE, bad_signal); 777 SIGNAL(SIGILL, bad_signal); 778 SIGNAL(SIGPIPE, bad_signal); 779 SIGNAL(SIGQUIT, bad_signal); 780 SIGNAL(SIGSEGV, bad_signal); 781 #ifdef SIGBUS 782 SIGNAL(SIGBUS, bad_signal); 783 #endif 784 #ifdef SIGEMT 785 SIGNAL(SIGEMT, bad_signal); 786 #endif 787 #ifdef SIGPOLL 788 SIGNAL(SIGPOLL, bad_signal); 789 #endif 790 #ifdef SIGPROF 791 SIGNAL(SIGPROF, bad_signal); 792 #endif 793 #ifdef SIGSYS 794 SIGNAL(SIGSYS, bad_signal); 795 #endif 796 #ifdef SIGTRAP 797 SIGNAL(SIGTRAP, bad_signal); 798 #endif 799 #ifdef SIGVTALRM 800 SIGNAL(SIGVTALRM, bad_signal); 801 #endif 802 #ifdef SIGXCPU 803 SIGNAL(SIGXCPU, bad_signal); 804 #endif 805 #ifdef SIGXFSZ 806 SIGNAL(SIGXFSZ, bad_signal); 807 #endif 808 809 /* 810 * Apparently we can get a SIGPIPE when we call syslog, if 811 * syslogd has died and been restarted. Ignoring it seems 812 * be sufficient. 813 */ 814 signal(SIGPIPE, SIG_IGN); 815 } 816 817 /* 818 * net-* scripts to be run come through here. 819 */ 820 void run_net_script(char* script, int wait) 821 { 822 char strspeed[32]; 823 char *argv[6]; 824 825 slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); 826 827 argv[0] = script; 828 argv[1] = ifname; 829 argv[2] = devnam; 830 argv[3] = strspeed; 831 argv[4] = ipparam; 832 argv[5] = NULL; 833 834 run_program(script, argv, 0, NULL, NULL, wait); 835 } 836 837 /* 838 * set_ifunit - do things we need to do once we know which ppp 839 * unit we are using. 840 */ 841 void 842 set_ifunit(int iskey) 843 { 844 char ifkey[32]; 845 846 if (req_ifname[0] != '\0') 847 slprintf(ifname, sizeof(ifname), "%s", req_ifname); 848 else 849 slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); 850 info("Using interface %s", ifname); 851 ppp_script_setenv("IFNAME", ifname, iskey); 852 slprintf(ifkey, sizeof(ifkey), "%d", ifunit); 853 ppp_script_setenv("UNIT", ifkey, iskey); 854 if (iskey) { 855 create_pidfile(getpid()); /* write pid to file */ 856 create_linkpidfile(getpid()); 857 } 858 if (*remote_number) 859 ppp_script_setenv("REMOTENUMBER", remote_number, 0); 860 run_net_script(path_net_init, 1); 861 } 862 863 /* 864 * detach - detach us from the controlling terminal. 865 */ 866 void 867 detach(void) 868 { 869 int pid; 870 int ret; 871 char numbuf[16]; 872 int pipefd[2]; 873 874 if (detached) 875 return; 876 if (pipe(pipefd) == -1) 877 pipefd[0] = pipefd[1] = -1; 878 if ((pid = fork()) < 0) { 879 error("Couldn't detach (fork failed: %m)"); 880 die(1); /* or just return? */ 881 } 882 if (pid != 0) { 883 /* parent */ 884 notify(pidchange, pid); 885 /* update pid files if they have been written already */ 886 if (pidfilename[0]) 887 create_pidfile(pid); 888 create_linkpidfile(pid); 889 exit(0); /* parent dies */ 890 } 891 setsid(); 892 ret = chdir("/"); 893 if (ret != 0) { 894 fatal("Could not change directory to '/', %m"); 895 } 896 dup2(fd_devnull, 0); 897 dup2(fd_devnull, 1); 898 dup2(fd_devnull, 2); 899 detached = 1; 900 if (log_default) 901 log_to_fd = -1; 902 slprintf(numbuf, sizeof(numbuf), "%d", getpid()); 903 ppp_script_setenv("PPPD_PID", numbuf, 1); 904 905 /* wait for parent to finish updating pid & lock files and die */ 906 close(pipefd[1]); 907 complete_read(pipefd[0], numbuf, 1); 908 close(pipefd[0]); 909 } 910 911 /* 912 * reopen_log - (re)open our connection to syslog. 913 */ 914 void 915 reopen_log(void) 916 { 917 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); 918 setlogmask(LOG_UPTO(LOG_INFO)); 919 } 920 921 /* 922 * Create a file containing our process ID. 923 */ 924 static void 925 create_pidfile(int pid) 926 { 927 FILE *pidfile; 928 929 mkdir_recursive(PPP_PATH_VARRUN); 930 slprintf(pidfilename, sizeof(pidfilename), "%s/%s.pid", 931 PPP_PATH_VARRUN, ifname); 932 if ((pidfile = fopen(pidfilename, "w")) != NULL) { 933 fprintf(pidfile, "%d\n", pid); 934 (void) fclose(pidfile); 935 } else { 936 error("Failed to create pid file %s: %m", pidfilename); 937 pidfilename[0] = 0; 938 } 939 } 940 941 void 942 create_linkpidfile(int pid) 943 { 944 FILE *pidfile; 945 946 if (linkname[0] == 0) 947 return; 948 ppp_script_setenv("LINKNAME", linkname, 1); 949 slprintf(linkpidfile, sizeof(linkpidfile), "%s/ppp-%s.pid", 950 PPP_PATH_VARRUN, linkname); 951 if ((pidfile = fopen(linkpidfile, "w")) != NULL) { 952 fprintf(pidfile, "%d\n", pid); 953 if (ifname[0]) 954 fprintf(pidfile, "%s\n", ifname); 955 (void) fclose(pidfile); 956 } else { 957 error("Failed to create pid file %s: %m", linkpidfile); 958 linkpidfile[0] = 0; 959 } 960 } 961 962 /* 963 * remove_pidfile - remove our pid files 964 */ 965 void remove_pidfiles(void) 966 { 967 if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) 968 warn("unable to delete pid file %s: %m", pidfilename); 969 pidfilename[0] = 0; 970 if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) 971 warn("unable to delete pid file %s: %m", linkpidfile); 972 linkpidfile[0] = 0; 973 } 974 975 /* 976 * holdoff_end - called via a timeout when the holdoff period ends. 977 */ 978 static void 979 holdoff_end(void *arg) 980 { 981 new_phase(PHASE_DORMANT); 982 } 983 984 /* List of protocol names, to make our messages a little more informative. */ 985 struct protocol_list { 986 u_short proto; 987 const char *name; 988 } protocol_list[] = { 989 { 0x21, "IP" }, 990 { 0x23, "OSI Network Layer" }, 991 { 0x25, "Xerox NS IDP" }, 992 { 0x27, "DECnet Phase IV" }, 993 { 0x29, "Appletalk" }, 994 { 0x2b, "Novell IPX" }, 995 { 0x2d, "VJ compressed TCP/IP" }, 996 { 0x2f, "VJ uncompressed TCP/IP" }, 997 { 0x31, "Bridging PDU" }, 998 { 0x33, "Stream Protocol ST-II" }, 999 { 0x35, "Banyan Vines" }, 1000 { 0x39, "AppleTalk EDDP" }, 1001 { 0x3b, "AppleTalk SmartBuffered" }, 1002 { 0x3d, "Multi-Link" }, 1003 { 0x3f, "NETBIOS Framing" }, 1004 { 0x41, "Cisco Systems" }, 1005 { 0x43, "Ascom Timeplex" }, 1006 { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, 1007 { 0x47, "DCA Remote Lan" }, 1008 { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, 1009 { 0x4b, "SNA over 802.2" }, 1010 { 0x4d, "SNA" }, 1011 { 0x4f, "IP6 Header Compression" }, 1012 { 0x51, "KNX Bridging Data" }, 1013 { 0x53, "Encryption" }, 1014 { 0x55, "Individual Link Encryption" }, 1015 { 0x57, "IPv6" }, 1016 { 0x59, "PPP Muxing" }, 1017 { 0x5b, "Vendor-Specific Network Protocol" }, 1018 { 0x61, "RTP IPHC Full Header" }, 1019 { 0x63, "RTP IPHC Compressed TCP" }, 1020 { 0x65, "RTP IPHC Compressed non-TCP" }, 1021 { 0x67, "RTP IPHC Compressed UDP 8" }, 1022 { 0x69, "RTP IPHC Compressed RTP 8" }, 1023 { 0x6f, "Stampede Bridging" }, 1024 { 0x73, "MP+" }, 1025 { 0xc1, "NTCITS IPI" }, 1026 { 0xfb, "single-link compression" }, 1027 { 0xfd, "Compressed Datagram" }, 1028 { 0x0201, "802.1d Hello Packets" }, 1029 { 0x0203, "IBM Source Routing BPDU" }, 1030 { 0x0205, "DEC LANBridge100 Spanning Tree" }, 1031 { 0x0207, "Cisco Discovery Protocol" }, 1032 { 0x0209, "Netcs Twin Routing" }, 1033 { 0x020b, "STP - Scheduled Transfer Protocol" }, 1034 { 0x020d, "EDP - Extreme Discovery Protocol" }, 1035 { 0x0211, "Optical Supervisory Channel Protocol" }, 1036 { 0x0213, "Optical Supervisory Channel Protocol" }, 1037 { 0x0231, "Luxcom" }, 1038 { 0x0233, "Sigma Network Systems" }, 1039 { 0x0235, "Apple Client Server Protocol" }, 1040 { 0x0281, "MPLS Unicast" }, 1041 { 0x0283, "MPLS Multicast" }, 1042 { 0x0285, "IEEE p1284.4 standard - data packets" }, 1043 { 0x0287, "ETSI TETRA Network Protocol Type 1" }, 1044 { 0x0289, "Multichannel Flow Treatment Protocol" }, 1045 { 0x2063, "RTP IPHC Compressed TCP No Delta" }, 1046 { 0x2065, "RTP IPHC Context State" }, 1047 { 0x2067, "RTP IPHC Compressed UDP 16" }, 1048 { 0x2069, "RTP IPHC Compressed RTP 16" }, 1049 { 0x4001, "Cray Communications Control Protocol" }, 1050 { 0x4003, "CDPD Mobile Network Registration Protocol" }, 1051 { 0x4005, "Expand accelerator protocol" }, 1052 { 0x4007, "ODSICP NCP" }, 1053 { 0x4009, "DOCSIS DLL" }, 1054 { 0x400B, "Cetacean Network Detection Protocol" }, 1055 { 0x4021, "Stacker LZS" }, 1056 { 0x4023, "RefTek Protocol" }, 1057 { 0x4025, "Fibre Channel" }, 1058 { 0x4027, "EMIT Protocols" }, 1059 { 0x405b, "Vendor-Specific Protocol (VSP)" }, 1060 { 0x8021, "Internet Protocol Control Protocol" }, 1061 { 0x8023, "OSI Network Layer Control Protocol" }, 1062 { 0x8025, "Xerox NS IDP Control Protocol" }, 1063 { 0x8027, "DECnet Phase IV Control Protocol" }, 1064 { 0x8029, "Appletalk Control Protocol" }, 1065 { 0x802b, "Novell IPX Control Protocol" }, 1066 { 0x8031, "Bridging NCP" }, 1067 { 0x8033, "Stream Protocol Control Protocol" }, 1068 { 0x8035, "Banyan Vines Control Protocol" }, 1069 { 0x803d, "Multi-Link Control Protocol" }, 1070 { 0x803f, "NETBIOS Framing Control Protocol" }, 1071 { 0x8041, "Cisco Systems Control Protocol" }, 1072 { 0x8043, "Ascom Timeplex" }, 1073 { 0x8045, "Fujitsu LBLB Control Protocol" }, 1074 { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, 1075 { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, 1076 { 0x804b, "SNA over 802.2 Control Protocol" }, 1077 { 0x804d, "SNA Control Protocol" }, 1078 { 0x804f, "IP6 Header Compression Control Protocol" }, 1079 { 0x8051, "KNX Bridging Control Protocol" }, 1080 { 0x8053, "Encryption Control Protocol" }, 1081 { 0x8055, "Individual Link Encryption Control Protocol" }, 1082 { 0x8057, "IPv6 Control Protocol" }, 1083 { 0x8059, "PPP Muxing Control Protocol" }, 1084 { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, 1085 { 0x806f, "Stampede Bridging Control Protocol" }, 1086 { 0x8073, "MP+ Control Protocol" }, 1087 { 0x80c1, "NTCITS IPI Control Protocol" }, 1088 { 0x80fb, "Single Link Compression Control Protocol" }, 1089 { 0x80fd, "Compression Control Protocol" }, 1090 { 0x8207, "Cisco Discovery Protocol Control" }, 1091 { 0x8209, "Netcs Twin Routing" }, 1092 { 0x820b, "STP - Control Protocol" }, 1093 { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, 1094 { 0x8235, "Apple Client Server Protocol Control" }, 1095 { 0x8281, "MPLSCP" }, 1096 { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, 1097 { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, 1098 { 0x8289, "Multichannel Flow Treatment Protocol" }, 1099 { 0xc021, "Link Control Protocol" }, 1100 { 0xc023, "Password Authentication Protocol" }, 1101 { 0xc025, "Link Quality Report" }, 1102 { 0xc027, "Shiva Password Authentication Protocol" }, 1103 { 0xc029, "CallBack Control Protocol (CBCP)" }, 1104 { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, 1105 { 0xc02d, "BAP" }, 1106 { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, 1107 { 0xc081, "Container Control Protocol" }, 1108 { 0xc223, "Challenge Handshake Authentication Protocol" }, 1109 { 0xc225, "RSA Authentication Protocol" }, 1110 { 0xc227, "Extensible Authentication Protocol" }, 1111 { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, 1112 { 0xc26f, "Stampede Bridging Authorization Protocol" }, 1113 { 0xc281, "Proprietary Authentication Protocol" }, 1114 { 0xc283, "Proprietary Authentication Protocol" }, 1115 { 0xc481, "Proprietary Node ID Authentication Protocol" }, 1116 { 0, NULL }, 1117 }; 1118 1119 /* 1120 * protocol_name - find a name for a PPP protocol. 1121 */ 1122 const char * 1123 protocol_name(int proto) 1124 { 1125 struct protocol_list *lp; 1126 1127 for (lp = protocol_list; lp->proto != 0; ++lp) 1128 if (proto == lp->proto) 1129 return lp->name; 1130 return NULL; 1131 } 1132 1133 /* 1134 * get_input - called when incoming data is available. 1135 */ 1136 static void 1137 get_input(void) 1138 { 1139 int len, i; 1140 u_char *p; 1141 u_short protocol; 1142 struct protent *protp; 1143 1144 p = inpacket_buf; /* point to beginning of packet buffer */ 1145 1146 len = read_packet(inpacket_buf); 1147 if (len < 0) 1148 return; 1149 1150 if (len == 0) { 1151 if (bundle_eof && mp_master()) { 1152 notice("Last channel has disconnected"); 1153 mp_bundle_terminated(); 1154 return; 1155 } 1156 notice("Modem hangup"); 1157 hungup = 1; 1158 code = EXIT_HANGUP; 1159 need_holdoff = 0; 1160 lcp_lowerdown(0); /* serial link is no longer available */ 1161 link_terminated(0); 1162 return; 1163 } 1164 1165 if (len < PPP_HDRLEN) { 1166 dbglog("received short packet:%.*B", len, p); 1167 return; 1168 } 1169 1170 dump_packet("rcvd", p, len); 1171 if (snoop_recv_hook) snoop_recv_hook(p, len); 1172 1173 p += 2; /* Skip address and control */ 1174 GETSHORT(protocol, p); 1175 len -= PPP_HDRLEN; 1176 1177 /* 1178 * Toss all non-LCP packets unless LCP is OPEN. 1179 */ 1180 if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { 1181 dbglog("Discarded non-LCP packet when LCP not open"); 1182 return; 1183 } 1184 1185 /* 1186 * Until we get past the authentication phase, toss all packets 1187 * except LCP, LQR and authentication packets. 1188 */ 1189 if (phase <= PHASE_AUTHENTICATE 1190 && !(protocol == PPP_LCP || protocol == PPP_LQR 1191 || protocol == PPP_PAP || protocol == PPP_CHAP || 1192 protocol == PPP_EAP)) { 1193 dbglog("discarding proto 0x%x in phase %d", 1194 protocol, phase); 1195 return; 1196 } 1197 1198 /* 1199 * Upcall the proper protocol input routine. 1200 */ 1201 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 1202 if (protp->protocol == protocol && protp->enabled_flag) { 1203 (*protp->input)(0, p, len); 1204 return; 1205 } 1206 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag 1207 && protp->datainput != NULL) { 1208 (*protp->datainput)(0, p, len); 1209 return; 1210 } 1211 } 1212 1213 if (debug) { 1214 const char *pname = protocol_name(protocol); 1215 if (pname != NULL) 1216 warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); 1217 else 1218 warn("Unsupported protocol 0x%x received", protocol); 1219 } 1220 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); 1221 } 1222 1223 /* 1224 * ppp_send_config - configure the transmit-side characteristics of 1225 * the ppp interface. Returns -1, indicating an error, if the channel 1226 * send_config procedure called error() (or incremented error_count 1227 * itself), otherwise 0. 1228 */ 1229 int 1230 ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) 1231 { 1232 int errs; 1233 1234 if (the_channel->send_config == NULL) 1235 return 0; 1236 errs = error_count; 1237 (*the_channel->send_config)(mtu, accm, pcomp, accomp); 1238 return (error_count != errs)? -1: 0; 1239 } 1240 1241 /* 1242 * ppp_recv_config - configure the receive-side characteristics of 1243 * the ppp interface. Returns -1, indicating an error, if the channel 1244 * recv_config procedure called error() (or incremented error_count 1245 * itself), otherwise 0. 1246 */ 1247 int 1248 ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) 1249 { 1250 int errs; 1251 1252 if (the_channel->recv_config == NULL) 1253 return 0; 1254 errs = error_count; 1255 (*the_channel->recv_config)(mru, accm, pcomp, accomp); 1256 return (error_count != errs)? -1: 0; 1257 } 1258 1259 /* 1260 * new_phase - signal the start of a new phase of pppd's operation. 1261 */ 1262 void 1263 new_phase(ppp_phase_t p) 1264 { 1265 switch (p) { 1266 case PHASE_NETWORK: 1267 if (phase <= PHASE_NETWORK) { 1268 char iftmpname[IFNAMSIZ]; 1269 int ifindex = if_nametoindex(ifname); 1270 run_net_script(path_net_preup, 1); 1271 if (if_indextoname(ifindex, iftmpname) && strcmp(iftmpname, ifname)) { 1272 info("Detected interface name change from %s to %s.", ifname, iftmpname); 1273 strcpy(ifname, iftmpname); 1274 } 1275 } 1276 break; 1277 case PHASE_DISCONNECT: 1278 run_net_script(path_net_down, 0); 1279 break; 1280 default: 1281 break; 1282 } 1283 1284 phase = p; 1285 if (new_phase_hook) 1286 (*new_phase_hook)(p); 1287 notify(phasechange, p); 1288 } 1289 1290 bool 1291 in_phase(ppp_phase_t p) 1292 { 1293 return (phase == p); 1294 } 1295 1296 /* 1297 * die - clean up state and exit with the specified status. 1298 */ 1299 void 1300 die(int status) 1301 { 1302 1303 if (!mp_on() || mp_master()) 1304 print_link_stats(); 1305 cleanup(); 1306 notify(exitnotify, status); 1307 syslog(LOG_INFO, "Exit."); 1308 exit(status); 1309 } 1310 1311 /* 1312 * cleanup - restore anything which needs to be restored before we exit 1313 */ 1314 /* ARGSUSED */ 1315 static void 1316 cleanup(void) 1317 { 1318 sys_cleanup(); 1319 1320 if (fd_ppp >= 0) 1321 the_channel->disestablish_ppp(devfd); 1322 if (the_channel->cleanup) 1323 (*the_channel->cleanup)(); 1324 remove_pidfiles(); 1325 1326 #ifdef PPP_WITH_TDB 1327 if (pppdb != NULL) 1328 cleanup_db(); 1329 #endif 1330 1331 } 1332 1333 void 1334 print_link_stats(void) 1335 { 1336 /* 1337 * Print connect time and statistics. 1338 */ 1339 if (link_stats_print && link_stats_valid) { 1340 int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ 1341 info("Connect time %d.%d minutes.", t/10, t%10); 1342 info("Sent %llu bytes, received %llu bytes.", 1343 link_stats.bytes_out, link_stats.bytes_in); 1344 link_stats_print = 0; 1345 } 1346 } 1347 1348 /* 1349 * reset_link_stats - "reset" stats when link goes up. 1350 */ 1351 void 1352 reset_link_stats(int u) 1353 { 1354 get_ppp_stats(u, &old_link_stats); 1355 ppp_get_time(&start_time); 1356 link_stats_print = 1; 1357 } 1358 1359 /* 1360 * update_link_stats - get stats at link termination. 1361 */ 1362 static void 1363 update_link_stats(int u) 1364 { 1365 struct timeval now; 1366 char numbuf[32]; 1367 1368 if (!get_ppp_stats(u, &link_stats) 1369 || ppp_get_time(&now) < 0) 1370 return; 1371 link_connect_time = now.tv_sec - start_time.tv_sec; 1372 link_stats_valid = 1; 1373 1374 link_stats.bytes_in -= old_link_stats.bytes_in; 1375 link_stats.bytes_out -= old_link_stats.bytes_out; 1376 link_stats.pkts_in -= old_link_stats.pkts_in; 1377 link_stats.pkts_out -= old_link_stats.pkts_out; 1378 1379 slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); 1380 ppp_script_setenv("CONNECT_TIME", numbuf, 0); 1381 snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_out); 1382 ppp_script_setenv("BYTES_SENT", numbuf, 0); 1383 snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_in); 1384 ppp_script_setenv("BYTES_RCVD", numbuf, 0); 1385 } 1386 1387 bool 1388 ppp_get_link_stats(ppp_link_stats_st *stats) 1389 { 1390 update_link_stats(0); 1391 if (stats != NULL && 1392 link_stats_valid) { 1393 1394 memcpy(stats, &link_stats, sizeof(*stats)); 1395 return true; 1396 } 1397 return false; 1398 } 1399 1400 1401 struct callout { 1402 struct timeval c_time; /* time at which to call routine */ 1403 void *c_arg; /* argument to routine */ 1404 void (*c_func)(void *); /* routine */ 1405 struct callout *c_next; 1406 }; 1407 1408 static struct callout *callout = NULL; /* Callout list */ 1409 static struct timeval timenow; /* Current time */ 1410 1411 /* 1412 * timeout - Schedule a timeout. 1413 */ 1414 void 1415 ppp_timeout(void (*func)(void *), void *arg, int secs, int usecs) 1416 { 1417 struct callout *newp, *p, **pp; 1418 1419 /* 1420 * Allocate timeout. 1421 */ 1422 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) 1423 fatal("Out of memory in timeout()!"); 1424 newp->c_arg = arg; 1425 newp->c_func = func; 1426 ppp_get_time(&timenow); 1427 newp->c_time.tv_sec = timenow.tv_sec + secs; 1428 newp->c_time.tv_usec = timenow.tv_usec + usecs; 1429 if (newp->c_time.tv_usec >= 1000000) { 1430 newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000; 1431 newp->c_time.tv_usec %= 1000000; 1432 } 1433 1434 /* 1435 * Find correct place and link it in. 1436 */ 1437 for (pp = &callout; (p = *pp); pp = &p->c_next) 1438 if (newp->c_time.tv_sec < p->c_time.tv_sec 1439 || (newp->c_time.tv_sec == p->c_time.tv_sec 1440 && newp->c_time.tv_usec < p->c_time.tv_usec)) 1441 break; 1442 newp->c_next = p; 1443 *pp = newp; 1444 } 1445 1446 1447 /* 1448 * untimeout - Unschedule a timeout. 1449 */ 1450 void 1451 ppp_untimeout(void (*func)(void *), void *arg) 1452 { 1453 struct callout **copp, *freep; 1454 1455 /* 1456 * Find first matching timeout and remove it from the list. 1457 */ 1458 for (copp = &callout; (freep = *copp); copp = &freep->c_next) 1459 if (freep->c_func == func && freep->c_arg == arg) { 1460 *copp = freep->c_next; 1461 free((char *) freep); 1462 break; 1463 } 1464 } 1465 1466 1467 /* 1468 * calltimeout - Call any timeout routines which are now due. 1469 */ 1470 static void 1471 calltimeout(void) 1472 { 1473 struct callout *p; 1474 1475 while (callout != NULL) { 1476 p = callout; 1477 1478 if (ppp_get_time(&timenow) < 0) 1479 fatal("Failed to get time of day: %m"); 1480 if (!(p->c_time.tv_sec < timenow.tv_sec 1481 || (p->c_time.tv_sec == timenow.tv_sec 1482 && p->c_time.tv_usec <= timenow.tv_usec))) 1483 break; /* no, it's not time yet */ 1484 1485 callout = p->c_next; 1486 (*p->c_func)(p->c_arg); 1487 1488 free((char *) p); 1489 } 1490 } 1491 1492 1493 /* 1494 * timeleft - return the length of time until the next timeout is due. 1495 */ 1496 static struct timeval * 1497 timeleft(struct timeval *tvp) 1498 { 1499 if (callout == NULL) 1500 return NULL; 1501 1502 ppp_get_time(&timenow); 1503 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; 1504 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; 1505 if (tvp->tv_usec < 0) { 1506 tvp->tv_usec += 1000000; 1507 tvp->tv_sec -= 1; 1508 } 1509 if (tvp->tv_sec < 0) 1510 tvp->tv_sec = tvp->tv_usec = 0; 1511 1512 return tvp; 1513 } 1514 1515 1516 /* 1517 * kill_my_pg - send a signal to our process group, and ignore it ourselves. 1518 * We assume that sig is currently blocked. 1519 */ 1520 static void 1521 kill_my_pg(int sig) 1522 { 1523 struct sigaction act, oldact; 1524 struct subprocess *chp; 1525 1526 if (!detached) { 1527 /* 1528 * There might be other things in our process group that we 1529 * didn't start that would get hit if we did a kill(0), so 1530 * just send the signal individually to our children. 1531 */ 1532 for (chp = children; chp != NULL; chp = chp->next) 1533 if (chp->killable) 1534 kill(chp->pid, sig); 1535 return; 1536 } 1537 1538 /* We've done a setsid(), so we can just use a kill(0) */ 1539 sigemptyset(&act.sa_mask); /* unnecessary in fact */ 1540 act.sa_handler = SIG_IGN; 1541 act.sa_flags = 0; 1542 kill(0, sig); 1543 /* 1544 * The kill() above made the signal pending for us, as well as 1545 * the rest of our process group, but we don't want it delivered 1546 * to us. It is blocked at the moment. Setting it to be ignored 1547 * will cause the pending signal to be discarded. If we did the 1548 * kill() after setting the signal to be ignored, it is unspecified 1549 * (by POSIX) whether the signal is immediately discarded or left 1550 * pending, and in fact Linux would leave it pending, and so it 1551 * would be delivered after the current signal handler exits, 1552 * leading to an infinite loop. 1553 */ 1554 sigaction(sig, &act, &oldact); 1555 sigaction(sig, &oldact, NULL); 1556 } 1557 1558 1559 /* 1560 * hup - Catch SIGHUP signal. 1561 * 1562 * Indicates that the physical layer has been disconnected. 1563 * We don't rely on this indication; if the user has sent this 1564 * signal, we just take the link down. 1565 */ 1566 static void 1567 hup(int sig) 1568 { 1569 /* can't log a message here, it can deadlock */ 1570 got_sighup = 1; 1571 if (conn_running) 1572 /* Send the signal to the [dis]connector process(es) also */ 1573 kill_my_pg(sig); 1574 notify(sigreceived, sig); 1575 if (waiting) { 1576 #pragma GCC diagnostic push 1577 #pragma GCC diagnostic ignored "-Wunused-result" 1578 write(sigpipe[1], &sig, sizeof(sig)); 1579 #pragma GCC diagnostic pop 1580 } 1581 } 1582 1583 1584 /* 1585 * term - Catch SIGTERM signal and SIGINT signal (^C/del). 1586 * 1587 * Indicates that we should initiate a graceful disconnect and exit. 1588 */ 1589 /*ARGSUSED*/ 1590 static void 1591 term(int sig) 1592 { 1593 /* can't log a message here, it can deadlock */ 1594 got_sigterm = sig; 1595 if (conn_running) 1596 /* Send the signal to the [dis]connector process(es) also */ 1597 kill_my_pg(sig); 1598 notify(sigreceived, sig); 1599 if (waiting) { 1600 #pragma GCC diagnostic push 1601 #pragma GCC diagnostic ignored "-Wunused-result" 1602 write(sigpipe[1], &sig, sizeof(sig)); 1603 #pragma GCC diagnostic pop 1604 } 1605 } 1606 1607 1608 /* 1609 * chld - Catch SIGCHLD signal. 1610 * Sets a flag so we will call reap_kids in the mainline. 1611 */ 1612 static void 1613 chld(int sig) 1614 { 1615 got_sigchld = 1; 1616 if (waiting) { 1617 #pragma GCC diagnostic push 1618 #pragma GCC diagnostic ignored "-Wunused-result" 1619 write(sigpipe[1], &sig, sizeof(sig)); 1620 #pragma GCC diagnostic pop 1621 } 1622 } 1623 1624 1625 /* 1626 * toggle_debug - Catch SIGUSR1 signal. 1627 * 1628 * Toggle debug flag. 1629 */ 1630 /*ARGSUSED*/ 1631 static void 1632 toggle_debug(int sig) 1633 { 1634 debug = !debug; 1635 if (debug) { 1636 setlogmask(LOG_UPTO(LOG_DEBUG)); 1637 } else { 1638 setlogmask(LOG_UPTO(LOG_WARNING)); 1639 } 1640 } 1641 1642 1643 /* 1644 * open_ccp - Catch SIGUSR2 signal. 1645 * 1646 * Try to (re)negotiate compression. 1647 */ 1648 /*ARGSUSED*/ 1649 static void 1650 open_ccp(int sig) 1651 { 1652 got_sigusr2 = 1; 1653 if (waiting) { 1654 #pragma GCC diagnostic push 1655 #pragma GCC diagnostic ignored "-Wunused-result" 1656 write(sigpipe[1], &sig, sizeof(sig)); 1657 #pragma GCC diagnostic pop 1658 } 1659 } 1660 1661 1662 /* 1663 * bad_signal - We've caught a fatal signal. Clean up state and exit. 1664 */ 1665 static void 1666 bad_signal(int sig) 1667 { 1668 static int crashed = 0; 1669 1670 if (crashed) 1671 _exit(127); 1672 crashed = 1; 1673 error("Fatal signal %d", sig); 1674 if (conn_running) 1675 kill_my_pg(SIGTERM); 1676 notify(sigreceived, sig); 1677 die(127); 1678 } 1679 1680 /* 1681 * ppp_safe_fork - Create a child process. The child closes all the 1682 * file descriptors that we don't want to leak to a script. 1683 * The parent waits for the child to do this before returning. 1684 * This also arranges for the specified fds to be dup'd to 1685 * fds 0, 1, 2 in the child. 1686 */ 1687 pid_t 1688 ppp_safe_fork(int infd, int outfd, int errfd) 1689 { 1690 pid_t pid; 1691 int fd, pipefd[2]; 1692 char buf[1]; 1693 1694 /* make sure fds 0, 1, 2 are occupied (probably not necessary) */ 1695 while ((fd = dup(fd_devnull)) >= 0) { 1696 if (fd > 2) { 1697 close(fd); 1698 break; 1699 } 1700 } 1701 1702 if (pipe(pipefd) == -1) 1703 pipefd[0] = pipefd[1] = -1; 1704 pid = fork(); 1705 if (pid < 0) { 1706 error("fork failed: %m"); 1707 return -1; 1708 } 1709 if (pid > 0) { 1710 /* parent */ 1711 close(pipefd[1]); 1712 /* this read() blocks until the close(pipefd[1]) below */ 1713 complete_read(pipefd[0], buf, 1); 1714 close(pipefd[0]); 1715 return pid; 1716 } 1717 1718 /* Executing in the child */ 1719 ppp_sys_close(); 1720 #ifdef PPP_WITH_TDB 1721 if (pppdb != NULL) 1722 tdb_close(pppdb); 1723 #endif 1724 1725 /* make sure infd, outfd and errfd won't get tromped on below */ 1726 if (infd == 1 || infd == 2) 1727 infd = dup(infd); 1728 if (outfd == 0 || outfd == 2) 1729 outfd = dup(outfd); 1730 if (errfd == 0 || errfd == 1) 1731 errfd = dup(errfd); 1732 1733 closelog(); 1734 1735 /* dup the in, out, err fds to 0, 1, 2 */ 1736 if (infd != 0) 1737 dup2(infd, 0); 1738 if (outfd != 1) 1739 dup2(outfd, 1); 1740 if (errfd != 2) 1741 dup2(errfd, 2); 1742 1743 if (log_to_fd > 2) 1744 close(log_to_fd); 1745 if (the_channel->close) 1746 (*the_channel->close)(); 1747 else 1748 close(devfd); /* some plugins don't have a close function */ 1749 close(fd_ppp); 1750 close(fd_devnull); 1751 if (infd != 0) 1752 close(infd); 1753 if (outfd != 1) 1754 close(outfd); 1755 if (errfd != 2) 1756 close(errfd); 1757 1758 notify(fork_notifier, 0); 1759 close(pipefd[0]); 1760 /* this close unblocks the read() call above in the parent */ 1761 close(pipefd[1]); 1762 1763 return 0; 1764 } 1765 1766 static bool 1767 add_script_env(int pos, char *newstring) 1768 { 1769 if (pos + 1 >= s_env_nalloc) { 1770 int new_n = pos + 17; 1771 char **newenv = realloc(script_env, new_n * sizeof(char *)); 1772 if (newenv == NULL) { 1773 free(newstring - 1); 1774 return 0; 1775 } 1776 script_env = newenv; 1777 s_env_nalloc = new_n; 1778 } 1779 script_env[pos] = newstring; 1780 script_env[pos + 1] = NULL; 1781 return 1; 1782 } 1783 1784 static void 1785 remove_script_env(int pos) 1786 { 1787 free(script_env[pos] - 1); 1788 while ((script_env[pos] = script_env[pos + 1]) != NULL) 1789 pos++; 1790 } 1791 1792 /* 1793 * update_system_environment - process the list of set/unset options 1794 * and update the system environment. 1795 */ 1796 static void 1797 update_system_environment(void) 1798 { 1799 struct userenv *uep; 1800 1801 for (uep = userenv_list; uep != NULL; uep = uep->ue_next) { 1802 if (uep->ue_isset) 1803 setenv(uep->ue_name, uep->ue_value, 1); 1804 else 1805 unsetenv(uep->ue_name); 1806 } 1807 } 1808 1809 /* 1810 * device_script - run a program to talk to the specified fds 1811 * (e.g. to run the connector or disconnector script). 1812 * stderr gets connected to the log fd or to the PPP_PATH_CONNERRS file. 1813 */ 1814 int 1815 device_script(char *program, int in, int out, int dont_wait) 1816 { 1817 int pid; 1818 int status = -1; 1819 int errfd; 1820 int ret; 1821 1822 if (log_to_fd >= 0) 1823 errfd = log_to_fd; 1824 else { 1825 errfd = open(PPP_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); 1826 if (errfd == -1) { 1827 error("Cannot open `%s': %m", PPP_PATH_CONNERRS); 1828 return -1; 1829 } 1830 } 1831 1832 ++conn_running; 1833 pid = ppp_safe_fork(in, out, errfd); 1834 1835 if (pid != 0 && log_to_fd < 0) 1836 close(errfd); 1837 1838 if (pid < 0) { 1839 --conn_running; 1840 error("Failed to create child process: %m"); 1841 return -1; 1842 } 1843 1844 if (pid != 0) { 1845 record_child(pid, program, NULL, NULL, 1); 1846 status = 0; 1847 if (!dont_wait) { 1848 while (waitpid(pid, &status, 0) < 0) { 1849 if (errno == EINTR) 1850 continue; 1851 fatal("error waiting for (dis)connection process: %m"); 1852 } 1853 forget_child(pid, status); 1854 --conn_running; 1855 } 1856 return (status == 0 ? 0 : -1); 1857 } 1858 1859 /* here we are executing in the child */ 1860 ret = setgid(getgid()); 1861 if (ret != 0) { 1862 perror("pppd: setgid failed\n"); 1863 exit(1); 1864 } 1865 ret = setuid(uid); 1866 if (ret != 0 || getuid() != uid) { 1867 perror("pppd: setuid failed\n"); 1868 exit(1); 1869 } 1870 update_system_environment(); 1871 execl("/bin/sh", "sh", "-c", program, (char *)0); 1872 perror("pppd: could not exec /bin/sh"); 1873 _exit(99); 1874 /* NOTREACHED */ 1875 } 1876 1877 1878 /* 1879 * update_script_environment - process the list of set/unset options 1880 * and update the script environment. Note that we intentionally do 1881 * not update the TDB. These changes are layered on top right before 1882 * exec. It is not possible to use script_setenv() or 1883 * ppp_script_unsetenv() safely after this routine is run. 1884 */ 1885 static void 1886 update_script_environment(void) 1887 { 1888 struct userenv *uep; 1889 1890 for (uep = userenv_list; uep != NULL; uep = uep->ue_next) { 1891 int i; 1892 char *p, *newstring; 1893 int nlen = strlen(uep->ue_name); 1894 1895 for (i = 0; (p = script_env[i]) != NULL; i++) { 1896 if (strncmp(p, uep->ue_name, nlen) == 0 && p[nlen] == '=') 1897 break; 1898 } 1899 if (uep->ue_isset) { 1900 nlen += strlen(uep->ue_value) + 2; 1901 newstring = malloc(nlen + 1); 1902 if (newstring == NULL) 1903 continue; 1904 *newstring++ = 0; 1905 slprintf(newstring, nlen, "%s=%s", uep->ue_name, uep->ue_value); 1906 if (p != NULL) 1907 script_env[i] = newstring; 1908 else 1909 add_script_env(i, newstring); 1910 } else if (p != NULL) { 1911 remove_script_env(i); 1912 } 1913 } 1914 } 1915 1916 /* 1917 * run_program - execute a program with given arguments, 1918 * but don't wait for it unless wait is non-zero. 1919 * If the program can't be executed, logs an error unless 1920 * must_exist is 0 and the program file doesn't exist. 1921 * Returns -1 if it couldn't fork, 0 if the file doesn't exist 1922 * or isn't an executable plain file, or the process ID of the child. 1923 * If done != NULL, (*done)(arg) will be called later (within 1924 * reap_kids) iff the return value is > 0. 1925 */ 1926 pid_t 1927 run_program(char *prog, char * const *args, int must_exist, void (*done)(void *), void *arg, int wait) 1928 { 1929 int pid, status, ret; 1930 struct stat sbuf; 1931 1932 /* 1933 * First check if the file exists and is executable. 1934 * We don't use access() because that would use the 1935 * real user-id, which might not be root, and the script 1936 * might be accessible only to root. 1937 */ 1938 errno = EINVAL; 1939 if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) 1940 || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { 1941 if (must_exist || errno != ENOENT) 1942 warn("Can't execute %s: %m", prog); 1943 return 0; 1944 } 1945 1946 pid = ppp_safe_fork(fd_devnull, fd_devnull, fd_devnull); 1947 if (pid == -1) { 1948 error("Failed to create child process for %s: %m", prog); 1949 return -1; 1950 } 1951 if (pid != 0) { 1952 if (debug) 1953 dbglog("Script %s started (pid %d)", prog, pid); 1954 record_child(pid, prog, done, arg, 0); 1955 if (wait) { 1956 while (waitpid(pid, &status, 0) < 0) { 1957 if (errno == EINTR) 1958 continue; 1959 fatal("error waiting for script %s: %m", prog); 1960 } 1961 forget_child(pid, status); 1962 } 1963 return pid; 1964 } 1965 1966 /* Leave the current location */ 1967 (void) setsid(); /* No controlling tty. */ 1968 (void) umask (S_IRWXG|S_IRWXO); 1969 ret = chdir ("/"); /* no current directory. */ 1970 if (ret != 0) { 1971 fatal("Failed to change directory to '/', %m"); 1972 } 1973 ret = setuid(0); /* set real UID = root */ 1974 if (ret != 0) { 1975 fatal("Failed to set uid, %m"); 1976 } 1977 ret = setgid(getegid()); 1978 if (ret != 0) { 1979 fatal("failed to set gid, %m"); 1980 } 1981 1982 #ifdef BSD 1983 /* Force the priority back to zero if pppd is running higher. */ 1984 if (setpriority (PRIO_PROCESS, 0, 0) < 0) 1985 warn("can't reset priority to 0: %m"); 1986 #endif 1987 1988 /* run the program */ 1989 update_script_environment(); 1990 execve(prog, args, script_env); 1991 if (must_exist || errno != ENOENT) { 1992 /* have to reopen the log, there's nowhere else 1993 for the message to go. */ 1994 reopen_log(); 1995 syslog(LOG_ERR, "Can't execute %s: %m", prog); 1996 closelog(); 1997 } 1998 _exit(99); 1999 } 2000 2001 2002 /* 2003 * record_child - add a child process to the list for reap_kids 2004 * to use. 2005 */ 2006 void 2007 record_child(int pid, char *prog, void (*done)(void *), void *arg, int killable) 2008 { 2009 struct subprocess *chp; 2010 2011 ++n_children; 2012 2013 chp = (struct subprocess *) malloc(sizeof(struct subprocess)); 2014 if (chp == NULL) { 2015 warn("losing track of %s process", prog); 2016 } else { 2017 chp->pid = pid; 2018 chp->prog = prog; 2019 chp->done = done; 2020 chp->arg = arg; 2021 chp->next = children; 2022 chp->killable = killable; 2023 children = chp; 2024 } 2025 } 2026 2027 /* 2028 * childwait_end - we got fed up waiting for the child processes to 2029 * exit, send them all a SIGTERM. 2030 */ 2031 static void 2032 childwait_end(void *arg) 2033 { 2034 struct subprocess *chp; 2035 2036 for (chp = children; chp != NULL; chp = chp->next) { 2037 if (debug) 2038 dbglog("sending SIGTERM to process %d", chp->pid); 2039 kill(chp->pid, SIGTERM); 2040 } 2041 childwait_done = 1; 2042 } 2043 2044 /* 2045 * forget_child - clean up after a dead child 2046 */ 2047 static void 2048 forget_child(int pid, int status) 2049 { 2050 struct subprocess *chp, **prevp; 2051 2052 for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) { 2053 if (chp->pid == pid) { 2054 --n_children; 2055 *prevp = chp->next; 2056 break; 2057 } 2058 } 2059 if (WIFSIGNALED(status)) { 2060 warn("Child process %s (pid %d) terminated with signal %d", 2061 (chp? chp->prog: "??"), pid, WTERMSIG(status)); 2062 } else if (debug) 2063 dbglog("Script %s finished (pid %d), status = 0x%x", 2064 (chp? chp->prog: "??"), pid, 2065 WIFEXITED(status) ? WEXITSTATUS(status) : status); 2066 if (chp && chp->done) 2067 (*chp->done)(chp->arg); 2068 if (chp) 2069 free(chp); 2070 } 2071 2072 /* 2073 * reap_kids - get status from any dead child processes, 2074 * and log a message for abnormal terminations. 2075 */ 2076 static int 2077 reap_kids(void) 2078 { 2079 int pid, status; 2080 2081 if (n_children == 0) 2082 return 0; 2083 while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) { 2084 forget_child(pid, status); 2085 } 2086 if (pid == -1) { 2087 if (errno == ECHILD) 2088 return -1; 2089 if (errno != EINTR) 2090 error("Error waiting for child process: %m"); 2091 } 2092 return 0; 2093 } 2094 2095 2096 static struct notifier **get_notifier_by_type(ppp_notify_t type) 2097 { 2098 struct notifier **list[NF_MAX_NOTIFY] = { 2099 [NF_PID_CHANGE ] = &pidchange, 2100 [NF_PHASE_CHANGE] = &phasechange, 2101 [NF_EXIT ] = &exitnotify, 2102 [NF_SIGNALED ] = &sigreceived, 2103 [NF_IP_UP ] = &ip_up_notifier, 2104 [NF_IP_DOWN ] = &ip_down_notifier, 2105 #ifdef PPP_WITH_IPV6CP 2106 [NF_IPV6_UP ] = &ipv6_up_notifier, 2107 [NF_IPV6_DOWN ] = &ipv6_down_notifier, 2108 #endif 2109 [NF_AUTH_UP ] = &auth_up_notifier, 2110 [NF_LINK_DOWN ] = &link_down_notifier, 2111 [NF_FORK ] = &fork_notifier, 2112 }; 2113 return list[type]; 2114 } 2115 2116 /* 2117 * add_notifier - add a new function to be called when something happens. 2118 */ 2119 void 2120 ppp_add_notify(ppp_notify_t type, ppp_notify_fn *func, void *arg) 2121 { 2122 struct notifier **notif = get_notifier_by_type(type); 2123 if (notif) { 2124 2125 struct notifier *np = malloc(sizeof(struct notifier)); 2126 if (np == 0) 2127 novm("notifier struct"); 2128 np->next = *notif; 2129 np->func = func; 2130 np->arg = arg; 2131 *notif = np; 2132 } else { 2133 error("Could not find notifier function for: %d", type); 2134 } 2135 } 2136 2137 /* 2138 * remove_notifier - remove a function from the list of things to 2139 * be called when something happens. 2140 */ 2141 void 2142 ppp_del_notify(ppp_notify_t type, ppp_notify_fn *func, void *arg) 2143 { 2144 struct notifier **notif = get_notifier_by_type(type); 2145 if (notif) { 2146 struct notifier *np; 2147 2148 for (; (np = *notif) != 0; notif = &np->next) { 2149 if (np->func == func && np->arg == arg) { 2150 *notif = np->next; 2151 free(np); 2152 break; 2153 } 2154 } 2155 } else { 2156 error("Could not find notifier function for: %d", type); 2157 } 2158 } 2159 2160 /* 2161 * notify - call a set of functions registered with add_notifier. 2162 */ 2163 void 2164 notify(struct notifier *notif, int val) 2165 { 2166 struct notifier *np; 2167 2168 while ((np = notif) != 0) { 2169 notif = np->next; 2170 (*np->func)(np->arg, val); 2171 } 2172 } 2173 2174 /* 2175 * novm - log an error message saying we ran out of memory, and die. 2176 */ 2177 void 2178 novm(const char *msg) 2179 { 2180 fatal("Virtual memory exhausted allocating %s\n", msg); 2181 } 2182 2183 /* 2184 * ppp_script_setenv - set an environment variable value to be used 2185 * for scripts that we run (e.g. ip-up, auth-up, etc.) 2186 */ 2187 void 2188 ppp_script_setenv(char *var, char *value, int iskey) 2189 { 2190 size_t varl = strlen(var); 2191 size_t vl = varl + strlen(value) + 2; 2192 int i; 2193 char *p, *newstring; 2194 2195 newstring = (char *) malloc(vl+1); 2196 if (newstring == 0) 2197 return; 2198 *newstring++ = iskey; 2199 slprintf(newstring, vl, "%s=%s", var, value); 2200 2201 /* check if this variable is already set */ 2202 if (script_env != 0) { 2203 for (i = 0; (p = script_env[i]) != 0; ++i) { 2204 if (strncmp(p, var, varl) == 0 && p[varl] == '=') { 2205 #ifdef PPP_WITH_TDB 2206 if (p[-1] && pppdb != NULL) 2207 delete_db_key(p); 2208 #endif 2209 free(p-1); 2210 script_env[i] = newstring; 2211 #ifdef PPP_WITH_TDB 2212 if (pppdb != NULL) { 2213 if (iskey) 2214 add_db_key(newstring); 2215 update_db_entry(); 2216 } 2217 #endif 2218 return; 2219 } 2220 } 2221 } else { 2222 /* no space allocated for script env. ptrs. yet */ 2223 i = 0; 2224 script_env = malloc(16 * sizeof(char *)); 2225 if (script_env == 0) { 2226 free(newstring - 1); 2227 return; 2228 } 2229 s_env_nalloc = 16; 2230 } 2231 2232 if (!add_script_env(i, newstring)) 2233 return; 2234 2235 #ifdef PPP_WITH_TDB 2236 if (pppdb != NULL) { 2237 if (iskey) 2238 add_db_key(newstring); 2239 update_db_entry(); 2240 } 2241 #endif 2242 } 2243 2244 /* 2245 * ppp_script_unsetenv - remove a variable from the environment 2246 * for scripts. 2247 */ 2248 void 2249 ppp_script_unsetenv(char *var) 2250 { 2251 int vl = strlen(var); 2252 int i; 2253 char *p; 2254 2255 if (script_env == 0) 2256 return; 2257 for (i = 0; (p = script_env[i]) != 0; ++i) { 2258 if (strncmp(p, var, vl) == 0 && p[vl] == '=') { 2259 #ifdef PPP_WITH_TDB 2260 if (p[-1] && pppdb != NULL) 2261 delete_db_key(p); 2262 #endif 2263 remove_script_env(i); 2264 break; 2265 } 2266 } 2267 #ifdef PPP_WITH_TDB 2268 if (pppdb != NULL) 2269 update_db_entry(); 2270 #endif 2271 } 2272 2273 /* 2274 * Any arbitrary string used as a key for locking the database. 2275 * It doesn't matter what it is as long as all pppds use the same string. 2276 */ 2277 #define PPPD_LOCK_KEY "pppd lock" 2278 2279 /* 2280 * lock_db - get an exclusive lock on the TDB database. 2281 * Used to ensure atomicity of various lookup/modify operations. 2282 */ 2283 void lock_db(void) 2284 { 2285 #ifdef PPP_WITH_TDB 2286 TDB_DATA key; 2287 2288 key.dptr = PPPD_LOCK_KEY; 2289 key.dsize = strlen(key.dptr); 2290 tdb_chainlock(pppdb, key); 2291 #endif 2292 } 2293 2294 /* 2295 * unlock_db - remove the exclusive lock obtained by lock_db. 2296 */ 2297 void unlock_db(void) 2298 { 2299 #ifdef PPP_WITH_TDB 2300 TDB_DATA key; 2301 2302 key.dptr = PPPD_LOCK_KEY; 2303 key.dsize = strlen(key.dptr); 2304 tdb_chainunlock(pppdb, key); 2305 #endif 2306 } 2307 2308 #ifdef PPP_WITH_TDB 2309 /* 2310 * update_db_entry - update our entry in the database. 2311 */ 2312 static void 2313 update_db_entry(void) 2314 { 2315 TDB_DATA key, dbuf; 2316 int vlen, i; 2317 char *p, *q, *vbuf; 2318 2319 if (script_env == NULL) 2320 return; 2321 vlen = 0; 2322 for (i = 0; (p = script_env[i]) != 0; ++i) 2323 vlen += strlen(p) + 1; 2324 vbuf = malloc(vlen + 1); 2325 if (vbuf == 0) 2326 novm("database entry"); 2327 q = vbuf; 2328 for (i = 0; (p = script_env[i]) != 0; ++i) 2329 q += slprintf(q, vbuf + vlen - q, "%s;", p); 2330 2331 key.dptr = db_key; 2332 key.dsize = strlen(db_key); 2333 dbuf.dptr = vbuf; 2334 dbuf.dsize = vlen; 2335 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) 2336 error("tdb_store failed: %s", tdb_errorstr(pppdb)); 2337 2338 if (vbuf) 2339 free(vbuf); 2340 2341 } 2342 2343 /* 2344 * add_db_key - add a key that we can use to look up our database entry. 2345 */ 2346 static void 2347 add_db_key(const char *str) 2348 { 2349 TDB_DATA key, dbuf; 2350 2351 key.dptr = (char *) str; 2352 key.dsize = strlen(str); 2353 dbuf.dptr = db_key; 2354 dbuf.dsize = strlen(db_key); 2355 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) 2356 error("tdb_store key failed: %s", tdb_errorstr(pppdb)); 2357 } 2358 2359 /* 2360 * delete_db_key - delete a key for looking up our database entry. 2361 */ 2362 static void 2363 delete_db_key(const char *str) 2364 { 2365 TDB_DATA key; 2366 2367 key.dptr = (char *) str; 2368 key.dsize = strlen(str); 2369 tdb_delete(pppdb, key); 2370 } 2371 2372 /* 2373 * cleanup_db - delete all the entries we put in the database. 2374 */ 2375 static void 2376 cleanup_db(void) 2377 { 2378 TDB_DATA key; 2379 int i; 2380 char *p; 2381 2382 key.dptr = db_key; 2383 key.dsize = strlen(db_key); 2384 tdb_delete(pppdb, key); 2385 for (i = 0; (p = script_env[i]) != 0; ++i) 2386 if (p[-1]) 2387 delete_db_key(p); 2388 } 2389 #endif /* PPP_WITH_TDB */ 2390