问题 Mac OS X上的奇怪RAW套接字


当我在Mac OS X上运行一个用C编码的简单数据包嗅探器时,我根本没有输出,这是一个奇怪的事情!有人可以帮我理解发生了什么。

#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

谢谢你的帮助。


6461
2017-07-29 20:23


起源

你可能有更好的运气使用libpcap,而不是试图直接打开原始套接字。 - duskwuff


答案:


这不适用于* BSD(包括OSX / Darwin)。看调查 这里 更多细节:

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。)


12
2017-07-30 01:53



谢谢你的回答。对于之前使用过的lpcap,它工作正常。我只是在研究为什么这个简单的原始套接字在Linux上而不是在Mac OS X上工作,现在我得到了确认。谢谢。 - funnyCoder


我跑了然后得到:

# ./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
2017-07-29 22:14



谢谢查理,你在MacOsX或Linux上运行它(因为在linux上它没关系)。似乎它在while循环中停止了!我将旧的printf调试添加到代码中(谢谢:-)并得到:即将阅读套接字。这个mac盒子上有奇怪的东西我在桌面上拥有所有权限。 - funnyCoder