simple_sniffer_example_main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /* Sniffer example.
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "sdkconfig.h"
  11. #include "linenoise/linenoise.h"
  12. #include "argtable3/argtable3.h"
  13. #include "esp_console.h"
  14. #include "esp_event.h"
  15. #include "esp_vfs_fat.h"
  16. #include "esp_wifi.h"
  17. #include "esp_err.h"
  18. #include "esp_log.h"
  19. #if CONFIG_SNIFFER_PCAP_DESTINATION_SD
  20. #include "driver/sdmmc_host.h"
  21. #include "driver/sdspi_host.h"
  22. #include "driver/spi_common.h"
  23. #endif
  24. #include "nvs_flash.h"
  25. #include "sdmmc_cmd.h"
  26. #include "cmd_sniffer.h"
  27. #include "cmd_pcap.h"
  28. #if CONFIG_ETH_USE_SPI_ETHERNET
  29. #include "driver/spi_master.h"
  30. #endif // CONFIG_ETH_USE_SPI_ETHERNET
  31. #if CONFIG_SNIFFER_STORE_HISTORY
  32. #define HISTORY_MOUNT_POINT "/data"
  33. #define HISTORY_FILE_PATH HISTORY_MOUNT_POINT "/history.txt"
  34. #endif
  35. #if CONFIG_SNIFFER_SD_SPI_MODE
  36. #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
  37. #define PIN_NUM_MISO 2
  38. #define PIN_NUM_MOSI 15
  39. #define PIN_NUM_CLK 14
  40. #define PIN_NUM_CS 13
  41. #elif CONFIG_IDF_TARGET_ESP32C3
  42. #define PIN_NUM_MISO 18
  43. #define PIN_NUM_MOSI 9
  44. #define PIN_NUM_CLK 8
  45. #define PIN_NUM_CS 19
  46. #endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
  47. #endif // CONFIG_SNIFFER_SD_SPI_MODE
  48. static const char *TAG = "example";
  49. #if CONFIG_SNIFFER_STORE_HISTORY
  50. /* Initialize filesystem for command history store */
  51. static void initialize_filesystem(void)
  52. {
  53. static wl_handle_t wl_handle;
  54. const esp_vfs_fat_mount_config_t mount_config = {
  55. .max_files = 4,
  56. .format_if_mount_failed = true
  57. };
  58. esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(HISTORY_MOUNT_POINT, "storage", &mount_config, &wl_handle);
  59. if (err != ESP_OK) {
  60. ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
  61. return;
  62. }
  63. }
  64. #endif
  65. static void initialize_nvs(void)
  66. {
  67. esp_err_t err = nvs_flash_init();
  68. if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  69. ESP_ERROR_CHECK(nvs_flash_erase());
  70. err = nvs_flash_init();
  71. }
  72. ESP_ERROR_CHECK(err);
  73. }
  74. /* Initialize wifi with tcp/ip adapter */
  75. static void initialize_wifi(void)
  76. {
  77. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  78. ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  79. ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
  80. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
  81. }
  82. #ifndef CONFIG_SNIFFER_NO_ETHERNET
  83. /** Event handler for Ethernet events */
  84. static void eth_event_handler(void *arg, esp_event_base_t event_base,
  85. int32_t event_id, void *event_data)
  86. {
  87. uint8_t mac_addr[6] = {0};
  88. /* we can get the ethernet driver handle from event data */
  89. esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
  90. switch (event_id) {
  91. case ETHERNET_EVENT_CONNECTED:
  92. esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
  93. printf("\n");
  94. ESP_LOGI(TAG, "Ethernet Link Up");
  95. ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x\n",
  96. mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  97. break;
  98. case ETHERNET_EVENT_DISCONNECTED:
  99. printf("\n");
  100. ESP_LOGI(TAG, "Ethernet Link Down");
  101. break;
  102. case ETHERNET_EVENT_START:
  103. printf("\n");
  104. ESP_LOGI(TAG, "Ethernet Started");
  105. break;
  106. case ETHERNET_EVENT_STOP:
  107. printf("\n");
  108. ESP_LOGI(TAG, "Ethernet Stopped");
  109. break;
  110. default:
  111. break;
  112. }
  113. }
  114. static void initialize_eth(void)
  115. {
  116. // Register user defined event handers
  117. ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
  118. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  119. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  120. phy_config.phy_addr = CONFIG_SNIFFER_ETH_PHY_ADDR;
  121. phy_config.reset_gpio_num = CONFIG_SNIFFER_ETH_PHY_RST_GPIO;
  122. #if CONFIG_SNIFFER_USE_INTERNAL_ETHERNET
  123. eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
  124. esp32_emac_config.smi_mdc_gpio_num = CONFIG_SNIFFER_ETH_MDC_GPIO;
  125. esp32_emac_config.smi_mdio_gpio_num = CONFIG_SNIFFER_ETH_MDIO_GPIO;
  126. esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
  127. #if CONFIG_SNIFFER_ETH_PHY_IP101
  128. esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
  129. #elif CONFIG_SNIFFER_ETH_PHY_RTL8201
  130. esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
  131. #elif CONFIG_SNIFFER_ETH_PHY_LAN87XX
  132. esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
  133. #elif CONFIG_SNIFFER_ETH_PHY_DP83848
  134. esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
  135. #elif CONFIG_SNIFFER_ETH_PHY_KSZ80XX
  136. esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
  137. #endif
  138. #elif CONFIG_ETH_USE_SPI_ETHERNET
  139. gpio_install_isr_service(0);
  140. spi_bus_config_t buscfg = {
  141. .miso_io_num = CONFIG_SNIFFER_ETH_SPI_MISO_GPIO,
  142. .mosi_io_num = CONFIG_SNIFFER_ETH_SPI_MOSI_GPIO,
  143. .sclk_io_num = CONFIG_SNIFFER_ETH_SPI_SCLK_GPIO,
  144. .quadwp_io_num = -1,
  145. .quadhd_io_num = -1,
  146. };
  147. ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_SNIFFER_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
  148. spi_device_interface_config_t spi_devcfg = {
  149. .mode = 0,
  150. .clock_speed_hz = CONFIG_SNIFFER_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  151. .spics_io_num = CONFIG_SNIFFER_ETH_SPI_CS_GPIO,
  152. .queue_size = 20
  153. };
  154. #if CONFIG_SNIFFER_USE_KSZ8851SNL
  155. eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(CONFIG_SNIFFER_ETH_SPI_HOST, &spi_devcfg);
  156. ksz8851snl_config.int_gpio_num = CONFIG_SNIFFER_ETH_SPI_INT_GPIO;
  157. esp_eth_mac_t *mac = esp_eth_mac_new_ksz8851snl(&ksz8851snl_config, &mac_config);
  158. esp_eth_phy_t *phy = esp_eth_phy_new_ksz8851snl(&phy_config);
  159. #elif CONFIG_SNIFFER_USE_DM9051
  160. eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_SNIFFER_ETH_SPI_HOST, &spi_devcfg);
  161. dm9051_config.int_gpio_num = CONFIG_SNIFFER_ETH_SPI_INT_GPIO;
  162. esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
  163. esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);
  164. #elif CONFIG_SNIFFER_USE_W5500
  165. eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_SNIFFER_ETH_SPI_HOST, &spi_devcfg);
  166. w5500_config.int_gpio_num = CONFIG_SNIFFER_ETH_SPI_INT_GPIO;
  167. esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
  168. esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);
  169. #endif
  170. #endif // CONFIG_ETH_USE_SPI_ETHERNET
  171. esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
  172. esp_eth_handle_t eth_handle = NULL;
  173. ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
  174. #if !CONFIG_SNIFFER_USE_INTERNAL_ETHERNET
  175. /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually.
  176. 02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.
  177. */
  178. ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
  179. 0x02, 0x00, 0x00, 0x12, 0x34, 0x56
  180. }));
  181. #endif
  182. /* start Ethernet driver state machine */
  183. ESP_ERROR_CHECK(esp_eth_start(eth_handle));
  184. /* Register Ethernet interface to could be used by sniffer */
  185. ESP_ERROR_CHECK(sniffer_reg_eth_intf(eth_handle));
  186. }
  187. #endif // CONFIG_SNIFFER_NO_ETHERNET
  188. #if CONFIG_SNIFFER_PCAP_DESTINATION_SD
  189. static struct {
  190. struct arg_str *device;
  191. struct arg_end *end;
  192. } mount_args;
  193. /** 'mount' command */
  194. static int mount(int argc, char **argv)
  195. {
  196. esp_err_t ret;
  197. int nerrors = arg_parse(argc, argv, (void **)&mount_args);
  198. if (nerrors != 0) {
  199. arg_print_errors(stderr, mount_args.end, argv[0]);
  200. return 1;
  201. }
  202. /* mount sd card */
  203. if (!strncmp(mount_args.device->sval[0], "sd", 2)) {
  204. ESP_LOGI(TAG, "Initializing SD card");
  205. esp_vfs_fat_sdmmc_mount_config_t mount_config = {
  206. .format_if_mount_failed = true,
  207. .max_files = 4,
  208. .allocation_unit_size = 16 * 1024
  209. };
  210. // initialize SD card and mount FAT filesystem.
  211. sdmmc_card_t *card;
  212. #if CONFIG_SNIFFER_SD_SPI_MODE
  213. ESP_LOGI(TAG, "Using SPI peripheral");
  214. sdmmc_host_t host = SDSPI_HOST_DEFAULT();
  215. spi_bus_config_t bus_cfg = {
  216. .mosi_io_num = PIN_NUM_MOSI,
  217. .miso_io_num = PIN_NUM_MISO,
  218. .sclk_io_num = PIN_NUM_CLK,
  219. .quadwp_io_num = -1,
  220. .quadhd_io_num = -1,
  221. .max_transfer_sz = 4000,
  222. };
  223. ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CH_AUTO);
  224. if (ret != ESP_OK) {
  225. ESP_LOGE(TAG, "Failed to initialize bus.");
  226. return 1;
  227. }
  228. // This initializes the slot without card detect (CD) and write protect (WP) signals.
  229. // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
  230. sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
  231. slot_config.gpio_cs = PIN_NUM_CS;
  232. slot_config.host_id = host.slot;
  233. ret = esp_vfs_fat_sdspi_mount(CONFIG_SNIFFER_MOUNT_POINT, &host, &slot_config, &mount_config, &card);
  234. #else
  235. ESP_LOGI(TAG, "Using SDMMC peripheral");
  236. sdmmc_host_t host = SDMMC_HOST_DEFAULT();
  237. sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
  238. gpio_set_pull_mode(15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1-line modes
  239. gpio_set_pull_mode(2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
  240. gpio_set_pull_mode(4, GPIO_PULLUP_ONLY); // D1, needed in 4-line mode only
  241. gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only
  242. gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes
  243. ret = esp_vfs_fat_sdmmc_mount(CONFIG_SNIFFER_MOUNT_POINT, &host, &slot_config, &mount_config, &card);
  244. #endif
  245. if (ret != ESP_OK) {
  246. if (ret == ESP_FAIL) {
  247. ESP_LOGE(TAG, "Failed to mount filesystem. "
  248. "If you want the card to be formatted, set format_if_mount_failed = true.");
  249. } else {
  250. ESP_LOGE(TAG, "Failed to initialize the card (%s). "
  251. "Make sure SD card lines have pull-up resistors in place.",
  252. esp_err_to_name(ret));
  253. }
  254. return 1;
  255. }
  256. /* print card info if mount successfully */
  257. sdmmc_card_print_info(stdout, card);
  258. }
  259. return 0;
  260. }
  261. static void register_mount(void)
  262. {
  263. mount_args.device = arg_str1(NULL, NULL, "<sd>", "choose a proper device to mount/unmount");
  264. mount_args.end = arg_end(1);
  265. const esp_console_cmd_t cmd = {
  266. .command = "mount",
  267. .help = "mount the filesystem",
  268. .hint = NULL,
  269. .func = &mount,
  270. .argtable = &mount_args
  271. };
  272. ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
  273. }
  274. static int unmount(int argc, char **argv)
  275. {
  276. int nerrors = arg_parse(argc, argv, (void **)&mount_args);
  277. if (nerrors != 0) {
  278. arg_print_errors(stderr, mount_args.end, argv[0]);
  279. return 1;
  280. }
  281. /* unmount sd card */
  282. if (!strncmp(mount_args.device->sval[0], "sd", 2)) {
  283. if (esp_vfs_fat_sdmmc_unmount() != ESP_OK) {
  284. ESP_LOGE(TAG, "Card unmount failed");
  285. return -1;
  286. }
  287. ESP_LOGI(TAG, "Card unmounted");
  288. }
  289. return 0;
  290. }
  291. static void register_unmount(void)
  292. {
  293. mount_args.device = arg_str1(NULL, NULL, "<sd>", "choose a proper device to mount/unmount");
  294. mount_args.end = arg_end(1);
  295. const esp_console_cmd_t cmd = {
  296. .command = "unmount",
  297. .help = "unmount the filesystem",
  298. .hint = NULL,
  299. .func = &unmount,
  300. .argtable = &mount_args
  301. };
  302. ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
  303. }
  304. #endif // CONFIG_SNIFFER_PCAP_DESTINATION_SD
  305. void app_main(void)
  306. {
  307. initialize_nvs();
  308. /*--- Initialize Network ---*/
  309. ESP_ERROR_CHECK(esp_event_loop_create_default());
  310. /* Initialize WiFi */
  311. initialize_wifi();
  312. #ifndef CONFIG_SNIFFER_NO_ETHERNET
  313. /* Initialize Ethernet */
  314. initialize_eth();
  315. #endif
  316. /*--- Initialize Console ---*/
  317. esp_console_repl_t *repl = NULL;
  318. esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
  319. #if CONFIG_SNIFFER_STORE_HISTORY
  320. initialize_filesystem();
  321. repl_config.history_save_path = HISTORY_FILE_PATH;
  322. #endif
  323. repl_config.prompt = "sniffer>";
  324. // install console REPL environment
  325. #if CONFIG_ESP_CONSOLE_UART
  326. esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
  327. ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
  328. #elif CONFIG_ESP_CONSOLE_USB_CDC
  329. esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
  330. ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl));
  331. #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
  332. esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
  333. ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
  334. #endif
  335. /* Register commands */
  336. #if CONFIG_SNIFFER_PCAP_DESTINATION_SD
  337. register_mount();
  338. register_unmount();
  339. #endif
  340. register_sniffer_cmd();
  341. register_pcap_cmd();
  342. #if CONFIG_SNIFFER_PCAP_DESTINATION_SD
  343. printf("\n =======================================================\n");
  344. printf(" | Steps to sniff network packets |\n");
  345. printf(" | |\n");
  346. printf(" | 1. Enter 'help' to check all commands usage |\n");
  347. printf(" | 2. Enter 'mount <device>' to mount filesystem |\n");
  348. printf(" | 3. Enter 'pcap' to create pcap file |\n");
  349. printf(" | 4. Enter 'sniffer' to start capture packets |\n");
  350. printf(" | 5. Enter 'unmount <device>' to unmount filesystem |\n");
  351. printf(" | |\n");
  352. printf(" =======================================================\n\n");
  353. #else
  354. printf("\n =======================================================\n");
  355. printf(" | Steps to sniff network packets |\n");
  356. printf(" | |\n");
  357. printf(" | 1. Enter 'help' to check all commands' usage |\n");
  358. printf(" | 2. Enter 'pcap' to create pcap file |\n");
  359. printf(" | 3. Enter 'sniffer' to start capture packets |\n");
  360. printf(" | |\n");
  361. printf(" =======================================================\n\n");
  362. #endif
  363. // start console REPL
  364. ESP_ERROR_CHECK(esp_console_start_repl(repl));
  365. }