2012-11-24 10 views
5

. Si tratta di un compito, che deve essere eseguito con socket raw. Devo programmare un semplice ping icmp. L'ho usato come base http://www.pdbuchan.com/rawsock/icmp4.c. Alla riga 127 è wlan0, Im che usa eth0. In linea 290 ho codificato questo:Come ricevere la richiesta ICMP in C con socket non elaborati

`

struct sockaddr_in rec; 

    unsigned char * pkt = (unsigned char *) malloc (IP_MAXPACKET * sizeof (unsigned char)); 

    if (recvfrom (sd, (void*)pkt, IP4_HDRLEN + ICMP_HDRLEN+datalen , 0, NULL, (socklen_t*)sizeof (struct sockaddr)) < 0) { 
    perror ("recvfrom() failed "); 
    exit (EXIT_FAILURE); 
    } 
    struct ip *ip = (struct ip *)pkt; 
    struct icmphdr *icmp = (struct icmphdr *)(pkt + IP4_HDRLEN); 

    printf("%s %s %d\n",(char*)inet_ntoa(*(struct in_addr*)&ip->ip_dst), 
      (char*)inet_ntoa(*(struct in_addr*)&ip->ip_src), 
     icmp->type); 
    free (pkt); 

` Il problema è che ip_dst e ip_src vengono mostrati come IP mie macchine, e il tipo di ICMP come 0 e non 8. Wireshark mostra sia risposta ICMP e richiesta. Probabilmente la mia recvfrom è sbagliata, ma ho sentito che Linux/TCP di Linux potrebbero gestire i pacchetti. Se è vero, qual è la soluzione per questo?

modifica: ho controllato questo raw socket listener ma non ha risolto il mio problema.

+0

La creazione è sul link che ho postato. È dagli esempi di quel sito. Ho inserito questo codice nella riga 290 di quello icmp4.c – liwing

risposta

6

Non penso che si possa ottenere una risposta quando si utilizza IPPROTO_RAW.

devi usare

socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 

Con IPPROTO_ICMP si deve solo inviare un pacchetto ICMP, non l'intero pacchetto IP.

Quando si riceve tuttavia si ottiene l'intero pacchetto IP e si deve estrarre la risposta ICMP. Si noti che si riceverà una copia di tutti i pacchetti ICMP inviati all'host, quindi è necessario filtrarli.

Vedere a real ping per l'ispirazione.

+0

OK, così ho fatto questo http://pastebin.com/62JmMddE; Il mio programma stampa ip_dst e ip_src entrambi come il mio IP ancora. E se metto una struttura non NULL in recvfrom, ottengo l'errore di Bad Address. Quel ping vero dà appena un nuovo sockaddr_in dichiarato da recvfrom, proprio come sto cercando di fare. – liwing

+0

lol, non saprei mai di questo problema inet_ntoa. Grazie mille. Ancora non capisco quando dovrei usare il parametro sockaddr non NULL in recvfrom. – liwing

Problemi correlati