mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #297 from DrDoof/hostname
system: configurable hostname + show model on the System page
This commit is contained in:
@@ -1524,6 +1524,29 @@ void cmd_parser(void) __banked
|
|||||||
igmp_show();
|
igmp_show();
|
||||||
else
|
else
|
||||||
igmp_setup(); // Reverts to default with IP-MC being flooded
|
igmp_setup(); // Reverts to default with IP-MC being flooded
|
||||||
|
} else if (cmd_compare(0, "hostname")) {
|
||||||
|
/* "hostname" alone reports the current name; "hostname <text>"
|
||||||
|
* sets it, sanitized to JSON-safe printable ASCII. A name with
|
||||||
|
* spaces would tokenize into several words - reject it instead
|
||||||
|
* of silently keeping the first one. */
|
||||||
|
if (cmd_words_len == 1) {
|
||||||
|
print_string_x(hostname);
|
||||||
|
write_char('\n');
|
||||||
|
} else if (cmd_words_len == 2) {
|
||||||
|
__xdata uint8_t *hp = &cmd_buffer[cmd_words_b[1]];
|
||||||
|
__xdata char *dst = hostname;
|
||||||
|
for (uint8_t hn = 0; hn < sizeof(hostname) - 1; hn++) {
|
||||||
|
uint8_t c = *hp++;
|
||||||
|
if (c == '\0' || c == '\r' || c == '\n')
|
||||||
|
break;
|
||||||
|
if (c < 0x20 || c > 0x7e || c == '"' || c == '\\')
|
||||||
|
c = '.';
|
||||||
|
*dst++ = c;
|
||||||
|
}
|
||||||
|
*dst = '\0';
|
||||||
|
} else {
|
||||||
|
print_string("Error: hostname [name] - the name must not contain spaces\n");
|
||||||
|
}
|
||||||
} else if (cmd_compare(0, "stp")) {
|
} else if (cmd_compare(0, "stp")) {
|
||||||
if (cmd_compare(1, "on")) {
|
if (cmd_compare(1, "on")) {
|
||||||
print_string("STP enabled\n");
|
print_string("STP enabled\n");
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ const conf_cmds = [
|
|||||||
/^igmp\s+(on|off)$/,
|
/^igmp\s+(on|off)$/,
|
||||||
/^mtu\s+\d{1,2}\s+\d+$/,
|
/^mtu\s+\d{1,2}\s+\d+$/,
|
||||||
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
||||||
|
/^hostname\s+.{1,23}$/,
|
||||||
];
|
];
|
||||||
const conf_overwrite = [
|
const conf_overwrite = [
|
||||||
/^ip\b/,
|
/^ip\b/,
|
||||||
@@ -49,6 +50,7 @@ const conf_overwrite = [
|
|||||||
/^igmp\b/,
|
/^igmp\b/,
|
||||||
/^mtu\s+\d{1,2}\b/,
|
/^mtu\s+\d{1,2}\b/,
|
||||||
/^bw\s+(in|out)\s+\d{1,2}\b/,
|
/^bw\s+(in|out)\s+\d{1,2}\b/,
|
||||||
|
/^hostname\b/,
|
||||||
];
|
];
|
||||||
|
|
||||||
function parseConf(s){
|
function parseConf(s){
|
||||||
|
|||||||
@@ -138,6 +138,9 @@ var LANG = {
|
|||||||
sys_tab_console: 'Console',
|
sys_tab_console: 'Console',
|
||||||
sys_heading: 'System Settings',
|
sys_heading: 'System Settings',
|
||||||
sys_ip: 'IP address:',
|
sys_ip: 'IP address:',
|
||||||
|
sys_model: 'Model:',
|
||||||
|
sys_hostname: 'Hostname:',
|
||||||
|
sys_apply: 'Apply',
|
||||||
sys_netmask: 'Netmask:',
|
sys_netmask: 'Netmask:',
|
||||||
sys_gateway: 'Gateway:',
|
sys_gateway: 'Gateway:',
|
||||||
sys_language: 'Language:',
|
sys_language: 'Language:',
|
||||||
@@ -317,6 +320,9 @@ var LANG = {
|
|||||||
sys_tab_console: 'コンソール',
|
sys_tab_console: 'コンソール',
|
||||||
sys_heading: 'システム設定',
|
sys_heading: 'システム設定',
|
||||||
sys_ip: 'IP アドレス:',
|
sys_ip: 'IP アドレス:',
|
||||||
|
sys_model: 'モデル:',
|
||||||
|
sys_hostname: 'ホスト名:',
|
||||||
|
sys_apply: '適用',
|
||||||
sys_netmask: 'ネットマスク:',
|
sys_netmask: 'ネットマスク:',
|
||||||
sys_gateway: 'ゲートウェイ:',
|
sys_gateway: 'ゲートウェイ:',
|
||||||
sys_language: '言語:',
|
sys_language: '言語:',
|
||||||
@@ -496,6 +502,9 @@ var LANG = {
|
|||||||
sys_tab_console: '控制台',
|
sys_tab_console: '控制台',
|
||||||
sys_heading: '系统设置',
|
sys_heading: '系统设置',
|
||||||
sys_ip: 'IP 地址:',
|
sys_ip: 'IP 地址:',
|
||||||
|
sys_model: '型号:',
|
||||||
|
sys_hostname: '主机名:',
|
||||||
|
sys_apply: '应用',
|
||||||
sys_netmask: '子网掩码:',
|
sys_netmask: '子网掩码:',
|
||||||
sys_gateway: '网关:',
|
sys_gateway: '网关:',
|
||||||
sys_language: '语言:',
|
sys_language: '语言:',
|
||||||
|
|||||||
@@ -25,6 +25,15 @@
|
|||||||
|
|
||||||
<div id="system-tab" class="tab-content active">
|
<div id="system-tab" class="tab-content active">
|
||||||
<h1 data-i18n="sys_heading">System Settings</h1>
|
<h1 data-i18n="sys_heading">System Settings</h1>
|
||||||
|
<div class="row">
|
||||||
|
<div class="lcol"> <label for="hostname" data-i18n="sys_hostname">Hostname:</label></div>
|
||||||
|
<div class="rcol"> <input id="hostname" type="text" maxlength="23" size="20"/>
|
||||||
|
<button onclick="hostSub()" data-i18n="sys_apply">Apply</button></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="lcol"> <label data-i18n="sys_model">Model:</label></div>
|
||||||
|
<div class="rcol"><span id="model"></span></div>
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lcol"> <label for="ip" data-i18n="sys_ip">IP address:</label></div>
|
<div class="lcol"> <label for="ip" data-i18n="sys_ip">IP address:</label></div>
|
||||||
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ async function cmdSub() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function hostSub() {
|
||||||
|
const h = document.getElementById("hostname").value;
|
||||||
|
try { await fetch('/cmd', { method: 'POST', body: "hostname " + h }); }
|
||||||
|
catch(err) { console.error(`Error: ${err}`); }
|
||||||
|
fetchIP();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async function sendConfig(c) {
|
async function sendConfig(c) {
|
||||||
if (isSaving) return;
|
if (isSaving) return;
|
||||||
isSaving = true;
|
isSaving = true;
|
||||||
@@ -123,6 +131,8 @@ function fetchIP() {
|
|||||||
document.getElementById("ip").value=s.ip_address;
|
document.getElementById("ip").value=s.ip_address;
|
||||||
document.getElementById("netmask").value=s.ip_netmask;
|
document.getElementById("netmask").value=s.ip_netmask;
|
||||||
document.getElementById("gw").value=s.ip_gateway;
|
document.getElementById("gw").value=s.ip_gateway;
|
||||||
|
document.getElementById("hostname").value=s.hostname;
|
||||||
|
document.getElementById("model").textContent=s.hw_ver;
|
||||||
clearInterval(systemInterval);
|
clearInterval(systemInterval);
|
||||||
// Fetch and populate the config textbox
|
// Fetch and populate the config textbox
|
||||||
fetchConfig().then((configText) => {
|
fetchConfig().then((configText) => {
|
||||||
|
|||||||
@@ -252,6 +252,12 @@ void send_basic_info(void)
|
|||||||
byte_to_html(uip_ethaddr.addr[3]); char_to_html(':');
|
byte_to_html(uip_ethaddr.addr[3]); char_to_html(':');
|
||||||
byte_to_html(uip_ethaddr.addr[4]); char_to_html(':');
|
byte_to_html(uip_ethaddr.addr[4]); char_to_html(':');
|
||||||
byte_to_html(uip_ethaddr.addr[5]);
|
byte_to_html(uip_ethaddr.addr[5]);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"hostname\":\"");
|
||||||
|
{
|
||||||
|
__xdata char *hp = hostname; /* sanitized on ingest, emit verbatim */
|
||||||
|
while (*hp)
|
||||||
|
char_to_html(*hp++);
|
||||||
|
}
|
||||||
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
||||||
slen += strtox(outbuf + slen, VERSION_SW);
|
slen += strtox(outbuf + slen, VERSION_SW);
|
||||||
slen += strtox(outbuf + slen, "\",\"build_date\":\"");
|
slen += strtox(outbuf + slen, "\",\"build_date\":\"");
|
||||||
|
|||||||
@@ -115,6 +115,11 @@ struct flash_region_t {
|
|||||||
|
|
||||||
extern __xdata char port_names[9][PORT_NAME_SIZE];
|
extern __xdata char port_names[9][PORT_NAME_SIZE];
|
||||||
|
|
||||||
|
/* System hostname (device identity). Set via `hostname <text>` and the System
|
||||||
|
* Settings page, reported in /information.json. Other modules (e.g. LLDP, which
|
||||||
|
* advertises it as the System Name TLV) read it from here. */
|
||||||
|
extern __xdata char hostname[24];
|
||||||
|
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
||||||
extern __xdata struct uip_eth_addr uip_ethaddr;
|
extern __xdata struct uip_eth_addr uip_ethaddr;
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
|
#include "httpd/page_impl.h"
|
||||||
|
|
||||||
extern __code const struct machine machine;
|
extern __code const struct machine machine;
|
||||||
extern __xdata uint32_t flash_size;
|
extern __xdata uint32_t flash_size;
|
||||||
@@ -120,6 +121,7 @@ __xdata uint16_t management_vlan;
|
|||||||
__xdata uint8_t tx_seq;
|
__xdata uint8_t tx_seq;
|
||||||
|
|
||||||
__xdata uint8_t stpEnabled;
|
__xdata uint8_t stpEnabled;
|
||||||
|
__xdata char hostname[24]; /* device hostname, default set at boot, see rtl837x_common.h */
|
||||||
|
|
||||||
__code uint16_t bit_mask[16] = {
|
__code uint16_t bit_mask[16] = {
|
||||||
0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
|
0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
|
||||||
@@ -2004,6 +2006,34 @@ void check_and_flash_update_image(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Give the switch a name carrying the tail of its MAC, so several of them on
|
||||||
|
* one network are distinguishable out of the box. Called after the startup
|
||||||
|
* config has been replayed and returns at once if that config already set a
|
||||||
|
* name, so a configured switch does no work for it (suggested in review).
|
||||||
|
*
|
||||||
|
* Written without a loop on purpose. Locals - counters and pointers alike -
|
||||||
|
* land in the 8051's internal-RAM overlay, and on an image with LACP and STP
|
||||||
|
* both enabled that overlay is exhausted: a loop here makes the linker fail
|
||||||
|
* with "Could not get 8 consecutive bytes in internal RAM for area OSEG".
|
||||||
|
* Moving the code into its own function does not help; the overlay is shared
|
||||||
|
* across the whole image. Hoisting the locals to xdata does not help either,
|
||||||
|
* because itohex() is inline and brings its own frame. */
|
||||||
|
void set_hostname_default(void)
|
||||||
|
{
|
||||||
|
if (hostname[0] != '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
strcpy((__xdata uint8_t *)hostname, "RTLPlayground-");
|
||||||
|
hostname[14] = hex[uip_ethaddr.addr[3] >> 4];
|
||||||
|
hostname[15] = hex[uip_ethaddr.addr[3] & 0xf];
|
||||||
|
hostname[16] = hex[uip_ethaddr.addr[4] >> 4];
|
||||||
|
hostname[17] = hex[uip_ethaddr.addr[4] & 0xf];
|
||||||
|
hostname[18] = hex[uip_ethaddr.addr[5] >> 4];
|
||||||
|
hostname[19] = hex[uip_ethaddr.addr[5] & 0xf];
|
||||||
|
hostname[20] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
ticks = 0;
|
ticks = 0;
|
||||||
@@ -2168,6 +2198,8 @@ void main(void)
|
|||||||
early_boot_handle_button();
|
early_boot_handle_button();
|
||||||
|
|
||||||
execute_config();
|
execute_config();
|
||||||
|
/* After the config: a name from it wins, otherwise derive one. */
|
||||||
|
set_hostname_default();
|
||||||
print_cmd_prompt();
|
print_cmd_prompt();
|
||||||
idle_ready = 1;
|
idle_ready = 1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user