/* 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; } }
static void connectCall(int clientSocket, int clientNumber) { #define NUM2ARRAY(array, num) snprintf(array, sizeof(array), "%d", num) char *ctrl_argv[16]; /* arguments for launching 'pptpctrl' binary */ int pptpctrl_argc = 0; /* count the number of arguments sent to pptpctrl */ /* lame strings to hold passed args. */ char ctrl_debug[2]; char ctrl_noipparam[2]; char pppdoptfile_argv[2]; char speedgiven_argv[2]; extern char **environ; char ptimeout_argv[16]; /* * Launch the CTRL manager binary; we send it some information such as * speed and option file on the command line. */ ctrl_argv[pptpctrl_argc++] = PPTP_CTRL_BIN " "; /* Pass socket as stdin */ if (clientSocket != 0) { dup2(clientSocket, 0); close(clientSocket); } /* get argv set up */ NUM2ARRAY(ctrl_debug, pptp_debug ? 1 : 0); ctrl_debug[1] = '\0'; ctrl_argv[pptpctrl_argc++] = ctrl_debug; NUM2ARRAY(ctrl_noipparam, pptp_noipparam ? 1 : 0); ctrl_noipparam[1] = '\0'; ctrl_argv[pptpctrl_argc++] = ctrl_noipparam; #ifdef VRF ctrl_argv[pptpctrl_argc++] = vrf ? vrf : ""; #endif /* optionfile = TRUE or FALSE; so the CTRL manager knows whether to load a non-standard options file */ NUM2ARRAY(pppdoptfile_argv, pppdoptstr ? 1 : 0); pppdoptfile_argv[1] = '\0'; ctrl_argv[pptpctrl_argc++] = pppdoptfile_argv; if (pppdoptstr) { /* send the option filename so the CTRL manager can launch pppd with this alternate file */ ctrl_argv[pptpctrl_argc++] = pppdoptstr; } /* tell the ctrl manager whether we were given a speed */ NUM2ARRAY(speedgiven_argv, speedstr ? 1 : 0); speedgiven_argv[1] = '\0'; ctrl_argv[pptpctrl_argc++] = speedgiven_argv; if (speedstr) { /* send the CTRL manager the speed of the connection so it can fire pppd at that speed */ ctrl_argv[pptpctrl_argc++] = speedstr; } if (pptp_delegate) { /* no local or remote address to specify */ ctrl_argv[pptpctrl_argc++] = "0"; ctrl_argv[pptpctrl_argc++] = "0"; } else { /* specify local & remote addresses for this call */ ctrl_argv[pptpctrl_argc++] = "1"; ctrl_argv[pptpctrl_argc++] = slot_get_local(clientNumber); ctrl_argv[pptpctrl_argc++] = "1"; ctrl_argv[pptpctrl_argc++] = slot_get_remote(clientNumber); } /* our call id to be included in GRE packets the client * will send to us */ NUM2ARRAY(ptimeout_argv, pptp_ptimeout); ctrl_argv[pptpctrl_argc++] = ptimeout_argv; /* pass path to ppp binary */ ctrl_argv[pptpctrl_argc++] = ppp_binary; /* pass logwtmp flag */ ctrl_argv[pptpctrl_argc++] = pptp_logwtmp ? "1" : "0"; /* note: update pptpctrl.8 if the argument list format is changed */ /* terminate argv array with a NULL */ ctrl_argv[pptpctrl_argc] = NULL; pptpctrl_argc++; /* ok, args are setup: invoke the call handler */ execve(PPTP_CTRL_BIN, ctrl_argv, environ); syslog(LOG_ERR, "MGR: Failed to exec " PPTP_CTRL_BIN "!"); _exit(1); }