user1226868
user1226868

Reputation: 1758

Socket won't bind: no such device

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

Upvotes: 17

Views: 15188

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 148965

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.

Upvotes: 2

Figus
Figus

Reputation: 681

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.

Upvotes: 6

jdog_siis
jdog_siis

Reputation: 1

this is a client that can send a handcrafted message. the variables ip and port are the port and ip address of your server the values in the below program are examples

import socket
ip = "127.0.0.1"
port = 447
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
msg = ("hello ex. message")
s.send(msg.encode('ascii'))
rep = s.recv(1024)
rep1 = (rep.decode('ascii'))
print rep1

and the server is

import socket
ip = "127.0.0.1"
port = 447
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((ip, port))
s.listen(15)
con, addr = s.accept()
msg = con.recv(1024)
msg1 = (msg.decode('ascii'))
print (msg1)
rep = ("got message")
con.send(rep.encode('ascii'))

I hope this answer helps and this is what your looking for.

Upvotes: -3

Related Questions