2011-07-29 14 views
8

Po uruchomieniu prostego sniffera kodowanego w C na moim Mac OS X, nie mam żadnego wyjścia, to dziwne! Czy ktoś może mi pomóc zrozumieć, co się dzieje.Dziwne gniazdo RAW w systemie Mac OS X

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

int main(void) { 
    int i, recv_length, sockfd; 

    u_char buffer[9000]; 

    if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) { 
     printf("Socket failed!!\n"); 

     return -1; 
    } 

    for(i=0; i < 3; i++) { 
     recv_length = recv(sockfd, buffer, 8000, 0); 
     printf("Got some bytes : %d\n", recv_length); 
    } 

    return 0; 
} 

skompilować i uruchomić go na moim polu i nic się nie dzieje:

MacOsxBox:Desktop evariste$sudo ./simpleSniffer 

Dzięki za pomoc.

+0

Możesz mieć więcej szczęścia używając libpcap zamiast próbować bezpośrednio otworzyć surowe gniazdo. – duskwuff

Odpowiedz

10

Nie będzie działać na * BSD (w tym OSX/Darwin). Zobacz dochodzenie here więcej szczegółów:

b. FreeBSD 
********** 

FreeBSD takes another approach. It *never* passes TCP or UDP packets to raw 
sockets. Such packets need to be read directly at the datalink layer by using 
libraries like libpcap or the bpf API. It also *never* passes any fragmented 
datagram. Each datagram has to be completeley reassembled before it is passed 
to a raw socket. 
FreeBSD passes to a raw socket: 
    a) every IP datagram with a protocol field that is not registered in 
    the kernel 
    b) all IGMP packets after kernel finishes processing them 
    c) all ICMP packets (except echo request, timestamp request and address 
    mask request) after kernel finishes processes them 

Morał z tej historii: użyj libpcap do tego. To znacznie ułatwi ci życie. (Jeśli używasz MacPorts, wykonaj sudo port install libpcap.)

+0

Dzięki za tę odpowiedź. Dla lpcap użyłem go wcześniej i działa dobrze. Właśnie sprawdzałem, dlaczego to proste gniazdko działa na Linuksie, a nie na Mac OS X, a teraz otrzymałem potwierdzenie. Dzięki. – funnyCoder

0

go uruchomić i uzyskać:

# ./a.out 
Got some bytes : 176 
Got some bytes : 168 
Got some bytes : 168 
# 

Zgaduję, że to będzie coś naprawdę dziwne, jak nie masz uprawnień do otwierania gniazdo i stderr jest przekierowywany dziwnie.

Sugeruję dobre staromodne wilk-pułapki debugowania:

printf("I got ti 1\n"); 
    if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) { 
     printf("Socket failed!!\n"); 

     return -1; 
    } 
    printf("I got to 2\n"); 
    for(i=0; i < 3; i++) { 
     printf("About to read socket.\n"); 
     recv_length = recv(sockfd, buffer, 8000, 0); 
     printf("Got some bytes : %d\n", recv_length); 
    } 
    printf("Past the for loop.\n"); 

... i zobaczyć, co ona mówi.

+0

Dzięki Charlie, uruchamiasz go na MacOsX lub Linuksie (bo na Linuksie jest OK). Wygląda na to, że zatrzymuje się na pętli while! Dodałem stare debugowanie printf do kodu (podziękowania :-) i dostałem tylko: O czytaniu gniazda. Dziwna rzecz na tym pudełku Maca mam wszystkie uprawnienia na pulpicie. – funnyCoder

Powiązane problemy