1# Simple Sniffer Example
2
3(See the README.md file in the upper level 'examples' directory for more information about examples.)
4
5## Overview
6
7This example demonstrates basic usage of WiFi and Ethernet sniffer mode by saving packets into SD card with pcap format. There is also an option to send pcap file to host via JTAG interface.
8
9For more information about pcap, please go to [wikipedia](https://en.wikipedia.org/wiki/Pcap).
10
11This example is based on console component. For more information about console, please refer to [console guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/console.html).
12
13## How to use example
14
15### Hardware Required
16
17To run this example with WiFi interface, you should have one ESP32 dev board integrated with a SD card slot (e.g. [ESP-WROVER-KIT](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp-wrover-kit-v4-1)) or just connect [ESP32-DevKitC](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp32-devkitc-v4) to a SD card breakout board. To run this example with Ethernet interface option, you should have one ESP32 dev board with physical layer Ethernet support (e.g. [ESP32-Ethernet-Kit](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-ethernet-kit.html#)) or connect SPI-Ethernet module (e.g. DM9051) to your dev board.
18If you want to send packets to host, make sure to connect ESP32 to some kind of [JTAG adapter](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#jtag-debugging-selecting-jtag-adapter).
19
20#### Ethernet Pin Assignment
21
22See common pin assignments for Ethernet from [ethernet examples folder](../../ethernet/README.md#common-pin-assignments).
23
24### Configure the project
25
26Open the project configuration menu (`idf.py menuconfig`). Then go into `Example Configuration` menu.
27
28- Check `Store command history in flash` if you want to save command history into flash (recommend).
29- Select where to save the pcap file in `Select destination to store pcap file` menu item.
30  - `SD Card` means saving packets (pcap format) into the SD card you plug in. The default SD card work mode is set to SDMMC for target ESP32 and ESP32S3, but SPI is the only choice for other targets.
31  - `Memory` means saving packets in memory and can parse packets in place.
32  - `JTAG (App Trace)` means sending packets (pcap format) to host via JTAG interface. This feature depends on [app trace component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html), Component config -> Application Level Tracing -> Data Destination -> JTAG should be enabled to choose `JTAG (App Trace)` as destination.
33- Set the mount point in your filesystem in `SD card mount point in the filesystem` menu item. This configuration only takes effect when you choose to save packets into SD card.
34- Set max name length of pcap file in `Max name length of pcap file` menu item.
35- Set the length of sniffer work queue in `Length of sniffer work queue` menu item.
36- Set the stack size of the sniffer task in `Stack size of sniffer task` menu item.
37- Set the priority of the sniffer task in `Length of sniffer work queue` menu item.
38- Select Ethernet Type
39  - `No Ethernet` means your board does not have Ethernet.
40  - `Internal EMAC` means ESP32 EMAC is used in conjunction with with selected PHY.
41  - `DM9051 Module`, `W5500 Module` or `KSZ8851SNL Module` means that SPI-Ethernet module is used with its own EMAC and PHY.
42  - For more information related to Ethernet configurations see common configuration of Ethernet from [ethernet examples folder](../../ethernet/README.md#common-configurations).
43
44### Build and Flash
45
46```
47idf.py -p PORT flash monitor
48```
49
50(Replace PORT with name of the serial port.)
51
52(To exit the serial monitor, type ``Ctrl-]``.)
53
54See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
55
56### `sniffer` Command Usage
57
58> sniffer  [-i <wlan|eth0|eth1|...>] [-F <mgmt|data|ctrl|misc|mpdu|ampdu|fcsfail>]... [-c <channel>] [--stop] [-n <num>]
59>   Capture specific packet and store in pcap format
60>   -i, --interface=<wlan|eth0|eth1|...>  which interface to capture packet
61>   -F, --filter=<mgmt|data|ctrl|misc|mpdu|ampdu|fcsfail>  filter parameters
62>   -c, --channel=<channel>  communication channel to use
63>         --stop  stop running sniffer
64>   -n, --number=<num>  the number of the packets to be captured
65
66The `sniffer` command support some important options as follow:
67
68* `-i`: Specify the interface to sniff packets, currently only support `wlan` and `eth0`
69* `-c`: Specify the channel to sniff packet at `wlan` interface
70* `-F`: Specify the filter condition at `wlan` interface, currently only support following filter conditions, you can select any number of them
71  * mgmt: Management packets
72  * data: Data packets
73  * ctrl: Control packets
74  * misc: Other packets
75  * mpdu: MPDU packets
76  * ampdu: AMPDU packets
77* `-n`: Specify the number of packages to capture in this sniffer job. The sniffer job will stop automatically without using `sniffer --stop` command.
78* `--stop`: Stop sniffer job
79
80### `pcap` Command Usage When the Destination is `SD Card`
81
82> pcap  -f <file> [--open] [--close] [--summary]
83>   Save and parse pcap file
84>   -f, --file=<file>  name of the file storing the packets in pcap format
85>         --open  open .pcap file
86>        --close  close .pcap file
87>      --summary  option to parse and show the summary of .pcap file
88
89The `pcap` command support some important options as follow:
90
91* `-f`: Specify the name of file which will store the packets or show summary, default value is `sniffer`, and the resulting file name will be like “snifferX.pcap”, here ‘X’ shows the file’s order.
92* `--open`: Option to open a '.pcap' file
93* `--close`: Option to close the '.pcap' file
94* `--summary`: Show the summary of '.pcap' file
95
96### `pcap` Command Usage When the Destination is `Memory`
97
98> pcap  -f <file> [--open] [--close] [--summary]
99>   Save and parse pcap file
100>   -f, --file=<file>  name of the file storing the packets in pcap format
101>         --open  open .pcap file
102>        --close  close .pcap file
103>      --summary  option to parse and show the summary of .pcap file
104
105The `pcap` command support some important options as follow:
106
107* `-f`: Specify the file name to storage packet or show summary
108* `--open`: Option to open a '.pcap' file
109* `--close`: Option to close the '.pcap' file
110* `--summary`: Show the summary of '.pcap' file (needs to be called prior file closing)
111
112### `pcap` Command Usage When the Destination is `JTAG`
113pcap command is not used when destination is JTAG. The pcap session is started automatically with the Sniffer start.
114
115## Example Output
116### Steps for using **SD Card** to storage packages and watch summary
117#### Mount SD Card
118
119```bash
120 =======================================================
121 |         Steps to sniff network packets              |
122 |                                                     |
123 |  1. Enter 'help' to check all commands usage        |
124 |  2. Enter 'mount <device>' to mount filesystem      |
125 |  3. Enter 'pcap' to create pcap file                |
126 |  4. Enter 'sniffer' to start capture packets        |
127 |  5. Enter 'unmount <device>' to unmount filesystem  |
128 |                                                     |
129 =======================================================
130
131
132Type 'help' to get the list of commands.
133Use UP/DOWN arrows to navigate through command history.
134Press TAB when typing command name to auto-complete.
135sniffer> mount sd
136I (12653) example: Initializing SD card
137I (12653) example: Using SDMMC peripheral
138I (12663) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
139Name: SC64G
140Type: SDHC/SDXC
141Speed: 20 MHz
142Size: 60906MB
143```
144
145#### Create .pcap file
146
147```bash
148sniffer> pcap --open -f simple-sniffer
149I (41383) cmd_pcap: open file successfully
150```
151
152#### Start Sniffer (with 10 packages)
153
154```bash
155sniffer> sniffer -i wlan -c 2 -n 10
156I (58153) cmd_sniffer: 10 packages will be captured
157I (58163) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
158I (58263) wifi:ic_enable_sniffer
159I (58263) cmd_sniffer: start WiFi promiscuous ok
160I (58303) wifi:ic_disable_sniffer
161I (58303) wifi:flush txq
162I (58303) wifi:stop sw txq
163I (58303) wifi:lmac stop hw txq
164I (58303) cmd_sniffer: stop promiscuous ok
165```
166
167#### Close .pcap file
168
169```bash
170sniffer> pcap --close -f simple-sniffer
171I (80453) cmd_pcap: .pcap file close done
172```
173
174#### Parse '.pcap' file and watch at bash with '--summary' option
175
176```bash
177sniffer> pcap --summary -f simple-sniffer
178I (112833) cmd_pcap: /sdcard/simple-sniffer.pcap is to be parsed
179------------------------------------------------------------------------
180Pcap packet Head:
181------------------------------------------------------------------------
182Magic Number: a1b2c3d4
183Major Version: 2
184Minor Version: 4
185SnapLen: 262144
186LinkType: 105
187------------------------------------------------------------------------
188Packet 0:
189Timestamp (Seconds): 0
190Timestamp (Microseconds): 3670
191Capture Length: 303
192Packet Length: 303
193Packet Type:  0
194Packet Subtype:  5
195Destination:  0  0  0  0 a1  0
196Source:  2 84 56  e  0  0
197------------------------------------------------------------------------
198Packet 1:
199Timestamp (Seconds): 0
200Timestamp (Microseconds): 3670
201Capture Length: 294
202Packet Length: 294
203Packet Type:  0
204Packet Subtype:  5
205Destination:  0  0  0  0 a1  0
206Source:  2 84 56  e  0  0
207------------------------------------------------------------------------
208Packet 2:
209
210...
211
212------------------------------------------------------------------------
213Pcap packet Number: 10
214------------------------------------------------------------------------
215```
216
217#### Unmount SD Card
218
219```bash
220sniffer> unmount sd
221I (183873) example: Card unmounted
222```
223
224### Steps for using **memory** to storage packages and watch summary
225#### Open a memory for pcap
226
227```bash
228sniffer> pcap --open -f simple-sniffer
229I (11816) cmd_pcap: open file successfully
230```
231
232#### Sniff 10 packages
233
234```bash
235sniffer> sniffer -i wlan -c 2 -n 10
236I (71086) cmd_sniffer: 10 packages will be captured
237I (71096) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
238I (71186) wifi:ic_enable_sniffer
239I (71186) cmd_sniffer: start WiFi promiscuous ok
240I (71246) wifi:ic_disable_sniffer
241I (71246) wifi:flush txq
242I (71256) wifi:stop sw txq
243I (71256) wifi:lmac stop hw txq
244I (71256) cmd_sniffer: stop promiscuous ok
245```
246
247#### Watch the summary of the package captured above
248
249```bash
250sniffer> pcap --summary -f simple-sniffer
251I (93396) cmd_pcap: Memory is to be parsed
252------------------------------------------------------------------------
253Pcap packet Head:
254------------------------------------------------------------------------
255Magic Number: a1b2c3d4
256Major Version: 2
257Minor Version: 4
258SnapLen: 262144
259LinkType: 105
260------------------------------------------------------------------------
261Packet 0:
262Timestamp (Seconds): 0
263Timestamp (Microseconds): 5481
264Capture Length: 266
265Packet Length: 266
266Packet Type:  0
267Packet Subtype:  2
268Destination:  0  0  0  0 a1  0
269Source:  2 8a 69 15  0  0
270------------------------------------------------------------------------
271Packet 1:
272Timestamp (Seconds): 0
273Timestamp (Microseconds): 24405
274Capture Length: 175
275Packet Length: 175
276Packet Type:  0
277Packet Subtype:  f
278Destination:  0  0  0  0 a1  0
279Source:  2 84 55 5f  0  0
280------------------------------------------------------------------------
281Packet 2:
282
283...
284
285------------------------------------------------------------------------
286Pcap packet Number: 10
287------------------------------------------------------------------------
288```
289
290
291#### Close pcap file in memory
292
293```bash
294sniffer> pcap --close -f simple-sniffer
295I (130566) cmd_pcap: free memory successfully
296I (130566) cmd_pcap: .pcap file close done
297```
298
299### Steps for sending packets to host via **JTAG interface**
300
3011. Select `JTAG (App Trace)` as the destination of pcap files in project configuration.
3022. Build & Flash with `idf.py -p PORT flash`
3033. Connect JTAG, run OpenOCD (for more information about how-to please refer to [JTAG Debugging](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html)).
3044. Telnet to localhost with 4444 port: `telnet localhost 4444`.
3055. In the telnet session, run command like `esp32 apptrace start file://sniffer-esp32.pcap 1 -1 20` (more information about this command, please refer to [apptrace command](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#openocd-application-level-tracing-commands)).
3066. Run the example, start sniffer with `sniffer` command.
3077. Stop sniffer by entering command `sniffer --stop` in the example console.
3088. Stop tracing by entering command `esp32 apptrace stop` in the telnet session.
309
310### Open PCap File in Wireshark
311
312![sniffer-example0.pcap](sniffer-esp32-pcap.png)
313
314## Troubleshooting
315
316- Make sure you have pluged in your SD card and mount it into filesystem before doing sniffer work or you will get error message like “Create file /sdcard/sniffer0.pcap failed”.
317- To protect the SD card, we recommand you to execute command `unmount sd` before you plug out your SD card.
318- Make sure to run `esp32 apptrace` command before or immediately after a new sniffer task started when you try this example with JTAG. Otherwise the console will issue warning message `waiting for apptrace established` every 1 second. If the apptrace communication doesn't be established within 10 seconds (can be altered by macro `SNIFFER_APPTRACE_RETRY`), this sniffer command will failed with an error message `waiting for apptrace established timeout`.
319
320(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)
321