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-server.c 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /* Header files required for the console bindings
  2. * not included outside of this file. */
  3. #include <utmp.h>
  4. #include <stdio.h>
  5. #include <sys/un.h>
  6. #include <unistd.h>
  7. #include "console.h"
  8. #include "netsukuku.h"
  9. /* Variable and structure defintions, serverfd refers to socket file descriptor
  10. * length refers to the required length of the requests that will be sent.
  11. * recv won't wake up until length is received.
  12. * rc is used for error checking in socket operations.
  13. * serveraddr is a structure describing the address of
  14. * an AF_LOCAL (aka AF_UNIX) socket. */
  15. int serverfd = -1;
  16. struct sockaddr_un serveraddr;
  17. int rc, length;
  18. /* Cleans up the console bindings for closing, Closes socket file descriptors,
  19. * unlinks the server path, etc. */
  20. static void
  21. clean_up(void)
  22. {
  23. const int optVal = 1;
  24. const socklen_t optLen = sizeof(optVal);
  25. setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (void *) &optVal,
  26. optLen);
  27. if (serverfd != -1)
  28. close(serverfd);
  29. unlink(CONSOLE_SOCKET_PATH);
  30. }
  31. /* Creates an AF_UNIX socket and binds it to a local address. */
  32. static void
  33. opensocket(void)
  34. {
  35. int stop_trying;
  36. serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
  37. if (serverfd < 0) {
  38. perror("socket creation failed");
  39. exit(-1);
  40. }
  41. memset(&serveraddr, 0, sizeof(serveraddr));
  42. serveraddr.sun_family = AF_UNIX;
  43. strcpy(serveraddr.sun_path, CONSOLE_SOCKET_PATH);
  44. rc = bind(serverfd, (struct sockaddr *) &serveraddr,
  45. SUN_LEN(&serveraddr));
  46. if (rc < 0) {
  47. perror("bind() failed");
  48. clean_up();
  49. if (stop_trying >= 2) {
  50. perror("bind() failed");
  51. clean_up();
  52. opensocket();
  53. exit(-1);
  54. }
  55. stop_trying++;
  56. opensocket();
  57. }
  58. }
  59. /* Sends a parsed response to the ntk console client. */
  60. static void
  61. send_response(int session_fd, char response[CONSOLE_BUFFER_LENGTH], ...)
  62. {
  63. int response_length = (int) strlen(response);
  64. rc = send(session_fd, response, response_length, 0);
  65. if (rc < 0) {
  66. perror("send() failed");
  67. exit(-1);
  68. }
  69. }
  70. /* Parses the received request from the ntk console client
  71. * to data from ntkd structures such as: me
  72. * into a response for the ntk console client. */
  73. static void
  74. request_processing(int session_fd, cmd_packet_t packet)
  75. {
  76. char buffer[CONSOLE_BUFFER_LENGTH];
  77. int maxBuffer = CONSOLE_BUFFER_LENGTH - 1;
  78. memset(buffer, 0, sizeof(buffer));
  79. switch (packet.command) {
  80. case COMMAND_UPTIME:
  81. {
  82. int uptime = time(0) - me.uptime;
  83. snprintf(buffer, maxBuffer, "node uptime: %d seconds", uptime);
  84. break;
  85. }
  86. case COMMAND_VERSION:
  87. snprintf(buffer, maxBuffer, "ntkd version: %s", VERSION_STR);
  88. break;
  89. case COMMAND_CURIFS:
  90. {
  91. strcat(buffer, "current interfaces: ");
  92. int i;
  93. for (i = 0; i < me.cur_ifs_n; i++) {
  94. strcat(buffer, me.cur_ifs[i].dev_name);
  95. strcat(buffer, " ");
  96. }
  97. break;
  98. }
  99. case COMMAND_CURIFSCT:
  100. snprintf(buffer, maxBuffer, "current interface count: %d",
  101. me.cur_ifs_n);
  102. break;
  103. case COMMAND_INETCONN:
  104. if (me.inet_connected)
  105. snprintf(buffer, maxBuffer, "internet connectivity: true");
  106. else
  107. snprintf(buffer, maxBuffer, "internet connectivity: false");
  108. break;
  109. case COMMAND_CURQSPNID:
  110. //send_response(session_fd, (char)me.cur_qspn_id);
  111. break;
  112. case COMMAND_CURIP:
  113. snprintf(buffer, maxBuffer, "IP: %s", inet_to_str(me.cur_ip));
  114. break;
  115. case COMMAND_CURNODE:
  116. //send_response(session_fd, (char)me.cur_node);
  117. break;
  118. case COMMAND_IFS:
  119. //send_response(session_fd, "IFS: TODO");
  120. break;
  121. case COMMAND_IFSCT:
  122. //send_response(session_fd, "IFS: TODO");
  123. break;
  124. default:
  125. snprintf(buffer, maxBuffer,
  126. "Provided command is invalid or not implemented in this API");
  127. break;
  128. }
  129. send_response(session_fd, buffer);
  130. }
  131. static void
  132. handle_session(int session_fd)
  133. {
  134. cmd_packet_t packetIn;
  135. rc = recv(session_fd, &packetIn, sizeof(packetIn), 0);
  136. if (rc < sizeof(packetIn)) {
  137. perror("recv() failed");
  138. exit(-1);
  139. }
  140. request_processing(session_fd, packetIn);
  141. }
  142. static void
  143. wait_session(int server_fd)
  144. {
  145. rc = listen(serverfd, 10);
  146. if (rc < 0) {
  147. perror("listen() failed");
  148. exit(-1);
  149. }
  150. printf("Ready for client connect().\n");
  151. for (;;) {
  152. int session_fd = accept(server_fd, NULL, NULL);
  153. if (session_fd < 0) {
  154. perror("accept() failed");
  155. exit(-1);
  156. }
  157. pid_t pid = fork();
  158. if (pid == -1) {
  159. perror("Failed to spawn child console process");
  160. exit(-1);
  161. } else if (pid == 0) {
  162. close(server_fd);
  163. handle_session(session_fd);
  164. _exit(0);
  165. } else {
  166. close(session_fd);
  167. }
  168. }
  169. }
  170. void *
  171. console_recv_send(void *arg)
  172. {
  173. char *uargv = NULL;
  174. opensocket();
  175. wait_session(serverfd);
  176. return uargv;
  177. }