Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3024154
  • 博文数量: 272
  • 博客积分: 5544
  • 博客等级: 大校
  • 技术积分: 5496
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-08 00:48
个人简介

  每个人都要有一个骨灰级的爱好,不为金钱,而纯粹是为了在这个领域享受追寻真理的快乐。

文章分类

全部博文(272)

文章存档

2015年(2)

2014年(5)

2013年(25)

2012年(58)

2011年(182)

分类: LINUX

2012-05-29 16:24:12


  1. /*
  2. 记录icmp_tpye类型数据包接收的数量。
  3. kill -SIGHUP $(pidof filename) 生成文件
  4. kill -SIGQUIT $(pidof filename) 退出程序
  5. 程序在接收到SIGHUP信号后在当前目录下生成result文件,
  6. 接收SIGQUIT信号后退出程序,并删除result文件。
  7. */

  8. #include <pcap.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <signal.h>
  12. #include <string.h>
  13. #include <linux/if_ether.h>
  14. #include <linux/ip.h>
  15. #include <linux/icmp.h>

  16. #define SNAP_LEN 1518        /*数据包最大长度*/
  17. #define MIN_LEN    (sizeof(struct ethhdr) + sizeof(struct iphdr) \
  18.                  + sizeof(struct icmphdr))        /* 所分析的数据包最小长度 避免访问到空指针 */
  19. #define ICMP_TPYE 19        /* icmp_tpye的类型为0~18 */
  20. #define MAXBUFSIZE 1024        /* 路径数组的长度 */

  21. static pcap_t *handle;
  22. static struct bpf_program fp;
  23. static unsigned int count[ICMP_TPYE];
  24. //static int fd;
  25. static FILE *fd;
  26. static char path[MAXBUFSIZE];

  27. static void Exit_Free()
  28. {
  29.     /* cleanup */
  30.     pcap_freecode(&fp);
  31.     pcap_close(handle);
  32.     unlink(path);
  33.     exit(EXIT_SUCCESS);
  34. }

  35. static void Print_Count()
  36. {
  37.     int i, len;
  38.     char buffer[256] = {0};

  39. #if 0
  40.     if ((fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644)) == -1)    exit(EXIT_FAILURE);
  41.     for(i=0; i<ICMP_TPYE; i++){
  42.         if ((len = snprintf(buffer, sizeof(buffer)-1,
  43.             "The Tpye: %2d, Count: %d\n", i, count[i])) == -1)    exit(EXIT_FAILURE);
  44.         if (write(fd, buffer, len) != len)    exit(EXIT_FAILURE);
  45.     }
  46.     close(fd);
  47. #endif

  48.     if ((fd = fopen(path, "w")) == NULL)    exit(EXIT_FAILURE);
  49.     for(i=0; i<ICMP_TPYE; i++){
  50.         fprintf(fd, "The Tpye: %2d, Count: %d\n", i, count[i]);
  51.     }
  52.     fclose(fd);
  53. }

  54. static void packet_callback(u_char *args, const struct pcap_pkthdr *header,
  55.                             const u_char *packet)
  56. {
  57.     struct icmphdr *ih;
  58.     size_t qlen, hlen;
  59.     
  60.     /* 长度校验 */
  61.     if (header->caplen < MIN_LEN)    return;
  62.     /* 取得ICMP报文首部地址 */
  63.     hlen = MIN_LEN - sizeof(struct icmphdr);
  64.     /* 获得icmphdr头部指针地址 */
  65.     packet += hlen;
  66.     ih = (struct icmphdr *)packet;
  67.     /* 计数统计 */
  68.     count[ih->type]++;
  69.     return;
  70. }

  71. int main(int argc, char **argv)
  72. {
  73.     char *dev = NULL;            /* capture device name */
  74.     char filter_exp[] = "icmp";        /* filter expression [3] */
  75.     char errbuf[PCAP_ERRBUF_SIZE];        /* error buffer */
  76.     bpf_u_int32 mask;            /* subnet mask */
  77.     bpf_u_int32 net;            /* ip */
  78.     int num_packets = -1;        /* 包捕获的数量,-1为无限捕获 */
  79.     
  80. //    unsigned int *count = (unsigned int *)malloc(ICMP_TPYE * sizeof(unsigned int));
  81. //    memset(count, 0, sizeof(unsigned int));
  82.         
  83.     /* check for capture device name on command-line */
  84.     if (argc == 2) {
  85.         dev = argv[1];
  86.     } else if (argc > 2) {
  87.         fprintf(stderr, "error: unrecognized command-line options\n\n");
  88.         exit(EXIT_FAILURE);
  89.     } else {
  90.         /* find a capture device if not specified on command-line */
  91.         dev = pcap_lookupdev(errbuf);
  92.         if (dev == NULL) {
  93.             fprintf(stderr, "Couldn't find default device: %s\n",
  94.                     errbuf);
  95.             exit(EXIT_FAILURE);
  96.         }
  97.     }

  98. #if 0
  99.     printf("Device: %s\n", dev);
  100.     printf("Number of packets: %d\n", num_packets);
  101.     printf("Filter expression: %s\n", filter_exp);
  102. #endif

  103.     

  104.     /* get network number and mask associated with capture device */
  105.     if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
  106.         fprintf(stderr, "Couldn't get netmask for device %s: %s\n",
  107.                 dev, errbuf);
  108.         net = 0;
  109.         mask = 0;
  110.     }
  111.     
  112.     /* open capture device */
  113.     handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
  114.     if (handle == NULL) {
  115.         fprintf(stderr, "Couldn't open device %s: %s\n",
  116.                 dev, errbuf);
  117.         exit(EXIT_FAILURE);
  118.     }

  119.     /* make sure we're capturing on an Ethernet device [2] */
  120.     if (pcap_datalink(handle) != DLT_EN10MB) {
  121.         fprintf(stderr, "%s is not an Ethernet\n", dev);
  122.         exit(EXIT_FAILURE);
  123.     }

  124.     /* compile the filter expression */
  125.     if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
  126.         fprintf(stderr, "Couldn't parse filter %s: %s\n",
  127.          filter_exp, pcap_geterr(handle));
  128.         exit(EXIT_FAILURE);
  129.     }

  130.     /* apply the compiled filter */
  131.     if (pcap_setfilter(handle, &fp) == -1) {
  132.         fprintf(stderr, "Couldn't install filter %s: %s\n",
  133.          filter_exp, pcap_geterr(handle));
  134.         exit(EXIT_FAILURE);
  135.     }
  136.     
  137.     /* 接收到信号触发函数 */
  138.     signal(SIGHUP, Print_Count);
  139.     signal(SIGQUIT, Exit_Free);
  140.     
  141.     /* 获得当前路径 */
  142.     getcwd(path, MAXBUFSIZE);
  143.     strcat(path,"/result");
  144.     daemon(0, 0);
  145.     
  146.     /* now we can set our callback function */
  147.     pcap_loop(handle, num_packets, packet_callback, NULL);

  148.     return 0;
  149. }

阅读(2487) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~