Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / pptpd / pptpd.c
blob3913f266677332b97e46b3b71a11b77c446ddd0b
1 /*
2 * pptpd.c
4 * Grabs any command line argument and processes any further options in
5 * the pptpd config file, before throwing over to pptpmanager.c.
7 * $Id: pptpd.c,v 1.18 2006/09/04 23:17:25 quozl Exp $
8 */
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
14 #ifdef __linux__
15 #define _GNU_SOURCE 1 /* strdup() prototype, broken arpa/inet.h */
16 #endif
18 #ifdef __svr4__
19 #define __EXTENSIONS__ 1 /* strdup() prototype */
20 #endif
22 #ifdef __sgi__
23 #define _XOPEN_SOURCE 500 /* strdup() prototype */
24 #endif
26 #include "our_syslog.h"
27 #include "our_getopt.h"
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>
43 #include "configfile.h"
44 #include "defaults.h"
45 #include "compat.h"
46 #include "pptpmanager.h"
48 #ifdef CONFIG_NETtel
49 #include <linux/ledman.h>
50 #endif
52 /* command line arg variables */
53 char *ppp_binary = NULL;
54 char *pppdoptstr = NULL;
55 char *speedstr = NULL;
56 char *bindaddr = NULL;
57 #ifdef BCRELAY
58 char *bcrelay = NULL;
59 #endif
60 int pptp_debug = 0;
61 int pptp_noipparam = 0;
62 int pptp_logwtmp = 0;
63 int pptp_delegate = 0;
65 int pptp_stimeout = STIMEOUT_DEFAULT;
67 int pptp_connections = CONNECTIONS_DEFAULT;
69 /* Local prototypes */
70 static void processIPStr(int type, char *ipstr);
72 #ifndef HAVE_DAEMON
73 static void my_daemon(int argc, char **argv);
74 #endif
76 static void log_pid(char *pid_file);
77 static char *lookup(char *);
79 #ifdef BCRELAY
80 static void launch_bcrelay();
81 static void launch_bcrelay_br0();
82 static void launch_bcrelay_ppp();
83 static pid_t bcrelayfork;
84 #endif
86 static void showusage(char *prog)
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");
120 printf("\n\nLogs and debugging go to syslog as DAEMON.");
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);
127 static void showversion()
129 printf("pptpd v%s\n", VERSION);
132 int main(int argc, char **argv)
134 /* command line options */
135 int c;
137 /* function-local options */
138 int foreground = FALSE;
139 char *pid_file = NULL;
141 /* config file */
142 char *configFile = NULL;
144 /* config file parsing temp strings */
145 char tmp[MAX_CONFIG_STRING_SIZE], *tmpstr;
147 /* open a connection to the syslog daemon */
148 openlog("pptpd", LOG_PID, PPTP_FACILITY);
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
159 static struct option long_options[] =
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}
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
200 case 'l': /* --listen */
201 tmpstr = lookup(optarg);
202 if (!tmpstr) {
203 syslog(LOG_ERR, "MGR: Invalid listening address: %s!", optarg);
204 return 1;
206 if (bindaddr) free(bindaddr);
207 bindaddr = strdup(tmpstr);
208 break;
210 case 'h': /* --help */
211 showusage(argv[0]);
212 return 0;
214 case 'i': /* --noipparam */
215 pptp_noipparam = TRUE;
216 break;
218 case 'e': /* --ppp */
219 if (ppp_binary) free(ppp_binary);
220 ppp_binary = strdup(optarg);
221 break;
223 case 'd': /* --debug */
224 pptp_debug = TRUE;
225 break;
227 case 'f': /* --fg */
228 foreground = TRUE;
229 break;
231 case 'v': /* --version */
232 showversion();
233 return 0;
235 case 'w': /* --logwtmp */
236 pptp_logwtmp = TRUE;
237 break;
239 case 'C': /* --connections */
240 pptp_connections = atoi(optarg);
241 break;
243 case 'D': /* --delegate */
244 pptp_delegate = TRUE;
245 break;
247 case 'o': /* --option */
248 if (pppdoptstr) free(pppdoptstr);
249 pppdoptstr = strdup(optarg);
250 break;
252 case 'p': /* --pidfile */
253 if (pid_file) free(pid_file);
254 pid_file = strdup(optarg);
255 break;
257 case 's': /* --speed */
258 if (speedstr) free(speedstr);
259 speedstr = strdup(optarg);
260 break;
262 case 't': /* --stimeout */
263 pptp_stimeout = atoi(optarg);
264 break;
266 case 'c': /* --conf */
268 FILE *f;
269 if (!(f = fopen(optarg, "r"))) {
270 syslog(LOG_ERR, "MGR: Config file not found!");
271 return 1;
273 fclose(f);
274 if(configFile) free(configFile);
275 configFile = strdup(optarg);
276 break;
279 default:
280 showusage(argv[0]);
281 return 1;
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 :-)
290 if (!configFile)
291 configFile = strdup(PPTPD_CONFIG_FILE_DEFAULT);
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;
299 slot_init(pptp_connections);
301 if (!pptp_debug && read_config_file(configFile, DEBUG_KEYWORD, tmp) > 0)
302 pptp_debug = TRUE;
304 #ifdef BCRELAY
305 if (!bcrelay && read_config_file(configFile, BCRELAY_KEYWORD, tmp) > 0)
306 bcrelay = strdup(tmp);
307 #endif
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;
315 if (!pptp_noipparam && read_config_file(configFile, NOIPPARAM_KEYWORD, tmp) > 0) {
316 pptp_noipparam = TRUE;
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;
325 bindaddr = strdup(tmpstr);
328 if (!speedstr && read_config_file(configFile, SPEED_KEYWORD, tmp) > 0)
329 speedstr = strdup(tmp);
331 if (!pppdoptstr && read_config_file(configFile, PPPD_OPTION_KEYWORD, tmp) > 0) {
332 pppdoptstr = strdup(tmp);
335 if (!ppp_binary && read_config_file(configFile, PPP_BINARY_KEYWORD, tmp) > 0) {
336 ppp_binary = strdup(tmp);
339 if (!pptp_logwtmp && read_config_file(configFile, LOGWTMP_KEYWORD, tmp) > 0) {
340 pptp_logwtmp = TRUE;
343 if (!pptp_delegate && read_config_file(configFile, DELEGATE_KEYWORD, tmp) > 0) {
344 pptp_delegate = TRUE;
347 if (!pid_file)
348 pid_file = strdup((read_config_file(configFile, PIDFILE_KEYWORD,
349 tmp) > 0) ? tmp : PIDFILE_DEFAULT);
351 if (!pptp_delegate) {
352 /* NOTE: remote then local, reason can be seen at the end of processIPStr */
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));
359 processIPStr(REMOTE, tmp);
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));
366 processIPStr(LOCAL, tmp);
369 free(configFile);
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;
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;
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;
392 #endif
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)
407 #endif
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);
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);
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);
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);
449 } /* End bcrelay */
450 #endif
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);
459 /* manage connections until SIGTERM */
460 pptp_manager(argc, argv);
462 #ifdef BCRELAY
463 if (bcrelayfork > 0) {
464 syslog(LOG_DEBUG, "CTRL: Closing child BCrelay with pid %i", bcrelayfork);
465 kill(bcrelayfork, SIGTERM);
467 #endif
469 slot_free();
470 return 0;
473 static void log_pid(char *pid_file) {
474 FILE *f;
475 pid_t pid;
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;
483 fprintf(f, "%d\n", pid);
484 fclose(f);
487 #ifndef HAVE_DAEMON
488 static void my_daemon(int argc, char **argv)
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;
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);
517 #else
518 int pid;
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
534 #endif
536 /* added for hostname/address lookup -tmk
537 * returns NULL if not a valid hostname
539 static char *lookup(char *hostname)
541 struct hostent *ent;
542 struct in_addr hst_addr;
544 /* Try to parse IP directly */
545 if (inet_addr(hostname) != -1)
546 return hostname;
548 /* Else lookup hostname, return NULL if it fails */
549 if ((ent = gethostbyname(hostname)) == NULL)
550 return NULL;
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);
557 #define DEBUG_IP_PARSER 1
559 /* Return the address or NULL if not valid */
560 static char *validip(char *hostname)
562 /* Try to parse IP directly */
563 if (inet_addr(hostname) != -1)
564 return hostname;
565 else
566 return NULL;
569 /* Check if it's a valid IP range */
570 static int isIpRange(char *str)
572 int dashes = 0;
573 int dots = 0;
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;
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);
596 /* process a type 0 (LOCAL) or type 1 (REMOTE) IP string */
597 static void processIPStr(int type, char *ipstr)
599 int pos;
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;
610 char ipa[8]; /* xxx-xxx (largest we can get) */
611 char ipb[8];
612 char ipc[8];
613 char ipd[8];
615 char ip_pre[13]; /* xxx.xxx.xxx. (largest we can get) */
616 char ip_post[13];
618 char ipl[4];
619 char ipu[4];
621 int bail = FALSE; /* so we know when to stop formatting the ip line */
623 int lower, upper, n;
625 num = 0;
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;
639 #if DEBUG_IP_PARSER
640 syslog(LOG_DEBUG, "MGR: Parsing segment: %s", tmpstr2);
641 #endif
643 if (!isIpRange(tmpstr2)) {
644 /* We got a normal IP
645 * Check if the IP address is valid, use it if so
647 if ((tmpstr7 = lookup(tmpstr2)) == NULL) {
648 syslog(LOG_ERR, "MGR: Bad IP address (%s) in config file!", tmpstr2);
649 exit(1);
651 if (num == pptp_connections) {
652 syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections);
653 return;
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
670 /* lose the "."'s */
671 while ((tmpstr3 = strchr(tmpstr2, '.')) != NULL) {
672 pos = tmpstr3 - tmpstr2;
673 tmpstr2[pos] = ' ';
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;
681 /* should be left with "192 168 0 234-238"
682 * or 192 168-178 1 231
685 sscanf(tmpstr2, "%7s %7s %7s %7s", ipa, ipb, ipc, ipd);
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;
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);
767 if (num == pptp_connections) {
768 syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections);
769 return;
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++;
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;
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.
800 static void launch_bcrelay() {
801 char *bcrelay_argv[8];
802 int an = 0;
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[4-9].*");
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[4-9].*";
813 if (!pptp_debug) {
814 bcrelay_argv[an++] = "-n";
816 bcrelay_argv[an++] = NULL;
818 execvp(bcrelay_argv[0], bcrelay_argv);
822 //Yau add
823 static void launch_bcrelay_br0() {
824 char *bcrelay_argv[8];
825 int an = 0;
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[4-9].*");
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[4-9].*";
836 if (!pptp_debug) {
837 bcrelay_argv[an++] = "-n";
839 bcrelay_argv[an++] = NULL;
841 execvp(bcrelay_argv[0], bcrelay_argv);
845 static void launch_bcrelay_ppp() {
846 char *bcrelay_argv[8];
847 int an = 0;
849 if (strstr(bcrelay, "ppp")) {
850 syslog(LOG_DEBUG, "MGR: BCrelay incoming interface is regexp ppp[4-9].*");
851 syslog(LOG_DEBUG, "MGR: BCrelay outgoing interface is br0");
853 bcrelay_argv[an++] = BCRELAY_BIN;
854 bcrelay_argv[an++] = "-i";
855 bcrelay_argv[an++] = "ppp[4-9].*";
856 bcrelay_argv[an++] = "-o";
857 bcrelay_argv[an++] = "br0";
858 if (!pptp_debug) {
859 bcrelay_argv[an++] = "-n";
861 bcrelay_argv[an++] = NULL;
863 execvp(bcrelay_argv[0], bcrelay_argv);
867 #endif