I would like to send an IOCTL call from a Python application to a fake network interface I have running in Ubuntu 12.04. I know that I can open a socket and bind it to the network that the fake network interface is governing, and then use fcntl.ioctl(socket, IOC_COMMAND_NUM, some_struct)
to send an IOCTL call. But, this seems to use a different network interface than I need it to. So, my question is, how can I ensure that a specific network interface is used? And, it seems like a lot of trouble to open a socket just to send an IOCTL call, so is there anyway to bypass that step? Below is some sample Python code that behaves as mentioned above.
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.bind(("192.168.0.1",0))
>>> fcntl.ioctl(sock,IOC_COMMAND_NUM,some_struct)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 25] Inappropriate ioctl for device
# This proves that it is sending the IOCTL to a different interface because my
# interface automatically returns success for any IOCTL call.
Below is the output of ifconfig myDummyNetInter
.
myDummyNetInter0 Link encap:Ethernet HWaddr e2:44:46:d5:79:3e
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::e044:46ff:fed5:793e/64 Scope:Link
UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:24 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:2682 (2.6 KB)
If it helps, I do have another application written in C++ using this network interface without any problems. (Including IOCTL calls.)
Thanks, I appreciate any and all help.
While this doesn't necessarily answer all of my questions, I was able to find a solution. The IOCTL call is a bit different than I had expected. The first thing I needed to fix was using the correct IOCTL number. Unlike character drivers, network drivers can only use a certain range (starting at 0x89F0) for custom IOCTLs. The other thing I had to do was to put an ifreq
struct as the third argument of the IOCTL call. The ifreq
struct has an ifr_name
member that is used to select the specific network interface to interact with. These two fixes allowed me to communicate with my driver flawlessly.