mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #36 from logicog/config
System settings and configuration management
This commit is contained in:
+92
-12
@@ -5,9 +5,6 @@
|
|||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
// #define REGDBG 1
|
// #define REGDBG 1
|
||||||
|
|
||||||
#define CONFIG_START 0x70000
|
|
||||||
#define CONFIG_LEN 0x1000
|
|
||||||
|
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_port.h"
|
#include "rtl837x_port.h"
|
||||||
#include "rtl837x_flash.h"
|
#include "rtl837x_flash.h"
|
||||||
@@ -38,6 +35,8 @@ extern __code uint8_t * __code hex;
|
|||||||
extern __xdata uint8_t flash_buf[512];
|
extern __xdata uint8_t flash_buf[512];
|
||||||
extern __xdata struct flash_region_t flash_region;
|
extern __xdata struct flash_region_t flash_region;
|
||||||
|
|
||||||
|
extern __xdata char passwd[21];
|
||||||
|
|
||||||
__xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
__xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
||||||
__xdata uint16_t vlan_ptr;
|
__xdata uint16_t vlan_ptr;
|
||||||
__xdata uint8_t gpio_last_value[8] = { 0 };
|
__xdata uint8_t gpio_last_value[8] = { 0 };
|
||||||
@@ -54,12 +53,16 @@ __xdata uint8_t cmd_available;
|
|||||||
__xdata uint8_t l;
|
__xdata uint8_t l;
|
||||||
__xdata uint8_t line_ptr;
|
__xdata uint8_t line_ptr;
|
||||||
__xdata char is_white;
|
__xdata char is_white;
|
||||||
|
__xdata char save_cmd;
|
||||||
|
|
||||||
__xdata uint8_t ip[4];
|
__xdata uint8_t ip[4];
|
||||||
|
|
||||||
#define N_WORDS SBUF_SIZE
|
#define N_WORDS SBUF_SIZE
|
||||||
__xdata signed char cmd_words_b[N_WORDS];
|
__xdata signed char cmd_words_b[N_WORDS];
|
||||||
|
|
||||||
|
__xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
||||||
|
__xdata uint16_t cmd_history_ptr;
|
||||||
|
|
||||||
// Maps the physical port (starting from 0) to the logical port
|
// Maps the physical port (starting from 0) to the logical port
|
||||||
__code uint8_t phys_to_log_port[6] = {
|
__code uint8_t phys_to_log_port[6] = {
|
||||||
4, 5, 6, 7, 3, 8
|
4, 5, 6, 7, 3, 8
|
||||||
@@ -431,6 +434,36 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parse_rnd(void)
|
||||||
|
{
|
||||||
|
// In order to get a new random numner, this bit has to be set each time!
|
||||||
|
reg_bit_set(RTL837X_RLDP_RLPP, RLDP_RND_EN);
|
||||||
|
reg_read_m(RTL837X_RAND_NUM1);
|
||||||
|
print_byte(sfr_data[2]);
|
||||||
|
print_byte(sfr_data[3]);
|
||||||
|
reg_read_m(RTL837X_RAND_NUM0);
|
||||||
|
print_byte(sfr_data[0]);
|
||||||
|
print_byte(sfr_data[1]);
|
||||||
|
print_byte(sfr_data[2]);
|
||||||
|
print_byte(sfr_data[3]);
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parse_passwd(void)
|
||||||
|
{
|
||||||
|
if (cmd_words_b[2] > 0) {
|
||||||
|
signed char i;
|
||||||
|
signed char j = 0;
|
||||||
|
for (i = cmd_words_b[1]; (i != cmd_words_b[2] && i - cmd_words_b[1] < 20); i++)
|
||||||
|
passwd[j++] = cmd_buffer[i];
|
||||||
|
passwd[j] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print_string("Missing password\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parse command into words
|
// Parse command into words
|
||||||
uint8_t cmd_tokenize(void) __banked
|
uint8_t cmd_tokenize(void) __banked
|
||||||
{
|
{
|
||||||
@@ -679,6 +712,12 @@ void cmd_parser(void) __banked
|
|||||||
if (cmd_compare(0, "regset")) {
|
if (cmd_compare(0, "regset")) {
|
||||||
parse_regset();
|
parse_regset();
|
||||||
}
|
}
|
||||||
|
if (cmd_compare(0, "rnd")) {
|
||||||
|
parse_rnd();
|
||||||
|
}
|
||||||
|
if (cmd_compare(0, "passwd")) {
|
||||||
|
parse_passwd();
|
||||||
|
}
|
||||||
if (cmd_compare(0, "eee")) {
|
if (cmd_compare(0, "eee")) {
|
||||||
int8_t port = -1;
|
int8_t port = -1;
|
||||||
if (cmd_words_b[3] > 0) {
|
if (cmd_words_b[3] > 0) {
|
||||||
@@ -706,21 +745,55 @@ void cmd_parser(void) __banked
|
|||||||
if (cmd_compare(0, "version")) {
|
if (cmd_compare(0, "version")) {
|
||||||
print_sw_version();
|
print_sw_version();
|
||||||
}
|
}
|
||||||
|
if (cmd_compare(0, "history")) {
|
||||||
|
__xdata uint16_t p = (cmd_history_ptr + 1) & CMD_HISTORY_MASK;
|
||||||
|
__xdata uint8_t found_begin = 0;
|
||||||
|
print_string("History ptr: ");
|
||||||
|
print_short(cmd_history_ptr); write_char('\n');
|
||||||
|
while (p != cmd_history_ptr) {
|
||||||
|
print_short(p); write_char(' ');
|
||||||
|
if (!cmd_history[p] || cmd_history[p] == '\n')
|
||||||
|
found_begin = 1;
|
||||||
|
if (found_begin && cmd_history[p])
|
||||||
|
write_char(cmd_history[p]);
|
||||||
|
p = (p + 1) & CMD_HISTORY_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (save_cmd) {
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 0; i < N_WORDS; i++) {
|
||||||
|
if (cmd_words_b[i] < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < N_WORDS) {
|
||||||
|
i = cmd_words_b[--i];
|
||||||
|
cmd_history_ptr = (cmd_history_ptr + i) & CMD_HISTORY_MASK;
|
||||||
|
__xdata uint16_t p = cmd_history_ptr;
|
||||||
|
cmd_history[cmd_history_ptr++] = '\n';
|
||||||
|
do {
|
||||||
|
i--;
|
||||||
|
cmd_history[--p & CMD_HISTORY_MASK] = cmd_buffer[i];
|
||||||
|
} while (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FLASH_READ_BURST_SIZE 0x100;
|
#define FLASH_READ_BURST_SIZE 0x100
|
||||||
|
#define PASSWORD "1234"
|
||||||
void execute_config(void) __banked
|
void execute_config(void) __banked
|
||||||
{
|
{
|
||||||
memcpyc(flash_buf, "test", 5);
|
__xdata uint32_t pos = CONFIG_START;
|
||||||
print_string_x(flash_buf);
|
__xdata uint16_t len_left = CONFIG_LEN;
|
||||||
|
|
||||||
__xdata uint32_t pos = CONFIG_START;
|
// Set default password, it can be overwritten in the configuration file
|
||||||
__xdata uint16_t len_left = CONFIG_LEN;
|
strtox(passwd, PASSWORD);
|
||||||
do {
|
save_cmd = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
flash_region.addr = pos;
|
flash_region.addr = pos;
|
||||||
flash_region.len = FLASH_READ_BURST_SIZE;
|
flash_region.len = FLASH_READ_BURST_SIZE;
|
||||||
write_char('-'); print_long(flash_region.addr); write_char(':'); print_short(flash_region.len); write_char('\n');
|
write_char('-'); print_long(flash_region.addr); write_char(':'); print_short(flash_region.len); write_char('\n');
|
||||||
|
|
||||||
flash_read_bulk(flash_buf);
|
flash_read_bulk(flash_buf);
|
||||||
|
|
||||||
@@ -737,7 +810,7 @@ void execute_config(void) __banked
|
|||||||
if (cmd_idx && !cmd_tokenize())
|
if (cmd_idx && !cmd_tokenize())
|
||||||
cmd_parser();
|
cmd_parser();
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
return;
|
goto config_done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,5 +821,12 @@ void execute_config(void) __banked
|
|||||||
|
|
||||||
len_left -= FLASH_READ_BURST_SIZE;
|
len_left -= FLASH_READ_BURST_SIZE;
|
||||||
pos += FLASH_READ_BURST_SIZE;
|
pos += FLASH_READ_BURST_SIZE;
|
||||||
} while(len_left);
|
} while(len_left);
|
||||||
|
|
||||||
|
config_done:
|
||||||
|
// Start saving commands to cmd_history
|
||||||
|
save_cmd = 1;
|
||||||
|
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
|
||||||
|
cmd_history[cmd_history_ptr] = 0;
|
||||||
|
cmd_history_ptr = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../config.txt
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
var configInterval = Number();
|
||||||
|
var configuration = [];
|
||||||
|
const conf_cmds = [
|
||||||
|
/ip\s+(\d{1,3}\.){3}\d{1,3}/, /gw\s+(\d{1,3}\.){3}\d{1,3}/, /netmask\s+(\d{1,3}\.){3}\d{1,3}/,
|
||||||
|
/eee(\s+\d)?\s+(on|off)/, /mirror(\s+(\d|10))(\s+(\d|10)(t|r)?)+/, /vlan\s+(\d{1,4})(\s+(\d|10)(t|u)?)+/
|
||||||
|
];
|
||||||
|
const conf_overwrite = [
|
||||||
|
/ip/, /gw/, /netmask/, /eee\s+\w+/, /eee(\s+\w)/, /mirror/, /vlan\s+(\d{1,4})/
|
||||||
|
];
|
||||||
|
|
||||||
|
function parseConf(s){
|
||||||
|
var a = s.split(/\r\n|\n/);
|
||||||
|
for (var l = 0; l < a.length; l++) {
|
||||||
|
if (!a[l].length || a[l] == "\n" || a[l] == "\r\n")
|
||||||
|
continue;
|
||||||
|
console.log(l + ' --> ' + a[l]);
|
||||||
|
var ignore = true;
|
||||||
|
for (const x of conf_cmds)
|
||||||
|
if (x.test(a[l])) ignore = false;
|
||||||
|
if (ignore) continue;
|
||||||
|
for (const x of conf_overwrite) {
|
||||||
|
if (x.test(a[l])) {
|
||||||
|
console.log("Match ", x, " to ", a[l]);
|
||||||
|
m = a[l].match(x);
|
||||||
|
console.log("Starts with ", m[0]);
|
||||||
|
configuration = configuration.filter(item => !(item.startsWith(m[0])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configuration.push(a[l]);
|
||||||
|
}
|
||||||
|
console.log("Configuration now:");
|
||||||
|
for (const x of configuration) { console.log(x); }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchConfig() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/config');
|
||||||
|
console.log("CONFIG: ", response);
|
||||||
|
const t = await response.text();
|
||||||
|
return t;
|
||||||
|
} catch(err) {
|
||||||
|
console.error("Error: ", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchCmdLog() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/cmd_log');
|
||||||
|
console.log("CMD-Log: ", response);
|
||||||
|
const t = await response.text();
|
||||||
|
return t;
|
||||||
|
} catch(error) {
|
||||||
|
console.error("Error: ", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<title>RTL Switch Login</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
function removeNote() {
|
||||||
|
document.getElementById("incorrect").innerHTML = "";
|
||||||
|
}
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
if (document.referrer.endsWith("login.html"))
|
||||||
|
document.getElementById("incorrect").innerHTML = "Wrong password!";
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="login_page">
|
||||||
|
<div class = "center">
|
||||||
|
<h1> RTL Switch Login</h1>
|
||||||
|
<form method="post" action="login">
|
||||||
|
<div class="txt_field">
|
||||||
|
<input name="pwd" type="password" onclick="removeNote()" required />
|
||||||
|
<span></span>
|
||||||
|
<label>Password</label>
|
||||||
|
</div>
|
||||||
|
<input type="submit" value="Login"/>
|
||||||
|
<h3 id="incorrect" style="margin-top: 5em;"></h3>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -10,6 +10,8 @@ var numPorts = 0;
|
|||||||
function update() {
|
function update() {
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 401)
|
||||||
|
document.location = "/login.html"
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
const s = JSON.parse(xhttp.responseText);
|
const s = JSON.parse(xhttp.responseText);
|
||||||
if (!numPorts) {
|
if (!numPorts) {
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ document.getElementById('sidebar').innerHTML =
|
|||||||
+ "<li><a href='mirror.html'>Mirroring</a></li>"
|
+ "<li><a href='mirror.html'>Mirroring</a></li>"
|
||||||
+ "<li><a href='trunk.html'>Port Aggregation</a></li>"
|
+ "<li><a href='trunk.html'>Port Aggregation</a></li>"
|
||||||
+ "<li><a href='eee.html'>EEE</a></li>"
|
+ "<li><a href='eee.html'>EEE</a></li>"
|
||||||
|
+ "<li><a href='system.html'>System Settings</a></li>"
|
||||||
+ "<li><a href='update.html'>Firmware Update</a></li></ul>";
|
+ "<li><a href='update.html'>Firmware Update</a></li></ul>";
|
||||||
|
|
||||||
|
|||||||
+48
-4
@@ -1,4 +1,4 @@
|
|||||||
h1, h2 {
|
h1, h2, h3 {
|
||||||
color: #226;
|
color: #226;
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
@@ -38,10 +38,17 @@ td {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=submit] { padding: 8px 16px;background-color:#aaf;color:#000; margin-bottom: 2em;}
|
input[type=submit] { padding: 8px 16px;background-color:#aaf;color:#000; margin-bottom: 2em;border-radius: 15px;width: 100%;}
|
||||||
input[type=submit]:hover { background-color: #226; color: white;}
|
input[type=submit]:hover { background-color: #226; color: white;}
|
||||||
button {padding: 8px; background-color:#99f; color:#000;}
|
input[type=file] { padding: 8px 16px;background-color:#aaf;color:#000; margin-bottom: 2em;border-radius: 15px;width: 60%;}
|
||||||
|
input[type=file]:hover { background-color: #226; color: white;}
|
||||||
|
b
|
||||||
|
button {padding: 8px; background-color:#99f; color:#000;border-radius: 15px;}
|
||||||
button:hover { background-color: #226; color: white;}
|
button:hover { background-color: #226; color: white;}
|
||||||
|
.action{padding: 8px 16px;margin-top: 2em;margin-right: 3em; background-color: #aaf;color: #000;border-radius: 15px; width: 100%;}
|
||||||
|
.action:hover { background-color: #226; color: white;}
|
||||||
|
|
||||||
|
/* Port selection inputs */
|
||||||
.psel {
|
.psel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -73,4 +80,41 @@ object {
|
|||||||
.isSFP{ opacity: .4; background-color: #660;}
|
.isSFP{ opacity: .4; background-color: #660;}
|
||||||
.isNOK{ color: #900;}
|
.isNOK{ color: #900;}
|
||||||
.isOK{ color: #090;}
|
.isOK{ color: #090;}
|
||||||
.action{padding: 8px 16px;margin-top: 2em;margin-right: 3em; background-color: #aaf;color: #000;}
|
.ip{padding:8px 16px;margin-bottom: 1em;margin-left: 1em}
|
||||||
|
.row {display: flex;}
|
||||||
|
.rcol {flex: 90%;}
|
||||||
|
.lcol {flex: 10%;}
|
||||||
|
span::before{ content:''; position: absolute; top: 40px; left:0; width: 100%; height: 2px; background: #aaf;}
|
||||||
|
|
||||||
|
/* Login page */
|
||||||
|
.login_page {margin: 0; padding: 0; background: #aaf; height: 100vh; overflow: hidden;}
|
||||||
|
.center{
|
||||||
|
position: absolute; top: 50%; left: 50%;
|
||||||
|
transform: translate(-50%, -40% );
|
||||||
|
width: 500px; height: 400px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center h1 {
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid silver;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center form {
|
||||||
|
padding: 0 60px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
form .txt_field{
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 2px solid #adadad;
|
||||||
|
margin: 30px 0;
|
||||||
|
}
|
||||||
|
.txt_field input { width: 100%; padding: 0 5px; height: 40px; font-size: 16px; border: none;
|
||||||
|
background: none;
|
||||||
|
outline: none;}
|
||||||
|
.txt_field label { position: absolute; top: 50%; left: 5px; color:#adadad; transform: translateY(-50%);
|
||||||
|
font-size: 16px; pointer-events: none;transition: .5s; }
|
||||||
|
.txt_field span::before{ content:''; position: absolute; top: 40px; left:0; width: 100%; height: 2px; background: #aaf;}
|
||||||
|
.txt_field input:focus ~ label,
|
||||||
|
.txt_field input:valid ~ label { top: -5px; color: #aaf; }
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<title>System Settings</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav id="sidebar"></nav>
|
||||||
|
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
||||||
|
<div id="ports"></div>
|
||||||
|
<h1>System Settings</h1>
|
||||||
|
<div class="row">
|
||||||
|
<div class="lcol"> <label for="ip">IP address:</label></div>
|
||||||
|
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="lcol"> <label for="netmask">Netmask:</label></div>
|
||||||
|
<div class="rcol"><input id="netmask" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
||||||
|
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||||
|
</div>
|
||||||
|
<br/><br/>
|
||||||
|
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
||||||
|
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
||||||
|
<br/><br/>
|
||||||
|
Save all current settings to Flash:<br/>
|
||||||
|
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script src="/config.js"></script>
|
||||||
|
<script src="/system.js"></script>
|
||||||
|
<script src="/navigation.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
var systemInterval = Number();
|
||||||
|
const ips = ["ip", "netmask", "gw"];
|
||||||
|
|
||||||
|
function checkIp(ip) {
|
||||||
|
const ipv4 = /^(\d{1,3}\.){3}\d{1,3}$/;
|
||||||
|
if (!ipv4.test(ip)) {alert(`Invalid ip:${ip}`); return false };
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ipSub() {
|
||||||
|
for (let i=0;i<3;i++) {
|
||||||
|
if (!checkIp(document.getElementById(ips[i]).value))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i=0; i<3;i++){
|
||||||
|
var cmd = ips[i]+' '+document.getElementById(ips[i]).value;
|
||||||
|
try {
|
||||||
|
const response = await fetch('/cmd', {
|
||||||
|
method: 'POST',
|
||||||
|
body: cmd
|
||||||
|
});
|
||||||
|
console.log('Completed!', response);
|
||||||
|
fetchIP();
|
||||||
|
} catch(err) {
|
||||||
|
console.error(`Error: ${err}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendConfig(c) {
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("MAX_FILE_SIZE", "4096");
|
||||||
|
form.append("configuration", new Blob([c], {type: "application/octet-stream"}));
|
||||||
|
try {
|
||||||
|
const response = await fetch('/config', {
|
||||||
|
method: 'POST',
|
||||||
|
body: form
|
||||||
|
});
|
||||||
|
console.log('Completed!', response);
|
||||||
|
} catch(err) {
|
||||||
|
console.error(`Error: ${err}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function flashSave() {
|
||||||
|
fetchConfig().then((s) => {
|
||||||
|
parseConf(s);
|
||||||
|
fetchCmdLog().then((s) => {
|
||||||
|
parseConf(s);
|
||||||
|
var body = "";
|
||||||
|
for (const x of configuration) { body = body + x + "\n"; }
|
||||||
|
console.log("CONFIGURATION to save: ", body);
|
||||||
|
sendConfig(body);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchIP() {
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
const s = JSON.parse(xhttp.responseText);
|
||||||
|
console.log("IP: ", s);
|
||||||
|
document.getElementById("ip").value=s.ip_address;
|
||||||
|
document.getElementById("netmask").value=s.ip_netmask;
|
||||||
|
document.getElementById("gw").value=s.ip_gateway;
|
||||||
|
clearInterval(systemInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhttp.open("GET", `/information.json`, true);
|
||||||
|
xhttp.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
systemInterval = setInterval(fetchIP, 1000);
|
||||||
|
});
|
||||||
+4
-4
@@ -6,13 +6,13 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav id="sidebar"></nav>
|
<nav id="sidebar"></nav>
|
||||||
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
<div style="margin-left:16%;padding:1px 16px;height:1000px;width:40%;">
|
||||||
<div id="ports"></div>
|
|
||||||
<h1>Firmware Update</h1>
|
<h1>Firmware Update</h1>
|
||||||
<form enctype="multipart/form-data" action="/upload" method="POST">
|
<form enctype="multipart/form-data" action="/upload" method="POST">
|
||||||
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
|
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
|
||||||
Choose a firmware update file to upload: <input name="uploadedfile" type="file" accept=".bin" /><br />
|
Choose a firmware update file to upload: <br/> <br/>
|
||||||
<input type="submit" value="Upload File" />
|
<input name="uploadedfile" type="file" accept=".bin" /><br />
|
||||||
|
<input style="margin-top:3em" type="submit" value="Upload File" />
|
||||||
</form>
|
</form>
|
||||||
<script src="/navigation.js"></script>
|
<script src="/navigation.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+163
-18
@@ -2,11 +2,15 @@
|
|||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
#include "page_impl.h"
|
#include "page_impl.h"
|
||||||
#include "../rtl837x_common.h"
|
#include "../rtl837x_common.h"
|
||||||
|
#include "../rtl837x_regs.h"
|
||||||
#include "../cmd_parser.h"
|
#include "../cmd_parser.h"
|
||||||
#include "../rtl837x_flash.h"
|
#include "../rtl837x_flash.h"
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "../html_data.h"
|
#include "../html_data.h"
|
||||||
|
|
||||||
|
#define SESSION_ID_LENGTH 12
|
||||||
|
#define SESSION_TIMEOUT 200
|
||||||
|
|
||||||
// Upload Firmware to 1M
|
// Upload Firmware to 1M
|
||||||
#define FIRMWARE_UPLOAD_START 0x100000
|
#define FIRMWARE_UPLOAD_START 0x100000
|
||||||
|
|
||||||
@@ -18,6 +22,8 @@
|
|||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
|
|
||||||
|
extern volatile __xdata uint8_t sfr_data[4];
|
||||||
|
extern __code uint8_t * __code hex;
|
||||||
extern __code struct f_data f_data[];
|
extern __code struct f_data f_data[];
|
||||||
extern __code char * __code mime_strings[];
|
extern __code char * __code mime_strings[];
|
||||||
extern __xdata struct flash_region_t flash_region;
|
extern __xdata struct flash_region_t flash_region;
|
||||||
@@ -33,16 +39,27 @@ __xdata uint16_t slen;
|
|||||||
__xdata uint16_t o_idx;
|
__xdata uint16_t o_idx;
|
||||||
__xdata uint16_t mpos;
|
__xdata uint16_t mpos;
|
||||||
__xdata uint16_t len_left;
|
__xdata uint16_t len_left;
|
||||||
|
__xdata uint16_t cont_len;
|
||||||
|
__xdata uint32_t cont_addr;
|
||||||
|
|
||||||
// HTTP header properties
|
// HTTP header properties
|
||||||
__xdata uint8_t boundary[72];
|
__xdata uint8_t boundary[72];
|
||||||
__xdata uint8_t *content_type = 0;
|
__xdata uint8_t *content_type = 0;
|
||||||
|
__xdata uint8_t *session = 0;
|
||||||
|
|
||||||
// Global variables holding POST state
|
// Global variables holding POST state
|
||||||
__xdata uint16_t bindex; // Current index into the boundary
|
__xdata uint16_t bindex; // Current index into the boundary
|
||||||
|
__xdata uint8_t verify_crc;
|
||||||
|
__xdata uint32_t max_upload;
|
||||||
__xdata uint16_t short_parsed;
|
__xdata uint16_t short_parsed;
|
||||||
|
|
||||||
|
__xdata char passwd[21];
|
||||||
|
__xdata char session_id[SESSION_ID_LENGTH + 1];
|
||||||
|
__xdata uint8_t authenticated;
|
||||||
|
__xdata uint32_t now;
|
||||||
|
__xdata uint8_t *timeptr;
|
||||||
|
__xdata uint32_t last_session_use;
|
||||||
|
|
||||||
#define TSTATE_NONE 0
|
#define TSTATE_NONE 0
|
||||||
#define TSTATE_TX 1
|
#define TSTATE_TX 1
|
||||||
#define TSTATE_ACKED 2
|
#define TSTATE_ACKED 2
|
||||||
@@ -161,6 +178,19 @@ void send_bad_request(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_to_login(void)
|
||||||
|
{
|
||||||
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\n" \
|
||||||
|
"Location: login.html\r\n\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_unauthorized(void)
|
||||||
|
{
|
||||||
|
slen = strtox(outbuf, "HTTP/1.1 401 Unauthorized\r\n\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
__xdata uint8_t *skip_boundary(__xdata uint8_t *p)
|
__xdata uint8_t *skip_boundary(__xdata uint8_t *p)
|
||||||
{
|
{
|
||||||
while (*p) {
|
while (*p) {
|
||||||
@@ -175,6 +205,8 @@ __xdata uint8_t *skip_boundary(__xdata uint8_t *p)
|
|||||||
__xdata uint8_t *scan_header(__xdata uint8_t *p)
|
__xdata uint8_t *scan_header(__xdata uint8_t *p)
|
||||||
{
|
{
|
||||||
content_type = 0;
|
content_type = 0;
|
||||||
|
session = 0;
|
||||||
|
authenticated = 0;
|
||||||
|
|
||||||
while (*p != '\r' || *(p + 1) != '\n' || *(p + 2) != '\r' || *(p + 3) != '\n') {
|
while (*p != '\r' || *(p + 1) != '\n' || *(p + 2) != '\r' || *(p + 3) != '\n') {
|
||||||
write_char(*p);
|
write_char(*p);
|
||||||
@@ -182,9 +214,11 @@ __xdata uint8_t *scan_header(__xdata uint8_t *p)
|
|||||||
break;
|
break;
|
||||||
if (is_word(p, "\nContent-Type:"))
|
if (is_word(p, "\nContent-Type:"))
|
||||||
content_type = p + 15;
|
content_type = p + 15;
|
||||||
|
else if (is_word(p, "\nCookie:"))
|
||||||
|
session = p + 17;
|
||||||
}
|
}
|
||||||
if (content_type && is_word(content_type, "multipart/form-data; boundary")) {
|
if (content_type && is_word(content_type, "multipart/form-data; boundary")) {
|
||||||
print_string("\nFound multiplart\n");
|
print_string("\nFound multipart\n");
|
||||||
content_type += 30;
|
content_type += 30;
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
while (content_type[i] != '\r' && content_type[i] != '\n') {
|
while (content_type[i] != '\r' && content_type[i] != '\n') {
|
||||||
@@ -198,10 +232,37 @@ __xdata uint8_t *scan_header(__xdata uint8_t *p)
|
|||||||
boundary[3] = '-';
|
boundary[3] = '-';
|
||||||
boundary[i + 4] = 0;
|
boundary[i + 4] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read_reg_timer(&now);
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
if (now - last_session_use > SESSION_TIMEOUT) {
|
||||||
|
print_string("Session expired\n");
|
||||||
|
} else {
|
||||||
|
if (is_word_x(session, session_id))
|
||||||
|
authenticated = 1;
|
||||||
|
else
|
||||||
|
print_string("Invalid session cookie!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void gen_random_bytes(__xdata uint8_t *b, uint8_t bytes)
|
||||||
|
{
|
||||||
|
__xdata uint8_t i = 0;
|
||||||
|
while (bytes) {
|
||||||
|
if (!i)
|
||||||
|
get_random_32();
|
||||||
|
b[--bytes] = itohex(sfr_data[i]);
|
||||||
|
if (!bytes) { break; }
|
||||||
|
b[--bytes] = itohex(sfr_data[i] >> 4 | sfr_data[i] << 4);
|
||||||
|
i = (i + 1) & 0x3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads post data from the http stream and writes it into flash memory
|
* Reads post data from the http stream and writes it into flash memory
|
||||||
* Input: the current position in the TCP buffer (uip_appdata)
|
* Input: the current position in the TCP buffer (uip_appdata)
|
||||||
@@ -230,14 +291,21 @@ uint8_t stream_upload(uint16_t bptr)
|
|||||||
uptr += write_len;
|
uptr += write_len;
|
||||||
write_len = 0;
|
write_len = 0;
|
||||||
// TODO: This is a bit premature, what about a nice web-page saying the device will reset???
|
// TODO: This is a bit premature, what about a nice web-page saying the device will reset???
|
||||||
print_string("CRC16: "); print_short(crc_final); write_char('\n');
|
if (verify_crc) {
|
||||||
if (crc_final == 0xb001) {
|
print_string("CRC16: "); print_short(crc_final); write_char('\n');
|
||||||
print_string("Checksum OK.");
|
if (crc_final == 0xb001) {
|
||||||
} else {
|
print_string("Checksum OK.");
|
||||||
print_string("Checksum incorrect!");
|
} else {
|
||||||
|
print_string("Checksum incorrect!");
|
||||||
|
}
|
||||||
|
print_string("Upload to flash done, will reset!\n");
|
||||||
|
reset_chip();
|
||||||
}
|
}
|
||||||
print_string("Upload to flash done, will reset!\n");
|
// Make sure there is a 0 at the end of the uploaded data
|
||||||
reset_chip();
|
flash_buf[0] = 0;
|
||||||
|
flash_region.addr = uptr;
|
||||||
|
flash_region.len = 1;
|
||||||
|
flash_write_bytes(flash_buf);
|
||||||
if (bptr >= uip_len)
|
if (bptr >= uip_len)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -302,13 +370,38 @@ void handle_post(void)
|
|||||||
if (is_word(request_path, "cmd")) {
|
if (is_word(request_path, "cmd")) {
|
||||||
register uint8_t i = 0;
|
register uint8_t i = 0;
|
||||||
p += 4;
|
p += 4;
|
||||||
|
if (!authenticated) {
|
||||||
|
send_unauthorized();
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (*p && *p != '\n' && *p != '\r')
|
while (*p && *p != '\n' && *p != '\r')
|
||||||
cmd_buffer[i++] = *p++;
|
cmd_buffer[i++] = *p++;
|
||||||
cmd_buffer[i] = '\0';
|
cmd_buffer[i] = '\0';
|
||||||
if (i)
|
if (i)
|
||||||
cmd_available = 1;
|
cmd_available = 1;
|
||||||
} else if (is_word(request_path, "upload")) {
|
} else if (is_word(request_path, "login")) {
|
||||||
print_string("POST upload request\n");
|
print_string("POST login\n");
|
||||||
|
p += 8; // Read also over "pwd="
|
||||||
|
if (is_word_x(p, passwd)) {
|
||||||
|
print_string("Password accepted!\n");
|
||||||
|
read_reg_timer(&last_session_use);
|
||||||
|
gen_random_bytes(session_id, SESSION_ID_LENGTH);
|
||||||
|
session_id[SESSION_ID_LENGTH] = '\0';
|
||||||
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nLocation: index.html\r\n" \
|
||||||
|
"Set-Cookie: session=");
|
||||||
|
for (register uint8_t i = 0; i < SESSION_ID_LENGTH; i++)
|
||||||
|
outbuf[slen++] = session_id[i];
|
||||||
|
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
||||||
|
} else {
|
||||||
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nLocation: login.html\r\n\r\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (is_word(request_path, "upload") || is_word(request_path, "config")) {
|
||||||
|
print_string("POST upload/config request\n");
|
||||||
|
if (!authenticated) {
|
||||||
|
send_unauthorized();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!boundary[0]) {
|
if (!boundary[0]) {
|
||||||
print_string("Bad request, no boundary!\n");
|
print_string("Bad request, no boundary!\n");
|
||||||
send_bad_request();
|
send_bad_request();
|
||||||
@@ -328,7 +421,18 @@ void handle_post(void)
|
|||||||
print_string("Have content octets\n");
|
print_string("Have content octets\n");
|
||||||
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
||||||
|
|
||||||
uptr = FIRMWARE_UPLOAD_START;
|
if (is_word(request_path, "upload")) {
|
||||||
|
uptr = FIRMWARE_UPLOAD_START;
|
||||||
|
verify_crc = 1;
|
||||||
|
max_upload = 1024576;
|
||||||
|
} else {
|
||||||
|
print_string("Configuration upload, erasing config mem!\n");
|
||||||
|
uptr = CONFIG_START;
|
||||||
|
verify_crc = 0;
|
||||||
|
max_upload = 2048;
|
||||||
|
flash_region.addr = CONFIG_START;
|
||||||
|
flash_sector_erase();
|
||||||
|
}
|
||||||
crc_value = 0;
|
crc_value = 0;
|
||||||
bindex = 0;
|
bindex = 0;
|
||||||
write_len = 0;
|
write_len = 0;
|
||||||
@@ -386,17 +490,34 @@ void httpd_appcall(void)
|
|||||||
if (slen > uip_mss()) {
|
if (slen > uip_mss()) {
|
||||||
print_string("Sending A: "); print_short(slen); write_char('\n');
|
print_string("Sending A: "); print_short(slen); write_char('\n');
|
||||||
uip_send(outbuf + o_idx, uip_mss());
|
uip_send(outbuf + o_idx, uip_mss());
|
||||||
print_string("Sending A done\n");
|
|
||||||
s->tstate = TSTATE_TX;
|
s->tstate = TSTATE_TX;
|
||||||
} else if (slen > 0) {
|
} else if (slen > 0) {
|
||||||
print_string("Sending B: "); print_short(slen); write_char('\n');
|
print_string("Sending B: "); print_short(slen); write_char('\n');
|
||||||
uip_send(outbuf + o_idx, slen);
|
uip_send(outbuf + o_idx, slen);
|
||||||
print_string("Sending B done\n");
|
s->tstate = TSTATE_TX;
|
||||||
|
} else if (cont_len) {
|
||||||
|
print_string("CONT cont_len: "); print_short(cont_len);
|
||||||
|
slen = cont_len > uip_mss() ? uip_mss() : cont_len;
|
||||||
|
if (slen > TCP_OUTBUF_SIZE)
|
||||||
|
slen = TCP_OUTBUF_SIZE;
|
||||||
|
flash_region.addr = cont_addr;
|
||||||
|
flash_region.len = slen;
|
||||||
|
flash_read_bulk(outbuf);
|
||||||
|
uip_send(outbuf, slen);
|
||||||
|
cont_len -= slen;
|
||||||
|
cont_addr += slen;
|
||||||
s->tstate = TSTATE_TX;
|
s->tstate = TSTATE_TX;
|
||||||
}
|
}
|
||||||
} else if (uip_newdata() && s->tstate == TSTATE_POST) {
|
} else if (uip_newdata() && s->tstate == TSTATE_POST) {
|
||||||
stream_upload(0);
|
// Check here maxupload by subtracting uip_len and close socekt if fails!
|
||||||
|
if (max_upload - uip_len > 0) {
|
||||||
|
stream_upload(0);
|
||||||
|
} else {
|
||||||
|
send_bad_request();
|
||||||
|
goto do_send;
|
||||||
|
}
|
||||||
} else if (uip_newdata() && s->tstate != TSTATE_TX) {
|
} else if (uip_newdata() && s->tstate != TSTATE_TX) {
|
||||||
|
cont_len = 0;
|
||||||
write_char('<'); print_short(uip_len); write_char('\n');
|
write_char('<'); print_short(uip_len); write_char('\n');
|
||||||
__xdata uint8_t *p = uip_appdata;
|
__xdata uint8_t *p = uip_appdata;
|
||||||
// Mark end of request header with \0
|
// Mark end of request header with \0
|
||||||
@@ -418,6 +539,7 @@ void httpd_appcall(void)
|
|||||||
if (is_word(p, "GET"))
|
if (is_word(p, "GET"))
|
||||||
print_string("GET request ");
|
print_string("GET request ");
|
||||||
p += 4;
|
p += 4;
|
||||||
|
scan_header(p);
|
||||||
__xdata uint8_t *q = p;
|
__xdata uint8_t *q = p;
|
||||||
while (!is_separator(*p))
|
while (!is_separator(*p))
|
||||||
p++;
|
p++;
|
||||||
@@ -429,6 +551,11 @@ void httpd_appcall(void)
|
|||||||
entry = find_entry(q);
|
entry = find_entry(q);
|
||||||
print_string("Entry is: "); print_byte(entry); write_char('\n');
|
print_string("Entry is: "); print_byte(entry); write_char('\n');
|
||||||
if (entry == 0xff) {
|
if (entry == 0xff) {
|
||||||
|
if (!authenticated) {
|
||||||
|
print_string("Not authorized!\n");
|
||||||
|
send_unauthorized();
|
||||||
|
goto do_send;
|
||||||
|
}
|
||||||
print_string("Not file entry\n");
|
print_string("Not file entry\n");
|
||||||
if (!strcmp(q, "/status.json")) {
|
if (!strcmp(q, "/status.json")) {
|
||||||
send_status();
|
send_status();
|
||||||
@@ -443,16 +570,34 @@ void httpd_appcall(void)
|
|||||||
send_eee();
|
send_eee();
|
||||||
} else if (is_word(q, "/mirror.json")) {
|
} else if (is_word(q, "/mirror.json")) {
|
||||||
send_mirror();
|
send_mirror();
|
||||||
|
} else if (is_word(q, "/config")) {
|
||||||
|
send_config();
|
||||||
|
} else if (is_word(q, "/cmd_log")) {
|
||||||
|
send_cmd_log();
|
||||||
} else {
|
} else {
|
||||||
send_not_found();
|
send_not_found();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print_string("Have entry\n");
|
print_string("Have entry, authenticated: "); print_byte(authenticated); write_char('\n');
|
||||||
|
if (!authenticated && !(f_data[entry].start == FDATA_START_login_html
|
||||||
|
|| f_data[entry].start == FDATA_START_style_css)) {
|
||||||
|
send_to_login();
|
||||||
|
goto do_send;
|
||||||
|
}
|
||||||
|
// A web-page is actively accessed, we can reset session time-out
|
||||||
|
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||||
|
timeptr = (uint8_t*)&last_session_use; // last_session_use is Little endian
|
||||||
|
timeptr[0] = sfr_data[3]; timeptr[1] = sfr_data[2]; timeptr[2] = sfr_data[1]; timeptr[3] = sfr_data[0];
|
||||||
|
|
||||||
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
|
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
|
||||||
slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]);
|
slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]);
|
||||||
slen += strtox(outbuf + slen, "\r\nCache-Control: max-age=2592000\r\n\r\n");
|
slen += strtox(outbuf + slen, "\r\nCache-Control: max-age=60, must-revalidate\r\n\r\n");
|
||||||
len_left = f_data[entry].len;
|
len_left = f_data[entry].len;
|
||||||
|
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
||||||
|
cont_len = len_left - (TCP_OUTBUF_SIZE - slen);
|
||||||
|
len_left = TCP_OUTBUF_SIZE - slen;
|
||||||
|
cont_addr = f_data[entry].start + len_left;
|
||||||
|
}
|
||||||
print_string("MIME: "); print_string(mime_strings[f_data[entry].mime]); write_char('\n');
|
print_string("MIME: "); print_string(mime_strings[f_data[entry].mime]); write_char('\n');
|
||||||
flash_region.addr = f_data[entry].start;
|
flash_region.addr = f_data[entry].start;
|
||||||
flash_region.len = len_left;
|
flash_region.len = len_left;
|
||||||
|
|||||||
+53
-15
@@ -4,17 +4,21 @@
|
|||||||
#include "../rtl837x_common.h"
|
#include "../rtl837x_common.h"
|
||||||
#include "../rtl837x_regs.h"
|
#include "../rtl837x_regs.h"
|
||||||
#include "../rtl837x_port.h"
|
#include "../rtl837x_port.h"
|
||||||
|
#include "../rtl837x_flash.h"
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "../html_data.h"
|
#include "../html_data.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../phy.h"
|
#include "../phy.h"
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
#include "page_impl.h"
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
|
|
||||||
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
|
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
|
||||||
extern __xdata uint16_t slen;
|
extern __xdata uint16_t slen;
|
||||||
|
extern __xdata uint16_t cont_len;
|
||||||
|
extern __xdata uint32_t cont_addr;
|
||||||
extern __code uint8_t * __code hex;
|
extern __code uint8_t * __code hex;
|
||||||
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
||||||
extern __code struct uip_eth_addr uip_ethaddr;
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
@@ -30,22 +34,13 @@ extern __xdata uint8_t isRTL8373;
|
|||||||
extern __xdata uint8_t sfp_pins_last;
|
extern __xdata uint8_t sfp_pins_last;
|
||||||
extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
||||||
|
|
||||||
|
extern __xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
||||||
|
extern __xdata uint16_t cmd_history_ptr;
|
||||||
|
|
||||||
|
extern __xdata struct flash_region_t flash_region;
|
||||||
|
|
||||||
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
|
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
|
||||||
|
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
||||||
/* Convert only the lower nibble to ascii HEX char.
|
|
||||||
For convenience the upper nibble is masked out.
|
|
||||||
*/
|
|
||||||
inline char itohex(uint8_t val) {
|
|
||||||
// Ignore upper nibble for convenience.
|
|
||||||
val &= 0x0f;
|
|
||||||
val -= 10;
|
|
||||||
|
|
||||||
// 10 or above
|
|
||||||
if ((int8_t)val >= 0)
|
|
||||||
val += ('a' - '0' - 10);
|
|
||||||
|
|
||||||
return val + ('0' + 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert uint8_t to ascii HEX char push on html-buffer.
|
// Convert uint8_t to ascii HEX char push on html-buffer.
|
||||||
void charhex_to_html(char c)
|
void charhex_to_html(char c)
|
||||||
@@ -371,3 +366,46 @@ void send_status(void)
|
|||||||
char_to_html(']');
|
char_to_html(']');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_config(void)
|
||||||
|
{
|
||||||
|
print_string("send_config called\n");
|
||||||
|
__xdata uint32_t pos = CONFIG_START; // 70000 , 6c000 / 0xc000 = 9
|
||||||
|
|
||||||
|
extern __xdata uint16_t len_left = CONFIG_LEN;
|
||||||
|
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
||||||
|
while (read_flash((CONFIG_START-CODE0_SIZE) / CODE_BANK_SIZE + 1,
|
||||||
|
(__code uint8_t *) (((CONFIG_START + len_left - CODE0_SIZE) % CODE_BANK_SIZE) + CODE0_SIZE + len_left)) == 0xff) {
|
||||||
|
print_short(len_left);
|
||||||
|
len_left--;
|
||||||
|
}
|
||||||
|
len_left++;
|
||||||
|
|
||||||
|
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
||||||
|
cont_len = len_left - (TCP_OUTBUF_SIZE - slen);
|
||||||
|
len_left = TCP_OUTBUF_SIZE - slen;
|
||||||
|
cont_addr = len_left;
|
||||||
|
}
|
||||||
|
flash_region.addr = CONFIG_START;
|
||||||
|
flash_region.len = len_left;
|
||||||
|
flash_read_bulk(outbuf + slen);
|
||||||
|
slen += len_left;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_cmd_log(void)
|
||||||
|
{
|
||||||
|
print_string("send_cmd_log called\n");
|
||||||
|
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
||||||
|
__xdata uint16_t p = (cmd_history_ptr + 1) & CMD_HISTORY_MASK;
|
||||||
|
__xdata uint8_t found_begin = 0;
|
||||||
|
print_string("History ptr: ");
|
||||||
|
print_short(cmd_history_ptr); write_char('\n');
|
||||||
|
while (p != cmd_history_ptr) {
|
||||||
|
if (!cmd_history[p] || cmd_history[p] == '\n')
|
||||||
|
found_begin = 1;
|
||||||
|
if (found_begin && cmd_history[p])
|
||||||
|
outbuf[slen++] = cmd_history[p];
|
||||||
|
p = (p + 1) & CMD_HISTORY_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+18
-1
@@ -3,9 +3,26 @@
|
|||||||
|
|
||||||
void send_counters(char port);
|
void send_counters(char port);
|
||||||
void send_status(void);
|
void send_status(void);
|
||||||
void send_vlan(register uint16_t vlan);
|
void send_vlan(uint16_t vlan);
|
||||||
void send_basic_info(void);
|
void send_basic_info(void);
|
||||||
void send_eee(void);
|
void send_eee(void);
|
||||||
void send_mirror(void);
|
void send_mirror(void);
|
||||||
|
void send_config(void);
|
||||||
|
void send_cmd_log(void);
|
||||||
|
|
||||||
|
/* Convert only the lower nibble to ascii HEX char.
|
||||||
|
For convenience the upper nibble is masked out.
|
||||||
|
*/
|
||||||
|
inline char itohex(uint8_t val) {
|
||||||
|
// Ignore upper nibble for convenience.
|
||||||
|
val &= 0x0f;
|
||||||
|
val -= 10;
|
||||||
|
|
||||||
|
// 10 or above
|
||||||
|
if ((int8_t)val >= 0)
|
||||||
|
val += ('a' - '0' - 10);
|
||||||
|
|
||||||
|
return val + ('0' + 10);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+12
-1
@@ -47,6 +47,15 @@
|
|||||||
#define IS_SFP(port) (i == maxPort || i == 3)
|
#define IS_SFP(port) (i == maxPort || i == 3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CONFIG_START 0x70000
|
||||||
|
#define CONFIG_LEN 0x1000
|
||||||
|
#define CODE0_SIZE 0x4000
|
||||||
|
#define CODE_BANK_SIZE 0xc000
|
||||||
|
|
||||||
|
// Constants for the circular command buffer, the size must be 2^n
|
||||||
|
#define CMD_HISTORY_SIZE 0x400
|
||||||
|
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of a 48-bit Ethernet address.
|
* Representation of a 48-bit Ethernet address.
|
||||||
*/
|
*/
|
||||||
@@ -94,6 +103,8 @@ uint16_t strlen_x(register __xdata const char *s);
|
|||||||
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
||||||
void tcpip_output(void);
|
void tcpip_output(void);
|
||||||
void print_string_x(__xdata char *p);
|
void print_string_x(__xdata char *p);
|
||||||
|
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||||
|
void get_random_32(void);
|
||||||
|
void read_reg_timer(uint32_t * tmr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -170,6 +170,13 @@
|
|||||||
#define EEE_1000 0x04
|
#define EEE_1000 0x04
|
||||||
#define EEE_2G5 0x10
|
#define EEE_2G5 0x10
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RANDOM
|
||||||
|
*/
|
||||||
|
#define RTL837X_RLDP_RLPP 0x106C
|
||||||
|
#define RLDP_RND_EN 3
|
||||||
|
#define RTL837X_RAND_NUM0 0x107C
|
||||||
|
#define RTL837X_RAND_NUM1 0x1080
|
||||||
|
|
||||||
#ifdef REGDBG
|
#ifdef REGDBG
|
||||||
|
|
||||||
|
|||||||
@@ -402,6 +402,18 @@ void sfr_set_zero(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create 32 random number in sfr_data
|
||||||
|
*/
|
||||||
|
void get_random_32(void)
|
||||||
|
{
|
||||||
|
// In order to get a new random numner, this bit has to be set each time!
|
||||||
|
reg_bit_set(RTL837X_RLDP_RLPP, RLDP_RND_EN);
|
||||||
|
reg_read_m(RTL837X_RAND_NUM0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transfer Network Interface RX data from the ASIC to the 8051 XMEM
|
* Transfer Network Interface RX data from the ASIC to the 8051 XMEM
|
||||||
* data will be stored in the rx_header structure
|
* data will be stored in the rx_header structure
|
||||||
@@ -590,6 +602,20 @@ void cpy_4(__xdata uint8_t dest[], __xdata uint8_t source[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void read_reg_timer(uint32_t * tmr)
|
||||||
|
{
|
||||||
|
uint8_t * val = (uint8_t *)tmr;
|
||||||
|
SFR_REG_ADDR_U16 = RTL837X_REG_SEC_COUNTER;
|
||||||
|
SFR_EXEC_GO = SFR_EXEC_READ_REG;
|
||||||
|
do {
|
||||||
|
} while (SFR_EXEC_STATUS != 0);
|
||||||
|
*val++ = SFR_DATA_0;
|
||||||
|
*val++ = SFR_DATA_8;
|
||||||
|
*val++ = SFR_DATA_16;
|
||||||
|
*val = SFR_DATA_24;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void sds_config_mac(uint8_t sds, uint8_t mode)
|
void sds_config_mac(uint8_t sds, uint8_t mode)
|
||||||
{
|
{
|
||||||
reg_read_m(RTL837X_REG_SDS_MODES);
|
reg_read_m(RTL837X_REG_SDS_MODES);
|
||||||
|
|||||||
+171
-20
@@ -4,14 +4,20 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "httpd_sim.h"
|
#include "httpd_sim.h"
|
||||||
#include <json.h>
|
#include <json.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
|
#define SESSION_ID "1234567890ab"
|
||||||
|
#define PASSWORD "1234"
|
||||||
|
#define SESSION_TIMEOUT 20
|
||||||
|
|
||||||
#define PORTS 6
|
#define PORTS 6
|
||||||
time_t last_called;
|
time_t last_called;
|
||||||
|
time_t last_session_use;
|
||||||
|
|
||||||
uint64_t txG[PORTS], txB[PORTS], rxG[PORTS], rxB[PORTS];
|
uint64_t txG[PORTS], txB[PORTS], rxG[PORTS], rxB[PORTS];
|
||||||
char txG_buff[20], txB_buff[20], rxG_buff[20], rxB_buff[20];
|
char txG_buff[20], txB_buff[20], rxG_buff[20], rxB_buff[20];
|
||||||
@@ -20,6 +26,12 @@ char upload_buffer[4194304]; // 4MB
|
|||||||
|
|
||||||
char *content_type = NULL;
|
char *content_type = NULL;
|
||||||
char boundary[72];
|
char boundary[72];
|
||||||
|
char cmd_history[1024][256];
|
||||||
|
uint16_t cmd_ptr = 0;
|
||||||
|
char *uploaded_config = NULL;
|
||||||
|
int uploaded_config_len;
|
||||||
|
const char *session = NULL;
|
||||||
|
bool authenticated = false;
|
||||||
|
|
||||||
char is_word(char *c, char *d)
|
char is_word(char *c, char *d)
|
||||||
{
|
{
|
||||||
@@ -101,8 +113,10 @@ void send_status(int s)
|
|||||||
struct json_object *ports, *v;
|
struct json_object *ports, *v;
|
||||||
const char *jstring;
|
const char *jstring;
|
||||||
char *header = "HTTP/1.1 200 OK\r\n"
|
char *header = "HTTP/1.1 200 OK\r\n"
|
||||||
"Content-Type: application/json; charset=UTF-8\r\n\r\n";
|
"Cache-Control: no-cache\r\n"
|
||||||
|
"Content-Type: application/json; charset=UTF-8\r\n\r\n";
|
||||||
|
|
||||||
|
printf("Sending status.\n");
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
now = last_called ? last_called + 1 : now; // Make sure we don't divide by 0 for rates
|
now = last_called ? last_called + 1 : now; // Make sure we don't divide by 0 for rates
|
||||||
|
|
||||||
@@ -202,6 +216,32 @@ void send_mirror(int s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_cmd_log(int s)
|
||||||
|
{
|
||||||
|
char *header = "HTTP/1.1 200 OK\r\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\r\n\r\n";
|
||||||
|
write(s, header, strlen(header));
|
||||||
|
|
||||||
|
for (int i = 0; i < cmd_ptr; i++) {
|
||||||
|
write(s, cmd_history[i], strlen(cmd_history[i]));
|
||||||
|
write(s, "\n", 1);
|
||||||
|
printf("%d: %s\n", i, cmd_history[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_config(int s)
|
||||||
|
{
|
||||||
|
char *header = "HTTP/1.1 200 OK\r\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\r\n\r\n";
|
||||||
|
printf("Sending uploaded config\n");
|
||||||
|
write(s, header, strlen(header));
|
||||||
|
printf("Uploaded config len: %d\n", uploaded_config_len);
|
||||||
|
printf(">%s<", uploaded_config);
|
||||||
|
write(s, uploaded_config, uploaded_config_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Server serverConstructor(int port, void (*launch)(struct Server *server)) {
|
struct Server serverConstructor(int port, void (*launch)(struct Server *server)) {
|
||||||
struct Server server;
|
struct Server server;
|
||||||
|
|
||||||
@@ -253,13 +293,30 @@ void send_bad_request(int socket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_to_login(int socket) {
|
||||||
|
char *response = "HTTP/1.1 302 Found\r\n"
|
||||||
|
"Location: login.html\r\n\r\n";
|
||||||
|
write(socket, response, strlen(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_unauthorized(int socket) {
|
||||||
|
char *response = "HTTP/1.1 401 Unauthorized\r\n\r\n";
|
||||||
|
write(socket, response, strlen(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *scan_header(char *p)
|
char *scan_header(char *p)
|
||||||
{
|
{
|
||||||
|
session = 0;
|
||||||
|
authenticated = false;
|
||||||
while (*p != '\r' || *(p + 1) != '\n' || *(p + 2) != '\r' || *(p + 3) != '\n') {
|
while (*p != '\r' || *(p + 1) != '\n' || *(p + 2) != '\r' || *(p + 3) != '\n') {
|
||||||
if (!*p++)
|
if (!*p++)
|
||||||
break;
|
break;
|
||||||
if (*p == '\n' && is_word(p + 1, "Content-Type:"))
|
if (is_word(p, "\nContent-Type:"))
|
||||||
content_type = p + 15;
|
content_type = p + 15;
|
||||||
|
else if (is_word(p, "\nCookie:"))
|
||||||
|
session = p + 17;
|
||||||
}
|
}
|
||||||
if (content_type && is_word(content_type, "multipart/form-data; boundary")) {
|
if (content_type && is_word(content_type, "multipart/form-data; boundary")) {
|
||||||
printf("Found multiplart\n");
|
printf("Found multiplart\n");
|
||||||
@@ -275,6 +332,19 @@ char *scan_header(char *p)
|
|||||||
boundary[i + 2] = 0;
|
boundary[i + 2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
if (session) {
|
||||||
|
printf("Session: >%s<. time now: %ld last %ld\n", session, now, last_session_use);
|
||||||
|
if (now - last_session_use > SESSION_TIMEOUT) {
|
||||||
|
printf("Session expired\n");
|
||||||
|
} else {
|
||||||
|
if (!strncmp(session, SESSION_ID, 12))
|
||||||
|
authenticated = true;
|
||||||
|
else
|
||||||
|
printf("Invalid session cookie!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Time now: %ld last %ld\n", now, last_session_use);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,6 +359,11 @@ char *skip_boundary(char *p)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_cmd_history(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cmd_ptr; i++)
|
||||||
|
printf("%d: %s\n", i, cmd_history[i]);
|
||||||
|
}
|
||||||
|
|
||||||
void launch(struct Server *server)
|
void launch(struct Server *server)
|
||||||
{
|
{
|
||||||
@@ -313,33 +388,66 @@ void launch(struct Server *server)
|
|||||||
puts(buffer);
|
puts(buffer);
|
||||||
|
|
||||||
if (is_word(buffer, "GET")) {
|
if (is_word(buffer, "GET")) {
|
||||||
printf("GET request\n");
|
scan_header(buffer);
|
||||||
if (!strncmp(&buffer[4], "/status.json", 12)) {
|
if (!strncmp(&buffer[4], "/status.json", 12)) {
|
||||||
printf("Status request\n");
|
printf("Status request\n");
|
||||||
send_status(new_socket);
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_status(new_socket);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
} else if (!strncmp(&buffer[4], "/eee.json", 9)) {
|
||||||
if (!strncmp(&buffer[4], "/eee.json", 9)) {
|
|
||||||
printf("EEE request\n");
|
printf("EEE request\n");
|
||||||
send_eee(new_socket);
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_eee(new_socket);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
} else if (!strncmp(&buffer[4], "/information.json", 17)) {
|
||||||
if (!strncmp(&buffer[4], "/information.json", 12)) {
|
|
||||||
printf("Status request\n");
|
printf("Status request\n");
|
||||||
send_basic_info(new_socket);
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_basic_info(new_socket);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
} else if (!strncmp(&buffer[4], "/mirror.json", 12)) {
|
||||||
if (!strncmp(&buffer[4], "/mirror.json", 12)) {
|
|
||||||
printf("Mirror request\n");
|
printf("Mirror request\n");
|
||||||
send_mirror(new_socket);
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_mirror(new_socket);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
} else if (!strncmp(&buffer[4], "/vlan.json?vid=", 15)) {
|
||||||
if (!strncmp(&buffer[4], "/vlan.json?vid=", 15)) {
|
|
||||||
int vlan = atoi(&buffer[19]);
|
int vlan = atoi(&buffer[19]);
|
||||||
printf("VLAN request for %d\n", vlan);
|
printf("VLAN request for %d\n", vlan);
|
||||||
send_vlan(new_socket, vlan);
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_vlan(new_socket, vlan);
|
||||||
|
goto done;
|
||||||
|
} else if (!strncmp(&buffer[4], "/cmd_log", 8)) {
|
||||||
|
printf("Request cmd_log\n");
|
||||||
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_cmd_log(new_socket);
|
||||||
|
goto done;
|
||||||
|
} else if (!strncmp(&buffer[4], "/config ", 8) && uploaded_config) {
|
||||||
|
printf("Request current config.\n");
|
||||||
|
if (!authenticated)
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
else
|
||||||
|
send_config(new_socket);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!authenticated && !(!strncmp(&buffer[4], "/login.html", 11) || !strncmp(&buffer[4], "/style.css", 10))) {
|
||||||
|
send_to_login(new_socket);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A web-page is actively accessed, we can reset session time-out
|
||||||
|
last_session_use = time(NULL);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (!isspace(buffer[4 + i]))
|
while (!isspace(buffer[4 + i]))
|
||||||
i++;
|
i++;
|
||||||
@@ -389,10 +497,44 @@ void launch(struct Server *server)
|
|||||||
send_bad_request(new_socket);
|
send_bad_request(new_socket);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!authenticated && !is_word(&buffer[5], "/login")) {
|
||||||
|
send_unauthorized(new_socket);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
printf("Bytes read %ld\n", bytesRead);
|
printf("Bytes read %ld\n", bytesRead);
|
||||||
if (is_word(&buffer[5], "/upload")) {
|
if (is_word(&buffer[5], "/cmd")) {
|
||||||
printf("POST upload request\n");
|
printf("POST cmd\n");
|
||||||
|
printf("CMD: %s\n", p + 4);
|
||||||
|
strcpy(cmd_history[cmd_ptr], p + 4);
|
||||||
|
cmd_ptr++;
|
||||||
|
print_cmd_history();
|
||||||
|
char *response = "HTTP/1.1 200 OK\r\n"
|
||||||
|
"Content-Type: text/html\r\n\r\n"
|
||||||
|
"<!DOCTYPE html> <html><head><title>Upload OK</title></head>"
|
||||||
|
"<body><h1>Command executed successully</h1></html>";
|
||||||
|
write(new_socket, response, strlen(response));
|
||||||
|
goto done;
|
||||||
|
} else if (is_word(&buffer[5], "/login")) {
|
||||||
|
printf("POST login\n");
|
||||||
|
p += 4;
|
||||||
|
p += 4; // Read also over "pwd="
|
||||||
|
char *response;
|
||||||
|
if (is_word(p, PASSWORD)) {
|
||||||
|
printf("Password accepted!\n");
|
||||||
|
response = "HTTP/1.1 302 Found\r\n"
|
||||||
|
"Location: index.html\r\n"
|
||||||
|
"Set-Cookie: session=" SESSION_ID "; SameSite=Strict\r\n";
|
||||||
|
} else {
|
||||||
|
response = "HTTP/1.1 302 Found\r\n"
|
||||||
|
"Location: login.html\r\n\r\n";
|
||||||
|
}
|
||||||
|
write(new_socket, response, strlen(response));
|
||||||
|
goto done;
|
||||||
|
} else if (is_word(&buffer[5], "/upload") || is_word(&buffer[5], "/config")) {
|
||||||
|
printf("POST upload/config request\n");
|
||||||
|
bool config_upload = false;
|
||||||
|
if (is_word(&buffer[5], "/config"))
|
||||||
|
config_upload = true;
|
||||||
if (!boundary[0]) {
|
if (!boundary[0]) {
|
||||||
printf("Bad request, no boundary!\n");
|
printf("Bad request, no boundary!\n");
|
||||||
send_bad_request(new_socket);
|
send_bad_request(new_socket);
|
||||||
@@ -409,6 +551,7 @@ void launch(struct Server *server)
|
|||||||
} while (!is_word(content_type, "application/octet-stream"));
|
} while (!is_word(content_type, "application/octet-stream"));
|
||||||
printf("Have content: >%s<\n", content_type);
|
printf("Have content: >%s<\n", content_type);
|
||||||
|
|
||||||
|
p += 4; // Skip \r\n\r\n after content type
|
||||||
char *uptr = upload_buffer;
|
char *uptr = upload_buffer;
|
||||||
int bindex = 0;
|
int bindex = 0;
|
||||||
int bptr = p - buffer;
|
int bptr = p - buffer;
|
||||||
@@ -441,11 +584,19 @@ void launch(struct Server *server)
|
|||||||
"<!DOCTYPE html> <html><head><title>Upload OK</title></head>"
|
"<!DOCTYPE html> <html><head><title>Upload OK</title></head>"
|
||||||
"<body><h1>File uploaded successully</h1></html>";
|
"<body><h1>File uploaded successully</h1></html>";
|
||||||
write(new_socket, response, strlen(response));
|
write(new_socket, response, strlen(response));
|
||||||
|
if (config_upload) {
|
||||||
|
uploaded_config_len = (uptr - upload_buffer);
|
||||||
|
if (uploaded_config)
|
||||||
|
free (uploaded_config);
|
||||||
|
uploaded_config = malloc(uploaded_config_len + 1);
|
||||||
|
memcpy(uploaded_config, upload_buffer, uploaded_config_len);
|
||||||
|
}
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char *response = "HTTP/1.1 200 OK\r\n"
|
char *response = "HTTP/1.1 200 OK\r\n"
|
||||||
"Content-Type: ";
|
"Cache-Control: max-age=60, must-revalidate\r\n"
|
||||||
|
"Content-Type: ";
|
||||||
write(new_socket, response, strlen(response));
|
write(new_socket, response, strlen(response));
|
||||||
|
|
||||||
write(new_socket, mime, strlen(mime));
|
write(new_socket, mime, strlen(mime));
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#define BUFFER_SIZE 2400
|
#define BUFFER_SIZE 24000
|
||||||
|
|
||||||
struct Server {
|
struct Server {
|
||||||
int domain;
|
int domain;
|
||||||
|
|||||||
Reference in New Issue
Block a user