5

I was trying to create my own sniffer (ONLY FOR FUN), and I work on a Mac. I'm using libpcap, which is a very good library for sniffing. So, I used this simple sniffer, which sniffs 5 packets: (It is written in C)

#include <pcap.h>
#include "hacking.h"

void pcap_fatal(const char *failed_in, const char *errbuf) {
     printf("Fatal Error in %s: %s\n", failed_in, errbuf);
     exit(1);
}

int main() {
    struct pcap_pkthdr header;
    const u_char *packet;
    char errbuf[PCAP_ERRBUF_SIZE];
    char *device;
    pcap_t *pcap_handle;
    int i;

device = pcap_lookupdev(errbuf);
if(device == NULL)
    pcap_fatal("pcap_lookupdev", errbuf);

printf("Sniffing on device %s\n", device);

pcap_handle = pcap_open_live(device, 4096, 1, 0, errbuf);
if(pcap_handle == NULL)
    pcap_fatal("pcap_open_live", errbuf);

for(i=0; i < 5; i++) {
    packet = pcap_next(pcap_handle, &header);
    printf("Got a %d byte packet\n", header.len);
    dump(packet, header.len);
}

pcap_close(pcap_handle);

}

If you're wondering, yes I took it from a book (Hacking: The Art of Exploitation) and modified a little bit. The problem is, if I run this on Linux, it works perfectly, no problems. But if I run this on a Mac, it doesn't work and it doesn't capture any packet.

Can someone of you help? Thanks in advance!

jndok
  • 909
  • 3
  • 14
  • 28
  • Does it print any error messages? Are you sure you're listening on the right network device? – thejh Feb 23 '13 at 10:39
  • yes, I'm sure. It sniffs on 'en0' which is the right device. – jndok Feb 23 '13 at 10:40
  • 2
    you don't have access to /dev/bpf*, which is the sniffing device on Mac OS X. run it under sudo, and it may work for you. – Anya Shenanigans Feb 23 '13 at 11:46
  • The other problem is that there is a backing buffer for the pcap_open_live, and `pcap_next` may not return until the buffer has been filled. You should use a non-zero timeout when reading (e.g. 1000), and check if a packet got returned. – Anya Shenanigans Feb 23 '13 at 13:02
  • I am seeing the same strange behaviour on some Macs with my program (which also uses pcap_setfilter, started with sudo). On two Macs my program works fine, on two other (also latest OS, also all updates installed), I do not get any packets. Same code, different behavior. And what makes it even more strange: if I am running tcpdump in parallel, then tcdump dumps packets and my program starts receiving packets. – Werner Henze May 30 '13 at 11:51
  • @WernerHenze: does your program pass 1 as the "promisc" argument to `pcap_open_live()`, or call `pcap_set_promisc()` after calling `pcap_create()` and before calling `pcap_activate()`? If not, you're not running in promiscuous mode, so you will only see packets sent to or from your machine and broadcast/multicast packets; running tcpdump will, by default, put the interface into promiscuous mode, and *all* programs, including yours, might see third-party packets. –  Jun 13 '13 at 20:32
  • @GuyHarris I am not using promiscuous mode. I am only interested in packets that are targeted to my PC or to broadcast address. These packets should always be delivered to me. But I had a case where I only got them when tcpdump ran in parallel (and might have put the NIC into promiscuous mode). – Werner Henze Jun 14 '13 at 09:23

3 Answers3

1

If you're getting a "Fatal Error in pcap_lookupdev" error message, then the problem is what Sascha said it was - you don't have permission to capture packets. If you're getting that message, try running the program with sudo, or try, for example, changing the ownership of the /dev/bpf* devices to you (which you will need to do with sudo). However, you're saying that "It sniffs on 'en0'", so presumably you're saying that because it's printing "Sniffing on device en0", in which case pcap_lookupdev() isn't failing.

If you're getting a "Fatal Error in pcap_open_live", that might also be a problem with permissions, but you almost certainly wouldn't get an error due to permissions there, as pcap_lookupdev() would already have failed.

If you're not getting a "Fatal Error in" error message, the problem is probably, as Petesh noted, that you specified 0 as the timeout. If 0 is specified as the timeout, pcap_loop(), pcap_dispatch(), pcap_next(), and pcap_next_ex() can wait indefinitely before providing packets to the application; on some platforms, such as Linux and Solaris, it won't wait indefinitely, but on other platforms, such as *BSD and OS X, it could wait indefinitely. Try a timeout of 1000, which is one second; that's what tcpdump does, for example.

0

In addition to Petesh: For details, please check the manpage ("man pcap" in Terminal).

It states:

Under BSD (this includes Mac OS X):

          You must have read access to /dev/bpf* on systems that don't have a cloning
          BPF device, or to /dev/bpf on systems that do.  On BSDs with a devfs  (this
          includes  Mac OS X), this might involve more than just having somebody with
          super-user access setting the ownership or permissions on the BPF devices -
          it  might  involve  configuring  devfs  to set the ownership or permissions
          every time the system is booted, if the system even supports  that;  if  it
          doesn't  support  that,  you might have to find some other way to make that
          happen at boot time.
Abu Dun
  • 364
  • 1
  • 12
  • You should add a note about the 'read timeout' - he's probably hitting that problem as well. – Anya Shenanigans Feb 23 '13 at 13:14
  • 1
    Actually, *you* should add that note - if you're answering his question (which your comments did), you should do so in an answer, not a comment. –  Feb 23 '13 at 23:49
0

I tested code at 10.8.4 and worked with changing param to_ms (read timeout) to some non-zero value then started receiving packet.

Thanks for basic code. It saved my time.

Regards, Anand Choubey

Andy
  • 338
  • 3
  • 10