luci-mod-status: add simple filtering for connections
authorMiguel Angel Mulero Martinez <migmul@gmail.com>
Mon, 23 Dec 2024 15:17:29 +0000 (16:17 +0100)
committerPaul Donald <newtwen+github@gmail.com>
Fri, 27 Dec 2024 22:59:03 +0000 (22:59 +0000)
This commit adds a simple filtering input text into the connections status page. You can type some filtering like:
- '100.15' -> Will show only connections that include this '100.15' onto the IP.
- 'UDP 100.15' -> Will show only UDP connections that include this '100.15' onto the IP.
- ':443' -> Will show only connections that use the port 443 as source or destination.

You can use a part of the IP or part of the name if the DNS resolution button is enabled.

It's a very simple filter that can grow in the future if it deserves some interest, maybe adding some regular expression support.

Signed-off-by: Miguel Angel Mulero Martinez <migmul@gmail.com>
modules/luci-mod-status/htdocs/luci-static/resources/view/status/connections.js

index bb5e937e36294dc81951708f925ce94e11379fa3..f6d505416dd8521f7531b32d3be987cbca34e3a0 100644 (file)
@@ -27,7 +27,8 @@ var callNetworkRrdnsLookup = rpc.declare({
 var graphPolls = [],
     pollInterval = 3,
     dns_cache = {},
-    enableLookups = false;
+    enableLookups = false,
+    filterText = '';
 
 var recheck_lookup_queue = {};
 
@@ -130,12 +131,27 @@ return view.extend({
                        var src = dns_cache[c.src] || (c.layer3 == 'ipv6' ? '[' + c.src + ']' : c.src);
                        var dst = dns_cache[c.dst] || (c.layer3 == 'ipv6' ? '[' + c.dst + ']' : c.dst);
 
+                       const network = c.layer3.toUpperCase();
+                       const protocol = c.layer4.toUpperCase();
+                       const source ='%h'.format(c.hasOwnProperty('sport') ? (src + ':' + c.sport) : src);
+                       const destination = '%h'.format(c.hasOwnProperty('dport') ? (dst + ':' + c.dport) : dst);
+                       const transfer = [ c.bytes, '%1024.2mB (%d %s)'.format(c.bytes, c.packets, _('Pkts.')) ];
+
+                       if (filterText) {
+                               let filterTextExpressions = filterText.split(' ');
+                               if (filterTextExpressions.some((element) => element.toUpperCase() !== network && element.toUpperCase() !== protocol 
+                                               && !(c.src.includes(element) || source.includes(element))
+                                               && !(c.dst.includes(element) || destination.includes(element)))) {
+                                       continue;
+                               }
+                       }
+
                        rows.push([
-                               c.layer3.toUpperCase(),
-                               c.layer4.toUpperCase(),
-                               '%h'.format(c.hasOwnProperty('sport') ? (src + ':' + c.sport) : src),
-                               '%h'.format(c.hasOwnProperty('dport') ? (dst + ':' + c.dport) : dst),
-                               [ c.bytes, '%1024.2mB (%d %s)'.format(c.bytes, c.packets, _('Pkts.')) ]
+                               network,
+                               protocol,
+                               source,
+                               destination,
+                               transfer,
                        ]);
                }
 
@@ -359,23 +375,48 @@ return view.extend({
                                        ])
                                ]),
 
-                               E('div', { 'class': 'right' }, [
-                                       E('button', {
-                                               'class': 'btn cbi-button cbi-button-apply toggle-lookups',
-                                               'click': function(ev) {
-                                                       if (!enableLookups) {
-                                                               ev.currentTarget.classList.add('spinning');
-                                                               ev.currentTarget.disabled = true;
-                                                               enableLookups = true;
-                                                       }
-                                                       else {
-                                                               ev.currentTarget.firstChild.data = _('Enable DNS lookups');
-                                                               enableLookups = false;
-                                                       }
+                               E('br'),
 
-                                                       this.blur();
-                                               }
-                                       }, [ enableLookups ? _('Disable DNS lookups') : _('Enable DNS lookups') ])
+                               E('div', { 
+                                       id: 'settings-row',
+                                       style: 'display: flex',
+                               }, [
+                                       E('span', { 
+                                               class: 'filter',
+                                               style: 'flex: auto',
+                                       }, [
+                                               E('input', {
+                                                       id: 'filter-connections',
+                                                       type: 'text',
+                                                       placeholder: '192.168.1.15 / UDP 1.15 / :443',
+                                                       class: 'cbi-input-text',
+                                                       style: 'width: 100%',
+                                                       keyup: function(ev) {
+                                                               filterText = this.value;
+                                                   }
+                                               })
+                                       ]),
+                                       E('span', { 
+                                               class: 'right',
+                                               style: 'flex: auto',
+                                       }, [
+                                               E('button', {
+                                                       'class': 'btn cbi-button cbi-button-apply toggle-lookups',
+                                                       'click': function(ev) {
+                                                               if (!enableLookups) {
+                                                                       ev.currentTarget.classList.add('spinning');
+                                                                       ev.currentTarget.disabled = true;
+                                                                       enableLookups = true;
+                                                               }
+                                                               else {
+                                                                       ev.currentTarget.firstChild.data = _('Enable DNS lookups');
+                                                                       enableLookups = false;
+                                                               }
+
+                                                               this.blur();
+                                                       }
+                                               }, [ enableLookups ? _('Disable DNS lookups') : _('Enable DNS lookups') ])
+                                       ]),
                                ]),
 
                                E('br'),