C   29
pcap hexprint c
Guest on 16th March 2023 01:36:18 PM


  1. #include <pcap.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7.  
  8. // use these to further dissect packets
  9. #include <netinet/ip.h>
  10. #include <arpa/inet.h>
  11. #include <netinet/if_ether.h>
  12.  
  13. // global: datalink type and header size
  14. int dltype;
  15. int dlt_size;
  16.  
  17. struct my_pcap_context {
  18.      int cnt;
  19. };
  20.  
  21. void callback(u_char *, const struct pcap_pkthdr*, const u_char*);
  22.  
  23. void callback(u_char *user,                  // pass data between the calls with this
  24.               const struct pcap_pkthdr* pkthdr, // pcap header, metadata about the packet
  25.               const u_char* packet)             // bytes on the wire, starting with Layer2 (e.g., Ethernet)
  26. {
  27.      int i;
  28.      // struct ether_header *eptr;  /* net/ethernet.h            */
  29.  
  30.      // IP header (or another layer 3 protocol header, e.g., ARP)
  31.      //   will be found at the offset dlt_size .
  32.  
  33.      printf("\nFrame %d: %d bytes on the wire, %d captured\n", ((struct my_pcap_context*) user)->cnt++,
  34.             pkthdr->len, pkthdr->caplen);
  35.      for (i = 0; i < (bpf_u_int32) pkthdr->caplen; i++) {
  36.           printf("%02X%s", (uint8_t)packet[i], (i + 1)%16 ? " " : "\n");
  37.      }
  38.      printf("\n");
  39. }
  40.  
  41. int main(int argc,char **argv)
  42. {
  43.      char *dev;
  44.      char errbuf[PCAP_ERRBUF_SIZE];
  45.      pcap_t* cap;
  46.      struct bpf_program fp;      /* hold compiled program     */
  47.      bpf_u_int32 maskp;          /* subnet mask               */
  48.      bpf_u_int32 netp;           /* ip                        */
  49.      
  50.      if(argc != 3){
  51.           fprintf(stdout,"Usage: %s interface \"filter program\"\n", argv[0]);
  52.           return 0;
  53.      }
  54.  
  55.      dev = argv[1];
  56.      
  57.      /* open device for reading this time lets set it in promiscuous
  58.       * mode so we can monitor traffic to another machine             */
  59.      cap = pcap_open_live(dev, IP_MAXPACKET, // snaplen, truncate packets at this size (0 will do)
  60.                             1, 1000, errbuf);    // promiscuous mode? , timeout
  61.      if(cap == NULL){
  62.           printf("pcap_open_live(): %s\n", errbuf);
  63.           exit(1);
  64.      }
  65.      
  66.      /* ask pcap for the network address and mask of the device */
  67.      if( pcap_lookupnet(dev, &netp, &maskp, errbuf) < 0 ){
  68.           printf("pcap_open_live(): %s\n", errbuf);
  69.           exit(1);
  70.      }
  71.  
  72.      // Datalink is important because the packet will start with a datalink-specific
  73.      //   header, which we must skip to get to IP. But how many bytes to skip?
  74.      //   Different DLTs have different lengths. We can either hard-code them,
  75.      //   or try setting DLT_RAW, to get rid of the datalink header entirely.
  76.      //   This will lose us info such as on which intreface the packet arrived,
  77.      //   and from what MAC address. --SB: RAW does not work on "any".
  78.      dltype = pcap_datalink(cap);
  79.      printf("Datalink type (see DLT_* in pcap/bpf.h and 'man pcap-linktype'): %d\n", dltype);
  80.      switch(dltype){  // this seems like something PCAP would have a function for...
  81.      case PCAP_ERROR_NOT_ACTIVATED:
  82.           fprintf(stderr, "Failed to get data link type, bailing.\n");
  83.           exit(1);
  84.      case DLT_RAW:
  85.           dlt_size = 0;
  86.           break;
  87.      case DLT_LINUX_SLL:  // "any" for device will give you this
  88.           dlt_size = 16;
  89.           break;
  90.      case DLT_EN10MB:
  91.           dlt_size = 14;
  92.           break;
  93.      default:
  94.           fprintf(stderr, "Unknown data link type %d, bailing.\n", dltype );
  95.           exit(1);
  96.      }
  97.  
  98.      /* Lets try and compile the program.. non-optimized */
  99.      /*  Instead of netp, you can use PCAP_NETMASK_UNKNOWN if you don't need
  100.          to use the broadcast-related filtering; this saves a call to pcap_lookupnet() above. */
  101.      if(pcap_compile(cap, &fp, argv[2], 0, netp) == -1){
  102.           fprintf(stderr, "Error calling pcap_compile (filter: %s)\n", argv[2]);
  103.           exit(1);
  104.      }
  105.      
  106.      /* set the compiled program as the filter */
  107.      if(pcap_setfilter(cap, &fp) == -1){
  108.           fprintf(stderr, "Error setting filter\n");
  109.           exit(1);
  110.      }
  111.      
  112.      struct my_pcap_context mydata = { .cnt = 0 };
  113.  
  114.      /* ... and loop */
  115.      pcap_loop(cap, -1, callback, (u_char*) &mydata); //cast to avoid type warning
  116.      
  117.      return 0;
  118. }

Raw Paste

Login or Register to edit or fork this paste. It's free.