- #include <pcap.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- // use these to further dissect packets
- #include <netinet/ip.h>
- #include <arpa/inet.h>
- #include <netinet/if_ether.h>
- // global: datalink type and header size
- int dltype;
- int dlt_size;
- struct my_pcap_context {
- int cnt;
- };
- void callback(u_char *, const struct pcap_pkthdr*, const u_char*);
- void callback(u_char *user, // pass data between the calls with this
- const struct pcap_pkthdr* pkthdr, // pcap header, metadata about the packet
- const u_char* packet) // bytes on the wire, starting with Layer2 (e.g., Ethernet)
- {
- int i;
- // struct ether_header *eptr; /* net/ethernet.h */
- // IP header (or another layer 3 protocol header, e.g., ARP)
- // will be found at the offset dlt_size .
- pkthdr->len, pkthdr->caplen);
- for (i = 0; i < (bpf_u_int32) pkthdr->caplen; i++) {
- }
- }
- int main(int argc,char **argv)
- {
- char *dev;
- char errbuf[PCAP_ERRBUF_SIZE];
- pcap_t* cap;
- struct bpf_program fp; /* hold compiled program */
- bpf_u_int32 maskp; /* subnet mask */
- bpf_u_int32 netp; /* ip */
- if(argc != 3){
- return 0;
- }
- dev = argv[1];
- /* open device for reading this time lets set it in promiscuous
- * mode so we can monitor traffic to another machine */
- cap = pcap_open_live(dev, IP_MAXPACKET, // snaplen, truncate packets at this size (0 will do)
- 1, 1000, errbuf); // promiscuous mode? , timeout
- if(cap == NULL){
- }
- /* ask pcap for the network address and mask of the device */
- if( pcap_lookupnet(dev, &netp, &maskp, errbuf) < 0 ){
- }
- // Datalink is important because the packet will start with a datalink-specific
- // header, which we must skip to get to IP. But how many bytes to skip?
- // Different DLTs have different lengths. We can either hard-code them,
- // or try setting DLT_RAW, to get rid of the datalink header entirely.
- // This will lose us info such as on which intreface the packet arrived,
- // and from what MAC address. --SB: RAW does not work on "any".
- dltype = pcap_datalink(cap);
- switch(dltype){ // this seems like something PCAP would have a function for...
- case PCAP_ERROR_NOT_ACTIVATED:
- case DLT_RAW:
- dlt_size = 0;
- break;
- case DLT_LINUX_SLL: // "any" for device will give you this
- dlt_size = 16;
- break;
- case DLT_EN10MB:
- dlt_size = 14;
- break;
- default:
- }
- /* Lets try and compile the program.. non-optimized */
- /* Instead of netp, you can use PCAP_NETMASK_UNKNOWN if you don't need
- to use the broadcast-related filtering; this saves a call to pcap_lookupnet() above. */
- if(pcap_compile(cap, &fp, argv[2], 0, netp) == -1){
- }
- /* set the compiled program as the filter */
- if(pcap_setfilter(cap, &fp) == -1){
- }
- struct my_pcap_context mydata = { .cnt = 0 };
- /* ... and loop */
- pcap_loop(cap, -1, callback, (u_char*) &mydata); //cast to avoid type warning
- return 0;
- }
Raw Paste