2014-12-30 7 views
15

Così ho questo pezzo di Python 3 Codice:socket non si legherà: senza tale dispositivo

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

Questo codice funziona sul mio Raspberry Pi, ma non sul mio server esterno. Quando provo a farlo funzionare sul mio server esterni ottengo:

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

E ho controllato l'uscita interfacce di rete (tramite uno script python): server esterni (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]'] 

Qualcuno può spiegare cosa sta succedendo? Voglio solo inviare un messaggio fatto a mano ma questo errore continua a infastidirmi, può essere un problema con i driver del mio server? Questo è lo stesso risultato di ifconfig.

Modifica

Ok, ho usato strace per questo esempio:

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

E questa è la parte importante su 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

Do 'eth0: 0' o' lo' funziona nella macchina Debian? – Carpetsmoker

+0

eth0: 0 non funziona neanche. – user1226868

+5

Il nome dell'interfaccia passato a bind (in questo caso "eth0") viene cercato da ioctl() SIOCGIFINDEX. Dovresti pubblicare l'output di strace. Le parti rilevanti della mia strace appaiono così: 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

risposta

-3

questo è un client in grado di inviare un messaggio fatto a mano. le variabili IP e la porta sono l'indirizzo della porta e IP del server i valori nel programma di seguito sono esempi

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 

e il server è

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

Spero che questa risposta aiuta e questo è ciò che il vostro cercando.

+4

Questa risposta non ha nulla a che fare con la domanda precedente, che riguarda i socket non elaborati. – kag

4

Quando si associa un socket RAW con packet su un'interfaccia, è necessario un tupla con 2 oggetti:

(interfaceName, protoNumber) 

o 5 oggetti:

(interfaceName, protoNumber, pkttype, hatype, haddr) 

si specifica 0 a protoNumber ma forse protoNumber 0 non esiste nel tuo sistema.

Documentation about packet family: packet(7)

sll_protocol è il tipo di protocollo standard Ethernet in byte di rete ordine come definito nel file includere.

cercare di trovare il numero di protocollo nel linux/if_ether.h.

1

Supponendo che il server esterno funzioni sotto Linux, ci sono alcuni motivi per non essere in grado di eseguire il programma.

Come già notato da Figus, in realtà si utilizza il numero di protocollo 0, che potrebbe non essere definito.Si potrebbe essere più fortunati con:

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

dove proto è il numero di protocollo corrispondente al ETH_P_ALL in linux/if_ether.h (3 su alcune macchine Linux)

Ma man packet dice anche: elabora solo con efficace UID 0 o CAP_NET_RAW può aprire socket packet. Significa che devi avere i privilegi di root sul tuo server esterno per eseguire il tuo codice.

Problemi correlati