2011-07-29 68 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,它工作正常。我只是调查为什么这个简单的原始套接字在Linux上,而不是在Mac OS X上,现在我得到了确认。谢谢。 – funnyCoder

0

我运行,并得到:

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

我猜这将是一些非常奇怪的,像你没有权限打开一个套接字和标准错误重定向奇怪。

我建议的老式狼陷阱调试:

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调试代码(谢谢:-),只是:关于读取套接字。奇怪的事情在这个mac箱子我有桌面上的所有权限。 – funnyCoder