diff options
-rw-r--r-- | example/ndpiReader.c | 22 | ||||
-rw-r--r-- | wireshark/ndpi.lua | 131 |
2 files changed, 89 insertions, 64 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 001e60249..e4f6b917f 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -151,15 +151,11 @@ FILE *trace = NULL; /********************** FUNCTIONS ********************* */ - - - /** * @brief Set main components necessary to the detection */ static void setupDetection(u_int16_t thread_id, pcap_t * pcap_handle); - /** * @brief Print help instructions */ @@ -170,13 +166,15 @@ static void help(u_int long_help) { " [-p <protos>][-l <loops> [-q][-d][-h][-t][-v <level>]\n" " [-n <threads>] [-w <file>] [-j <file>]\n\n" "Usage:\n" - " -i <file.pcap|device> | Specify a pcap file/playlist to read packets from or a device for live capture (comma-separated list)\n" + " -i <file.pcap|device> | Specify a pcap file/playlist to read packets from or a\n" + " | device for live capture (comma-separated list)\n" " -f <BPF filter> | Specify a BPF filter for filtering selected traffic\n" " -s <duration> | Maximum capture duration in seconds (live traffic capture only)\n" " -m <duration> | Split analysis duration in <duration> max seconds\n" " -p <file>.protos | Specify a protocol file (eg. protos.txt)\n" " -l <num loops> | Number of detection loops (test only)\n" - " -n <num threads> | Number of threads. Default: number of interfaces in -i. Ignored with pcap files.\n" + " -n <num threads> | Number of threads. Default: number of interfaces in -i.\n" + " | Ignored with pcap files.\n" " -j <file.json> | Specify a file to write the content of packets in .json format\n" #ifdef linux " -g <id:id...> | Thread affinity mask (one core id per thread)\n" @@ -188,9 +186,12 @@ static void help(u_int long_help) { " -w <path> | Write test output on the specified file. This is useful for\n" " | testing purposes in order to compare results across runs\n" " -h | This help\n" - " -v <1|2|3> | Verbose 'unknown protocol' packet print. 1=verbose, 2=very verbose, 3=port stats\n"); + " -v <1|2|3> | Verbose 'unknown protocol' packet print.\n" + " | 1 = verbose\n" + " | 2 = very verbose\n" + " | 3 = port stats\n"); - #ifndef WIN32 +#ifndef WIN32 printf("\nExcap (wireshark) options:\n" " --extcap-interfaces\n" " --extcap-version\n" @@ -202,7 +203,7 @@ static void help(u_int long_help) { " --fifo <path to file or pipe>\n" " --debug\n" ); - #endif +#endif if(long_help) { printf("\n\nSupported protocols:\n"); @@ -287,11 +288,8 @@ void extcap_config() { /* -i <interface> */ printf("arg {number=%u}{call=-i}{display=Capture Interface or Pcap File Path}{type=string}" "{tooltip=The interface name}\n", argidx++); - -#if 0 printf("arg {number=%u}{call=-i}{display=Pcap File to Analize}{type=fileselect}" "{tooltip=The pcap file to analyze (if the interface is unspecified)}\n", argidx++); -#endif setupDetection(0, NULL); ndpi_mod = ndpi_thread_info[0].workflow->ndpi_struct; diff --git a/wireshark/ndpi.lua b/wireshark/ndpi.lua index 3d35c9083..789b46f54 100644 --- a/wireshark/ndpi.lua +++ b/wireshark/ndpi.lua @@ -15,9 +15,65 @@ fds.name = ProtoField.new("nDPI Protocol Name", "ndpi.protocol.name", ftypes.STR local f_eth_trailer = Field.new("eth.trailer") -local ndpi_protos = {} -local ndpi_flows = {} -local compute_flows_stats = true +local ndpi_protos = {} +local ndpi_flows = {} +local num_ndpi_flows = 0 + +local lower_ndpi_flow_id = 0 +local lower_ndpi_flow_volume = 0 + +local compute_flows_stats = true +local max_num_entries = 10 +local max_num_flows = 50 + +-- ############################################### + +function round(num, idp) return tonumber(string.format("%." .. (idp or 0) .. "f", num)) end + +-- Convert bytes to human readable format +function bytesToSize(bytes) + if(bytes == nil) then + return("0") + else + precision = 2 + kilobyte = 1024; + megabyte = kilobyte * 1024; + gigabyte = megabyte * 1024; + terabyte = gigabyte * 1024; + + bytes = tonumber(bytes) + if((bytes >= 0) and (bytes < kilobyte)) then + return round(bytes, precision) .. " Bytes"; + elseif((bytes >= kilobyte) and (bytes < megabyte)) then + return round(bytes / kilobyte, precision) .. ' KB'; + elseif((bytes >= megabyte) and (bytes < gigabyte)) then + return round(bytes / megabyte, precision) .. ' MB'; + elseif((bytes >= gigabyte) and (bytes < terabyte)) then + return round(bytes / gigabyte, precision) .. ' GB'; + elseif(bytes >= terabyte) then + return round(bytes / terabyte, precision) .. ' TB'; + else + return round(bytes, precision) .. ' Bytes'; + end + end +end + +function pairsByValues(t, f) + local a = {} + for n in pairs(t) do table.insert(a, n) end + table.sort(a, function(x, y) return f(t[x], t[y]) end) + local i = 0 -- iterator variable + local iter = function () -- iterator function + i = i + 1 + if a[i] == nil then return nil + else return a[i], t[a[i]] + end + end + return iter +end + +function asc(a,b) return (a < b) end +function rev(a,b) return (a > b) end -- ############################################### @@ -80,9 +136,27 @@ function ndpi_proto.dissector(tvb, pinfo, tree) flowkey = srckey.." / "..dstkey.." ["..ndpikey.."]" if(ndpi_flows[flowkey] == nil) then ndpi_flows[flowkey] = 0 + num_ndpi_flows = num_ndpi_flows + 1 + + if(num_ndpi_flows > max_num_flows) then + -- We need to harvest the flow with least packets beside this new one + local tot_removed = 0 + + for k,v in pairsByValues(ndpi_flows, asc) do + if(k ~= flowkey) then + table.remove(ndpi_flows, k) + tot_removed = tot_removed + 1 + if(tot_removed == max_num_entries) then + break + end + end + end + + end end ndpi_flows[flowkey] = ndpi_flows[flowkey] + pinfo.len + end end end @@ -91,58 +165,11 @@ register_postdissector(ndpi_proto) -- ############################################### -function round(num, idp) return tonumber(string.format("%." .. (idp or 0) .. "f", num)) end - --- Convert bytes to human readable format -function bytesToSize(bytes) - if(bytes == nil) then - return("0") - else - precision = 2 - kilobyte = 1024; - megabyte = kilobyte * 1024; - gigabyte = megabyte * 1024; - terabyte = gigabyte * 1024; - - bytes = tonumber(bytes) - if((bytes >= 0) and (bytes < kilobyte)) then - return round(bytes, precision) .. " Bytes"; - elseif((bytes >= kilobyte) and (bytes < megabyte)) then - return round(bytes / kilobyte, precision) .. ' KB'; - elseif((bytes >= megabyte) and (bytes < gigabyte)) then - return round(bytes / megabyte, precision) .. ' MB'; - elseif((bytes >= gigabyte) and (bytes < terabyte)) then - return round(bytes / gigabyte, precision) .. ' GB'; - elseif(bytes >= terabyte) then - return round(bytes / terabyte, precision) .. ' TB'; - else - return round(bytes, precision) .. ' Bytes'; - end - end -end - -function pairsByValues(t, f) - local a = {} - for n in pairs(t) do table.insert(a, n) end - table.sort(a, function(x, y) return f(t[x], t[y]) end) - local i = 0 -- iterator variable - local iter = function () -- iterator function - i = i + 1 - if a[i] == nil then return nil - else return a[i], t[a[i]] - end - end - return iter -end - -function asc(a,b) return (a < b) end -function rev(a,b) return (a > b) end local function ndpi_dialog_menu() local win = TextWindow.new("nDPI Protocol Statistics"); local label = "" local i - local max_i = 10 if(ndpi_protos ~= {}) then label = "nDPI Protocol Breakdown\n" @@ -152,7 +179,7 @@ local function ndpi_dialog_menu() for k,v in pairsByValues(ndpi_protos, rev) do -- label = label .. k .. "\t".. bytesToSize(v) .. "\n" label = label .. string.format("%-32s\t%s\n", k, bytesToSize(v)) - if(i == max_i) then break else i = i + 1 end + if(i == max_num_entries) then break else i = i + 1 end end -- ####### @@ -162,7 +189,7 @@ local function ndpi_dialog_menu() i = 0 for k,v in pairsByValues(ndpi_flows, rev) do label = label .. string.format("%-32s\t%s\n", k, bytesToSize(v)) - if(i == max_i) then break else i = i + 1 end + if(i == max_num_entries) then break else i = i + 1 end end win:set(label) |