Commit 09af4b21 authored by Yann Garcia's avatar Yann Garcia
Browse files

Enhance web server

parent 411a1939
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ include $(INCLUDE_DIR)/package.mk
define Package/its_bridge
  SECTION:=utils
  CATEGORY:=Utilities
  TITLE:=ITS bridge clents and server
  TITLE:=ITS bridge clients and server
  DEPENDS:=+libpcap +libmicrohttpd
endef

+4 −4
Original line number Diff line number Diff line
# server.conf sample
daemon_mode=0
mac_address=90fd61e61902
its_nic=en0
mac_address=f8cab8083918
its_nic=eno1

udp_nic=en1
udp_address=239.0.101.101
udp_nic=wlp2s0
udp_address=239.0.102.102;239.0.104.104;239.0.112.112;239.0.114.114
udp_protocol=multicast
udp_port=5000
+1 −1
Original line number Diff line number Diff line
@@ -6,4 +6,4 @@ password=password
https_port=8888
cert_pem=../certs/server.pem
cert_key=../certs/server.key
conf_path=../etc
conf_path=../etc/its_bridge
+17 −13
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ struct ip_mreq** mreq = NULL;

void sig_handler(int p_signal) {
  printf(">>> sig_handler: signal=%d.\n", p_signal);
  state = _exiting;
  running = false;
  shutdown(socket_hd, SHUT_RDWR);
  close(socket_hd);
@@ -172,15 +173,11 @@ int main(const int32_t p_argc, char* const p_argv[]) {
        }
        printf("Interface address for %s: %s\n", ifr.ifr_name, inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr));
        /* Join the multicast group */
        mreq = (struct ip_mreq*)malloc(num_addresses * sizeof(struct ip_mreq*));
        fprintf(stderr, "0000\n");
        mreq = (struct ip_mreq**)malloc(num_addresses * sizeof(struct ip_mreq*));
        memset((void*)mreq, 0x00, num_addresses * sizeof(struct ip_mreq*));
        fprintf(stderr, "1111\n");
        for (size_t i = 0; i < num_addresses; i++) {
          fprintf(stderr, "2222\n");
          struct ip_mreq* mr = (struct ip_mreq*)malloc(sizeof(struct ip_mreq));
          *(mreq + i) = mr;
          fprintf(stderr, "3333\n");
          mr->imr_interface.s_addr = inet_addr(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr)); /* Local address */
          mr->imr_multiaddr.s_addr = inet_addr(*(udp_addresses + i)); /* IP multicast address of group */
          printf("mreq.imr_interface.s_addr = %s.\n", inet_ntoa(mr->imr_interface));
@@ -221,7 +218,7 @@ int main(const int32_t p_argc, char* const p_argv[]) {
    while (running == true) {
      result = recvfrom(socket_hd, buffer, MAX_BUFFER_SIZE, 0, (struct sockaddr*)&addr, &addr_len);
      if (result < 0) {
        fprintf(stderr, "'recvfrom' operation failure: %s, stay in loop.\n", strerror(errno));
        fprintf(stderr, "'recvfrom' operation failure: %s, state=%d.\n", strerror(errno), state);
        continue;
      }
      printf("Received UDP broadcast:%s:%u.\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
@@ -238,7 +235,7 @@ int main(const int32_t p_argc, char* const p_argv[]) {
    if (socket_hd != -1) {
      if (strcmp(udp_protocol, "multicast") == 0) {
        /* Leave the multicast group */
        for (size_t i = 0; *(udp_addresses + i); i++) {
        for (size_t i = 0; i < num_addresses; i++) {
          struct ip_mreq* mr = *(mreq + i);
          if (setsockopt(socket_hd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)mr, sizeof(struct ip_mreq)) < 0) {
            fprintf(stderr, "Failed to set option IP_DROP_MEMBERSHIP: %s.\n", strerror(errno));
@@ -279,14 +276,21 @@ int main(const int32_t p_argc, char* const p_argv[]) {
  return 0;

 error:
  for (size_t i = 0; *(udp_addresses + i); i++) {
  if (udp_addresses != NULL) {
    for (size_t i = 0; i < num_addresses; i++) {
      free(*(udp_addresses + i));
      if (mreq != NULL) {
        if (*(mreq + i) != NULL) {
          free(*(mreq + i));
        }
      }
    }
    free(udp_addresses);
    if (mreq != NULL) {
      free(mreq);
    }
  }

  unlink(PID_FILE_NAME);
  unlink(LOCK_FILE_NAME);
  return -1;
+101 −26
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ static char* buffer = NULL; /* Shall be static because of asynchronous mode */
#define MAX_PATH_SIZE   256
static char client_config_file[MAX_PATH_SIZE];
static char server_config_file[MAX_PATH_SIZE];
static char web_config_file[MAX_PATH_SIZE];

#define PID_FILE_NAME   "/var/run/its_web_server_config.pid"
#define LOCK_FILE_NAME  "/var/run/its_web_server_config.lock"
@@ -101,13 +102,14 @@ static int32_t send_favicon(struct MHD_Connection *p_connection) {

static int32_t web_client_page(struct MHD_Connection *p_connection) {
  const char* page =
    "<!DOCTYPE html><html><body><h2>ITS Bridge Web Confgurator</h2><p>Please enter ETSI ITS_Bridge_client configuration:</p>"
    "<!DOCTYPE html><html><body><h2>ITS Bridge Web Confgurator</h2><p>Please enter ETSI its_bridge_client configuration:</p>"
    "<form action=\"/client_url\" method=\"POST\">"
    "<label for=\"its_nic\">NIC ITS:</label><br>"
    "<label for=\"its_nic\">NIC on ITS device side:</label><br>"
    "<input type=\"text\" id=\"its_nic\" name=\"its_nic\" value=\"%s\"><br>"
    "<label for=\"mac_address\">Source MAC address of ITS messages:</label><br>"
    "<input type=\"text\" id=\"mac_address\" name=\"mac_address\" value=\"%s\"><br>"
    "<label for=\"udp_nic\">NIC multicast:</label><br>"
    "<p>"
    "<label for=\"udp_nic\">NIC on network side:</label><br>"
    "<input type=\"text\" id=\"udp_nic\" name=\"udp_nic\" value=\"%s\"><br>"
    "<label for=\"udp_address\">Multicast Address:</label><br>"
    "<input type=\"text\" id=\"udp_address\" name=\"udp_address\" value=\"%s\"><br>"
@@ -119,12 +121,12 @@ static int32_t web_client_page(struct MHD_Connection *p_connection) {
  /* Load ITS_Bridge_client configuration file */
  free_config_file_resources();
  sprintf(client_config_file, "%s/client.conf", conf_path);
  printf("Parsing file %s.\n", client_config_file);
  printf("web_client_page: Parsing file %s.\n", client_config_file);
  if (parse_config_file(client_config_file) == -1) {
    fprintf(stderr, "Failed to parse configuration file %s, exit.\n", config_file);
    return MHD_NO;
  }
  printf("its_nic:%s/%s, IP:%s:%d.\n", its_nic, mac_address, udp_address, udp_port);
  printf("web_client_page: its_nic:%s/%s, IP:%s:%d.\n", its_nic, mac_address, udp_address, udp_port);
  /* Prepare the HTML page to sent to the browser */
  if (buffer != NULL) {
    free(buffer);
@@ -147,17 +149,18 @@ static int32_t web_client_page(struct MHD_Connection *p_connection) {

static int32_t web_server_page(struct MHD_Connection *p_connection) {
  const char* page =
    "<!DOCTYPE html><html><body><h2>ITS Bridge Web Confgurator</h2><p>Please enter ETSI ITS_Bridge_server configuration:</p>"
    "<!DOCTYPE html><html><body><h2>ITS Bridge Web Confgurator</h2><p>Please enter ETSI its_bridge_server configuration:</p>"
    "<form action=\"/server_url\" method=\"POST\">"
    "<label for=\"its_nic\">NIC ITS:</label><br>"
    "<label for=\"its_nic\">NIC on ITS device side:</label><br>"
    "<input type=\"text\" id=\"its_nic\" name=\"its_nic\" value=\"%s\"><br>"
    "<label for=\"mac_address\">Mac Address for injection filtering:</label><br>"
    "<input type=\"text\" id=\"mac_address\" name=\"mac_address\" value=\"%s\"><br>"
    "<label for=\"udp_nic\">NIC multicast:</label><br>"
    "<p>"
    "<label for=\"udp_nic\">NIC on network side:</label><br>"
    "<input type=\"text\" id=\"udp_nic\" name=\"udp_nic\" value=\"%s\"><br>"
    "<label for=\"udp_address\">Multicast Addresses (Enter multicast address of the other vendors of your session separarated by a semi-colon):</label><br>"
    "<input type=\"text\" id=\"udp_address\" name=\"udp_address\" value=\"%s\" size=\"100\"><br>"
    "<label for=\"https_port\">Multicqst Port:</label><br>"
    "<label for=\"https_port\">Multicast Port:</label><br>"
    "<input type=\"number\" id=\"udp_port\" name=\"udp_port\" value=\"%d\"><br><br>"
    "<input type=\"submit\" value=\"Submit\">"
    "<input type=\"reset\">"
@@ -165,12 +168,12 @@ static int32_t web_server_page(struct MHD_Connection *p_connection) {
  /* Load ITS_Bridge_server configuration file */
  free_config_file_resources();
  sprintf(server_config_file, "%s/server.conf", conf_path);
  printf("Parsing file %s.\n", server_config_file);
  printf("web_server_page: Parsing file %s.\n", server_config_file);
  if (parse_config_file(server_config_file) == -1) {
    fprintf(stderr, "Failed to parse configuration file %s, exit.\n", config_file);
    return MHD_NO;
  }
  printf("its_nic:%s/%s, IP:%s:%d.\n", its_nic, mac_address, udp_address, udp_port);
  printf("web_server_page: its_nic:%s/%s, IP:%s:%d.\n", its_nic, mac_address, udp_address, udp_port);
  /* Prepare the HTML page to sent to the browser */
  if (buffer != NULL) {
    free(buffer);
@@ -213,7 +216,7 @@ static int32_t web_config_page(struct MHD_Connection *p_connection) {
  printf(">>> web_config_page.\n");

  const char* page =
    "<!DOCTYPE html><html><body><h2>ITS Bridge Web Confgurator</h2><p>Please enter ETSI ITS_Bridge webserver configuration:</p>"
    "<!DOCTYPE html><html><body><h2>ITS Bridge Web Confgurator</h2><p>Please enter ETSI ITS-Bridge webserver configuration:</p>"
    "<form action=\"/web_config\" method=\"POST\">"
    "<label for=\"realm\">Realm:</label><br>"
    "<input type=\"text\" id=\"realm\" name=\"realm\" value=\"%s\"><br>"
@@ -226,7 +229,16 @@ static int32_t web_config_page(struct MHD_Connection *p_connection) {
    "<input type=\"submit\" value=\"Submit\">"
    "<input type=\"reset\">"
    "</form></body></html>";

  /* Load ITS_Bridge_server configuration file */
  free_config_file_resources();
  sprintf(web_config_file, "%s/webserver.conf", conf_path);
  printf("web_config_page: Parsing file %s.\n", web_config_file);
  if (parse_config_file(web_config_file) == -1) {
    fprintf(stderr, "Failed to parse configuration file %s, exit.\n", config_file);
    return MHD_NO;
  }
  printf("web_config_page: save_configuration_file: realm:%s,login:%s,password:%s,port:%d.\n", realm, login, password, https_port);
  /* Prepare the HTML page to sent to the browser */
  if (buffer != NULL) {
    free(buffer);
  }
@@ -348,7 +360,49 @@ static int32_t post_iterator(void *coninfo_cls, enum MHD_ValueKind kind, const c
      udp_port = atoi(data);
    }
  } else if (strcmp(con_info->url, "/server_url") == 0) {
  } else {
    if (strcmp(key, "its_nic") == 0) {
      if (its_nic != NULL) {
        free(its_nic);
      }
      its_nic = strdup(data);
    } else if (strcmp(key, "mac_address") == 0) {
      if (mac_address != NULL) {
        free(mac_address);
      }
      mac_address = strdup(data);
    } else if (strcmp(key, "udp_address") == 0) {
      if (udp_address != NULL) {
        free(udp_address);
      }
      udp_address = strdup(data);
      /* Remove ';' at the end if any */
      printf("post_iterator: udp_address=%s.\n", udp_address);
      if (*(udp_address + strlen(udp_address) - 1) == ';') {
        *(udp_address + strlen(udp_address) - 1) = '\x00';
      }
      printf("post_iterator: after check, udp_address=%s.\n", udp_address);
    } else if (strcmp(key, "udp_port") == 0) {
      udp_port = atoi(data);
    }
  } else if (strcmp(con_info->url, "/web_config") == 0) {
    if (strcmp(key, "realm") == 0) {
      if (realm != NULL) {
        free(realm);
      }
      realm = strdup(data);
    } else if (strcmp(key, "login") == 0) {
      if (login != NULL) {
        free(login);
      }
      login = strdup(data);
    } else if (strcmp(key, "pwd") == 0) {
      if (password != NULL) {
        free(password);
      }
      password = strdup(data);
    } else if (strcmp(key, "port") == 0) {
      https_port = atoi(data);
    }
  }

  return MHD_YES;
@@ -455,8 +509,8 @@ static void request_completed(void *cls, struct MHD_Connection *connection,
    MHD_destroy_post_processor(con_info->postprocessor);
    if (strcmp(con_info->url, "/client_url") == 0) {
      printf("request_completed: Update client.conf.\n");
      /* Create a new one */
      //save_configuration_file(client_config_file, "client", daemon_mode, 0, "mac_address", mac_address, "its_nic", its_nic, "udp_nic", udp_nic, "udp_address", udp_address, "udp_protocol", "multicast", "udp_port", udp_port, -1);
      /* Create a function */
      //save_configuration_file(client_config_file, "client", daemon_mode, 1, "mac_address", mac_address, "its_nic", its_nic, "udp_nic", udp_nic, "udp_address", udp_address, "udp_protocol", "multicast", "udp_port", udp_port, -1);
      {
        printf("save_configuration_file: its_nic:%s/%s, IP:%s:%s:%d.\n", its_nic, mac_address, udp_nic, udp_address, udp_port);
        FILE* fp = fopen(client_config_file, "w");
@@ -464,7 +518,7 @@ static void request_completed(void *cls, struct MHD_Connection *connection,
          goto end;
        }
        fprintf(fp, "# %s.conf sample\n", "client");
        fprintf(fp, "daemon_mode=%d\n", 0);
        fprintf(fp, "daemon_mode=%d\n", 1);
        fprintf(fp, "mac_address=%s\n", mac_address);
        fprintf(fp, "its_nic=%s\n", its_nic);
        fprintf(fp, "\n");
@@ -485,16 +539,16 @@ static void request_completed(void *cls, struct MHD_Connection *connection,
      }
    } else if (strcmp(con_info->url, "/server_url") == 0) {
      printf("request_completed: Update server.conf.\n");
      /* Create a new one */
      //save_configuration_file(server_config_file, "server", daemon_mode, 0, "mac_address", mac_address, "its_nic", its_nic, "udp_nic", udp_nic, "udp_address", udp_address, "udp_protocol", "multicast", "udp_port", udp_port, -1);
      /* Create a function */
      //save_configuration_file(server_config_file, "server", daemon_mode, 1, "mac_address", mac_address, "its_nic", its_nic, "udp_nic", udp_nic, "udp_address", udp_address, "udp_protocol", "multicast", "udp_port", udp_port, -1);
      {
        printf("save_configuration_file: its_nic:%s/%s, IP:%s:%s:%d.\n", its_nic, mac_address, udp_nic, udp_address, udp_port);
        FILE* fp = fopen(server_config_file, "w");
        if (fp == NULL) {
          goto end;
        }
        fprintf(fp, "# server.conf sample\n");
        fprintf(fp, "daemon_mode=%d\n", 0);
        fprintf(fp, "# %s.conf sample\n", "server");
        fprintf(fp, "daemon_mode=%d\n", 1);
        fprintf(fp, "mac_address=%s\n", mac_address);
        fprintf(fp, "its_nic=%s\n", its_nic);
        fprintf(fp, "\n");
@@ -513,6 +567,27 @@ static void request_completed(void *cls, struct MHD_Connection *connection,
        }
        free(server_pid);
      }
    } else if (strcmp(con_info->url, "/web_config") == 0) {
      printf("request_completed: Update webserver.conf.\n");
      /* Create a function */
      //save_configuration_file(web_config_file, "web_server", daemon_mode, 1, "realm", realm, "login", login, "password", password, "https_port", https_port, "cert_pem", "../certs/server.pem", "cert_key", "../certs/server.key", "conf_path", "../etc/its_bridge", -1);
      {
        printf("save_configuration_file: realm:%s,login:%s,password:%s,port:%d.\n", realm, login, password, https_port);
        FILE* fp = fopen(web_config_file, "w");
        if (fp == NULL) {
          goto end;
        }
        fprintf(fp, "# %s.conf sample\n", "webserver");
        fprintf(fp, "daemon_mode=%d\n", 1);
        fprintf(fp, "realm=%s\n", realm);
        fprintf(fp, "login=%s\n", login);
        fprintf(fp, "password=%s\n", password);
        fprintf(fp, "https_port=%d\n", https_port);
        fprintf(fp, "cert_pem=../certs/server.pem\n");
        fprintf(fp, "cert_key=../certs/server.key\n");
        fprintf(fp, "conf_path=../etc/its_bridge\n");
        fclose(fp);
      }
    }
  }
end:
Loading