kenzok8-package/luci-app-packet-capture/htdocs/luci-static/resources/view/packet_capture/tcpdump.js
2023-01-28 01:28:48 +08:00

288 lines
8.3 KiB
JavaScript

'use strict';
'require rpc';
'require uci';
'require ui';
'require fs';
'require form';
'require network';
'require tools.widgets as widgets';
var eventSource,
captureFilePoll,
hostName;
function stopTcpdump() {
fs.exec("/usr/libexec/packet_capture_stop").then(function(replay) {
if (eventSource)
eventSource.close();
}.bind(this)).catch(function(error) {
console.log(error);
});
}
window.addEventListener('beforeunload', stopTcpdump);
var callLuciProcessList = rpc.declare({
object: 'luci',
method: 'getProcessList',
expect: { result: [] }
});
var callInitAction = rpc.declare({
object: 'luci',
method: 'setInitAction',
params: [ 'name', 'action' ],
expect: { result: false }
});
function addOutput() {
var tcpdumpOut = document.querySelectorAll('[id$="tcpdump_out"]')[0];
if (tcpdumpOut)
return;
var frameEl = E('div', {'class': 'cbi-value'});
frameEl.appendChild(E('textarea', {
'id': 'tcpdump_out',
'class': 'cbi-input-textarea',
'readonly': '',
'style': 'width:100%',
'rows': 30,
}));
frameEl.firstElementChild.style.fontFamily = 'monospace';
var downloadBtn = document.querySelectorAll('[id$="download_file"]')[0];
if (downloadBtn)
downloadBtn.parentNode.insertBefore(frameEl, downloadBtn.nextSibling);
}
var downloadCaptureFile = function(ev) {
var form = E('form', {
method: 'post',
action: '/cgi-bin/cgi-download',
enctype: 'application/x-www-form-urlencoded'
}, E('input', { type: 'hidden', name: 'sessionid', value: rpc.getSessionID()},
E('input', { type: 'hidden', name: 'path', value: "/tmp/capture.pcap"},
E('input', { type: 'hidden', name: 'filename', value: hostName + "-" + Date.now() + ".pcap"},
E('input', { type: 'hidden', name: 'mimetype', value: 'application/vnd.tcpdump.pcap'}
)))));
ev.currentTarget.parentNode.appendChild(form);
form.submit();
form.parentNode.removeChild(form);
}
function subscribeTcpdump() {
if (eventSource)
eventSource.close();
eventSource = new EventSource('/ubus/subscribe/tcpdump' + '?' + rpc.getSessionID());
eventSource.onerror = function(event) {
eventSource.close();
console.log(event);
};
addOutput();
var textOut = document.querySelectorAll('[id$="tcpdump_out"]')[0];
textOut.value = "";
eventSource.addEventListener("tcpdump.data", function(event) {
textOut.value = textOut.value + "\n" + JSON.parse(event.data).data;
});
}
function updateButtons() {
var tasks = [];
tasks.push(fs.stat("/var/run/packet_capture.pid").then(L.bind(function(res) {
var downloadBtn = document.querySelectorAll('[id$="download_file"]')[0];
if (!downloadBtn)
return;
if (!eventSource || eventSource.readyState == 2)
subscribeTcpdump();
var textOut = document.querySelectorAll('[id$="tcpdump_out"]')[0];
if (textOut)
textOut.style.borderColor = "green";
var startBtn = document.querySelectorAll('[id$="start_tcpdump"]')[0];
if (startBtn)
startBtn.hidden = true;
var stopBtn = document.querySelectorAll('[id$="stop_tcpdump"]')[0];
if (stopBtn)
stopBtn.hidden = false;
return;
})).catch(function(error) {
var textOut = document.querySelectorAll('[id$="tcpdump_out"]')[0];
if (textOut)
textOut.style.borderColor = "red";
var startBtn = document.querySelectorAll('[id$="start_tcpdump"]')[0];
if (startBtn)
startBtn.hidden = false;
var stopBtn = document.querySelectorAll('[id$="stop_tcpdump"]')[0];
if (stopBtn)
stopBtn.hidden = true;
if (eventSource)
eventSource.close();
}));
return Promise.all(tasks);
}
function updatePollCheckCaptureFileExists() {
checkCaptureFileExists();
L.Poll.remove(captureFilePoll);
L.Poll.add(L.bind(checkCaptureFileExists, m),5);
}
function checkCaptureFileExists() {
var tasks = [];
tasks.push(fs.stat("/tmp/capture.pcap").then(L.bind(function(res) {
var downloadBtn = document.querySelector('[data-action="download"]');
if (!downloadBtn)
return;
var downloadCheckBox = document.querySelectorAll('[data-widget-id$="file"]')[0].checked;
if (!downloadCheckBox) {
fs.remove("/tmp/capture.pcap").then(function(replay) {
downloadBtn.disabled = true;;
}.bind(this)).catch(function(error) {
console.log(error);
});
} else {
downloadBtn.disabled = false;
}
})).catch(function(error) {
var downloadBtn = document.querySelector('[data-action="download"]');
if (downloadBtn)
downloadBtn.disabled = true;
}));
return Promise.all(tasks);
}
return L.view.extend({
load: function() {
return Promise.all([
uci.load('system')
]);
},
handleDownload: function(ev) {
downloadCaptureFile(ev);
},
render: function(processes) {
var m, s, o;
hostName = uci.get('system', '@system[0]', 'hostname');
m = new form.Map('packet_capture', _('Packet Capture - Tcpdump'), _('Capture packets with tcpdump.'));
s = m.section(form.TypedSection, 'tcpdump');
s.anonymous = 1;
o = s.option(widgets.DeviceSelect, 'interface', _('Interface'), _(''));
o.noaliases = true;
o.modalonly = true;
o.rmempty = false;
o.filter = function(section_id, value) {
return true;
}
o = s.option(form.Value, 'filter', _('Filter'), _('Tcpdump filter like protocol, port etc.'));
o.modalonly = false;
o.datatype = 'and(minlength(1),maxlength(1024))';
o = s.option(form.Value, 'duration', _('Duration'), _('Duration of packet capturing in seconds.'));
o.modalonly = false;
o.datatype = 'range(1,4294967296)';
o = s.option(form.Value, 'packets', _('Packets'), _('Number of packets to be captured.'));
o.modalonly = false;
o.datatype = 'range(1,4294967296)';
o = s.option(form.Flag, 'domains', _('Resolve domains'), _("Convert host addresses to names."));
o = s.option(form.Flag, 'verbose', _('Verbose output'), _("Print the link-level header on each dump line."));
o = s.option(form.Flag, 'file', _('Save to file'), _("Save capture to pcap file."));
o = s.option(form.Button, 'start_tcpdump', _('Start tcpdump'), _(''));
o.inputstyle = 'apply';
o.onclick = ui.createHandlerFn(this, function(section_id, ev) {
var downloadBtn = document.querySelector('[data-action="download"]');
if (!downloadBtn)
return;
fs.remove("/tmp/capture.pcap").then(function(replay) {
downloadBtn.disabled = true;;
}.bind(this)).catch(function(error) {
console.log(error);
});
var iface = document.querySelectorAll('[id$="interface"]')[1].value,
filter = document.querySelectorAll('[id$="filter"]')[2].value,
packets = document.querySelectorAll('[id$="packets"]')[2].value,
duration = document.querySelectorAll('[id$="duration"]')[2].value,
verbose = document.querySelectorAll('[data-widget-id$="verbose"]')[0].checked,
domains = document.querySelectorAll('[data-widget-id$="domains"]')[0].checked,
file = document.querySelectorAll('[data-widget-id$="file"]')[0].checked
var args = {
"interface": iface,
"filter": filter,
"packets": packets,
"duration": duration,
"verbose": verbose,
"domains": domains,
"file": file
}
return fs.exec_direct('/usr/libexec/packet_capture_start', [JSON.stringify(args)]).then(function(replay) {
var error_position = replay.search("error:");
if (error_position != -1){
ui.showModal(_(replay.substring(error_position + 6, replay.length)), [
E('div', { 'class': 'right' }, [
E('button', {
'class': 'cbi-button cbi-button-negative important',
'click': function(ev) {
ui.hideModal();
}
}, _('Close')),
])
]);
return;
}
rpc.list.apply(rpc).then(function(res) {
for (var k in res) {
if (res[k] == "tcpdump" )
subscribeTcpdump()
}
}.bind(this));
}.bind(this)).catch(function(error) {
console.log(error);
});
});
o = s.option(form.Button, 'stop_tcpdump', _('Stop tcpdump'), _(''));
o.inputstyle = 'apply';
o.onclick = ui.createHandlerFn(this, function(section_id, ev) {
if (!eventSource)
return;
return fs.exec("/usr/libexec/packet_capture_stop").then(function(replay) {
eventSource.close();
}.bind(this)).catch(function(error) {
console.log(error);
});
});
o = s.option(form.Button, 'download_file', _('Download capture file'));
o.inputstyle = 'action important';
o.inputtitle = _('Download');
o.data_action = 'download'
o.onclick = this.handleDownload;
L.Poll.add(L.bind(updateButtons, m),1);
captureFilePoll = L.bind(updatePollCheckCaptureFileExists, m);
L.Poll.add(captureFilePoll,1);
return m.render();
},
});