2011-07-29 17 views
8

Mac OS XでCでコーディングされた単純なパケットスニッファを実行すると、全く出力が得られませんでしたが、これは奇妙なことです!誰かが私が何が起こっているのか理解するのを助けることができますMac OS Xで奇妙なRAWソケット

#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; 
} 

私はそれをコンパイルし、私の箱の上にそれを実行し、何が起こっていない:あなたの助けのための

MacOsxBox:Desktop evariste$sudo ./simpleSniffer 

感謝。

+0

生のソケットを直接開こうとするのではなく、libpcapを使用してください。 – duskwuff

答えて

10

* BSD(OSX/Darwinを含む)では動作しません。詳細は調査hereを参照してください:

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 

物語のモラル:このためlibpcapを使用しています。それはあなたの人生をはるかに簡単にします。 (MacPortsを使用する場合はsudo port install libpcapを入力してください)

+0

この回答に感謝します。 lpcapのために私は前にそれを使用し、それは正常に動作します。私はちょうどこの単純なrawソケットがMac OS XではなくLinux上で動作する理由を調査していました。ありがとう。 – funnyCoder

0

私はそれを実行して取得:

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

私はあなたがソケットとstderrを開く権限が妙にリダイレクトされていないよう、本当に奇妙なものになるだろう推測しています。

私は昔ながらの狼トラップのデバッグをお勧めしたい:

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

を...そしてそれが言うものを参照してください。

+0

チャーリーに感謝、MacOsXまたはLinuxで実行しますか(Linuxの場合は問題ありません)。それはwhileループで停止するようです!私は古いprintfのデバッグをコードに追加しました(感謝:-)、ちょうど:ソケットを読むことについて。この奇妙なものは、私はデスクトップ上のすべての権限を持っています。 – funnyCoder