Implement http2telnet gateway
authorHenning Rogge <hrogge@googlemail.com>
Wed, 16 Sep 2009 16:25:07 +0000 (18:25 +0200)
committerHenning Rogge <hrogge@googlemail.com>
Wed, 16 Sep 2009 16:25:07 +0000 (18:25 +0200)
lib/debuginfo/src/olsrd_debuginfo.c
lib/txtinfo/src/olsrd_txtinfo.c
src/olsr_comport.c
src/olsr_comport_http.c
src/olsr_comport_http.h
src/olsr_comport_txt.c
src/olsr_comport_txt.h

index 980d258..4d369f1 100644 (file)
@@ -75,9 +75,12 @@ struct debuginfo_cmd {
 static void debuginfo_new(void) __attribute__ ((constructor));
 static void debuginfo_delete(void) __attribute__ ((destructor));
 
-static enum olsr_txtcommand_result debuginfo_msgstat(struct comport_connection *con,  char *cmd, char *param);
-static enum olsr_txtcommand_result debuginfo_pktstat(struct comport_connection *con,  char *cmd, char *param);
-static enum olsr_txtcommand_result debuginfo_cookies(struct comport_connection *con,  char *cmd, char *param);
+static enum olsr_txtcommand_result debuginfo_msgstat(struct comport_connection *con,
+    const char *cmd, const char *param);
+static enum olsr_txtcommand_result debuginfo_pktstat(struct comport_connection *con,
+    const char *cmd, const char *param);
+static enum olsr_txtcommand_result debuginfo_cookies(struct comport_connection *con,
+    const char *cmd, const char *param);
 
 static void update_statistics_ptr(void *);
 static void olsr_msg_statistics(union olsr_message *, struct interface *, union olsr_ip_addr *, enum duplicate_status);
@@ -406,7 +409,8 @@ static bool debuginfo_print_msgstat(struct autobuf *buf, union olsr_ip_addr *ip,
 }
 
 static enum olsr_txtcommand_result
-debuginfo_msgstat(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused)))
+debuginfo_msgstat(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
 {
   struct debug_msgtraffic *tr;
 
@@ -478,7 +482,8 @@ static bool debuginfo_print_pktstat(struct autobuf *buf, union olsr_ip_addr *ip,
 }
 
 static enum olsr_txtcommand_result
-debuginfo_pktstat(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused)))
+debuginfo_pktstat(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
 {
   struct debug_pkttraffic *tr;
 
@@ -572,7 +577,8 @@ static INLINE bool debuginfo_print_cookies_timer(struct autobuf *buf, const char
 }
 
 static enum olsr_txtcommand_result
-debuginfo_cookies(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused)))
+debuginfo_cookies(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
 {
   if (abuf_puts(&con->out, "Memory cookies:\n") < 0) {
     return ABUF_ERROR;
index eec02b0..7c6f762 100644 (file)
@@ -54,6 +54,7 @@
 #include "olsr_ip_prefix_list.h"
 #include "parser.h"
 #include "olsr_comport_txt.h"
+#include "olsr_comport_http.h"
 #include "common/string.h"
 #include "common/autobuf.h"
 #include "plugin_loader.h"
@@ -73,12 +74,18 @@ static bool txtinfo_pre_init(void);
 static bool txtinfo_post_init(void);
 static bool txtinfo_pre_cleanup(void);
 
-static enum olsr_txtcommand_result txtinfo_neigh(struct comport_connection *con, char *cmd, char *param);
-static enum olsr_txtcommand_result txtinfo_link(struct comport_connection *con,  char *cmd, char *param);
-static enum olsr_txtcommand_result txtinfo_routes(struct comport_connection *con,  char *cmd, char *param);
-static enum olsr_txtcommand_result txtinfo_topology(struct comport_connection *con,  char *cmd, char *param);
-static enum olsr_txtcommand_result txtinfo_hna(struct comport_connection *con,  char *cmd, char *param);
-static enum olsr_txtcommand_result txtinfo_mid(struct comport_connection *con,  char *cmd, char *param);
+static enum olsr_txtcommand_result txtinfo_neigh(struct comport_connection *con,
+    const char *cmd, const char *param);
+static enum olsr_txtcommand_result txtinfo_link(struct comport_connection *con,
+    const char *cmd, const char *param);
+static enum olsr_txtcommand_result txtinfo_routes(struct comport_connection *con,
+    const char *cmd, const char *param);
+static enum olsr_txtcommand_result txtinfo_topology(struct comport_connection *con,
+    const char *cmd, const char *param);
+static enum olsr_txtcommand_result txtinfo_hna(struct comport_connection *con,
+    const char *cmd, const char *param);
+static enum olsr_txtcommand_result txtinfo_mid(struct comport_connection *con,
+    const char *cmd, const char *param);
 
 /* plugin configuration */
 static struct ip_acl allowed_nets;
@@ -110,6 +117,9 @@ static struct txtinfo_cmd commands[] = {
     {"routes", &txtinfo_routes, NULL},
 };
 
+/* base path for http access (should end with a '/') */
+static const char TXTINFO_HTTP_PATH[] = "/txtinfo/";
+
 /* constants and static storage for template engine */
 static const char KEY_LOCALIP[] = "localip";
 static const char KEY_NEIGHIP[] = "neighip";
@@ -292,17 +302,15 @@ txtinfo_post_init(void)
  * @param template
  */
 static char *
-parse_user_template(char *template) {
-  char *src = template;
-  char *dst = template;
-  bool changed = false;
-
-  while (*src) {
-    if (*src == '\\') {
-      changed = true;
-
-      src++;
-      switch (*src) {
+parse_user_template(const char *template) {
+  // TODO: dynamic buffer ?
+  static char buffer[1024];
+  char *dst = buffer;
+
+  while (*template && dst < &buffer[1023]) {
+    if (*template == '\\') {
+      template++;
+      switch (*template) {
         case 0:
           *dst = 0;
           break;
@@ -317,25 +325,26 @@ parse_user_template(char *template) {
           break;
         default:
           *dst++ = '\\';
-          *dst = *src;
+          *dst = *template;
           break;
       }
     }
-    else if (changed) {
-      *dst = *src;
+    else {
+      *dst = *template;
     }
-    src++;
+    template++;
     dst++;
   }
   *dst = 0;
-  return template;
+  return dst;
 }
 
 /**
  * Callback for neigh command
  */
 static enum olsr_txtcommand_result
-txtinfo_neigh(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param)
+txtinfo_neigh(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param)
 {
   struct nbr_entry *neigh;
   const char *template;
@@ -369,22 +378,12 @@ txtinfo_neigh(struct comport_connection *con,  char *cmd __attribute__ ((unused)
   return CONTINUE;
 }
 
-#if 0
-static char tmpl_link[256], link_template_csv[256];
-static const char *keys_link[4+16] = {
-  "localip",
-  "neighip",
-  "rawlinkcost",
-  "linkcost",
-  NULL
-};
-static size_t link_keys_static = 0, link_keys_count = 0;
-#endif
 /**
  * Callback for link command
  */
 static enum olsr_txtcommand_result
-txtinfo_link(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param)
+txtinfo_link(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param)
 {
   struct link_entry *lnk;
   size_t i;
@@ -429,7 +428,8 @@ txtinfo_link(struct comport_connection *con,  char *cmd __attribute__ ((unused))
  * Callback for routes command
  */
 static enum olsr_txtcommand_result
-txtinfo_routes(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused)))
+txtinfo_routes(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
 {
   struct rt_entry *rt;
   const char *template;
@@ -470,7 +470,8 @@ txtinfo_routes(struct comport_connection *con,  char *cmd __attribute__ ((unused
  * Callback for topology command
  */
 static enum olsr_txtcommand_result
-txtinfo_topology(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused)))
+txtinfo_topology(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
 {
   struct tc_entry *tc;
   const char *template;
@@ -529,7 +530,8 @@ txtinfo_topology(struct comport_connection *con,  char *cmd __attribute__ ((unus
  * Callback for hna command
  */
 static enum olsr_txtcommand_result
-txtinfo_hna(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused)))
+txtinfo_hna(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
 {
   const struct ip_prefix_entry *hna;
   struct tc_entry *tc;
@@ -588,7 +590,8 @@ txtinfo_hna(struct comport_connection *con,  char *cmd __attribute__ ((unused)),
  * Callback for mid command
  */
 static enum olsr_txtcommand_result
-txtinfo_mid(struct comport_connection *con,  char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused)))
+txtinfo_mid(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
 {
   struct tc_entry *tc;
   struct interface *interface;
index 563eedb..4d95275 100644 (file)
@@ -479,6 +479,8 @@ static void olsr_com_parse_http(struct comport_connection *con,
 
   /* we have everything to process the http request */
   con->state = SEND_AND_QUIT;
+  olsr_com_decode_url(filename);
+
   if (strcmp(req_type, "GET") == 0) {
     /* HTTP-GET request */
     para = strchr(filename, '?');
@@ -501,7 +503,6 @@ static void olsr_com_parse_http(struct comport_connection *con,
 
     /* we have null terminated key at *para. Now decode the key */
     para_keyvalue[para_count++] = para;
-    olsr_com_decode_url(para);
 
     /* split the string at the next '&' (the splitter of multiple key/value pairs */
     para = strchr(str, '&');
@@ -510,7 +511,6 @@ static void olsr_com_parse_http(struct comport_connection *con,
     }
 
     /* we have a null terminated value at *str, Now decode it */
-    olsr_com_decode_url(str);
     para_keyvalue[para_count++] = str;
   }
 
@@ -532,9 +532,14 @@ static void olsr_com_parse_http(struct comport_connection *con,
     }
 
     /* try to find a handler for a path prefix */
-    do {
+    if (i > 0 && filename[i] == '/') {
       filename[i--] = 0;
-    } while (i > 0 && filename[i] != '/');
+    }
+    else {
+      do {
+        filename[i--] = 0;
+      } while (i > 0 && filename[i] != '/');
+    }
   }
   con->send_as = HTTP_404_NOT_FOUND;
 }
index 29deb8d..0277f19 100644 (file)
 #include "olsr_cookie.h"
 #include "olsr_comport.h"
 #include "olsr_comport_http.h"
+#include "olsr_comport_txt.h"
 #include "olsr_cfg.h"
+#include "ipcalc.h"
 
-#define HTTP_VERSION "HTTP/1.1"
+static const char HTTP_VERSION[] = "HTTP/1.1";
+static const char TELNET_PATH[] = "/telnet/";
 
 static struct olsr_cookie_info *htmlsite_cookie;
 struct avl_tree http_handler_tree;
@@ -64,6 +67,7 @@ static char http_501_response[] = "Not Implemented";
 static char http_503_response[] = "Service Unavailable";
 
 /* sample for a static html page */
+#if 0
 static void init_test(void) {
   static char content[] = "<html><body>Yes, you got it !</body></html>";
   static char path[] = "/";
@@ -74,6 +78,26 @@ static void init_test(void) {
   site = olsr_com_add_htmlsite(path, content, strlen(content));
   olsr_com_set_htmlsite_acl_auth(site, NULL, 1, aclPtr);
 }
+#endif
+
+static void
+olsr_com_html2telnet_gate(struct comport_connection *con, char *path, int pCount, char *p[]) {
+  if (strlen(path) > strlen(TELNET_PATH)) {
+    char *cmd = &path[strlen(TELNET_PATH)];
+    char *next;
+    int count = 0;
+
+    while (cmd) {
+      next = strchr(cmd, '/');
+      if (next) {
+        *next++ = 0;
+      }
+
+      olsr_com_handle_txtcommand(con, cmd, pCount > count ? p[count] : NULL);
+      cmd = next;
+    }
+  }
+}
 
 void
 olsr_com_init_http(void) {
@@ -82,7 +106,9 @@ olsr_com_init_http(void) {
   htmlsite_cookie = olsr_alloc_cookie("comport http sites", OLSR_COOKIE_TYPE_MEMORY);
   olsr_cookie_set_memory_size(htmlsite_cookie, sizeof(struct olsr_html_site));
 
-  init_test();
+  /* activate telnet gateway */
+  olsr_com_add_htmlhandler(olsr_com_html2telnet_gate, "/telnet/");
+  //init_test();
 }
 
 void olsr_com_destroy_http(void) {
@@ -108,8 +134,8 @@ olsr_com_add_htmlsite(char *path, char *content, size_t length) {
 }
 
 struct olsr_html_site *
-olsr_com_add_htmlhandler(void(*sitehandler)(struct autobuf *buf, char *path, int parameter_count, char *parameters[]),
-    char *path) {
+olsr_com_add_htmlhandler(void(*sitehandler)(struct comport_connection *con, char *path, int parameter_count, char *parameters[]),
+    const char *path) {
   struct olsr_html_site *site;
 
   site = olsr_cookie_malloc(htmlsite_cookie);
@@ -148,6 +174,7 @@ olsr_com_handle_htmlsite(struct comport_connection *con, char *path,
 
   site = (struct olsr_html_site *)avl_find(&http_handler_tree, path);
   if (site == NULL) {
+    OLSR_DEBUG(LOG_COMPORT, "No httphandler found for path %s\n", path);
     return false;
   }
 
@@ -169,13 +196,18 @@ olsr_com_handle_htmlsite(struct comport_connection *con, char *path,
       }
     }
     if (con->send_as == HTTP_401_UNAUTHORIZED) {
+      OLSR_DEBUG(LOG_COMPORT, "Error, invalid authorization\n");
       return true;
     }
   }
 
   /* check if ip is allowed */
   if (site->acl != NULL && !ip_acl_acceptable(site->acl, &con->addr, olsr_cnf->ip_version)) {
+    struct ipaddr_str buf;
+
     con->send_as = HTTP_403_FORBIDDEN;
+    OLSR_DEBUG(LOG_COMPORT, "Error, access by IP %s is not allowed for path %s\n",
+        path, olsr_ip_to_string(&buf, &con->addr));
     return true;
   }
 
@@ -183,7 +215,7 @@ olsr_com_handle_htmlsite(struct comport_connection *con, char *path,
   if (site->static_site) {
     abuf_memcpy(&con->out, site->site_data, site->site_length);
   } else {
-    site->sitehandler(&con->out, fullpath, para_count, para);
+    site->sitehandler(con, fullpath, para_count, para);
   }
   con->send_as = HTTP_200_OK;
   return true;
index e903f67..8b4e4a2 100644 (file)
@@ -63,7 +63,7 @@ struct olsr_html_site {
   size_t site_length;
 
        /* for non static, this is the handler */
-  void (*sitehandler)(struct autobuf *buf, char *path, int parameter_count, char *parameters[]);
+  void (*sitehandler)(struct comport_connection *con, char *path, int parameter_count, char *parameters[]);
 };
 
 AVLNODE2STRUCT(html_tree2site, olsr_html_site, node);
@@ -76,8 +76,8 @@ void olsr_com_destroy_http(void);
 struct olsr_html_site *EXPORT(olsr_com_add_htmlsite) (
     char *path, char *content, size_t length);
 struct olsr_html_site *EXPORT(olsr_com_add_htmlhandler) (
-    void (*sitehandler)(struct autobuf *buf, char *path, int parameter_count, char *parameters[]),
-    char *path);
+    void (*sitehandler)(struct comport_connection *con, char *path, int parameter_count, char *parameters[]),
+    const char *path);
 void EXPORT(olsr_com_remove_htmlsite) (struct olsr_html_site *site);
 void EXPORT(olsr_com_set_htmlsite_acl_auth) (struct olsr_html_site *site,
     struct ip_acl *acl, int auth_count, char **auth_entries);
index e1e75b5..6dcc858 100644 (file)
@@ -62,21 +62,21 @@ static struct avl_tree txt_normal_tree, txt_help_tree;
 static struct olsr_cookie_info *txtcommand_cookie, *txt_repeattimer_cookie;
 
 static enum olsr_txtcommand_result olsr_txtcmd_quit(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 static enum olsr_txtcommand_result olsr_txtcmd_help(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 static enum olsr_txtcommand_result olsr_txtcmd_echo(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 static enum olsr_txtcommand_result olsr_txtcmd_repeat(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 static enum olsr_txtcommand_result olsr_txtcmd_timeout(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 static enum olsr_txtcommand_result olsr_txtcmd_version(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 static enum olsr_txtcommand_result olsr_txtcmd_plugin(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 static enum olsr_txtcommand_result olsr_txtcmd_displayhelp(
-    struct comport_connection *con, char *cmd, char *param);
+    struct comport_connection *con, const char *cmd, const char *param);
 
 
 static const char *txt_internal_names[] = {
@@ -201,13 +201,13 @@ olsr_com_handle_txtcommand(struct comport_connection *con, char *cmd, char *para
 
 static enum olsr_txtcommand_result
 olsr_txtcmd_quit(struct comport_connection *con __attribute__ ((unused)),
-    char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused))) {
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused))) {
   return QUIT;
 }
 
 static enum olsr_txtcommand_result
 olsr_txtcmd_displayhelp(struct comport_connection *con,
-    char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused))) {
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused))) {
   size_t i;
 
   for (i=0; i<ARRAYSIZE(txt_internal_names); i++) {
@@ -221,7 +221,7 @@ olsr_txtcmd_displayhelp(struct comport_connection *con,
 
 static enum olsr_txtcommand_result
 olsr_txtcmd_help(struct comport_connection *con,
-    char *cmd __attribute__ ((unused)), char *param) {
+    const char *cmd __attribute__ ((unused)), const char *param) {
   struct olsr_txtcommand *ptr;
 
   if (param != NULL) {
@@ -252,7 +252,7 @@ olsr_txtcmd_help(struct comport_connection *con,
 
 static enum olsr_txtcommand_result
 olsr_txtcmd_echo(struct comport_connection *con,
-    char *cmd __attribute__ ((unused)), char *param) {
+    const char *cmd __attribute__ ((unused)), const char *param) {
   if (strcasecmp(param, "on") == 0) {
     con->show_echo = true;
   }
@@ -269,7 +269,7 @@ olsr_txtcmd_echo(struct comport_connection *con,
 
 static enum olsr_txtcommand_result
 olsr_txtcmd_timeout(struct comport_connection *con,
-    char *cmd __attribute__ ((unused)), char *param) {
+    const char *cmd __attribute__ ((unused)), const char *param) {
   con->timeout_value = (uint32_t)strtoul(param, NULL, 10);
   return CONTINUE;
 }
@@ -294,7 +294,8 @@ static void olsr_txt_repeat_timer(void *data) {
 }
 
 static enum olsr_txtcommand_result
-olsr_txtcmd_repeat(struct comport_connection *con, char *cmd __attribute__ ((unused)), char *param) {
+olsr_txtcmd_repeat(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param) {
   int interval = 0;
   char *ptr;
   struct timer_entry *timer;
@@ -335,14 +336,15 @@ olsr_txtcmd_repeat(struct comport_connection *con, char *cmd __attribute__ ((unu
 }
 
 static enum olsr_txtcommand_result
-olsr_txtcmd_version(struct comport_connection *con, char *cmd __attribute__ ((unused)), char *param __attribute__ ((unused))) {
+olsr_txtcmd_version(struct comport_connection *con,
+    const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused))) {
   abuf_appendf(&con->out, " *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n",
       olsrd_version, build_date, build_host);
   return CONTINUE;
 }
 
 static enum olsr_txtcommand_result
-olsr_txtcmd_plugin(struct comport_connection *con, char *cmd, char *param) {
+olsr_txtcmd_plugin(struct comport_connection *con, const char *cmd, const char *param) {
   struct olsr_plugin *plugin;
   char *para2 = NULL;
   if (param == NULL || strcasecmp(param, "list") == 0) {
index 1953e98..116945c 100644 (file)
@@ -56,7 +56,7 @@ enum olsr_txtcommand_result {
 };
 
 typedef enum olsr_txtcommand_result (*olsr_txthandler)
-    (struct comport_connection *con, char *command, char *parameter);
+    (struct comport_connection *con, const char *command, const char *parameter);
 
 struct olsr_txtcommand {
   struct avl_node node;