Exemplo n.º 1
0
/* 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;
	}
}
Exemplo n.º 2
0
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);
}