mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #68 from logicog/dhcp
Add a DHCP client implementation and validate BANKS code size.
This commit is contained in:
@@ -6,7 +6,7 @@ CONFIG_LOCATION = 458752
|
|||||||
HTML_LOCATION = 262144
|
HTML_LOCATION = 262144
|
||||||
|
|
||||||
CC = sdcc
|
CC = sdcc
|
||||||
CC_FLAGS = -mmcs51 -Ihttpd -Iuip
|
CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
|
||||||
ASM = sdas8051
|
ASM = sdas8051
|
||||||
AFLAGS= -plosgff
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin
|
|||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c machine.c
|
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c dhcp.c machine.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-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
|
||||||
|
|
||||||
@@ -59,17 +59,14 @@ $(BUILDDIR)%.rel: $(BUILDDIR)%.asm
|
|||||||
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
||||||
|
|
||||||
$(BUILDDIR)rtlplayground.ihx: $(BUILDDIR)crtstart.rel $(OBJS) $(BUILDDIR)crc16.rel
|
$(BUILDDIR)rtlplayground.ihx: $(BUILDDIR)crtstart.rel $(OBJS) $(BUILDDIR)crc16.rel
|
||||||
$(CC) $(CC_FLAGS) -Wl-bHOME=${BOOTLOADER_ADDRESS} -Wl-bBANK1=0x14000 -Wl-r -o $@ $^
|
$(CC) $(CC_FLAGS) -Wl-bHOME=${BOOTLOADER_ADDRESS} -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx
|
$(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx
|
||||||
objcopy --input-target=ihex -O binary $< $@
|
objcopy --input-target=ihex -O binary $< $@
|
||||||
|
|
||||||
$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img
|
$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img
|
||||||
if [ -e $@ ]; then rm $@; fi
|
if [ -e $@ ]; then rm $@; fi
|
||||||
echo "0000000: 00 40" | xxd -r - $@
|
tools/$(BUILDDIR)imagebuilder -i $^ $@
|
||||||
cat $< >> $@
|
|
||||||
truncate --size=16K $@
|
|
||||||
dd if=$< skip=80 bs=1024 >>$@
|
|
||||||
tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@
|
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@
|
||||||
tools/$(BUILDDIR)crc_calculator -u $@
|
tools/$(BUILDDIR)crc_calculator -u $@
|
||||||
|
|||||||
+59
-19
@@ -13,6 +13,7 @@
|
|||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
|
#include "dhcp.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@@ -37,6 +38,8 @@ extern __xdata struct flash_region_t flash_region;
|
|||||||
|
|
||||||
extern __xdata char passwd[21];
|
extern __xdata char passwd[21];
|
||||||
|
|
||||||
|
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;
|
||||||
__xdata uint8_t gpio_last_value[8] = { 0 };
|
__xdata uint8_t gpio_last_value[8] = { 0 };
|
||||||
@@ -149,6 +152,7 @@ uint8_t atoi_hex(uint8_t idx)
|
|||||||
return ((h_idx + 1) >> 1);
|
return ((h_idx + 1) >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t atoi_short(register uint16_t *vlan, register uint8_t idx)
|
uint8_t atoi_short(register uint16_t *vlan, register uint8_t idx)
|
||||||
{
|
{
|
||||||
uint8_t err = 1;
|
uint8_t err = 1;
|
||||||
@@ -774,28 +778,64 @@ void cmd_parser(void) __banked
|
|||||||
} else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) {
|
} else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) {
|
||||||
parse_mtu();
|
parse_mtu();
|
||||||
} else if (cmd_compare(0, "ip")) {
|
} else if (cmd_compare(0, "ip")) {
|
||||||
print_string("Got ip command: ");
|
if (cmd_words_b[2] > 0 && cmd_compare(1, "dhcp")) {
|
||||||
if (!parse_ip(cmd_words_b[1]))
|
dhcp_start();
|
||||||
uip_ipaddr(&uip_hostaddr, ip[0], ip[1], ip[2], ip[3]);
|
} else if (cmd_words_b[2] < 0) {
|
||||||
else
|
print_string("Current IP: ");
|
||||||
print_string("Invalid IP address\n");
|
itoa(uip_hostaddr[0]); write_char('.'); itoa(uip_hostaddr[0] >> 8); write_char('.');
|
||||||
print_byte(ip[0]); print_byte(ip[1]); print_byte(ip[2]); print_byte(ip[3]);
|
itoa(uip_hostaddr[1]); write_char('.'); itoa(uip_hostaddr[1] >> 8);
|
||||||
write_char('\n');
|
if (dhcp_state.state == DHCP_LEASING) {
|
||||||
|
print_string(" (dhcp, renewal in sec: ");
|
||||||
|
print_short(dhcp_state.dhcp_timer);
|
||||||
|
write_char(')');
|
||||||
|
} else {
|
||||||
|
print_string(" (static)");
|
||||||
|
}
|
||||||
|
write_char('\n');
|
||||||
|
} else {
|
||||||
|
if (dhcp_state.state)
|
||||||
|
dhcp_stop();
|
||||||
|
if (!parse_ip(cmd_words_b[1])) {
|
||||||
|
uip_ipaddr(&uip_hostaddr, ip[0], ip[1], ip[2], ip[3]);
|
||||||
|
print_string("Setting ip: ");
|
||||||
|
itoa(ip[0]); write_char('.'); itoa(ip[1]); write_char('.');
|
||||||
|
itoa(ip[2]); write_char('.'); itoa(ip[3]); write_char('\n');
|
||||||
|
} else {
|
||||||
|
print_string("Invalid IP address\n");
|
||||||
|
print_string("Error: ip [<ip-address>|dhcp]\n");
|
||||||
|
print_string(" The dhcp option enables the dhcp client, calling ip without options prints the current IP\n");
|
||||||
|
print_string(" Calling with a valid IP address will stop any ongoing dhcp client and set the IP address\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (cmd_compare(0, "gw")) {
|
} else if (cmd_compare(0, "gw")) {
|
||||||
print_string("Got gw command: ");
|
if (cmd_words_b[2] < 0) {
|
||||||
if (!parse_ip(cmd_words_b[1]))
|
print_string("Current gw: ");
|
||||||
uip_ipaddr(&uip_draddr, ip[0], ip[1], ip[2], ip[3]);
|
itoa(uip_draddr[0]); write_char('.'); itoa(uip_draddr[0] >> 8); write_char('.');
|
||||||
else
|
itoa(uip_draddr[1]); write_char('.'); itoa(uip_draddr[1] >> 8);
|
||||||
print_string("Invalid IP address\n");
|
} else {
|
||||||
print_byte(ip[0]); print_byte(ip[1]); print_byte(ip[2]); print_byte(ip[3]);
|
if (!parse_ip(cmd_words_b[1]))
|
||||||
|
uip_ipaddr(&uip_draddr, ip[0], ip[1], ip[2], ip[3]);
|
||||||
|
else
|
||||||
|
print_string("Invalid IP address\n");
|
||||||
|
print_string("Setting gw: ");
|
||||||
|
itoa(ip[0]); write_char('.'); itoa(ip[1]); write_char('.');
|
||||||
|
itoa(ip[2]); write_char('.'); itoa(ip[3]);
|
||||||
|
}
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
} else if (cmd_compare(0, "netmask")) {
|
} else if (cmd_compare(0, "netmask")) {
|
||||||
print_string("Got netmask command: ");
|
if (cmd_words_b[2] < 0) {
|
||||||
if (!parse_ip(cmd_words_b[1]))
|
print_string("Current netmask: ");
|
||||||
uip_ipaddr(&uip_netmask, ip[0], ip[1], ip[2], ip[3]);
|
itoa(uip_netmask[0]); write_char('.'); itoa(uip_netmask[0] >> 8); write_char('.');
|
||||||
else
|
itoa(uip_netmask[1]); write_char('.'); itoa(uip_netmask[1] >> 8);
|
||||||
print_string("Invalid IP address\n");
|
} else {
|
||||||
print_byte(ip[0]);print_byte(ip[1]);print_byte(ip[2]);print_byte(ip[3]);
|
if (!parse_ip(cmd_words_b[1]))
|
||||||
|
uip_ipaddr(&uip_netmask, ip[0], ip[1], ip[2], ip[3]);
|
||||||
|
else
|
||||||
|
print_string("Invalid IP address\n");
|
||||||
|
print_string("Setting netmask: ");
|
||||||
|
itoa(ip[0]); write_char('.'); itoa(ip[1]); write_char('.');
|
||||||
|
itoa(ip[2]); write_char('.'); itoa(ip[3]);
|
||||||
|
}
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
} else if (cmd_compare(0, "l2")) {
|
} else if (cmd_compare(0, "l2")) {
|
||||||
if (cmd_words_b[1] > 0 && cmd_compare(1, "forget"))
|
if (cmd_words_b[1] > 0 && cmd_compare(1, "forget"))
|
||||||
|
|||||||
@@ -0,0 +1,391 @@
|
|||||||
|
/*
|
||||||
|
* This is a DHCP client implementation for the RTL837x-based switches
|
||||||
|
*/
|
||||||
|
|
||||||
|
// #define REGDBG
|
||||||
|
// #define DEBUG
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "rtl837x_sfr.h"
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "dhcp.h"
|
||||||
|
#include "uip.h"
|
||||||
|
#include "uip/uip.h"
|
||||||
|
|
||||||
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
|
__xdata struct dhcp_state dhcp_state;
|
||||||
|
__xdata uip_ipaddr_t server;
|
||||||
|
|
||||||
|
#define DHCP_HW_TYPE_ETH 1
|
||||||
|
|
||||||
|
#define DHCP_SUBNET_MASK 1
|
||||||
|
#define DHCP_SUBNET_MASK_LEN 4
|
||||||
|
#define DHCP_ROUTER 3
|
||||||
|
#define DHCP_ROUTER_LEN 4
|
||||||
|
#define DHCP_DNS 6
|
||||||
|
#define DHCP_DNS_LEN 4
|
||||||
|
#define DHCP_BROADCAST 28
|
||||||
|
#define DHCP_BROADCAST_LEN 4
|
||||||
|
#define DHCP_SERVER_ID 54
|
||||||
|
#define DHCP_SERVER_ID_LEN 4
|
||||||
|
#define DHCP_MESSAGE_TYPE 53
|
||||||
|
#define DHCP_MESSAGE_TYPE_LEN 1
|
||||||
|
#define DHCP_MESSAGE_DISCOVER 1
|
||||||
|
#define DHCP_MESSAGE_OFFER 2
|
||||||
|
#define DHCP_MESSAGE_REQUEST 3
|
||||||
|
#define DHCP_MESSAGE_ACK 5
|
||||||
|
#define DHCP_LEASE 51
|
||||||
|
#define DHCP_LEASE_LEN 4
|
||||||
|
#define DHCP_RENEWAL 58
|
||||||
|
#define DHCP_RENEWAL_LEN 4
|
||||||
|
#define DHCP_REBIND 59
|
||||||
|
#define DHCP_REBIND_LEN 4
|
||||||
|
#define DHCP_CLIENT_ID 61
|
||||||
|
#define DHCP_CLIENT_ID_LEN 7
|
||||||
|
#define DHCP_REQUEST_IP 50
|
||||||
|
#define DHCP_REQUEST_IP_LEN 4
|
||||||
|
#define DHCP_PARAMS 55
|
||||||
|
#define DHCP_PARAM_SUBNET 1
|
||||||
|
#define DHCP_PARAM_ROUTER 3
|
||||||
|
#define DHCP_PARAM_DNS 6
|
||||||
|
#define DHCP_END 255
|
||||||
|
|
||||||
|
#pragma codeseg BANK2
|
||||||
|
#pragma constseg BANK2
|
||||||
|
|
||||||
|
struct dhcp_pkt {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t hw;
|
||||||
|
uint8_t hw_len;
|
||||||
|
uint8_t hops;
|
||||||
|
uint32_t tid;
|
||||||
|
uint16_t delay;
|
||||||
|
uint16_t flags;
|
||||||
|
uint8_t client_ip[4];
|
||||||
|
uint8_t your_ip[4];
|
||||||
|
uint8_t next_server_ip[4];
|
||||||
|
uint8_t relay_ip[4];
|
||||||
|
uint8_t client_addr[6];
|
||||||
|
uint8_t client_pad[10];
|
||||||
|
uint8_t server_name[64];
|
||||||
|
uint8_t file[128];
|
||||||
|
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_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt))
|
||||||
|
|
||||||
|
__xdata uint32_t long_value;
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_print_ip(uint8_t *a)
|
||||||
|
{
|
||||||
|
itoa(a[0]); write_char('.');
|
||||||
|
itoa(a[1]); write_char('.');
|
||||||
|
itoa(a[2]); write_char('.');
|
||||||
|
itoa(a[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_prepare_request(void)
|
||||||
|
{
|
||||||
|
DHCP_P->type = 1;
|
||||||
|
DHCP_P->hw = DHCP_HW_TYPE_ETH;
|
||||||
|
DHCP_P->hw_len = 6;
|
||||||
|
DHCP_P->hops = 0;
|
||||||
|
|
||||||
|
DHCP_P->tid = HTONS(dhcp_state.transaction_id);
|
||||||
|
DHCP_P->delay = HTONS(0);
|
||||||
|
DHCP_P->flags = 0;
|
||||||
|
// Clear fields client_ip to bootp_file
|
||||||
|
memset(DHCP_P->client_ip, 0, 224);
|
||||||
|
memcpyc(DHCP_P->client_addr, uip_ethaddr.addr, 6);
|
||||||
|
DHCP_P->cookie[0] = 0x63;
|
||||||
|
DHCP_P->cookie[1] = 0x82;
|
||||||
|
DHCP_P->cookie[2] = 0x53;
|
||||||
|
DHCP_P->cookie[3] = 0x63;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_addopt_client_id(void)
|
||||||
|
{
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID_LEN;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_HW_TYPE_ETH;
|
||||||
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 6);
|
||||||
|
dhcp_state.opt_ptr += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_addopt_request_ip(void)
|
||||||
|
{
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REQUEST_IP;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REQUEST_IP_LEN;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[0];
|
||||||
|
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[3];
|
||||||
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_addopt_server_id(void)
|
||||||
|
{
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SERVER_ID;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SERVER_ID_LEN;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[0];
|
||||||
|
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[3];
|
||||||
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_send_discover(void)
|
||||||
|
{
|
||||||
|
print_string("dhcp_send_discover called\n");
|
||||||
|
dhcp_prepare_request();
|
||||||
|
|
||||||
|
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++] = DHCP_MESSAGE_DISCOVER;
|
||||||
|
|
||||||
|
dhcp_addopt_client_id();
|
||||||
|
dhcp_addopt_request_ip();
|
||||||
|
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAM_SUBNET;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAM_ROUTER;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAM_DNS;
|
||||||
|
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_END;
|
||||||
|
// Padding to 300 bytes
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
|
||||||
|
uip_udp_send(sizeof(struct dhcp_pkt) + dhcp_state.opt_ptr);
|
||||||
|
dhcp_state.state = DHCP_DISCOVER_SENT;
|
||||||
|
dhcp_state.ticks = SYS_TICK_HZ;
|
||||||
|
dhcp_state.dhcp_timer = 30; // Timeout for discover
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_send_request(void)
|
||||||
|
{
|
||||||
|
print_string("dhcp_send_request called\n");
|
||||||
|
dhcp_prepare_request();
|
||||||
|
|
||||||
|
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++] = DHCP_MESSAGE_REQUEST;
|
||||||
|
|
||||||
|
dhcp_addopt_client_id();
|
||||||
|
dhcp_addopt_request_ip();
|
||||||
|
dhcp_addopt_server_id();
|
||||||
|
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAM_SUBNET;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAM_ROUTER;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAM_DNS;
|
||||||
|
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_END;
|
||||||
|
// Padding to 300 bytes
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
||||||
|
|
||||||
|
uip_udp_send(sizeof(struct dhcp_pkt) + dhcp_state.opt_ptr);
|
||||||
|
dhcp_state.state = DHCP_REQUEST_SENT;
|
||||||
|
dhcp_state.ticks = SYS_TICK_HZ;
|
||||||
|
dhcp_state.dhcp_timer = 30; // Timeout for request
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ip_opt(uint8_t * __xdata ip)
|
||||||
|
{
|
||||||
|
dhcp_state.opt_ptr++;
|
||||||
|
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
// There may be more than one IP option, such as 2 DNS servers advertised
|
||||||
|
dhcp_state.opt_ptr += len - 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void long_opt(void)
|
||||||
|
{
|
||||||
|
dhcp_state.opt_ptr++;
|
||||||
|
dhcp_state.opt_ptr++;
|
||||||
|
long_value = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
long_value <<= 8;
|
||||||
|
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
long_value <<= 8;
|
||||||
|
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
long_value <<= 8;
|
||||||
|
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parse_opts(void)
|
||||||
|
{
|
||||||
|
while (DHCP_OPT[dhcp_state.opt_ptr] && DHCP_OPT[dhcp_state.opt_ptr] != DHCP_END) {
|
||||||
|
switch(DHCP_OPT[dhcp_state.opt_ptr]) {
|
||||||
|
case DHCP_SUBNET_MASK:
|
||||||
|
ip_opt(&dhcp_state.subnet[0]);
|
||||||
|
break;
|
||||||
|
case DHCP_ROUTER:
|
||||||
|
ip_opt(&dhcp_state.router[0]);
|
||||||
|
break;
|
||||||
|
case DHCP_DNS:
|
||||||
|
ip_opt(&dhcp_state.dns[0]);
|
||||||
|
break;
|
||||||
|
case DHCP_SERVER_ID:
|
||||||
|
ip_opt(&dhcp_state.server[0]);
|
||||||
|
break;
|
||||||
|
case DHCP_BROADCAST:
|
||||||
|
ip_opt(&dhcp_state.broadcast[0]);
|
||||||
|
break;
|
||||||
|
case DHCP_LEASE:
|
||||||
|
long_opt();
|
||||||
|
dhcp_state.lease = long_value;
|
||||||
|
break;
|
||||||
|
case DHCP_REBIND:
|
||||||
|
long_opt();
|
||||||
|
dhcp_state.rebind = long_value;
|
||||||
|
break;
|
||||||
|
case DHCP_RENEWAL:
|
||||||
|
long_opt();
|
||||||
|
dhcp_state.renewal = long_value;
|
||||||
|
break;
|
||||||
|
case DHCP_END:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_string("Unknown DHCP option: "); print_byte(DHCP_OPT[dhcp_state.opt_ptr]); write_char('\n');
|
||||||
|
dhcp_state.opt_ptr++;
|
||||||
|
dhcp_state.opt_ptr += DHCP_OPT[dhcp_state.opt_ptr];
|
||||||
|
dhcp_state.opt_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parse_dhcp(void)
|
||||||
|
{
|
||||||
|
if (!DHCP_P->tid == HTONS(dhcp_state.transaction_id))
|
||||||
|
return;
|
||||||
|
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_OFFER) {
|
||||||
|
dhcp_state.opt_ptr++;
|
||||||
|
dhcp_state.current_ip[0] = DHCP_P->your_ip[0];
|
||||||
|
dhcp_state.current_ip[1] = DHCP_P->your_ip[1];
|
||||||
|
dhcp_state.current_ip[2] = DHCP_P->your_ip[2];
|
||||||
|
dhcp_state.current_ip[3] = DHCP_P->your_ip[3];
|
||||||
|
parse_opts();
|
||||||
|
print_string("DHCP offer received for IP "); dhcp_print_ip(dhcp_state.current_ip);
|
||||||
|
write_char('\n');
|
||||||
|
dhcp_send_request();
|
||||||
|
} else if (DHCP_OPT[dhcp_state.opt_ptr++] == DHCP_MESSAGE_ACK) {
|
||||||
|
parse_opts();
|
||||||
|
print_string("DHCP ACK, our IP is "); dhcp_print_ip(dhcp_state.current_ip);
|
||||||
|
write_char('\n');
|
||||||
|
print_string("DHCP netmask "); dhcp_print_ip(dhcp_state.subnet);
|
||||||
|
write_char('\n');
|
||||||
|
print_string("DHCP gateway "); dhcp_print_ip(dhcp_state.router);
|
||||||
|
write_char('\n');
|
||||||
|
print_string("DHCP lease-time ");
|
||||||
|
print_long(dhcp_state.lease);
|
||||||
|
write_char('\n');
|
||||||
|
uip_ipaddr(&uip_hostaddr, dhcp_state.current_ip[0], dhcp_state.current_ip[1], dhcp_state.current_ip[2], dhcp_state.current_ip[3]);
|
||||||
|
uip_ipaddr(&uip_draddr, dhcp_state.router[0], dhcp_state.router[1], dhcp_state.router[2], dhcp_state.router[3]);
|
||||||
|
uip_ipaddr(&uip_netmask, dhcp_state.subnet[0], dhcp_state.subnet[1], dhcp_state.subnet[2], dhcp_state.subnet[3]);
|
||||||
|
dhcp_state.state = DHCP_LEASING;
|
||||||
|
dhcp_state.ticks = SYS_TICK_HZ;
|
||||||
|
dhcp_state.dhcp_timer = dhcp_state.renewal > 0xffff ? 0xffff : dhcp_state.renewal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_start(void) __banked
|
||||||
|
{
|
||||||
|
uip_ipaddr(server, 255,255,255,255);
|
||||||
|
dhcp_state.conn = uip_udp_new(&server, HTONS(DHCPC_SERVER_PORT));
|
||||||
|
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) {
|
||||||
|
uip_udp_bind(dhcp_state.conn, HTONS(DHCPC_CLIENT_PORT));
|
||||||
|
} else {
|
||||||
|
print_string("dhcp_start failed to set up socket\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
get_random_32();
|
||||||
|
dhcp_state.transaction_id = SFR_DATA_U32;
|
||||||
|
dhcp_state.state = DHCP_START;
|
||||||
|
print_string("dhcp_start done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_stop(void) __banked
|
||||||
|
{
|
||||||
|
print_string("dhcp_stop called\n");
|
||||||
|
uip_udp_remove(dhcp_state.conn);
|
||||||
|
dhcp_state.state = DHCP_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhcp_callback(void) __banked
|
||||||
|
{
|
||||||
|
if (!dhcp_state.state)
|
||||||
|
return;
|
||||||
|
if (uip_closed()) {
|
||||||
|
print_string("Closed\n");
|
||||||
|
return;
|
||||||
|
} else if (uip_newdata()) {
|
||||||
|
parse_dhcp();
|
||||||
|
} else {
|
||||||
|
if (dhcp_state.state == DHCP_START) {
|
||||||
|
dhcp_send_discover();
|
||||||
|
} else if (!--dhcp_state.ticks) {
|
||||||
|
// print_string("Timer: "); print_short(dhcp_state.ticks); write_char(' '); print_short(dhcp_state.dhcp_timer);
|
||||||
|
dhcp_state.dhcp_timer--;
|
||||||
|
dhcp_state.ticks = SYS_TICK_HZ;
|
||||||
|
}
|
||||||
|
if (!dhcp_state.dhcp_timer) {
|
||||||
|
switch (dhcp_state.state) {
|
||||||
|
case DHCP_DISCOVER_SENT:
|
||||||
|
dhcp_send_discover();
|
||||||
|
break;
|
||||||
|
case DHCP_LEASING:
|
||||||
|
case DHCP_REQUEST_SENT:
|
||||||
|
dhcp_send_request();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_string("UNKNOWN STATE\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// By default we do not send anything out
|
||||||
|
uip_len = 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef _DHCP_H_
|
||||||
|
#define _DHCP_H_
|
||||||
|
|
||||||
|
#include "uipopt.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define DHCPC_SERVER_PORT 67
|
||||||
|
#define DHCPC_CLIENT_PORT 68
|
||||||
|
|
||||||
|
#define DHCP_OFF 0
|
||||||
|
#define DHCP_START 1
|
||||||
|
#define DHCP_DISCOVER_SENT 2
|
||||||
|
#define DHCP_REQUEST_SENT 3
|
||||||
|
#define DHCP_LEASING 4
|
||||||
|
|
||||||
|
void dhcp_start(void) __banked;
|
||||||
|
void dhcp_stop(void) __banked;
|
||||||
|
// void dhcp_periodic(void) __banked;
|
||||||
|
void dhcp_callback(void) __banked;
|
||||||
|
|
||||||
|
|
||||||
|
struct dhcp_state {
|
||||||
|
uint8_t state;
|
||||||
|
uint32_t transaction_id;
|
||||||
|
uint16_t dhcp_timer;
|
||||||
|
uint8_t ticks;
|
||||||
|
uint16_t opt_ptr;
|
||||||
|
uint8_t current_ip[4];
|
||||||
|
uint8_t server[4];
|
||||||
|
uint8_t router[4];
|
||||||
|
uint8_t subnet[4];
|
||||||
|
uint8_t dns[4];
|
||||||
|
uint8_t broadcast[4];
|
||||||
|
uint32_t lease;
|
||||||
|
uint32_t rebind;
|
||||||
|
uint32_t renewal;
|
||||||
|
|
||||||
|
struct uip_udp_conn *conn;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct dhcp_state uip_udp_appstate_t;
|
||||||
|
|
||||||
|
/* Finally we define the application function to be called by uIP. */
|
||||||
|
#ifndef UIP_UDP_APPCALL
|
||||||
|
#define UIP_UDP_APPCALL dhcp_callback
|
||||||
|
#endif /* UIP_APPCALL */
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
#define SESSION_ID_LENGTH 12
|
#define SESSION_ID_LENGTH 12
|
||||||
#define SESSION_TIMEOUT 200
|
#define SESSION_TIMEOUT 200
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define SYS_TICK_HZ 200
|
||||||
|
|
||||||
// SCL and SDA pin numbers for SFP cage 0 and SFP cage 1
|
// SCL and SDA pin numbers for SFP cage 0 and SFP cage 1
|
||||||
#define SCL_PIN 3
|
#define SCL_PIN 3
|
||||||
#define SDA_PIN_0 4
|
#define SDA_PIN_0 4
|
||||||
@@ -88,6 +90,7 @@ void print_string(__code char *p);
|
|||||||
void print_long(__xdata uint32_t a);
|
void print_long(__xdata uint32_t a);
|
||||||
void print_short(uint16_t a);
|
void print_short(uint16_t a);
|
||||||
void print_byte(uint8_t a);
|
void print_byte(uint8_t a);
|
||||||
|
void itoa(uint8_t v);
|
||||||
void print_sfr_data(void);
|
void print_sfr_data(void);
|
||||||
void print_phy_data(void);
|
void print_phy_data(void);
|
||||||
void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v);
|
void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v);
|
||||||
|
|||||||
+2
-2
@@ -16,8 +16,8 @@
|
|||||||
#include "rtl837x_phy.h"
|
#include "rtl837x_phy.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK2
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK2
|
||||||
|
|
||||||
extern __code uint16_t bit_mask[16];
|
extern __code uint16_t bit_mask[16];
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "rtl837x_port.h"
|
#include "rtl837x_port.h"
|
||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
|
#include "dhcp.h"
|
||||||
#include "cmd_parser.h"
|
#include "cmd_parser.h"
|
||||||
#include "uip/uipopt.h"
|
#include "uip/uipopt.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
@@ -80,6 +81,7 @@ volatile __xdata uint32_t ticks;
|
|||||||
volatile __xdata uint8_t sec_counter;
|
volatile __xdata uint8_t sec_counter;
|
||||||
volatile __xdata uint16_t sleep_ticks;
|
volatile __xdata uint16_t sleep_ticks;
|
||||||
__xdata uint8_t stp_clock;
|
__xdata uint8_t stp_clock;
|
||||||
|
extern __xdata struct dhcp_state dhcp_state;
|
||||||
|
|
||||||
#define STP_TICK_DIVIDER 3
|
#define STP_TICK_DIVIDER 3
|
||||||
|
|
||||||
@@ -172,6 +174,22 @@ void write_char(char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void itoa(uint8_t v)
|
||||||
|
{
|
||||||
|
uint8_t t = (v / 100);
|
||||||
|
// when print_zeros is not zero, we know that a non-zero number has printed.
|
||||||
|
// That have to print all the next numbers.
|
||||||
|
uint8_t print_zeros = t;
|
||||||
|
if (print_zeros)
|
||||||
|
write_char('0' + t);
|
||||||
|
t = (v / 10) % 10;
|
||||||
|
print_zeros |= t;
|
||||||
|
if (print_zeros)
|
||||||
|
write_char('0' + t);
|
||||||
|
write_char('0' + (v % 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_string(__code char *p)
|
void print_string(__code char *p)
|
||||||
{
|
{
|
||||||
while (*p)
|
while (*p)
|
||||||
@@ -910,6 +928,10 @@ void handle_rx(void)
|
|||||||
uip_arp_out();
|
uip_arp_out();
|
||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#ifdef RXTXDBG
|
||||||
|
print_string("Unknown RX on port "); print_byte(rx_headers[3] & 0xf); write_char('\n');
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -927,6 +949,13 @@ void handle_tx(void)
|
|||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(uint8_t i = 0; i < UIP_UDP_CONNS; i++) {
|
||||||
|
uip_udp_periodic(i);
|
||||||
|
if(uip_len > 0) {
|
||||||
|
uip_arp_out();
|
||||||
|
tcpip_output();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1739,6 +1768,7 @@ void bootloader(void)
|
|||||||
{
|
{
|
||||||
ticks = 0;
|
ticks = 0;
|
||||||
stp_clock = STP_TICK_DIVIDER;
|
stp_clock = STP_TICK_DIVIDER;
|
||||||
|
dhcp_state.state = DHCP_OFF;
|
||||||
sbuf_ptr = 0;
|
sbuf_ptr = 0;
|
||||||
|
|
||||||
CKCON = 0; // Initial Clock configuration
|
CKCON = 0; // Initial Clock configuration
|
||||||
|
|||||||
+5
-1
@@ -2,7 +2,8 @@ CC = gcc
|
|||||||
CCFLAGS = -Wall -o
|
CCFLAGS = -Wall -o
|
||||||
BUILDDIR = output/
|
BUILDDIR = output/
|
||||||
|
|
||||||
all: create_build_dir $(BUILDDIR)injector $(BUILDDIR)fileadder $(BUILDDIR)httpd_sim $(BUILDDIR)crc_calculator
|
all: create_build_dir $(BUILDDIR)injector $(BUILDDIR)fileadder $(BUILDDIR)httpd_sim\
|
||||||
|
$(BUILDDIR)crc_calculator $(BUILDDIR)imagebuilder
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
@@ -21,3 +22,6 @@ $(BUILDDIR)crc_calculator: crc_calculator.c
|
|||||||
|
|
||||||
$(BUILDDIR)httpd_sim: httpd_sim.c httpd_sim.h
|
$(BUILDDIR)httpd_sim: httpd_sim.c httpd_sim.h
|
||||||
gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c
|
gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c
|
||||||
|
|
||||||
|
$(BUILDDIR)imagebuilder: imagebuilder.c
|
||||||
|
gcc $^ $(CCFLAGS) $@
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* Adds data files into specified locations of an image, optionally creates
|
||||||
|
* an index in the form of a header file
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <argp.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define OFFSET 2
|
||||||
|
#define BANK0_SIZE 0x4000
|
||||||
|
#define BANK_SIZE 0xc000
|
||||||
|
#define BANK_STRIDE 0x10000
|
||||||
|
|
||||||
|
// Use a 4MB buffer, the maximum flash rom size
|
||||||
|
#define BUFFER_SIZE 0x400000
|
||||||
|
uint8_t buffer[BUFFER_SIZE];
|
||||||
|
FILE *inptr;
|
||||||
|
int outptr;
|
||||||
|
|
||||||
|
const char *argp_program_version = "imagebuilder 0.1";
|
||||||
|
const char *argp_program_bug_address = "<git@logicog.de>";
|
||||||
|
static char doc[] = "Create an image with multiple banks for RTL837X-based switches";
|
||||||
|
static char args_doc[] = "INPUT_IMAGE";
|
||||||
|
static struct argp_option options[] = {
|
||||||
|
{ "input", 'i', "FILE", 0, "Input file"},
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct arguments {
|
||||||
|
char *input_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||||
|
{
|
||||||
|
struct arguments *arguments = state->input;
|
||||||
|
switch (key) {
|
||||||
|
case 'i':
|
||||||
|
arguments->input_file = arg;
|
||||||
|
break;
|
||||||
|
case ARGP_KEY_END:
|
||||||
|
if (state->arg_num < 1) // Expect 1 command line argument at end
|
||||||
|
argp_usage(state);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct argp argp = {
|
||||||
|
options, parse_opt, args_doc, doc, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct arguments arguments;
|
||||||
|
int arg_index;
|
||||||
|
|
||||||
|
arguments.input_file = NULL;
|
||||||
|
|
||||||
|
argp_parse(&argp, argc, argv, 0, &arg_index, &arguments);
|
||||||
|
|
||||||
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
|
|
||||||
|
size_t filesize = 0;
|
||||||
|
inptr = fopen(arguments.input_file, "rb");
|
||||||
|
if (inptr == NULL) {
|
||||||
|
printf("Cannot open input file %s\n", arguments.input_file);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(inptr, 0L, SEEK_END);
|
||||||
|
filesize = ftell(inptr);
|
||||||
|
rewind(inptr);
|
||||||
|
printf("Input file size: %ld\n", filesize);
|
||||||
|
if (filesize > BUFFER_SIZE) {
|
||||||
|
printf("File too large.\n");
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nbanks = (filesize - BANK0_SIZE) / BANK_STRIDE;
|
||||||
|
printf("Input file contains %d banks\n", nbanks);
|
||||||
|
|
||||||
|
/* Verify the size of banks in input file:
|
||||||
|
* Bank 0: 0x00002 - 0x04000 <- 0x00000 - 0x03ffe
|
||||||
|
* Bank 1: 0x04000 - 0x10000 <- 0x14000 - 0x20000
|
||||||
|
* Bank 2: 0x10000 - 0x1c000 <- 0x24000 - 0x33000
|
||||||
|
* [...]
|
||||||
|
* by verifying whether other than 0-bytes are found in the input
|
||||||
|
* file after these ranges.
|
||||||
|
*/
|
||||||
|
size_t bytes_read = fread(buffer, 1, filesize, inptr);
|
||||||
|
if (bytes_read != filesize) {
|
||||||
|
printf("Error reading input file.\n");
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
for (int b = BANK0_SIZE; b < BANK_STRIDE + BANK0_SIZE; b ++) {
|
||||||
|
if (buffer[b]) {
|
||||||
|
printf("WARNING: Bank 0: code segment too large at 0x%x!\n", b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int bank = 1; bank <= nbanks; bank++) {
|
||||||
|
for (int b = (bank + 1) * BANK_STRIDE; b < (bank + 1) * BANK_STRIDE + BANK0_SIZE; b ++) {
|
||||||
|
if (buffer[b]) {
|
||||||
|
printf("WARNING: Bank %d: code segment too large at 0x%x!\n", bank, b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind(inptr);
|
||||||
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
|
|
||||||
|
// BANK0-Size
|
||||||
|
buffer[0] = 0x00;
|
||||||
|
buffer[1] = 0x40;
|
||||||
|
|
||||||
|
// Read bank 0
|
||||||
|
bytes_read = fread(buffer + OFFSET, 1, BANK0_SIZE, inptr);
|
||||||
|
printf("Bank 0: Bytes read: %ld\n", bytes_read);
|
||||||
|
|
||||||
|
if (bytes_read != BANK0_SIZE) {
|
||||||
|
printf("Error reading input file.\n");
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
fseek(inptr, BANK_STRIDE, SEEK_CUR);
|
||||||
|
|
||||||
|
for (int bank = 1; bank <= nbanks; bank++) {
|
||||||
|
bytes_read = fread(buffer + (bank - 1) * BANK_SIZE + BANK0_SIZE, 1, BANK_SIZE, inptr);
|
||||||
|
printf("Bank %d: bytes read: %ld\n", bank, bytes_read);
|
||||||
|
if (bank != nbanks)
|
||||||
|
fseek(inptr, BANK0_SIZE, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(inptr);
|
||||||
|
|
||||||
|
outptr = creat(argv[arg_index], S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
|
|
||||||
|
if (!outptr) {
|
||||||
|
printf("Cannot open %s\n", argv[arg_index]);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t written = write(outptr, buffer, (nbanks + 1) * BANK_STRIDE);
|
||||||
|
|
||||||
|
if (written != (nbanks + 1) * BANK_STRIDE) {
|
||||||
|
printf("Error writing output file.\n");
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
close(outptr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+7
-2
@@ -129,14 +129,18 @@ typedef unsigned short uip_stats_t;
|
|||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#define UIP_CONF_UDP 0
|
#define UIP_CONF_UDP 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UDP checksums on or off
|
* UDP checksums on or off
|
||||||
|
* The RTL8372/3 are able to calculate and verify all L2 and L3 checksums
|
||||||
|
* in hardware. The TX checksums are configured in the CPU-tag of outgoing
|
||||||
|
* packets, while the RTL837X_NIC_RX_CTRL register configures the verification
|
||||||
|
* of the checksum of inbound packets and subsequent possible drop.
|
||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
#define UIP_CONF_UDP_CHECKSUMS 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* uIP statistics on or off
|
* uIP statistics on or off
|
||||||
@@ -149,6 +153,7 @@ typedef unsigned short uip_stats_t;
|
|||||||
our project. */
|
our project. */
|
||||||
/*#include "smtp.h"*/
|
/*#include "smtp.h"*/
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
|
#include "dhcp.h"
|
||||||
/*#include "telnetd.h"*/
|
/*#include "telnetd.h"*/
|
||||||
/*#include "webserver.h" */
|
/*#include "webserver.h" */
|
||||||
/*#include "dhcpc.h"*/
|
/*#include "dhcpc.h"*/
|
||||||
|
|||||||
@@ -85,6 +85,7 @@
|
|||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "uipopt.h"
|
#include "uipopt.h"
|
||||||
#include "uip_arch.h"
|
#include "uip_arch.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
@@ -168,8 +169,8 @@ __xdata u16_t uip_listenports[UIP_LISTENPORTS];
|
|||||||
/* The uip_listenports list all currently
|
/* The uip_listenports list all currently
|
||||||
listning ports. */
|
listning ports. */
|
||||||
#if UIP_UDP
|
#if UIP_UDP
|
||||||
struct uip_udp_conn *uip_udp_conn;
|
__xdata struct uip_udp_conn *uip_udp_conn;
|
||||||
struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
__xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
|
|
||||||
__xdata static u16_t ipid; /* Ths ipid variable is an increasing
|
__xdata static u16_t ipid; /* Ths ipid variable is an increasing
|
||||||
@@ -401,7 +402,7 @@ uip_init(void) __banked
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_ACTIVE_OPEN
|
#if UIP_ACTIVE_OPEN
|
||||||
__xdata struct uip_conn *
|
__xdata struct uip_conn *
|
||||||
uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport)
|
uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked
|
||||||
{
|
{
|
||||||
__xdata struct uip_conn *conn, *cconn;
|
__xdata struct uip_conn *conn, *cconn;
|
||||||
|
|
||||||
@@ -467,9 +468,9 @@ uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport)
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_UDP
|
#if UIP_UDP
|
||||||
struct uip_udp_conn *
|
struct uip_udp_conn *
|
||||||
uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
|
uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked
|
||||||
{
|
{
|
||||||
register struct uip_udp_conn *conn;
|
__xdata struct uip_udp_conn *conn;
|
||||||
|
|
||||||
/* Find an unused local port. */
|
/* Find an unused local port. */
|
||||||
again:
|
again:
|
||||||
@@ -512,7 +513,7 @@ uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
|
|||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_unlisten(u16_t port)
|
uip_unlisten(u16_t port) __banked
|
||||||
{
|
{
|
||||||
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
||||||
if(uip_listenports[c] == port) {
|
if(uip_listenports[c] == port) {
|
||||||
@@ -523,7 +524,7 @@ uip_unlisten(u16_t port)
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_listen(u16_t port)
|
uip_listen(u16_t port) __banked
|
||||||
{
|
{
|
||||||
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
||||||
if(uip_listenports[c] == 0) {
|
if(uip_listenports[c] == 0) {
|
||||||
@@ -721,7 +722,6 @@ uip_process(u8_t flag) __banked
|
|||||||
/* Reset the length variables. */
|
/* Reset the length variables. */
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
uip_slen = 0;
|
uip_slen = 0;
|
||||||
|
|
||||||
/* Check if the connection is in a state in which we simply wait
|
/* Check if the connection is in a state in which we simply wait
|
||||||
for the connection to time out. If so, we increase the
|
for the connection to time out. If so, we increase the
|
||||||
connection's timer and remove the connection if it times
|
connection's timer and remove the connection if it times
|
||||||
@@ -919,12 +919,14 @@ uip_process(u8_t flag) __banked
|
|||||||
}
|
}
|
||||||
#endif /* UIP_BROADCAST */
|
#endif /* UIP_BROADCAST */
|
||||||
|
|
||||||
/* 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(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) {
|
if(!(BUF->proto == UIP_PROTO_UDP && UDPBUF->destport == HTONS(DHCPC_CLIENT_PORT))) {
|
||||||
UIP_STAT(++uip_stat.ip.drop);
|
if(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) {
|
||||||
goto drop;
|
UIP_STAT(++uip_stat.ip.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
|
||||||
@@ -1901,7 +1903,7 @@ htons(u16_t val)
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_send(register __xdata const void *data, register uint16_t len)
|
uip_send(register __xdata const void *data, register uint16_t len) __banked
|
||||||
{
|
{
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
uip_slen = len;
|
uip_slen = len;
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ void uip_setipid(u16_t id);
|
|||||||
*
|
*
|
||||||
* \param port A 16-bit port number in network byte order.
|
* \param port A 16-bit port number in network byte order.
|
||||||
*/
|
*/
|
||||||
void uip_listen(u16_t port);
|
void uip_listen(u16_t port) __banked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop listening to the specified port.
|
* Stop listening to the specified port.
|
||||||
@@ -461,7 +461,7 @@ void uip_listen(u16_t port);
|
|||||||
*
|
*
|
||||||
* \param port A 16-bit port number in network byte order.
|
* \param port A 16-bit port number in network byte order.
|
||||||
*/
|
*/
|
||||||
void uip_unlisten(u16_t port);
|
void uip_unlisten(u16_t port) __banked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to a remote host using TCP.
|
* Connect to a remote host using TCP.
|
||||||
@@ -495,7 +495,7 @@ void uip_unlisten(u16_t port);
|
|||||||
* or NULL if no connection could be allocated.
|
* or NULL if no connection could be allocated.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
__xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t port);
|
__xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t port) __banked;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -535,7 +535,7 @@ __xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __x
|
|||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
void uip_send(register __xdata const void *data, register uint16_t len);
|
void uip_send(register __xdata const void *data, register uint16_t len) __banked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The length of any incoming data that is currently avaliable (if avaliable)
|
* The length of any incoming data that is currently avaliable (if avaliable)
|
||||||
@@ -763,7 +763,7 @@ void uip_send(register __xdata const void *data, register uint16_t len);
|
|||||||
* \return The uip_udp_conn structure for the new connection or NULL
|
* \return The uip_udp_conn structure for the new connection or NULL
|
||||||
* if no connection could be allocated.
|
* if no connection could be allocated.
|
||||||
*/
|
*/
|
||||||
struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
|
struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removed a UDP connection.
|
* Removed a UDP connection.
|
||||||
@@ -1224,8 +1224,8 @@ struct uip_udp_conn {
|
|||||||
/**
|
/**
|
||||||
* The current UDP connection.
|
* The current UDP connection.
|
||||||
*/
|
*/
|
||||||
extern struct uip_udp_conn *uip_udp_conn;
|
extern __xdata struct uip_udp_conn *uip_udp_conn;
|
||||||
extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
extern __xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1538,58 +1538,6 @@ extern __xdata uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
|
|||||||
extern __xdata uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
|
extern __xdata uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
|
||||||
#endif /* UIP_FIXEDADDR */
|
#endif /* UIP_FIXEDADDR */
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the Internet checksum over a buffer.
|
|
||||||
*
|
|
||||||
* The Internet checksum is the one's complement of the one's
|
|
||||||
* complement sum of all 16-bit words in the buffer.
|
|
||||||
*
|
|
||||||
* See RFC1071.
|
|
||||||
*
|
|
||||||
* \param buf A pointer to the buffer over which the checksum is to be
|
|
||||||
* computed.
|
|
||||||
*
|
|
||||||
* \param len The length of the buffer over which the checksum is to
|
|
||||||
* be computed.
|
|
||||||
*
|
|
||||||
* \return The Internet checksum of the buffer.
|
|
||||||
*/
|
|
||||||
u16_t uip_chksum(u16_t *buf, u16_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the IP header checksum of the packet header in uip_buf.
|
|
||||||
*
|
|
||||||
* The IP header checksum is the Internet checksum of the 20 bytes of
|
|
||||||
* the IP header.
|
|
||||||
*
|
|
||||||
* \return The IP header checksum of the IP header in the uip_buf
|
|
||||||
* buffer.
|
|
||||||
*/
|
|
||||||
u16_t uip_ipchksum(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
|
|
||||||
*
|
|
||||||
* The TCP checksum is the Internet checksum of data contents of the
|
|
||||||
* TCP segment, and a pseudo-header as defined in RFC793.
|
|
||||||
*
|
|
||||||
* \return The TCP checksum of the TCP segment in uip_buf and pointed
|
|
||||||
* to by uip_appdata.
|
|
||||||
*/
|
|
||||||
u16_t uip_tcpchksum(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
|
|
||||||
*
|
|
||||||
* The UDP checksum is the Internet checksum of data contents of the
|
|
||||||
* UDP segment, and a pseudo-header as defined in RFC768.
|
|
||||||
*
|
|
||||||
* \return The UDP checksum of the UDP segment in uip_buf and pointed
|
|
||||||
* to by uip_appdata.
|
|
||||||
*/
|
|
||||||
u16_t uip_udpchksum(void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __UIP_H__ */
|
#endif /* __UIP_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user