mirror of
https://github.com/kenzok8/small-package
synced 2025-01-08 11:17:34 +08:00
288 lines
8.3 KiB
JavaScript
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();
|
|
},
|
|
});
|