diff --git a/Makefile b/Makefile index 4d6e8ffa..d6e1008a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ SRCS = mongoose.c test/unit_test.c test/packed_fs.c HDRS = $(wildcard src/*.h) $(wildcard mip/*.h) -PACKED ?= 1 -DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=$(PACKED) -DMG_ENABLE_SSI=1 +DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_SSI=1 C_WARN ?= -Wmissing-prototypes -Wstrict-prototypes WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef $(C_WARN) OPTS ?= -O3 -g3 @@ -35,14 +34,16 @@ CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto endif -all: mg_prefix unamalgamated unpacked test test++ arm examples vc98 vc17 vc22 mingw mingw++ linux linux++ fuzz +all: mg_prefix unamalgamated unpacked test test++ mip_test arm examples vc98 vc17 vc22 mingw mingw++ linux linux++ fuzz -mip_test: PACKED=0 -mip_test: DEFS += -DMG_ENABLE_SOCKET=0 -DMG_ENABLE_MIP=1 mip_test: test/mip_test.c mongoose.c mongoose.h Makefile - $(CC) test/mip_test.c $(CFLAGS) $(LDFLAGS) -g -o $@ + $(CC) test/mip_test.c $(INCS) $(WARN) $(OPTS) -g -o $@ ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@ +mip_test++: mip_test +mip_test++: C_WARN = -Wno-deprecated +mip_test++: CC = g++ + examples: @for X in $(EXAMPLES); do test -f $$X/Makefile || continue; $(MAKE) -C $$X example || exit 1; done @@ -79,8 +80,9 @@ unamalgamated: $(HDRS) Makefile test/packed_fs.c unpacked: $(CC) -I. mongoose.c test/unit_test.c -o $@ +fuzzer: WARN += -Wno-missing-field-initializers fuzzer: mongoose.c mongoose.h Makefile test/fuzz.c - clang++ mongoose.c test/fuzz.c $(WARN) $(INCS) $(TFLAGS) -DMG_ENABLE_LINES -fsanitize=fuzzer,signed-integer-overflow,address -Wno-deprecated -Wno-vla-extension -o $@ + $(CXX) test/fuzz.c $(WARN) $(INCS) $(TFLAGS) -fsanitize=fuzzer,signed-integer-overflow,address -Wno-deprecated -Wno-vla-extension -o $@ fuzz: fuzzer $(RUN) ./fuzzer diff --git a/mip/driver_enc28j60.c b/mip/driver_enc28j60.c index d765ae49..015f9730 100644 --- a/mip/driver_enc28j60.c +++ b/mip/driver_enc28j60.c @@ -16,7 +16,7 @@ static uint8_t rd(struct mip_spi *spi, uint8_t op, uint8_t addr) { static bool mip_driver_enc28j60_init(uint8_t *mac, void *data) { (void) mac, (void) data; - rd(data, OP_SRC, 0x1f); + rd((struct mip_spi *) data, OP_SRC, 0x1f); return false; } @@ -35,8 +35,7 @@ static bool mip_driver_enc28j60_up(void *data) { return false; } -struct mip_driver mip_driver_enc28j60 = {.init = mip_driver_enc28j60_init, - .tx = mip_driver_enc28j60_tx, - .rx = mip_driver_enc28j60_rx, - .up = mip_driver_enc28j60_up}; +struct mip_driver mip_driver_enc28j60 = { + mip_driver_enc28j60_init, mip_driver_enc28j60_tx, mip_driver_enc28j60_rx, + mip_driver_enc28j60_up, NULL}; #endif diff --git a/mip/driver_stm32.c b/mip/driver_stm32.c index f4835c00..e58a2732 100644 --- a/mip/driver_stm32.c +++ b/mip/driver_stm32.c @@ -1,6 +1,6 @@ #include "mip.h" -#if MG_ENABLE_MIP && defined(__arm__) +#if MG_ENABLE_MIP struct stm32_eth { volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR, MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR, @@ -30,7 +30,7 @@ static void *s_rxdata; // Recv callback data enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 }; // PHY constants static inline void spin(volatile uint32_t count) { - while (count--) asm("nop"); + while (count--) (void) 0; } static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) { @@ -126,7 +126,7 @@ static bool mip_driver_stm32_init(uint8_t *mac, void *userdata) { // Set MDC clock divider. If user told us the value, use it. Otherwise, guess int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr; - ETH->MACMIIAR = (cr & 3) << 2; + ETH->MACMIIAR = ((uint32_t)cr & 3) << 2; // NOTE(cpq): we do not use extended descriptor bit 7, and do not use // hardware checksum. Therefore, descriptor size is 4, not 8 @@ -201,8 +201,7 @@ void ETH_IRQHandler(void) { ETH->DMASR = sr & ~(BIT(2) | BIT(7)); // Clear status } -struct mip_driver mip_driver_stm32 = {.init = mip_driver_stm32_init, - .tx = mip_driver_stm32_tx, - .setrx = mip_driver_stm32_setrx, - .up = mip_driver_stm32_up}; +struct mip_driver mip_driver_stm32 = { + mip_driver_stm32_init, mip_driver_stm32_tx, NULL, mip_driver_stm32_up, + mip_driver_stm32_setrx}; #endif diff --git a/mip/driver_w5500.c b/mip/driver_w5500.c index 8e1ca2e9..e3515fbc 100644 --- a/mip/driver_w5500.c +++ b/mip/driver_w5500.c @@ -6,8 +6,9 @@ enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 }; static void w5500_txn(struct mip_spi *s, uint8_t block, uint16_t addr, bool wr, void *buf, size_t len) { - uint8_t *p = buf, cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255), - (uint8_t) ((block << 3) | (wr ? 4 : 0))}; + uint8_t *p = (uint8_t *) buf; + uint8_t cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255), + (uint8_t) ((block << 3) | (wr ? 4 : 0))}; s->begin(s->spi); for (size_t i = 0; i < sizeof(cmd); i++) s->txn(s->spi, cmd[i]); for (size_t i = 0; i < len; i++) { @@ -84,6 +85,6 @@ static bool w5500_up(void *data) { return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up) } -struct mip_driver mip_driver_w5500 = { - .init = w5500_init, .tx = w5500_tx, .rx = w5500_rx, .up = w5500_up}; +struct mip_driver mip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up, + NULL}; #endif diff --git a/mip/mip.c b/mip/mip.c index 9155efd1..60a416c3 100644 --- a/mip/mip.c +++ b/mip/mip.c @@ -2,7 +2,7 @@ #if MG_ENABLE_MIP -#if defined(_MSC_VER) || defined(ARDUINO) +#if defined(_MSC_VER) || defined(ARDUINO) || defined(__cplusplus) #define _Atomic #else #include @@ -311,11 +311,16 @@ static void arp_ask(struct mip_if *ifp, uint32_t ip) { ifp->driver->tx(eth, PDIFF(eth, arp + 1), ifp->driver_data); } +static size_t mg_print_ipv4(mg_pfn_t fn, void *fn_data, va_list *ap) { + uint32_t ip = mg_ntohl(va_arg(*ap, uint32_t)); + return mg_xprintf(fn, fn_data, "%d.%d.%d.%d", ip >> 24, (ip >> 16) & 255, + (ip >> 8) & 255, ip & 255); +} + static void onstatechange(struct mip_if *ifp) { if (ifp->state == MIP_STATE_READY) { - char buf[40]; - struct mg_addr addr = {.ip = ifp->ip}; - MG_INFO(("READY, IP: %s", mg_ntoa(&addr, buf, sizeof(buf)))); + MG_INFO(("READY, IP: %M", mg_print_ipv4, ifp->ip)); + MG_INFO((" GW: %M", mg_print_ipv4, ifp->gw)); arp_ask(ifp, ifp->gw); } else if (ifp->state == MIP_STATE_UP) { MG_ERROR(("Link up")); @@ -371,11 +376,19 @@ static void tx_udp(struct mip_if *ifp, uint32_t ip_src, uint16_t sport, static void tx_dhcp(struct mip_if *ifp, uint32_t src, uint32_t dst, uint8_t *opts, size_t optslen) { - struct dhcp dhcp = {.op = 1, - .htype = 1, - .hlen = 6, - .ciaddr = src, - .magic = mg_htonl(0x63825363)}; +#if 0 +struct dhcp { + uint8_t op, htype, hlen, hops; + uint32_t xid; + uint16_t secs, flags; + uint32_t ciaddr, yiaddr, siaddr, giaddr; + uint8_t hwaddr[208]; + uint32_t magic; + uint8_t options[32]; +}; +#endif + struct dhcp dhcp = {1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}}; + dhcp.magic = mg_htonl(0x63825363); memcpy(&dhcp.hwaddr, ifp->mac, sizeof(ifp->mac)); memcpy(&dhcp.xid, ifp->mac + 2, sizeof(dhcp.xid)); memcpy(&dhcp.options, opts, optslen); @@ -733,7 +746,11 @@ static void rx_ip6(struct mip_if *ifp, struct pkt *pkt) { static void mip_rx(struct mip_if *ifp, void *buf, size_t len) { const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255}; - struct pkt pkt = {.raw = {.buf = (uint8_t *) buf, .len = len}}; + // struct pkt pkt = {.raw = {.buf = (uint8_t *) buf, .len = len}}; + struct pkt pkt; + memset(&pkt, 0, sizeof(pkt)); + pkt.raw.buf = (uint8_t *) buf; + pkt.raw.len = len; pkt.eth = (struct eth *) buf; if (pkt.raw.len < sizeof(*pkt.eth)) return; // Truncated - runt? if (memcmp(pkt.eth->dst, ifp->mac, sizeof(pkt.eth->dst)) != 0 && @@ -835,32 +852,38 @@ static void on_rx(void *buf, size_t len, void *userdata) { } } +static void if_init(struct mip_if *ifp, struct mg_mgr *mgr, + struct mip_cfg *ipcfg, struct mip_driver *driver, + void *driver_data, size_t maxpktsize, size_t qlen) { + memcpy(ifp->mac, ipcfg->mac, sizeof(ifp->mac)); + ifp->use_dhcp = ipcfg->ip == 0; + ifp->ip = ipcfg->ip, ifp->mask = ipcfg->mask, ifp->gw = ipcfg->gw; + ifp->rx.buf = (uint8_t *) (ifp + 1), ifp->rx.len = maxpktsize; + ifp->tx.buf = ifp->rx.buf + maxpktsize, ifp->tx.len = maxpktsize; + ifp->driver = driver; + ifp->driver_data = driver_data; + ifp->mgr = mgr; + ifp->queue.buf = ifp->tx.buf + maxpktsize; + ifp->queue.len = qlen; + ifp->timer_1000ms = mg_millis(); + arp_cache_init(ifp->arp_cache, MIP_ARP_ENTRIES, 12); + if (driver->setrx) driver->setrx(on_rx, ifp); + mgr->priv = ifp; + mgr->extraconnsize = sizeof(struct connstate); +#ifdef MIP_QPROFILE + qp_init(); +#endif +} + void mip_init(struct mg_mgr *mgr, struct mip_cfg *ipcfg, struct mip_driver *driver, void *driver_data) { if (driver->init && !driver->init(ipcfg->mac, driver_data)) { MG_ERROR(("driver init failed")); } else { - size_t maxpktsize = 1518, qlen = driver->setrx ? MIP_QSIZE : 0; + size_t maxpktsize = 1540, qlen = driver->setrx ? MIP_QSIZE : 0; struct mip_if *ifp = (struct mip_if *) calloc(1, sizeof(*ifp) + 2 * maxpktsize + qlen); - memcpy(ifp->mac, ipcfg->mac, sizeof(ifp->mac)); - ifp->use_dhcp = ipcfg->ip == 0; - ifp->ip = ipcfg->ip, ifp->mask = ipcfg->mask, ifp->gw = ipcfg->gw; - ifp->rx.buf = (uint8_t *) (ifp + 1), ifp->rx.len = maxpktsize; - ifp->tx.buf = ifp->rx.buf + maxpktsize, ifp->tx.len = maxpktsize; - ifp->driver = driver; - ifp->driver_data = driver_data; - ifp->mgr = mgr; - ifp->queue.buf = ifp->tx.buf + maxpktsize; - ifp->queue.len = qlen; - ifp->timer_1000ms = mg_millis(); - arp_cache_init(ifp->arp_cache, MIP_ARP_ENTRIES, 12); - if (driver->setrx) driver->setrx(on_rx, ifp); - mgr->priv = ifp; - mgr->extraconnsize = sizeof(struct connstate); -#ifdef MIP_QPROFILE - qp_init(); -#endif + if_init(ifp, mgr, ipcfg, driver, driver_data, maxpktsize, qlen); } } diff --git a/mongoose.c b/mongoose.c index 968613be..a5560d02 100644 --- a/mongoose.c +++ b/mongoose.c @@ -5958,7 +5958,7 @@ static uint8_t rd(struct mip_spi *spi, uint8_t op, uint8_t addr) { static bool mip_driver_enc28j60_init(uint8_t *mac, void *data) { (void) mac, (void) data; - rd(data, OP_SRC, 0x1f); + rd((struct mip_spi *) data, OP_SRC, 0x1f); return false; } @@ -5977,10 +5977,9 @@ static bool mip_driver_enc28j60_up(void *data) { return false; } -struct mip_driver mip_driver_enc28j60 = {.init = mip_driver_enc28j60_init, - .tx = mip_driver_enc28j60_tx, - .rx = mip_driver_enc28j60_rx, - .up = mip_driver_enc28j60_up}; +struct mip_driver mip_driver_enc28j60 = { + mip_driver_enc28j60_init, mip_driver_enc28j60_tx, mip_driver_enc28j60_rx, + mip_driver_enc28j60_up, NULL}; #endif #ifdef MG_ENABLE_LINES @@ -5988,7 +5987,7 @@ struct mip_driver mip_driver_enc28j60 = {.init = mip_driver_enc28j60_init, #endif -#if MG_ENABLE_MIP && defined(__arm__) +#if MG_ENABLE_MIP struct stm32_eth { volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR, MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR, @@ -6018,7 +6017,7 @@ static void *s_rxdata; // Recv callback data enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 }; // PHY constants static inline void spin(volatile uint32_t count) { - while (count--) asm("nop"); + while (count--) (void) 0; } static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) { @@ -6114,7 +6113,7 @@ static bool mip_driver_stm32_init(uint8_t *mac, void *userdata) { // Set MDC clock divider. If user told us the value, use it. Otherwise, guess int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr; - ETH->MACMIIAR = (cr & 3) << 2; + ETH->MACMIIAR = ((uint32_t)cr & 3) << 2; // NOTE(cpq): we do not use extended descriptor bit 7, and do not use // hardware checksum. Therefore, descriptor size is 4, not 8 @@ -6189,10 +6188,9 @@ void ETH_IRQHandler(void) { ETH->DMASR = sr & ~(BIT(2) | BIT(7)); // Clear status } -struct mip_driver mip_driver_stm32 = {.init = mip_driver_stm32_init, - .tx = mip_driver_stm32_tx, - .setrx = mip_driver_stm32_setrx, - .up = mip_driver_stm32_up}; +struct mip_driver mip_driver_stm32 = { + mip_driver_stm32_init, mip_driver_stm32_tx, NULL, mip_driver_stm32_up, + mip_driver_stm32_setrx}; #endif #ifdef MG_ENABLE_LINES @@ -6206,8 +6204,9 @@ enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 }; static void w5500_txn(struct mip_spi *s, uint8_t block, uint16_t addr, bool wr, void *buf, size_t len) { - uint8_t *p = buf, cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255), - (uint8_t) ((block << 3) | (wr ? 4 : 0))}; + uint8_t *p = (uint8_t *) buf; + uint8_t cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255), + (uint8_t) ((block << 3) | (wr ? 4 : 0))}; s->begin(s->spi); for (size_t i = 0; i < sizeof(cmd); i++) s->txn(s->spi, cmd[i]); for (size_t i = 0; i < len; i++) { @@ -6284,8 +6283,8 @@ static bool w5500_up(void *data) { return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up) } -struct mip_driver mip_driver_w5500 = { - .init = w5500_init, .tx = w5500_tx, .rx = w5500_rx, .up = w5500_up}; +struct mip_driver mip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up, + NULL}; #endif #ifdef MG_ENABLE_LINES @@ -6295,7 +6294,7 @@ struct mip_driver mip_driver_w5500 = { #if MG_ENABLE_MIP -#if defined(_MSC_VER) || defined(ARDUINO) +#if defined(_MSC_VER) || defined(ARDUINO) || defined(__cplusplus) #define _Atomic #else #include @@ -6604,11 +6603,16 @@ static void arp_ask(struct mip_if *ifp, uint32_t ip) { ifp->driver->tx(eth, PDIFF(eth, arp + 1), ifp->driver_data); } +static size_t mg_print_ipv4(mg_pfn_t fn, void *fn_data, va_list *ap) { + uint32_t ip = mg_ntohl(va_arg(*ap, uint32_t)); + return mg_xprintf(fn, fn_data, "%d.%d.%d.%d", ip >> 24, (ip >> 16) & 255, + (ip >> 8) & 255, ip & 255); +} + static void onstatechange(struct mip_if *ifp) { if (ifp->state == MIP_STATE_READY) { - char buf[40]; - struct mg_addr addr = {.ip = ifp->ip}; - MG_INFO(("READY, IP: %s", mg_ntoa(&addr, buf, sizeof(buf)))); + MG_INFO(("READY, IP: %M", mg_print_ipv4, ifp->ip)); + MG_INFO((" GW: %M", mg_print_ipv4, ifp->gw)); arp_ask(ifp, ifp->gw); } else if (ifp->state == MIP_STATE_UP) { MG_ERROR(("Link up")); @@ -6664,11 +6668,19 @@ static void tx_udp(struct mip_if *ifp, uint32_t ip_src, uint16_t sport, static void tx_dhcp(struct mip_if *ifp, uint32_t src, uint32_t dst, uint8_t *opts, size_t optslen) { - struct dhcp dhcp = {.op = 1, - .htype = 1, - .hlen = 6, - .ciaddr = src, - .magic = mg_htonl(0x63825363)}; +#if 0 +struct dhcp { + uint8_t op, htype, hlen, hops; + uint32_t xid; + uint16_t secs, flags; + uint32_t ciaddr, yiaddr, siaddr, giaddr; + uint8_t hwaddr[208]; + uint32_t magic; + uint8_t options[32]; +}; +#endif + struct dhcp dhcp = {1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}}; + dhcp.magic = mg_htonl(0x63825363); memcpy(&dhcp.hwaddr, ifp->mac, sizeof(ifp->mac)); memcpy(&dhcp.xid, ifp->mac + 2, sizeof(dhcp.xid)); memcpy(&dhcp.options, opts, optslen); @@ -7026,7 +7038,11 @@ static void rx_ip6(struct mip_if *ifp, struct pkt *pkt) { static void mip_rx(struct mip_if *ifp, void *buf, size_t len) { const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255}; - struct pkt pkt = {.raw = {.buf = (uint8_t *) buf, .len = len}}; + // struct pkt pkt = {.raw = {.buf = (uint8_t *) buf, .len = len}}; + struct pkt pkt; + memset(&pkt, 0, sizeof(pkt)); + pkt.raw.buf = (uint8_t *) buf; + pkt.raw.len = len; pkt.eth = (struct eth *) buf; if (pkt.raw.len < sizeof(*pkt.eth)) return; // Truncated - runt? if (memcmp(pkt.eth->dst, ifp->mac, sizeof(pkt.eth->dst)) != 0 && @@ -7128,32 +7144,38 @@ static void on_rx(void *buf, size_t len, void *userdata) { } } +static void if_init(struct mip_if *ifp, struct mg_mgr *mgr, + struct mip_cfg *ipcfg, struct mip_driver *driver, + void *driver_data, size_t maxpktsize, size_t qlen) { + memcpy(ifp->mac, ipcfg->mac, sizeof(ifp->mac)); + ifp->use_dhcp = ipcfg->ip == 0; + ifp->ip = ipcfg->ip, ifp->mask = ipcfg->mask, ifp->gw = ipcfg->gw; + ifp->rx.buf = (uint8_t *) (ifp + 1), ifp->rx.len = maxpktsize; + ifp->tx.buf = ifp->rx.buf + maxpktsize, ifp->tx.len = maxpktsize; + ifp->driver = driver; + ifp->driver_data = driver_data; + ifp->mgr = mgr; + ifp->queue.buf = ifp->tx.buf + maxpktsize; + ifp->queue.len = qlen; + ifp->timer_1000ms = mg_millis(); + arp_cache_init(ifp->arp_cache, MIP_ARP_ENTRIES, 12); + if (driver->setrx) driver->setrx(on_rx, ifp); + mgr->priv = ifp; + mgr->extraconnsize = sizeof(struct connstate); +#ifdef MIP_QPROFILE + qp_init(); +#endif +} + void mip_init(struct mg_mgr *mgr, struct mip_cfg *ipcfg, struct mip_driver *driver, void *driver_data) { if (driver->init && !driver->init(ipcfg->mac, driver_data)) { MG_ERROR(("driver init failed")); } else { - size_t maxpktsize = 1518, qlen = driver->setrx ? MIP_QSIZE : 0; + size_t maxpktsize = 1540, qlen = driver->setrx ? MIP_QSIZE : 0; struct mip_if *ifp = (struct mip_if *) calloc(1, sizeof(*ifp) + 2 * maxpktsize + qlen); - memcpy(ifp->mac, ipcfg->mac, sizeof(ifp->mac)); - ifp->use_dhcp = ipcfg->ip == 0; - ifp->ip = ipcfg->ip, ifp->mask = ipcfg->mask, ifp->gw = ipcfg->gw; - ifp->rx.buf = (uint8_t *) (ifp + 1), ifp->rx.len = maxpktsize; - ifp->tx.buf = ifp->rx.buf + maxpktsize, ifp->tx.len = maxpktsize; - ifp->driver = driver; - ifp->driver_data = driver_data; - ifp->mgr = mgr; - ifp->queue.buf = ifp->tx.buf + maxpktsize; - ifp->queue.len = qlen; - ifp->timer_1000ms = mg_millis(); - arp_cache_init(ifp->arp_cache, MIP_ARP_ENTRIES, 12); - if (driver->setrx) driver->setrx(on_rx, ifp); - mgr->priv = ifp; - mgr->extraconnsize = sizeof(struct connstate); -#ifdef MIP_QPROFILE - qp_init(); -#endif + if_init(ifp, mgr, ipcfg, driver, driver_data, maxpktsize, qlen); } } diff --git a/mongoose.h b/mongoose.h index f4799f2b..ae74e734 100644 --- a/mongoose.h +++ b/mongoose.h @@ -1006,7 +1006,7 @@ enum { MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis - MG_EV_USER, // Starting ID for user events + MG_EV_USER // Starting ID for user events }; diff --git a/src/event.h b/src/event.h index e50fdae8..769c12af 100644 --- a/src/event.h +++ b/src/event.h @@ -26,5 +26,5 @@ enum { MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis - MG_EV_USER, // Starting ID for user events + MG_EV_USER // Starting ID for user events }; diff --git a/test/driver_mock.c b/test/driver_mock.c new file mode 100644 index 00000000..eeef942c --- /dev/null +++ b/test/driver_mock.c @@ -0,0 +1,25 @@ +static bool my_random(void) { + return mg_millis() & 1; +} + +static bool mock_init(uint8_t *mac, void *data) { + (void) mac, (void) data; + return my_random(); +} + +static size_t mock_tx(const void *buf, size_t len, void *data) { + (void) buf, (void) len, (void) data; + return len; +} + +static size_t mock_rx(void *buf, size_t len, void *data) { + (void) buf, (void) len, (void) data; + return len; +} + +static bool mock_up(void *data) { + (void) data; + return my_random(); +} + +struct mip_driver mip_driver_mock = {mock_init, mock_tx, mock_rx, mock_up, 0}; diff --git a/test/fuzz.c b/test/fuzz.c index 120bcd84..9fb9f1a1 100644 --- a/test/fuzz.c +++ b/test/fuzz.c @@ -1,4 +1,11 @@ -#include "mongoose.h" +#define MG_ENABLE_SOCKET 0 +#define MG_ENABLE_LOG 0 +#define MG_ENABLE_LINES 1 +#define MG_ENABLE_MIP 1 + +#include "mongoose.c" + +#include "driver_mock.c" #ifdef __cplusplus extern "C" int LLVMFuzzerTestOneInput(const uint8_t *, size_t); @@ -47,6 +54,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int n; mg_json_get(mg_str_n((char *) data, size), "$", &n); + mg_json_get(mg_str_n((char *) data, size), "$.a.b", &n); + mg_json_get(mg_str_n((char *) data, size), "$[0]", &n); + + struct mip_cfg cfg = {}; + size_t pktlen = 1540; + char t[sizeof(struct mip_if) + pktlen * 2 + 0 /* qlen */]; + struct mip_if *ifp = (struct mip_if *) t; + struct mg_mgr mgr; + mg_mgr_init(&mgr); + if_init(ifp, &mgr, &cfg, &mip_driver_mock, NULL, pktlen, 0); + mip_rx(ifp, (void *) data, size); + mgr.priv = NULL; // Don't let Mongoose free() ifp + mg_mgr_free(&mgr); return 0; } diff --git a/test/mip_test.c b/test/mip_test.c index 3bb05940..1b4af3dd 100644 --- a/test/mip_test.c +++ b/test/mip_test.c @@ -1,8 +1,15 @@ +#define MG_ENABLE_SOCKET 0 +#define MG_ENABLE_MIP 1 +#define MG_ENABLE_PACKED_FS 0 + #include #include "mongoose.c" +#include "driver_mock.c" + static void test_queue(void) { - static uint8_t buf[sizeof(size_t) + sizeof(uint16_t) + 3 ]; // fit 1 element but not 2 + static uint8_t + buf[sizeof(size_t) + sizeof(uint16_t) + 3]; // fit 1 element but not 2 uint16_t val = 1234; static struct queue q = {buf, sizeof(buf), 0, 0}; @@ -30,8 +37,20 @@ static void test_queue(void) { assert(q_avail(&q) == 0); } +static void test_statechange(void) { + uint8_t tx[1540]; + struct mip_if iface; + memset(&iface, 0, sizeof(iface)); + iface.ip = mg_htonl(0x01020304); + iface.state = MIP_STATE_READY; + iface.tx.buf = tx, iface.tx.len = sizeof(tx); + iface.driver = &mip_driver_mock; + onstatechange(&iface); +} + int main(void) { test_queue(); + test_statechange(); printf("SUCCESS\n"); return 0; }