luci-app-cshark: initial commit 1025/head
authordanrl <mail@danrl.com>
Fri, 17 Feb 2017 10:08:46 +0000 (11:08 +0100)
committerdanrl <mail@danrl.com>
Fri, 17 Feb 2017 10:08:46 +0000 (11:08 +0100)
Moved over here from the packages repository.

Signed-off-by: Dan Luedtke <mail@danrl.com>
applications/luci-app-cshark/Makefile [new file with mode: 0644]
applications/luci-app-cshark/luasrc/controller/cshark.lua [new file with mode: 0644]
applications/luci-app-cshark/luasrc/model/cbi/admin_network/cshark.lua [new file with mode: 0644]
applications/luci-app-cshark/luasrc/view/cshark.htm [new file with mode: 0644]

diff --git a/applications/luci-app-cshark/Makefile b/applications/luci-app-cshark/Makefile
new file mode 100644 (file)
index 0000000..40b0e9f
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2017 Dan Luedtke <mail@danrl.com>
+#
+# This is free software, licensed under the Apache License, Version 2.0 .
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=Cloudshark capture tool Web UI
+LUCI_DEPENDS:=+cshark
+LUCI_PKGARCH:=all
+
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-cshark/luasrc/controller/cshark.lua b/applications/luci-app-cshark/luasrc/controller/cshark.lua
new file mode 100644 (file)
index 0000000..4d9bbba
--- /dev/null
@@ -0,0 +1,125 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright (C) 2014, QA Cafe, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+]]--
+
+module("luci.controller.cshark", package.seeall)
+
+function index()
+               page = node("admin", "network", "cloudshark")
+               page.target = cbi("admin_network/cshark")
+               page.title = _("CloudShark")
+               page.order = 70
+
+               page = entry({"admin", "network", "cshark_iface_dump_start"}, call("cshark_iface_dump_start"), nil)
+               page.leaf = true
+
+               page = entry({"admin", "network", "cshark_iface_dump_stop"}, call("cshark_iface_dump_stop"), nil)
+               page.leaf = true
+
+               page = entry({"admin", "network", "cshark_check_status"}, call("cshark_check_status"), nil)
+               page.leaf = true
+
+               page = entry({"admin", "network", "cshark_link_list_get"}, call("cshark_link_list_get"), nil)
+               page.leaf = true
+
+               page = entry({"admin", "network", "cshark_link_list_clear"}, call("cshark_link_list_clear"), nil)
+               page.leaf = true
+end
+
+function cshark_iface_dump_start(ifname, value, flag, filter)
+       if ifname == nil or ifname == '' then
+               ifname = 'any'
+       end
+       if tonumber(value) == nil
+       then
+               value = '0'
+       end
+       if filter == nil or filter == '' then
+               filter = ''
+       end
+
+       if flag == nil or flag == '' then
+               filter = 'T'
+       end
+
+       luci.http.prepare_content("text/plain")
+
+       local res = os.execute("(/sbin/cshark -i " .. ifname .. " -" .. flag .. " " .. value .. " -p /tmp/cshark-luci.pid " .. filter .. " > /tmp/cshark-luci.out 2>&1) &")
+       luci.http.write(tostring(res))
+end
+
+function cshark_iface_dump_stop()
+       luci.http.prepare_content("text/plain")
+
+       local f = io.open("/tmp/cshark-luci.pid", "rb")
+       local pid = f:read("*all")
+       io.close(f)
+
+       local res = os.execute("kill -TERM " .. pid)
+       luci.http.write(tostring(res))
+end
+
+function cshark_check_status()
+
+       local msg = "";
+       local status;
+       local f = io.open("/tmp/cshark-luci.pid","r")
+       if f ~= nil then
+               status = 1;
+               io.close(f)
+       else
+               status = 0;
+       end
+
+       f = io.open("/tmp/cshark-luci.out","r")
+       if f ~= nil then
+               msg = f:read("*all")
+               io.close(f)
+               if msg ~= '' then
+                       os.remove('/tmp/cshark-luci.out')
+               end
+       end
+
+       luci.http.prepare_content("application/json")
+
+       local res = {}
+       res["status"] = status;
+       res["msg"] = msg;
+
+       luci.http.write_json(res)
+end
+
+function cshark_link_list_get()
+       local uci = require("uci").cursor()
+
+       luci.http.prepare_content("application/json")
+
+       luci.http.write("[")
+
+       local t = uci:get("cshark", "cshark", "entry")
+  if (t ~= nil) then
+         for i = #t, 1, -1 do
+                 luci.http.write("[\"" .. t[i] .. "\"],")
+         end
+  end
+
+       luci.http.write("[]]")
+end
+
+function cshark_link_list_clear()
+       local uci = require("uci").cursor()
+
+       uci:delete("cshark", "cshark", "entry")
+       uci:commit("cshark");
+
+       luci.http.status(200, "OK")
+end
diff --git a/applications/luci-app-cshark/luasrc/model/cbi/admin_network/cshark.lua b/applications/luci-app-cshark/luasrc/model/cbi/admin_network/cshark.lua
new file mode 100644 (file)
index 0000000..8db9559
--- /dev/null
@@ -0,0 +1,30 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright (C) 2014, QA Cafe, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+]]--
+
+local fs = require "nixio.fs"
+
+m = Map("cshark", translate("CloudShark"))
+
+if fs.access("/etc/config/cshark") then
+       m:section(SimpleSection).template = "cshark"
+
+       s = m:section(TypedSection, "cshark", translate("Options"))
+       s.anonymous = true
+       s.addremove = false
+
+       s:option(Value, "url", translate("CloudShark URL"))
+       s:option(Value, "token", translate("CloudShark API token"))
+end
+
+return m
diff --git a/applications/luci-app-cshark/luasrc/view/cshark.htm b/applications/luci-app-cshark/luasrc/view/cshark.htm
new file mode 100644 (file)
index 0000000..bc67f80
--- /dev/null
@@ -0,0 +1,291 @@
+<%#
+LuCI - Lua Configuration Interface
+
+Copyright (C) 2014, QA Cafe, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+-%>
+
+<fieldset class="cbi-section">
+       <legend><%:Start network capture%></legend>
+       <div class="cbi-section-node">
+               <table class="cbi-section-table">
+                       <tr>
+                               <th><%:Interface%></th>
+                               <th colspan='2'><%:seconds, packets, bytes%></th>
+                               <th><%:Filter%></th>
+                               <th><%:Actions%></th>
+                       </tr>
+                       <tr>
+                               <td>
+                                       <select title="<%:Interface%>" style="width:auto" id="s_interfaces">
+                                       <%
+                                               local nixio = require "nixio"
+                                               for k, v in ipairs(nixio.getifaddrs()) do
+                                                       if v.family == "packet" then
+                                                       %>
+                                                               <option value="<%=v.name%>"><%=v.name%> </option>
+                                                       <%
+                                                       end
+                                               end
+                                       %>
+                                               <option value="any"><%:any%></option>
+                                       </select>
+                               </td>
+                               <td colspan='2'>
+                                       <input id="tx_value" type="text" value="0" />
+                                       <select title="<%:timeout, bytes, seconds%>" id="s_value_type" style="width:auto">
+                                               <option value="T"><%:seconds%></option>
+                                               <option value="P"><%:packets%></option>
+                                               <option value="S"><%:bytes%></option>
+                                       </select>
+                               </td>
+                               <td>
+                                       <input style="margin: 5px 0" type="text" title="<%:Filter%>" placeholder="filter" id="i_filter" />
+                               </td>
+                               <td>
+                                       <input type="button" id="bt_action" data-action="start" value="<%:Start capture%>" class="cbi-button" />
+                               </td>
+                       </tr>
+               </table>
+       </div>
+</fieldset>
+
+<fieldset class="cbi-section">
+       <span id="cshark-rc-output"></span>
+</fieldset>
+
+<hr/>
+
+<fieldset class="cbi-section">
+       <legend><%:Capture links%></legend>
+       <div class="cbi-section-node">
+               <table id="t_link_list" class="cbi-section-table">
+                       <tr class="cbi-section-table-titles">
+                               <th class="cbi-section-table-cell"><%:Capture URL%></th>
+                               <th class="cbi-section-table-cell"><%:Capture time%></th>
+                       </tr>
+               </table>
+       </div>
+</fieldset>
+
+<fieldset class="cbi-section">
+  <a href="https://support.cloudshark.org/openwrt/openwrt-cloudshark.html" target="_blank">Visit support.cloudshark.org for help.</a>
+</fieldset>
+
+<hr/>
+
+<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
+<script type="text/javascript">//<![CDATA[
+
+       var capture_running = 0;
+       var pid_file = 0;
+       var bt_action = document.getElementById('bt_action');
+       var a_clear_links = document.getElementById('a_clear_links');
+       var output = document.getElementById('cshark-rc-output');
+       var loader = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" /> ';
+       var msg = { 'start' : '<%:Waiting for capture to complete...%>', 'stop' : '<%:Waiting for upload to complete...%>' };
+       var status_msg = msg['start'];
+
+       function get_date(timestamp)
+       {
+               function pad_str(str)
+               {
+                       return (str < 10) ? "0" + str : str;
+               }
+
+               var current_date = new Date(timestamp * 1000);
+               return current_date.getFullYear() + "-" +
+                               pad_str(current_date.getMonth() + 1) + "-" +
+                               pad_str(current_date.getDate()) + " " +
+                               pad_str(current_date.getHours()) + ":" +
+                               pad_str(current_date.getMinutes()) + ":" +
+                               pad_str(current_date.getSeconds());
+       }
+
+       bt_action.onclick = function()
+       {
+               var action = this.getAttribute("data-action");
+               var csxhr = new XHR();
+
+               if (action == "stop")
+               {
+                       update_status(action);
+
+                       bt_action.disabled = true;
+
+                       csxhr.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_iface_dump_stop', null,
+                       function(x)
+                       {
+                               if (!x || x.responseText.trim() != "0")
+                               {
+                                       update_status("failed", "Invalid response on stop.");
+                               }
+                       });
+
+               }
+               else if (action == "start")
+               {
+
+                       var s_interfaces = document.getElementById('s_interfaces');
+                       var s_value_type = document.getElementById('s_value_type');
+                       var i_filter = document.getElementById('i_filter');
+
+                       var if_n = s_interfaces.selectedIndex;
+                       var t_n = s_value_type.selectedIndex;
+                       var ifname = s_interfaces.options[if_n].value.trim();
+                       var filter_val = i_filter.value.trim();
+                       var tx_val = document.getElementById('tx_value').value.trim();
+                       var type_val = s_value_type.options[t_n].value.trim();
+
+                       if (type_val != 'P' && type_val != 'T' && type_val != 'S') type_val = 'T';
+
+                       if (!ifname || !type_val) return;
+
+                       if (isNaN(tx_val)) return alert("<%:value for [seconds, packets, bytes] must be Integer%>");
+
+                       update_status(action);
+
+                       csxhr.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_iface_dump_start/' + ifname + '/' + tx_val + '/' + type_val + '/'+ filter_val, null,
+                       function(x)
+                       {
+                               if (!x)
+                                       update_status("failed", "Invalid response on start.");
+                               else
+                                       update_status("running");
+                       });
+               }
+       }
+
+       function update_status(status, message)
+       {
+               switch (status)
+               {
+                       case 'start':
+                       case 'stop':
+                               status_msg = msg[status];
+                               output.innerHTML = loader + status_msg;
+                       break
+
+                       case 'running':
+                               if (capture_running) break;;
+
+                               output.innerHTML = loader + status_msg;
+
+                               bt_action.value = '<%:Stop capture%>';
+                               bt_action.setAttribute('data-action', 'stop');
+                               capture_running = 1;
+                       break;
+
+                       case 'completed':
+                       case 'failed':
+                               if (!capture_running) break;
+
+                               if (status == "completed")
+                               {
+                                       link_list_update();
+                               }
+
+                               output.innerHTML = "<pre>" + message + "</pre>";
+                               bt_action.value = '<%:Start capture%>';
+                               bt_action.setAttribute('data-action', 'start');
+                               bt_action.disabled = false;
+                               capture_running = 0;
+                       break;
+               }
+       }
+
+
+       function check_status()
+       {
+
+               XHR.poll(3, '<%=luci.dispatcher.build_url("admin", "network")%>/cshark_check_status', null,
+               function(x, data)
+               {
+                       if (!x)
+                       {
+                               if (capture_running)
+                                       update_status("failed", "Invalid response when fetching status.");
+
+                               return;
+                       }
+                       console.log(data)
+
+                       update_status( (data.status == 1) && "running" || "completed", data.msg);
+               })
+       }
+
+       function link_list_clear()
+       {
+               var csxhr_del = new XHR();
+               csxhr_del.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_link_list_clear', null,
+               function(x)
+               {
+                       if (!x)
+                               return false;
+
+                       link_list_update();
+               });
+       }
+
+
+       function link_list_update()
+       {
+               var t_link = document.getElementById("t_link_list");
+               if (!t_link) return;
+
+               var row_count = t_link.rows.length;
+               while(--row_count) t_link.deleteRow(row_count);
+
+               var cell = t_link.insertRow(-1).insertCell(0);
+               cell.colSpan = 2;
+               cell.innerHTML = loader;
+
+               var csxhr_link = new XHR();
+               csxhr_link.get('<%=luci.dispatcher.build_url("admin", "network")%>/cshark_link_list_get', null,
+               function(x, entries)
+               {
+                       var row = t_link.deleteRow(1);
+
+                       if (!x) return;
+
+                       if (!entries || !entries.length)
+                       {
+                               var cell = t_link.insertRow(-1).insertCell(0);
+                               cell.colSpan = 2;
+                               cell.innerHTML = '<em><br />There are no captures available yet.</em>';
+
+                               return;
+                       }
+
+                       for (var i = 0, len = entries.length; i < len ; i++)
+                       {
+                               var entry = entries[i][0];
+                               if (!entry) continue;
+
+                               var data = entry.split(",");
+                               var url = data[0];
+                               var timestamp = data[1];
+
+                               var row = t_link.insertRow(-1);
+                               row.insertCell(0).innerHTML = '<a href="'+url+'" target="_blank">'+url+'</a>';
+                               row.insertCell(1).innerHTML = get_date(timestamp);
+                       }
+
+                       var cell = t_link.insertRow(-1).insertCell(0);
+                       cell.colSpan = 2;
+                       cell.style.textAlign="center";
+                       cell.innerHTML = '<input type="button" onclick="link_list_clear()" class="cbi-button" value ="<%:Clear list%>" />';
+               })
+       }
+
+       check_status();
+       link_list_update();
+//]]></script>