123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /* Header files required for the console bindings
- * not included outside of this file. */
-
-
- #include <utmp.h>
- #include <stdio.h>
- #include <sys/un.h>
- #include <unistd.h>
-
- #include "console.h"
- #include "netsukuku.h"
-
-
- /* Variable and structure defintions, serverfd refers to socket file descriptor
- * length refers to the required length of the requests that will be sent.
- * recv won't wake up until length is received.
- * rc is used for error checking in socket operations.
- * serveraddr is a structure describing the address of
- * an AF_LOCAL (aka AF_UNIX) socket. */
-
- int serverfd = -1;
- struct sockaddr_un serveraddr;
- int rc, length;
-
- /* Cleans up the console bindings for closing, Closes socket file descriptors,
- * unlinks the server path, etc. */
-
- static void
- clean_up(void)
- {
- const int optVal = 1;
- const socklen_t optLen = sizeof(optVal);
-
- setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (void *) &optVal,
- optLen);
-
- if (serverfd != -1)
- close(serverfd);
-
- unlink(CONSOLE_SOCKET_PATH);
-
- }
-
- /* Creates an AF_UNIX socket and binds it to a local address. */
-
- static void
- opensocket(void)
- {
- int stop_trying;
-
- serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (serverfd < 0) {
- perror("socket creation failed");
- exit(-1);
- }
-
- memset(&serveraddr, 0, sizeof(serveraddr));
- serveraddr.sun_family = AF_UNIX;
- strcpy(serveraddr.sun_path, CONSOLE_SOCKET_PATH);
-
- rc = bind(serverfd, (struct sockaddr *) &serveraddr,
- SUN_LEN(&serveraddr));
- if (rc < 0) {
- perror("bind() failed");
- clean_up();
- if (stop_trying >= 2) {
- perror("bind() failed");
- clean_up();
- opensocket();
- exit(-1);
- }
- stop_trying++;
- opensocket();
- }
- }
-
-
- /* Sends a parsed response to the ntk console client. */
-
- static void
- send_response(int session_fd, char response[CONSOLE_BUFFER_LENGTH], ...)
- {
- int response_length = (int) strlen(response);
- rc = send(session_fd, response, response_length, 0);
- if (rc < 0) {
- perror("send() failed");
- exit(-1);
- }
- }
-
-
- /* Parses the received request from the ntk console client
- * to data from ntkd structures such as: me
- * into a response for the ntk console client. */
-
- static void
- request_processing(int session_fd, cmd_packet_t packet)
- {
- char buffer[CONSOLE_BUFFER_LENGTH];
- int maxBuffer = CONSOLE_BUFFER_LENGTH - 1;
-
- memset(buffer, 0, sizeof(buffer));
-
- switch (packet.command) {
- case COMMAND_UPTIME:
- {
- int uptime = time(0) - me.uptime;
- snprintf(buffer, maxBuffer, "node uptime: %d seconds", uptime);
- break;
- }
- case COMMAND_VERSION:
- snprintf(buffer, maxBuffer, "ntkd version: %s", VERSION_STR);
- break;
- case COMMAND_CURIFS:
- {
- strcat(buffer, "current interfaces: ");
- int i;
- for (i = 0; i < me.cur_ifs_n; i++) {
- strcat(buffer, me.cur_ifs[i].dev_name);
- strcat(buffer, " ");
- }
- break;
- }
- case COMMAND_CURIFSCT:
- snprintf(buffer, maxBuffer, "current interface count: %d",
- me.cur_ifs_n);
- break;
- case COMMAND_INETCONN:
- if (me.inet_connected)
- snprintf(buffer, maxBuffer, "internet connectivity: true");
- else
- snprintf(buffer, maxBuffer, "internet connectivity: false");
- break;
- case COMMAND_CURQSPNID:
- //send_response(session_fd, (char)me.cur_qspn_id);
- break;
- case COMMAND_CURIP:
- snprintf(buffer, maxBuffer, "IP: %s", inet_to_str(me.cur_ip));
- break;
- case COMMAND_CURNODE:
- //send_response(session_fd, (char)me.cur_node);
- break;
- case COMMAND_IFS:
- //send_response(session_fd, "IFS: TODO");
- break;
- case COMMAND_IFSCT:
- //send_response(session_fd, "IFS: TODO");
- break;
- default:
- snprintf(buffer, maxBuffer,
- "Provided command is invalid or not implemented in this API");
- break;
- }
- send_response(session_fd, buffer);
- }
-
-
-
- static void
- handle_session(int session_fd)
- {
- cmd_packet_t packetIn;
-
- rc = recv(session_fd, &packetIn, sizeof(packetIn), 0);
-
- if (rc < sizeof(packetIn)) {
- perror("recv() failed");
- exit(-1);
- }
-
- request_processing(session_fd, packetIn);
- }
-
-
- static void
- wait_session(int server_fd)
- {
- rc = listen(serverfd, 10);
- if (rc < 0) {
- perror("listen() failed");
- exit(-1);
- }
-
- printf("Ready for client connect().\n");
-
- for (;;) {
- int session_fd = accept(server_fd, NULL, NULL);
- if (session_fd < 0) {
- perror("accept() failed");
- exit(-1);
- }
-
- pid_t pid = fork();
- if (pid == -1) {
- perror("Failed to spawn child console process");
- exit(-1);
- } else if (pid == 0) {
- close(server_fd);
- handle_session(session_fd);
- _exit(0);
- } else {
- close(session_fd);
- }
-
- }
- }
-
-
- void *
- console_recv_send(void *arg)
- {
- char *uargv = NULL;
-
- opensocket();
- wait_session(serverfd);
-
- return uargv;
- }
|