15 Commits
15 changed files with 439 additions and 58 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ create_build_dir:
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c \ SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c \
rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-neighbor.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel
html_data.c html_data.h: html tools html_data.c html_data.h: html tools
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
+19
View File
@@ -44,6 +44,7 @@ extern __xdata struct dhcp_state dhcp_state;
__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;
extern __xdata uint16_t management_vlan; extern __xdata uint16_t management_vlan;
extern __xdata uint16_t dhcpd_vlan;
__xdata uint8_t gpio_last_value[8] = { 0 }; __xdata uint8_t gpio_last_value[8] = { 0 };
// Temporatly for str to hex convertion value. // Temporatly for str to hex convertion value.
@@ -992,6 +993,24 @@ void cmd_parser(void) __banked
stp_off(); stp_off();
stpEnabled = 0; stpEnabled = 0;
} }
} else if (cmd_compare(0, "dhcp")) {
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
dhcp_start();
} else {
print_string("DHCP disabled\n");
dhcp_stop();
}
} else if (cmd_compare(0, "dhcpd")) {
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
if (cmd_words_b[2] > 0)
atoi_short(&dhcpd_vlan, cmd_words_b[2]);
else
dhcpd_vlan = 0;
dhcpd_start();
} else {
print_string("DHCP Server disabled\n");
dhcpd_stop();
}
} else if (cmd_compare(0, "pvid") && cmd_words_b[1] > 0 && cmd_words_b[2] > 0) { } else if (cmd_compare(0, "pvid") && cmd_words_b[1] > 0 && cmd_words_b[2] > 0) {
__xdata uint16_t pvid; __xdata uint16_t pvid;
uint8_t port; uint8_t port;
+268 -21
View File
@@ -15,6 +15,9 @@
__xdata struct dhcp_state dhcp_state; __xdata struct dhcp_state dhcp_state;
__xdata uip_ipaddr_t server; __xdata uip_ipaddr_t server;
#define BOOTP_REQUEST 1
#define BOOTP_REPY 2
#define DHCP_HW_TYPE_ETH 1 #define DHCP_HW_TYPE_ETH 1
#define DHCP_SUBNET_MASK 1 #define DHCP_SUBNET_MASK 1
@@ -32,6 +35,7 @@ __xdata uip_ipaddr_t server;
#define DHCP_MESSAGE_DISCOVER 1 #define DHCP_MESSAGE_DISCOVER 1
#define DHCP_MESSAGE_OFFER 2 #define DHCP_MESSAGE_OFFER 2
#define DHCP_MESSAGE_REQUEST 3 #define DHCP_MESSAGE_REQUEST 3
#define DHCP_MESSAGE_NACK 4
#define DHCP_MESSAGE_ACK 5 #define DHCP_MESSAGE_ACK 5
#define DHCP_LEASE 51 #define DHCP_LEASE 51
#define DHCP_LEASE_LEN 4 #define DHCP_LEASE_LEN 4
@@ -43,15 +47,23 @@ __xdata uip_ipaddr_t server;
#define DHCP_CLIENT_ID_LEN 7 #define DHCP_CLIENT_ID_LEN 7
#define DHCP_REQUEST_IP 50 #define DHCP_REQUEST_IP 50
#define DHCP_REQUEST_IP_LEN 4 #define DHCP_REQUEST_IP_LEN 4
#define DHCP_CLIENT_NAME 12
#define DHCP_PARAMS 55 #define DHCP_PARAMS 55
#define DHCP_VENDOR_ID 60
#define DHCP_CLIENT_ID 61
#define DHCP_PARAM_SUBNET 1 #define DHCP_PARAM_SUBNET 1
#define DHCP_PARAM_ROUTER 3 #define DHCP_PARAM_ROUTER 3
#define DHCP_PARAM_DNS 6 #define DHCP_PARAM_DNS 6
#define DHCP_END 255 #define DHCP_END 255
#define LEASE_TIME 43200
#define RENEWAL_TIME 21600
#define REBIND_TIME 21600
#pragma codeseg BANK2 #pragma codeseg BANK2
#pragma constseg BANK2 #pragma constseg BANK2
struct dhcp_pkt { struct dhcp_pkt {
uint8_t type; uint8_t type;
uint8_t hw; uint8_t hw;
@@ -71,16 +83,13 @@ struct dhcp_pkt {
uint8_t cookie[4]; uint8_t cookie[4];
}; };
/*
#define DHCP_P ((__xdata struct dhcp_pkt *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
#define DHCP_OPT ((__xdata uint8_t *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE + sizeof (struct dhcp_pkt)])
*/
#define DHCP_P ((__xdata struct dhcp_pkt *)uip_appdata) #define DHCP_P ((__xdata struct dhcp_pkt *)uip_appdata)
#define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt)) #define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt))
__xdata uint32_t long_value; __xdata uint32_t long_value;
__xdata struct dhcpd_cstate cstates[DHCPD_MAX_CLIENTS];
__xdata uint8_t client_idx;
__xdata uint16_t dhcpd_vlan;
void dhcp_print_ip(uint8_t *a) void dhcp_print_ip(uint8_t *a)
{ {
@@ -91,14 +100,14 @@ void dhcp_print_ip(uint8_t *a)
} }
void dhcp_prepare_request(void) void dhcp_prepare_msg(void)
{ {
DHCP_P->type = 1; DHCP_P->type = BOOTP_REQUEST;
DHCP_P->hw = DHCP_HW_TYPE_ETH; DHCP_P->hw = DHCP_HW_TYPE_ETH;
DHCP_P->hw_len = 6; DHCP_P->hw_len = 6;
DHCP_P->hops = 0; DHCP_P->hops = 0;
DHCP_P->tid = HTONS(dhcp_state.transaction_id); DHCP_P->tid = dhcp_state.transaction_id; // In network byte order
DHCP_P->delay = HTONS(0); DHCP_P->delay = HTONS(0);
DHCP_P->flags = 0; DHCP_P->flags = 0;
// Clear fields client_ip to bootp_file // Clear fields client_ip to bootp_file
@@ -129,7 +138,6 @@ void dhcp_addopt_request_ip(void)
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
} }
@@ -141,14 +149,68 @@ void dhcp_addopt_server_id(void)
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4); }
void dhcp_addopt_subnet(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SUBNET_MASK;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SUBNET_MASK_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[0];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[3];
}
void dhcp_addopt_router(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_ROUTER;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_ROUTER_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[0];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[3];
}
void dhcp_addopt_lease(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_LEASE;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_LEASE_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = LEASE_TIME >> 8;
DHCP_OPT[dhcp_state.opt_ptr++] = LEASE_TIME & 0xff;
}
void dhcp_addopt_renewal(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_RENEWAL;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_RENEWAL_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = RENEWAL_TIME >> 8;
DHCP_OPT[dhcp_state.opt_ptr++] = RENEWAL_TIME & 0xff;
}
void dhcp_addopt_rebind(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REBIND;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REBIND_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = REBIND_TIME >> 8;
DHCP_OPT[dhcp_state.opt_ptr++] = REBIND_TIME & 0xff;
} }
void dhcp_send_discover(void) void dhcp_send_discover(void)
{ {
print_string("dhcp_send_discover called\n"); print_string("dhcp_send_discover called\n");
dhcp_prepare_request(); dhcp_prepare_msg();
dhcp_state.opt_ptr = 0; dhcp_state.opt_ptr = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE; DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
@@ -183,7 +245,7 @@ void dhcp_send_discover(void)
void dhcp_send_request(void) void dhcp_send_request(void)
{ {
print_string("dhcp_send_request called\n"); print_string("dhcp_send_request called\n");
dhcp_prepare_request(); dhcp_prepare_msg();
dhcp_state.opt_ptr = 0; dhcp_state.opt_ptr = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE; DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
@@ -216,6 +278,41 @@ void dhcp_send_request(void)
} }
void dhcp_send_reply(uint8_t rtype)
{
print_string("dhcp_send_reply called\n");
dhcp_prepare_msg();
DHCP_P->type = BOOTP_REPY;
DHCP_P->client_addr[0] = cstates[client_idx].mac[0]; DHCP_P->client_addr[1] = cstates[client_idx].mac[1];
DHCP_P->client_addr[2] = cstates[client_idx].mac[2]; DHCP_P->client_addr[3] = cstates[client_idx].mac[3];
DHCP_P->client_addr[4] = cstates[client_idx].mac[4]; DHCP_P->client_addr[5] = cstates[client_idx].mac[5];
if (rtype != DHCP_MESSAGE_NACK) {
DHCP_P->your_ip[0] = dhcp_state.server[0];
DHCP_P->your_ip[1] = dhcp_state.server[1];
DHCP_P->your_ip[2] = dhcp_state.server[2];
DHCP_P->your_ip[3] = DHCPD_START_IP + client_idx;
}
dhcp_state.opt_ptr = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = rtype;
if (rtype != DHCP_MESSAGE_NACK) {
dhcp_addopt_subnet();
dhcp_addopt_router();
dhcp_addopt_server_id();
dhcp_addopt_rebind();
dhcp_addopt_lease();
dhcp_addopt_renewal();
}
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_END;
uip_udp_send(sizeof(struct dhcp_pkt) + dhcp_state.opt_ptr);
}
void ip_opt(uint8_t * __xdata ip) void ip_opt(uint8_t * __xdata ip)
{ {
dhcp_state.opt_ptr++; dhcp_state.opt_ptr++;
@@ -243,6 +340,22 @@ void long_opt(void)
} }
void print_txt_opt(void)
{
dhcp_state.opt_ptr++;
for (uint8_t l = DHCP_OPT[dhcp_state.opt_ptr++]; l ; l--)
write_char(DHCP_OPT[dhcp_state.opt_ptr++]);
}
void print_eth_opt(void)
{
dhcp_state.opt_ptr++;
for (uint8_t l = DHCP_OPT[dhcp_state.opt_ptr++]; l ; l--)
print_byte(DHCP_OPT[dhcp_state.opt_ptr++]);
}
void parse_opts(void) void parse_opts(void)
{ {
while (DHCP_OPT[dhcp_state.opt_ptr] && DHCP_OPT[dhcp_state.opt_ptr] != DHCP_END) { while (DHCP_OPT[dhcp_state.opt_ptr] && DHCP_OPT[dhcp_state.opt_ptr] != DHCP_END) {
@@ -262,6 +375,9 @@ void parse_opts(void)
case DHCP_BROADCAST: case DHCP_BROADCAST:
ip_opt(&dhcp_state.broadcast[0]); ip_opt(&dhcp_state.broadcast[0]);
break; break;
case DHCP_REQUEST_IP:
ip_opt(&dhcp_state.current_ip[0]);
break;
case DHCP_LEASE: case DHCP_LEASE:
long_opt(); long_opt();
dhcp_state.lease = long_value; dhcp_state.lease = long_value;
@@ -274,6 +390,27 @@ void parse_opts(void)
long_opt(); long_opt();
dhcp_state.renewal = long_value; dhcp_state.renewal = long_value;
break; break;
case DHCP_CLIENT_NAME:
print_string("Client name: ");
print_txt_opt();
write_char('\n');
break;
case DHCP_VENDOR_ID:
print_string("Vendor ID: ");
print_txt_opt();
write_char('\n');
break;
case DHCP_CLIENT_ID:
print_string("Client ID: ");
print_eth_opt();
write_char('\n');
break;
case DHCP_PARAMS:
print_string("PARAMS request (ignored)\n");
dhcp_state.opt_ptr++;
dhcp_state.opt_ptr += DHCP_OPT[dhcp_state.opt_ptr];
dhcp_state.opt_ptr++;
break;
case DHCP_END: case DHCP_END:
break; break;
default: default:
@@ -286,9 +423,39 @@ void parse_opts(void)
} }
void parse_dhcp(void) void find_client(void)
{ {
if (!DHCP_P->tid == HTONS(dhcp_state.transaction_id)) uint8_t i;
for (i = 0; i < DHCPD_MAX_CLIENTS; i++) {
if (cstates[i].mac[0] == DHCP_P->client_addr[0] && cstates[i].mac[1] == DHCP_P->client_addr[1]
&& cstates[i].mac[2] == DHCP_P->client_addr[2] && cstates[i].mac[3] == DHCP_P->client_addr[3]
&& cstates[i].mac[4] == DHCP_P->client_addr[4] && cstates[i].mac[5] == DHCP_P->client_addr[5]
)
break;
}
if (i < DHCPD_MAX_CLIENTS) {
client_idx = i;
return;
}
client_idx = 255;
}
void find_slot(void)
{
for (client_idx = 0; client_idx < DHCPD_MAX_CLIENTS; client_idx++) {
if (!cstates[client_idx].cstate)
return;
}
client_idx = 255;
return;
}
void parse_dhcp_response(void)
{
if (!DHCP_P->tid == dhcp_state.transaction_id)
return; return;
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63) if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
return; return;
@@ -327,13 +494,50 @@ void parse_dhcp(void)
} }
void parse_dhcp_request(void)
{
print_string("parse_dhcp_request called\n");
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
return;
dhcp_state.opt_ptr = 0;
if (DHCP_OPT[dhcp_state.opt_ptr++] != DHCP_MESSAGE_TYPE || DHCP_OPT[dhcp_state.opt_ptr++] != DHCP_MESSAGE_TYPE_LEN)
return;
if (DHCP_OPT[dhcp_state.opt_ptr] == DHCP_MESSAGE_DISCOVER) {
dhcp_state.opt_ptr++;
find_client();
if (client_idx == 255)
find_slot();
// If there is no empty slot, we play possum and do not answer to the request
if (client_idx == 255)
return;
cstates[client_idx].cstate = CSTATE_OFFERED;
cstates[client_idx].mac[0] = DHCP_P->client_addr[0]; cstates[client_idx].mac[1] = DHCP_P->client_addr[1];
cstates[client_idx].mac[2] = DHCP_P->client_addr[2]; cstates[client_idx].mac[3] = DHCP_P->client_addr[3];
cstates[client_idx].mac[4] = DHCP_P->client_addr[4]; cstates[client_idx].mac[5] = DHCP_P->client_addr[5];
dhcp_state.transaction_id = DHCP_P->tid;
parse_opts();
dhcp_send_reply(DHCP_MESSAGE_OFFER);
} else if (DHCP_OPT[dhcp_state.opt_ptr++] == DHCP_MESSAGE_REQUEST) {
find_client();
if (client_idx == 255) {
dhcp_send_reply(DHCP_MESSAGE_NACK);
return;
}
parse_opts();
dhcp_send_reply(DHCP_MESSAGE_ACK);
}
}
void dhcp_start(void) __banked void dhcp_start(void) __banked
{ {
uip_ipaddr(server, 255,255,255,255); uip_ipaddr(server, 255,255,255,255);
dhcp_state.conn = uip_udp_new(&server, HTONS(DHCPC_SERVER_PORT)); dhcp_state.conn = uip_udp_new(&server, HTONS(DHCP_SERVER_PORT));
dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0; dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0;
if(dhcp_state.conn) { if(dhcp_state.conn) {
uip_udp_bind(dhcp_state.conn, HTONS(DHCPC_CLIENT_PORT)); uip_udp_bind(dhcp_state.conn, HTONS(DHCP_CLIENT_PORT));
} else { } else {
print_string("dhcp_start failed to set up socket\n"); print_string("dhcp_start failed to set up socket\n");
return; return;
@@ -345,6 +549,43 @@ void dhcp_start(void) __banked
} }
void dhcpd_start(void) __banked
{
memset(&cstates[0], 0, sizeof (struct dhcpd_cstate) * DHCPD_MAX_CLIENTS);
dhcp_state.conn = uip_udp_new(0, 0);
if(dhcp_state.conn) {
uip_udp_bind(dhcp_state.conn, HTONS(DHCP_SERVER_PORT));
} else {
print_string("dhcpd_start failed to set up socket\n");
return;
}
if (!dhcpd_vlan)
print_string("dhcpd: enabling for all VLANs\n");
else
print_string("dhcpd: enabling for VLAN "); print_short(dhcpd_vlan); write_char('\n');
dhcp_state.state = DHCP_SERVER;
dhcp_state.server[1] = uip_hostaddr[0] >> 8; dhcp_state.server[0] = uip_hostaddr[0] & 0xff;
dhcp_state.server[3] = uip_hostaddr[1] >> 8; dhcp_state.server[2] = uip_hostaddr[1] & 0xff;
dhcp_state.router[1] = uip_draddr[0] >> 8; dhcp_state.router[0] = uip_draddr[0] & 0xff;
dhcp_state.router[3] = uip_draddr[1] >> 8; dhcp_state.router[2] = uip_draddr[1] & 0xff;
dhcp_state.subnet[1] = uip_netmask[0] >> 8; dhcp_state.subnet[0] = uip_netmask[0] & 0xff;
dhcp_state.subnet[3] = uip_netmask[1] >> 8; dhcp_state.subnet[2] = uip_netmask[1] & 0xff;
dhcp_state.broadcast[0] = dhcp_state.router[0]; dhcp_state.broadcast[1] = dhcp_state.router[1];
dhcp_state.broadcast[2] = dhcp_state.router[2]; dhcp_state.broadcast[3] = 0xff;
for (uint8_t i = 0; i < DHCPD_MAX_CLIENTS; i++) {
cstates[i].cstate = CSTATE_NONE;
}
// TODO: DNS, correct broadcast address
print_string("dhcpd_start done\n");
}
void dhcp_stop(void) __banked void dhcp_stop(void) __banked
{ {
print_string("dhcp_stop called\n"); print_string("dhcp_stop called\n");
@@ -352,6 +593,13 @@ void dhcp_stop(void) __banked
dhcp_state.state = DHCP_OFF; dhcp_state.state = DHCP_OFF;
} }
void dhcpd_stop(void) __banked
{
print_string("dhcpd_stop called\n");
uip_udp_remove(dhcp_state.conn);
dhcp_state.state = DHCP_OFF;
}
void dhcp_callback(void) __banked void dhcp_callback(void) __banked
{ {
@@ -360,8 +608,10 @@ void dhcp_callback(void) __banked
if (uip_closed()) { if (uip_closed()) {
print_string("Closed\n"); print_string("Closed\n");
return; return;
} else if (dhcp_state.state == DHCP_SERVER && uip_newdata()) {
parse_dhcp_request();
} else if (uip_newdata()) { } else if (uip_newdata()) {
parse_dhcp(); parse_dhcp_response();
} else { } else {
if (dhcp_state.state == DHCP_START) { if (dhcp_state.state == DHCP_START) {
dhcp_send_discover(); dhcp_send_discover();
@@ -384,7 +634,4 @@ void dhcp_callback(void) __banked
} }
} }
} }
// By default we do not send anything out
uip_len = 0;
} }
+21 -4
View File
@@ -3,22 +3,27 @@
#include "uipopt.h" #include "uipopt.h"
#include <stdint.h> #include <stdint.h>
#define DHCPD_MAX_CLIENTS 20
#define DHCPD_START_IP 100
#define DHCPC_SERVER_PORT 67 #define DHCP_SERVER_PORT 67
#define DHCPC_CLIENT_PORT 68 #define DHCP_CLIENT_PORT 68
#define DHCP_OFF 0 #define DHCP_OFF 0
#define DHCP_START 1 #define DHCP_START 1
#define DHCP_DISCOVER_SENT 2 #define DHCP_DISCOVER_SENT 2
#define DHCP_REQUEST_SENT 3 #define DHCP_REQUEST_SENT 3
#define DHCP_LEASING 4 #define DHCP_LEASING 4
#define DHCP_SERVER 5
#define CSTATE_NONE 0
#define CSTATE_OFFERED 1
#define CSTATE_LEASED 2
void dhcp_start(void) __banked; void dhcp_start(void) __banked;
void dhcp_stop(void) __banked; void dhcp_stop(void) __banked;
// void dhcp_periodic(void) __banked;
void dhcp_callback(void) __banked; void dhcp_callback(void) __banked;
struct dhcp_state { struct dhcp_state {
uint8_t state; uint8_t state;
uint32_t transaction_id; uint32_t transaction_id;
@@ -38,6 +43,18 @@ struct dhcp_state {
struct uip_udp_conn *conn; struct uip_udp_conn *conn;
}; };
struct dhcpd_cstate {
uint8_t cstate;
uint16_t timer;
uint32_t transaction_id;
uint8_t mac[6];
uint8_t ip[4];
};
void dhcpd_start(void) __banked;
void dhcpd_stop(void) __banked;
typedef struct dhcp_state uip_udp_appstate_t; typedef struct dhcp_state uip_udp_appstate_t;
/* Finally we define the application function to be called by uIP. */ /* Finally we define the application function to be called by uIP. */
+1 -1
View File
@@ -51,7 +51,7 @@ function fetchMirror() {
for (let i = 1; i <= numPorts; i++) { for (let i = 1; i <= numPorts; i++) {
let p = i - 1; let p = i - 1;
if (numPorts < 9) if (numPorts < 9)
p = physToLogPort[p];members & (1<<p) p = physToLogPort[p];
setM("mPortsTX"+i, m_tx&(1<<p)); setM("mPortsRX"+i, m_rx&(1<<p)); setM("mPortsTX"+i, m_tx&(1<<p)); setM("mPortsRX"+i, m_rx&(1<<p));
} }
} }
+13
View File
@@ -23,6 +23,7 @@
<div id="system-tab" class="tab-content active"> <div id="system-tab" class="tab-content active">
<h1>System Settings</h1> <h1>System Settings</h1>
<label class="dhcpon">DHCP client endabled: <input id="dhcp" type="checkbox" onchange="dhcpClicked(this)"></label><br/><br/>
<div class="row"> <div class="row">
<div class="lcol"> <label for="ip">IP address:</label></div> <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 class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
@@ -55,6 +56,18 @@
<br/> <br/>
<input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch"> <input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch">
</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/>
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/>
<label class="dhcpdon">Enable DHCP Server: <input id="dhcpd" type="checkbox"></label><br/><br/>
<label class="dhcpdvlan">Limit DHCP Server to VLAN (0: serve all VLANs): <input type="number" min="0" max="2047" value="0" id="dhcpd_vid" name="dhcpd_vid"></label><br/>
<input style="width:40%;" class="action" id="dhcpd_sub" onclick="dhcpdSub();" type="button" value="Change DHCPD State"><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> </div>
<script src="/config.js"></script> <script src="/config.js"></script>
+49 -1
View File
@@ -8,6 +8,20 @@ function checkIp(ip) {
} }
async function ipSub() { async function ipSub() {
if (document.getElementById('dhcp').checked) {
var cmd = "ip dhcp";
try {
const response = await fetch('/cmd', {
method: 'POST',
body: cmd
});
console.log('Completed!', response);
systemInterval = setInterval(fetchIP, 10000);
} catch(err) {
console.error(`Error: ${err}`);
}
return;
}
for (let i=0;i<3;i++) { for (let i=0;i<3;i++) {
if (!checkIp(document.getElementById(ips[i]).value)) if (!checkIp(document.getElementById(ips[i]).value))
return; return;
@@ -26,7 +40,39 @@ async function ipSub() {
} }
} }
} }
async function dhcpdSub() {
var dhcpd_cmd = "dhcpd off";
if (document.getElementById('dhcpd').checked) {
dhcpd_cmd = "dhcpd on";
var v=document.getElementById('dhcpd_vid').value
if (v && v!= 0)
dhcpd_cmd = dhcpd_cmd + " " + v;
}
try {
console.log("Sending: ", dhcpd_cmd);
const response = await fetch('/cmd', {
method: 'POST',
body: dhcpd_cmd
});
console.log('Completed!', response);
} catch(err) {
console.error(`Error: ${err}`);
}
}
function dhcpClicked(e)
{
console.log("dhcpClicked called");
if (e.checked) {
for (let i=0; i<3;i++)
document.getElementById(ips[i]).disabled = true;
document.getElementById('dhcpd').disabled = true;
} else {
console.log("dhcpClicked off");
for (let i=0; i<3;i++)
document.getElementById(ips[i]).disabled = false;
document.getElementById('dhcpd').disabled = false;
}
}
async function sendConfig(c) { async function sendConfig(c) {
const form = new FormData(); const form = new FormData();
form.append("MAX_FILE_SIZE", "4096"); form.append("MAX_FILE_SIZE", "4096");
@@ -98,6 +144,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('dhcp').checked = s.dhcp_client;
document.getElementById('dhcpd').checked = s.dhcp_server;
clearInterval(systemInterval); clearInterval(systemInterval);
// Fetch and populate the config textbox // Fetch and populate the config textbox
fetchConfig().then((configText) => { fetchConfig().then((configText) => {
+9
View File
@@ -9,6 +9,7 @@
#include "uip.h" #include "uip.h"
#include "html_data.h" #include "html_data.h"
#include <stdint.h> #include <stdint.h>
#include "dhcp.h"
#include "phy.h" #include "phy.h"
#include "version.h" #include "version.h"
#include "machine.h" #include "machine.h"
@@ -45,6 +46,8 @@ extern __xdata char sfp_module_model[2][17];
extern __xdata char sfp_module_serial[2][17]; extern __xdata char sfp_module_serial[2][17];
extern __xdata uint8_t sfp_options[2]; extern __xdata uint8_t sfp_options[2];
extern __xdata struct dhcp_state dhcp_state;
__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"; __code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
@@ -250,6 +253,12 @@ void send_basic_info(void)
send_sfp_info(1); send_sfp_info(1);
char_to_html('"'); char_to_html('"');
} }
if (dhcp_state.state != DHCP_OFF && dhcp_state.state != DHCP_SERVER)
slen += strtox(outbuf + slen, ",\"dhcp_client\":1,\"dhcp_server\":0");
else if (dhcp_state.state == DHCP_SERVER)
slen += strtox(outbuf + slen, ",\"dhcp_client\":0,\"dhcp_server\":1");
else
slen += strtox(outbuf + slen, ",\"dhcp_client\":0,\"dhcp_server\":0");
char_to_html('}'); char_to_html('}');
} }
+2
View File
@@ -97,6 +97,8 @@ struct flash_region_t {
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;
extern __xdata uint16_t rx_packet_vlan;
extern __xdata uint16_t dhcpd_vlan;
// Headers for calls in the common code area (HOME/BANK0) // Headers for calls in the common code area (HOME/BANK0)
void print_string(__code char *p); void print_string(__code char *p);
+2 -3
View File
@@ -949,13 +949,12 @@ void handle_rx(void)
if (uip_len) { if (uip_len) {
tcpip_output(); tcpip_output();
} }
} else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // TCP? } else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // IP packet?
if (!management_vlan || management_vlan == rx_packet_vlan) { if (!management_vlan || management_vlan == rx_packet_vlan) {
uip_arp_ipin(); // Learn MAC addresses in TCP packets uip_arp_ipin(); // Learn MAC addresses in TCP packets
uip_input(); uip_input();
if (uip_len) { if (uip_len) {
// Add ethernet frame uip_arp_out(); // Add ethernet frame
uip_arp_out();
tcpip_output(); tcpip_output();
} }
} }
+2 -1
View File
@@ -121,7 +121,8 @@ void send_basic_info(int socket)
{ {
char *response = "HTTP/1.1 200 OK\r\n" char *response = "HTTP/1.1 200 OK\r\n"
"Content-Type: application/json; charset=UTF-8\r\n\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n"
"{\"ip_address\":\"192.168.10.247\",\"ip_gateway\":\"192.168.2.22\",\"ip_netmask\":\"255.255.255.0\",\"mac_address\":\"1c:2a:a3:23:00:02\",\"sw_ver\":\"" VERSION_SW "\",\"hw_ver\":\"SWGT024-V2.0\"}"; "{\"ip_address\":\"192.168.10.247\",\"ip_gateway\":\"192.168.2.22\",\"ip_netmask\":\"255.255.255.0\",\"mac_address\":\"1c:2a:a3:23:00:02\",\"sw_ver\":\"" VERSION_SW "\",\"hw_ver\":\"SWGT024-V2.0\""
",\"dhcp_client\":1,\"dhcp_server\":0}";
write(socket, response, strlen(response)); write(socket, response, strlen(response));
} }
+1 -1
View File
@@ -5,7 +5,7 @@ AFLAGS= -plosgff
BUILDDIR = output/ BUILDDIR = output/
SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-split.c
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
all: create_build_dir $(OBJS) all: create_build_dir $(OBJS)
+7 -3
View File
@@ -919,12 +919,12 @@ uip_process(u8_t flag) __banked
/* Check if we have a DHCP packet, otherwise check if the packet is destined for our IP address. */ /* Check if we have a DHCP packet, otherwise check if the packet is destined for our IP address. */
#if !UIP_CONF_IPV6 #if !UIP_CONF_IPV6
if(!(BUF->proto == UIP_PROTO_UDP && UDPBUF->destport == HTONS(DHCPC_CLIENT_PORT))) { if(!(BUF->proto == UIP_PROTO_UDP && (UDPBUF->destport == HTONS(DHCP_CLIENT_PORT) || UDPBUF->destport == HTONS(DHCP_SERVER_PORT)) )) {
if(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) { if(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) {
UIP_STAT(++uip_stat.ip.drop); UIP_STAT(++uip_stat.ip.drop);
goto drop; goto drop;
} }
} }
#else /* UIP_CONF_IPV6 */ #else /* UIP_CONF_IPV6 */
/* For IPv6, packet reception is a little trickier as we need to /* For IPv6, packet reception is a little trickier as we need to
make sure that we listen to certain multicast addresses (all make sure that we listen to certain multicast addresses (all
@@ -938,7 +938,11 @@ uip_process(u8_t flag) __banked
} }
#endif /* UIP_CONF_IPV6 */ #endif /* UIP_CONF_IPV6 */
} }
// If we serve only the designated DHCPD-VLAN, we drop the packet if not in that VLAN
if(BUF->proto == UIP_PROTO_UDP && dhcpd_vlan && UDPBUF->destport == HTONS(DHCP_SERVER_PORT) && dhcpd_vlan != rx_packet_vlan) {
UIP_STAT(++uip_stat.ip.drop);
goto drop;
}
#if !UIP_CONF_IPV6 #if !UIP_CONF_IPV6
// if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header // if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
// checksum. */ // checksum. */
+42 -20
View File
@@ -93,7 +93,7 @@ struct arp_hdr_o {
u16_t dipaddr[2]; u16_t dipaddr[2];
}; };
struct ethip_hdr { struct ethip_hdr_o {
struct uip_eth_hdr ethhdr; struct uip_eth_hdr ethhdr;
/* IP header. */ /* IP header. */
u8_t vhl, u8_t vhl,
@@ -106,6 +106,24 @@ struct ethip_hdr {
u16_t ipchksum; u16_t ipchksum;
u16_t srcipaddr[2], u16_t srcipaddr[2],
destipaddr[2]; destipaddr[2];
u16_t sport, dport;
};
struct ethip_hdr_i {
struct uip_eth_hdr ethhdr;
struct rtl_tag rtl_tag;
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
u16_t sport, dport;
}; };
#define ARP_REQUEST 1 #define ARP_REQUEST 1
@@ -130,9 +148,10 @@ static __xdata u8_t i, c;
static __xdata u8_t arptime; static __xdata u8_t arptime;
static __xdata u8_t tmpage; static __xdata u8_t tmpage;
#define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0]) #define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0])
#define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE]) #define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
#define IPBUF ((__xdata struct ethip_hdr *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE]) #define IPBUF_I ((__xdata struct ethip_hdr_i *)&uip_buf[0])
#define IPBUF_O ((__xdata struct ethip_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/** /**
* Initialize the ARP module. * Initialize the ARP module.
@@ -238,27 +257,26 @@ uip_arp_update(__xdata u16_t *ipaddr, __xdata struct uip_eth_addr *ethaddr)
* variable uip_len. * variable uip_len.
*/ */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if 0
void void
uip_arp_ipin(void) uip_arp_ipin(void) __banked
{ {
uip_len -= sizeof(struct uip_eth_hdr); uip_len -= sizeof(struct uip_eth_hdr);
/* Only insert/update an entry if the source IP address of the /* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */ incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) != if((IPBUF_I->srcipaddr[0] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) { (uip_hostaddr[0] & uip_netmask[0])) {
return; return;
} }
if((IPBUF->srcipaddr[1] & uip_netmask[1]) != if((IPBUF_I->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) { (uip_hostaddr[1] & uip_netmask[1])) {
return; return;
} }
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src)); uip_arp_update(IPBUF_I->srcipaddr, &(IPBUF_I->ethhdr.src));
return; return;
} }
#endif /* 0 */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/** /**
* ARP processing for incoming ARP packets. * ARP processing for incoming ARP packets.
@@ -302,8 +320,7 @@ uip_arp_arpin(void) __banked
with this host in the future. */ with this host in the future. */
uip_arp_update(BUF->sipaddr, &BUF->shwaddr); uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
/* The reply opcode is 2. */ BUF_O->opcode = HTONS(ARP_REPLY);
BUF_O->opcode = HTONS(2);
memcpy(BUF_O->dhwaddr.addr, BUF->shwaddr.addr, 6); memcpy(BUF_O->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6); memcpy(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6);
@@ -371,19 +388,24 @@ uip_arp_out(void) __banked
If not ARP table entry is found, we overwrite the original IP If not ARP table entry is found, we overwrite the original IP
packet with an ARP request for the IP address. */ packet with an ARP request for the IP address. */
if (IPBUF_O->sport == 0x4300 && !IPBUF_O->destipaddr[0] && !IPBUF_O->destipaddr[1]) {
IPBUF_O->destipaddr[0] = 0xffff;
IPBUF_O->destipaddr[1] = 0xffff;
IPBUF_O->dport = 0x4400;
}
/* First check if destination is a local broadcast. */ /* First check if destination is a local broadcast. */
if(uip_ipaddr_cmpc(IPBUF->destipaddr, broadcast_ipaddr)) { if(uip_ipaddr_cmpc(IPBUF_O->destipaddr, broadcast_ipaddr)) {
memcpyc(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); memcpyc(IPBUF_O->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
} else { } else {
/* Check if the destination address is on the local network. */ /* Check if the destination address is on the local network. */
if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) { if(!uip_ipaddr_maskcmp(IPBUF_O->destipaddr, uip_hostaddr, uip_netmask)) {
/* Destination address was not on the local network, so we need to /* Destination address was not on the local network, so we need to
use the default router's IP address instead of the destination use the default router's IP address instead of the destination
address when determining the MAC address. */ address when determining the MAC address. */
uip_ipaddr_copy(ipaddr, uip_draddr); uip_ipaddr_copy(ipaddr, uip_draddr);
} else { } else {
/* Else, we use the destination IP address. */ /* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); uip_ipaddr_copy(ipaddr, IPBUF_O->destipaddr);
} }
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
@@ -418,11 +440,11 @@ uip_arp_out(void) __banked
} }
/* Build an ethernet header. */ /* Build an ethernet header. */
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); memcpy(IPBUF_O->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
} }
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6); memcpy(IPBUF_O->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP); IPBUF_O->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr); uip_len += sizeof(struct uip_eth_hdr);
} }
+2 -2
View File
@@ -78,8 +78,8 @@ void uip_arp_init(void) __banked;
inserts a new mapping if none exists. The function assumes that an inserts a new mapping if none exists. The function assumes that an
IP packet with an Ethernet header is present in the uip_buf buffer IP packet with an Ethernet header is present in the uip_buf buffer
and that the length of the packet is in the uip_len variable. */ and that the length of the packet is in the uip_len variable. */
/*void uip_arp_ipin(void);*/ void uip_arp_ipin(void) __banked;
#define uip_arp_ipin() // #define uip_arp_ipin()
/* The uip_arp_arpin() should be called when an ARP packet is received /* The uip_arp_arpin() should be called when an ARP packet is received
by the Ethernet driver. This function also assumes that the by the Ethernet driver. This function also assumes that the