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 26KB

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