luci-app-lldpd: Create from Tano Systems

This is a copy of https://github.com/tano-systems/luci-app-tn-lldpd, which is licensed under the MIT License.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Rename luci-app-tn-lldpd to luci-app-lldpd

The original version of Tanosystem has a naming scheme which does not correspond to the standard naming scheme in OpenWrt LuCi. Therefore the renaming.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Fix bug not getting the current lldpd status

Specifying the arguments in the wrong order can (and has in my tests) resulted in errors. So you can see in the man page that flags like -f come first and then the command.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Disable option to enable SNMP agent

SNMP agent support is not enabled by default in lldpd. This can (and has in my tests) cause LLDP to stop working. See comment in source code.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Add option to disable sending sensitive information

Added an option that sets the "-k" flag, which results in less sensitive information being sent. See man pages and description in source code.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Add license information to Makefile

All of Tano Systems source code for the app is licensed under the MIT License. This has now been indicated accordingly in the Makefile.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Remove old footer from Tano Systems

The app from Tano Systems appears to include a footer. Since most LuCi apps do not, I have removed it.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Bug fix caused that the management IP address could not be set.

The TanoWrt fork calls the option to set the management IP addresses "lldp_sys_mgmt_ip". However, in OpenWrt it is called "lldp_mgmt_ip".

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Improve style

Remove double space

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Adding the Lua dependency

The rpcd script used by the Luci app is written in Lua. Therefore, runtime dependencies for Lua must exist when using the Luci app.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Remove old files

Since the app is called luci-app-lldpd and not luci-app-tn-lldpd, the files for the TanoWrt app are no longer necessary.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: RPCd backend change from Lua to ucode

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Update filter matrix

The old filter matrix was based on the man pages, but the selected value in the range 1-20 was also assigned to the configuration and thus lldpd was configured incorrectly. lldpd expects a value in the range 0-19. The webapp matrix has now been changed so that the values 0-19 also appear there.
This leads to a unification of configuration and webapp.

Signed-off-by: Marek Küthe <m.k@mk16.de>

luci-app-lldpd: Add location parameter

Signed-off-by: Marek Küthe <m.k@mk16.de>
This commit is contained in:
Marek Küthe
2023-07-04 11:42:23 +02:00
parent 51d9b9d33f
commit 49207b47ca
13 changed files with 2861 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
#
# Copyright (c) 2018, Tano Systems. All Rights Reserved.
# Anton Kikin <a.kikin@tano-systems.com>
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for LLDP daemon
LUCI_DEPENDS:=+lldpd +rpcd-mod-ucode
PKG_LICENSE:=MIT
include ../../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@@ -0,0 +1,193 @@
/*
* Copyright (c) 2018-2020, Tano Systems LLC. All Rights Reserved.
* Anton Kikin <a.kikin@tano-systems.com>
*/
'use strict';
'require ui';
'require form';
'require network';
'require session';
'require uci';
/*
* Filter neighbors (-H)
*
* The filter column means that filtering is enabled
* The 1proto column tells that only one protocol will be kept.
* The 1neigh column tells that only one neighbor will be kept.
*
* incoming outgoing
* filter 1proto 1neigh filter 1proto 1neigh
* 0
* 1 x x x x
* 2 x x
* 3 x x
* 4 x x
* 5 x
* 6 x
* 7 x x x x x
* 8 x x x
* 9 x x x x
* 10 x x
* 11 x x
* 12 x x x x
* 13 x x x
* 14 x x x x
* 15 x x x
* 16 x x x x x
* 17 x x x x
* 18 x x x
* 19 x x x
*/
var cbiFilterSelect = form.Value.extend({
__name__: 'CBI.LLDPD.FilterSelect',
__init__: function() {
this.super('__init__', arguments);
this.selected = null;
this.filterVal = [
[ 0, 0, 0, 0, 0, 0 ],
[ 1, 1, 0, 1, 1, 0 ],
[ 1, 1, 0, 0, 0, 0 ],
[ 0, 0, 0, 1, 1, 0 ],
[ 1, 0, 0, 1, 0, 0 ],
[ 1, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 1, 0, 0 ],
[ 1, 1, 1, 1, 1, 0 ],
[ 1, 1, 1, 0, 0, 0 ],
[ 1, 0, 1, 1, 1, 0 ],
[ 0, 0, 0, 1, 0, 1 ],
[ 1, 0, 1, 0, 0, 0 ],
[ 1, 0, 1, 1, 0, 1 ],
[ 1, 0, 1, 1, 0, 0 ],
[ 1, 1, 0, 1, 0, 1 ],
[ 1, 1, 0, 1, 0, 0 ],
[ 1, 1, 1, 1, 0, 1 ],
[ 1, 1, 1, 1, 0, 0 ],
[ 1, 0, 0, 1, 0, 1 ],
[ 1, 0, 0, 1, 1, 0 ]
];
},
/** @private */
handleRowClick: function(section_id, ev) {
var row = ev.currentTarget;
var tbody = row.parentNode;
var selected = row.getAttribute('data-filter');
var input = tbody.querySelector('[id="' + this.cbid(section_id) + '-' + selected + '"]');
this.selected = selected;
tbody.querySelectorAll('tr').forEach(function(e) {
e.classList.remove('lldpd-filter-selected');
});
input.checked = true;
row.classList.add('lldpd-filter-selected');
},
formvalue: function(section_id) {
return this.selected || this.cfgvalue(section_id);
},
renderFrame: function(section_id, in_table, option_index, nodes) {
var tmp = this.description;
// Prepend description with table legend
this.description =
'<ul><li>' + _('E &mdash; enable filter') + '</li>' +
'<li>' + _('P &mdash; keep only one protocol') + '</li>' +
'<li>' + _('N &mdash; keep only one neighbor') + '</li>' +
'</ul>' + this.description;
var rendered = this.super('renderFrame', arguments);
// Restore original description
this.description = tmp;
return rendered;
},
renderWidget: function(section_id, option_index, cfgvalue) {
var selected = parseInt(cfgvalue) - 1;
var tbody = [];
var renderFilterVal = L.bind(function(row, col) {
return this.filterVal[row][col] ? '&#x2714;' : '';
}, this);
for (var i = 0; i < this.filterVal.length; i++) {
tbody.push(E('tr', {
'class': ((selected == i) ? 'lldpd-filter-selected' : ''),
'click': L.bind(this.handleRowClick, this, section_id),
'data-filter': i,
}, [
E('td', {}, [
E('input', {
'class': 'cbi-input-radio',
'data-update': 'click change',
'type': 'radio',
'id': this.cbid(section_id) + '-' + i,
'name': this.cbid(section_id),
'checked': (selected == i) ? '' : null,
'value': i
})
]),
E('td', {}, i),
E('td', {}, renderFilterVal(i, 0)),
E('td', {}, renderFilterVal(i, 1)),
E('td', {}, renderFilterVal(i, 2)),
E('td', {}, renderFilterVal(i, 3)),
E('td', {}, renderFilterVal(i, 4)),
E('td', {}, renderFilterVal(i, 5))
]));
};
var table = E('table', { 'class': 'lldpd-filter', 'id': this.cbid(section_id) }, [
E('thead', {}, [
E('tr', {}, [
E('th', { 'rowspan': 2 }),
E('th', { 'rowspan': 2 }, _('Filter')),
E('th', { 'colspan': 3 }, _('Incoming')),
E('th', { 'colspan': 3 }, _('Outgoing'))
]),
E('tr', {}, [
E('th', {}, 'E'),
E('th', {}, 'P'),
E('th', {}, 'N'),
E('th', {}, 'E'),
E('th', {}, 'P'),
E('th', {}, 'N'),
])
]),
E('tbody', {}, tbody)
]);
return table;
},
});
function init() {
return new Promise(function(resolveFn, rejectFn) {
var data = session.getLocalData('luci-app-lldpd');
if (data !== null) {
return resolveFn();
}
data = {};
return uci.load('luci').then(function() {
session.setLocalData('luci-app-lldpd', data);
return resolveFn();
});
});
}
return L.Class.extend({
cbiFilterSelect: cbiFilterSelect,
init: init,
});

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 18 11.12" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m 9,11.12 9,-9 L 15.88,0 9,6.88 2.12,0 0,2.12 Z"/>
<path d="m-9-12h36v36h-36z" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m4.585 2.83 9.17 9.17-9.17 9.17 2.83 2.83 12-12-12-12z"/>
<path d="m0-24h48v48h-48z" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 563 B

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2020, Tano Systems LLC. All Rights Reserved.
* Author: Anton Kikin <a.kikin@tano-systems.com>
*/
/*
* Filter select widget
*/
table.lldpd-filter td,
table.lldpd-filter th {
border: 1px solid #ccc !important;
padding: 2px 10px 2px 10px;
text-align: center;
}
table.lldpd-filter td,
table.lldpd-filter td input[type="radio"] {
vertical-align: middle;
}
table.lldpd-filter th { font-weight: bold; }
table.lldpd-filter tbody tr {
cursor: pointer;
}
table.lldpd-filter tr.lldpd-filter-selected td {
background-color: #eeeeee;
}
/*
* Parameters
*/
.lldpd-params {
column-count: 2;
-moz-column-count: 2;
-webkit-column-count: 2;
column-gap: 24px;
-moz-column-gap: 24px;
-webkit-column-gap: 24px;
}
@media only screen and (max-width: 850px) {
.lldpd-params {
column-count: 1;
-moz-column-count: 1;
-webkit-column-count: 1;
}
}
.lldpd-params > div {
display: grid;
grid-template-columns: 1fr auto;
border-bottom: 1px solid #e6e6e6;
padding: 0 8px;
-webkit-column-break-inside: avoid;
-moz-column-break-inside: avoid;
column-break-inside: avoid;
}
.td .lldpd-params > div:last-of-type {
border-bottom: none;
}
.lldpd-params .lldpd-param {
margin-right: 10px;
font-weight: bold;
}
.lldpd-params .lldpd-param::after {
content: ':';
}
.lldpd-params .lldpd-param-value {
white-space: normal;
font-weight: normal;
text-align: right;
}
.td .lldpd-params {
column-count: 1;
-moz-column-count: 1;
-webkit-column-count: 1;
}
.td .lldpd-params > div {
padding: 0;
}
/*
* Status table
*/
.lldpd-folded,
.lldpd-unfolded {
width: 100%;
}
.lldpd-table .tr .td { cursor: pointer; }
.lldpd-protocol-badge {
display: inline-block;
width: auto !important;
width: fit-content !important;
width: -moz-fit-content !important;
width: -webkit-fit-content !important;
box-shadow: 0 1px 3px 0 grey;
padding: 0px 8px;
border-radius: 5px;
width: 100%;
background-color: #e6e6e6;
border: 0;
margin-right: 5px;
margin-bottom: 5px;
color: #595959;
}
.lldpd-protocol-badge.lldpd-protocol-lldp { background-color: #b7efcf; border-color: #2abd69; color: #165e34; }
.lldpd-protocol-badge.lldpd-protocol-cdp { background-color: #b2daf3; border-color: #46a6e2; color: #1a74ac; }
.lldpd-protocol-badge.lldpd-protocol-fdp { background-color: #f9e3b3; border-color: #b7820f; color: #b7820f; }
.lldpd-protocol-badge.lldpd-protocol-edp { background-color: #f9e3f9; border-color: #e380e3; color: #b70f82; }
.lldpd-protocol-badge.lldpd-protocol-sonmp { background-color: #f4ffc4; border-color: #a7ce00; color: #7e9b00; }

View File

@@ -0,0 +1,484 @@
/*
* Copyright (c) 2020 Tano Systems LLC. All Rights Reserved.
* Author: Anton Kikin <a.kikin@tano-systems.com>
*/
'use strict';
'require rpc';
'require form';
'require lldpd';
'require uci';
'require tools.widgets as widgets';
var callInitList = rpc.declare({
object: 'luci',
method: 'getInitList',
params: [ 'name' ],
expect: { '': {} },
filter: function(res) {
for (var k in res)
return +res[k].enabled;
return null;
}
});
var callInitAction = rpc.declare({
object: 'luci',
method: 'setInitAction',
params: [ 'name', 'action' ],
expect: { result: false }
});
return L.view.extend({
__init__: function() {
this.super('__init__', arguments);
// Inject CSS
var head = document.getElementsByTagName('head')[0];
var css = E('link', { 'href':
L.resource('lldpd/lldpd.css')
+ '?v=#PKG_VERSION', 'rel': 'stylesheet' });
head.appendChild(css);
},
load: function() {
return Promise.all([
callInitList('lldpd'),
lldpd.init(),
uci.load('lldpd')
]);
},
// -----------------------------------------------------------------------------------------
//
// Basic Options
//
// -----------------------------------------------------------------------------------------
/** @private */
populateBasicOptions: function(s, tab, data) {
var o;
var serviceEnabled = data[0];
// Service enable/disable
o = s.taboption(tab, form.Flag, 'enabled', _('Enable service'));
o.optional = false;
o.rmempty = false;
o.cfgvalue = function() {
return serviceEnabled ? this.enabled : this.disabled;
};
o.write = function(section_id, value) {
uci.set('mstpd', section_id, 'enabled', value);
if (value == '1') {
// Enable and start
return callInitAction('lldpd', 'enable').then(function() {
return callInitAction('lldpd', 'start');
});
}
else {
// Stop and disable
return callInitAction('lldpd', 'stop').then(function() {
return callInitAction('lldpd', 'disable');
});
}
};
// System description
o = s.taboption(tab, form.Value, 'lldp_description',
_('System description'),
_('Override system description with the provided description.'));
o.placeholder = 'System description';
// System hostname
o = s.taboption(tab, form.Value, 'lldp_hostname',
_('System hostname'),
_('Override system hostname with the provided value.'));
o.placeholder = 'System hostname';
// Host location
o = s.taboption(tab, form.Value, 'lldp_location',
_('Host location'),
_('Override the location of the host announced by lldp.'));
o.placeholder = 'address country EU';
// Platform
o = s.taboption(tab, form.Value, 'lldp_platform',
_('System platform description'),
_('Override the platform description with the provided value. ' +
'The default description is the kernel name (Linux).'));
o.placeholder = 'System platform description';
// Management addresses of this system
o = s.taboption(tab, form.Value, 'lldp_mgmt_ip',
_('Management addresses of this system'),
_('Specify the management addresses of this system. ' +
'If not specified, the first IPv4 and the first ' +
'IPv6 are used. If an exact IP address is provided, it is used ' +
'as a management address without any check. If you want to ' +
'blacklist IPv6 addresses, you can use <code>!*:*</code>. ' +
'See more details about available patterns ' +
'<a href=\"https://vincentbernat.github.io/lldpd/usage.html\">here</a>.'));
o.placeholder = 'Management addresses';
// LLDP tx interval
o = s.taboption(tab, form.Value, 'lldp_tx_interval',
_('Transmit delay'),
_('The transmit delay is the delay between two ' +
'transmissions of LLDP PDU. The default value ' +
'is 30 seconds.'));
o.datatype = 'uinteger';
o.default = 30;
o.placeholder = 30;
o.rmempty = false;
o.validate = function(section_id, value) {
if (value != parseInt(value))
return _('Must be a number');
else if (value <= 0)
return _('Transmit delay must be greater than 0');
return true;
};
// LLDP tx hold
o = s.taboption(tab, form.Value, 'lldp_tx_hold',
_('Transmit hold value'),
_('This value is used to compute the TTL of transmitted ' +
'packets which is the product of this value and of the ' +
'transmit delay. The default value is 4 and therefore ' +
'the default TTL is 120 seconds.'));
o.datatype = 'uinteger';
o.default = 4;
o.placeholder = 4;
o.rmempty = false;
o.validate = function(section_id, value) {
if (value != parseInt(value))
return _('Must be a number');
else if (value <= 0)
return _('Transmit hold value must be greater than 0');
return true;
};
// Received-only mode (-r)
o = s.taboption(tab, form.Flag, 'readonly_mode',
_('Enable receive-only mode'),
_('With this option, LLDPd will not send any frames. ' +
'It will only listen to neighbors.'));
o.rmempty = false;
o.optional = false;
o.default = '0';
},
// -----------------------------------------------------------------------------------------
//
// Network Interfaces
//
// -----------------------------------------------------------------------------------------
/** @private */
populateIfacesOptions: function(s, tab, data) {
var o;
// Interfaces to listen on
o = s.taboption(tab, widgets.DeviceSelect, 'interface',
_('Network interfaces'),
_('Specify which interface to listen and send LLDPDU to. ' +
'If no interfaces is specified, LLDPd will use all available physical interfaces.'));
o.nobridges = true;
o.rmempty = true;
o.multiple = true;
o.nocreate = true;
o.noaliases = true;
o.networks = null;
// ChassisID interfaces
o = s.taboption(tab, widgets.DeviceSelect, 'cid_interface',
_('Network interfaces for chassis ID computing'),
_('Specify which interfaces to use for computing chassis ID. ' +
'If no interfaces is specified, all interfaces are considered. ' +
'LLDPd will take the first MAC address from all the considered ' +
'interfaces to compute the chassis ID.'));
o.nobridges = false;
o.rmempty = true;
o.multiple = true;
o.nocreate = true;
o.noaliases = true;
o.networks = null;
},
// -----------------------------------------------------------------------------------------
//
// Advanced Options
//
// -----------------------------------------------------------------------------------------
/** @private */
populateAdvancedOptions: function(s, tab, data) {
var o;
// SNMP agentX socket
// **Note**: lldpd is compiled in OpenWrt without SNMP support by default. Setting this action will then cause the lldpd daemon to stop starting and thus lldpd will stop working. To fix this, the value must then be deleted and lldpd restarted.
// o = s.taboption(tab, form.Value, 'agentxsocket',
// _('SNMP agentX socket path'),
// _('If the path to the socket is set, then LLDPd will enable an ' +
// 'SNMP subagent using AgentX protocol. This allows you to get ' +
// 'information about local system and remote systems through SNMP.'));
// o.rmempty = true;
// o.placeholder = '/var/run/agentx.sock';
// o.default = '';
// LLDP class
o = s.taboption(tab, form.ListValue, 'lldp_class',
_('LLDP-MED device class'));
o.value('1', _('Generic Endpoint (Class I)'));
o.value('2', _('Media Endpoint (Class II)'));
o.value('3', _('Communication Device Endpoints (Class III)'));
o.value('4', _('Network Connectivity Device (Class IV)'));
o.default = '4';
// LLDP-MED inventory TLV transmission (-i)
o = s.taboption(tab, form.Flag, 'lldpmed_no_inventory',
_('Disable LLDP-MED inventory TLV transmission'),
_('LLDPd will still receive (and publish using SNMP if enabled) ' +
'those LLDP-MED TLV but will not send them. Use this option ' +
'if you don\'t want to transmit sensible information like serial numbers.'));
o.default = '0';
// Disable advertising of kernel release, version and machine. (-k)
o = s.taboption(tab, form.Flag, 'lldp_no_version',
_('Disable advertising of kernel release, version and machine'),
_('Kernel name (ie: Linux) will still be shared, and Inventory ' +
'software version will be set to \'Unknown\'.'));
o.default = '0';
// Filter neighbors (-H)
o = s.taboption(tab, lldpd.cbiFilterSelect, 'filter',
_('Specify the behaviour when detecting multiple neighbors'),
_('The default filter is 15. For more details see \"FILTERING NEIGHBORS\" section ' +
'<a href=\"https://vincentbernat.github.io/lldpd/usage.html\">here</a>.'));
o.default = 15;
// Force port ID subtype
o = s.taboption(tab, form.ListValue, 'lldp_portidsubtype',
_('Force port ID subtype'),
_('With this option, you can force the port identifier ' +
'to be the interface name or the MAC address.'));
o.value('macaddress', _('Interface MAC address'));
o.value('ifname', _('Interface name'));
o.default = 'macaddress';
// The destination MAC address used to send LLDPDU
o = s.taboption(tab, form.ListValue, 'lldp_agenttype',
_('The destination MAC address used to send LLDPDU'),
_('The destination MAC address used to send LLDPDU allows an agent ' +
'to control the propagation of LLDPDUs. By default, the ' +
'<code>01:80:c2:00:00:0e</code> MAC address is used and limit the propagation ' +
'of the LLDPDU to the nearest bridge.'));
o.value('nearest-bridge', '01:80:c2:00:00:0e (nearest-bridge)');
o.value('nearest-nontpmr-bridge', '01:80:c2:00:00:03 (nearest-nontpmr-bridge)');
o.value('nearest-customer-bridge', '01:80:c2:00:00:00 (nearest-customer-bridge)');
o.default = 'nearest-bridge';
},
// -----------------------------------------------------------------------------------------
//
// Protocols Support
//
// -----------------------------------------------------------------------------------------
/** @private */
populateProtocolsOptions: function(s, tab, data) {
var o;
o = s.taboption(tab, form.SectionValue, '_protocols', form.TypedSection, 'lldpd');
var ss = o.subsection;
ss.anonymous = true;
ss.addremove = false;
//
// LLDPD
// Link Layer Discovery Protocol
//
ss.tab('lldp', _('LLDP'));
o = ss.taboption('lldp', form.Flag, 'enable_lldp',
_('Enable LLDP'));
o.default = '1';
o.rmempty = true;
o = ss.taboption('lldp', form.Flag, 'force_lldp',
_('Force to send LLDP packets'),
_('Force to send LLDP packets even when there is no LLDP peer ' +
'detected but there is a peer speaking another protocol detected. ' +
'By default, LLDP packets are sent when there is a peer speaking ' +
'LLDP detected or when there is no peer at all.'));
o.default = '0';
o.rmempty = true;
o.depends('enable_lldp', '1');
//
// CDP
// Cisco Discovery Protocol
//
ss.tab('cdp', _('CDP'));
o = ss.taboption('cdp', form.Flag, 'enable_cdp',
_('Enable CDP'),
_('Enable the support of CDP protocol to deal with Cisco routers ' +
'that do not speak LLDP'));
o.default = '1';
o.rmempty = false;
o = ss.taboption('cdp', form.ListValue, 'cdp_version',
_('CDP version'));
o.value('cdpv1v2', _('CDPv1 and CDPv2'));
o.value('cdpv2', _('Only CDPv2'));
o.depends('enable_cdp', '1');
o.default = 'cdpv1v2';
o = ss.taboption('cdp', form.Flag, 'force_cdp',
_('Send CDP packets even if no CDP peer detected'));
o.default = '0';
o.rmempty = true;
o.depends('enable_cdp', '1');
o = ss.taboption('cdp', form.Flag, 'force_cdpv2',
_('Force sending CDPv2 packets'));
o.default = '0';
o.rmempty = true;
o.depends({
force_cdp: '1',
enable_cdp: '1',
cdp_version: 'cdpv1v2'
});
//
// FDP
// Foundry Discovery Protocol
//
ss.tab('fdp', _('FDP'));
o = ss.taboption('fdp', form.Flag, 'enable_fdp',
_('Enable FDP'),
_('Enable the support of FDP protocol to deal with Foundry routers ' +
'that do not speak LLDP'));
o.default = '1';
o.rmempty = false;
o = ss.taboption('fdp', form.Flag, 'force_fdp',
_('Send FDP packets even if no FDP peer detected'));
o.default = '0';
o.rmempty = true;
o.depends('enable_fdp', '1');
//
// EDP
// Extreme Discovery Protocol
//
ss.tab('edp', _('EDP'));
o = ss.taboption('edp', form.Flag, 'enable_edp',
_('Enable EDP'),
_('Enable the support of EDP protocol to deal with Extreme routers ' +
'and switches that do not speak LLDP.'));
o.default = '1';
o.rmempty = false;
o = ss.taboption('edp', form.Flag, 'force_edp',
_('Send EDP packets even if no EDP peer detected'));
o.default = '0';
o.rmempty = true;
o.depends('enable_edp', '1');
//
// SONMP
// SynOptics Network Management Protocol
//
// a.k.a.
// Nortel Topology Discovery Protocol (NTDP)
// Nortel Discovery Protocol (NDP)
// Bay Network Management Protocol (BNMP)
// Bay Discovery Protocol (BDP)
//
ss.tab('sonmp', _('SONMP (NTDP, NDP, BNMP, BDP)'));
o = ss.taboption('sonmp', form.Flag, 'enable_sonmp',
_('Enable SONMP'),
_('Enable the support of SONMP protocol to deal with Nortel ' +
'routers and switches that do not speak LLDP.'));
o.default = '1';
o.rmempty = false;
o = ss.taboption('sonmp', form.Flag, 'force_sonmp',
_('Send SONMP packets even if no SONMP peer detected'));
o.default = '0';
o.rmempty = true;
o.depends('enable_sonmp', '1');
},
/** @private */
populateOptions: function(s, data) {
var o;
s.tab('basic', _('Basic Settings'));
this.populateBasicOptions(s, 'basic', data);
s.tab('ifaces', _('Network Interfaces'));
this.populateIfacesOptions(s, 'ifaces', data);
s.tab('advanced', _('Advanced Settings'));
this.populateAdvancedOptions(s, 'advanced', data);
s.tab('protocols', _('Protocols Support'));
this.populateProtocolsOptions(s, 'protocols', data);
},
render: function(data) {
var m, s;
m = new form.Map('lldpd', _('LLDPd Settings'),
_('LLDPd is a implementation of IEEE 802.1ab ' +
'(<abbr title=\"Link Layer Discovery Protocol\">LLDP</abbr>).') +
_('On this page you may configure LLDPd parameters.'));
s = m.section(form.TypedSection, 'lldpd');
s.addremove = false;
s.anonymous = true;
this.populateOptions(s, data);
return m.render();
},
});

View File

@@ -0,0 +1,711 @@
/*
* Copyright (c) 2020 Tano Systems. All Rights Reserved.
* Author: Anton Kikin <a.kikin@tano-systems.com>
*/
'use strict';
'require rpc';
'require form';
'require lldpd';
'require dom';
'require poll';
var callLLDPStatus = rpc.declare({
object: 'lldpd',
method: 'getStatus',
expect: {}
});
var dataMap = {
local: {
localChassis: null,
},
remote: {
neightbors: null,
statistics: null,
},
};
return L.view.extend({
__init__: function() {
this.super('__init__', arguments);
this.rowsUnfolded = {};
this.tableNeighbors = E('div', { 'class': 'table lldpd-table' }, [
E('div', { 'class': 'tr table-titles' }, [
E('div', { 'class': 'th left top' }, _('Local interface')),
E('div', { 'class': 'th left top' }, _('Protocol')),
E('div', { 'class': 'th left top' }, _('Discovered chassis')),
E('div', { 'class': 'th left top' }, _('Discovered port')),
]),
E('div', { 'class': 'tr center placeholder' }, [
E('div', { 'class': 'td' }, E('em', { 'class': 'spinning' },
_('Collecting data...'))),
])
]);
this.tableStatistics = E('div', { 'class': 'table lldpd-table' }, [
E('div', { 'class': 'tr table-titles' }, [
E('div', { 'class': 'th left top' }, _('Local interface')),
E('div', { 'class': 'th left top' }, _('Protocol')),
E('div', { 'class': 'th left top' }, _('Administrative Status')),
E('div', { 'class': 'th right top' }, _('Tx')),
E('div', { 'class': 'th right top' }, _('Rx')),
E('div', { 'class': 'th right top' }, _('Tx discarded')),
E('div', { 'class': 'th right top' }, _('Rx unrecognized')),
E('div', { 'class': 'th right top' }, _('Ageout count')),
E('div', { 'class': 'th right top' }, _('Insert count')),
E('div', { 'class': 'th right top' }, _('Delete count')),
]),
E('div', { 'class': 'tr center placeholder' }, [
E('div', { 'class': 'td' }, E('em', { 'class': 'spinning' },
_('Collecting data...'))),
])
]);
// Inject CSS
var head = document.getElementsByTagName('head')[0];
var css = E('link', { 'href':
L.resource('lldpd/lldpd.css')
+ '?v=#PKG_VERSION', 'rel': 'stylesheet' });
head.appendChild(css);
},
load: function() {
return Promise.all([
L.resolveDefault(callLLDPStatus(), {}),
lldpd.init(),
]);
},
/** @private */
renderParam: function(param, value) {
if (typeof value === 'undefined')
return '';
return E('div', {}, [
E('span', { 'class': 'lldpd-param' }, param),
E('span', { 'class': 'lldpd-param-value' }, value)
]);
},
/** @private */
renderAge: function(v) {
if (typeof v === 'undefined')
return "&#8211;";
return E('nobr', {}, v);
},
/** @private */
renderIdType: function(v) {
if (typeof v === 'undefined')
return "&#8211;";
if (v == 'mac')
return _('MAC address');
else if (v == 'ifname')
return _('Interface name');
else if (v == 'local')
return _('Local ID');
else if (v == 'ip')
return _('IP address');
return v;
},
/** @private */
renderProtocol: function(v) {
if (typeof v === 'undefined' || v == 'unknown')
return "&#8211;";
if (v == 'LLDP')
return E('span', { 'class': 'lldpd-protocol-badge lldpd-protocol-lldp' }, v);
else if ((v == 'CDPv1') || (v == 'CDPv2'))
return E('span', { 'class': 'lldpd-protocol-badge lldpd-protocol-cdp' }, v);
else if (v == 'FDP')
return E('span', { 'class': 'lldpd-protocol-badge lldpd-protocol-fdp' }, v);
else if (v == 'EDP')
return E('span', { 'class': 'lldpd-protocol-badge lldpd-protocol-edp' }, v);
else if (v == 'SONMP')
return E('span', { 'class': 'lldpd-protocol-badge lldpd-protocol-sonmp' }, v);
else
return E('span', { 'class': 'lldpd-protocol-badge' }, v);
},
/** @private */
renderAdminStatus: function(status) {
if ((typeof status === 'undefined') || !Array.isArray(status))
return '&#8211;';
if (status[0].value === 'RX and TX')
return _('Rx and Tx');
else if (status[0].value === 'RX only')
return _('Rx only');
else if (status[0].value === 'TX only')
return _('Tx only');
else if (status[0].value === 'disabled')
return _('Disabled');
else
return _('Unknown');
},
/** @private */
renderNumber: function(v) {
if (parseInt(v))
return v;
return '&#8211;';
},
/** @private */
renderPort: function(port) {
if (typeof port.port !== 'undefined')
{
if (typeof port.port[0].descr !== 'undefined' &&
typeof port.port[0].id[0].value !== 'undefined' &&
port.port[0].descr[0].value !== port.port[0].id[0].value)
{
return [
E('strong', {}, port.port[0].descr[0].value),
E('br', {}),
port.port[0].id[0].value
];
}
else
{
if (typeof port.port[0].descr !== 'undefined')
return port.port[0].descr[0].value;
else
return port.port[0].id[0].value;
}
}
else
{
return '%s'.format(port.name);
}
},
/** @private */
renderPortParamTableShort: function(port) {
var items = [];
items.push(this.renderParam(_('Name'), port.name));
items.push(this.renderParam(_('Age'), this.renderAge(port.age)));
return E('div', { 'class': 'lldpd-params' }, items);
},
/** @private */
renderPortParamTable: function(port, only_id_and_ttl) {
var items = [];
if (!only_id_and_ttl) {
items.push(this.renderParam(_('Name'), port.name));
items.push(this.renderParam(_('Age'), this.renderAge(port.age)));
}
if (typeof port.port !== 'undefined')
{
if (typeof port.port[0].id !== 'undefined')
{
items.push(this.renderParam(_('Port ID'),
port.port[0].id[0].value));
items.push(this.renderParam(_('Port ID type'),
this.renderIdType(port.port[0].id[0].type)));
}
if (typeof port.port[0].descr !== 'undefined')
items.push(this.renderParam(_('Port description'),
port.port[0].descr[0].value));
if (typeof port.ttl !== 'undefined')
items.push(this.renderParam(_('TTL'), port.ttl[0].ttl));
else if (port.port[0].ttl !== 'undefined')
items.push(this.renderParam(_('TTL'), port.port[0].ttl[0].value));
if (typeof port.port[0].mfs !== 'undefined')
items.push(this.renderParam(_('MFS'), port.port[0].mfs[0].value));
}
return E('div', { 'class': 'lldpd-params' }, items);
},
/** @private */
renderChassis: function(ch) {
if (typeof ch.name !== 'undefined' &&
typeof ch.descr !== 'undefined' &&
typeof ch.name[0].value !== 'undefined' &&
typeof ch.descr[0].value !== 'undefined')
{
return [
E('strong', {}, ch.name[0].value),
E('br', {}),
ch.descr[0].value
];
}
else if (typeof ch.name !== 'undefined' &&
typeof ch.name[0].value !== 'undefined')
return E('strong', {}, ch.name[0].value);
else if (typeof ch.descr !== 'undefined' &&
typeof ch.descr[0].value !== 'undefined')
return ch.descr[0].value;
else if (typeof ch.id !== 'undefined' &&
typeof ch.id[0].value !== 'undefined')
return ch.id[0].value;
else
return _('Unknown');
},
/** @private */
renderChassisParamTable: function(ch) {
var items = [];
if (typeof ch.name !== 'undefined')
items.push(this.renderParam(_('Name'), ch.name[0].value));
if (typeof ch.descr !== 'undefined')
items.push(this.renderParam(_('Description'), ch.descr[0].value));
if (typeof ch.id !== 'undefined') {
items.push(this.renderParam(_('ID'), ch.id[0].value));
items.push(this.renderParam(_('ID type'),
this.renderIdType(ch.id[0].type)));
}
// Management addresses
if (typeof ch['mgmt-ip'] !== 'undefined') {
var ips = '';
if (ch['mgmt-ip'].length > 0) {
// Array of addresses
for (var ip = 0; ip < ch["mgmt-ip"].length; ip++)
ips += ch['mgmt-ip'][ip].value + '<br />';
}
else {
// One address
ips += ch['mgmt-ip'][0].value;
}
items.push(this.renderParam(_('Management IP(s)'), ips));
}
if (typeof ch.capability !== 'undefined') {
var caps = '';
if (ch.capability.length > 0)
{
// Array of capabilities
for (var cap = 0; cap < ch.capability.length; cap++) {
caps += ch.capability[cap].type;
caps += ' (' + (ch.capability[cap].enabled
? _('enabled') : _('disabled')) + ')';
caps += '<br />';
}
}
else
{
// One capability
caps += ch.capability[0].type;
caps += ' (' + (ch.capability[0].enabled
? _('enabled') : _('disabled')) + ')';
}
items.push(this.renderParam(_('Capabilities'), caps));
}
return E('div', { 'class': 'lldpd-params' }, items);
},
/** @private */
getFoldingImage: function(unfolded) {
return L.resource('lldpd/details_' +
(unfolded ? 'hide' : 'show') + '.svg');
},
/** @private */
generateRowId: function(str) {
return str.replace(/[^a-z0-9]/gi, '-');
},
/** @private */
handleToggleFoldingRow: function(row, row_id) {
var e_img = row.querySelector('img');
var e_folded = row.querySelectorAll('.lldpd-folded');
var e_unfolded = row.querySelectorAll('.lldpd-unfolded');
if (e_folded.length != e_unfolded.length)
return;
var do_unfold = (e_folded[0].style.display !== 'none');
this.rowsUnfolded[row_id] = do_unfold;
for (var i = 0; i < e_folded.length; i++)
{
if (do_unfold)
{
e_folded[i].style.display = 'none';
e_unfolded[i].style.display = 'block';
}
else
{
e_folded[i].style.display = 'block';
e_unfolded[i].style.display = 'none';
}
}
e_img.src = this.getFoldingImage(do_unfold);
},
/** @private */
makeFoldingTableRow: function(row, unfolded) {
//
// row[0] - row id
// row[1] - contents for first cell in row
// row[2] - contents for second cell in row
// ...
// row[N] - contents for N-th cell in row
//
if (row.length < 2)
return row;
for (let i = 1; i < row.length; i++) {
if (i == 1) {
// Fold/unfold image appears only in first column
var dImg = E('div', { 'style': 'padding: 0 8px 0 0;' }, [
E('img', { 'width': '16px', 'src': this.getFoldingImage(unfolded) }),
]);
}
if (Array.isArray(row[i])) {
// row[i][0] = folded contents
// row[i][1] = unfolded contents
// Folded cell data
let dFolded = E('div', {
'class': 'lldpd-folded',
'style': unfolded ? 'display: none;' : 'display: block;'
}, row[i][0]);
// Unfolded cell data
let dUnfolded = E('div', {
'class': 'lldpd-unfolded',
'style': unfolded ? 'display: block;' : 'display: none;'
}, row[i][1]);
if (i == 1) {
row[i] = E('div', {
'style': 'display: flex; flex-wrap: nowrap;'
}, [ dImg, dFolded, dUnfolded ]);
}
else {
row[i] = E('div', {}, [ dFolded, dUnfolded ]);
}
}
else {
// row[i] = same content for folded and unfolded states
if (i == 1) {
row[i] = E('div', {
'style': 'display: flex; flex-wrap: nowrap;'
}, [ dImg, E('div', row[i]) ]);
}
}
}
return row;
},
/** @private */
makeNeighborsTableRow: function(obj) {
if (typeof obj === 'undefined')
obj.name = 'Unknown';
var new_id = obj.name + '-' + obj.rid;
if (typeof obj.port !== 'undefined') {
if (typeof obj.port[0].id !== 'undefined')
new_id += "-" + obj.port[0].id[0].value;
if (typeof obj.port[0].descr !== 'undefined')
new_id += "-" + obj.port[0].descr[0].value;
}
var row_id = this.generateRowId(new_id);
return this.makeFoldingTableRow([
row_id,
[
'%s'.format(obj.name),
this.renderPortParamTableShort(obj)
],
this.renderProtocol(obj.via),
[
this.renderChassis(obj.chassis[0]),
this.renderChassisParamTable(obj.chassis[0])
],
[
this.renderPort(obj),
this.renderPortParamTable(obj, true)
]
], this.rowsUnfolded[row_id] || false);
},
/** @private */
renderInterfaceProtocols: function(iface, neighbors) {
if ((typeof iface === 'undefined') ||
(typeof neighbors == 'undefined') ||
(typeof neighbors.lldp[0] === 'undefined') ||
(typeof neighbors.lldp[0].interface === 'undefined'))
return "&#8211;";
var name = iface.name;
var protocols = [];
/* Search protocols for interface <name> */
neighbors.lldp[0].interface.forEach(function(n) {
if (n.name !== name)
return;
protocols.push(this.renderProtocol(n.via));
}.bind(this));
if (protocols.length > 0)
return E('span', {}, protocols);
else
return "&#8211;";
},
/** @private */
makeStatisticsTableRow: function(sobj, iobj, neighbors) {
var row_id = this.generateRowId(iobj.name);
return this.makeFoldingTableRow([
row_id,
[
this.renderPort(iobj), // folded
this.renderPortParamTable(iobj, false) // unfolded
],
this.renderInterfaceProtocols(iobj, neighbors),
this.renderAdminStatus(iobj.status),
this.renderNumber(sobj.tx[0].tx),
this.renderNumber(sobj.rx[0].rx),
this.renderNumber(sobj.rx_discarded_cnt[0].rx_discarded_cnt),
this.renderNumber(sobj.rx_unrecognized_cnt[0].rx_unrecognized_cnt),
this.renderNumber(sobj.ageout_cnt[0].ageout_cnt),
this.renderNumber(sobj.insert_cnt[0].insert_cnt),
this.renderNumber(sobj.delete_cnt[0].delete_cnt)
], this.rowsUnfolded[row_id] || false);
},
/** @private */
updateTable: function(table, data, placeholder) {
var target = isElem(table) ? table : document.querySelector(table);
if (!isElem(target))
return;
target.querySelectorAll(
'.tr.table-titles, .cbi-section-table-titles').forEach(L.bind(function(thead) {
var titles = [];
thead.querySelectorAll('.th').forEach(function(th) {
titles.push(th);
});
if (Array.isArray(data)) {
var n = 0, rows = target.querySelectorAll('.tr');
data.forEach(L.bind(function(row) {
var id = row[0];
var trow = E('div', { 'class': 'tr', 'click': L.bind(function(ev) {
this.handleToggleFoldingRow(ev.currentTarget, id);
// lldpd_folding_toggle(ev.currentTarget, id);
}, this) });
for (var i = 0; i < titles.length; i++) {
var text = (titles[i].innerText || '').trim();
var td = trow.appendChild(E('div', {
'class': titles[i].className,
'data-title': (text !== '') ? text : null
}, row[i + 1] || ''));
td.classList.remove('th');
td.classList.add('td');
}
trow.classList.add('cbi-rowstyle-%d'.format((n++ % 2) ? 2 : 1));
if (rows[n])
target.replaceChild(trow, rows[n]);
else
target.appendChild(trow);
}, this));
while (rows[++n])
target.removeChild(rows[n]);
if (placeholder && target.firstElementChild === target.lastElementChild) {
var trow = target.appendChild(
E('div', { 'class': 'tr placeholder' }));
var td = trow.appendChild(
E('div', { 'class': 'center ' + titles[0].className }, placeholder));
td.classList.remove('th');
td.classList.add('td');
}
} else {
thead.parentNode.style.display = 'none';
thead.parentNode.querySelectorAll('.tr, .cbi-section-table-row').forEach(function(trow) {
if (trow !== thead) {
var n = 0;
trow.querySelectorAll('.th, .td').forEach(function(td) {
if (n < titles.length) {
var text = (titles[n++].innerText || '').trim();
if (text !== '')
td.setAttribute('data-title', text);
}
});
}
});
thead.parentNode.style.display = '';
}
}, this));
},
/** @private */
startPolling: function() {
poll.add(L.bind(function() {
return callLLDPStatus().then(L.bind(function(data) {
this.renderData(data);
}, this));
}, this));
},
/** @private */
renderDataLocalChassis: function(data) {
if (data &&
typeof data !== 'undefined' &&
typeof data['local-chassis'] !== 'undefined' &&
typeof data['local-chassis'][0].chassis[0].name !== 'undefined') {
return this.renderChassisParamTable(data['local-chassis'][0].chassis[0]);
}
else {
return E('div', { 'class': 'alert-message warning' },
_('No data to display'));
}
},
/** @private */
renderDataNeighbors: function(neighbors) {
var rows = [];
if (neighbors &&
typeof neighbors !== 'undefined' &&
typeof neighbors.lldp !== 'undefined')
{
var ifaces = neighbors.lldp[0].interface;
// Fill table rows
if (typeof ifaces !== 'undefined') {
for (i = 0; i < ifaces.length; i++)
rows.push(this.makeNeighborsTableRow(ifaces[i]));
}
}
return rows;
},
/** @private */
renderDataStatistics: function(statistics, interfaces, neighbors) {
var rows = [];
if (statistics &&
interfaces &&
typeof statistics !== 'undefined' &&
typeof interfaces !== 'undefined' &&
typeof statistics.lldp !== 'undefined' &&
typeof interfaces.lldp !== 'undefined')
{
var sifaces = statistics.lldp[0].interface;
var ifaces = interfaces.lldp[0].interface;
if ((typeof sifaces !== 'undefined') &&
(typeof ifaces !== 'undefined')) {
for (var i = 0; i < sifaces.length; i++)
rows.push(this.makeStatisticsTableRow(sifaces[i], ifaces[i], neighbors));
}
}
return rows;
},
/** @private */
renderData: function(data) {
var r;
r = this.renderDataLocalChassis(data.chassis);
dom.content(document.getElementById('lldpd-local-chassis'), r);
r = this.renderDataNeighbors(data.neighbors);
this.updateTable(this.tableNeighbors, r,
_('No data to display'));
r = this.renderDataStatistics(data.statistics, data.interfaces, data.neighbors);
this.updateTable(this.tableStatistics, r,
_('No data to display'));
},
render: function(data) {
var m, s, ss, o;
m = new form.JSONMap(dataMap,
_('LLDP Status'),
_('This page allows you to see discovered LLDP neighbors, ' +
'local interfaces statistics and local chassis information.'));
s = m.section(form.NamedSection, 'local', 'local',
_('Local Chassis'));
o = s.option(form.DummyValue, 'localChassis');
o.render = function() {
return E('div', { 'id': 'lldpd-local-chassis' }, [
E('em', { 'class': 'spinning' }, _('Collecting data...'))
]);
};
s = m.section(form.NamedSection, 'remote', 'remote');
s.tab('neighbors', _('Discovered Neighbors'));
s.tab('statistics', _('Interface Statistics'));
o = s.taboption('neighbors', form.DummyValue, 'neighbors');
o.render = L.bind(function() {
return E('div', { 'class': 'table-wrapper' }, [
this.tableNeighbors
]);
}, this);
o = s.taboption('statistics', form.DummyValue, 'statistics');
o.render = L.bind(function() {
return E('div', { 'class': 'table-wrapper' }, [
this.tableStatistics
]);
}, this);
return m.render().then(L.bind(function(rendered) {
this.startPolling();
return rendered;
}, this));
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});

View File

@@ -0,0 +1,629 @@
msgid ""
msgstr ""
"Project-Id-Version: luci-app-lldpd\n"
"PO-Revision-Date: 2021-04-06 15:55+0300\n"
"Last-Translator: Anton Kikin <a.kikin@tano-systems.com>\n"
"Language-Team: Tano Systems LLC\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n"
"%100<10 || n%100>=20) ? 1 : 2);\n"
"POT-Creation-Date: 2018-05-23 18:25+0300\n"
"X-Generator: Poedit 2.3\n"
#: htdocs/luci-static/resources/view/lldpd/status.js:52
msgid "Administrative Status"
msgstr "Административное состояние"
#: htdocs/luci-static/resources/view/lldpd/config.js:445
msgid "Advanced Settings"
msgstr "Дополнительные настройки"
#: htdocs/luci-static/resources/view/lldpd/status.js:196
#: htdocs/luci-static/resources/view/lldpd/status.js:207
msgid "Age"
msgstr "Возраст"
#: htdocs/luci-static/resources/view/lldpd/status.js:57
msgid "Ageout count"
msgstr "Устарело"
#: htdocs/luci-static/resources/view/lldpd/config.js:439
msgid "Basic Settings"
msgstr "Основные настройки"
#: htdocs/luci-static/resources/view/lldpd/config.js:332
msgid "CDP"
msgstr "CDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:342
msgid "CDP version"
msgstr "Версия протокола CDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:344
msgid "CDPv1 and CDPv2"
msgstr "CDPv1 и CDPv2"
#: htdocs/luci-static/resources/view/lldpd/status.js:317
msgid "Capabilities"
msgstr "Возможности"
#: htdocs/luci-static/resources/view/lldpd/status.js:44
#: htdocs/luci-static/resources/view/lldpd/status.js:63
#: htdocs/luci-static/resources/view/lldpd/status.js:682
msgid "Collecting data..."
msgstr "Сбор данных..."
#: htdocs/luci-static/resources/view/lldpd/config.js:243
msgid "Communication Device Endpoints (Class III)"
msgstr "Communication Device Endpoints (класс III)"
#: htdocs/luci-static/resources/view/lldpd/status.js:59
msgid "Delete count"
msgstr "Удалено"
#: htdocs/luci-static/resources/view/lldpd/status.js:271
msgid "Description"
msgstr "Описание"
#: htdocs/luci-static/resources/view/lldpd/config.js:250
msgid "Disable LLDP-MED inventory TLV transmission"
msgstr "Отключить отправку инвентарной информации LLDP-MED TLV"
#: htdocs/luci-static/resources/view/lldpd/status.js:150
msgid "Disabled"
msgstr "Отключено"
#: htdocs/luci-static/resources/view/lldpd/status.js:688
msgid "Discovered Neighbors"
msgstr "Обнаруженные соседи"
#: htdocs/luci-static/resources/view/lldpd/status.js:39
msgid "Discovered chassis"
msgstr "Обнаруженное шасси"
#: htdocs/luci-static/resources/view/lldpd/status.js:40
msgid "Discovered port"
msgstr "Обнаруженный порт"
#: htdocs/luci-static/resources/lldpd.js:117
msgid "E &mdash; enable filter"
msgstr "E &mdash; включить фильтр"
#: htdocs/luci-static/resources/view/lldpd/config.js:392
msgid "EDP"
msgstr "EDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:334
msgid "Enable CDP"
msgstr "Включить CDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:394
msgid "Enable EDP"
msgstr "Включить EDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:374
msgid "Enable FDP"
msgstr "Включить FDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:312
msgid "Enable LLDP"
msgstr "Включить LLDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:420
msgid "Enable SONMP"
msgstr "Включить SONMP"
#: htdocs/luci-static/resources/view/lldpd/config.js:168
msgid "Enable receive-only mode"
msgstr "Включить режим «только приём»"
#: htdocs/luci-static/resources/view/lldpd/config.js:65
msgid "Enable service"
msgstr "Включить службу"
#: htdocs/luci-static/resources/view/lldpd/config.js:335
msgid ""
"Enable the support of CDP protocol to deal with Cisco routers that do not "
"speak LLDP"
msgstr ""
"Включить поддержку протокола CDP для работы с маршрутизаторами Cisco, "
"которые не имеют поддержки LLDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:395
msgid ""
"Enable the support of EDP protocol to deal with Extreme routers and switches "
"that do not speak LLDP."
msgstr ""
"Включить поддержку протокола EDP для работы с маршрутизаторами и "
"коммутаторам Extreme, которые не имеют поддержки LLDP."
#: htdocs/luci-static/resources/view/lldpd/config.js:375
msgid ""
"Enable the support of FDP protocol to deal with Foundry routers that do not "
"speak LLDP"
msgstr ""
"Включить поддержку протокола FDP для работы с маршрутизаторами Foundry, "
"которые не имеют поддержки LLDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:421
msgid ""
"Enable the support of SONMP protocol to deal with Nortel routers and "
"switches that do not speak LLDP."
msgstr ""
"Включить поддержку протокола SONMP для работы с маршрутизаторами и "
"коммутаторами Nortel, которые не имеют поддержки LLDP."
#: htdocs/luci-static/resources/view/lldpd/config.js:372
msgid "FDP"
msgstr "FDP"
#: htdocs/luci-static/resources/lldpd.js:170
msgid "Filter"
msgstr "Фильтр"
#: htdocs/luci-static/resources/view/lldpd/config.js:267
msgid "Force port ID subtype"
msgstr "Использовать в качестве ID порта"
#: htdocs/luci-static/resources/view/lldpd/config.js:358
msgid "Force sending CDPv2 packets"
msgstr "Форсировать отправку CDPv2 пакетов"
#: htdocs/luci-static/resources/view/lldpd/config.js:318
msgid "Force to send LLDP packets"
msgstr "Форсировать отправку LLDP пакетов"
#: htdocs/luci-static/resources/view/lldpd/config.js:319
msgid ""
"Force to send LLDP packets even when there is no LLDP peer detected but "
"there is a peer speaking another protocol detected. By default, LLDP packets "
"are sent when there is a peer speaking LLDP detected or when there is no "
"peer at all."
msgstr ""
"Принудительно отправлять пакеты LLDP, даже если соседей с поддержкой LLDP не "
"обнаружено, но есть соседи, с поддержкой другого протокола. По умолчанию "
"пакеты LLDP отправляются, когда обнаружен сосед с поддержкой LLDP или когда "
"вообще нет обнаруженных соседей."
#: htdocs/luci-static/resources/view/lldpd/config.js:241
msgid "Generic Endpoint (Class I)"
msgstr "Generic Endpoint (класс I)"
#: root/usr/share/rpcd/acl.d/luci-app-lldpd.json:18
msgid "Grant access for LLDP configuration"
msgstr "Предоставить доступ к конфигурации LLDP"
#: root/usr/share/rpcd/acl.d/luci-app-lldpd.json:3
msgid "Grant access for LLDP status information"
msgstr "Предоставить доступ к информации о состоянии LLDP"
#: htdocs/luci-static/resources/view/lldpd/status.js:274
msgid "ID"
msgstr "ID"
#: htdocs/luci-static/resources/view/lldpd/status.js:275
msgid "ID type"
msgstr "Тип ID"
#: htdocs/luci-static/resources/view/lldpd/status.js:114
msgid "IP address"
msgstr "IP-адрес"
#: htdocs/luci-static/resources/view/lldpd/config.js:229
msgid ""
"If the path to the socket is set, then LLDPd will enable an SNMP subagent "
"using AgentX protocol. This allows you to get information about local system "
"and remote systems through SNMP."
msgstr ""
"Если указан путь к сокету, то LLDPd включит SNMP агент, используя протокол "
"AgentX. Это позволяет получать информацию о локальной системе и удаленных "
"системах через SNMP."
#: htdocs/luci-static/resources/lldpd.js:171
msgid "Incoming"
msgstr "Входящие"
#: htdocs/luci-static/resources/view/lldpd/status.js:58
msgid "Insert count"
msgstr "Обнаружено"
#: htdocs/luci-static/resources/view/lldpd/config.js:271
msgid "Interface MAC address"
msgstr "MAC-адрес интерфейса"
#: htdocs/luci-static/resources/view/lldpd/status.js:689
msgid "Interface Statistics"
msgstr "Статистика интерфейсов"
#: htdocs/luci-static/resources/view/lldpd/config.js:272
#: htdocs/luci-static/resources/view/lldpd/status.js:110
msgid "Interface name"
msgstr "Имя интерфейса"
#: htdocs/luci-static/resources/view/lldpd/config.js:310
#: root/usr/share/luci/menu.d/luci-app-lldpd.json:3
msgid "LLDP"
msgstr "LLDP"
#: htdocs/luci-static/resources/view/lldpd/status.js:672
msgid "LLDP Status"
msgstr "Состояние LLDP"
#: htdocs/luci-static/resources/view/lldpd/config.js:239
msgid "LLDP-MED device class"
msgstr "Класс устройства LLDP-MED"
#: htdocs/luci-static/resources/lldpd.js:19
msgid "LLDPd LuCI application (version %s)"
msgstr "LuCI приложение управления LLDPd (версия %s)"
#: htdocs/luci-static/resources/view/lldpd/config.js:455
msgid "LLDPd Settings"
msgstr "Настройки LLDPd"
#: htdocs/luci-static/resources/view/lldpd/config.js:456
msgid ""
"LLDPd is a implementation of IEEE 802.1ab (<abbr title=\"Link Layer "
"Discovery Protocol\">LLDP</abbr>)."
msgstr ""
"LLDPd это программная реализация стандарта IEEE 802.1ab (<abbr title=\"Link "
"Layer Discovery Protocol\">LLDP</abbr>)."
#: htdocs/luci-static/resources/view/lldpd/config.js:251
msgid ""
"LLDPd will still receive (and publish using SNMP if enabled) those LLDP-MED "
"TLV but will not send them. Use this option if you don't want to transmit "
"sensible information like serial numbers."
msgstr ""
"LLDPd будет по прежнему получать (и публиковать, используя SNMP, если он "
"включен) информацию LLDP-MED TLV, но не будет отправлять. Используйте эту "
"опцию, если вы не хотите передавать важную информацию, такую как серийные "
"номера."
#: htdocs/luci-static/resources/view/lldpd/status.js:677
msgid "Local Chassis"
msgstr "Локальное шасси"
#: htdocs/luci-static/resources/view/lldpd/status.js:112
msgid "Local ID"
msgstr "Локально заданный ID"
#: htdocs/luci-static/resources/view/lldpd/status.js:37
#: htdocs/luci-static/resources/view/lldpd/status.js:50
msgid "Local interface"
msgstr "Локальный интерфейс"
#: htdocs/luci-static/resources/view/lldpd/status.js:108
msgid "MAC address"
msgstr "MAC-адрес"
#: htdocs/luci-static/resources/view/lldpd/status.js:231
msgid "MFS"
msgstr "MFS"
#: htdocs/luci-static/resources/view/lldpd/status.js:293
msgid "Management IP(s)"
msgstr "IP-адреса"
#: htdocs/luci-static/resources/view/lldpd/config.js:114
msgid "Management addresses of this system"
msgstr "Адреса управления данной системы"
#: htdocs/luci-static/resources/view/lldpd/config.js:242
msgid "Media Endpoint (Class II)"
msgstr "Media Endpoint (класс II)"
#: htdocs/luci-static/resources/view/lldpd/config.js:139
#: htdocs/luci-static/resources/view/lldpd/config.js:160
msgid "Must be a number"
msgstr "Должно быть числом"
#: htdocs/luci-static/resources/lldpd.js:119
msgid "N &mdash; keep only one neighbor"
msgstr "N &mdash; хранить только одного соседа"
#: htdocs/luci-static/resources/view/lldpd/status.js:195
#: htdocs/luci-static/resources/view/lldpd/status.js:206
#: htdocs/luci-static/resources/view/lldpd/status.js:268
msgid "Name"
msgstr "Имя"
#: htdocs/luci-static/resources/view/lldpd/config.js:244
msgid "Network Connectivity Device (Class IV)"
msgstr "Network Connectivity Device (класс IV)"
#: htdocs/luci-static/resources/view/lldpd/config.js:442
msgid "Network Interfaces"
msgstr "Сетевые интерфейсы"
#: htdocs/luci-static/resources/view/lldpd/config.js:189
msgid "Network interfaces"
msgstr "Сетевые интерфейсы"
#: htdocs/luci-static/resources/view/lldpd/config.js:202
msgid "Network interfaces for chassis ID computing"
msgstr "Сетевые интерфейсы, используемые для вычисления ID шасси (chassis ID)"
#: htdocs/luci-static/resources/view/lldpd/status.js:604
#: htdocs/luci-static/resources/view/lldpd/status.js:661
#: htdocs/luci-static/resources/view/lldpd/status.js:665
msgid "No data to display"
msgstr "Нет данных для отображения"
#: htdocs/luci-static/resources/view/lldpd/config.js:458
msgid "On this page you may configure LLDPd parameters."
msgstr "На данной странице можно настроить параметры LLDPd."
#: htdocs/luci-static/resources/view/lldpd/config.js:345
msgid "Only CDPv2"
msgstr "Только CDPv2"
#: htdocs/luci-static/resources/lldpd.js:172
msgid "Outgoing"
msgstr "Исходящие"
#: htdocs/luci-static/resources/view/lldpd/config.js:93
msgid "Override system description with the provided description."
msgstr "Переопределить описание системы заданным значением."
#: htdocs/luci-static/resources/view/lldpd/config.js:100
msgid "Override system hostname with the provided value."
msgstr "Переопределить имя системы заданным значением."
#: htdocs/luci-static/resources/view/lldpd/config.js:107
msgid ""
"Override the platform description with the provided value. The default "
"description is the kernel name (Linux)."
msgstr ""
"Переопределить описание платформы заданным значением. По умолчанию "
"используется имя используемого ядра (Linux)."
#: htdocs/luci-static/resources/lldpd.js:118
msgid "P &mdash; keep only one protocol"
msgstr "P &mdash; хранить только один протокол"
#: htdocs/luci-static/resources/view/lldpd/status.js:214
msgid "Port ID"
msgstr "ID порта"
#: htdocs/luci-static/resources/view/lldpd/status.js:217
msgid "Port ID type"
msgstr "Тип ID порта"
#: htdocs/luci-static/resources/view/lldpd/status.js:222
msgid "Port description"
msgstr "Описание порта"
#: htdocs/luci-static/resources/view/lldpd/status.js:38
#: htdocs/luci-static/resources/view/lldpd/status.js:51
msgid "Protocol"
msgstr "Протокол"
#: htdocs/luci-static/resources/view/lldpd/config.js:448
msgid "Protocols Support"
msgstr "Поддержка протоколов"
#: htdocs/luci-static/resources/view/lldpd/status.js:54
msgid "Rx"
msgstr "Rx"
#: htdocs/luci-static/resources/view/lldpd/status.js:144
msgid "Rx and Tx"
msgstr "Rx и Tx"
#: htdocs/luci-static/resources/view/lldpd/status.js:146
msgid "Rx only"
msgstr "Только Rx"
#: htdocs/luci-static/resources/view/lldpd/status.js:56
msgid "Rx unrecognized"
msgstr "Rx (не распознано)"
#: htdocs/luci-static/resources/view/lldpd/config.js:228
msgid "SNMP agentX socket path"
msgstr "Путь к сокету SNMP agentX"
#: htdocs/luci-static/resources/view/lldpd/config.js:418
msgid "SONMP (NTDP, NDP, BNMP, BDP)"
msgstr "SONMP (NTDP, NDP, BNMP, BDP)"
#: htdocs/luci-static/resources/view/lldpd/config.js:351
msgid "Send CDP packets even if no CDP peer detected"
msgstr "Отправлять CDP пакеты даже если не обнаружено соседей с CDP протоколом"
#: htdocs/luci-static/resources/view/lldpd/config.js:402
msgid "Send EDP packets even if no EDP peer detected"
msgstr "Отправлять EDP пакеты даже если не обнаружено соседей с EDP протоколом"
#: htdocs/luci-static/resources/view/lldpd/config.js:382
msgid "Send FDP packets even if no FDP peer detected"
msgstr "Отправлять FDP пакеты даже если не обнаружено соседей с FDP протоколом"
#: htdocs/luci-static/resources/view/lldpd/config.js:428
msgid "Send SONMP packets even if no SONMP peer detected"
msgstr ""
"Отправлять SONMP пакеты даже если не обнаружено соседей с SONMP протоколом"
#: root/usr/share/luci/menu.d/luci-app-lldpd.json:28
msgid "Settings"
msgstr "Настройки"
#: htdocs/luci-static/resources/view/lldpd/config.js:259
msgid "Specify the behaviour when detecting multiple neighbors"
msgstr "Поведение при обнаружении нескольких соседей"
#: htdocs/luci-static/resources/view/lldpd/config.js:115
msgid ""
"Specify the management addresses of this system. If not specified, the first "
"IPv4 and the first IPv6 are used. If an exact IP address is provided, it is "
"used as a management address without any check. If you want to blacklist "
"IPv6 addresses, you can use <code>!*:*</code>. See more details about "
"available patterns <a href=\"https://vincentbernat.github.io/lldpd/usage.html"
"\">here</a>."
msgstr ""
"Адреса управления данной системой. Если не указано, используется первый IPv4 "
"и первый IPv6 адреса. Если указан конкретный IP-адрес, он будет использован "
"как адрес управления без какой-либо проверки. Если вы хотите занести в "
"черный список IPv6-адреса, вы можете использовать шаблон <code>! *: *</"
"code>. Подробнее о доступных шаблонах читайте <a href=\"https://"
"vincentbernat.github.io/lldpd/usage.html\">здесь</a>."
#: htdocs/luci-static/resources/view/lldpd/config.js:190
msgid ""
"Specify which interface to listen and send LLDPDU to. If no interfaces is "
"specified, LLDPd will use all available physical interfaces."
msgstr ""
"Укажите какие интерфейсы должны прослушивать и отправлять LLDPDU. Если "
"интерфейсы не указаны, LLDPd будет использовать все доступные физические "
"интерфейсы."
#: htdocs/luci-static/resources/view/lldpd/config.js:203
msgid ""
"Specify which interfaces to use for computing chassis ID. If no interfaces "
"is specified, all interfaces are considered. LLDPd will take the first MAC "
"address from all the considered interfaces to compute the chassis ID."
msgstr ""
"Укажите какие интерфейсы необходимо использовать для вычисления "
"идентификатора шасси (chassis ID). Если интерфейсы не указаны, будут "
"иcпользованы все интерфейсы. LLDPd получит первый MAC-адрес из всех "
"доступных интерфейсов для вычисления ID шасси."
#: root/usr/share/luci/menu.d/luci-app-lldpd.json:16
msgid "Status"
msgstr "Состояние"
#: htdocs/luci-static/resources/view/lldpd/config.js:92
msgid "System description"
msgstr "Описание системы"
#: htdocs/luci-static/resources/view/lldpd/config.js:99
msgid "System hostname"
msgstr "Имя системы"
#: htdocs/luci-static/resources/view/lldpd/config.js:106
msgid "System platform description"
msgstr "Описание платформы"
#: htdocs/luci-static/resources/view/lldpd/status.js:226
#: htdocs/luci-static/resources/view/lldpd/status.js:228
msgid "TTL"
msgstr "TTL"
#: htdocs/luci-static/resources/view/lldpd/config.js:260
msgid ""
"The default filter is 15. For more details see \"FILTERING NEIGHBORS\" "
"section <a href=\"https://vincentbernat.github.io/lldpd/usage.html\">here</"
"a>."
msgstr ""
"По умолчанию используется фильтр 15. Более подробную информацию о данной "
"опции можно посмотреть в разделе «FILTERING NEIGHBORS» <a href=\"https://"
"vincentbernat.github.io/lldpd/usage.html\">здесь</a>."
#: htdocs/luci-static/resources/view/lldpd/config.js:278
msgid "The destination MAC address used to send LLDPDU"
msgstr "MAC-адрес назначения, используемый для отправки LLDPDU"
#: htdocs/luci-static/resources/view/lldpd/config.js:279
msgid ""
"The destination MAC address used to send LLDPDU allows an agent to control "
"the propagation of LLDPDUs. By default, the <code>01:80:c2:00:00:0e</code> "
"MAC address is used and limit the propagation of the LLDPDU to the nearest "
"bridge."
msgstr ""
"MAC-адрес назначения, используемый для отправки LLDPDU. Данный параметр "
"позволяет агенту контролировать распространение LLDPDU. По умолчанию "
"используется MAC-адрес <code>01:80:c2:00:00:0e</code> и ограничивает "
"распространение LLDPDU до ближайшего моста."
#: htdocs/luci-static/resources/view/lldpd/config.js:128
msgid ""
"The transmit delay is the delay between two transmissions of LLDP PDU. The "
"default value is 30 seconds."
msgstr ""
"Задержка между двумя передачами LLDP PDU. Значение по умолчанию составляет "
"30 секунд."
#: htdocs/luci-static/resources/view/lldpd/status.js:673
msgid ""
"This page allows you to see discovered LLDP neighbors, local interfaces "
"statistics and local chassis information."
msgstr ""
"На данной странице вы можете посмотреть таблицу обнаруженных соседей LLDP, "
"статистику локальных интерфейсов и информацию о локальном шасси."
#: htdocs/luci-static/resources/view/lldpd/config.js:148
msgid ""
"This value is used to compute the TTL of transmitted packets which is the "
"product of this value and of the transmit delay. The default value is 4 and "
"therefore the default TTL is 120 seconds."
msgstr ""
"Это значение используется для вычисления TTL переданных пакетов, которое "
"является произведением этого значения и задержки передачи. Значение по "
"умолчанию равно 4. Соответственно, значение TTL по умолчанию составляет 120 "
"секунд."
#: htdocs/luci-static/resources/view/lldpd/config.js:127
msgid "Transmit delay"
msgstr "Задержка отправки"
#: htdocs/luci-static/resources/view/lldpd/config.js:141
msgid "Transmit delay must be greater than 0"
msgstr "Значение задержки отправки должно быть больше 0"
#: htdocs/luci-static/resources/view/lldpd/config.js:147
msgid "Transmit hold value"
msgstr "Значение «transmit hold»"
#: htdocs/luci-static/resources/view/lldpd/config.js:162
msgid "Transmit hold value must be greater than 0"
msgstr "Значение «transmit hold» должно быть больше 0"
#: htdocs/luci-static/resources/view/lldpd/status.js:53
msgid "Tx"
msgstr "Tx"
#: htdocs/luci-static/resources/view/lldpd/status.js:55
msgid "Tx discarded"
msgstr "Tx (отброшено)"
#: htdocs/luci-static/resources/view/lldpd/status.js:148
msgid "Tx only"
msgstr "Только Tx"
#: htdocs/luci-static/resources/view/lldpd/status.js:152
#: htdocs/luci-static/resources/view/lldpd/status.js:260
msgid "Unknown"
msgstr "Неизвестно"
#: htdocs/luci-static/resources/view/lldpd/config.js:169
msgid ""
"With this option, LLDPd will not send any frames. It will only listen to "
"neighbors."
msgstr ""
"С этой опцией LLDPd не будет отправлять какие-либо пакеты. LLDPd будет "
"только прослушивать сеть для обнаружения соседей."
#: htdocs/luci-static/resources/view/lldpd/config.js:268
msgid ""
"With this option, you can force the port identifier to be the interface name "
"or the MAC address."
msgstr ""
"Данная настройка позволяет принудительно использовать в качестве "
"идентификатор порта имя интерфейса или MAC-адрес."
#: htdocs/luci-static/resources/view/lldpd/status.js:305
#: htdocs/luci-static/resources/view/lldpd/status.js:314
msgid "disabled"
msgstr "выключено"
#: htdocs/luci-static/resources/view/lldpd/status.js:305
#: htdocs/luci-static/resources/view/lldpd/status.js:314
msgid "enabled"
msgstr "включено"
#: htdocs/luci-static/resources/lldpd.js:21
msgid "© 20182021, Tano Systems LLC, Anton Kikin"
msgstr "© 20182021, ООО «Тано Системс», Антон Кикин"

View File

@@ -0,0 +1,561 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
#: htdocs/luci-static/resources/view/lldpd/status.js:52
msgid "Administrative Status"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:445
msgid "Advanced Settings"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:196
#: htdocs/luci-static/resources/view/lldpd/status.js:207
msgid "Age"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:57
msgid "Ageout count"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:439
msgid "Basic Settings"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:332
msgid "CDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:342
msgid "CDP version"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:344
msgid "CDPv1 and CDPv2"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:317
msgid "Capabilities"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:44
#: htdocs/luci-static/resources/view/lldpd/status.js:63
#: htdocs/luci-static/resources/view/lldpd/status.js:682
msgid "Collecting data..."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:243
msgid "Communication Device Endpoints (Class III)"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:59
msgid "Delete count"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:271
msgid "Description"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:250
msgid "Disable LLDP-MED inventory TLV transmission"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:150
msgid "Disabled"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:688
msgid "Discovered Neighbors"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:39
msgid "Discovered chassis"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:40
msgid "Discovered port"
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:117
msgid "E &mdash; enable filter"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:392
msgid "EDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:334
msgid "Enable CDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:394
msgid "Enable EDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:374
msgid "Enable FDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:312
msgid "Enable LLDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:420
msgid "Enable SONMP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:168
msgid "Enable receive-only mode"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:65
msgid "Enable service"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:335
msgid ""
"Enable the support of CDP protocol to deal with Cisco routers that do not "
"speak LLDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:395
msgid ""
"Enable the support of EDP protocol to deal with Extreme routers and switches "
"that do not speak LLDP."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:375
msgid ""
"Enable the support of FDP protocol to deal with Foundry routers that do not "
"speak LLDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:421
msgid ""
"Enable the support of SONMP protocol to deal with Nortel routers and "
"switches that do not speak LLDP."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:372
msgid "FDP"
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:170
msgid "Filter"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:267
msgid "Force port ID subtype"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:358
msgid "Force sending CDPv2 packets"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:318
msgid "Force to send LLDP packets"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:319
msgid ""
"Force to send LLDP packets even when there is no LLDP peer detected but "
"there is a peer speaking another protocol detected. By default, LLDP packets "
"are sent when there is a peer speaking LLDP detected or when there is no "
"peer at all."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:241
msgid "Generic Endpoint (Class I)"
msgstr ""
#: root/usr/share/rpcd/acl.d/luci-app-lldpd.json:18
msgid "Grant access for LLDP configuration"
msgstr ""
#: root/usr/share/rpcd/acl.d/luci-app-lldpd.json:3
msgid "Grant access for LLDP status information"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:274
msgid "ID"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:275
msgid "ID type"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:114
msgid "IP address"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:229
msgid ""
"If the path to the socket is set, then LLDPd will enable an SNMP subagent "
"using AgentX protocol. This allows you to get information about local system "
"and remote systems through SNMP."
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:171
msgid "Incoming"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:58
msgid "Insert count"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:271
msgid "Interface MAC address"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:689
msgid "Interface Statistics"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:272
#: htdocs/luci-static/resources/view/lldpd/status.js:110
msgid "Interface name"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:310
#: root/usr/share/luci/menu.d/luci-app-lldpd.json:3
msgid "LLDP"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:672
msgid "LLDP Status"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:239
msgid "LLDP-MED device class"
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:19
msgid "LLDPd LuCI application (version %s)"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:455
msgid "LLDPd Settings"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:456
msgid ""
"LLDPd is a implementation of IEEE 802.1ab (<abbr title=\"Link Layer "
"Discovery Protocol\">LLDP</abbr>)."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:251
msgid ""
"LLDPd will still receive (and publish using SNMP if enabled) those LLDP-MED "
"TLV but will not send them. Use this option if you don't want to transmit "
"sensible information like serial numbers."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:677
msgid "Local Chassis"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:112
msgid "Local ID"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:37
#: htdocs/luci-static/resources/view/lldpd/status.js:50
msgid "Local interface"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:108
msgid "MAC address"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:231
msgid "MFS"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:293
msgid "Management IP(s)"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:114
msgid "Management addresses of this system"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:242
msgid "Media Endpoint (Class II)"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:139
#: htdocs/luci-static/resources/view/lldpd/config.js:160
msgid "Must be a number"
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:119
msgid "N &mdash; keep only one neighbor"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:195
#: htdocs/luci-static/resources/view/lldpd/status.js:206
#: htdocs/luci-static/resources/view/lldpd/status.js:268
msgid "Name"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:244
msgid "Network Connectivity Device (Class IV)"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:442
msgid "Network Interfaces"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:189
msgid "Network interfaces"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:202
msgid "Network interfaces for chassis ID computing"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:604
#: htdocs/luci-static/resources/view/lldpd/status.js:661
#: htdocs/luci-static/resources/view/lldpd/status.js:665
msgid "No data to display"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:458
msgid "On this page you may configure LLDPd parameters."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:345
msgid "Only CDPv2"
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:172
msgid "Outgoing"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:93
msgid "Override system description with the provided description."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:100
msgid "Override system hostname with the provided value."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:107
msgid ""
"Override the platform description with the provided value. The default "
"description is the kernel name (Linux)."
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:118
msgid "P &mdash; keep only one protocol"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:214
msgid "Port ID"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:217
msgid "Port ID type"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:222
msgid "Port description"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:38
#: htdocs/luci-static/resources/view/lldpd/status.js:51
msgid "Protocol"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:448
msgid "Protocols Support"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:54
msgid "Rx"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:144
msgid "Rx and Tx"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:146
msgid "Rx only"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:56
msgid "Rx unrecognized"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:228
msgid "SNMP agentX socket path"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:418
msgid "SONMP (NTDP, NDP, BNMP, BDP)"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:351
msgid "Send CDP packets even if no CDP peer detected"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:402
msgid "Send EDP packets even if no EDP peer detected"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:382
msgid "Send FDP packets even if no FDP peer detected"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:428
msgid "Send SONMP packets even if no SONMP peer detected"
msgstr ""
#: root/usr/share/luci/menu.d/luci-app-lldpd.json:28
msgid "Settings"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:259
msgid "Specify the behaviour when detecting multiple neighbors"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:115
msgid ""
"Specify the management addresses of this system. If not specified, the first "
"IPv4 and the first IPv6 are used. If an exact IP address is provided, it is "
"used as a management address without any check. If you want to blacklist "
"IPv6 addresses, you can use <code>!*:*</code>. See more details about "
"available patterns <a href=\"https://vincentbernat.github.io/lldpd/usage.html"
"\">here</a>."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:190
msgid ""
"Specify which interface to listen and send LLDPDU to. If no interfaces is "
"specified, LLDPd will use all available physical interfaces."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:203
msgid ""
"Specify which interfaces to use for computing chassis ID. If no interfaces "
"is specified, all interfaces are considered. LLDPd will take the first MAC "
"address from all the considered interfaces to compute the chassis ID."
msgstr ""
#: root/usr/share/luci/menu.d/luci-app-lldpd.json:16
msgid "Status"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:92
msgid "System description"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:99
msgid "System hostname"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:106
msgid "System platform description"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:226
#: htdocs/luci-static/resources/view/lldpd/status.js:228
msgid "TTL"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:260
msgid ""
"The default filter is 15. For more details see \"FILTERING NEIGHBORS\" "
"section <a href=\"https://vincentbernat.github.io/lldpd/usage.html\">here</"
"a>."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:278
msgid "The destination MAC address used to send LLDPDU"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:279
msgid ""
"The destination MAC address used to send LLDPDU allows an agent to control "
"the propagation of LLDPDUs. By default, the <code>01:80:c2:00:00:0e</code> "
"MAC address is used and limit the propagation of the LLDPDU to the nearest "
"bridge."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:128
msgid ""
"The transmit delay is the delay between two transmissions of LLDP PDU. The "
"default value is 30 seconds."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:673
msgid ""
"This page allows you to see discovered LLDP neighbors, local interfaces "
"statistics and local chassis information."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:148
msgid ""
"This value is used to compute the TTL of transmitted packets which is the "
"product of this value and of the transmit delay. The default value is 4 and "
"therefore the default TTL is 120 seconds."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:127
msgid "Transmit delay"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:141
msgid "Transmit delay must be greater than 0"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:147
msgid "Transmit hold value"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:162
msgid "Transmit hold value must be greater than 0"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:53
msgid "Tx"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:55
msgid "Tx discarded"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:148
msgid "Tx only"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:152
#: htdocs/luci-static/resources/view/lldpd/status.js:260
msgid "Unknown"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:169
msgid ""
"With this option, LLDPd will not send any frames. It will only listen to "
"neighbors."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/config.js:268
msgid ""
"With this option, you can force the port identifier to be the interface name "
"or the MAC address."
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:305
#: htdocs/luci-static/resources/view/lldpd/status.js:314
msgid "disabled"
msgstr ""
#: htdocs/luci-static/resources/view/lldpd/status.js:305
#: htdocs/luci-static/resources/view/lldpd/status.js:314
msgid "enabled"
msgstr ""
#: htdocs/luci-static/resources/lldpd.js:21
msgid "© 20182021, Tano Systems LLC, Anton Kikin"
msgstr ""

View File

@@ -0,0 +1,4 @@
#!/bin/sh
rm -f /tmp/luci-indexcache
exit 0

View File

@@ -0,0 +1,38 @@
{
"admin/services/lldpd": {
"title": "LLDP",
"order": 80,
"action": {
"type": "firstchild"
},
"depends": {
"uci": {
"lldpd": true
}
}
},
"admin/services/lldpd/status": {
"title": "Status",
"order": 10,
"action": {
"type": "view",
"path": "lldpd/status"
},
"depends": {
"acl": [ "luci-app-lldpd-status" ]
}
},
"admin/services/lldpd/config": {
"title": "Settings",
"order": 20,
"action": {
"type": "view",
"path": "lldpd/config"
},
"depends": {
"acl": [ "luci-app-lldpd-config" ]
}
}
}

View File

@@ -0,0 +1,56 @@
{
"luci-app-lldpd-status": {
"description": "Grant access for LLDP status information",
"read": {
"ubus": {
"lldpd": [
"getStatus"
]
},
"uci": [
"lldpd",
"luci"
]
}
},
"luci-app-lldpd-config": {
"description": "Grant access for LLDP configuration",
"read": {
"uci": [
"lldpd",
"luci",
"network",
"wireless",
"firewall"
],
"ubus": {
"luci": [
"getInitList"
],
"luci-rpc": [
"getBoardJSON",
"getHostHints",
"getNetworkDevices",
"getWirelessDevices"
],
"network": [
"get_proto_handlers"
],
"network.interface": [
"dump"
]
}
},
"write": {
"uci": [
"lldpd"
],
"ubus": {
"luci": [
"setInitAction"
]
}
}
}
}

View File

@@ -0,0 +1,22 @@
'use strict';
import { popen } from 'fs';
function lldpcli_json(section) {
return json(popen(`lldpcli -f json0 show ${section}`, 'r'));
}
return {
lldpd: {
getStatus: {
call: function() {
return {
statistics: lldpcli_json("statistics"),
neighbors: lldpcli_json("neighbors details"),
interfaces: lldpcli_json("interfaces"),
chassis: lldpcli_json("chassis")
};
}
}
}
};