You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

netsukuku.c 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. * netsukuku.c:
  20. * Where main() resides.
  21. */
  22. #include "includes.h"
  23. #include "common.h"
  24. #include "conf.h"
  25. #include "libnetlink.h"
  26. #include "ll_map.h"
  27. #include "request.h"
  28. #include "pkts.h"
  29. #include "if.h"
  30. #include "bmap.h"
  31. #include "netsukuku.h"
  32. #include "qspn.h"
  33. #include "accept.h"
  34. #include "daemon.h"
  35. #include "crypto.h"
  36. #include "andna_cache.h"
  37. #include "andna.h"
  38. #include "radar.h"
  39. #include "hook.h"
  40. #include "rehook.h"
  41. #include "ntk-console-server.h"
  42. #include <pthread.h>
  43. extern int errno;
  44. extern char *optarg;
  45. extern int optind, opterr, optopt;
  46. int destroy_netsukuku_mutex;
  47. int pid_saved;
  48. int options_parsed = 0; /* How many times parse_options() has been called */
  49. void
  50. save_pid(void)
  51. {
  52. FILE *fd;
  53. if (!(fd = fopen(server_opt.pid_file, "w")))
  54. error("Couldn't create pid file \"%s\": %s",
  55. server_opt.pid_file, strerror(errno));
  56. fprintf(fd, "ntkd %ld\n", (long) getpid());
  57. fclose(fd);
  58. pid_saved = 1;
  59. }
  60. /*
  61. * is_ntkd_already_running
  62. *
  63. * Returns 1 if there's already a ntkd running
  64. */
  65. int
  66. is_ntkd_already_running(void)
  67. {
  68. pid_t oldpid;
  69. FILE *fd;
  70. if (!(fd = fopen(server_opt.pid_file, "r"))) {
  71. if (errno != ENOENT)
  72. error("Cannot read pid file \"%s\": %s",
  73. server_opt.pid_file, strerror(errno));
  74. return 0;
  75. }
  76. fscanf(fd, "ntkd %d\n", &oldpid);
  77. if (ferror(fd)) {
  78. error("error reading pid file \"%s\": %s\n",
  79. server_opt.pid_file, strerror(errno));
  80. fclose(fd);
  81. return 0;
  82. }
  83. fclose(fd);
  84. return !kill(oldpid, 0);
  85. }
  86. int
  87. ntk_load_maps(void)
  88. {
  89. if (file_exist(server_opt.int_map_file) &&
  90. (me.int_map = load_map(server_opt.int_map_file, &me.cur_node)))
  91. debug(DBG_NORMAL, "Internal map loaded");
  92. else
  93. me.int_map = init_map(0);
  94. #if 0
  95. /* Don't load the bnode map, it's useless */
  96. if ((me.bnode_map = load_bmap(server_opt.bnode_map_file, me.ext_map,
  97. FAMILY_LVLS, &me.bmap_nodes))) {
  98. debug(DBG_NORMAL, "Bnode map loaded");
  99. } else
  100. #endif
  101. bmap_levels_init(BMAP_LEVELS(FAMILY_LVLS), &me.bnode_map,
  102. &me.bmap_nodes);
  103. bmap_counter_init(BMAP_LEVELS(FAMILY_LVLS), &me.bmap_nodes_closed,
  104. &me.bmap_nodes_opened);
  105. if (file_exist(server_opt.ext_map_file) &&
  106. (me.ext_map = load_extmap(server_opt.ext_map_file, &me.cur_quadg)))
  107. debug(DBG_NORMAL, "External map loaded from '%s'", server_opt.ext_map_file);
  108. else
  109. me.ext_map = init_extmap(FAMILY_LVLS, 0);
  110. return 0;
  111. }
  112. int
  113. ntk_save_maps(void)
  114. {
  115. debug(DBG_NORMAL, "Saving the internal map");
  116. save_map(me.int_map, me.cur_node, server_opt.int_map_file);
  117. #ifdef DEBUG
  118. debug(DBG_NORMAL, "Saving the border nodes map");
  119. save_bmap(me.bnode_map, me.bmap_nodes, me.ext_map, me.cur_quadg,
  120. server_opt.bnode_map_file);
  121. #endif
  122. debug(DBG_NORMAL, "Saving the external map");
  123. save_extmap(me.ext_map, MAXGROUPNODE, &me.cur_quadg,
  124. server_opt.ext_map_file);
  125. return 0;
  126. }
  127. int
  128. ntk_free_maps(void)
  129. {
  130. bmap_levels_free(me.bnode_map, me.bmap_nodes);
  131. bmap_counter_free(me.bmap_nodes_closed, me.bmap_nodes_opened);
  132. free_extmap(me.ext_map, FAMILY_LVLS, 0);
  133. free_map(me.int_map, 0);
  134. return 0;
  135. }
  136. void
  137. usage(void)
  138. {
  139. printf("Usage:\n"
  140. " ntkd [-hvaldrRD46] [-i net_interface] [-c conf_file] [-l logfile]\n\n"
  141. " -4 ipv4\n"
  142. " -6 ipv6\n"
  143. " -i Specify the interface after this\n\n"
  144. " -a Prevents running the ANDNA daemon\n"
  145. " -R Prevents editting /etc/resolv.conf\n"
  146. " -D Prevents running as daemon (Does not fork to the background)\n"
  147. "\n"
  148. " -r Runs in restricted mode\n"
  149. " -I Share your internet connection with other nodes\n"
  150. "\n"
  151. " -c Configuration file\n"
  152. " -l Enables logging to file\n"
  153. "\n"
  154. " -d Debug (Add more ds to get more info)\n"
  155. " -h Shows this help\n"
  156. " -v Shows the version you are using\n"
  157. " -k Kills the running instance of ntkd\n"
  158. " -C Runs the console server for Ntk-Console to connect to\n"
  159. " -e Excludes an interface from usage I.E all interfaces except this one\n"
  160. " -n Experimental argument to implement ntk netsplit inet/INET or ntk/NTK\n http://netsukuku.freaknet.org/docs/main_doc/ntk_rfc/Ntk_net_split\n");
  161. }
  162. /*
  163. * fill_default_options: fills the default values in the server_opt struct
  164. */
  165. void
  166. fill_default_options(void)
  167. {
  168. setzero(&server_opt, sizeof(server_opt));
  169. server_opt.family = AF_INET;
  170. set_option_literal(&(server_opt.config_file), NTK_CONFIG_FILE);
  171. set_option_literal(&(server_opt.pid_file), NTK_PID_FILE);
  172. set_option_literal(&(server_opt.int_map_file), INT_MAP_FILE);
  173. set_option_literal(&(server_opt.ext_map_file), EXT_MAP_FILE);
  174. set_option_literal(&(server_opt.bnode_map_file), BNODE_MAP_FILE);
  175. set_option_literal(&(server_opt.andna_hnames_file), ANDNA_HNAMES_FILE);
  176. set_option_literal(&(server_opt.snsd_nodes_file), SNSD_NODES_FILE);
  177. set_option_literal(&(server_opt.andna_cache_file), ANDNA_CACHE_FILE);
  178. set_option_literal(&(server_opt.lclkey_file), LCLKEY_FILE);
  179. set_option_literal(&(server_opt.lcl_file), LCL_FILE);
  180. set_option_literal(&(server_opt.rhc_file), RHC_FILE);
  181. set_option_literal(&(server_opt.counter_c_file), COUNTER_C_FILE);
  182. server_opt.daemon = 1;
  183. server_opt.dbg_lvl = 0;
  184. server_opt.disable_andna = 0;
  185. server_opt.disable_resolvconf = 0;
  186. server_opt.restricted = 0;
  187. server_opt.restricted_class = 0;
  188. server_opt.use_shared_inet = 1;
  189. set_option_literal(&(server_opt.ip_masq_script), IPMASQ_SCRIPT_FILE);
  190. set_option_literal(&(server_opt.tc_shaper_script), TCSHAPER_SCRIPT_FILE);
  191. server_opt.max_connections = MAX_CONNECTIONS;
  192. server_opt.max_accepts_per_host = MAX_ACCEPTS;
  193. server_opt.max_accepts_per_host_time = FREE_ACCEPT_TIME;
  194. }
  195. /*
  196. * fill_loaded_cfg_options
  197. *
  198. * stores in server_opt the options loaded from the configuration file
  199. */
  200. void
  201. fill_loaded_cfg_options(void)
  202. {
  203. char *value;
  204. CONF_SET_STRN_OPT(&(server_opt.int_map_file), CONF_NTK_INT_MAP_FILE,
  205. NAME_MAX - 1);
  206. CONF_SET_STRN_OPT(&(server_opt.bnode_map_file), CONF_NTK_BNODE_MAP_FILE,
  207. NAME_MAX - 1);
  208. CONF_SET_STRN_OPT(&(server_opt.ext_map_file), CONF_NTK_EXT_MAP_FILE,
  209. NAME_MAX - 1);
  210. CONF_SET_STRN_OPT(&(server_opt.andna_hnames_file), CONF_ANDNA_HNAMES_FILE,
  211. NAME_MAX - 1);
  212. CONF_SET_STRN_OPT(&(server_opt.snsd_nodes_file), CONF_SNSD_NODES_FILE,
  213. NAME_MAX - 1);
  214. CONF_SET_STRN_OPT(&(server_opt.andna_cache_file), CONF_ANDNA_CACHE_FILE,
  215. NAME_MAX - 1);
  216. CONF_SET_STRN_OPT(&(server_opt.lclkey_file), CONF_ANDNA_LCLKEY_FILE,
  217. NAME_MAX - 1);
  218. CONF_SET_STRN_OPT(&(server_opt.lcl_file), CONF_ANDNA_LCL_FILE,
  219. NAME_MAX - 1);
  220. CONF_SET_STRN_OPT(&(server_opt.rhc_file), CONF_ANDNA_RHC_FILE,
  221. NAME_MAX - 1);
  222. CONF_SET_STRN_OPT(&(server_opt.counter_c_file), CONF_ANDNA_COUNTER_C_FILE,
  223. NAME_MAX - 1);
  224. CONF_SET_STRN_OPT(&(server_opt.pid_file), CONF_NTK_PID_FILE,
  225. NAME_MAX - 1);
  226. CONF_GET_INT_VALUE(CONF_NTK_MAX_CONNECTIONS,
  227. server_opt.max_connections);
  228. CONF_GET_INT_VALUE(CONF_NTK_MAX_ACCEPTS_PER_HOST,
  229. server_opt.max_accepts_per_host);
  230. CONF_GET_INT_VALUE(CONF_NTK_MAX_ACCEPTS_PER_HOST_TIME,
  231. server_opt.max_accepts_per_host_time);
  232. CONF_GET_INT_VALUE(CONF_DISABLE_ANDNA, server_opt.disable_andna);
  233. CONF_GET_INT_VALUE(CONF_DISABLE_RESOLVCONF,
  234. server_opt.disable_resolvconf);
  235. CONF_GET_INT_VALUE(CONF_NTK_RESTRICTED_MODE, server_opt.restricted);
  236. CONF_GET_INT_VALUE(CONF_NTK_RESTRICTED_CLASS,
  237. server_opt.restricted_class);
  238. CONF_GET_INT_VALUE(CONF_NTK_INTERNET_CONNECTION,
  239. server_opt.inet_connection);
  240. if ((value = CONF_GET_VALUE(CONF_NTK_INTERNET_GW))) {
  241. if (str_to_inet_gw(value, &server_opt.inet_gw,
  242. &server_opt.inet_gw_dev))
  243. fatal
  244. ("Malformed `%s' option: \"%s\". Its syntax is \"IP:dev\"",
  245. config_str[CONF_NTK_INTERNET_GW], value);
  246. }
  247. CONF_GET_INT_VALUE(CONF_NTK_INTERNET_UPLOAD, server_opt.my_upload_bw);
  248. CONF_GET_INT_VALUE(CONF_NTK_INTERNET_DOWNLOAD,
  249. server_opt.my_dnload_bw);
  250. if (server_opt.my_upload_bw && server_opt.my_dnload_bw)
  251. me.my_bandwidth =
  252. bandwidth_in_8bit((server_opt.my_upload_bw +
  253. server_opt.my_dnload_bw) / 2);
  254. if ((value = CONF_GET_VALUE(CONF_NTK_INTERNET_PING_HOSTS))) {
  255. server_opt.inet_hosts = parse_internet_hosts(value,
  256. &server_opt.
  257. inet_hosts_counter);
  258. if (!server_opt.inet_hosts)
  259. fatal("Malformed `%s' option: \"%s\". "
  260. "Its syntax is host1:host2:...",
  261. config_str[CONF_NTK_INTERNET_PING_HOSTS], value);
  262. }
  263. CONF_GET_INT_VALUE(CONF_SHARE_INTERNET, server_opt.share_internet);
  264. CONF_GET_INT_VALUE(CONF_SHAPE_INTERNET, server_opt.shape_internet);
  265. CONF_GET_INT_VALUE(CONF_USE_SHARED_INET, server_opt.use_shared_inet);
  266. CONF_GET_STRN_VALUE(CONF_NTK_IP_MASQ_SCRIPT,
  267. &server_opt.ip_masq_script, NAME_MAX - 1);
  268. CONF_GET_STRN_VALUE(CONF_NTK_TC_SHAPER_SCRIPT,
  269. &server_opt.tc_shaper_script, NAME_MAX - 1);
  270. /* Clean the enviroment */
  271. clear_config_env();
  272. }
  273. void
  274. free_server_opt(void)
  275. {
  276. int i;
  277. xfree(server_opt.config_file);
  278. xfree(server_opt.pid_file);
  279. xfree(server_opt.int_map_file);
  280. xfree(server_opt.ext_map_file);
  281. xfree(server_opt.bnode_map_file);
  282. xfree(server_opt.andna_hnames_file);
  283. xfree(server_opt.snsd_nodes_file);
  284. xfree(server_opt.andna_cache_file);
  285. xfree(server_opt.lclkey_file);
  286. xfree(server_opt.lcl_file);
  287. xfree(server_opt.rhc_file);
  288. xfree(server_opt.counter_c_file);
  289. xfree(server_opt.ip_masq_script);
  290. xfree(server_opt.tc_shaper_script);
  291. xfree(server_opt.inet_gw_dev);
  292. for (i = 0; i < MAX_INTERFACES && server_opt.ifs[i]; i++)
  293. xfree(server_opt.ifs[i]);
  294. }
  295. /* Removes specified existing interface, Ntkd should populate the device list
  296. * prior to this.
  297. * returns 0 on success, return -1 and closes ntkd on error.
  298. */
  299. int
  300. exclude_interface(void)
  301. {
  302. int i;
  303. printf("Number of Interfaces in Use: %d\n", me.cur_ifs_n);
  304. for (i = 0; i < me.cur_ifs_n; i++)
  305. printf("Interface names in Use: %s", me.cur_ifs[i].dev_name);
  306. for (i = 0; i < me.cur_ifs_n; i++) {
  307. if (strcmp(me.cur_ifs[i].dev_name, optarg) == 0) {
  308. printf("Interface %s removed, And replaced with %s",
  309. me.cur_ifs[i].dev_name, me.cur_ifs[me.cur_ifs_n].dev_name);
  310. ifs_del(me.cur_ifs, &me.cur_ifs_n, i);
  311. return 0;
  312. }
  313. else
  314. fatal("Interface %s not found!", optarg);
  315. }
  316. return -1;
  317. }
  318. void
  319. ntk_thread_creatation(void)
  320. {
  321. int x;
  322. pthread_t console_recv_send_thread;
  323. if (pthread_create
  324. (&console_recv_send_thread, NULL, &console_recv_send, &x)) {
  325. fprintf(stderr, "Error creating thread\n");
  326. exit(-1);
  327. }
  328. }
  329. void
  330. parse_options(int argc, char **argv)
  331. {
  332. int c, saved_argc = argc;
  333. int if_n, if_dup;
  334. optind = 0;
  335. while (1) {
  336. int option_index = 0;
  337. static struct option long_options[] = {
  338. {"help", 0, 0, 'h'},
  339. {"iface", 1, 0, 'i'},
  340. {"ipv6", 0, 0, '6'},
  341. {"ipv4", 0, 0, '4'},
  342. {"conf", 1, 0, 'c'},
  343. {"logfile", 1, 0, 'l'},
  344. {"no_andna", 0, 0, 'a'},
  345. {"no_daemon", 0, 0, 'D'},
  346. {"no_resolv", 0, 0, 'R'},
  347. {"restricted", 0, 0, 'r'},
  348. {"share-inet", 0, 0, 'I'},
  349. {"debug", 0, 0, 'd'},
  350. {"version", 0, 0, 'v'},
  351. {"kill", 0, 0, 'k'},
  352. {"exclude", 1, 0, 'e'},
  353. {"console", 0, 0, 'C'},
  354. {"netsplit", 1, 0, 'n'},
  355. {0, 0, 0, 0}
  356. };
  357. c = getopt_long(argc, argv, "i:c:l:e:n:hvd64DRrIakC", long_options,
  358. &option_index);
  359. if (c == -1)
  360. break;
  361. switch (c) {
  362. case 'n':
  363. printf("netsplit argument: %s\n", optarg);
  364. if(strcmp("inet", optarg) == 0 || strcmp("INET", optarg) == 0)
  365. netsplit.netsplit_inet_mode = 1;
  366. if(strcmp("ntk", optarg) == 0 || strcmp("NTK", optarg) == 0)
  367. netsplit.netsplit_ntk_mode = 1;
  368. break;
  369. case 'C':
  370. ntk_thread_creatation();
  371. break;
  372. case 'v':
  373. printf("%s\n", VERSION_STR);
  374. exit(0);
  375. break;
  376. case 'e':
  377. exclude_interface();
  378. break;
  379. case 'k':
  380. if (is_ntkd_already_running() == 1) {
  381. char process_name[256] = { 0 };
  382. pid_t pid;
  383. printf("...Closing ntkd...\n");
  384. FILE *fd = fopen(server_opt.pid_file, "r");
  385. while (fscanf(fd, "%s %d", process_name, &pid) != EOF) {
  386. if (strcmp(process_name, "ntkd") == 0) {
  387. kill(pid, SIGINT);
  388. }
  389. }
  390. fclose(fd);
  391. exit(0);
  392. } else if (is_ntkd_already_running() == 0) {
  393. printf("ntkd is not running\n ...Exiting...\n");
  394. exit(0);
  395. }
  396. break;
  397. case 'h':
  398. usage();
  399. exit(0);
  400. break;
  401. case '4':
  402. server_opt.family = AF_INET;
  403. break;
  404. case '6':
  405. #ifdef IPV6_DISABLED
  406. fatal("The ipv6 is still not supported");
  407. #endif
  408. loginfo
  409. ("WARNING: The ipv6 support is still experimental and under "
  410. "development, nothing is assured to work.");
  411. server_opt.family = AF_INET6;
  412. break;
  413. case 'c':
  414. if(strlen(optarg) > NAME_MAX - 1)
  415. {
  416. optarg[NAME_MAX] = '\0';
  417. }
  418. set_option_str(&(server_opt.config_file), optarg);
  419. break;
  420. case 'l':
  421. if (log_to_file(optarg) < 0)
  422. fatal(0);
  423. break;
  424. case 'i':
  425. if(server_opt.ifs_n+1 >= MAX_INTERFACES)
  426. fatal("The maximum number of interfaces is %d",
  427. MAX_INTERFACES);
  428. if_dup = 0;
  429. printf("IF COUNT : %d\n", server_opt.ifs_n);
  430. for(if_n = 0; if_n < server_opt.ifs_n; if_n++) {
  431. if(strncmp(server_opt.ifs[if_n], optarg, IFNAMSIZ-1) == 0) {
  432. if_dup = 1;
  433. printf("DEDUP !!!\n");
  434. break;
  435. }
  436. }
  437. if(if_dup) { break; }
  438. server_opt.ifs[server_opt.ifs_n++]=xstrndup(optarg, IFNAMSIZ-1);
  439. break;
  440. case 'D':
  441. server_opt.daemon = 0;
  442. break;
  443. case 'a':
  444. server_opt.disable_andna = 1;
  445. break;
  446. case 'R':
  447. server_opt.disable_resolvconf = 1;
  448. break;
  449. case 'r':
  450. server_opt.restricted = 1;
  451. /***
  452. * This is a very dirty hack, but it handles
  453. * the optional argument better than getopt.
  454. *
  455. * This is the problem:
  456. * ntkd -abcrdefg
  457. * If 'r' is an element that specifies an
  458. * optional argument, then the "defg" string
  459. * is taken as its arg, but this is not what
  460. * we want because in this case '-r' is
  461. * specified without its argument.
  462. *
  463. * So, what we do is checking if the argv
  464. * next to the arg of 'r' begins with a '-'
  465. * or not. If not, it is the option of '-r'
  466. *
  467. * The only thing that won't work is:
  468. * ntkd -rOPTION
  469. * it has to be specified in this way:
  470. * ntkd -r OPTION
  471. */
  472. if (argc > optind && argv[optind][0] != '-') {
  473. server_opt.restricted_class = atoi(argv[optind]);
  474. saved_argc--;
  475. }
  476. /**/ break;
  477. case 'I':
  478. server_opt.share_internet = 1;
  479. if (!server_opt.restricted) {
  480. loginfo("Share_internet=1. Assuming restricted=1");
  481. server_opt.restricted = 1;
  482. }
  483. if (!server_opt.inet_connection) {
  484. loginfo("Share_internet=1. Assuming inet_connection=1");
  485. server_opt.inet_connection = 1;
  486. }
  487. break;
  488. case 'd':
  489. server_opt.dbg_lvl++;
  490. break;
  491. default:
  492. usage();
  493. exit(1);
  494. break;
  495. }
  496. }
  497. if (optind < saved_argc && !options_parsed) {
  498. usage();
  499. exit(1);
  500. }
  501. options_parsed++;
  502. }
  503. void
  504. check_conflicting_options(void)
  505. {
  506. #define FATAL_NOT_SPECIFIED(str) fatal("You didn't specified the `%s' " \
  507. "option in netsukuku.conf", \
  508. (str)); \
  509. if (!server_opt.pid_file)
  510. FATAL_NOT_SPECIFIED("pid_file");
  511. if (!server_opt.inet_hosts && server_opt.restricted)
  512. FATAL_NOT_SPECIFIED("internet_ping_hosts");
  513. if (server_opt.restricted && server_opt.share_internet &&
  514. !file_exist(server_opt.ip_masq_script))
  515. fatal("ip_masquerade_script \"%s\" is inexistent",
  516. server_opt.ip_masq_script);
  517. if (server_opt.shape_internet &&
  518. !file_exist(server_opt.tc_shaper_script))
  519. fatal("tc_shaper_script \"%s\" is inexistent",
  520. server_opt.ip_masq_script);
  521. if (!server_opt.restricted && server_opt.inet_connection)
  522. fatal("inet_connection=1 but ntk_restricted_mode=0. If you "
  523. "want to be compatible with the Internet, "
  524. "set the restricted mode in the options");
  525. if (!server_opt.restricted && (server_opt.share_internet))
  526. fatal("You want to share your Internet connection,"
  527. "but I am not running in restricted mode (-r), "
  528. "'cause I'm not sure of what you want... " "I'm aborting.");
  529. if (server_opt.share_internet && me.my_bandwidth < MIN_CONN_BANDWIDTH)
  530. fatal("You want to share your Internet connection but "
  531. "your bandwidth is just TOO small. Do not share "
  532. "it, or your connection will be saturated");
  533. if (!server_opt.inet_connection && server_opt.share_internet) {
  534. loginfo("You want to share your Internet connection,"
  535. "but `internet_connection' is set to 0."
  536. "We are assuming it is 1");
  537. server_opt.inet_connection = 1;
  538. }
  539. if (server_opt.shape_internet && !server_opt.inet_connection)
  540. fatal("The Internet traffic shaping option is set, but "
  541. "the `internet_connection' is set to 0, please check "
  542. "your options.");
  543. #ifdef IPV6_DISABLED
  544. if (server_opt.inet_gw.family == AF_INET6)
  545. fatal("Ipv6 is not supported");
  546. #endif
  547. }
  548. void
  549. init_netsukuku(char **argv)
  550. {
  551. xsrand();
  552. if (geteuid())
  553. fatal("Need root privileges");
  554. destroy_netsukuku_mutex = pid_saved = 0;
  555. sigterm_timestamp = sighup_timestamp = sigalrm_timestamp = 0;
  556. setzero(&me, sizeof(struct current_globals));
  557. if (is_ntkd_already_running())
  558. fatal("ntkd is already running. If it is not, remove \"%s\"",
  559. server_opt.pid_file);
  560. else
  561. save_pid();
  562. my_family = server_opt.family;
  563. restricted_mode = server_opt.restricted;
  564. restricted_class =
  565. server_opt.restricted_class ? RESTRICTED_172 : RESTRICTED_10;
  566. /* Check if the DATA_DIR exists, if not create it */
  567. if (check_and_create_dir(DATA_DIR))
  568. fatal("Cannot access to the %s directory. Exiting.", DATA_DIR);
  569. /*
  570. * Device initialization
  571. */
  572. if (if_init_all(server_opt.ifs, server_opt.ifs_n,
  573. me.cur_ifs, &me.cur_ifs_n) < 0)
  574. fatal("Cannot initialize any network interfaces");
  575. /*
  576. * ANDNA init
  577. */
  578. if (!server_opt.disable_andna)
  579. andna_init();
  580. /*
  581. * Initialize the Internet gateway stuff
  582. */
  583. if (server_opt.my_upload_bw && server_opt.my_dnload_bw)
  584. me.my_bandwidth = bandwidth_in_8bit((server_opt.my_upload_bw +
  585. server_opt.my_dnload_bw) / 2);
  586. init_internet_gateway_search();
  587. pkts_init(me.cur_ifs, me.cur_ifs_n, 0);
  588. qspn_init(FAMILY_LVLS);
  589. me.cur_erc = e_rnode_init(&me.cur_erc_counter);
  590. /* Radar init */
  591. rq_wait_idx_init(rq_wait_idx);
  592. first_init_radar();
  593. total_radars = 0;
  594. ntk_load_maps();
  595. #if 0
  596. /* TODO: activate and test it !! */
  597. debug(DBG_NORMAL, "ACPT: Initializing the accept_tbl: \n"
  598. " max_connections: %d,\n"
  599. " max_accepts_per_host: %d,\n"
  600. " max_accept_per_host_time: %d",
  601. server_opt.max_connections,
  602. server_opt.max_accepts_per_host,
  603. server_opt.max_accepts_per_host_time);
  604. init_accept_tbl(server_opt.max_connections,
  605. server_opt.max_accepts_per_host,
  606. server_opt.max_accepts_per_host_time);
  607. #endif
  608. if (restricted_mode)
  609. loginfo("NetsukukuD is in restricted mode. "
  610. "Restricted class: %s",
  611. server_opt.
  612. restricted_class ? RESTRICTED_172_STR : RESTRICTED_10_STR);
  613. hook_init();
  614. rehook_init();
  615. me.uptime = time(0);
  616. }
  617. int
  618. destroy_netsukuku(void)
  619. {
  620. if (destroy_netsukuku_mutex)
  621. return -1;
  622. destroy_netsukuku_mutex = 1;
  623. unlink(server_opt.pid_file);
  624. ntk_save_maps();
  625. ntk_free_maps();
  626. if (!server_opt.disable_andna)
  627. andna_close();
  628. close_internet_gateway_search();
  629. last_close_radar();
  630. e_rnode_free(&me.cur_erc, &me.cur_erc_counter);
  631. destroy_accept_tbl();
  632. if_close_all();
  633. qspn_free();
  634. free_server_opt();
  635. return 0;
  636. }
  637. void
  638. sigterm_handler(int sig)
  639. {
  640. time_t cur_t;
  641. if (sigterm_timestamp == (cur_t = time(0)))
  642. return;
  643. sigterm_timestamp = time(0);
  644. if (!destroy_netsukuku())
  645. fatal("Termination signal caught. Dying, bye, bye");
  646. }
  647. void *
  648. reload_hostname_thread(void *null)
  649. {
  650. /*
  651. * Reload the file where the hostnames to be registered are and
  652. * register the new ones
  653. */
  654. loginfo("Reloading the andna hostnames file");
  655. load_hostnames(server_opt.andna_hnames_file, &andna_lcl, &lcl_counter);
  656. load_snsd(server_opt.snsd_nodes_file, andna_lcl);
  657. andna_update_hnames(1);
  658. return 0;
  659. }
  660. void
  661. sighup_handler(int sig)
  662. {
  663. pthread_t thread;
  664. pthread_attr_t t_attr;
  665. time_t cur_t;
  666. if (sighup_timestamp == (cur_t = time(0)))
  667. return;
  668. sighup_timestamp = time(0);
  669. pthread_attr_init(&t_attr);
  670. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  671. pthread_create(&thread, &t_attr, reload_hostname_thread, 0);
  672. }
  673. void *
  674. rh_cache_flush_thread(void *null)
  675. {
  676. /*
  677. * Flush the resolved hostnames cache.
  678. */
  679. loginfo("Flush the resolved hostnames cache");
  680. rh_cache_flush();
  681. return 0;
  682. }
  683. void
  684. sigalrm_handler(int sig)
  685. {
  686. pthread_t thread;
  687. pthread_attr_t t_attr;
  688. time_t cur_t;
  689. if (sigalrm_timestamp == (cur_t = time(0)))
  690. return;
  691. sigalrm_timestamp = time(0);
  692. pthread_attr_init(&t_attr);
  693. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  694. pthread_create(&thread, &t_attr, rh_cache_flush_thread, 0);
  695. }
  696. /*
  697. * The main flow shall never be stopped, and the sand of time will be
  698. * revealed.
  699. */
  700. int
  701. main(int argc, char **argv)
  702. {
  703. struct udp_daemon_argv ud_argv;
  704. u_short *port;
  705. pthread_t daemon_tcp_thread, daemon_udp_thread, andna_thread;
  706. pthread_t ping_igw_thread;
  707. pthread_attr_t t_attr;
  708. log_init(argv[0], 0, 1);
  709. /* Options loading... */
  710. fill_default_options();
  711. parse_options(argc, argv);
  712. /* reinit the logs using the new `dbg_lvl' value */
  713. log_init(argv[0], server_opt.dbg_lvl, 1);
  714. log_to_file(0);
  715. /* Load the option from the config file */
  716. load_config_file(server_opt.config_file);
  717. fill_loaded_cfg_options();
  718. /* If a same option was specified in the config file and in the
  719. * command line, give priority to the latter */
  720. parse_options(argc, argv);
  721. check_conflicting_options();
  722. /* Initialize the whole netsukuku source code */
  723. init_netsukuku(argv);
  724. signal(SIGALRM, sigalrm_handler);
  725. signal(SIGHUP, sighup_handler);
  726. signal(SIGINT, sigterm_handler);
  727. signal(SIGTERM, sigterm_handler);
  728. signal(SIGQUIT, sigterm_handler);
  729. /* Angelic foreground or Daemonic background ? */
  730. if (server_opt.daemon) {
  731. loginfo("Forking to background");
  732. log_init(argv[0], server_opt.dbg_lvl, 0);
  733. if (daemon(0, 0) == -1)
  734. error("Impossible to daemonize: %s.", strerror(errno));
  735. }
  736. pthread_attr_init(&t_attr);
  737. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  738. setzero(&ud_argv, sizeof(struct udp_daemon_argv));
  739. port = xmalloc(sizeof(u_short));
  740. /*
  741. * These are the daemons, the main threads that keeps NetsukukuD
  742. * up & running.
  743. */
  744. debug(DBG_NORMAL, "Activating all daemons");
  745. pthread_mutex_init(&udp_daemon_lock, 0);
  746. pthread_mutex_init(&tcp_daemon_lock, 0);
  747. debug(DBG_SOFT, "Evoking the netsukuku udp radar daemon.");
  748. ud_argv.port = ntk_udp_radar_port;
  749. pthread_mutex_lock(&udp_daemon_lock);
  750. pthread_create(&daemon_udp_thread, &t_attr, udp_daemon,
  751. (void *) &ud_argv);
  752. pthread_mutex_lock(&udp_daemon_lock);
  753. pthread_mutex_unlock(&udp_daemon_lock);
  754. debug(DBG_SOFT, "Evoking the netsukuku tcp daemon.");
  755. *port = ntk_tcp_port;
  756. pthread_mutex_lock(&tcp_daemon_lock);
  757. pthread_create(&daemon_tcp_thread, &t_attr, tcp_daemon, (void *) port);
  758. pthread_mutex_lock(&tcp_daemon_lock);
  759. pthread_mutex_unlock(&tcp_daemon_lock);
  760. /* Now we hook in Netsukuku */
  761. netsukuku_hook(0, 0);
  762. /*
  763. * If not disabled, start the ANDNA daemon
  764. */
  765. if (!server_opt.disable_andna)
  766. pthread_create(&andna_thread, &t_attr, andna_main, 0);
  767. xfree(port);
  768. if (restricted_mode && (server_opt.share_internet ||
  769. server_opt.use_shared_inet)) {
  770. debug(DBG_SOFT, "Evoking the Internet Gateway Pinger daemon");
  771. pthread_create(&ping_igw_thread, &t_attr, igw_monitor_igws_t, 0);
  772. }
  773. /* We use this same process for the radar_daemon. */
  774. debug(DBG_SOFT, "Evoking radar daemon.");
  775. radar_daemon(0);
  776. /* Not reached, hahaha */
  777. loginfo("Cya m8");
  778. pthread_attr_destroy(&t_attr);
  779. destroy_netsukuku();
  780. exit(0);
  781. }