Странный RAW сокет в Mac OS X - PullRequest
10 голосов
/ 30 июля 2011

Когда я запускаю простой сниффер пакетов, закодированный в C, на моем 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;
}

Я скомпилировал его и запустил на своей коробке, и ничего не происходит:

MacOsxBox:Desktop evariste$sudo ./simpleSniffer

Спасибо за вашу помощь.

Ответы [ 2 ]

12 голосов
/ 30 июля 2011

Это не будет работать на * 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.)

0 голосов
/ 30 июля 2011

Я запускаю его и получаю:

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

... и посмотри, что там написано.

...