-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Example of promiscuous mode #4
Comments
In the README I added an update explaining that the code does not enter true promiscuous mode (as with wifi_enable_promiscuous(1)), because I was unable to catch frames with MAC addresses not matching the devices' own address, or the broadcast address. I didn't make further research to find if that is possible without further reverse engineering efforts. What it can do, is capture packets addressed to the device or broadcast. At the time when I wrote this, if I remember correctly, there was a limitation in the official sniffer API that allowed only less than 112 bytes to be sniffed. But I was able to get the full packet by tapping into more low-level functions and parsing the headers. For example code, you can look in user_main.c, in the init_done() function. There is this function call: wifi_raw_set_recv_cb(my_recv_cb); The wifi_raw_set_recv_cb just sets the rx_func callback (in wifi_raw.c) to point to the my_recv_cb function. The prototype for this callback is void ICACHE_FLASH_ATTR my_recv_cb(struct RxPacket *pkt). The struct RxPacket (defined in wifi_raw.h) contains the information on packet, as well as the data. The length is stored in the rx_ctl.legacy_length field. The current example my_recv_cb just prints the full packet in hex and ascii format (like in the xxd dump format). I haven't been able to test this further anymore because I don't have access to esp8266 device. |
Just a quick follow-up question: what sdk version does this use? |
I don't remember on the top of my head, I'll get back to you later today when I get the chance to check. I really should have written this in the README, but apparently I forgot... sorry about that :S |
I haven't been able to get it to receive anything. How does |
The original libraries have a ppEnqueueRxq symbol which is the one I was hooking into. The initial way I implemented the hooking was to create a copy of the libpp library (called libpp2.a). I explain this in the NOTES section of the README. The libpp2 has the symbol for ppEnqueueRxq replaced by symbol aaEnqueueRxq (a copy of this patched library is provided in the lib/ folder). @tgoddard proposed a better way to hook into ppEnqueueRxq by using a linker option LD_FLAGS = ... -Wl,-wrap=ppEnqueueRxq. See this issue: #1 If you use the patched library, you have to also link against it instead of the original library. I have a Makefile2 that does this, so you can use make -f Makefile2 instead of make -f Makefile. If you want to try tgoddard's method instead, you can use the original Makefile, but with appending to LDFLAGS that -Wl,-wrap=ppEnqueueRxq flag (and change the wifi_raw.c function aaEnqueueRxq to be called __wrap_ppEnqueueRxq. |
I modified the libraries with the commands in the README and used the modified Makefile. When that failed, I tried to copy the included libraries, but that failed (I think it might be because of a version mismatch). Will definitely try out the mentioned alternative and maybe open a PR if it works. |
By curiosity, what kind of failure was it? Segfault? Or just the callback not getting called? But yeah, I would not be surprised if using different libraries than the version I have causes problems, because they might have changed the way binaries interface between each other, or changed the internal packet processing structures. |
I finally got the receiving part working! 😄 Will submit a PR later on, but in short: I switched from modifying the libraries to adding a wrapper function as @tgoddard described. This is way cleaner, since we now don't have to worry about library versions (for others reading this, I am using v0.9.3). I'll have to check out the sending possibilities later, but I don't think it's much different from (BTW, the failure was basically that it wouldn't let me compile) |
I am glad this worked out, and thankful for your efforts in actually trying this out. |
By the way, I suspect the compilation error you had was due to a missing reference to ppEnqueueRxq (which would be the case if you have overwritten all references to aaEnqueueRxq in libpp.a). But one of them must be kept to ppEnqueueRxq because it exports the real ppEnqueueRxq symbol that I call from the wrapper in wifi_raw.c. The other two symbols were, I think, some kinds of indirect GOT entries or something of that sort, and were those I had to overwrite to point to the aaEnqueueRxq. But yeah, that thing was really kludgy and tgoddard's solution is much easier to implement, and probably much more portable. Also another note, I earlier said that the length is in the rx_ctl.legacy_length field. I think this actually depends on the packet type. I read the official sniffer API docs where they describe the sniffer_buf and RxControl structs, and there is also the HT_length field which is used instead for some other kinds of packets. I don't know what was the distinction anymore though. |
By the way, just so you know, the version of the SDK I was using is esp_iot_sdk_v1.2.0. |
I just tested my latest version (see #5) against v1.3.0. I am able to receive, and I wonder how |
Also, is it currently possible to send shorter packets (no full 802.11 header)? |
When you refer to But no even with the |
Yes, I meant |
Hi, it seems that there is no example code of the ESP8266 in promiscuous mode, so I have a few questions:
The text was updated successfully, but these errors were encountered: