mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-29 10:17:30 +02:00
MDNS-Fuzzer: AFL fuzzer tests for mdsn packet parser
* Original commit: espressif/esp-idf@e983230be9
This commit is contained in:
committed by
suren-gabrielyan-espressif
parent
450c9de67b
commit
9f1be3668e
@ -1,17 +1,25 @@
|
||||
TEST_NAME=test
|
||||
FUZZ=afl-fuzz
|
||||
CC=afl-clang-fast
|
||||
COMPONENTS_DIR=../..
|
||||
CFLAGS=-g -DMDNS_TEST_MODE -I. -I.. -I../include -I../private_include -I$(COMPONENTS_DIR)/tcpip_adapter/include -I$(COMPONENTS_DIR)/esp32/include -include esp32_compat.h
|
||||
MDNS_C_DEPENDENCY_INJECTION=-include mdns_di.h
|
||||
ifeq ($(INSTR),off)
|
||||
CC=gcc
|
||||
CFLAGS+=-DINSTR_IS_OFF
|
||||
TEST_NAME=test_sim
|
||||
else
|
||||
CC=afl-clang-fast
|
||||
endif
|
||||
CPP=$(CC)
|
||||
LD=$(CC)
|
||||
OBJECTS=mdns.o test.o
|
||||
CFLAGS=-DMDNS_TEST_MODE -I. -I../include
|
||||
OBJECTS=mdns.o esp32_mock.o test.o
|
||||
|
||||
OS := $(shell uname)
|
||||
ifeq ($(OS),Darwin)
|
||||
LDLIBS=
|
||||
else
|
||||
LDLIBS=-lbsd
|
||||
CFLAGS+=-DUSE_BSD_STRING
|
||||
LDLIBS=-lbsd
|
||||
CFLAGS+=-DUSE_BSD_STRING
|
||||
endif
|
||||
|
||||
all: $(TEST_NAME)
|
||||
@ -22,11 +30,11 @@ all: $(TEST_NAME)
|
||||
|
||||
mdns.o: ../mdns.c
|
||||
@echo "[CC] $<"
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
@$(CC) $(CFLAGS) $(MDNS_C_DEPENDENCY_INJECTION) -c $< -o $@
|
||||
|
||||
$(TEST_NAME): $(OBJECTS)
|
||||
@echo "[LD] $@"
|
||||
@$(LD) $(LDLIBS) $(OBJECTS) -o $@
|
||||
@$(LD) $(OBJECTS) -o $@ $(LDLIBS)
|
||||
|
||||
fuzz: $(TEST_NAME)
|
||||
@$(FUZZ) -i "in" -o "out" -- ./$(TEST_NAME)
|
||||
|
@ -17,6 +17,12 @@
|
||||
|
||||
#ifdef MDNS_TEST_MODE
|
||||
|
||||
// Not to include
|
||||
#define ESP_MDNS_NETWORKING_H_
|
||||
#define _TCPIP_ADAPTER_H_
|
||||
#define __ESP_EVENT_H__
|
||||
|
||||
|
||||
#ifdef USE_BSD_STRING
|
||||
#include <bsd/string.h>
|
||||
#endif
|
||||
@ -28,6 +34,7 @@
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
#define ERR_OK 0
|
||||
#define ESP_OK 0
|
||||
#define ESP_FAIL -1
|
||||
@ -44,21 +51,26 @@
|
||||
|
||||
#define pdTRUE true
|
||||
#define pdFALSE false
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
|
||||
#define portMAX_DELAY 0xFFFFFFFF
|
||||
#define portTICK_PERIOD_MS 1
|
||||
|
||||
#define xSemaphoreTake(s,d)
|
||||
#define xTaskDelete(a)
|
||||
#define vTaskDelete(a) free(a)
|
||||
#define xSemaphoreGive(s)
|
||||
#define _mdns_pcb_init(a,b) true
|
||||
#define _mdns_pcb_deinit(a,b) true
|
||||
#define xSemaphoreCreateMutex() malloc(1)
|
||||
#define vSemaphoreDelete(s) free(s)
|
||||
#define xQueueCreate(n,s) malloc((n)*(s))
|
||||
#define vQueueDelete(q) free(q)
|
||||
#define xQueueReceive(q, d, t) (ESP_OK)
|
||||
#define vTaskDelay(m) usleep((m)*1000)
|
||||
#define xTaskCreatePinnedToCore(a,b,c,d,e,f,g) *(f) = malloc(1)
|
||||
#define vTaskDelay(m) usleep((m)*0)
|
||||
#define pbuf_free(p) free(p)
|
||||
|
||||
#define tcpip_adapter_get_ip_info(i,d)
|
||||
#define esp_random() (rand()%UINT32_MAX)
|
||||
#define tcpip_adapter_get_ip_info(i,d) true
|
||||
#define tcpip_adapter_dhcpc_get_status(a, b) TCPIP_ADAPTER_DHCP_STARTED
|
||||
#define tcpip_adapter_get_ip6_linklocal(i,d) (ESP_OK)
|
||||
#define tcpip_adapter_get_hostname(i, n) *(n) = "esp32-0123456789AB"
|
||||
|
||||
@ -67,17 +79,31 @@
|
||||
((uint32_t)((c) & 0xff) << 16) | \
|
||||
((uint32_t)((b) & 0xff) << 8) | \
|
||||
(uint32_t)((a) & 0xff)
|
||||
#define ip_2_ip6(ipaddr) (&((ipaddr)->u_addr.ip6))
|
||||
#define ip_2_ip4(ipaddr) (&((ipaddr)->u_addr.ip4))
|
||||
|
||||
#define IPADDR_TYPE_V4 0U
|
||||
#define IPADDR_TYPE_V6 6U
|
||||
#define IPADDR_TYPE_ANY 46U
|
||||
#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0)
|
||||
#define IP_ADDR4(ipaddr,a,b,c,d) do { IP4_ADDR(ip_2_ip4(ipaddr),a,b,c,d); \
|
||||
IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V4); } while(0)
|
||||
#define IP_ADDR6(ipaddr,i0,i1,i2,i3) do { IP6_ADDR(ip_2_ip6(ipaddr),i0,i1,i2,i3); \
|
||||
IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V6); } while(0)
|
||||
|
||||
#define IPADDR6_INIT(a, b, c, d) { { { { a, b, c, d } } }, IPADDR_TYPE_V6 }
|
||||
|
||||
typedef int32_t esp_err_t;
|
||||
|
||||
typedef void * xSemaphoreHandle;
|
||||
typedef void * SemaphoreHandle_t;
|
||||
typedef void * xQueueHandle;
|
||||
typedef void * QueueHandle_t;
|
||||
typedef void * TaskHandle_t;
|
||||
typedef void * esp_timer_handle_t;
|
||||
typedef uint32_t TickType_t;
|
||||
typedef uint32_t portTickType;
|
||||
|
||||
typedef enum {
|
||||
TCPIP_ADAPTER_IF_STA = 0, /**< ESP32 station interface */
|
||||
TCPIP_ADAPTER_IF_AP, /**< ESP32 soft-AP interface */
|
||||
TCPIP_ADAPTER_IF_ETH, /**< ESP32 ethernet interface */
|
||||
TCPIP_ADAPTER_IF_MAX
|
||||
} tcpip_adapter_if_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_MODE_NULL = 0, /**< null mode */
|
||||
@ -87,6 +113,42 @@ typedef enum {
|
||||
WIFI_MODE_MAX
|
||||
} wifi_mode_t;
|
||||
|
||||
/* status of DHCP client or DHCP server */
|
||||
typedef enum {
|
||||
TCPIP_ADAPTER_DHCP_INIT = 0, /**< DHCP client/server in initial state */
|
||||
TCPIP_ADAPTER_DHCP_STARTED, /**< DHCP client/server already been started */
|
||||
TCPIP_ADAPTER_DHCP_STOPPED, /**< DHCP client/server already been stopped */
|
||||
TCPIP_ADAPTER_DHCP_STATUS_MAX
|
||||
} tcpip_adapter_dhcp_status_t;
|
||||
|
||||
typedef enum {
|
||||
SYSTEM_EVENT_WIFI_READY = 0, /**< ESP32 WiFi ready */
|
||||
SYSTEM_EVENT_SCAN_DONE, /**< ESP32 finish scanning AP */
|
||||
SYSTEM_EVENT_STA_START, /**< ESP32 station start */
|
||||
SYSTEM_EVENT_STA_STOP, /**< ESP32 station stop */
|
||||
SYSTEM_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */
|
||||
SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */
|
||||
SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */
|
||||
SYSTEM_EVENT_STA_GOT_IP, /**< ESP32 station got IP from connected AP */
|
||||
SYSTEM_EVENT_STA_LOST_IP, /**< ESP32 station lost IP and the IP is reset to 0 */
|
||||
SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /**< ESP32 station wps succeeds in enrollee mode */
|
||||
SYSTEM_EVENT_STA_WPS_ER_FAILED, /**< ESP32 station wps fails in enrollee mode */
|
||||
SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP32 station wps timeout in enrollee mode */
|
||||
SYSTEM_EVENT_STA_WPS_ER_PIN, /**< ESP32 station wps pin code in enrollee mode */
|
||||
SYSTEM_EVENT_AP_START, /**< ESP32 soft-AP start */
|
||||
SYSTEM_EVENT_AP_STOP, /**< ESP32 soft-AP stop */
|
||||
SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */
|
||||
SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */
|
||||
SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */
|
||||
SYSTEM_EVENT_GOT_IP6, /**< ESP32 station or ap or ethernet interface v6IP addr is preferred */
|
||||
SYSTEM_EVENT_ETH_START, /**< ESP32 ethernet start */
|
||||
SYSTEM_EVENT_ETH_STOP, /**< ESP32 ethernet stop */
|
||||
SYSTEM_EVENT_ETH_CONNECTED, /**< ESP32 ethernet phy link up */
|
||||
SYSTEM_EVENT_ETH_DISCONNECTED, /**< ESP32 ethernet phy link down */
|
||||
SYSTEM_EVENT_ETH_GOT_IP, /**< ESP32 ethernet got IP from connected AP */
|
||||
SYSTEM_EVENT_MAX
|
||||
} system_event_id_t;
|
||||
|
||||
struct udp_pcb {
|
||||
uint8_t dummy;
|
||||
};
|
||||
@ -101,27 +163,76 @@ struct ip6_addr {
|
||||
};
|
||||
typedef struct ip6_addr ip6_addr_t;
|
||||
|
||||
typedef struct _ip_addr {
|
||||
union {
|
||||
ip6_addr_t ip6;
|
||||
ip4_addr_t ip4;
|
||||
} u_addr;
|
||||
uint8_t type;
|
||||
} ip_addr_t;
|
||||
|
||||
typedef struct {
|
||||
ip4_addr_t ip;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
} tcpip_adapter_ip_info_t;
|
||||
|
||||
// typedef int32_t system_event_id_t;
|
||||
typedef enum {
|
||||
TCPIP_ADAPTER_IF_STA = 0, /**< ESP32 station interface */
|
||||
TCPIP_ADAPTER_IF_AP, /**< ESP32 soft-AP interface */
|
||||
TCPIP_ADAPTER_IF_ETH, /**< ESP32 ethernet interface */
|
||||
TCPIP_ADAPTER_IF_MAX
|
||||
} tcpip_adapter_if_t;
|
||||
|
||||
typedef struct {
|
||||
ip6_addr_t ip;
|
||||
} tcpip_adapter_ip6_info_t;
|
||||
typedef struct {
|
||||
tcpip_adapter_if_t if_index;
|
||||
tcpip_adapter_ip6_info_t ip6_info;
|
||||
} system_event_got_ip6_t;
|
||||
typedef union {
|
||||
system_event_got_ip6_t got_ip6; /**< ESP32 station or ap or ethernet ipv6 addr state change to preferred */
|
||||
} system_event_info_t;
|
||||
|
||||
typedef struct {
|
||||
system_event_id_t event_id; /**< event ID */
|
||||
system_event_info_t event_info; /**< event information */
|
||||
} system_event_t;
|
||||
|
||||
inline esp_err_t esp_wifi_get_mode(wifi_mode_t * mode)
|
||||
{
|
||||
*mode = WIFI_MODE_APSTA;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
inline uint32_t xTaskGetTickCount()
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
if (gettimeofday(&tv, &tz) == 0) {
|
||||
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
struct pbuf {
|
||||
struct pbuf *next;
|
||||
void *payload;
|
||||
uint16_t tot_len;
|
||||
uint16_t len;
|
||||
uint8_t /*pbuf_type*/ type;
|
||||
uint8_t flags;
|
||||
uint16_t ref;
|
||||
};
|
||||
|
||||
#define IP_GET_TYPE(ipaddr) ((ipaddr)->type)
|
||||
#define IP_IS_V6_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6)
|
||||
#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
|
||||
#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \
|
||||
(dest).addr[1] = (src).addr[1]; \
|
||||
(dest).addr[2] = (src).addr[2]; \
|
||||
(dest).addr[3] = (src).addr[3];}while(0)
|
||||
|
||||
#define ip_addr_copy(dest, src) do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \
|
||||
ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \
|
||||
ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); }}while(0)
|
||||
|
||||
#include "esp32_mock.h"
|
||||
|
||||
uint32_t xTaskGetTickCount();
|
||||
|
||||
|
||||
#endif //MDNS_TEST_MODE
|
||||
|
||||
|
84
components/mdns/test_afl_fuzz_host/esp32_mock.c
Normal file
84
components/mdns/test_afl_fuzz_host/esp32_mock.c
Normal file
@ -0,0 +1,84 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "esp32_compat.h"
|
||||
|
||||
void* g_queue;
|
||||
int g_queue_send_shall_fail = 0;
|
||||
int g_size = 0;
|
||||
|
||||
esp_err_t esp_timer_delete(esp_timer_handle_t timer)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_timer_stop(esp_timer_handle_t timer)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
|
||||
esp_timer_handle_t* out_handle)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t xTaskGetTickCount()
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
if (gettimeofday(&tv, &tz) == 0) {
|
||||
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Queue mock
|
||||
QueueHandle_t xQueueCreate( uint32_t uxQueueLength, uint32_t uxItemSize )
|
||||
{
|
||||
g_size = uxItemSize;
|
||||
g_queue = malloc((uxQueueLength)*(uxItemSize));
|
||||
return g_queue;
|
||||
}
|
||||
|
||||
|
||||
void vQueueDelete( QueueHandle_t xQueue )
|
||||
{
|
||||
free(xQueue);
|
||||
}
|
||||
|
||||
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait)
|
||||
{
|
||||
if (g_queue_send_shall_fail)
|
||||
{
|
||||
return pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(xQueue, pvItemToQueue, g_size);
|
||||
return pdPASS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait)
|
||||
{
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
void GetLastItem(void *pvBuffer)
|
||||
{
|
||||
memcpy(pvBuffer, g_queue, g_size);
|
||||
}
|
||||
|
||||
void ForceTaskDelete()
|
||||
{
|
||||
g_queue_send_shall_fail = 1;
|
||||
}
|
45
components/mdns/test_afl_fuzz_host/esp32_mock.h
Normal file
45
components/mdns/test_afl_fuzz_host/esp32_mock.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef ESP32_MOCK_H_
|
||||
#define ESP32_MOCK_H_
|
||||
|
||||
typedef void (*esp_timer_cb_t)(void* arg);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ESP_TIMER_TASK, //!< Callback is called from timer task
|
||||
} esp_timer_dispatch_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
esp_timer_cb_t callback; //!< Function to call when timer expires
|
||||
void* arg; //!< Argument to pass to the callback
|
||||
esp_timer_dispatch_t dispatch_method; //!< Call the callback from task or from ISR
|
||||
const char* name; //!< Timer name, used in esp_timer_dump function
|
||||
} esp_timer_create_args_t;
|
||||
|
||||
esp_err_t esp_timer_delete(esp_timer_handle_t timer);
|
||||
|
||||
esp_err_t esp_timer_stop(esp_timer_handle_t timer);
|
||||
|
||||
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period);
|
||||
|
||||
esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
|
||||
esp_timer_handle_t* out_handle);
|
||||
|
||||
|
||||
// Queue mock
|
||||
QueueHandle_t xQueueCreate( uint32_t uxQueueLength,
|
||||
uint32_t uxItemSize );
|
||||
|
||||
void vQueueDelete( QueueHandle_t xQueue );
|
||||
|
||||
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
|
||||
|
||||
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
|
||||
|
||||
void GetLastItem(void *pvBuffer);
|
||||
|
||||
void ForceTaskDelete();
|
||||
|
||||
#define _mdns_udp_pcb_write(tcpip_if, ip_protocol, ip, port, data, len) len
|
||||
|
||||
#endif /* ESP32_MOCK_H_ */
|
53
components/mdns/test_afl_fuzz_host/mdns_di.h
Normal file
53
components/mdns/test_afl_fuzz_host/mdns_di.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* MDNS Dependecy injection -- preincluded to inject interface test functions into static variables
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mdns.h"
|
||||
#include "mdns_private.h"
|
||||
|
||||
void (*mdns_test_static_execute_action)(mdns_action_t *) = NULL;
|
||||
mdns_srv_item_t * (*mdns_test_static_mdns_get_service_item)(const char * service, const char * proto) = NULL;
|
||||
mdns_search_once_t * (*mdns_test_static_search_init)(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results) = NULL;
|
||||
esp_err_t (*mdns_test_static_send_search_action)(mdns_action_type_t type, mdns_search_once_t * search) = NULL;
|
||||
void (*mdns_test_static_search_free)(mdns_search_once_t * search) = NULL;
|
||||
|
||||
static void _mdns_execute_action(mdns_action_t * action);
|
||||
static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char * proto);
|
||||
static mdns_search_once_t * _mdns_search_init(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results);
|
||||
static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_once_t * search);
|
||||
static void _mdns_search_free(mdns_search_once_t * search);
|
||||
|
||||
void mdns_test_init_di()
|
||||
{
|
||||
mdns_test_static_execute_action = _mdns_execute_action;
|
||||
mdns_test_static_mdns_get_service_item = _mdns_get_service_item;
|
||||
mdns_test_static_search_init = _mdns_search_init;
|
||||
mdns_test_static_send_search_action = _mdns_send_search_action;
|
||||
mdns_test_static_search_free = _mdns_search_free;
|
||||
}
|
||||
|
||||
void mdns_test_execute_action(void * action)
|
||||
{
|
||||
mdns_test_static_execute_action((mdns_action_t *)action);
|
||||
}
|
||||
|
||||
void mdns_test_search_free(mdns_search_once_t * search)
|
||||
{
|
||||
return mdns_test_static_search_free(search);
|
||||
}
|
||||
|
||||
esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once_t * search)
|
||||
{
|
||||
return mdns_test_static_send_search_action(type, search);
|
||||
}
|
||||
|
||||
mdns_search_once_t * mdns_test_search_init(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results)
|
||||
{
|
||||
return mdns_test_static_search_init(name, service, proto, type, timeout, max_results);
|
||||
}
|
||||
|
||||
mdns_srv_item_t * mdns_test_mdns_get_service_item(const char * service, const char * proto)
|
||||
{
|
||||
return mdns_test_static_mdns_get_service_item(service, proto);
|
||||
}
|
@ -12,8 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifdef MDNS_TEST_MODE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -21,93 +19,210 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mdns.h"
|
||||
#include "mdns_private.h"
|
||||
|
||||
void mdns_parse_packet(mdns_server_t * server, const uint8_t * data, size_t len);
|
||||
//
|
||||
// Global stuctures containing packet payload, search
|
||||
mdns_rx_packet_t g_packet;
|
||||
struct pbuf mypbuf;
|
||||
mdns_search_once_t * search = NULL;
|
||||
|
||||
//
|
||||
// Dependency injected test functions
|
||||
void mdns_test_execute_action(void * action);
|
||||
mdns_srv_item_t * mdns_test_mdns_get_service_item(const char * service, const char * proto);
|
||||
mdns_search_once_t * mdns_test_search_init(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results);
|
||||
esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once_t * search);
|
||||
void mdns_test_search_free(mdns_search_once_t * search);
|
||||
void mdns_test_init_di();
|
||||
|
||||
//
|
||||
// mdns function wrappers for mdns setup in test mode
|
||||
static int mdns_test_hostname_set(const char * mdns_hostname)
|
||||
{
|
||||
int ret = mdns_hostname_set(mdns_hostname);
|
||||
mdns_action_t * a = NULL;
|
||||
GetLastItem(&a);
|
||||
mdns_test_execute_action(a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mdns_test_service_instance_name_set(const char * service, const char * proto, const char * instance)
|
||||
{
|
||||
int ret = mdns_service_instance_name_set(service, proto, instance);
|
||||
mdns_action_t * a = NULL;
|
||||
GetLastItem(&a);
|
||||
mdns_test_execute_action(a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mdns_test_service_txt_set(const char * service, const char * proto, uint8_t num_items, mdns_txt_item_t txt[])
|
||||
{
|
||||
int ret = mdns_service_txt_set(service, proto, txt, num_items);
|
||||
mdns_action_t * a = NULL;
|
||||
GetLastItem(&a);
|
||||
mdns_test_execute_action(a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mdns_test_service_add(const char * service_name, const char * proto, uint32_t port)
|
||||
{
|
||||
if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) {
|
||||
// This is expected failure as the service thread is not running
|
||||
}
|
||||
mdns_action_t * a = NULL;
|
||||
GetLastItem(&a);
|
||||
mdns_test_execute_action(a);
|
||||
|
||||
if (mdns_test_mdns_get_service_item(service_name, proto)==NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static mdns_result_t* mdns_test_query(const char * service_name, const char * proto)
|
||||
{
|
||||
search = mdns_test_search_init(NULL, service_name, proto, MDNS_TYPE_PTR, 3000, 20);
|
||||
if (!search) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_test_send_search_action(ACTION_SEARCH_ADD, search)) {
|
||||
mdns_test_search_free(search);
|
||||
abort();
|
||||
}
|
||||
|
||||
mdns_action_t * a = NULL;
|
||||
GetLastItem(&a);
|
||||
mdns_test_execute_action(a);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void mdns_test_query_free()
|
||||
{
|
||||
mdns_test_search_free(search);
|
||||
}
|
||||
|
||||
//
|
||||
// function "under test" where afl-mangled packets passed
|
||||
//
|
||||
void mdns_parse_packet(mdns_rx_packet_t * packet);
|
||||
|
||||
//
|
||||
// Test starts here
|
||||
//
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int i;
|
||||
const char * mdns_hostname = "minifritz";
|
||||
const char * mdns_instance = "Hristo's Time Capsule";
|
||||
const char * arduTxtData[4] = {
|
||||
"board=esp32",
|
||||
"tcp_check=no",
|
||||
"ssh_upload=no",
|
||||
"auth_upload=no"
|
||||
mdns_txt_item_t arduTxtData[4] = {
|
||||
{"board","esp32"},
|
||||
{"tcp_check","no"},
|
||||
{"ssh_upload","no"},
|
||||
{"auth_upload","no"}
|
||||
};
|
||||
|
||||
const uint8_t mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x32};
|
||||
|
||||
mdns_server_t * mdns = NULL;
|
||||
uint8_t buf[1460];
|
||||
char winstance[21+strlen(mdns_hostname)];
|
||||
|
||||
sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", mdns_hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
if (mdns_init(TCPIP_ADAPTER_IF_ETH, &mdns)) {
|
||||
// Init depencency injected methods
|
||||
mdns_test_init_di();
|
||||
|
||||
if (mdns_init()) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_set_hostname(mdns, mdns_hostname)) {
|
||||
if (mdns_test_hostname_set(mdns_hostname)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_set_instance(mdns, mdns_instance)) {
|
||||
if (mdns_test_service_add("_workstation", "_tcp", 9)) {
|
||||
abort();
|
||||
}
|
||||
if (mdns_test_service_instance_name_set("_workstation", "_tcp", winstance)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_service_add(mdns, "_workstation", "_tcp", 9)) {
|
||||
if (mdns_test_service_add("_arduino", "_tcp", 3232)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_service_instance_set(mdns, "_workstation", "_tcp", winstance)) {
|
||||
if (mdns_test_service_txt_set("_arduino", "_tcp", 4, arduTxtData)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_service_add(mdns, "_arduino", "_tcp", 3232)) {
|
||||
if (mdns_test_service_add("_http", "_tcp", 80)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_service_txt_set(mdns, "_arduino", "_tcp", 4, arduTxtData)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_service_add(mdns, "_http", "_tcp", 80)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mdns_service_instance_set(mdns, "_http", "_tcp", "ESP WebServer")) {
|
||||
if (mdns_test_service_instance_name_set("_http", "_tcp", "ESP WebServer")) {
|
||||
abort();
|
||||
}
|
||||
|
||||
if (
|
||||
mdns_service_add(mdns, "_afpovertcp", "_tcp", 548)
|
||||
|| mdns_service_add(mdns, "_rfb", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_smb", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_adisk", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_airport", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_printer", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_airplay", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_raop", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_uscan", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_uscans", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_ippusb", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_scanner", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_ipp", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_ipps", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_pdl-datastream", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_ptp", "_tcp", 885)
|
||||
|| mdns_service_add(mdns, "_sleep-proxy", "_udp", 885))
|
||||
mdns_test_service_add("_afpovertcp", "_tcp", 548)
|
||||
|| mdns_test_service_add("_rfb", "_tcp", 885)
|
||||
|| mdns_test_service_add("_smb", "_tcp", 885)
|
||||
|| mdns_test_service_add("_adisk", "_tcp", 885)
|
||||
|| mdns_test_service_add("_airport", "_tcp", 885)
|
||||
|| mdns_test_service_add("_printer", "_tcp", 885)
|
||||
|| mdns_test_service_add("_airplay", "_tcp", 885)
|
||||
|| mdns_test_service_add("_raop", "_tcp", 885)
|
||||
|| mdns_test_service_add("_uscan", "_tcp", 885)
|
||||
|| mdns_test_service_add("_uscans", "_tcp", 885)
|
||||
|| mdns_test_service_add("_ippusb", "_tcp", 885)
|
||||
|| mdns_test_service_add("_scanner", "_tcp", 885)
|
||||
|| mdns_test_service_add("_ipp", "_tcp", 885)
|
||||
|| mdns_test_service_add("_ipps", "_tcp", 885)
|
||||
|| mdns_test_service_add("_pdl-datastream", "_tcp", 885)
|
||||
|| mdns_test_service_add("_ptp", "_tcp", 885)
|
||||
|| mdns_test_service_add("_sleep-proxy", "_udp", 885))
|
||||
{
|
||||
abort();
|
||||
abort();
|
||||
}
|
||||
|
||||
mdns_result_t * results = NULL;
|
||||
FILE *file;
|
||||
size_t nread;
|
||||
|
||||
#ifdef INSTR_IS_OFF
|
||||
size_t len = 1460;
|
||||
memset(buf, 0, 1460);
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Non-instrumentation mode: please supply a file name created by AFL to reproduce crash\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Note: parameter1 is a file (mangled packet) which caused the crash
|
||||
file = fopen(argv[1], "r");
|
||||
if (file) {
|
||||
len = fread(buf, 1, 1460, file);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
for (i=0; i<1; i++) {
|
||||
#else
|
||||
while (__AFL_LOOP(1000)) {
|
||||
memset(buf, 0, 1460);
|
||||
size_t len = read(0, buf, 1460);
|
||||
mdns_query(mdns, "_afpovertcp", "_tcp", 0);
|
||||
mdns_parse_packet(mdns, buf, len);
|
||||
mdns_query_end(mdns);
|
||||
#endif
|
||||
mypbuf.payload = buf;
|
||||
mypbuf.len = len;
|
||||
g_packet.pb = &mypbuf;
|
||||
mdns_test_query("_afpovertcp", "_tcp");
|
||||
mdns_parse_packet(&g_packet);
|
||||
}
|
||||
ForceTaskDelete();
|
||||
mdns_free();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user