test.c
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <unistd.h> 18 #include <signal.h> 19 #include <string.h> 20 21 #include "mdns.h" 22 #include "mdns_private.h" 23 24 // 25 // Global stuctures containing packet payload, search 26 mdns_rx_packet_t g_packet; 27 struct pbuf mypbuf; 28 mdns_search_once_t * search = NULL; 29 30 // 31 // Dependency injected test functions 32 void mdns_test_execute_action(void * action); 33 mdns_srv_item_t * mdns_test_mdns_get_service_item(const char * service, const char * proto); 34 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); 35 esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once_t * search); 36 void mdns_test_search_free(mdns_search_once_t * search); 37 void mdns_test_init_di(void); 38 39 // 40 // mdns function wrappers for mdns setup in test mode 41 static int mdns_test_hostname_set(const char * mdns_hostname) 42 { 43 int ret = mdns_hostname_set(mdns_hostname); 44 mdns_action_t * a = NULL; 45 GetLastItem(&a); 46 mdns_test_execute_action(a); 47 return ret; 48 } 49 50 static int mdns_test_service_instance_name_set(const char * service, const char * proto, const char * instance) 51 { 52 int ret = mdns_service_instance_name_set(service, proto, instance); 53 mdns_action_t * a = NULL; 54 GetLastItem(&a); 55 mdns_test_execute_action(a); 56 return ret; 57 } 58 59 static int mdns_test_service_txt_set(const char * service, const char * proto, uint8_t num_items, mdns_txt_item_t txt[]) 60 { 61 int ret = mdns_service_txt_set(service, proto, txt, num_items); 62 mdns_action_t * a = NULL; 63 GetLastItem(&a); 64 mdns_test_execute_action(a); 65 return ret; 66 } 67 68 static int mdns_test_service_add(const char * service_name, const char * proto, uint32_t port) 69 { 70 if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) { 71 // This is expected failure as the service thread is not running 72 } 73 mdns_action_t * a = NULL; 74 GetLastItem(&a); 75 mdns_test_execute_action(a); 76 77 if (mdns_test_mdns_get_service_item(service_name, proto)==NULL) { 78 return ESP_FAIL; 79 } 80 return ESP_OK; 81 } 82 83 static mdns_result_t* mdns_test_query(const char * service_name, const char * proto) 84 { 85 search = mdns_test_search_init(NULL, service_name, proto, MDNS_TYPE_PTR, 3000, 20); 86 if (!search) { 87 abort(); 88 } 89 90 if (mdns_test_send_search_action(ACTION_SEARCH_ADD, search)) { 91 mdns_test_search_free(search); 92 abort(); 93 } 94 95 mdns_action_t * a = NULL; 96 GetLastItem(&a); 97 mdns_test_execute_action(a); 98 return NULL; 99 } 100 101 static void mdns_test_query_free(void) 102 { 103 mdns_test_search_free(search); 104 } 105 106 // 107 // function "under test" where afl-mangled packets passed 108 // 109 void mdns_parse_packet(mdns_rx_packet_t * packet); 110 111 // 112 // Test starts here 113 // 114 int main(int argc, char** argv) 115 { 116 int i; 117 const char * mdns_hostname = "minifritz"; 118 const char * mdns_instance = "Hristo's Time Capsule"; 119 mdns_txt_item_t arduTxtData[4] = { 120 {"board","esp32"}, 121 {"tcp_check","no"}, 122 {"ssh_upload","no"}, 123 {"auth_upload","no"} 124 }; 125 126 const uint8_t mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x32}; 127 128 uint8_t buf[1460]; 129 char winstance[21+strlen(mdns_hostname)]; 130 131 sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", mdns_hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 132 133 // Init depencency injected methods 134 mdns_test_init_di(); 135 136 if (mdns_init()) { 137 abort(); 138 } 139 140 if (mdns_test_hostname_set(mdns_hostname)) { 141 abort(); 142 } 143 144 if (mdns_test_service_add("_workstation", "_tcp", 9)) { 145 abort(); 146 } 147 if (mdns_test_service_instance_name_set("_workstation", "_tcp", winstance)) { 148 abort(); 149 } 150 151 if (mdns_test_service_add("_arduino", "_tcp", 3232)) { 152 abort(); 153 } 154 155 if (mdns_test_service_txt_set("_arduino", "_tcp", 4, arduTxtData)) { 156 abort(); 157 } 158 159 if (mdns_test_service_add("_http", "_tcp", 80)) { 160 abort(); 161 } 162 163 if (mdns_test_service_instance_name_set("_http", "_tcp", "ESP WebServer")) { 164 abort(); 165 } 166 167 if ( 168 mdns_test_service_add("_afpovertcp", "_tcp", 548) 169 || mdns_test_service_add("_rfb", "_tcp", 885) 170 || mdns_test_service_add("_smb", "_tcp", 885) 171 || mdns_test_service_add("_adisk", "_tcp", 885) 172 || mdns_test_service_add("_airport", "_tcp", 885) 173 || mdns_test_service_add("_printer", "_tcp", 885) 174 || mdns_test_service_add("_airplay", "_tcp", 885) 175 || mdns_test_service_add("_raop", "_tcp", 885) 176 || mdns_test_service_add("_uscan", "_tcp", 885) 177 || mdns_test_service_add("_uscans", "_tcp", 885) 178 || mdns_test_service_add("_ippusb", "_tcp", 885) 179 || mdns_test_service_add("_scanner", "_tcp", 885) 180 || mdns_test_service_add("_ipp", "_tcp", 885) 181 || mdns_test_service_add("_ipps", "_tcp", 885) 182 || mdns_test_service_add("_pdl-datastream", "_tcp", 885) 183 || mdns_test_service_add("_ptp", "_tcp", 885) 184 || mdns_test_service_add("_sleep-proxy", "_udp", 885)) 185 { 186 abort(); 187 } 188 189 mdns_result_t * results = NULL; 190 FILE *file; 191 size_t nread; 192 193 #ifdef INSTR_IS_OFF 194 size_t len = 1460; 195 memset(buf, 0, 1460); 196 197 if (argc != 2) 198 { 199 printf("Non-instrumentation mode: please supply a file name created by AFL to reproduce crash\n"); 200 return 1; 201 } 202 else 203 { 204 // 205 // Note: parameter1 is a file (mangled packet) which caused the crash 206 file = fopen(argv[1], "r"); 207 if (file) { 208 len = fread(buf, 1, 1460, file); 209 } 210 fclose(file); 211 } 212 213 for (i=0; i<1; i++) { 214 #else 215 while (__AFL_LOOP(1000)) { 216 memset(buf, 0, 1460); 217 size_t len = read(0, buf, 1460); 218 #endif 219 mypbuf.payload = buf; 220 mypbuf.len = len; 221 g_packet.pb = &mypbuf; 222 mdns_test_query("_afpovertcp", "_tcp"); 223 mdns_parse_packet(&g_packet); 224 } 225 ForceTaskDelete(); 226 mdns_free(); 227 return 0; 228 }