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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  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");
  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. server_opt.config_file = NTK_CONFIG_FILE;
  171. server_opt.pid_file = NTK_PID_FILE;
  172. server_opt.int_map_file = INT_MAP_FILE;
  173. server_opt.ext_map_file = EXT_MAP_FILE;
  174. server_opt.bnode_map_file = BNODE_MAP_FILE;
  175. server_opt.andna_hnames_file = ANDNA_HNAMES_FILE;
  176. server_opt.snsd_nodes_file = SNSD_NODES_FILE;
  177. server_opt.andna_cache_file = ANDNA_CACHE_FILE;
  178. server_opt.lclkey_file = LCLKEY_FILE;
  179. server_opt.lcl_file = LCL_FILE;
  180. server_opt.rhc_file = RHC_FILE;
  181. 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. server_opt.ip_masq_script = IPMASQ_SCRIPT_FILE;
  190. 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_GET_STRN_VALUE(CONF_NTK_INT_MAP_FILE, &server_opt.int_map_file,
  205. NAME_MAX - 1);
  206. CONF_GET_STRN_VALUE(CONF_NTK_BNODE_MAP_FILE,
  207. &server_opt.bnode_map_file, NAME_MAX - 1);
  208. CONF_GET_STRN_VALUE(CONF_NTK_EXT_MAP_FILE, &server_opt.ext_map_file,
  209. NAME_MAX - 1);
  210. CONF_GET_STRN_VALUE(CONF_ANDNA_HNAMES_FILE,
  211. &server_opt.andna_hnames_file, NAME_MAX - 1);
  212. CONF_GET_STRN_VALUE(CONF_SNSD_NODES_FILE, &server_opt.snsd_nodes_file,
  213. NAME_MAX - 1);
  214. CONF_GET_STRN_VALUE(CONF_ANDNA_CACHE_FILE,
  215. &server_opt.andna_cache_file, NAME_MAX - 1);
  216. CONF_GET_STRN_VALUE(CONF_ANDNA_LCLKEY_FILE, &server_opt.lclkey_file,
  217. NAME_MAX - 1);
  218. CONF_GET_STRN_VALUE(CONF_ANDNA_LCL_FILE, &server_opt.lcl_file,
  219. NAME_MAX - 1);
  220. CONF_GET_STRN_VALUE(CONF_ANDNA_RHC_FILE, &server_opt.rhc_file,
  221. NAME_MAX - 1);
  222. CONF_GET_STRN_VALUE(CONF_ANDNA_COUNTER_C_FILE,
  223. &server_opt.counter_c_file, NAME_MAX - 1);
  224. CONF_GET_STRN_VALUE(CONF_NTK_PID_FILE, &server_opt.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. if (server_opt.config_file != NTK_CONFIG_FILE)
  278. xfree(server_opt.config_file);
  279. if (server_opt.pid_file != NTK_PID_FILE)
  280. xfree(server_opt.pid_file);
  281. if (server_opt.int_map_file != INT_MAP_FILE)
  282. xfree(server_opt.int_map_file);
  283. if (server_opt.ext_map_file != EXT_MAP_FILE)
  284. xfree(server_opt.ext_map_file);
  285. if (server_opt.bnode_map_file != BNODE_MAP_FILE)
  286. xfree(server_opt.bnode_map_file);
  287. if (server_opt.andna_hnames_file != ANDNA_HNAMES_FILE)
  288. xfree(server_opt.andna_hnames_file);
  289. if (server_opt.snsd_nodes_file != SNSD_NODES_FILE)
  290. xfree(server_opt.snsd_nodes_file);
  291. if (server_opt.andna_cache_file != ANDNA_CACHE_FILE)
  292. xfree(server_opt.andna_cache_file);
  293. if (server_opt.lclkey_file != LCLKEY_FILE)
  294. xfree(server_opt.lclkey_file);
  295. if (server_opt.lcl_file != LCL_FILE)
  296. xfree(server_opt.lcl_file);
  297. if (server_opt.rhc_file != RHC_FILE)
  298. xfree(server_opt.rhc_file);
  299. if (server_opt.counter_c_file != COUNTER_C_FILE)
  300. xfree(server_opt.counter_c_file);
  301. if (server_opt.ip_masq_script != IPMASQ_SCRIPT_FILE)
  302. xfree(server_opt.ip_masq_script);
  303. if (server_opt.tc_shaper_script != TCSHAPER_SCRIPT_FILE)
  304. xfree(server_opt.tc_shaper_script);
  305. if (server_opt.inet_gw_dev)
  306. xfree(server_opt.inet_gw_dev);
  307. for (i = 0; i < MAX_INTERFACES && server_opt.ifs[i]; i++)
  308. xfree(server_opt.ifs[i]);
  309. }
  310. /* Removes specified existing interface, Ntkd should populate the device list
  311. * prior to this.
  312. * returns 0 on success, And closes ntkd on error.
  313. */
  314. int
  315. exclude_interface(void)
  316. {
  317. int i;
  318. printf("Number of Interfaces in Use: %d\n", me.cur_ifs_n);
  319. for (i = 0; i < me.cur_ifs_n; i++)
  320. printf("Interface names in Use: %s", me.cur_ifs[i].dev_name);
  321. for (i = 0; i < me.cur_ifs_n; i++) {
  322. if (strcmp(me.cur_ifs[i].dev_name, optarg) == 0) {
  323. printf("Interface %s removed, And replaced with %s",
  324. me.cur_ifs[i].dev_name, me.cur_ifs[me.cur_ifs_n].dev_name);
  325. ifs_del(me.cur_ifs, &me.cur_ifs_n, i);
  326. return 0;
  327. }
  328. else
  329. fatal("Interface %s not found!", optarg);
  330. }
  331. }
  332. void
  333. ntk_thread_creatation(void)
  334. {
  335. int x;
  336. pthread_t console_recv_send_thread;
  337. if (pthread_create
  338. (&console_recv_send_thread, NULL, &console_recv_send, &x)) {
  339. fprintf(stderr, "Error creating thread\n");
  340. exit(-1);
  341. }
  342. }
  343. void
  344. parse_options(int argc, char **argv)
  345. {
  346. int c, saved_argc = argc;
  347. optind = 0;
  348. while (1) {
  349. int option_index = 0;
  350. static struct option long_options[] = {
  351. {"help", 0, 0, 'h'},
  352. {"iface", 1, 0, 'i'},
  353. {"ipv6", 0, 0, '6'},
  354. {"ipv4", 0, 0, '4'},
  355. {"conf", 1, 0, 'c'},
  356. {"logfile", 1, 0, 'l'},
  357. {"no_andna", 0, 0, 'a'},
  358. {"no_daemon", 0, 0, 'D'},
  359. {"no_resolv", 0, 0, 'R'},
  360. {"restricted", 0, 0, 'r'},
  361. {"share-inet", 0, 0, 'I'},
  362. {"debug", 0, 0, 'd'},
  363. {"version", 0, 0, 'v'},
  364. {"kill", 0, 0, 'k'},
  365. {"exclude", 1, 0, 'e'},
  366. {"console", 0, 0, 'C'},
  367. {"netsplit", 1, 0, 'n'},
  368. {0, 0, 0, 0}
  369. };
  370. c = getopt_long(argc, argv, "i:c:l:e:n:hvd64DRrIakC", long_options,
  371. &option_index);
  372. if (c == -1)
  373. break;
  374. switch (c) {
  375. case 'n':
  376. printf("netsplit argument: %s\n", optarg);
  377. if(strcmp("inet", optarg) == 0 || strcmp("INET", optarg) == 0)
  378. netsplit.netsplit_inet_mode = 1;
  379. if(strcmp("ntk", optarg) == 0 || strcmp("NTK", optarg) == 0)
  380. netsplit.netsplit_ntk_mode = 1;
  381. break;
  382. case 'C':
  383. ntk_thread_creatation();
  384. break;
  385. case 'v':
  386. printf("%s\n", VERSION_STR);
  387. exit(0);
  388. break;
  389. case 'e':
  390. exclude_interface();
  391. break;
  392. case 'k':
  393. if (is_ntkd_already_running() == 1) {
  394. char process_name[256] = { 0 };
  395. pid_t pid;
  396. printf("...Closing ntkd...\n");
  397. FILE *fd = fopen(server_opt.pid_file, "r");
  398. while (fscanf(fd, "%s %d", process_name, &pid) != EOF) {
  399. if (strcmp(process_name, "ntkd") == 0) {
  400. kill(pid, SIGINT);
  401. }
  402. }
  403. fclose(fd);
  404. exit(0);
  405. } else if (is_ntkd_already_running() == 0) {
  406. printf("ntkd is not running\n ...Exiting...\n");
  407. exit(0);
  408. }
  409. break;
  410. case 'h':
  411. usage();
  412. exit(0);
  413. break;
  414. case '4':
  415. server_opt.family = AF_INET;
  416. break;
  417. case '6':
  418. #ifdef IPV6_DISABLED
  419. fatal("The ipv6 is still not supported");
  420. #endif
  421. loginfo
  422. ("WARNING: The ipv6 support is still experimental and under "
  423. "development, nothing is assured to work.");
  424. server_opt.family = AF_INET6;
  425. break;
  426. case 'c':
  427. server_opt.config_file = xstrndup(optarg, NAME_MAX - 1);
  428. break;
  429. case 'l':
  430. if (log_to_file(optarg) < 0)
  431. fatal(0);
  432. break;
  433. case 'i':
  434. if(server_opt.ifs_n+1 >= MAX_INTERFACES)
  435. fatal("The maximum number of interfaces is %d",
  436. MAX_INTERFACES);
  437. server_opt.ifs[server_opt.ifs_n++]=xstrndup(optarg, IFNAMSIZ-1);
  438. break;
  439. case 'D':
  440. server_opt.daemon = 0;
  441. break;
  442. case 'a':
  443. server_opt.disable_andna = 1;
  444. break;
  445. case 'R':
  446. server_opt.disable_resolvconf = 1;
  447. break;
  448. case 'r':
  449. server_opt.restricted = 1;
  450. /***
  451. * This is a very dirty hack, but it handles
  452. * the optional argument better than getopt.
  453. *
  454. * This is the problem:
  455. * ntkd -abcrdefg
  456. * If 'r' is an element that specifies an
  457. * optional argument, then the "defg" string
  458. * is taken as its arg, but this is not what
  459. * we want because in this case '-r' is
  460. * specified without its argument.
  461. *
  462. * So, what we do is checking if the argv
  463. * next to the arg of 'r' begins with a '-'
  464. * or not. If not, it is the option of '-r'
  465. *
  466. * The only thing that won't work is:
  467. * ntkd -rOPTION
  468. * it has to be specified in this way:
  469. * ntkd -r OPTION
  470. */
  471. if (argc > optind && argv[optind][0] != '-') {
  472. server_opt.restricted_class = atoi(argv[optind]);
  473. saved_argc--;
  474. }
  475. /**/ break;
  476. case 'I':
  477. server_opt.share_internet = 1;
  478. if (!server_opt.restricted) {
  479. loginfo("Share_internet=1. Assuming restricted=1");
  480. server_opt.restricted = 1;
  481. }
  482. if (!server_opt.inet_connection) {
  483. loginfo("Share_internet=1. Assuming inet_connection=1");
  484. server_opt.inet_connection = 1;
  485. }
  486. break;
  487. case 'd':
  488. server_opt.dbg_lvl++;
  489. break;
  490. default:
  491. usage();
  492. exit(1);
  493. break;
  494. }
  495. }
  496. if (optind < saved_argc && !options_parsed) {
  497. usage();
  498. exit(1);
  499. }
  500. options_parsed++;
  501. }
  502. void
  503. check_conflicting_options(void)
  504. {
  505. #define FATAL_NOT_SPECIFIED(str) fatal("You didn't specified the `%s' " \
  506. "option in netsukuku.conf", \
  507. (str)); \
  508. if (!server_opt.pid_file)
  509. FATAL_NOT_SPECIFIED("pid_file");
  510. if (!server_opt.inet_hosts && server_opt.restricted)
  511. FATAL_NOT_SPECIFIED("internet_ping_hosts");
  512. if (server_opt.restricted && server_opt.share_internet &&
  513. !file_exist(server_opt.ip_masq_script))
  514. fatal("ip_masquerade_script \"%s\" is inexistent",
  515. server_opt.ip_masq_script);
  516. if (server_opt.shape_internet &&
  517. !file_exist(server_opt.tc_shaper_script))
  518. fatal("tc_shaper_script \"%s\" is inexistent",
  519. server_opt.ip_masq_script);
  520. if (!server_opt.restricted && server_opt.inet_connection)
  521. fatal("inet_connection=1 but ntk_restricted_mode=0. If you "
  522. "want to be compatible with the Internet, "
  523. "set the restricted mode in the options");
  524. if (!server_opt.restricted && (server_opt.share_internet))
  525. fatal("You want to share your Internet connection,"
  526. "but I am not running in restricted mode (-r), "
  527. "'cause I'm not sure of what you want... " "I'm aborting.");
  528. if (server_opt.share_internet && me.my_bandwidth < MIN_CONN_BANDWIDTH)
  529. fatal("You want to share your Internet connection but "
  530. "your bandwidth is just TOO small. Do not share "
  531. "it, or your connection will be saturated");
  532. if (!server_opt.inet_connection && server_opt.share_internet) {
  533. loginfo("You want to share your Internet connection,"
  534. "but `internet_connection' is set to 0."
  535. "We are assuming it is 1");
  536. server_opt.inet_connection = 1;
  537. }
  538. if (server_opt.shape_internet && !server_opt.inet_connection)
  539. fatal("The Internet traffic shaping option is set, but "
  540. "the `internet_connection' is set to 0, please check "
  541. "your options.");
  542. #ifdef IPV6_DISABLED
  543. if (server_opt.inet_gw.family == AF_INET6)
  544. fatal("Ipv6 is not supported");
  545. #endif
  546. }
  547. void
  548. init_netsukuku(char **argv)
  549. {
  550. xsrand();
  551. if (geteuid())
  552. fatal("Need root privileges");
  553. destroy_netsukuku_mutex = pid_saved = 0;
  554. sigterm_timestamp = sighup_timestamp = sigalrm_timestamp = 0;
  555. setzero(&me, sizeof(struct current_globals));
  556. if (is_ntkd_already_running())
  557. fatal("ntkd is already running. If it is not, remove \"%s\"",
  558. server_opt.pid_file);
  559. else
  560. save_pid();
  561. my_family = server_opt.family;
  562. restricted_mode = server_opt.restricted;
  563. restricted_class =
  564. server_opt.restricted_class ? RESTRICTED_172 : RESTRICTED_10;
  565. /* Check if the DATA_DIR exists, if not create it */
  566. if (check_and_create_dir(DATA_DIR))
  567. fatal("Cannot access to the %s directory. Exiting.", DATA_DIR);
  568. /*
  569. * Device initialization
  570. */
  571. if (if_init_all(server_opt.ifs, server_opt.ifs_n,
  572. me.cur_ifs, &me.cur_ifs_n) < 0)
  573. fatal("Cannot initialize any network interfaces");
  574. /*
  575. * ANDNA init
  576. */
  577. if (!server_opt.disable_andna)
  578. andna_init();
  579. /*
  580. * Initialize the Internet gateway stuff
  581. */
  582. if (server_opt.my_upload_bw && server_opt.my_dnload_bw)
  583. me.my_bandwidth = bandwidth_in_8bit((server_opt.my_upload_bw +
  584. server_opt.my_dnload_bw) / 2);
  585. init_internet_gateway_search();
  586. pkts_init(me.cur_ifs, me.cur_ifs_n, 0);
  587. qspn_init(FAMILY_LVLS);
  588. me.cur_erc = e_rnode_init(&me.cur_erc_counter);
  589. /* Radar init */
  590. rq_wait_idx_init(rq_wait_idx);
  591. first_init_radar();
  592. total_radars = 0;
  593. ntk_load_maps();
  594. #if 0
  595. /* TODO: activate and test it !! */
  596. debug(DBG_NORMAL, "ACPT: Initializing the accept_tbl: \n"
  597. " max_connections: %d,\n"
  598. " max_accepts_per_host: %d,\n"
  599. " max_accept_per_host_time: %d",
  600. server_opt.max_connections,
  601. server_opt.max_accepts_per_host,
  602. server_opt.max_accepts_per_host_time);
  603. init_accept_tbl(server_opt.max_connections,
  604. server_opt.max_accepts_per_host,
  605. server_opt.max_accepts_per_host_time);
  606. #endif
  607. if (restricted_mode)
  608. loginfo("NetsukukuD is in restricted mode. "
  609. "Restricted class: %s",
  610. server_opt.
  611. restricted_class ? RESTRICTED_172_STR : RESTRICTED_10_STR);
  612. hook_init();
  613. rehook_init();
  614. me.uptime = time(0);
  615. }
  616. int
  617. destroy_netsukuku(void)
  618. {
  619. if (destroy_netsukuku_mutex)
  620. return -1;
  621. destroy_netsukuku_mutex = 1;
  622. unlink(server_opt.pid_file);
  623. ntk_save_maps();
  624. ntk_free_maps();
  625. if (!server_opt.disable_andna)
  626. andna_close();
  627. close_internet_gateway_search();
  628. last_close_radar();
  629. e_rnode_free(&me.cur_erc, &me.cur_erc_counter);
  630. destroy_accept_tbl();
  631. if_close_all();
  632. qspn_free();
  633. free_server_opt();
  634. return 0;
  635. }
  636. void
  637. sigterm_handler(int sig)
  638. {
  639. time_t cur_t;
  640. if (sigterm_timestamp == (cur_t = time(0)))
  641. return;
  642. sigterm_timestamp = time(0);
  643. if (!destroy_netsukuku())
  644. fatal("Termination signal caught. Dying, bye, bye");
  645. }
  646. void *
  647. reload_hostname_thread(void *null)
  648. {
  649. /*
  650. * Reload the file where the hostnames to be registered are and
  651. * register the new ones
  652. */
  653. loginfo("Reloading the andna hostnames file");
  654. load_hostnames(server_opt.andna_hnames_file, &andna_lcl, &lcl_counter);
  655. load_snsd(server_opt.snsd_nodes_file, andna_lcl);
  656. andna_update_hnames(1);
  657. return 0;
  658. }
  659. void
  660. sighup_handler(int sig)
  661. {
  662. pthread_t thread;
  663. pthread_attr_t t_attr;
  664. time_t cur_t;
  665. if (sighup_timestamp == (cur_t = time(0)))
  666. return;
  667. sighup_timestamp = time(0);
  668. pthread_attr_init(&t_attr);
  669. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  670. pthread_create(&thread, &t_attr, reload_hostname_thread, 0);
  671. }
  672. void *
  673. rh_cache_flush_thread(void *null)
  674. {
  675. /*
  676. * Flush the resolved hostnames cache.
  677. */
  678. loginfo("Flush the resolved hostnames cache");
  679. rh_cache_flush();
  680. return 0;
  681. }
  682. void
  683. sigalrm_handler(int sig)
  684. {
  685. pthread_t thread;
  686. pthread_attr_t t_attr;
  687. time_t cur_t;
  688. if (sigalrm_timestamp == (cur_t = time(0)))
  689. return;
  690. sigalrm_timestamp = time(0);
  691. pthread_attr_init(&t_attr);
  692. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  693. pthread_create(&thread, &t_attr, rh_cache_flush_thread, 0);
  694. }
  695. /*
  696. * The main flow shall never be stopped, and the sand of time will be
  697. * revealed.
  698. */
  699. int
  700. main(int argc, char **argv)
  701. {
  702. struct udp_daemon_argv ud_argv;
  703. u_short *port;
  704. pthread_t daemon_tcp_thread, daemon_udp_thread, andna_thread;
  705. pthread_t ping_igw_thread;
  706. pthread_attr_t t_attr;
  707. log_init(argv[0], 0, 1);
  708. /* Options loading... */
  709. fill_default_options();
  710. parse_options(argc, argv);
  711. /* reinit the logs using the new `dbg_lvl' value */
  712. log_init(argv[0], server_opt.dbg_lvl, 1);
  713. log_to_file(0);
  714. /* Load the option from the config file */
  715. load_config_file(server_opt.config_file);
  716. fill_loaded_cfg_options();
  717. /* If a same option was specified in the config file and in the
  718. * command line, give priority to the latter */
  719. parse_options(argc, argv);
  720. check_conflicting_options();
  721. /* Initialize the whole netsukuku source code */
  722. init_netsukuku(argv);
  723. signal(SIGALRM, sigalrm_handler);
  724. signal(SIGHUP, sighup_handler);
  725. signal(SIGINT, sigterm_handler);
  726. signal(SIGTERM, sigterm_handler);
  727. signal(SIGQUIT, sigterm_handler);
  728. /* Angelic foreground or Daemonic background ? */
  729. if (server_opt.daemon) {
  730. loginfo("Forking to background");
  731. log_init(argv[0], server_opt.dbg_lvl, 0);
  732. if (daemon(0, 0) == -1)
  733. error("Impossible to daemonize: %s.", strerror(errno));
  734. }
  735. pthread_attr_init(&t_attr);
  736. pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
  737. setzero(&ud_argv, sizeof(struct udp_daemon_argv));
  738. port = xmalloc(sizeof(u_short));
  739. /*
  740. * These are the daemons, the main threads that keeps NetsukukuD
  741. * up & running.
  742. */
  743. debug(DBG_NORMAL, "Activating all daemons");
  744. pthread_mutex_init(&udp_daemon_lock, 0);
  745. pthread_mutex_init(&tcp_daemon_lock, 0);
  746. debug(DBG_SOFT, "Evoking the netsukuku udp radar daemon.");
  747. ud_argv.port = ntk_udp_radar_port;
  748. pthread_mutex_lock(&udp_daemon_lock);
  749. pthread_create(&daemon_udp_thread, &t_attr, udp_daemon,
  750. (void *) &ud_argv);
  751. pthread_mutex_lock(&udp_daemon_lock);
  752. pthread_mutex_unlock(&udp_daemon_lock);
  753. debug(DBG_SOFT, "Evoking the netsukuku tcp daemon.");
  754. *port = ntk_tcp_port;
  755. pthread_mutex_lock(&tcp_daemon_lock);
  756. pthread_create(&daemon_tcp_thread, &t_attr, tcp_daemon, (void *) port);
  757. pthread_mutex_lock(&tcp_daemon_lock);
  758. pthread_mutex_unlock(&tcp_daemon_lock);
  759. /* Now we hook in Netsukuku */
  760. netsukuku_hook(0, 0);
  761. /*
  762. * If not disabled, start the ANDNA daemon
  763. */
  764. if (!server_opt.disable_andna)
  765. pthread_create(&andna_thread, &t_attr, andna_main, 0);
  766. xfree(port);
  767. if (restricted_mode && (server_opt.share_internet ||
  768. server_opt.use_shared_inet)) {
  769. debug(DBG_SOFT, "Evoking the Internet Gateway Pinger daemon");
  770. pthread_create(&ping_igw_thread, &t_attr, igw_monitor_igws_t, 0);
  771. }
  772. /* We use this same process for the radar_daemon. */
  773. debug(DBG_SOFT, "Evoking radar daemon.");
  774. radar_daemon(0);
  775. /* Not reached, hahaha */
  776. loginfo("Cya m8");
  777. pthread_attr_destroy(&t_attr);
  778. destroy_netsukuku();
  779. exit(0);
  780. }