pptpd.c 29 KB

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