Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket won't bind: no such device

Tags:

python

sockets

So I have this piece of Python 3 code:

import socket
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
s.bind(('eth0', 0))
s.send(eth_packet)

This code works on my Raspberry Pi, but not on my external server. When I try to run it on my external server i get:

# sudo python3 test.py
s.send(eth_packet)
socket.error: [Errno 19] No such device

And I checked the network interfaces output (via an python script): External server (debian):

['lo [index=1, IPv4=127.0.0.1, IPv6=::1]', 'eth0:0 [index=2, IPv4=xxxxx, IPv6=None]', 'eth0 [index=2, IPv4=yyyyyy, IPv6=zzzzzzz]']

Raspberry pi:

['lo [index=1, IPv4=127.0.0.1, IPv6=None]', 'eth0 [index=2, IPv4=rrrrr, IPv6=None]']

Can someone explain what is going on? I just want to send a handcrafted message but this error keeps bugging me, can this be a problem with the drivers of my server? This is the same result as ifconfig.

Edit

Ok, i used strace for this example:

#!/usr/bin/env python3

import socket
import binascii
import struct

test= '000a959d6816'
packet= struct.pack("!6s", binascii.unhexlify(bytes(test, 'UTF-8')))
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
s.bind(('eth0', 0))
s.send(packet)

And this is the important part about strace:

socket(PF_PACKET, SOCK_RAW, 0)          = 3
ioctl(3, SIOCGIFINDEX, {ifr_name="eth0", ifr_index=2}) = 0
bind(3, {sa_family=AF_PACKET, proto=0000, if2, pkttype=PACKET_HOST, addr(0)={0, }, 20) = 0
sendto(3, "\0\n\225\235h\26", 6, 0, NULL, 0) = -1 ENXIO (No such device or address)
open("test.py", O_RDONLY)               = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=247, ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff86c5f090) = -1 ENOTTY (Inappropriate ioctl for device)
fstat(4, {st_mode=S_IFREG|0644, st_size=247, ...}) = 0
lseek(4, 0, SEEK_CUR)                   = 0
dup(4)                                  = 5
fcntl(5, F_GETFL)                       = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fstat(5, {st_mode=S_IFREG|0644, st_size=247, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc1251c2000
lseek(5, 0, SEEK_CUR)                   = 0
read(5, "#!/usr/bin/env python3\n\nimport s"..., 4096) = 247
close(5)                                = 0
munmap(0x7fc1251c2000, 4096)            = 0
lseek(4, 0, SEEK_SET)                   = 0
lseek(4, 0, SEEK_CUR)                   = 0
read(4, "#!/usr/bin/env python3\n\nimport s"..., 4096) = 247
close(4)                                = 0
write(2, "Traceback (most recent call last"..., 143Traceback (most recent call last):
  File "test.py", line 11, in <module>
    s.send(packet)
socket.error: [Errno 6] No such device or address
) = 143
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7fc1264050a0}, {0x428787, [], SA_RESTORER, 0x7fc1264050a0}, 8) = 0
close(3)                                = 0
like image 793
user1226868 Avatar asked Dec 30 '14 22:12

user1226868


People also ask

Can not bind to socket?

Introduction. An HAProxy cannot bind socket error message is generated when there is another process listening on the same interface and TCP port combination that HAProxy is configured to use, or when HAProxy attempts to use an IP address that is not assigned to a network interface.

Why does socket bind fail?

If you're seeing a "TCP/UDP: Socket bind failed on local address" error message in the OpenVPN log, it means your VPN connection is configured to bind to a fixed local address and/or port number, and that this address/port number is unavailable.

What does socket binding mean?

Socket binding is process of binding a socket to a network address within the system. When a socket is bound the server can accept client connections.


2 Answers

When you bind a RAW socket with family PACKET on an interface, you need a tuple with 2 objects:

(interfaceName, protoNumber)

or 5 objects:

(interfaceName, protoNumber, pkttype, hatype, haddr)

You specify 0 in protoNumber but maybe protoNumber 0 doesn't exist in your system.

Documentation about packet family: packet(7)

sll_protocol is the standard ethernet protocol type in network byte order as defined in the include file.

Try to find the right protocol number in linux/if_ether.h.

like image 194
Figus Avatar answered Nov 14 '22 02:11

Figus


Assuming your external server runs under Linux, there are some reasons not to be able to run your program.

As already noted by Figus, you actually use protocol number 0, which may not be defined. You could be more lucky with :

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, proto)

where proto is the protocol number corresponding to ETH_P_ALL in linux/if_ether.h (3 on some Linux boxes)

But man packet also says : Only processes with effective UID 0 or the CAP_NET_RAW capability may open packet sockets. So it means you must have root privileges on your external server to run your code.

like image 44
Serge Ballesta Avatar answered Nov 14 '22 01:11

Serge Ballesta