【问题标题】:Strange RAW Socket on Mac OS XMac OS X 上奇怪的 RAW 套接字
【发布时间】:2011-10-16 06:08:03
【问题描述】:

当我在我的 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

感谢您的帮助。

【问题讨论】:

  • 使用 libpcap 而不是直接打开原始套接字可能会更好。

标签: c macos sockets packet-sniffers sniffing


【解决方案1】:

这不适用于 *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。)

【讨论】:

  • 感谢您的回答。对于我以前使用过的 lpcap,它工作正常。我只是在调查为什么这个简单的原始套接字在 linux 上工作而不是在 Mac OS X 上工作,现在我得到了确认。谢谢。
  • 为什么要使用 libpcap?有一些很好的例子(如果你继续挖掘,你至少会找到一些)解释如何使用 Berkeley Packet Filters 等:vankuik.nlbastion.rieck.ru 实际上,我更喜欢使用 BPF 而不是 libpcap。你不需要学习 API;相反,您可以照常进行。
  • 这是一个好点;也许我的结论措辞过于强硬。我推荐使用libpcap,因为它通常在所有平台上都可用,并且可以使您的代码更具可移植性。但是,如果您出于性能原因或其他原因想要进入低级别,我说去吧!
【解决方案2】:

我运行它并得到:

# ./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");

...看看它说了什么。

【讨论】:

  • 谢谢 Charlie,你是在 MacOsX 还是 Linux 上运行它(因为在 linux 上没问题)。似乎它在while循环上停止了!我将旧的 printf 调试添加到代码中(感谢:-) 并得到:即将读取套接字。这个mac盒子上奇怪的东西我在桌面上拥有所有权限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
相关资源
最近更新 更多