2011-07-29 4 views
8

Lorsque je lance un simple sniffer de paquets codé en C sur mon Mac OS X, je n'ai pas de sortie du tout, c'est une chose étrange! Quelqu'un peut-il m'aider à comprendre ce qui se passe.Strange RAW Socket sur 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; 
} 

je compile et exécute sur ma boîte et rien ne va:

MacOsxBox:Desktop evariste$sudo ./simpleSniffer 

Merci pour votre aide.

+0

Vous aurez peut-être plus de chance d'utiliser libpcap au lieu d'essayer d'ouvrir directement un socket brut. – duskwuff

Répondre

10

Cela ne fonctionnera pas sur * BSD (y compris OSX/Darwin). Voir l'enquête here pour plus de détails:

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 

Morale de l'histoire: utiliser libpcap pour cela. Cela rendra votre vie beaucoup plus facile. (Si vous utilisez MacPorts, faites sudo port install libpcap.)

+0

Merci pour cette réponse. Pour le lpcap je l'ai utilisé avant et ça marche bien. Je cherchais juste à savoir pourquoi cette simple socket raw fonctionne sur Linux et non sur Mac OS X et maintenant j'ai eu la confirmation. Merci. – funnyCoder

0

Je cours et obtenir:

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

Je devine que ça va être quelque chose avez vraiment bizarre, comme vous n'êtes pas autorisé à ouvrir une socket et stderr est redirigée curieusement.

Je vous suggère le bon vieux débogage piège du loup:

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"); 

... et voir ce qu'il dit.

+0

Merci Charlie, est-ce que vous l'exécutez sur MacOsX ou Linux (parce que sur Linux c'est OK). Il semble que ça s'arrête sur la boucle while! J'ai ajouté l'ancien debug de printf au code (merci :-) et j'ai juste: À propos de lire le socket. Chose étrange sur cette boîte mac j'ai toutes les autorisations sur le bureau. – funnyCoder