#include <stdio.h> #include <stdlib.h> #include <pcap/pcap.h> #include <net/ethernet.h> pcap_t * CreatePcapForInterface( const char * interfaceName ) { char errbuf[PCAP_ERRBUF_SIZE]; int success = 0; // Create a packet capture handle for the specified interface pcap_t * pcap = pcap_create( interfaceName, errbuf ); if( pcap == NULL ) { fprintf( stderr, "Unable to create pcap for interface %s (%s).\n", interfaceName, errbuf ); goto exit; } // Deliver packets as soon as they arrive. See the pcap man page for more info. if( pcap_set_timeout( pcap, 1 ) != 0 ) { fprintf( stderr, "Unable to configure timeout.\n" ); goto exit; } // When immediate mode is enabled, reads return immediately upon packet reception. // Otherwise, a read will block until either the kernel buffer becomes full or a timeout occurs. if( pcap_set_immediate_mode( pcap, 1 ) != 0 ) { fprintf( stderr, "Unable to configure immediate mode.\n" ); goto exit; } // Activate packet capture handle to look at packets on the network int activateStatus = pcap_activate( pcap ); if( activateStatus < 0 ) { pcap_perror( pcap, "Activate failed" ); goto exit; } // Set ethernet link-layer header type if( pcap_set_datalink( pcap, DLT_EN10MB ) ) { pcap_perror( pcap, "Set datalink failed" ); goto exit; } success = 1; exit: if( success == 0 ) { if( pcap ) { pcap_close( pcap ); pcap = NULL; } } return pcap; } void MonitorPcap( pcap_t * pcap ) { int pcapFD = pcap_get_selectable_fd( pcap ); if( pcapFD < 0 ) return; fd_set allFileDescriptorSet; FD_ZERO( &allFileDescriptorSet ); FD_SET( pcapFD, &allFileDescriptorSet ); for( ;; ) { fd_set readFileDescriptorSet = allFileDescriptorSet; int readyCount = select( pcapFD + 1, &readFileDescriptorSet, NULL, NULL, NULL ); if( readyCount < 0 ) break; if( FD_ISSET( pcapFD, &readFileDescriptorSet ) ) { struct pcap_pkthdr * pcapHeader; const u_char * packetPtr; int packetCount = pcap_next_ex( pcap, &pcapHeader, &packetPtr ); if( packetCount < 0 ) break; printf( "Got %u byte packet:\n", pcapHeader->caplen ); if( pcapHeader->caplen >= sizeof( struct ether_header ) ) { struct ether_header * eh = (struct ether_header *)packetPtr; printf( "\tdst=%02x:%02x:%02x:%02x,%02x:%02x src=%02x:%02x:%02x:%02x,%02x:%02x, type=0x%04x\n", eh->ether_dhost[0], eh->ether_dhost[1], eh->ether_dhost[2], eh->ether_dhost[3], eh->ether_dhost[4], eh->ether_dhost[5], eh->ether_shost[0], eh->ether_shost[1], eh->ether_shost[2], eh->ether_shost[3], eh->ether_shost[4], eh->ether_shost[5], ntohs( eh->ether_type ) ); } } } } int main() { pcap_t * pcap = CreatePcapForInterface( "en0" ); if( !pcap ) exit( EXIT_FAILURE ); // This could be done on a separate thread, or as a part // of general file descriptor monitoring. MonitorPcap( pcap ); return 0; }