2012-12-24 8 views
5

in base alle http://kernelnewbies.org/Linux_3.0#head-c5bcc118ee946645132a834a716ef0d7d05b282e possiamo ora ping come utente senza privilegi, e posso sorta di farlo funzionare.pitone con ping non privilegiato in linux IPPROTO_ICMP

utilizzando https://github.com/jedie/python-ping ho modificato della linea 210 per assomigliare

current_socket = socket.socket (socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP)

come root I "echo 1000 1000>/proc/sys/net/ipv4/ping_group_range"

mio gruppo è di 1000

e posso correre ping.py come me stesso come un utente ordinario, posso vedere le richieste di eco e risposte eco in tcpdump

18:33:24.840291 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo request, id 38, seq 0, length 249 
18:33:24.840309 IP (tos 0x0, ttl 64, id 37939, offset 0, flags [none], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo reply, id 38, seq 0, length 249 

ma ping.py non vede le risposte e dice timeout.

Qualche idea su come farlo funzionare?

edit:

sto restringendo il problema.

print "c", icmp_header, address, self.own_id 
if icmp_header["packet_id"] == self.own_id: # Our packet 

il problema è icmp_header [ "packet_id"] è sempre 8247 e self.own_id è il PID di ping.py. 8247 è 2037 in esadecimale, che posso vedere un bel po 'di tempo nella discarica.

Questa è una discarica piena di un ping sul filo

19:25:15.513285 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 283: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo request, id 70, seq 2, length 249 
    0x0000: 4500 010d 0000 4000 4001 3bee 7f00 0001 [email protected]@.;..... 
    0x0010: 7f00 0001 0800 d932 0046 0002 5b36 362c .......2.F..[66, 
    0x0020: 2036 372c 2036 382c 2036 392c 2037 302c .67,.68,.69,.70, 
    0x0030: 2037 312c 2037 322c 2037 332c 2037 342c .71,.72,.73,.74, 
    0x0040: 2037 352c 2037 362c 2037 372c 2037 382c .75,.76,.77,.78, 
    0x0050: 2037 392c 2038 302c 2038 312c 2038 322c .79,.80,.81,.82, 
    0x0060: 2038 332c 2038 342c 2038 352c 2038 362c .83,.84,.85,.86, 
    0x0070: 2038 372c 2038 382c 2038 392c 2039 302c .87,.88,.89,.90, 
    0x0080: 2039 312c 2039 322c 2039 332c 2039 342c .91,.92,.93,.94, 
    0x0090: 2039 352c 2039 362c 2039 372c 2039 382c .95,.96,.97,.98, 
    0x00a0: 2039 392c 2031 3030 2c20 3130 312c 2031 .99,.100,.101,.1 
    0x00b0: 3032 2c20 3130 332c 2031 3034 2c20 3130 02,.103,.104,.10 
    0x00c0: 352c 2031 3036 2c20 3130 372c 2031 3038 5,.106,.107,.108 
    0x00d0: 2c20 3130 392c 2031 3130 2c20 3131 312c ,.109,.110,.111, 
    0x00e0: 2031 3132 2c20 3131 332c 2031 3134 2c20 .112,.113,.114,. 
    0x00f0: 3131 352c 2031 3136 2c20 3131 372c 2031 115,.116,.117,.1 
    0x0100: 3138 2c20 3131 392c 2031 3230 5d   18,.119,.120] 
19:25:15.513300 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 283: (tos 0x0, ttl 64, id 37971, offset 0, flags [none], proto ICMP (1), length 269) 
    127.0.0.1 > 127.0.0.1: ICMP echo reply, id 70, seq 2, length 249 
    0x0000: 4500 010d 9453 0000 4001 e79a 7f00 0001 [email protected] 
    0x0010: 7f00 0001 0000 e132 0046 0002 5b36 362c .......2.F..[66, 
    0x0020: 2036 372c 2036 382c 2036 392c 2037 302c .67,.68,.69,.70, 
    0x0030: 2037 312c 2037 322c 2037 332c 2037 342c .71,.72,.73,.74, 
    0x0040: 2037 352c 2037 362c 2037 372c 2037 382c .75,.76,.77,.78, 
    0x0050: 2037 392c 2038 302c 2038 312c 2038 322c .79,.80,.81,.82, 
    0x0060: 2038 332c 2038 342c 2038 352c 2038 362c .83,.84,.85,.86, 
    0x0070: 2038 372c 2038 382c 2038 392c 2039 302c .87,.88,.89,.90, 
    0x0080: 2039 312c 2039 322c 2039 332c 2039 342c .91,.92,.93,.94, 
    0x0090: 2039 352c 2039 362c 2039 372c 2039 382c .95,.96,.97,.98, 
    0x00a0: 2039 392c 2031 3030 2c20 3130 312c 2031 .99,.100,.101,.1 
    0x00b0: 3032 2c20 3130 332c 2031 3034 2c20 3130 02,.103,.104,.10 
    0x00c0: 352c 2031 3036 2c20 3130 372c 2031 3038 5,.106,.107,.108 
    0x00d0: 2c20 3130 392c 2031 3130 2c20 3131 312c ,.109,.110,.111, 
    0x00e0: 2031 3132 2c20 3131 332c 2031 3134 2c20 .112,.113,.114,. 
    0x00f0: 3131 352c 2031 3136 2c20 3131 372c 2031 115,.116,.117,.1 
    0x0100: 3138 2c20 3131 392c 2031 3230 5d   18,.119,.120] 

AFAICT, l'intestazione ICMP potrebbe essere imballato sbagliato. comunque è solo una pugnalata selvaggia, la fisserò un po 'più tardi, nel frattempo, ogni aiuto sarebbe apprezzato.

risposta

3

Ci sono due cose che non ha preso in considerazione:

  • Quando la ricezione di messaggi su questo nuovo tipo di socket, l'header IP non è incluso. Dal momento che il codice si modifica prevede di utilizzare i socket RAW (che fanno includere l'intestazione IP nei messaggi ricevuti), è necessario modificare alcune cose abbastanza:
    • linea 306 estratti l'intestazione ICMP con packet_data[20:28] ma naturalmente dal l'intestazione IP non è inclusa, l'offset a 20 byte non ha senso. Questo deve diventare packet_data[0:8]
    • Alla riga 310, il codice tenta di estrarre l'intestazione IP dall'inizio del pacchetto, ma non è lì. Quindi questo codice in realtà estrarrà spazzatura. Ci sono opzioni extra che puoi impostare se vuoi sapere cose come il TTL (vedi lo documentation which accompanies the patch that enabled the functionality).
  • Con questa nuova funzionalità, il kernel controlla l'ID ICMP tramite il meccanismo di associazione socket. Puoi lasciare che il kernel scelga un ID (binding implicito) o imposta un ID (binding esplicito). È meglio fare affidamento sul binding implicito perché il kernel garantirà di scegliere un ID gratuito.

    Sulla riga 309, il codice controlla se la risposta ci appartiene controllando l'ID con self.own_id.Ma usando il binding implicito il kernel sceglie l'ID per noi. Potremmo impostare self.own_id per l'identificatore del kernel ha assegnato utilizzando

    self.own_id = current_socket.getsockname()[1] 
    

    (mettere questo subito dopo self.send_one_ping on line 221)

    Ma in realtà il controllo contro self.own_id non è nemmeno necessario in ogni caso dal momento che il kernel fa già certo, vediamo solo le risposte che dovremmo vedere.

+0

Impressionante, questo ha aiutato molto. "Ci sono opzioni extra che puoi impostare se vuoi sapere cose come TTL (vedi la documentazione che accompagna la patch che ha permesso la funzionalità)." Questo è ciò su cui sono attualmente bloccato. – chesty

+0

Sì, è difficile. Per accedere ai servizi ausiliari, devi usare la chiamata di sistema 'recvmsg' invece di' recvfrom'. Quindi devi analizzare i dati utilizzando una serie di macro 'CMSG' che, credo, sono disponibili solo in C. [Questa domanda] (http://stackoverflow.com/questions/6314982/what-is-recvmsg- equivalent-in-python) conferma che 'recvmsg' non è reso disponibile in Python. Vedi anche Python [problema 6560] (http://bugs.python.org/issue6560): sembra che aggiungerlo non sia semplice. Tuttavia, almeno questo riguarda solo il TTL. Puoi tutto il resto di interesse con 'recvfrom'. – Celada

+0

OK grazie Celada, mi hai messo sulla strada giusta, da quello che ho letto qui http://stackoverflow.com/questions/9237006/getting-ttl-of-incoming-udp-packet-in-python libpcap potrebbe essere l'opzione più semplice. – chesty