diff options
Diffstat (limited to 'pptpd-1.3.3/pptpd.c')
-rw-r--r-- | pptpd-1.3.3/pptpd.c | 829 |
1 files changed, 829 insertions, 0 deletions
diff --git a/pptpd-1.3.3/pptpd.c b/pptpd-1.3.3/pptpd.c new file mode 100644 index 00000000..b6d2b6a4 --- /dev/null +++ b/pptpd-1.3.3/pptpd.c @@ -0,0 +1,829 @@ +/* + * pptpd.c + * + * Grabs any command line argument and processes any further options in + * the pptpd config file, before throwing over to pptpmanager.c. + * + * $Id: pptpd.c,v 1.18 2006/09/04 23:17:25 quozl Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __linux__ +#define _GNU_SOURCE 1 /* strdup() prototype, broken arpa/inet.h */ +#endif + +#ifdef __svr4__ +#define __EXTENSIONS__ 1 /* strdup() prototype */ +#endif + +#ifdef __sgi__ +#define _XOPEN_SOURCE 500 /* strdup() prototype */ +#endif + +#include "our_syslog.h" +#include "our_getopt.h" + +#include <fcntl.h> +#include <netdb.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "configfile.h" +#include "defaults.h" +#include "compat.h" +#include "pptpmanager.h" + +#ifdef CONFIG_NETtel +#include <linux/ledman.h> +#endif + +/* command line arg variables */ +char *ppp_binary = NULL; +char *pppdoptstr = NULL; +char *speedstr = NULL; +char *bindaddr = NULL; +#ifdef BCRELAY +char *bcrelay = NULL; +#endif +int pptp_debug = 0; +int pptp_noipparam = 0; +int pptp_logwtmp = 0; +int pptp_delegate = 0; + +int pptp_stimeout = STIMEOUT_DEFAULT; +int pptp_ptimeout = PTIMEOUT_DEFAULT; + +int pptp_connections = CONNECTIONS_DEFAULT; + +int keep_connections=0; + +/* Local prototypes */ +static void processIPStr(int type, char *ipstr); + +#ifndef HAVE_DAEMON +static void my_daemon(int argc, char **argv); +#endif + +static void log_pid(char *pid_file); +static char *lookup(char *); + +#ifdef BCRELAY +static void launch_bcrelay(); +static pid_t bcrelayfork; +#endif + +static void showversion() +{ + printf("accel-pptpd v%s ", VERSION); + printf("compiled for pppd-%s, linux-%s\n",PPPD_VERSION,KERNELVERSION); +} +static void showusage(char *prog) +{ + showversion(); + printf("Usage: pptpd [options], where options are:\n\n"); +#ifdef BCRELAY + printf(" [-b] [--bcrelay if] Use broadcast relay for broadcasts comming from.\n"); + printf(" the specified interface (default is eth1).\n"); +#endif + printf(" [-c] [--conf file] Specifies the config file to read default\n"); + printf(" settings from (default is %s).\n", PPTPD_CONFIG_FILE_DEFAULT); + printf(" [-d] [--debug] Turns on debugging (to syslog).\n"); + printf(" [-e] [--ppp file] Use alternate pppd binary, default %s.\n", PPP_BINARY); + printf(" [-f] [--fg] Run in foreground.\n"); + printf(" [-h] [--help] Displays this help message.\n"); + printf(" [-i] [--noipparam] Suppress the passing of the client's IP address\n"); + printf(" to PPP, which is done by default otherwise.\n"); + printf(" [-l] [--listen x.x.x.x] Specifies IP of local interface to listen to.\n"); +#if !defined(BSDUSER_PPP) + printf(" [-o] [--option file] Specifies the PPP options file to use\n"); + printf(" (default is /etc/ppp/options).\n"); +#endif + printf(" [-p] [--pidfile file] Specifies the file to write the process ID to\n"); + printf(" (default is /var/run/pptpd.pid).\n"); +#if !defined(BSDUSER_PPP) + printf(" [-s] [--speed baud] Specifies the baud speed for the PPP daemon\n"); + printf(" (default is 115200).\n"); +#endif + printf(" [-t] [--stimeout seconds] Specifies the timeout for the first packet. This is a DOS protection\n"); + printf(" (default is 10).\n"); + printf(" [-T] [--ptimeout msec] Specifies the maximum timeout for the packet.\n"); + printf(" (default is 1000).\n"); + printf(" [-v] [--version] Displays the pptpd version number.\n"); + printf(" [-w] [--logwtmp] Update wtmp as users login.\n"); + printf(" [-C] [--connections n] Limit on number of connections.\n"); + printf(" [-D] [--delegate] Delegate IP allocation to pppd.\n"); + printf(" [-k] [--keep] Keep connections after exit.\n"); + printf(" (default do not keep).\n"); + + printf("\n\nLogs and debugging go to syslog as DAEMON."); + + printf("\n\nCommand line options will override any default settings and any settings\n"); + printf("specified in the config file (default config file: %s).\n\n", PPTPD_CONFIG_FILE_DEFAULT); +} + + + +int main(int argc, char **argv) +{ + /* command line options */ + int c; + + /* function-local options */ + int foreground = FALSE; + char *pid_file = NULL; + + /* config file */ + char *configFile = NULL; + + /* config file parsing temp strings */ + char tmp[MAX_CONFIG_STRING_SIZE], *tmpstr; + + /* open a connection to the syslog daemon */ + openlog("pptpd", LOG_PID, PPTP_FACILITY); + syslog(LOG_ERR, "MGR: Config file not found!"); + + /* process command line options */ + while (1) { + int option_index = 0; +#ifdef BCRELAY + char *optstring = "b:c:de:fhil:o:p:s:t:T:vwC:Dk"; +#else + char *optstring = "c:de:fhil:o:p:s:t:T:vwC:Dk"; +#endif + + static struct option long_options[] = + { +#ifdef BCRELAY + {"bcrelay", 1, 0, 0}, +#endif + {"conf", 1, 0, 'c'}, + {"debug", 0, 0, 'd'}, + {"ppp", 1, 0, 'e'}, + {"fg", 0, 0, 'f'}, + {"help", 0, 0, 'h'}, + {"noipparam", 0, 0, 'i'}, + {"listen", 1, 0, 'l'}, + {"option", 1, 0, 'o'}, + {"pidfile", 1, 0, 'p'}, + {"speed", 1, 0, 's'}, + {"stimeout", 1, 0, 't'}, + {"ptimeout", 1, 0, 'T'}, + {"version", 0, 0, 'v'}, + {"logwtmp", 0, 0, 'w'}, + {"connections", 1, 0, 'C'}, + {"delegate", 0, 0, 'D'}, + {"keep", 0, 0, 'k'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, optstring, long_options, &option_index); + if (c == -1) + break; + /* convert long options to short form */ + if (c == 0) +#ifdef BCRELAY + c = "bcdefhilopstvwCDk"[option_index]; +#else + c = "cdefhilopstvwCDk"[option_index]; +#endif + switch (c) { +#ifdef BCRELAY + case 'b': /* --bcrelay */ + if (bcrelay) free(bcrelay); + bcrelay = strdup(optarg); + break; +#endif + + case 'l': /* --listen */ + tmpstr = lookup(optarg); + if (!tmpstr) { + syslog(LOG_ERR, "MGR: Invalid listening address: %s!", optarg); + return 1; + } + if (bindaddr) free(bindaddr); + bindaddr = strdup(tmpstr); + break; + + case 'h': /* --help */ + showusage(argv[0]); + return 0; + + case 'i': /* --noipparam */ + pptp_noipparam = TRUE; + break; + + case 'e': /* --ppp */ + if (ppp_binary) free(ppp_binary); + ppp_binary = strdup(optarg); + break; + + case 'd': /* --debug */ + pptp_debug = TRUE; + break; + + case 'f': /* --fg */ + foreground = TRUE; + break; + + case 'v': /* --version */ + showversion(); + return 0; + + case 'w': /* --logwtmp */ + pptp_logwtmp = TRUE; + break; + + case 'C': /* --connections */ + pptp_connections = atoi(optarg); + break; + + case 'D': /* --delegate */ + pptp_delegate = TRUE; + break; + + case 'o': /* --option */ + if (pppdoptstr) free(pppdoptstr); + pppdoptstr = strdup(optarg); + break; + + case 'p': /* --pidfile */ + if (pid_file) free(pid_file); + pid_file = strdup(optarg); + break; + + case 's': /* --speed */ + if (speedstr) free(speedstr); + speedstr = strdup(optarg); + break; + + case 't': /* --stimeout */ + pptp_stimeout = atoi(optarg); + break; + + case 'T': /* --stimeout */ + pptp_ptimeout = atoi(optarg); + break; + case 'k': /* --keep */ + keep_connections = 1; + break; + + case 'c': /* --conf */ + { + FILE *f; + if (!(f = fopen(optarg, "r"))) { + syslog(LOG_ERR, "MGR: Config file not found!"); + return 1; + } + fclose(f); + if(configFile) free(configFile); + configFile = strdup(optarg); + break; + } + + default: + showusage(argv[0]); + return 1; + } + } + + /* Now that we have all the command line args.. lets open the + * conf file and add anything else (remembering not to override + * anything since the command line has more privilages :-) + */ + + if (!configFile) + configFile = strdup(PPTPD_CONFIG_FILE_DEFAULT); + + if (read_config_file(configFile, CONNECTIONS_KEYWORD, tmp) > 0) { + pptp_connections = atoi(tmp); + if (pptp_connections <= 0) + pptp_connections = CONNECTIONS_DEFAULT; + } + + slot_init(pptp_connections); + + if (!pptp_debug && read_config_file(configFile, DEBUG_KEYWORD, tmp) > 0) + pptp_debug = TRUE; + +#ifdef BCRELAY + if (!bcrelay && read_config_file(configFile, BCRELAY_KEYWORD, tmp) > 0) + bcrelay = strdup(tmp); +#endif + + if (!pptp_stimeout && read_config_file(configFile, STIMEOUT_KEYWORD, tmp) > 0) { + pptp_stimeout = atoi(tmp); + if (pptp_stimeout <= 0) + pptp_stimeout = STIMEOUT_DEFAULT; + } + + if (!pptp_ptimeout && read_config_file(configFile, PTIMEOUT_KEYWORD, tmp) > 0) { + pptp_ptimeout = atoi(tmp); + if (pptp_ptimeout <= 0) + pptp_ptimeout = PTIMEOUT_DEFAULT; + } + + if (!pptp_noipparam && read_config_file(configFile, NOIPPARAM_KEYWORD, tmp) > 0) { + pptp_noipparam = TRUE; + } + + if (!bindaddr && read_config_file(configFile, LISTEN_KEYWORD, tmp) > 0) { + tmpstr = lookup(tmp); + if(!tmpstr) { + syslog(LOG_ERR, "MGR: Invalid listening address: %s!", tmp); + return 1; + } + bindaddr = strdup(tmpstr); + } + + if (!speedstr && read_config_file(configFile, SPEED_KEYWORD, tmp) > 0) + speedstr = strdup(tmp); + + if (!pppdoptstr && read_config_file(configFile, PPPD_OPTION_KEYWORD, tmp) > 0) { + pppdoptstr = strdup(tmp); + } + + if (!ppp_binary && read_config_file(configFile, PPP_BINARY_KEYWORD, tmp) > 0) { + ppp_binary = strdup(tmp); + } + + if (!pptp_logwtmp && read_config_file(configFile, LOGWTMP_KEYWORD, tmp) > 0) { + pptp_logwtmp = TRUE; + } + + if (!pptp_delegate && read_config_file(configFile, DELEGATE_KEYWORD, tmp) > 0) { + pptp_delegate = TRUE; + } + + if (read_config_file(configFile, KEEP_KEYWORD, tmp) > 0) { + keep_connections = TRUE; + } + + if (!pid_file) + pid_file = strdup((read_config_file(configFile, PIDFILE_KEYWORD, + tmp) > 0) ? tmp : PIDFILE_DEFAULT); + + if (!pptp_delegate) { + /* NOTE: remote then local, reason can be seen at the end of processIPStr */ + + /* grab the remoteip string from the config file */ + if (read_config_file(configFile, REMOTEIP_KEYWORD, tmp) <= 0) { + /* use "smart" defaults */ + strlcpy(tmp, DEFAULT_REMOTE_IP_LIST, sizeof(tmp)); + } + processIPStr(REMOTE, tmp); + + /* grab the localip string from the config file */ + if (read_config_file(configFile, LOCALIP_KEYWORD, tmp) <= 0) { + /* use "smart" defaults */ + strlcpy(tmp, DEFAULT_LOCAL_IP_LIST, sizeof(tmp)); + } + processIPStr(LOCAL, tmp); + } + + free(configFile); + + /* if not yet set, adopt default PPP binary path */ + if (!ppp_binary) ppp_binary = strdup(PPP_BINARY); + /* check that the PPP binary is executable */ + if (access(ppp_binary, X_OK) < 0) { + syslog(LOG_ERR, "MGR: PPP binary %s not executable", + ppp_binary); + return 1; + } + /* check that the PPP options file is readable */ + if (pppdoptstr && access(pppdoptstr, R_OK) < 0) { + syslog(LOG_ERR, "MGR: PPP options file %s not readable", + pppdoptstr); + return 1; + } +#ifdef BCRELAY + /* check that the bcrelay binary is executable */ + if (bcrelay && access(BCRELAY_BIN, X_OK) < 0) { + syslog(LOG_ERR, "MGR: bcrelay binary %s not executable", + BCRELAY_BIN); + return 1; + } +#endif + + syslog(LOG_INFO, "accel-pptpd-%s compiled for pppd-%s, linux-%s\n",VERSION,PPPD_VERSION,KERNELVERSION); + + if (!foreground) { +#if HAVE_DAEMON + closelog(); + freopen("/dev/null", "r", stdin); + daemon(0, 0); + /* returns to child only */ + /* pid will have changed */ + openlog("pptpd", LOG_PID, PPTP_FACILITY); +#else /* !HAVE_DAEMON */ + my_daemon(argc, argv); + /* returns to child if !HAVE_FORK + * never returns if HAVE_FORK (re-execs with -f) + */ +#endif + } + +#ifdef BCRELAY + if (bcrelay) { + syslog(LOG_DEBUG, "CTRL: BCrelay incoming interface is %s", bcrelay); + /* Launch BCrelay */ +#ifndef HAVE_FORK + switch(bcrelayfork = vfork()){ +#else + switch(bcrelayfork = fork()){ +#endif + case -1: /* fork() error */ + syslog(LOG_ERR, "CTRL: Error forking to exec bcrelay"); + _exit(1); + + case 0: /* child */ + syslog(LOG_DEBUG, "CTRL (BCrelay Launcher): Launching BCrelay with pid %i", bcrelayfork); + launch_bcrelay(); + syslog(LOG_ERR, "CTRL (BCrelay Launcher): Failed to launch BCrelay."); + _exit(1); + } + } /* End bcrelay */ +#endif + +#ifdef CONFIG_NETtel + /* turn the NETtel VPN LED on */ + ledman_cmd(LEDMAN_CMD_ON, LEDMAN_VPN); +#endif + /* after we have our final pid... */ + log_pid(pid_file); + + /* manage connections until SIGTERM */ + pptp_manager(argc, argv); + +#ifdef BCRELAY + if (bcrelayfork > 0) { + syslog(LOG_DEBUG, "CTRL: Closing child BCrelay with pid %i", bcrelayfork); + kill(bcrelayfork, SIGTERM); + } +#endif + + slot_free(); + return 0; +} + +static void log_pid(char *pid_file) { + FILE *f; + pid_t pid; + + pid = getpid(); + if ((f = fopen(pid_file, "w")) == NULL) { + syslog(LOG_ERR, "PPTPD: failed to open(%s), errno=%d\n", + pid_file, errno); + return; + } + fprintf(f, "%d\n", pid); + fclose(f); +} + +#ifndef HAVE_DAEMON +static void my_daemon(int argc, char **argv) +{ +#ifndef HAVE_FORK + /* need to use vfork - eg, uClinux */ + char **new_argv; + int pid; + extern char **environ; + int fdr; + + new_argv = malloc((argc + 2) * sizeof(char **)); + fdr = open("/dev/null", O_RDONLY); + syslog(LOG_INFO, "MGR: Option parse OK, re-execing as daemon"); + fflush(stderr); + if ((pid = vfork()) == 0) { + if (fdr != 0) { dup2(fdr, 0); close(fdr); } + SETSIDPGRP(); + chdir("/"); + umask(0); + memcpy(new_argv + 1, argv, (argc + 1) * sizeof(char **)); + new_argv[0] = PPTPD_BIN; + new_argv[1] = "-f"; + execve(PPTPD_BIN, new_argv, environ); + _exit(1); + } else if (pid > 0) { + exit(0); + } else { + syslog_perror("vfork"); + exit(1); + } +#else + int pid; + + closelog(); + if ((pid = fork()) < 0) { + syslog_perror("fork"); + exit(1); + } else if (pid) + exit(0); + freopen("/dev/null", "r", stdin); + SETSIDPGRP(); + chdir("/"); + umask(0); + /* pid will have changed */ + openlog("pptpd", LOG_PID, PPTP_FACILITY); +#endif +} +#endif + +/* added for hostname/address lookup -tmk + * returns NULL if not a valid hostname + */ +static char *lookup(char *hostname) +{ + struct hostent *ent; + struct in_addr hst_addr; + + /* Try to parse IP directly */ + if (inet_addr(hostname) != -1) + return hostname; + + /* Else lookup hostname, return NULL if it fails */ + if ((ent = gethostbyname(hostname)) == NULL) + return NULL; + + /* That worked, print it back as a dotted quad. */ + memcpy(&hst_addr.s_addr, ent->h_addr, ent->h_length); + return inet_ntoa(hst_addr); +} + +#define DEBUG_IP_PARSER 0 + +/* Return the address or NULL if not valid */ +static char *validip(char *hostname) +{ + /* Try to parse IP directly */ + if (inet_addr(hostname) != -1) + return hostname; + else + return NULL; +} + +/* Check if it's a valid IP range */ +static int isIpRange(char *str) +{ + int dashes = 0; + int dots = 0; + +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Checking if %s is a valid IP range", str); +#endif + do { + if (*str == '-') + dashes++; + else if (*str == '.') + dots++; + else if (!strchr("0123456789", *str)) { +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Not an IP range: character %c is not valid", *str); +#endif + return 0; + } + } while (*++str); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Dashes = %d (wanted: 1), Dots = %d (wanted: 4)", dashes, dots); +#endif + return (dashes == 1 && dots == 3); +} + +/* process a type 0 (LOCAL) or type 1 (REMOTE) IP string */ +static void processIPStr(int type, char *ipstr) +{ + int pos; + + char *tmpstr; + /* char tmpstr2[20]; xxx.xxx.xxx.xxx-xxx (largest we can get) */ + char tmpstr2[128]; /* allow hostnames */ + char *tmpstr3; + char tmpstr5[16]; + char *tmpstr6; + char *tmpstr7; + int num; + + char ipa[8]; /* xxx-xxx (largest we can get) */ + char ipb[8]; + char ipc[8]; + char ipd[8]; + + char ip_pre[13]; /* xxx.xxx.xxx. (largest we can get) */ + char ip_post[13]; + + char ipl[4]; + char ipu[4]; + + int bail = FALSE; /* so we know when to stop formatting the ip line */ + + int lower, upper, n; + + num = 0; + + while (!bail) { + if ((tmpstr = strchr(ipstr, ',')) == NULL) { + /* last (or only) entry reached */ + strlcpy(tmpstr2, ipstr, sizeof(tmpstr2)); + bail = TRUE; + } else { + pos = tmpstr - ipstr; + ipstr[pos] = '\0'; + strlcpy(tmpstr2, ipstr, sizeof(tmpstr2)); + ipstr = tmpstr + 1; + } + +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Parsing segment: %s", tmpstr2); +#endif + + if (!isIpRange(tmpstr2)) { + /* We got a normal IP + * Check if the IP address is valid, use it if so + */ + if ((tmpstr7 = lookup(tmpstr2)) == NULL) { + syslog(LOG_ERR, "MGR: Bad IP address (%s) in config file!", tmpstr2); + exit(1); + } + if (num == pptp_connections) { + syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections); + return; + } +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Setting IP %d = %s", num, tmpstr7); +#endif + if (type == LOCAL) + slot_set_local(num, tmpstr7); + else + slot_set_remote(num, tmpstr7); + num++; + } else { + /* Got a range; + * eg. 192.168.0.234-238 + * or (thanx Kev! :-).. i thought i was finished :-) + * 192.168-178.1.231 + */ + + /* lose the "."'s */ + while ((tmpstr3 = strchr(tmpstr2, '.')) != NULL) { + pos = tmpstr3 - tmpstr2; + tmpstr2[pos] = ' '; + } + + if ((tmpstr3 = strchr(tmpstr2, '-')) == NULL || + strchr(tmpstr3 + 1, '-') != NULL) { + syslog(LOG_ERR, "MGR: Confused in IP parse routines (multiple hyphens)"); + continue; + } + /* should be left with "192 168 0 234-238" + * or 192 168-178 1 231 + */ + + sscanf(tmpstr2, "%7s %7s %7s %7s", ipa, ipb, ipc, ipd); + + if ((tmpstr6 = strchr(ipd, '-')) != NULL) { + pos = tmpstr6 - ipd; + ipd[pos] = ' '; + sscanf(ipd, "%3s %3s", ipl, ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); +#endif + lower = atoi(ipl); + upper = atoi(ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Range = %d to %d on 4th segment", lower, upper); +#endif + sprintf(ip_pre, "%.3s.%.3s.%.3s.", ipa, ipb, ipc); + ip_post[0] = '\0'; +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); +#endif + } else if ((tmpstr6 = strchr(ipc, '-')) != NULL) { + pos = tmpstr6 - ipc; + ipc[pos] = ' '; + sscanf(ipc, "%3s %3s", ipl, ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); +#endif + lower = atoi(ipl); + upper = atoi(ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Range = %d to %d on 3rd segment", lower, upper); +#endif + sprintf(ip_pre, "%.3s.%.3s.", ipa, ipb); + sprintf(ip_post, ".%.3s", ipd); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); +#endif + } else if ((tmpstr6 = strchr(ipb, '-')) != NULL) { + pos = tmpstr6 - ipb; + ipb[pos] = ' '; + sscanf(ipb, "%3s %3s", ipl, ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); +#endif + lower = atoi(ipl); + upper = atoi(ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Range = %d to %d on 2nd segment", lower, upper); +#endif + sprintf(ip_pre, "%.3s.", ipa); + sprintf(ip_post, ".%.3s.%.3s", ipc, ipd); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); +#endif + } else if ((tmpstr6 = strchr(ipa, '-')) != NULL) { + pos = tmpstr6 - ipa; + ipa[pos] = ' '; + sscanf(ipa, "%3s %3s", ipl, ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); +#endif + lower = atoi(ipl); + upper = atoi(ipu); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Range = %d to %d on 1st segment", lower, upper); +#endif + ip_pre[0] = '\0'; + sprintf(ip_post, ".%.3s.%.3s.%.3s", ipb, ipc, ipd); +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); +#endif + } else { + syslog(LOG_ERR, "MGR: Confused in IP parse routines (lost hyphen)"); + continue; + } + + for (n = lower; n <= upper; n++) { + sprintf(tmpstr5, "%s%d%s", ip_pre, n, ip_post); + /* Check if the ip address is valid */ + if ((tmpstr7 = validip(tmpstr5)) == NULL) { + syslog(LOG_ERR, "MGR: Bad IP address (%s) in config file!", tmpstr5); + exit(1); + } + if (num == pptp_connections) { + syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections); + return; + } +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Setting IP %d = %s", num, tmpstr7); +#endif + if (type == LOCAL) + slot_set_local(num, tmpstr7); + else + slot_set_remote(num, tmpstr7); + num++; + } + } + } + if (num == 1 && type == LOCAL && pptp_connections > 1) { +#if DEBUG_IP_PARSER + syslog(LOG_DEBUG, "MGR: Setting all %d local IPs to %s", pptp_connections, slot_get_local(0)); +#endif + for (n = 1; n < pptp_connections; n++) + slot_set_local(n, slot_get_local(0)); + } else if (pptp_connections > num) { + syslog(LOG_INFO, "MGR: Maximum of %d connections reduced to %d, not enough IP addresses given", + pptp_connections, num); + pptp_connections = num; + } +} + +#ifdef BCRELAY +/* launch_bcrelay + * Launches broadcast relay. Broadcast relay is responsible for relaying broadcasts to the clients + * retn: 0 on success, -1 on failure. + */ +static void launch_bcrelay() { + char *bcrelay_argv[8]; + int an = 0; + + if (bcrelay) { + syslog(LOG_DEBUG, "MGR: BCrelay incoming interface is %s", bcrelay); + syslog(LOG_DEBUG, "MGR: BCrelay outgoing interface is regexp ppp[0-9].*"); + + bcrelay_argv[an++] = BCRELAY_BIN; + bcrelay_argv[an++] = "-i"; + bcrelay_argv[an++] = bcrelay; + bcrelay_argv[an++] = "-o"; + bcrelay_argv[an++] = "ppp[0-9].*"; + if (!pptp_debug) { + bcrelay_argv[an++] = "-n"; + } + bcrelay_argv[an++] = NULL; + + execvp(bcrelay_argv[0], bcrelay_argv); + } +} +#endif |