simple_sniffer_example_main.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  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(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. mac_config.smi_mdc_gpio_num = CONFIG_SNIFFER_ETH_MDC_GPIO;
  124. mac_config.smi_mdio_gpio_num = CONFIG_SNIFFER_ETH_MDIO_GPIO;
  125. esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
  126. #if CONFIG_SNIFFER_ETH_PHY_IP101
  127. esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
  128. #elif CONFIG_SNIFFER_ETH_PHY_RTL8201
  129. esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
  130. #elif CONFIG_SNIFFER_ETH_PHY_LAN87XX
  131. esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
  132. #elif CONFIG_SNIFFER_ETH_PHY_DP83848
  133. esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
  134. #elif CONFIG_SNIFFER_ETH_PHY_KSZ8041
  135. esp_eth_phy_t *phy = esp_eth_phy_new_ksz8041(&phy_config);
  136. #elif CONFIG_SNIFFER_ETH_PHY_KSZ8081
  137. esp_eth_phy_t *phy = esp_eth_phy_new_ksz8081(&phy_config);
  138. #endif
  139. #elif CONFIG_ETH_USE_SPI_ETHERNET
  140. gpio_install_isr_service(0);
  141. spi_device_handle_t spi_handle = NULL;
  142. spi_bus_config_t buscfg = {
  143. .miso_io_num = CONFIG_SNIFFER_ETH_SPI_MISO_GPIO,
  144. .mosi_io_num = CONFIG_SNIFFER_ETH_SPI_MOSI_GPIO,
  145. .sclk_io_num = CONFIG_SNIFFER_ETH_SPI_SCLK_GPIO,
  146. .quadwp_io_num = -1,
  147. .quadhd_io_num = -1,
  148. };
  149. ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_SNIFFER_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
  150. #if CONFIG_SNIFFER_USE_KSZ8851SNL
  151. spi_device_interface_config_t devcfg = {
  152. .mode = 0,
  153. .clock_speed_hz = CONFIG_SNIFFER_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  154. .spics_io_num = CONFIG_SNIFFER_ETH_SPI_CS_GPIO,
  155. .queue_size = 20
  156. };
  157. ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_SNIFFER_ETH_SPI_HOST, &devcfg, &spi_handle));
  158. /* KSZ8851SNL ethernet driver is based on spi driver */
  159. eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_handle);
  160. ksz8851snl_config.int_gpio_num = CONFIG_SNIFFER_ETH_SPI_INT_GPIO;
  161. esp_eth_mac_t *mac = esp_eth_mac_new_ksz8851snl(&ksz8851snl_config, &mac_config);
  162. esp_eth_phy_t *phy = esp_eth_phy_new_ksz8851snl(&phy_config);
  163. #elif CONFIG_SNIFFER_USE_DM9051
  164. spi_device_interface_config_t devcfg = {
  165. .command_bits = 1,
  166. .address_bits = 7,
  167. .mode = 0,
  168. .clock_speed_hz = CONFIG_SNIFFER_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  169. .spics_io_num = CONFIG_SNIFFER_ETH_SPI_CS_GPIO,
  170. .queue_size = 20
  171. };
  172. ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_SNIFFER_ETH_SPI_HOST, &devcfg, &spi_handle));
  173. /* dm9051 ethernet driver is based on spi driver */
  174. eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
  175. dm9051_config.int_gpio_num = CONFIG_SNIFFER_ETH_SPI_INT_GPIO;
  176. esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
  177. esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);
  178. #elif CONFIG_SNIFFER_USE_W5500
  179. spi_device_interface_config_t devcfg = {
  180. .command_bits = 16, // Actually it's the address phase in W5500 SPI frame
  181. .address_bits = 8, // Actually it's the control phase in W5500 SPI frame
  182. .mode = 0,
  183. .clock_speed_hz = CONFIG_SNIFFER_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
  184. .spics_io_num = CONFIG_SNIFFER_ETH_SPI_CS_GPIO,
  185. .queue_size = 20
  186. };
  187. ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_SNIFFER_ETH_SPI_HOST, &devcfg, &spi_handle));
  188. /* w5500 ethernet driver is based on spi driver */
  189. eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
  190. w5500_config.int_gpio_num = CONFIG_SNIFFER_ETH_SPI_INT_GPIO;
  191. esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
  192. esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);
  193. #endif
  194. #endif // CONFIG_ETH_USE_SPI_ETHERNET
  195. esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
  196. esp_eth_handle_t eth_handle = NULL;
  197. ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
  198. #if !CONFIG_SNIFFER_USE_INTERNAL_ETHERNET
  199. /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually.
  200. 02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.
  201. */
  202. ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
  203. 0x02, 0x00, 0x00, 0x12, 0x34, 0x56
  204. }));
  205. #endif
  206. /* start Ethernet driver state machine */
  207. ESP_ERROR_CHECK(esp_eth_start(eth_handle));
  208. /* Register Ethernet interface to could be used by sniffer */
  209. ESP_ERROR_CHECK(sniffer_reg_eth_intf(eth_handle));
  210. }
  211. #endif // CONFIG_SNIFFER_NO_ETHERNET
  212. #if CONFIG_SNIFFER_PCAP_DESTINATION_SD
  213. static struct {
  214. struct arg_str *device;
  215. struct arg_end *end;
  216. } mount_args;
  217. /** 'mount' command */
  218. static int mount(int argc, char **argv)
  219. {
  220. esp_err_t ret;
  221. int nerrors = arg_parse(argc, argv, (void **)&mount_args);
  222. if (nerrors != 0) {
  223. arg_print_errors(stderr, mount_args.end, argv[0]);
  224. return 1;
  225. }
  226. /* mount sd card */
  227. if (!strncmp(mount_args.device->sval[0], "sd", 2)) {
  228. ESP_LOGI(TAG, "Initializing SD card");
  229. esp_vfs_fat_sdmmc_mount_config_t mount_config = {
  230. .format_if_mount_failed = true,
  231. .max_files = 4,
  232. .allocation_unit_size = 16 * 1024
  233. };
  234. // initialize SD card and mount FAT filesystem.
  235. sdmmc_card_t *card;
  236. #if CONFIG_SNIFFER_SD_SPI_MODE
  237. ESP_LOGI(TAG, "Using SPI peripheral");
  238. sdmmc_host_t host = SDSPI_HOST_DEFAULT();
  239. spi_bus_config_t bus_cfg = {
  240. .mosi_io_num = PIN_NUM_MOSI,
  241. .miso_io_num = PIN_NUM_MISO,
  242. .sclk_io_num = PIN_NUM_CLK,
  243. .quadwp_io_num = -1,
  244. .quadhd_io_num = -1,
  245. .max_transfer_sz = 4000,
  246. };
  247. ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CH_AUTO);
  248. if (ret != ESP_OK) {
  249. ESP_LOGE(TAG, "Failed to initialize bus.");
  250. return 1;
  251. }
  252. // This initializes the slot without card detect (CD) and write protect (WP) signals.
  253. // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
  254. sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
  255. slot_config.gpio_cs = PIN_NUM_CS;
  256. slot_config.host_id = host.slot;
  257. ret = esp_vfs_fat_sdspi_mount(CONFIG_SNIFFER_MOUNT_POINT, &host, &slot_config, &mount_config, &card);
  258. #else
  259. ESP_LOGI(TAG, "Using SDMMC peripheral");
  260. sdmmc_host_t host = SDMMC_HOST_DEFAULT();
  261. sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
  262. gpio_set_pull_mode(15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1-line modes
  263. gpio_set_pull_mode(2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
  264. gpio_set_pull_mode(4, GPIO_PULLUP_ONLY); // D1, needed in 4-line mode only
  265. gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only
  266. gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes
  267. ret = esp_vfs_fat_sdmmc_mount(CONFIG_SNIFFER_MOUNT_POINT, &host, &slot_config, &mount_config, &card);
  268. #endif
  269. if (ret != ESP_OK) {
  270. if (ret == ESP_FAIL) {
  271. ESP_LOGE(TAG, "Failed to mount filesystem. "
  272. "If you want the card to be formatted, set format_if_mount_failed = true.");
  273. } else {
  274. ESP_LOGE(TAG, "Failed to initialize the card (%s). "
  275. "Make sure SD card lines have pull-up resistors in place.",
  276. esp_err_to_name(ret));
  277. }
  278. return 1;
  279. }
  280. /* print card info if mount successfully */
  281. sdmmc_card_print_info(stdout, card);
  282. }
  283. return 0;
  284. }
  285. static void register_mount(void)
  286. {
  287. mount_args.device = arg_str1(NULL, NULL, "<sd>", "choose a proper device to mount/unmount");
  288. mount_args.end = arg_end(1);
  289. const esp_console_cmd_t cmd = {
  290. .command = "mount",
  291. .help = "mount the filesystem",
  292. .hint = NULL,
  293. .func = &mount,
  294. .argtable = &mount_args
  295. };
  296. ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
  297. }
  298. static int unmount(int argc, char **argv)
  299. {
  300. int nerrors = arg_parse(argc, argv, (void **)&mount_args);
  301. if (nerrors != 0) {
  302. arg_print_errors(stderr, mount_args.end, argv[0]);
  303. return 1;
  304. }
  305. /* unmount sd card */
  306. if (!strncmp(mount_args.device->sval[0], "sd", 2)) {
  307. if (esp_vfs_fat_sdmmc_unmount() != ESP_OK) {
  308. ESP_LOGE(TAG, "Card unmount failed");
  309. return -1;
  310. }
  311. ESP_LOGI(TAG, "Card unmounted");
  312. }
  313. return 0;
  314. }
  315. static void register_unmount(void)
  316. {
  317. mount_args.device = arg_str1(NULL, NULL, "<sd>", "choose a proper device to mount/unmount");
  318. mount_args.end = arg_end(1);
  319. const esp_console_cmd_t cmd = {
  320. .command = "unmount",
  321. .help = "unmount the filesystem",
  322. .hint = NULL,
  323. .func = &unmount,
  324. .argtable = &mount_args
  325. };
  326. ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
  327. }
  328. #endif // CONFIG_SNIFFER_PCAP_DESTINATION_SD
  329. void app_main(void)
  330. {
  331. initialize_nvs();
  332. /*--- Initialize Network ---*/
  333. ESP_ERROR_CHECK(esp_event_loop_create_default());
  334. /* Initialize WiFi */
  335. initialize_wifi();
  336. #ifndef CONFIG_SNIFFER_NO_ETHERNET
  337. /* Initialize Ethernet */
  338. initialize_eth();
  339. #endif
  340. /*--- Initialize Console ---*/
  341. esp_console_repl_t *repl = NULL;
  342. esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
  343. #if CONFIG_SNIFFER_STORE_HISTORY
  344. initialize_filesystem();
  345. repl_config.history_save_path = HISTORY_FILE_PATH;
  346. #endif
  347. repl_config.prompt = "sniffer>";
  348. // install console REPL environment
  349. #if CONFIG_ESP_CONSOLE_UART
  350. esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
  351. ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
  352. #elif CONFIG_ESP_CONSOLE_USB_CDC
  353. esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
  354. ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl));
  355. #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
  356. esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
  357. ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
  358. #endif
  359. /* Register commands */
  360. #if CONFIG_SNIFFER_PCAP_DESTINATION_SD
  361. register_mount();
  362. register_unmount();
  363. #endif
  364. register_sniffer_cmd();
  365. register_pcap_cmd();
  366. #if CONFIG_SNIFFER_PCAP_DESTINATION_SD
  367. printf("\n =======================================================\n");
  368. printf(" | Steps to sniff network packets |\n");
  369. printf(" | |\n");
  370. printf(" | 1. Enter 'help' to check all commands usage |\n");
  371. printf(" | 2. Enter 'mount <device>' to mount filesystem |\n");
  372. printf(" | 3. Enter 'pcap' to create pcap file |\n");
  373. printf(" | 4. Enter 'sniffer' to start capture packets |\n");
  374. printf(" | 5. Enter 'unmount <device>' to unmount filesystem |\n");
  375. printf(" | |\n");
  376. printf(" =======================================================\n\n");
  377. #else
  378. printf("\n =======================================================\n");
  379. printf(" | Steps to sniff network packets |\n");
  380. printf(" | |\n");
  381. printf(" | 1. Enter 'help' to check all commands' usage |\n");
  382. printf(" | 2. Enter 'pcap' to create pcap file |\n");
  383. printf(" | 3. Enter 'sniffer' to start capture packets |\n");
  384. printf(" | |\n");
  385. printf(" =======================================================\n\n");
  386. #endif
  387. // start console REPL
  388. ESP_ERROR_CHECK(esp_console_start_repl(repl));
  389. }