1/* 2 * pptpd.c 3 * 4 * Grabs any command line argument and processes any further options in 5 * the pptpd config file, before throwing over to pptpmanager.c. 6 * 7 * $Id: pptpd.c,v 1.18 2006/09/04 23:17:25 quozl Exp $ 8 */ 9 10#ifdef HAVE_CONFIG_H 11#include "config.h" 12#endif 13 14#ifdef __linux__ 15#define _GNU_SOURCE 1 /* strdup() prototype, broken arpa/inet.h */ 16#endif 17 18#ifdef __svr4__ 19#define __EXTENSIONS__ 1 /* strdup() prototype */ 20#endif 21 22#ifdef __sgi__ 23#define _XOPEN_SOURCE 500 /* strdup() prototype */ 24#endif 25 26#include "our_syslog.h" 27#include "our_getopt.h" 28 29#include <fcntl.h> 30#include <netdb.h> 31#include <signal.h> 32#include <stdio.h> 33#include <string.h> 34#include <stdlib.h> 35#include <sys/types.h> 36#include <sys/socket.h> 37#include <netinet/in.h> 38#include <arpa/inet.h> 39#include <sys/wait.h> 40#include <sys/stat.h> 41#include <unistd.h> 42 43#include "configfile.h" 44#include "defaults.h" 45#include "compat.h" 46#include "pptpmanager.h" 47 48#ifdef CONFIG_NETtel 49#include <linux/ledman.h> 50#endif 51 52/* command line arg variables */ 53char *ppp_binary = NULL; 54char *pppdoptstr = NULL; 55char *speedstr = NULL; 56char *bindaddr = NULL; 57#ifdef BCRELAY 58char *bcrelay = NULL; 59#endif 60int pptp_debug = 0; 61int pptp_noipparam = 0; 62int pptp_logwtmp = 0; 63int pptp_delegate = 0; 64 65int pptp_stimeout = STIMEOUT_DEFAULT; 66int pptp_ptimeout = PTIMEOUT_DEFAULT; 67 68int pptp_connections = CONNECTIONS_DEFAULT; 69 70int keep_connections=0; 71 72/* Local prototypes */ 73static void processIPStr(int type, char *ipstr); 74 75#ifndef HAVE_DAEMON 76static void my_daemon(int argc, char **argv); 77#endif 78 79static void log_pid(char *pid_file); 80static char *lookup(char *); 81 82#ifdef BCRELAY 83static void launch_bcrelay(); 84static pid_t bcrelayfork; 85#endif 86 87static void showversion() 88{ 89 printf("accel-pptpd v%s ", VERSION); 90 printf("compiled for pppd-%s, linux-%s\n",PPPD_VERSION,KERNELVERSION); 91} 92static void showusage(char *prog) 93{ 94 showversion(); 95 printf("Usage: pptpd [options], where options are:\n\n"); 96#ifdef BCRELAY 97 printf(" [-b] [--bcrelay if] Use broadcast relay for broadcasts comming from.\n"); 98 printf(" the specified interface (default is eth1).\n"); 99#endif 100 printf(" [-c] [--conf file] Specifies the config file to read default\n"); 101 printf(" settings from (default is %s).\n", PPTPD_CONFIG_FILE_DEFAULT); 102 printf(" [-d] [--debug] Turns on debugging (to syslog).\n"); 103 printf(" [-e] [--ppp file] Use alternate pppd binary, default %s.\n", PPP_BINARY); 104 printf(" [-f] [--fg] Run in foreground.\n"); 105 printf(" [-h] [--help] Displays this help message.\n"); 106 printf(" [-i] [--noipparam] Suppress the passing of the client's IP address\n"); 107 printf(" to PPP, which is done by default otherwise.\n"); 108 printf(" [-l] [--listen x.x.x.x] Specifies IP of local interface to listen to.\n"); 109#if !defined(BSDUSER_PPP) 110 printf(" [-o] [--option file] Specifies the PPP options file to use\n"); 111 printf(" (default is /etc/ppp/options).\n"); 112#endif 113 printf(" [-p] [--pidfile file] Specifies the file to write the process ID to\n"); 114 printf(" (default is /var/run/pptpd.pid).\n"); 115#if !defined(BSDUSER_PPP) 116 printf(" [-s] [--speed baud] Specifies the baud speed for the PPP daemon\n"); 117 printf(" (default is 115200).\n"); 118#endif 119 printf(" [-t] [--stimeout seconds] Specifies the timeout for the first packet. This is a DOS protection\n"); 120 printf(" (default is 10).\n"); 121 printf(" [-T] [--ptimeout msec] Specifies the maximum timeout for the packet.\n"); 122 printf(" (default is 1000).\n"); 123 printf(" [-v] [--version] Displays the pptpd version number.\n"); 124 printf(" [-w] [--logwtmp] Update wtmp as users login.\n"); 125 printf(" [-C] [--connections n] Limit on number of connections.\n"); 126 printf(" [-D] [--delegate] Delegate IP allocation to pppd.\n"); 127 printf(" [-k] [--keep] Keep connections after exit.\n"); 128 printf(" (default do not keep).\n"); 129 130 printf("\n\nLogs and debugging go to syslog as DAEMON."); 131 132 printf("\n\nCommand line options will override any default settings and any settings\n"); 133 printf("specified in the config file (default config file: %s).\n\n", PPTPD_CONFIG_FILE_DEFAULT); 134} 135 136 137 138int main(int argc, char **argv) 139{ 140 /* command line options */ 141 int c; 142 143 /* function-local options */ 144 int foreground = FALSE; 145 char *pid_file = NULL; 146 147 /* config file */ 148 char *configFile = NULL; 149 150 /* config file parsing temp strings */ 151 char tmp[MAX_CONFIG_STRING_SIZE], *tmpstr; 152 153 /* open a connection to the syslog daemon */ 154 openlog("pptpd", LOG_PID, PPTP_FACILITY); 155 syslog(LOG_ERR, "MGR: Config file not found!"); 156 157 /* process command line options */ 158 while (1) { 159 int option_index = 0; 160#ifdef BCRELAY 161 char *optstring = "b:c:de:fhil:o:p:s:t:T:vwC:Dk"; 162#else 163 char *optstring = "c:de:fhil:o:p:s:t:T:vwC:Dk"; 164#endif 165 166 static struct option long_options[] = 167 { 168#ifdef BCRELAY 169 {"bcrelay", 1, 0, 0}, 170#endif 171 {"conf", 1, 0, 'c'}, 172 {"debug", 0, 0, 'd'}, 173 {"ppp", 1, 0, 'e'}, 174 {"fg", 0, 0, 'f'}, 175 {"help", 0, 0, 'h'}, 176 {"noipparam", 0, 0, 'i'}, 177 {"listen", 1, 0, 'l'}, 178 {"option", 1, 0, 'o'}, 179 {"pidfile", 1, 0, 'p'}, 180 {"speed", 1, 0, 's'}, 181 {"stimeout", 1, 0, 't'}, 182 {"ptimeout", 1, 0, 'T'}, 183 {"version", 0, 0, 'v'}, 184 {"logwtmp", 0, 0, 'w'}, 185 {"connections", 1, 0, 'C'}, 186 {"delegate", 0, 0, 'D'}, 187 {"keep", 0, 0, 'k'}, 188 {0, 0, 0, 0} 189 }; 190 191 c = getopt_long(argc, argv, optstring, long_options, &option_index); 192 if (c == -1) 193 break; 194 /* convert long options to short form */ 195 if (c == 0) 196#ifdef BCRELAY 197 c = "bcdefhilopstvwCDk"[option_index]; 198#else 199 c = "cdefhilopstvwCDk"[option_index]; 200#endif 201 switch (c) { 202#ifdef BCRELAY 203 case 'b': /* --bcrelay */ 204 if (bcrelay) free(bcrelay); 205 bcrelay = strdup(optarg); 206 break; 207#endif 208 209 case 'l': /* --listen */ 210 tmpstr = lookup(optarg); 211 if (!tmpstr) { 212 syslog(LOG_ERR, "MGR: Invalid listening address: %s!", optarg); 213 return 1; 214 } 215 if (bindaddr) free(bindaddr); 216 bindaddr = strdup(tmpstr); 217 break; 218 219 case 'h': /* --help */ 220 showusage(argv[0]); 221 return 0; 222 223 case 'i': /* --noipparam */ 224 pptp_noipparam = TRUE; 225 break; 226 227 case 'e': /* --ppp */ 228 if (ppp_binary) free(ppp_binary); 229 ppp_binary = strdup(optarg); 230 break; 231 232 case 'd': /* --debug */ 233 pptp_debug = TRUE; 234 break; 235 236 case 'f': /* --fg */ 237 foreground = TRUE; 238 break; 239 240 case 'v': /* --version */ 241 showversion(); 242 return 0; 243 244 case 'w': /* --logwtmp */ 245 pptp_logwtmp = TRUE; 246 break; 247 248 case 'C': /* --connections */ 249 pptp_connections = atoi(optarg); 250 break; 251 252 case 'D': /* --delegate */ 253 pptp_delegate = TRUE; 254 break; 255 256 case 'o': /* --option */ 257 if (pppdoptstr) free(pppdoptstr); 258 pppdoptstr = strdup(optarg); 259 break; 260 261 case 'p': /* --pidfile */ 262 if (pid_file) free(pid_file); 263 pid_file = strdup(optarg); 264 break; 265 266 case 's': /* --speed */ 267 if (speedstr) free(speedstr); 268 speedstr = strdup(optarg); 269 break; 270 271 case 't': /* --stimeout */ 272 pptp_stimeout = atoi(optarg); 273 break; 274 275 case 'T': /* --stimeout */ 276 pptp_ptimeout = atoi(optarg); 277 break; 278 case 'k': /* --keep */ 279 keep_connections = 1; 280 break; 281 282 case 'c': /* --conf */ 283 { 284 FILE *f; 285 if (!(f = fopen(optarg, "r"))) { 286 syslog(LOG_ERR, "MGR: Config file not found!"); 287 return 1; 288 } 289 fclose(f); 290 if(configFile) free(configFile); 291 configFile = strdup(optarg); 292 break; 293 } 294 295 default: 296 showusage(argv[0]); 297 return 1; 298 } 299 } 300 301 /* Now that we have all the command line args.. lets open the 302 * conf file and add anything else (remembering not to override 303 * anything since the command line has more privilages :-) 304 */ 305 306 if (!configFile) 307 configFile = strdup(PPTPD_CONFIG_FILE_DEFAULT); 308 309 if (read_config_file(configFile, CONNECTIONS_KEYWORD, tmp) > 0) { 310 pptp_connections = atoi(tmp); 311 if (pptp_connections <= 0) 312 pptp_connections = CONNECTIONS_DEFAULT; 313 } 314 315 slot_init(pptp_connections); 316 317 if (!pptp_debug && read_config_file(configFile, DEBUG_KEYWORD, tmp) > 0) 318 pptp_debug = TRUE; 319 320#ifdef BCRELAY 321 if (!bcrelay && read_config_file(configFile, BCRELAY_KEYWORD, tmp) > 0) 322 bcrelay = strdup(tmp); 323#endif 324 325 if (!pptp_stimeout && read_config_file(configFile, STIMEOUT_KEYWORD, tmp) > 0) { 326 pptp_stimeout = atoi(tmp); 327 if (pptp_stimeout <= 0) 328 pptp_stimeout = STIMEOUT_DEFAULT; 329 } 330 331 if (!pptp_ptimeout && read_config_file(configFile, PTIMEOUT_KEYWORD, tmp) > 0) { 332 pptp_ptimeout = atoi(tmp); 333 if (pptp_ptimeout <= 0) 334 pptp_ptimeout = PTIMEOUT_DEFAULT; 335 } 336 337 if (!pptp_noipparam && read_config_file(configFile, NOIPPARAM_KEYWORD, tmp) > 0) { 338 pptp_noipparam = TRUE; 339 } 340 341 if (!bindaddr && read_config_file(configFile, LISTEN_KEYWORD, tmp) > 0) { 342 tmpstr = lookup(tmp); 343 if(!tmpstr) { 344 syslog(LOG_ERR, "MGR: Invalid listening address: %s!", tmp); 345 return 1; 346 } 347 bindaddr = strdup(tmpstr); 348 } 349 350 if (!speedstr && read_config_file(configFile, SPEED_KEYWORD, tmp) > 0) 351 speedstr = strdup(tmp); 352 353 if (!pppdoptstr && read_config_file(configFile, PPPD_OPTION_KEYWORD, tmp) > 0) { 354 pppdoptstr = strdup(tmp); 355 } 356 357 if (!ppp_binary && read_config_file(configFile, PPP_BINARY_KEYWORD, tmp) > 0) { 358 ppp_binary = strdup(tmp); 359 } 360 361 if (!pptp_logwtmp && read_config_file(configFile, LOGWTMP_KEYWORD, tmp) > 0) { 362 pptp_logwtmp = TRUE; 363 } 364 365 if (!pptp_delegate && read_config_file(configFile, DELEGATE_KEYWORD, tmp) > 0) { 366 pptp_delegate = TRUE; 367 } 368 369 if (read_config_file(configFile, KEEP_KEYWORD, tmp) > 0) { 370 keep_connections = TRUE; 371 } 372 373 if (!pid_file) 374 pid_file = strdup((read_config_file(configFile, PIDFILE_KEYWORD, 375 tmp) > 0) ? tmp : PIDFILE_DEFAULT); 376 377 if (!pptp_delegate) { 378 /* NOTE: remote then local, reason can be seen at the end of processIPStr */ 379 380 /* grab the remoteip string from the config file */ 381 if (read_config_file(configFile, REMOTEIP_KEYWORD, tmp) <= 0) { 382 /* use "smart" defaults */ 383 strlcpy(tmp, DEFAULT_REMOTE_IP_LIST, sizeof(tmp)); 384 } 385 processIPStr(REMOTE, tmp); 386 387 /* grab the localip string from the config file */ 388 if (read_config_file(configFile, LOCALIP_KEYWORD, tmp) <= 0) { 389 /* use "smart" defaults */ 390 strlcpy(tmp, DEFAULT_LOCAL_IP_LIST, sizeof(tmp)); 391 } 392 processIPStr(LOCAL, tmp); 393 } 394 395 free(configFile); 396 397 /* if not yet set, adopt default PPP binary path */ 398 if (!ppp_binary) ppp_binary = strdup(PPP_BINARY); 399 /* check that the PPP binary is executable */ 400 if (access(ppp_binary, X_OK) < 0) { 401 syslog(LOG_ERR, "MGR: PPP binary %s not executable", 402 ppp_binary); 403 return 1; 404 } 405 /* check that the PPP options file is readable */ 406 if (pppdoptstr && access(pppdoptstr, R_OK) < 0) { 407 syslog(LOG_ERR, "MGR: PPP options file %s not readable", 408 pppdoptstr); 409 return 1; 410 } 411#ifdef BCRELAY 412 /* check that the bcrelay binary is executable */ 413 if (bcrelay && access(BCRELAY_BIN, X_OK) < 0) { 414 syslog(LOG_ERR, "MGR: bcrelay binary %s not executable", 415 BCRELAY_BIN); 416 return 1; 417 } 418#endif 419 420 syslog(LOG_INFO, "accel-pptpd-%s compiled for pppd-%s, linux-%s\n",VERSION,PPPD_VERSION,KERNELVERSION); 421 422 if (!foreground) { 423#if HAVE_DAEMON 424 closelog(); 425 freopen("/dev/null", "r", stdin); 426 daemon(0, 0); 427 /* returns to child only */ 428 /* pid will have changed */ 429 openlog("pptpd", LOG_PID, PPTP_FACILITY); 430#else /* !HAVE_DAEMON */ 431 my_daemon(argc, argv); 432 /* returns to child if !HAVE_FORK 433 * never returns if HAVE_FORK (re-execs with -f) 434 */ 435#endif 436 } 437 438#ifdef BCRELAY 439 if (bcrelay) { 440 syslog(LOG_DEBUG, "CTRL: BCrelay incoming interface is %s", bcrelay); 441 /* Launch BCrelay */ 442#ifndef HAVE_FORK 443 switch(bcrelayfork = vfork()){ 444#else 445 switch(bcrelayfork = fork()){ 446#endif 447 case -1: /* fork() error */ 448 syslog(LOG_ERR, "CTRL: Error forking to exec bcrelay"); 449 _exit(1); 450 451 case 0: /* child */ 452 syslog(LOG_DEBUG, "CTRL (BCrelay Launcher): Launching BCrelay with pid %i", bcrelayfork); 453 launch_bcrelay(); 454 syslog(LOG_ERR, "CTRL (BCrelay Launcher): Failed to launch BCrelay."); 455 _exit(1); 456 } 457 } /* End bcrelay */ 458#endif 459 460#ifdef CONFIG_NETtel 461 /* turn the NETtel VPN LED on */ 462 ledman_cmd(LEDMAN_CMD_ON, LEDMAN_VPN); 463#endif 464 /* after we have our final pid... */ 465 log_pid(pid_file); 466 467 /* manage connections until SIGTERM */ 468 pptp_manager(argc, argv); 469 470#ifdef BCRELAY 471 if (bcrelayfork > 0) { 472 syslog(LOG_DEBUG, "CTRL: Closing child BCrelay with pid %i", bcrelayfork); 473 kill(bcrelayfork, SIGTERM); 474 } 475#endif 476 477 slot_free(); 478 return 0; 479} 480 481static void log_pid(char *pid_file) { 482 FILE *f; 483 pid_t pid; 484 485 pid = getpid(); 486 if ((f = fopen(pid_file, "w")) == NULL) { 487 syslog(LOG_ERR, "PPTPD: failed to open(%s), errno=%d\n", 488 pid_file, errno); 489 return; 490 } 491 fprintf(f, "%d\n", pid); 492 fclose(f); 493} 494 495#ifndef HAVE_DAEMON 496static void my_daemon(int argc, char **argv) 497{ 498#ifndef HAVE_FORK 499 /* need to use vfork - eg, uClinux */ 500 char **new_argv; 501 int pid; 502 extern char **environ; 503 int fdr; 504 505 new_argv = malloc((argc + 2) * sizeof(char **)); 506 fdr = open("/dev/null", O_RDONLY); 507 syslog(LOG_INFO, "MGR: Option parse OK, re-execing as daemon"); 508 fflush(stderr); 509 if ((pid = vfork()) == 0) { 510 if (fdr != 0) { dup2(fdr, 0); close(fdr); } 511 SETSIDPGRP(); 512 chdir("/"); 513 umask(0); 514 memcpy(new_argv + 1, argv, (argc + 1) * sizeof(char **)); 515 new_argv[0] = PPTPD_BIN; 516 new_argv[1] = "-f"; 517 execve(PPTPD_BIN, new_argv, environ); 518 _exit(1); 519 } else if (pid > 0) { 520 exit(0); 521 } else { 522 syslog_perror("vfork"); 523 exit(1); 524 } 525#else 526 int pid; 527 528 closelog(); 529 if ((pid = fork()) < 0) { 530 syslog_perror("fork"); 531 exit(1); 532 } else if (pid) 533 exit(0); 534 freopen("/dev/null", "r", stdin); 535 SETSIDPGRP(); 536 chdir("/"); 537 umask(0); 538 /* pid will have changed */ 539 openlog("pptpd", LOG_PID, PPTP_FACILITY); 540#endif 541} 542#endif 543 544/* added for hostname/address lookup -tmk 545 * returns NULL if not a valid hostname 546 */ 547static char *lookup(char *hostname) 548{ 549 struct hostent *ent; 550 struct in_addr hst_addr; 551 552 /* Try to parse IP directly */ 553 if (inet_addr(hostname) != -1) 554 return hostname; 555 556 /* Else lookup hostname, return NULL if it fails */ 557 if ((ent = gethostbyname(hostname)) == NULL) 558 return NULL; 559 560 /* That worked, print it back as a dotted quad. */ 561 memcpy(&hst_addr.s_addr, ent->h_addr, ent->h_length); 562 return inet_ntoa(hst_addr); 563} 564 565#define DEBUG_IP_PARSER 0 566 567/* Return the address or NULL if not valid */ 568static char *validip(char *hostname) 569{ 570 /* Try to parse IP directly */ 571 if (inet_addr(hostname) != -1) 572 return hostname; 573 else 574 return NULL; 575} 576 577/* Check if it's a valid IP range */ 578static int isIpRange(char *str) 579{ 580 int dashes = 0; 581 int dots = 0; 582 583#if DEBUG_IP_PARSER 584 syslog(LOG_DEBUG, "MGR: Checking if %s is a valid IP range", str); 585#endif 586 do { 587 if (*str == '-') 588 dashes++; 589 else if (*str == '.') 590 dots++; 591 else if (!strchr("0123456789", *str)) { 592#if DEBUG_IP_PARSER 593 syslog(LOG_DEBUG, "MGR: Not an IP range: character %c is not valid", *str); 594#endif 595 return 0; 596 } 597 } while (*++str); 598#if DEBUG_IP_PARSER 599 syslog(LOG_DEBUG, "MGR: Dashes = %d (wanted: 1), Dots = %d (wanted: 4)", dashes, dots); 600#endif 601 return (dashes == 1 && dots == 3); 602} 603 604/* process a type 0 (LOCAL) or type 1 (REMOTE) IP string */ 605static void processIPStr(int type, char *ipstr) 606{ 607 int pos; 608 609 char *tmpstr; 610 /* char tmpstr2[20]; xxx.xxx.xxx.xxx-xxx (largest we can get) */ 611 char tmpstr2[128]; /* allow hostnames */ 612 char *tmpstr3; 613 char tmpstr5[16]; 614 char *tmpstr6; 615 char *tmpstr7; 616 int num; 617 618 char ipa[8]; /* xxx-xxx (largest we can get) */ 619 char ipb[8]; 620 char ipc[8]; 621 char ipd[8]; 622 623 char ip_pre[13]; /* xxx.xxx.xxx. (largest we can get) */ 624 char ip_post[13]; 625 626 char ipl[4]; 627 char ipu[4]; 628 629 int bail = FALSE; /* so we know when to stop formatting the ip line */ 630 631 int lower, upper, n; 632 633 num = 0; 634 635 while (!bail) { 636 if ((tmpstr = strchr(ipstr, ',')) == NULL) { 637 /* last (or only) entry reached */ 638 strlcpy(tmpstr2, ipstr, sizeof(tmpstr2)); 639 bail = TRUE; 640 } else { 641 pos = tmpstr - ipstr; 642 ipstr[pos] = '\0'; 643 strlcpy(tmpstr2, ipstr, sizeof(tmpstr2)); 644 ipstr = tmpstr + 1; 645 } 646 647#if DEBUG_IP_PARSER 648 syslog(LOG_DEBUG, "MGR: Parsing segment: %s", tmpstr2); 649#endif 650 651 if (!isIpRange(tmpstr2)) { 652 /* We got a normal IP 653 * Check if the IP address is valid, use it if so 654 */ 655 if ((tmpstr7 = lookup(tmpstr2)) == NULL) { 656 syslog(LOG_ERR, "MGR: Bad IP address (%s) in config file!", tmpstr2); 657 exit(1); 658 } 659 if (num == pptp_connections) { 660 syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections); 661 return; 662 } 663#if DEBUG_IP_PARSER 664 syslog(LOG_DEBUG, "MGR: Setting IP %d = %s", num, tmpstr7); 665#endif 666 if (type == LOCAL) 667 slot_set_local(num, tmpstr7); 668 else 669 slot_set_remote(num, tmpstr7); 670 num++; 671 } else { 672 /* Got a range; 673 * eg. 192.168.0.234-238 674 * or (thanx Kev! :-).. i thought i was finished :-) 675 * 192.168-178.1.231 676 */ 677 678 /* lose the "."'s */ 679 while ((tmpstr3 = strchr(tmpstr2, '.')) != NULL) { 680 pos = tmpstr3 - tmpstr2; 681 tmpstr2[pos] = ' '; 682 } 683 684 if ((tmpstr3 = strchr(tmpstr2, '-')) == NULL || 685 strchr(tmpstr3 + 1, '-') != NULL) { 686 syslog(LOG_ERR, "MGR: Confused in IP parse routines (multiple hyphens)"); 687 continue; 688 } 689 /* should be left with "192 168 0 234-238" 690 * or 192 168-178 1 231 691 */ 692 693 sscanf(tmpstr2, "%7s %7s %7s %7s", ipa, ipb, ipc, ipd); 694 695 if ((tmpstr6 = strchr(ipd, '-')) != NULL) { 696 pos = tmpstr6 - ipd; 697 ipd[pos] = ' '; 698 sscanf(ipd, "%3s %3s", ipl, ipu); 699#if DEBUG_IP_PARSER 700 syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); 701#endif 702 lower = atoi(ipl); 703 upper = atoi(ipu); 704#if DEBUG_IP_PARSER 705 syslog(LOG_DEBUG, "MGR: Range = %d to %d on 4th segment", lower, upper); 706#endif 707 sprintf(ip_pre, "%.3s.%.3s.%.3s.", ipa, ipb, ipc); 708 ip_post[0] = '\0'; 709#if DEBUG_IP_PARSER 710 syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); 711#endif 712 } else if ((tmpstr6 = strchr(ipc, '-')) != NULL) { 713 pos = tmpstr6 - ipc; 714 ipc[pos] = ' '; 715 sscanf(ipc, "%3s %3s", ipl, ipu); 716#if DEBUG_IP_PARSER 717 syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); 718#endif 719 lower = atoi(ipl); 720 upper = atoi(ipu); 721#if DEBUG_IP_PARSER 722 syslog(LOG_DEBUG, "MGR: Range = %d to %d on 3rd segment", lower, upper); 723#endif 724 sprintf(ip_pre, "%.3s.%.3s.", ipa, ipb); 725 sprintf(ip_post, ".%.3s", ipd); 726#if DEBUG_IP_PARSER 727 syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); 728#endif 729 } else if ((tmpstr6 = strchr(ipb, '-')) != NULL) { 730 pos = tmpstr6 - ipb; 731 ipb[pos] = ' '; 732 sscanf(ipb, "%3s %3s", ipl, ipu); 733#if DEBUG_IP_PARSER 734 syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); 735#endif 736 lower = atoi(ipl); 737 upper = atoi(ipu); 738#if DEBUG_IP_PARSER 739 syslog(LOG_DEBUG, "MGR: Range = %d to %d on 2nd segment", lower, upper); 740#endif 741 sprintf(ip_pre, "%.3s.", ipa); 742 sprintf(ip_post, ".%.3s.%.3s", ipc, ipd); 743#if DEBUG_IP_PARSER 744 syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); 745#endif 746 } else if ((tmpstr6 = strchr(ipa, '-')) != NULL) { 747 pos = tmpstr6 - ipa; 748 ipa[pos] = ' '; 749 sscanf(ipa, "%3s %3s", ipl, ipu); 750#if DEBUG_IP_PARSER 751 syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); 752#endif 753 lower = atoi(ipl); 754 upper = atoi(ipu); 755#if DEBUG_IP_PARSER 756 syslog(LOG_DEBUG, "MGR: Range = %d to %d on 1st segment", lower, upper); 757#endif 758 ip_pre[0] = '\0'; 759 sprintf(ip_post, ".%.3s.%.3s.%.3s", ipb, ipc, ipd); 760#if DEBUG_IP_PARSER 761 syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); 762#endif 763 } else { 764 syslog(LOG_ERR, "MGR: Confused in IP parse routines (lost hyphen)"); 765 continue; 766 } 767 768 for (n = lower; n <= upper; n++) { 769 sprintf(tmpstr5, "%s%d%s", ip_pre, n, ip_post); 770 /* Check if the ip address is valid */ 771 if ((tmpstr7 = validip(tmpstr5)) == NULL) { 772 syslog(LOG_ERR, "MGR: Bad IP address (%s) in config file!", tmpstr5); 773 exit(1); 774 } 775 if (num == pptp_connections) { 776 syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections); 777 return; 778 } 779#if DEBUG_IP_PARSER 780 syslog(LOG_DEBUG, "MGR: Setting IP %d = %s", num, tmpstr7); 781#endif 782 if (type == LOCAL) 783 slot_set_local(num, tmpstr7); 784 else 785 slot_set_remote(num, tmpstr7); 786 num++; 787 } 788 } 789 } 790 if (num == 1 && type == LOCAL && pptp_connections > 1) { 791#if DEBUG_IP_PARSER 792 syslog(LOG_DEBUG, "MGR: Setting all %d local IPs to %s", pptp_connections, slot_get_local(0)); 793#endif 794 for (n = 1; n < pptp_connections; n++) 795 slot_set_local(n, slot_get_local(0)); 796 } else if (pptp_connections > num) { 797 syslog(LOG_INFO, "MGR: Maximum of %d connections reduced to %d, not enough IP addresses given", 798 pptp_connections, num); 799 pptp_connections = num; 800 } 801} 802 803#ifdef BCRELAY 804/* launch_bcrelay 805 * Launches broadcast relay. Broadcast relay is responsible for relaying broadcasts to the clients 806 * retn: 0 on success, -1 on failure. 807 */ 808static void launch_bcrelay() { 809 char *bcrelay_argv[8]; 810 int an = 0; 811 812 if (bcrelay) { 813 char *outif = strchr(bcrelay, ','); 814 if (outif == NULL) 815 outif = "ppp[0-9].*"; 816 else *outif++ = '\0'; 817 818 syslog(LOG_DEBUG, "MGR: BCrelay incoming interface is %s", bcrelay); 819 syslog(LOG_DEBUG, "MGR: BCrelay outgoing interface is regexp %s", outif); 820 821 bcrelay_argv[an++] = BCRELAY_BIN; 822 bcrelay_argv[an++] = "-i"; 823 bcrelay_argv[an++] = bcrelay; 824 bcrelay_argv[an++] = "-o"; 825 bcrelay_argv[an++] = outif; 826 if (!pptp_debug) { 827 bcrelay_argv[an++] = "-n"; 828 } 829 bcrelay_argv[an++] = NULL; 830 831 execvp(bcrelay_argv[0], bcrelay_argv); 832 } 833} 834#endif 835