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