diff --git a/rtl837x_regs.h b/rtl837x_regs.h index 37a7e99d..6154221b 100644 --- a/rtl837x_regs.h +++ b/rtl837x_regs.h @@ -144,6 +144,9 @@ #define RTL837X_REG_CPU_TAG_AWARE_PMASK 0x603C #define RTL837X_REG_MAC_FORCE_MODE 0x6344 +/* Flags in byte 1 of the RX frame descriptor */ +#define RX_TAG_L4_CSUM_BAD 0x04 + /* * Statistics related registers */ diff --git a/test/test_httpd_tx.c b/test/test_httpd_tx.c index 0b2d7a23..3a82b343 100644 --- a/test/test_httpd_tx.c +++ b/test/test_httpd_tx.c @@ -26,6 +26,7 @@ #include "httpd.h" #include "uip.h" #include "rtl837x_common.h" +#include "rtl837x_regs.h" #include "rtl837x_flash.h" #include "page_impl.h" #include "html_data.h" @@ -71,6 +72,7 @@ uint16_t crc_value; uint8_t *HTTP_RESPONCE_TXT = (uint8_t *)"HTTP/1.1 200 OK\r\n\r\n"; uint32_t flash_size = 0x80000; uint8_t flash_buf[FLASH_BUF_SIZE]; +uint8_t rx_headers[16]; struct flash_region_t flash_region; char *mime_strings[] = { "text/html", "image/svg+xml", "image/x-icon", @@ -455,6 +457,38 @@ static void scenario_rexmit_after_shrink(void) CHECK(same, "retransmission: the repeat carries the same bytes"); } +static void scenario_bad_l4_checksum(void) +{ + uip_stats_t chkerr_before; + uint32_t seq_before; + int len_before; + + session_start(MSS_FULL); + + chkerr_before = uip_stat.tcp.chkerr; + len_before = stream_len; + seq_before = cli_seq; + + rx_headers[1] = RX_TAG_L4_CSUM_BAD; + request_file(MSS_FULL); + rx_headers[1] = 0; + cli_seq = seq_before; + + CHECK(uip_stat.tcp.chkerr == chkerr_before + 1, + "bad checksum: the segment is counted as a checksum error"); + CHECK(stream_len == len_before, + "bad checksum: the request draws no reply"); + + request_file(MSS_FULL); + drain(MSS_FULL); + report("bad checksum"); + + CHECK(body_offset() >= 0, + "bad checksum control: the same request with a good flag is served"); + CHECK(first_body_mismatch() == -1, + "bad checksum control: the file that follows is intact"); +} + int main(int argc, char **argv) { if (argc > 1 && !strcmp(argv[1], "-v")) @@ -465,6 +499,7 @@ int main(int argc, char **argv) scenario_shrinking_window(); scenario_growing_window(); scenario_rexmit_after_shrink(); + scenario_bad_l4_checksum(); printf("\n%s (%d failure%s)\n", failures ? "BENCH: FAILURES" : "BENCH: ALL PASS", diff --git a/uip/uip.c b/uip/uip.c index de822aa8..774067da 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -95,6 +95,9 @@ #endif /* UIP_CONF_IPV6 */ #include "../rtl837x_common.h" +#include "../rtl837x_regs.h" + +extern __xdata uint8_t rx_headers[16]; /*---------------------------------------------------------------------------*/ /* Variable definitions. */ @@ -1120,6 +1123,12 @@ uip_process(u8_t flag) __banked goto drop; } #else /* UIP_UDP_CHECKSUMS */ + if (rx_headers[1] & RX_TAG_L4_CSUM_BAD) { + UIP_STAT(++uip_stat.udp.drop); + UIP_STAT(++uip_stat.udp.chkerr); + UIP_LOG("udp: bad checksum."); + goto drop; + } uip_len = uip_len - UIP_IPUDPH_LEN; #endif /* UIP_UDP_CHECKSUMS */ @@ -1200,15 +1209,12 @@ uip_process(u8_t flag) __banked /* Start of TCP input header processing code. */ -// BUG: We need to reimplement this with RTL837x TCP checksum checking -// i.e. figure out which bit in the RX-tag states the checksum is correct -// if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP -// checksum. */ -// UIP_STAT(++uip_stat.tcp.drop); -// UIP_STAT(++uip_stat.tcp.chkerr); -// UIP_LOG("tcp: bad checksum."); -// goto drop; -// } + if (rx_headers[1] & RX_TAG_L4_CSUM_BAD) { + UIP_STAT(++uip_stat.tcp.drop); + UIP_STAT(++uip_stat.tcp.chkerr); + UIP_LOG("tcp: bad checksum."); + goto drop; + } /* Demultiplex this segment. */