Open Raw Socket Micropython For 802.11 Packets - python

I am working with an ESP8266 (NodeMCU) with MicroPython and want to be able to do packet injection or send raw packets / freedom packets. I cannot find anyway to open a raw socket (usocket/socket module) or do this via the 'network' module. Is there anyway I can do this?
The normal python equivalent would be:
import socket
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))
s.bind(("wlan0", 0x0003)) #wlan0 being in monitor mode
In micropython, you can enter monitor mode (station mode) like this
import network
sta_if = network.WLAN(network.STA_IF)
But from there, you cannot send/receive any packets. Is there any way to be able to do this?
Any help is much appreciated.
Sorry for the lack of detail but I have no idea what to do from here.

I don't think you can achieve raw socket by using micropython#esp8266
One reason is the memory are very limited on esp8266. Another reason is their socket doesn't implement raw socket.
You could try to use CC3200 ports and modify it's micropython's firmware.

Related

How can I listen for raw ethernet frames in vanilla Python 3?

I'm doing some self-educational low-level network programming in Python. I'm using Ubuntu 18.04 and Python 3. Using this code, I'm able to send raw ethernet packets:
from socket import socket as Socket, AF_PACKET, SOCK_RAW
def send_bytes(byte_sequence):
with Socket(AF_PACKET, SOCK_RAW) as socket:
socket.bind(("enp0s31f6", 0))
socket.send(bytes(byte_sequence))
I can use this procedure to send pings. I know it's working because I can see the ping going out and receiving a response in Wireshark.
Now I want to listen for packets, like the response to my ping. How can I do this, hopefully without involving any non-standardlib libraries? I'd like the code to be as "close to the metal" as possible, so ideally I'd like to listen for the entire ethernet frame so I can parse it all by hand and figure out if it's the packet I'm looking for.
This works for me
import sys
import socket
ETH_P_ALL=3 # not defined in socket module, sadly...
s=socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
s.bind(("eth0", 0))
r=s.recv(2000)
sys.stdout.write("<%s>\n"%repr(r))
The third argument when creating the socket acts as a filter on the type of incoming frames we want to capture (all of them here).
The ETH_P_ALL constant comes from /usr/include/linux/if_ether.h.

Send CTS frames in Python

I was wondering if it was possible to send CTS frames in python3 with modules such as scapy. If not, how would I do it with the sockets module?
Thanks in advance.
I can't say for scapy, but CTS frames and 802.11 in general seems to be too deep for the python socket module.
This is OSI Level 2, while socket have limited capabilities below OSI Level 3.
Some possible starting points are:
People already tried to work with 802.11 via sockets.
You may try to modify this code for Ethernet communication. Note the socket creation: socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) - AF_PACKET instead of AF_INET allows Level 2 operations.
Try to use socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))). ETH_P_ALL means the socket will be receiving all Level 2 packets. All because actually I haven't find any 802.11-specific sources in the Linux kernel.
Get an open source driver for your Wireless NIC and see how they do it. It may appear that communicating directly with the hardware will be more fruitful than trying to find a general mechanism embedded in sockets.
A related email thread: Correct way to obtain the 802.11 headers with a raw socket?

Python indifference to serial / Ethernet

I'm trying to communicate with a device that uses the same protocol whether you're talking to it over a TCP socket or a serial port. Either way, it's an ASCII command-based interface, in which you type your command at a prompt, followed by a newline, you get a response with a newline, and then a new prompt.
> IDENTIFY
DEVICE_TYPE_RESPONSE
> TEST POWER
OK
>
The program can and should block until it gets the new prompt, but there needs to be a timeout so you don't wait forever in case of sudden device death. That timeout should be seconds so as not to falsely flag on a network glitch, but shouldn't force me to wait seconds once I've gotten my prompt character.
I'd love some way to abstract the interface so as to not care about what the underlying communications layer is. Just pass it either an open socket or an open serial port and let everything happen. Is there some good way to do this? Preferably capable of running under Python 2.6.
You could implement the protocol in Twisted which allows you to use TCP or the serial port as a transport without changing your protocol implementation. Twisted also allows you to set timeouts/delayed callbacks.
Python's serial package provides a lot of useful stuff including some serial over TCP/IP bridges. If you want to talk to it using ASCII/Telnet then you probably want the to use the '--convert' option with the Simple Serial to Network (TCP/IP) redirector.
Also you might want to take a look at this other related question on Converting serial port data to TCP/IP in a linux environment

Outgoing UDP sniffer in python?

I want to figure out whether my computer is somehow causing a UDP flood that is originating from my network. So that's my underlying problem, and what follows is simply my non-network-person attempt to hypothesize a solution using python. I'm extrapolating from recipe 13.1 ("Passing Messages with Socket Datagrams") from the python cookbook (also here).
Would it possible/sensible/not insane to try somehow writing an outgoing UDP proxy in python, so that outgoing packets could be logged before being sent on their merry way? If so, how would one go about it? Based on my quick research, perhaps I could start a server process listening on suspect UDP ports and log anything that gets sent, then forward it on, such as:
import socket
s =socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", MYPORT))
while True:
packet = dict(zip('data', 'addr'), s.recvfrom(1,024))
log.info("Recieved {data} from {addr}.".format(**packet))
But what about doing this for a large number of ports simultaneously? Impractical? Are there drawbacks or other reasons not to bother with this? Is there a better way to solve this problem (please be gentle).
It might be easier just to install Wireshark, instead of rolling your own in Python.

UDP packages appear in wireshark, but are not received by program

I am trying to read UDP packages sent by an FPGA with my computer. They are sent
to port 21844 and to the IP 192.168.1.2 (which is my computer's IP). I can see the package in wireshark, they have no errors. When I run however this little python script, then only a very very small fraction of all packages are received by it, also depending if wireshark is running or not.
import socket
import sys
HOST, PORT = "192.168.1.2", 21844
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((HOST,PORT))
received ,address= sock.recvfrom(2048)
print address
I use windows 7 with Norton Internet Security, where I allow all traffic in the firewall for the FPGA IP and also for python. The same program on a Windows XP computer does not receive anything either...
Thanks for any help!
The TCP/IP stack of your OS doesn't hold those packets for you for eternity. Your script looks like something that very much depends on when it is run. Try to recvfrom in a loop, and run the script in the background. Then, start sending packets from your FPGA.
For extra convenience, explore the SocketServer module from Python's stdlib.
Ok, I found the problem: The UDP checksum in the FPGA was computed wrongly. Wireshark shows every package, but by default it does not check if the checksum is correct. When I set the checksum to 0x0000, then the packages arrive in python! Thanks for your help again!

Categories

Resources