2014-12-30 15 views
15

Więc mam ten kawałek kodu Pythona 3:Gniazdo nie zwiąże: Nie ma takiego urządzenia

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

ten kod działa na moim Raspberry Pi, ale nie na moim serwerze zewnętrznym. Gdy próbuję uruchomić go na moim serwerze zewnętrznym uzyskać:

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

I sprawdzone wyjście interfejsów sieciowych (za pomocą skryptu Pythona): serwera zewnętrznego (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]'] 

Czy ktoś może wyjaśnić, co się dzieje? Chcę tylko wysłać wiadomość ręcznie, ale ten błąd nadal mnie niepokoi, czy może to być problem ze sterownikami mojego serwera? Jest to ten sam wynik co ifconfig.

Edit

Ok, użyłem strace na tym przykładzie:

#!/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) 

I to jest ważna część o 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 
+1

Czy 'eth0: 0' lub' lo' działa na komputerze Debiana? – Carpetsmoker

+0

eth0: 0 też nie działa. – user1226868

+5

Nazwa interfejsu przekazana do powiązania (w tym przypadku "eth0") jest sprawdzana przez ioctl() SIOCGIFINDEX. Powinieneś opublikować wyjście strace. Odpowiednie części mojego strace wyglądają tak: 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 – kag

Odpowiedz

-3

jest to klient, który może wysłać ręcznie napisana wiadomość. ip zmienne i port są portu i IP adres serwera wartości w poniższym programie są przykłady

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 

i serwer

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')) 

Mam nadzieję, że ta odpowiedź pomaga i to jest to, co szukam.

+4

Ta odpowiedź nie ma nic wspólnego z powyższym pytaniem, które dotyczy surowych gniazd. – kag

4

Podczas powiązać RAW gniazdo z PACKET rodzinnym na interfejsie, trzeba krotki z 2 obiektów:

(interfaceName, protoNumber) 

lub 5 obiektów:

(interfaceName, protoNumber, pkttype, hatype, haddr) 

jest określenie 0 w protoNumber ale może protoNumber 0 nie istnieje w twoim systemie.

Documentation about packet family: packet(7)

sll_protocol jest typ standardowy protokół sieci Ethernet w bajcie celu, jak określono w pliku włączenia.

Spróbuj znaleźć odpowiedni numer protokołu pod numerem linux/if_ether.h.

1

Zakładając, że twój serwer zewnętrzny działa pod Linuksem, jest kilka powodów, dla których nie możesz uruchomić swojego programu.

Jak już zauważył Figus, w rzeczywistości używasz numeru protokołu 0, który nie może być zdefiniowany.Można mieć więcej szczęścia z:

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

gdzie proto jest numer protokołu odpowiadający ETH_P_ALL w Linux/if_ether.h (3 na niektórych polach Linux)

Ale man packet mówi: Tylko procesy o skutecznym UID 0 lub zdolność CAP_NET_RAW mogą otwierać gniazda pakietów. Oznacza to, że musisz mieć uprawnienia root'a na swoim serwerze zewnętrznym, aby uruchomić swój kod.

Powiązane problemy