Advertisement
Guest User

Untitled

a guest
Aug 12th, 2011
1,245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.04 KB | None | 0 0
  1. /*
  2.  * acksniff
  3.  *
  4.  ****************************************************************************
  5.  *
  6.  * Example compiler command-line for GCC:
  7.  *   gcc -Wall -o acksniff acksniff.c -lpcap
  8.  *
  9.  ****************************************************************************
  10.  *
  11.  */
  12.  
  13. #define APP_NAME        "acksniff"
  14. #define MAGIC_ACK       0xdead
  15. #define MAGIC_SEQ       0xfeed
  16.  
  17. #include <pcap.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <ctype.h>
  22. #include <errno.h>
  23. #include <sys/types.h>
  24. #include <sys/socket.h>
  25. #include <netinet/in.h>
  26. #include <arpa/inet.h>
  27.  
  28. /* default snap length (maximum bytes per packet to capture) */
  29. #define SNAP_LEN 1518
  30.  
  31. /* ethernet headers are always exactly 14 bytes [1] */
  32. #define SIZE_ETHERNET 14
  33.  
  34. /* Ethernet addresses are 6 bytes */
  35. #define ETHER_ADDR_LEN  6
  36.  
  37. /* Ethernet header */
  38. struct sniff_ethernet {
  39.         u_char  ether_dhost[ETHER_ADDR_LEN];    /* destination host address */
  40.         u_char  ether_shost[ETHER_ADDR_LEN];    /* source host address */
  41.         u_short ether_type;                     /* IP? ARP? RARP? etc */
  42. };
  43.  
  44. /* IP header */
  45. struct sniff_ip {
  46.         u_char  ip_vhl;                 /* version << 4 | header length >> 2 */
  47.         u_char  ip_tos;                 /* type of service */
  48.         u_short ip_len;                 /* total length */
  49.         u_short ip_id;                  /* identification */
  50.         u_short ip_off;                 /* fragment offset field */
  51.         #define IP_RF 0x8000            /* reserved fragment flag */
  52.         #define IP_DF 0x4000            /* dont fragment flag */
  53.         #define IP_MF 0x2000            /* more fragments flag */
  54.         #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
  55.         u_char  ip_ttl;                 /* time to live */
  56.         u_char  ip_p;                   /* protocol */
  57.         u_short ip_sum;                 /* checksum */
  58.         struct  in_addr ip_src,ip_dst;  /* source and dest address */
  59. };
  60. #define IP_HL(ip)               (((ip)->ip_vhl) & 0x0f)
  61. #define IP_V(ip)                (((ip)->ip_vhl) >> 4)
  62.  
  63. /* TCP header */
  64. typedef u_int tcp_seq;
  65.  
  66. struct sniff_tcp {
  67.         u_short th_sport;               /* source port */
  68.         u_short th_dport;               /* destination port */
  69.         tcp_seq th_seq;                 /* sequence number */
  70.         tcp_seq th_ack;                 /* acknowledgement number */
  71.         u_char  th_offx2;               /* data offset, rsvd */
  72. #define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)
  73.         u_char  th_flags;
  74.         #define TH_FIN  0x01
  75.         #define TH_SYN  0x02
  76.         #define TH_RST  0x04
  77.         #define TH_PUSH 0x08
  78.         #define TH_ACK  0x10
  79.         #define TH_URG  0x20
  80.         #define TH_ECE  0x40
  81.         #define TH_CWR  0x80
  82.         #define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
  83.         u_short th_win;                 /* window */
  84.         u_short th_sum;                 /* checksum */
  85.         u_short th_urp;                 /* urgent pointer */
  86. };
  87.  
  88. void
  89. got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
  90.  
  91.  
  92. void
  93. print_app_usage(void);
  94.  
  95. /*
  96.  * print help text
  97.  */
  98. void
  99. print_app_usage(void)
  100. {
  101.  
  102.     printf("Usage: %s [interface]\n", APP_NAME);
  103.     printf("\n");
  104.     printf("Options:\n");
  105.     printf("    interface    Listen on <interface> for packets.\n");
  106.     printf("\n");
  107.  
  108. return;
  109. }
  110.  
  111. /*
  112.  * dissect/print packet
  113.  */
  114. void
  115. got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
  116. {
  117.  
  118.     static int count = 1;                   /* packet counter */
  119.    
  120.     /* declare pointers to packet headers */
  121.     const struct sniff_ip *ip;              /* The IP header */
  122.     const struct sniff_tcp *tcp;            /* The TCP header */
  123.  
  124.     int size_ip;
  125.     int size_tcp;
  126.     unsigned int r_ack;
  127.     unsigned int r_seq;
  128.  
  129.     count++;
  130.    
  131.    
  132.     /* define/compute ip header offset */
  133.     ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
  134.     size_ip = IP_HL(ip)*4;
  135.     if (size_ip < 20) {
  136.         printf("   * Invalid IP header length: %u bytes\n", size_ip);
  137.         return;
  138.     }
  139.  
  140.     /* print source and destination IP addresses
  141.     printf("       From: %s\n", inet_ntoa(ip->ip_src));
  142.     printf("         To: %s\n", inet_ntoa(ip->ip_dst));
  143.     */
  144.    
  145.     /* determine protocol */   
  146.     switch(ip->ip_p) {
  147.         case IPPROTO_TCP:
  148.             break;
  149.         default:
  150.             return;
  151.     }
  152.    
  153.     /*
  154.      *  OK, this packet is TCP.
  155.      */
  156.    
  157.     /* define/compute tcp header offset */
  158.     tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
  159.     size_tcp = TH_OFF(tcp)*4;
  160.     if (size_tcp < 20) {
  161.         printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
  162.         return;
  163.     }
  164.  
  165.     /* set ack and seq variables, then compare to MAGIC_ACK and MAGIC_SEQ */
  166.     r_ack = ntohl(tcp->th_ack);
  167.     r_seq = ntohl(tcp->th_seq);
  168.  
  169.     if (r_ack == MAGIC_ACK && r_seq == MAGIC_SEQ)
  170.         printf("magic packet received\n");
  171.  
  172. return;
  173. }
  174.  
  175. int main(int argc, char **argv)
  176. {
  177.  
  178.     char *dev = NULL;           /* capture device name */
  179.     char errbuf[PCAP_ERRBUF_SIZE];      /* error buffer */
  180.     pcap_t *handle;             /* packet capture handle */
  181.  
  182.     char filter_exp[] = "tcp";      /* filter expression [3] */
  183.     struct bpf_program fp;          /* compiled filter program (expression) */
  184.     bpf_u_int32 mask;           /* subnet mask */
  185.     bpf_u_int32 net;            /* ip */
  186.     int num_packets = 0;            /* Capture indefinitely */
  187.  
  188.     /* check for capture device name on command-line */
  189.     if (argc == 2) {
  190.         dev = argv[1];
  191.     }
  192.     else if (argc > 2) {
  193.         fprintf(stderr, "error: unrecognized command-line options\n\n");
  194.         print_app_usage();
  195.         exit(EXIT_FAILURE);
  196.     }
  197.     else {
  198.         /* find a capture device if not specified on command-line */
  199.         dev = pcap_lookupdev(errbuf);
  200.         if (dev == NULL) {
  201.             fprintf(stderr, "Couldn't find default device: %s\n",
  202.                 errbuf);
  203.             exit(EXIT_FAILURE);
  204.         }
  205.     }
  206.    
  207.     /* get network number and mask associated with capture device */
  208.     if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
  209.         fprintf(stderr, "Couldn't get netmask for device %s: %s\n",
  210.             dev, errbuf);
  211.         net = 0;
  212.         mask = 0;
  213.     }
  214.  
  215.     /* print capture info */
  216.     printf("Device: %s\n", dev);
  217.     printf("Filter expression: %s\n", filter_exp);
  218.  
  219.     /* open capture device */
  220.     handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
  221.     if (handle == NULL) {
  222.         fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
  223.         exit(EXIT_FAILURE);
  224.     }
  225.  
  226.     /* make sure we're capturing on an Ethernet device [2] */
  227.     if (pcap_datalink(handle) != DLT_EN10MB) {
  228.         fprintf(stderr, "%s is not an Ethernet\n", dev);
  229.         exit(EXIT_FAILURE);
  230.     }
  231.  
  232.     /* compile the filter expression */
  233.     if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
  234.         fprintf(stderr, "Couldn't parse filter %s: %s\n",
  235.             filter_exp, pcap_geterr(handle));
  236.         exit(EXIT_FAILURE);
  237.     }
  238.  
  239.     /* apply the compiled filter */
  240.     if (pcap_setfilter(handle, &fp) == -1) {
  241.         fprintf(stderr, "Couldn't install filter %s: %s\n",
  242.             filter_exp, pcap_geterr(handle));
  243.         exit(EXIT_FAILURE);
  244.     }
  245.  
  246.     /* now we can set our callback function */
  247.     pcap_loop(handle, num_packets, got_packet, NULL);
  248.  
  249.     /* cleanup */
  250.     pcap_freecode(&fp);
  251.     pcap_close(handle);
  252.  
  253. return 0;
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement