mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
cmd_parser: parse mac into a global result buffer
parse_mac() now writes to the global mac_parse_result[6] and takes only the index, like the other parsers (ip[4]). This drops the local __xdata buffer and the now-unused hexval() helper. Build (KP_9000_9XHML_X_V3_1): ROM 110302 -> 110193 bytes, XSEG and internal RAM unchanged.
This commit is contained in:
1 parent
dc4fb5becc
commit
12fb6fd809
2 files changed
+43
-51
No files matched your search
+43
-50
@@ -66,6 +66,7 @@ __xdata uint8_t cmd_available;
|
|||||||
__xdata char save_cmd;
|
__xdata char save_cmd;
|
||||||
|
|
||||||
__xdata uint8_t ip[4];
|
__xdata uint8_t ip[4];
|
||||||
|
__xdata uint8_t mac_parse_result[6];
|
||||||
|
|
||||||
/* Scratch for parse_syslog(), in xdata: a local here would take internal RAM
|
/* Scratch for parse_syslog(), in xdata: a local here would take internal RAM
|
||||||
* the linker has none of. */
|
* the linker has none of. */
|
||||||
@@ -106,19 +107,6 @@ inline uint8_t isnumber(uint8_t l)
|
|||||||
return (l <= ('9'-'0'));
|
return (l <= ('9'-'0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Converts a single ASCII hex digit to its value, or 0xff if it is not a valid
|
|
||||||
* hex digit. Accepts '0'-'9', 'a'-'f' and 'A'-'F'. */
|
|
||||||
inline uint8_t hexval(uint8_t c)
|
|
||||||
{
|
|
||||||
if (isnumber(c))
|
|
||||||
return c - '0';
|
|
||||||
c |= 0x20;
|
|
||||||
if (c >= 'a' && c <= 'f')
|
|
||||||
return c - 'a' + 10;
|
|
||||||
return 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t cmd_compare(uint8_t start, __code uint8_t * cmd)
|
uint8_t cmd_compare(uint8_t start, __code uint8_t * cmd)
|
||||||
{
|
{
|
||||||
if (cmd_words_len == 0 || start > (cmd_words_len - 1)) {
|
if (cmd_words_len == 0 || start > (cmd_words_len - 1)) {
|
||||||
@@ -392,45 +380,52 @@ void print_mac(__xdata uint8_t *ptr) __banked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a strict MAC address "aa:bb:cc:dd:ee:ff" (or "-" separators) from
|
// Parses a MAC address "aa:bb:cc:dd:ee:ff" (":" or "-" separators) from
|
||||||
// cmd_buffer starting at idx into mac[6]. Each of the 6 octets must be exactly
|
// cmd_buffer starting at idx into the global mac_parse_result[6]. Each octet
|
||||||
// two hex digits and the 5 separators must be the same single character, so
|
// must be exactly two hex digits with a separator between octets and nothing
|
||||||
// malformed input like repeated separators ("aa::bb"), missing digits or a
|
// trailing, so repeated separators, missing digits or a trailing hex digit are
|
||||||
// trailing hex digit ("aa:bb:cc:dd:ee:ff:0") is rejected. Returns the number of
|
// rejected. Returns the number of bytes consumed, or 0 on error.
|
||||||
// bytes consumed, or 0 on error.
|
uint8_t parse_mac(uint8_t idx)
|
||||||
uint8_t parse_mac(uint8_t idx, __xdata uint8_t *mac)
|
|
||||||
{
|
{
|
||||||
uint8_t sep = 0;
|
|
||||||
uint8_t b = 0;
|
uint8_t b = 0;
|
||||||
uint8_t c;
|
uint8_t c = ':';
|
||||||
uint8_t hi;
|
|
||||||
uint8_t lo;
|
|
||||||
|
|
||||||
while (b < 6) {
|
do {
|
||||||
hi = hexval(cmd_buffer[idx++]);
|
|
||||||
lo = hexval(cmd_buffer[idx++]);
|
|
||||||
if (hi == 0xff || lo == 0xff)
|
|
||||||
return 0;
|
|
||||||
mac[b++] = (hi << 4) | lo;
|
|
||||||
|
|
||||||
if (b == 6)
|
|
||||||
break;
|
|
||||||
c = cmd_buffer[idx];
|
|
||||||
if (c != ':' && c != '-')
|
if (c != ':' && c != '-')
|
||||||
return 0;
|
goto err;
|
||||||
if (sep == 0)
|
|
||||||
sep = c;
|
__bit again = true;
|
||||||
else if (c != sep)
|
uint8_t v = 0;
|
||||||
return 0;
|
|
||||||
idx++;
|
while(1) {
|
||||||
|
c = cmd_buffer[idx++];
|
||||||
|
c -= '0';
|
||||||
|
if (c > 9) {
|
||||||
|
c |= 0x20;
|
||||||
|
c += '0' - 'a';
|
||||||
|
if (c > 5)
|
||||||
|
goto err;
|
||||||
|
c += 10;
|
||||||
}
|
}
|
||||||
|
// force swap-instr.
|
||||||
|
v = (v << 4) | (v >> 4);
|
||||||
|
v |= c;
|
||||||
|
|
||||||
// No trailing characters: the next byte must be a separator-like EOF.
|
if (again)
|
||||||
c = cmd_buffer[idx];
|
again = false;
|
||||||
if (c != NUL && c != ' ')
|
else
|
||||||
return 0;
|
break;
|
||||||
|
}
|
||||||
|
mac_parse_result[b++] = v;
|
||||||
|
|
||||||
|
c = cmd_buffer[idx++];
|
||||||
|
} while(b < 6);
|
||||||
|
|
||||||
|
if (c == ' ' || c == NUL)
|
||||||
return idx;
|
return idx;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the management MAC from a "mac <aa:bb:cc:dd:ee:ff>" command (or prints
|
// Sets the management MAC from a "mac <aa:bb:cc:dd:ee:ff>" command (or prints
|
||||||
@@ -441,23 +436,21 @@ uint8_t parse_mac(uint8_t idx, __xdata uint8_t *mac)
|
|||||||
// on every boot (execute_config runs before the final static L2 entry).
|
// on every boot (execute_config runs before the final static L2 entry).
|
||||||
void parse_mac_cmd(void)
|
void parse_mac_cmd(void)
|
||||||
{
|
{
|
||||||
__xdata uint8_t mac[6];
|
|
||||||
|
|
||||||
if (cmd_words_len == 1) {
|
if (cmd_words_len == 1) {
|
||||||
print_string("Current MAC: ");
|
print_string("Current MAC: ");
|
||||||
print_mac(uip_ethaddr.addr);
|
print_mac(uip_ethaddr.addr);
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cmd_words_len != 2 || !parse_mac(cmd_words_b[1], mac)) {
|
if (cmd_words_len != 2 || !parse_mac(cmd_words_b[1])) {
|
||||||
print_string("Error: mac [<aa:bb:cc:dd:ee:ff>]\n");
|
print_string("Error: mac [<aa:bb:cc:dd:ee:ff>]\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((mac[0] & 0x03) || ((mac[0] | mac[1] | mac[2]) == 0)) {
|
if ((mac_parse_result[0] & 0x03) || ((mac_parse_result[0] | mac_parse_result[1] | mac_parse_result[2]) == 0)) {
|
||||||
print_string("refusing: must be unicast, globally administered\n");
|
print_string("refusing: must be unicast, globally administered\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (memcmp(mac, uip_ethaddr.addr, 6) == 0) {
|
if (memcmp(mac_parse_result, uip_ethaddr.addr, 6) == 0) {
|
||||||
print_string("MAC unchanged\n");
|
print_string("MAC unchanged\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -465,7 +458,7 @@ void parse_mac_cmd(void)
|
|||||||
// Swap the static management entry over to the new address: remove the
|
// Swap the static management entry over to the new address: remove the
|
||||||
// old one (still in uip_ethaddr) before overwriting it.
|
// old one (still in uip_ethaddr) before overwriting it.
|
||||||
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, true);
|
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, true);
|
||||||
memcpy(uip_ethaddr.addr, mac, 6);
|
memcpy(uip_ethaddr.addr, mac_parse_result, 6);
|
||||||
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, false);
|
port_l2_static_mgmt(uip_ethaddr.addr, management_vlan, false);
|
||||||
|
|
||||||
print_string("MAC set to: ");
|
print_string("MAC set to: ");
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ void execute_config(void) __banked;
|
|||||||
void execute_commands(__xdata uint8_t *p) __banked;
|
void execute_commands(__xdata uint8_t *p) __banked;
|
||||||
void print_ip(__xdata uint8_t *ptr) __banked;
|
void print_ip(__xdata uint8_t *ptr) __banked;
|
||||||
void print_mac(__xdata uint8_t *ptr) __banked;
|
void print_mac(__xdata uint8_t *ptr) __banked;
|
||||||
uint8_t parse_mac(uint8_t idx, __xdata uint8_t *mac);
|
|
||||||
void print_sw_version(void) __banked;
|
void print_sw_version(void) __banked;
|
||||||
void clear_command_history(void) __banked;
|
void clear_command_history(void) __banked;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user