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.

ntk-console.c 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /* This file is part of Netsukuku
  2. *
  3. * This source code is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU General Public License as published
  5. * by the Free Software Foundation; either version 2 of the License,
  6. * or (at your option) any later version.
  7. *
  8. * This source code is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * Please refer to the GNU Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Public License along with
  14. * this source code; if not, write to:
  15. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. *
  17. */
  18. #include "ntk-console.h"
  19. #include "console.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <sys/socket.h>
  24. #include <sys/un.h>
  25. #include <time.h>
  26. #include <unistd.h>
  27. const struct supported_commands {
  28. command_t id;
  29. const char *command;
  30. const char *help;
  31. int arguments;
  32. } kSupportedCommands[] = {
  33. {
  34. COMMAND_HELP, "help", "Shows console help", 0}, {
  35. COMMAND_UPTIME, "uptime",
  36. "Returns the time when ntkd finished the hooking", 0}, {
  37. COMMAND_KILL, "kill",
  38. "Kills the running instance of netsukuku with SIGINT", 0}, {
  39. COMMAND_VERSION, "version",
  40. "Shows the running version of the ntk-console, and ntkd.", 0},
  41. {
  42. COMMAND_INETCONN, "inet_connected",
  43. "Query if Ntkd is connected to the internet", 0}, {
  44. COMMAND_CURIFS, "cur_ifs",
  45. "Lists all of the interfaces in cur_ifs", 0}, {
  46. COMMAND_CURIFSCT, "cur_ifs_n",
  47. "Lists the number of interfaces present in `cur_ifs`", 0}, {
  48. COMMAND_CURQSPNID, "cur_qspn_id",
  49. "The current qspn_id we are processing. It is cur_qspn_id[levels] big",
  50. 0}, {
  51. COMMAND_CURIP, "cur_ip", "Current IP address", 0}, {
  52. COMMAND_CURNODE, "cur_node", "Current node", 0}, {
  53. COMMAND_IFS, "ifs", "List all the interfaces in server_opt.ifs", 0}, {
  54. COMMAND_IFSCT, "ifs_n",
  55. "List the number of interfaces present in server_opt.ifs", 0},
  56. {
  57. COMMAND_QUIT, "quit", "Exit the console", 0}, {
  58. COMMAND_CONSUPTIME, "console_uptime",
  59. "Get the uptime of this console", 0},};
  60. command_t
  61. command_parse(char *request)
  62. {
  63. int i;
  64. if (strlen(request) > CONSOLE_BUFFER_LENGTH) {
  65. printf("Error: Command longer than 250 bytes.\n");
  66. return -1;
  67. }
  68. for (i = 0; i < sizeof(kSupportedCommands)
  69. / sizeof(kSupportedCommands[0]); i++) {
  70. if (strncmp(request, kSupportedCommands[i].command,
  71. (int) strlen(request) - 1) == 0) {
  72. return kSupportedCommands[i].id;
  73. }
  74. }
  75. printf("Incorrect or unreadable command, Please correct it.\n");
  76. return -1;
  77. }
  78. static int
  79. request_receive(int sock, char message[], int max)
  80. {
  81. int total = 0;
  82. const int bsize = 1024;
  83. char buffer[bsize + 1];
  84. int read = bsize;
  85. message[0] = 0; // initialize for strcat()
  86. while (read == bsize) {
  87. read = recv(sock, buffer, bsize, 0);
  88. if (read < 0)
  89. return -1; // error, bail out
  90. total += read;
  91. if (total > max)
  92. return -2; // overflow
  93. buffer[read] = 0;
  94. strcat(message, buffer);
  95. }
  96. return total;
  97. }
  98. int
  99. opensocket(void)
  100. {
  101. sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  102. if (sockfd < 0) {
  103. perror("socket creation failed");
  104. return -1;
  105. }
  106. memset(&serveraddr, 0, sizeof(serveraddr));
  107. serveraddr.sun_family = AF_UNIX;
  108. strcpy(serveraddr.sun_path, CONSOLE_SOCKET_PATH);
  109. rc = connect(sockfd, (struct sockaddr *) &serveraddr,
  110. sizeof(serveraddr));
  111. if (rc < 0) {
  112. perror("connect() failed");
  113. return -1;
  114. }
  115. return 0;
  116. }
  117. void
  118. closesocket(void)
  119. {
  120. const int optVal = 1;
  121. const socklen_t optLen = sizeof(optVal);
  122. setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &optVal, optLen);
  123. if (sockfd >= 0)
  124. close(sockfd);
  125. }
  126. /* Sends and receives to ntkd */
  127. void
  128. ntkd_request(command_t command)
  129. {
  130. if (opensocket() < 0) {
  131. printf("Unable to connect to ntk daemon console.\n");
  132. return;
  133. }
  134. cmd_packet_t packetOut;
  135. packetOut.command = command;
  136. rc = send(sockfd, &packetOut, sizeof(packetOut), 0);
  137. if (rc < sizeof(packetOut)) {
  138. perror("send() failed");
  139. exit(-1);
  140. }
  141. char *response = (char *) malloc(CONSOLE_BUFFER_LENGTH);
  142. request_receive(sockfd, response, CONSOLE_BUFFER_LENGTH);
  143. if (rc < 0) {
  144. perror("recv() failed");
  145. exit(-1);
  146. }
  147. printf("%s\n", response);
  148. free(response);
  149. closesocket();
  150. }
  151. void
  152. console_uptime(void)
  153. {
  154. unsigned int uptime_sec1;
  155. unsigned int uptime_min1;
  156. unsigned int uptime_hour1;
  157. unsigned int uptime_day1;
  158. unsigned int uptime_month1;
  159. unsigned int uptime_year1;
  160. time(&rawtime);
  161. timeinfo = localtime(&rawtime);
  162. uptime_sec1 = timeinfo->tm_sec;
  163. uptime_min1 = timeinfo->tm_min;
  164. uptime_hour1 = timeinfo->tm_hour;
  165. uptime_day1 = timeinfo->tm_mday;
  166. uptime_month1 = timeinfo->tm_mon;
  167. uptime_year1 = timeinfo->tm_year;
  168. uptime_sec1 -= uptime_sec;
  169. uptime_min1 -= uptime_min;
  170. uptime_hour1 -= uptime_hour;
  171. uptime_day1 -= uptime_day;
  172. uptime_month1 -= uptime_month;
  173. uptime_year1 -= uptime_year;
  174. /* Checks if the date/time is negative,
  175. * And makes it positive.
  176. * e.g -11 is 1 because this is a signed variable
  177. * at a modulus of 12. Thus after 12, It is -12
  178. * which is zero, Every number after this is counting up
  179. * to 12 again, Which is going to be 0 in this instance.
  180. * -12 to 12 is 24 actual months.
  181. * So -11 + 12 is 1, As it should be, And -12 + 12 is zero
  182. * as it should be. The only difference is the modulus number,
  183. * i.e: 12, 24, etc. */
  184. if(uptime_month1 < 0)
  185. {
  186. uptime_month1 += 12;
  187. }
  188. if(uptime_day1 < 0)
  189. {
  190. uptime_day1 += 365;
  191. }
  192. if(uptime_hour1 < 0)
  193. {
  194. uptime_hour1 += 24;
  195. }
  196. if(uptime_min1 < 0)
  197. {
  198. uptime_min1 += 60;
  199. }
  200. if(uptime_sec1 < 0)
  201. {
  202. uptime_sec1 += 60;
  203. }
  204. /* Checks if the date/time is the modulus, And resets it to zero.
  205. * e.g: 12 months is a year, Listing 12 months and one year
  206. * is confusing,
  207. * And implies that it has been two years. */
  208. if(uptime_month1 == 12)
  209. {
  210. uptime_month1 = 0;
  211. }
  212. if(uptime_day1 == 365)
  213. {
  214. uptime_day1 = 0;
  215. }
  216. if(uptime_hour1 == 24)
  217. {
  218. uptime_hour1 = 0;
  219. }
  220. if(uptime_min1 == 60)
  221. {
  222. uptime_min1 = 0;
  223. }
  224. if(uptime_sec1 == 60)
  225. {
  226. uptime_sec1 = 0;
  227. }
  228. printf("Total Uptime is: %i Year(s), %i Month(s), %i Day(s), %i Hour(s), %i Minute(s), %i Second(s)\n",uptime_year1, uptime_month1, uptime_day1, uptime_hour1, uptime_min1, uptime_sec1);
  229. }
  230. static void
  231. millisleep(unsigned ms)
  232. {
  233. usleep(1000 * ms);
  234. }
  235. void
  236. console(char *request)
  237. {
  238. command_t commandID = command_parse(request);
  239. switch (commandID) {
  240. case COMMAND_QUIT:
  241. closesocket();
  242. exit(0);
  243. break;
  244. case COMMAND_UPTIME:
  245. case COMMAND_INETCONN:
  246. case COMMAND_CURIFS:
  247. case COMMAND_CURIFSCT:
  248. case COMMAND_CURQSPNID:
  249. case COMMAND_CURIP:
  250. case COMMAND_CURNODE:
  251. case COMMAND_IFS:
  252. case COMMAND_IFSCT:
  253. ntkd_request(commandID);
  254. millisleep(200);
  255. break;
  256. case COMMAND_VERSION:
  257. printf("ntk-console version: %d.%d\n",
  258. CONSOLE_VERSION_MAJOR, CONSOLE_VERSION_MINOR);
  259. ntkd_request(commandID);
  260. break;
  261. case COMMAND_CONSUPTIME:
  262. console_uptime();
  263. break;
  264. case COMMAND_KILL:
  265. closesocket();
  266. system("ntkd -k");
  267. break;
  268. case COMMAND_HELP:
  269. default:
  270. usage();
  271. }
  272. }
  273. int
  274. main(void)
  275. {
  276. time(&rawtime);
  277. timeinfo = localtime(&rawtime);
  278. uptime_sec = timeinfo->tm_sec;
  279. uptime_min = timeinfo->tm_min;
  280. uptime_hour = timeinfo->tm_hour;
  281. uptime_day = timeinfo->tm_mday;
  282. uptime_month = timeinfo->tm_mon;
  283. uptime_year = timeinfo->tm_year;
  284. printf
  285. ("This is the Netsukuku Console. Please type 'help' for more information.\n");
  286. for (;;) {
  287. char *request = (char *) malloc(CONSOLE_BUFFER_LENGTH);
  288. printf("\n> ");
  289. fgets(request, 16, stdin);
  290. fflush(stdin);
  291. console(request);
  292. free(request);
  293. closesocket();
  294. }
  295. return 0;
  296. }
  297. void
  298. usage(void)
  299. {
  300. int i;
  301. printf("Usage:\n");
  302. for (i = 0; i < sizeof(kSupportedCommands)
  303. / sizeof(kSupportedCommands[0]); i++) {
  304. printf(" %16s - %s\n", kSupportedCommands[i].command,
  305. kSupportedCommands[i].help);
  306. }
  307. }