diff --git a/src/printf.c b/src/printf.c index 1b6107ac..faed5aa0 100644 --- a/src/printf.c +++ b/src/printf.c @@ -3,10 +3,11 @@ #include "util.h" size_t mg_queue_vprintf(struct mg_queue *q, const char *fmt, va_list *ap) { + char *buf; + size_t len; va_list ap_copy; va_copy(ap_copy, *ap); - size_t len = mg_vsnprintf(NULL, 0, fmt, &ap_copy); - char *buf; + len = mg_vsnprintf(NULL, 0, fmt, &ap_copy); if (len == 0 || mg_queue_book(q, &buf, len + 1) < len + 1) { len = 0; // Nah. Not enough space } else { diff --git a/test/fuzz.c b/test/fuzz.c index 3b101be5..386bf10c 100644 --- a/test/fuzz.c +++ b/test/fuzz.c @@ -100,7 +100,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { memcpy(pkt, data, size); if (size > sizeof(*eth)) { static size_t i; - uint16_t eth_types[] = {0x800, 0x806, 0x86dd}; // IPv4, ARP, IPv6 +// uint16_t eth_types[] = {0x800, 0x806, 0x86dd}; // IPv4, ARP, IPv6 + uint16_t eth_types[] = {0x800, 0x806}; // IPv4, ARP, skip IPv6 until we merge it *** memcpy(eth->dst, mif.mac, 6); // Set valid destination MAC // send all handled eth types, then 2 random ones if (i >= (sizeof(eth_types) / sizeof(eth_types[0]) + 2)) i = 0; @@ -111,31 +112,49 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { uint8_t ip_protos[] = {1, 6, 17}; // ICMP, TCP, UDP struct ip *ip4 = (struct ip *) (eth + 1); ip4->ver = (ip4->ver & ~0xf0) | (4 << 4); - // send all handled ip protos, then 2 random ones + // send all handled IP protos, then 2 random ones if (j >= (sizeof(ip_protos) / sizeof(ip_protos[0]) + 2)) j = 0; if (j < (sizeof(ip_protos) / sizeof(ip_protos[0]))) ip4->proto = (ip_protos[j++]); if (ip4->proto == 1) { // ICMP } else if (ip4->proto == 6) { // TCP - } else if (ip4->proto == 17 && size > (sizeof(*eth) + sizeof(struct ip) + sizeof(struct udp))) { // UDP - static size_t k; - uint16_t udp_ports[] = {67, 68}; // DHCP server and client - struct udp *udp = (struct udp *) (ip4 + 1); - // send all handled udp ports, then 2 random ones - if (k >= (sizeof(udp_ports) / sizeof(udp_ports[0]) + 2)) k = 0; - if (k < (sizeof(udp_ports) / sizeof(udp_ports[0]))) udp->dport = mg_htons(udp_ports[k++]); + } else if (ip4->proto == 17) { // UDP + if (size > (sizeof(*eth) + sizeof(struct ip) + sizeof(struct udp))) { + static size_t k; + uint16_t udp_ports[] = {67, 68}; // DHCP server and client + struct udp *udp = (struct udp *) (ip4 + 1); + // send all handled UDP ports, then 2 random ones + if (k >= (sizeof(udp_ports) / sizeof(udp_ports[0]) + 2)) k = 0; + if (k < (sizeof(udp_ports) / sizeof(udp_ports[0]))) udp->dport = mg_htons(udp_ports[k++]); + } } } else if (eth->type == mg_htons(0x806)) { // ARP +#if 0 } else if (eth->type == mg_htons(0x86dd) && size > (sizeof(*eth) + sizeof(struct ip6))) { // IPv6 static size_t j; - uint8_t ip6_protos[] = {6, 17}; // TCP, UDP + uint8_t ip6_protos[] = {6, 17, 58}; // TCP, UDP, ICMPv6 struct ip6 *ip6 = (struct ip6 *) (eth + 1); ip6->ver = (ip6->ver & ~0xf0) | (6 << 4); - // send all handled ip6 "next headers", then 2 random ones + // send all handled IPv6 "next headers", then 2 random ones if (j >= (sizeof(ip6_protos) / sizeof(ip6_protos[0]) + 2)) j = 0; - if (j < (sizeof(ip6_protos) / sizeof(ip6_protos[0]))) ip6->proto = (ip6_protos[j++]); - if (ip6->proto == 6) { // TCP - } else if (ip6->proto == 17) { // UDP - } + if (j < (sizeof(ip6_protos) / sizeof(ip6_protos[0]))) ip6->next = (ip6_protos[j++]); + if (ip6->next == 6) { // TCP + } else if (ip6->next == 17) { // UDP + } else if (ip6->next == 58) { // ICMPv6 + if (size >= (sizeof(*eth) + sizeof(struct ip6) + sizeof(struct icmp6))) { + static size_t k; + uint16_t icmp6_types[] = {128, 134, 135, 136}; // Echo Request, RA, NS, NA + struct icmp6 *icmp6 = (struct icmp6 *) (ip6 + 1); + // send all handled ICMPv6 types, then 2 random ones + if (k >= (sizeof(icmp6_types) / sizeof(icmp6_types[0]) + 2)) k = 0; + if (k < (sizeof(icmp6_types) / sizeof(icmp6_types[0]))) icmp6->type = mg_htons(icmp6_types[k++]); + } + } +#else + } else if (eth->type == mg_htons(0x86dd)) { // IPv6 + free(pkt); + mg_mgr_free(&mgr); + return 0; +#endif } } diff --git a/test/fuzz_tls.c b/test/fuzz_tls.c index 309d4b80..8018ee7e 100644 --- a/test/fuzz_tls.c +++ b/test/fuzz_tls.c @@ -20,8 +20,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *, size_t); _(mg_tls_server_recv_hello) \ //_(mg_tls_client_recv_hello) \ //_(mg_tls_client_recv_ext ) \ -//_(mg_tls_client_recv_cert) \ -//_(mg_tls_client_recv_cert_verify) \ +//_(mg_tls_recv_cert) \ +//_(mg_tls_recv_cert_verify) \ // ... struct f { diff --git a/tutorials/stm32/portenta-h7-cube-baremetal-builtin/CM7/Core/Src/main.c b/tutorials/stm32/portenta-h7-cube-baremetal-builtin/CM7/Core/Src/main.c index 9816e081..8532fa36 100644 --- a/tutorials/stm32/portenta-h7-cube-baremetal-builtin/CM7/Core/Src/main.c +++ b/tutorials/stm32/portenta-h7-cube-baremetal-builtin/CM7/Core/Src/main.c @@ -203,23 +203,15 @@ static const struct mg_tcpip_driver_cyw_firmware fw = { // mif user states enum {AP, SCANNING, STOPPING_AP, CONNECTING, READY}; static unsigned int state; -static uint32_t s_ip, s_mask; static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { - // TODO(): should we include this inside ifp ? add an fn_data ? if (ev == MG_TCPIP_EV_ST_CHG) { MG_INFO(("State change: %u", *(uint8_t *) ev_data)); } switch(state) { case AP: // we are in AP mode, wait for a user connection to trigger a scan or a connection to a network - if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_UP) { - MG_INFO(("Access Point started")); - s_ip = ifp->ip, ifp->ip = MG_IPV4(192, 168, 169, 1); - s_mask = ifp->mask, ifp->mask = MG_IPV4(255, 255, 255, 0); - ifp->enable_dhcp_client = false; - ifp->enable_dhcp_server = true; - } else if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { + if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_READY) { MG_INFO(("Access Point READY !")); // simulate user request to scan for networks @@ -233,7 +225,6 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { struct mg_wifi_scan_bss_data *bss = (struct mg_wifi_scan_bss_data *) ev_data; MG_INFO(("BSS: %.*s (%u) (%M) %d dBm %u", bss->SSID.len, bss->SSID.buf, bss->channel, mg_print_mac, bss->BSSID, (int) bss->RSSI, bss->security)); } else if (ev == MG_TCPIP_EV_WIFI_SCAN_END) { - // struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; MG_INFO(("Wi-Fi scan finished")); // simulate user selection of a network (1/2: stop AP) @@ -245,18 +236,14 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { break; case STOPPING_AP: if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - d->apmode = false; + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi; + wifi->apmode = false; // simulate user selection of a network (2/2: actual connect) - bool res = mg_wifi_connect(d->ssid, d->pass); + bool res = mg_wifi_connect(wifi); MG_INFO(("Manually connecting: %s", res ? "OK":"FAIL")); if (res) { state = CONNECTING; - ifp->ip = s_ip; - ifp->mask = s_mask; - if (ifp->ip == 0) ifp->enable_dhcp_client = true; - ifp->enable_dhcp_server = false; } // else manually start AP as below } break; @@ -276,13 +263,13 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { case READY: // go back to AP mode after a disconnection (simulation 2/2), you could retry if (ev == MG_TCPIP_EV_ST_CHG && *(uint8_t *) ev_data == MG_TCPIP_STATE_DOWN) { - struct mg_tcpip_driver_cyw_data *d = (struct mg_tcpip_driver_cyw_data *) ifp->driver_data; - bool res = mg_wifi_ap_start(d->apssid, d->appass, d->apchannel); + struct mg_wifi_data *wifi = &((struct mg_tcpip_driver_cyw_data *) ifp->driver_data)->wifi; + bool res = mg_wifi_ap_start(wifi); MG_INFO(("Disconnected")); MG_INFO(("Manually starting AP: %s", res ? "OK":"FAIL")); if (res) { state = AP; - d->apmode = true; + wifi->apmode = true; } } break; @@ -291,7 +278,7 @@ static void mif_fn(struct mg_tcpip_if *ifp, int ev, void *ev_data) { static struct mg_tcpip_driver_cyw_data d = { - (void *)&sdio, (struct mg_tcpip_driver_cyw_firmware *)&fw, WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 10, true, false}; + {WIFI_SSID, WIFI_PASS, "mongoose", "mongoose", 0, 0, 0, 0, 10, true}, (void *)&sdio, (struct mg_tcpip_driver_cyw_firmware *)&fw, false}; /* USER CODE END 0 */ @@ -359,7 +346,9 @@ Error_Handler(); /* USER CODE BEGIN 2 */ hwspecific_sdio_init(); - state = d.apmode ? AP : CONNECTING; + d.wifi.apip = MG_IPV4(192, 168, 169, 1), + d.wifi.apmask = MG_IPV4(255, 255, 255, 0), + state = d.wifi.apmode ? AP : CONNECTING; struct mg_mgr mgr; // Initialise Mongoose event manager mg_mgr_init(&mgr); // and attach it to the interface