mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-26 22:41:03 +08:00
Fuzzing MIP
This commit is contained in:
parent
ec79ca71b2
commit
a12bd2271e
16
Makefile
16
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
81
mip/mip.c
81
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 <stdatomic.h>
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
112
mongoose.c
112
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 <stdatomic.h>
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
25
test/driver_mock.c
Normal file
25
test/driver_mock.c
Normal file
@ -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};
|
22
test/fuzz.c
22
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;
|
||||
}
|
||||
|
@ -1,8 +1,15 @@
|
||||
#define MG_ENABLE_SOCKET 0
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_PACKED_FS 0
|
||||
|
||||
#include <assert.h>
|
||||
#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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user