基于Qt实现的网络嗅探器

Tommorow

发布日期: 2021-01-13 18:52:56 浏览量: 192
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

一、概述

Sniffer程序是一种利用以太网的特性把网络适配卡(NIC,一般为以太网卡)置为混杂(promiscuous)模式状态的工具,一旦网卡设置为这种模式,它就能接收传输在网络上的每一个信息包。

普通的情况下,网卡只接收和自己的地址有关的信息包,即传输到本地主机的信息包。要使Sniffer能接收并处理这种方式的信息,系统需要支持 BPF,Linux下需要支持SOCKET-PACKET。但一般情况下,网络硬件和TCP/IP堆栈不支持接收或者发送与本地计算机无关的数据包,所以,为了绕过标准的TCP/IP堆栈,网卡就必须设置为混杂模式。一般情况下,要激活这种方式,内核必须支持这种伪设备BPFilter,而且需要root权限来运行这种程序,所以Sniffer需要root身份安装,如果只是以本地用户的身份进入了系统,那么不可能嗅探到root的密码,因为不能运行Sniffer。

基于Sniffer这样的模式,可以分析各种信息包并描述出网络的结构和使用的机器,由于它接收任何一个在同一网段上传输的数据包,所以也就存在着捕获密码、各种信息、秘密文档等一些没有加密的信息的可能性。

二、程序运行效果展示

系统设计主要分为以下几个功能模块:

  • 获取当前主机中的网卡

  • 设置过滤规则,并依据过滤规则捕获数据包

  • 捕获数据包在主面板中的实时显示(类似wireshark抓包动态显示)

  • 数据包解析、协议树显示以及数据包内容十六进制显示

  • 捕获数据包统计

  • 捕获数据包的保存以及读取

三、实现思路

获取当前运行程序主机中的网卡。

WinPcap中提供了pcap_findalldevs_ex()函数用于获得已连接的网络适配器列表,该函数返回的是一个pcap_if结构的链表,该结构数据域中的name和description表示一个适配器名称和一个适配器的可理解描述。

  1. void MainWindow::initCaps(){
  2. ui->comboBox->addItem("请选择一个网卡接口(必选)");
  3. if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&allDevs,errbuf)>0){
  4. qDebug("pcap_findallDevs_ex failed!");
  5. }
  6. QStringList texts;
  7. for(dev=allDevs;dev->next!=NULL;dev=dev->next){
  8. texts.append(dev->description);
  9. }
  10. dev=NULL;
  11. ui->comboBox->addItems(texts);
  12. }

设置过滤规则,并依据过滤规则捕获数据包。

  1. if (dev->addresses != NULL)
  2. /* Retrieve the mask of the first address of the interface */
  3. netmask=((struct sockaddr_in *)(dev->addresses->netmask))->sin_addr.S_un.S_addr;
  4. else
  5. /* If the interface is without an address we suppose to be in a C class network */
  6. netmask=0xffffff;
  7. std::string str = ui->lineEdit->text().toStdString();
  8. const char* c_s = str.c_str();
  9. if (pcap_compile(handle, &fcode, c_s, 1, netmask) <0 )
  10. {
  11. qDebug("语法错误,无法编译过滤器");
  12. return;
  13. }
  14. if (pcap_setfilter(handle,&fcode)<0)
  15. {
  16. qDebug("语法错误,无法设置滤器");
  17. return;
  18. }

嗅探器相关结构体的定义以及主面板数据包的动态显示(类似wireshark抓包动态显示):

通过qt独有的信号与槽机制,抓包线程每读取到一个数据包即将其解析并将其显示到tableView中,当双击某行时,将该数据包解析并显示在treeView和textedit中:

  1. void MainWindow::setData(datapkt *data){
  2. int i=tableModel->rowCount();
  3. QString src_mac,dest_mac,len,src_ip,dest_ip,time;
  4. char* buf=(char*)malloc(80*sizeof(char));
  5. sprintf(buf,"%02x-%02x-%02x-%02x-%02x-%02x",data->ethh->src[0],data->ethh->src[1],data->ethh->src[2],data->ethh->src[3],data->ethh->src[4],data->ethh->src[5]);
  6. src_mac=QString(QLatin1String(buf));
  7. sprintf(buf,"%02x-%02x-%02x-%02x-%02x-%02x",data->ethh->dest[0],data->ethh->dest[1],data->ethh->dest[2],data->ethh->dest[3],data->ethh->dest[4],data->ethh->dest[5]);
  8. dest_mac=QString(QLatin1String(buf));
  9. len=QString::number(data->len);
  10. switch(data->ethh->type)
  11. {
  12. case 0x0806:
  13. sprintf(buf,"%d.%d.%d.%d",data->arph->ar_srcip[0],data->arph->ar_srcip[1],data->arph->ar_srcip[2],data->arph->ar_srcip[3]);
  14. src_ip=QString(QLatin1String(buf));
  15. sprintf(buf,"%d.%d.%d.%d",data->arph->ar_destip[0],data->arph->ar_destip[1],data->arph->ar_destip[2],data->arph->ar_destip[3]);
  16. dest_ip=QString(QLatin1String(buf));
  17. break;
  18. case 0x0800:
  19. ipvalue_to_ipaddr(ntohl(data->iph->saddr),buf);
  20. src_ip=QString(QLatin1String(buf));
  21. ipvalue_to_ipaddr(ntohl(data->iph->daddr),buf);
  22. dest_ip=QString(QLatin1String(buf));
  23. break;
  24. default:
  25. break;
  26. }
  27. current_date_time =QDateTime::currentDateTime();
  28. current_date=current_date_time.toString("yyyy.MM.dd hh:mm:ss");
  29. tableModel->setItem(i,0,new QStandardItem(src_mac));
  30. tableModel->setItem(i,1,new QStandardItem(dest_mac));
  31. tableModel->setItem(i,2,new QStandardItem(len));
  32. tableModel->setItem(i,3,new QStandardItem(data->pktType));
  33. tableModel->setItem(i,4,new QStandardItem(src_ip));
  34. tableModel->setItem(i,5,new QStandardItem(dest_ip));
  35. tableModel->setItem(i,6,new QStandardItem(current_date));
  36. }
  37. void MainWindow::setNum(pktcount *npacket){
  38. QString num_arp=QString::number(npacket->n_arp);
  39. QString num_count=QString::number(npacket->n_sum);
  40. QString num_icmp=QString::number(npacket->n_icmp);
  41. QString num_ip=QString::number(npacket->n_ip);
  42. QString num_tcp=QString::number(npacket->n_tcp);
  43. QString num_udp=QString::number(npacket->n_udp);
  44. QString num_http=QString::number(npacket->n_http);
  45. QString num_others=QString::number(npacket->n_other);
  46. ui->TCP->setText(num_tcp);
  47. ui->UDP->setText(num_udp);
  48. ui->ICMP->setText(num_icmp);
  49. ui->HTTP->setText(num_http);
  50. ui->IPv4->setText(num_ip);
  51. ui->OTHERS->setText(num_others);
  52. ui->COUNT->setText(num_count);
  53. ui->ARP->setText(num_arp);
  54. }

通过print_packet_hex函数将数据包以十六进制存入char数组中:

在实现过程中通过sprintf和strcat函数解决了输出的数值转换问题!

  1. void print_packet_hex(char* pkt,int size_pkt,char *buf)
  2. {
  3. int i=0,j = 0,rowcount;
  4. char ch;
  5. char tempbuf[8];
  6. memset(tempbuf,0,8);
  7. for(i= 0;i<size_pkt;i+=16)
  8. {
  9. sprintf(tempbuf,"%04x: ",i);
  10. strcat(buf,tempbuf);
  11. rowcount= (size_pkt-i) > 16 ? 16 : (size_pkt-i);
  12. for(j = 0; j < rowcount; j++){
  13. sprintf(tempbuf,"%02x ",pkt[i+j]);
  14. strcat(buf,tempbuf);
  15. }
  16. //不足16,用空格补足
  17. for(j=rowcount;j<16;j++){
  18. strcpy(tempbuf," ");
  19. strcat(buf,tempbuf);
  20. }
  21. for(j = 0; j < rowcount; j++)
  22. {
  23. ch = pkt[i+j];
  24. ch = isprint(ch) ? ch : '.';
  25. sprintf(tempbuf,"%c ",ch);
  26. strcat(buf,tempbuf);
  27. }
  28. if(rowcount<16)
  29. return;
  30. }
  31. }

双击tableview将数据包解析的结果显示在treeview和textedit中:

  1. void MainWindow::on_tableView_doubleClicked(const QModelIndex &index)
  2. {
  3. int row=index.row();
  4. QString src_mac,dest_mac;
  5. char* buf=(char*)malloc(108*sizeof(char));
  6. sprintf(buf,"%02x-%02x-%02x-%02x-%02x-%02x",alldatapkt[row]->ethh->src[0],alldatapkt[row]->ethh->src[1],alldatapkt[row]->ethh->src[2],alldatapkt[row]->ethh->src[3],alldatapkt[row]->ethh->src[4],alldatapkt[row]->ethh->src[5]);
  7. src_mac=QString(QLatin1String(buf));
  8. sprintf(buf,"%02x-%02x-%02x-%02x-%02x-%02x",alldatapkt[row]->ethh->dest[0],alldatapkt[row]->ethh->dest[1],alldatapkt[row]->ethh->dest[2],alldatapkt[row]->ethh->dest[3],alldatapkt[row]->ethh->dest[4],alldatapkt[row]->ethh->dest[5]);
  9. dest_mac=QString(QLatin1String(buf));
  10. ui->data->setText("");
  11. int i=0,j = 0,rowcount;char ch;
  12. char tempbuf[8];strcpy(tempbuf,"");strcpy(buf,"");
  13. int size_pkt=alldatapkt[row]->len;u_char* pkt=datavec[row];
  14. for(i= 0;i<size_pkt;i+=16)
  15. {
  16. sprintf(tempbuf,"%04x:",i);
  17. strcat(buf,tempbuf);
  18. rowcount= (size_pkt-i) > 16 ? 16 : (size_pkt-i);
  19. for(j = 0; j < rowcount; j++){
  20. sprintf(tempbuf,"%02x ",pkt[i+j]);strcat(buf,tempbuf);
  21. }
  22. for(j=rowcount;j<16;j++){
  23. strcpy(tempbuf," ");strcat(buf,tempbuf);
  24. }
  25. for(j = 0; j < rowcount; j++){
  26. ch = pkt[i+j];
  27. ch = isprint(ch) ? ch : '.';
  28. sprintf(tempbuf,"%c ",ch);
  29. strcat(buf,tempbuf);
  30. }
  31. strcat(buf,"\n");
  32. ui->data->append(buf);
  33. strcpy(buf,"");
  34. if(rowcount<16)
  35. break;
  36. }
  37. QString h="接受到的第"+QString::number(row+1)+"个数据包";
  38. QStandardItem *head=new QStandardItem(h);
  39. QStandardItem *ethdata=new QStandardItem("链路层数据");
  40. QStandardItem *arpdata=new QStandardItem("ARP协议头");
  41. QStandardItem *ipdata=new QStandardItem("IP协议头");
  42. QStandardItem *tcpdata=new QStandardItem("TCP协议头");
  43. QStandardItem *udpdata=new QStandardItem("UDP协议头");
  44. QStandardItem *icmpdata=new QStandardItem("ICMP协议头");
  45. treeModel->setItem(0,head);
  46. head->setChild(0,ethdata);
  47. ethdata->setChild(0,new QStandardItem("源MAC:"+src_mac));
  48. ethdata->setChild(1,new QStandardItem("目的MAC:"+dest_mac));
  49. sprintf(tempbuf,"0x%04x",alldatapkt[row]->ethh->type);
  50. ethdata->setChild(2,new QStandardItem("类型:"+QString(QLatin1String(tempbuf))));
  51. QModelIndex current_index;
  52. switch (alldatapkt[row]->ethh->type) {
  53. case 0x0806:
  54. head->setChild(1,arpdata);
  55. arpdata->setChild(0,new QStandardItem("硬件类型:"+QString::number(alldatapkt[row]->arph->ar_hrd)));
  56. arpdata->setChild(1,new QStandardItem("协议类型:"+QString::number(alldatapkt[row]->arph->ar_pro)));
  57. arpdata->setChild(2,new QStandardItem("硬件地址长度:"+QString::number(alldatapkt[row]->arph->ar_hln)));
  58. arpdata->setChild(3,new QStandardItem("协议地址长度:"+QString::number(alldatapkt[row]->arph->ar_pln)));
  59. sprintf(buf,"%0d.%d.%d.%d",alldatapkt[row]->arph->ar_srcip[0],alldatapkt[row]->arph->ar_srcip[1],alldatapkt[row]->arph->ar_srcip[2],alldatapkt[row]->arph->ar_srcip[3]);
  60. arpdata->setChild(4,new QStandardItem("发送方IP:"+QString(QLatin1String(buf))));
  61. sprintf(buf,"%0d.%d.%d.%d",alldatapkt[row]->arph->ar_destip[0],alldatapkt[row]->arph->ar_destip[1],alldatapkt[row]->arph->ar_destip[2],alldatapkt[row]->arph->ar_destip[3]);
  62. arpdata->setChild(5,new QStandardItem("接受方IP:"+QString(QLatin1String(buf))));
  63. break;
  64. case 0x0800:
  65. head->setChild(1,ipdata);
  66. ipdata->setChild(0,new QStandardItem("版本号:"+QString::number(alldatapkt[row]->iph->version)));
  67. ipdata->setChild(1,new QStandardItem("头部长度:"+QString::number(alldatapkt[row]->iph->ihl)));
  68. ipdata->setChild(2,new QStandardItem("服务类型TOS:"+QString::number(alldatapkt[row]->iph->tos)));
  69. ipdata->setChild(3,new QStandardItem("总长度:"+QString::number(alldatapkt[row]->iph->tlen)));
  70. sprintf(tempbuf,"0x%04x",alldatapkt[row]->iph->id);
  71. ipdata->setChild(4,new QStandardItem("标识:"+QString(QLatin1String(tempbuf))));
  72. ipdata->setChild(5,new QStandardItem("位偏移:"+QString::number(alldatapkt[row]->iph->frag_off)));
  73. ipdata->setChild(6,new QStandardItem("生存时间TTL:"+QString::number(alldatapkt[row]->iph->ttl)));
  74. ipdata->setChild(7,new QStandardItem("协议:"+QString::number(alldatapkt[row]->iph->proto)));
  75. ipdata->setChild(8,new QStandardItem("头部校验和:"+QString::number(alldatapkt[row]->iph->check)));
  76. current_index=tableModel->index(row,4);
  77. ipdata->setChild(9,new QStandardItem("源IP:"+tableModel->data(current_index).toString()));
  78. current_index=tableModel->index(row,5);
  79. ipdata->setChild(10,new QStandardItem("目的IP:"+tableModel->data(current_index).toString()));
  80. switch (alldatapkt[row]->iph->proto) {
  81. case PROTO_TCP:
  82. head->setChild(2,tcpdata);
  83. tcpdata->setChild(0,new QStandardItem("源端口:"+QString::number(alldatapkt[row]->tcph->sport)));
  84. tcpdata->setChild(1,new QStandardItem("目的端口:"+QString::number(alldatapkt[row]->tcph->dport)));
  85. tcpdata->setChild(2,new QStandardItem("序列号:"+QString::number(alldatapkt[row]->tcph->seq)));
  86. tcpdata->setChild(3,new QStandardItem("确认序列号:"+QString::number(alldatapkt[row]->tcph->ack_seq)));
  87. tcpdata->setChild(4,new QStandardItem("窗口大小:"+QString::number(alldatapkt[row]->tcph->window)));
  88. tcpdata->setChild(5,new QStandardItem("SYN:"+QString::number(alldatapkt[row]->tcph->syn)));
  89. tcpdata->setChild(6,new QStandardItem("ACK:"+QString::number(alldatapkt[row]->tcph->ack)));
  90. tcpdata->setChild(7,new QStandardItem("FIN:"+QString::number(alldatapkt[row]->tcph->fin)));
  91. tcpdata->setChild(8,new QStandardItem("校验和:"+QString::number(alldatapkt[row]->tcph->check)));
  92. tcpdata->setChild(9,new QStandardItem("紧急指针:"+QString::number(alldatapkt[row]->tcph->urg_ptr)));
  93. break;
  94. case PROTO_UDP:
  95. head->setChild(2,udpdata);
  96. udpdata->setChild(0,new QStandardItem("源端口:"+QString::number(alldatapkt[row]->udph->sport)));
  97. udpdata->setChild(1,new QStandardItem("目的端口:"+QString::number(alldatapkt[row]->udph->dport)));
  98. udpdata->setChild(2,new QStandardItem("数据报长度:"+QString::number(alldatapkt[row]->udph->len)));
  99. udpdata->setChild(3,new QStandardItem("校验和:"+QString::number(alldatapkt[row]->udph->check)));
  100. break;
  101. case PROTO_ICMP:
  102. head->setChild(2,icmpdata);
  103. icmpdata->setChild(0,new QStandardItem("类型:"+QString::number(alldatapkt[row]->icmph->type)));
  104. icmpdata->setChild(1,new QStandardItem("代码:"+QString::number(alldatapkt[row]->icmph->code)));
  105. icmpdata->setChild(2,new QStandardItem("序列号:"+QString::number(alldatapkt[row]->icmph->seq)));
  106. icmpdata->setChild(3,new QStandardItem("校验和:"+QString::number(alldatapkt[row]->icmph->chksum)));
  107. break;
  108. default:
  109. break;
  110. }
  111. break;
  112. default:
  113. break;
  114. }
  115. }

接下来介绍数据包协议分析的实现:

在上面的代码中可以看到,在抓包线程的运行函数中很关键的一步是调用analyze类中的analyze_frame函数进行协议分析。

各协议头数据结构定义:

  1. //Mac帧头 占14个字节
  2. typedef struct _ethhdr
  3. {
  4. u_char dest[6]; //6个字节 目标地址
  5. u_char src[6]; //6个字节 源地址
  6. u_short type; //2个字节 类型
  7. }ethhdr;
  8. //ARP头
  9. typedef struct _arphdr
  10. {
  11. u_short ar_hrd; //硬件类型
  12. u_short ar_pro; //协议类型
  13. u_char ar_hln; //硬件地址长度
  14. u_char ar_pln; //协议地址长度
  15. u_short ar_op; //操作码,1为请求 2为回复
  16. u_char ar_srcmac[6]; //发送方MAC
  17. u_char ar_srcip[4]; //发送方IP
  18. u_char ar_destmac[6]; //接收方MAC
  19. u_char ar_destip[4]; //接收方IP
  20. }arphdr;
  21. //定义IP头
  22. typedef struct _iphdr
  23. {
  24. #if defined(LITTLE_ENDIAN)
  25. u_char ihl:4;
  26. u_char version:4;
  27. #elif defined(BIG_ENDIAN)
  28. u_char version:4;
  29. u_char ihl:4;
  30. #endif
  31. u_char tos; //TOS 服务类型
  32. u_short tlen; //包总长 u_short占两个字节
  33. u_short id; //标识
  34. u_short frag_off; //片位移
  35. u_char ttl; //生存时间
  36. u_char proto; //协议
  37. u_short check; //校验和
  38. u_int saddr; //源地址
  39. u_int daddr; //目的地址
  40. u_int op_pad; //选项等
  41. }iphdr;
  42. //定义TCP头
  43. typedef struct _tcphdr
  44. {
  45. u_short sport; //源端口地址 16位
  46. u_short dport; //目的端口地址 16位
  47. u_int seq; //序列号 32位
  48. u_int ack_seq; //确认序列号
  49. #if defined(LITTLE_ENDIAN)
  50. u_short res1:4,
  51. doff:4,
  52. fin:1,
  53. syn:1,
  54. rst:1,
  55. psh:1,
  56. ack:1,
  57. urg:1,
  58. ece:1,
  59. cwr:1;
  60. #elif defined(BIG_ENDIAN)
  61. u_short doff:4,
  62. res1:4,
  63. cwr:1,
  64. ece:1,
  65. urg:1,
  66. ack:1,
  67. psh:1,
  68. rst:1,
  69. syn:1,
  70. fin:1;
  71. #endif
  72. u_short window; //窗口大小 16位
  73. u_short check; //校验和 16位
  74. u_short urg_ptr; //紧急指针 16位
  75. u_int opt; //选项
  76. }tcphdr;
  77. //定义UDP头
  78. typedef struct _udphdr
  79. {
  80. u_short sport; //源端口 16位
  81. u_short dport; //目的端口 16位
  82. u_short len; //数据报长度 16位
  83. u_short check; //校验和 16位
  84. }udphdr;
  85. //定义ICMP
  86. typedef struct _icmphdr
  87. {
  88. u_char type; //8位 类型
  89. u_char code; //8位 代码
  90. u_char seq; //序列号 8位
  91. u_char chksum; //8位校验和
  92. }icmphdr;
  93. //对各种包进行计数
  94. typedef struct _pktcount
  95. {
  96. int n_ip;
  97. int n_arp;
  98. int n_tcp;
  99. int n_udp;
  100. int n_icmp;
  101. int n_http;
  102. int n_other;
  103. int n_sum;
  104. _pktcount(){
  105. n_ip=0;
  106. n_arp=0;
  107. n_tcp=0;
  108. n_udp=0;
  109. n_icmp=0;
  110. n_http=0;
  111. n_other=0;
  112. n_sum=0;
  113. }
  114. }pktcount;
  115. //要保存的数据结构
  116. typedef struct _datapkt
  117. {
  118. char pktType[8]; //包类型
  119. int time[6]; //时间
  120. int len; //长度
  121. ethhdr* ethh; //链路层包头
  122. arphdr* arph; //ARP包头
  123. iphdr* iph; //IP包头
  124. icmphdr* icmph; //ICMP包头
  125. udphdr* udph; //UDP包头
  126. tcphdr* tcph; //TCP包头
  127. bool isHttp;
  128. void *apph; //应用层包头
  129. }datapkt;
  130. #endif

解析数据包函数:

  1. #include "protocol.h"
  2. #include <QDebug>
  3. #include "mainwindow.h"
  4. #include <winsock2.h>
  5. #include <analyze.h>
  6. ///*pkt为网络中捕获的包,data为要存为本机上的数据*
  7. ///*分析链路层*/
  8. int analyze_frame(const u_char * pkt,datapkt * data,pktcount* npacket)
  9. {
  10. int i;
  11. ethhdr *ethh = (ethhdr*)pkt;
  12. data->ethh = (ethhdr*)malloc(sizeof(ethhdr));
  13. if(NULL == data->ethh)
  14. return -1;
  15. for(i=0;i<6;i++)
  16. {
  17. data->ethh->dest[i] = ethh->dest[i];
  18. data->ethh->src[i] = ethh->src[i];
  19. }
  20. npacket->n_sum++;
  21. /*由于网络字节顺序原因,需要对齐*/
  22. data->ethh->type = ntohs(ethh->type);
  23. //处理ARP还是IP包?
  24. switch(data->ethh->type)
  25. {
  26. case 0x0806:
  27. return analyze_arp((u_char*)pkt+14,data,npacket); //mac 头大小为14个字节
  28. break;
  29. case 0x0800:
  30. return analyze_ip((u_char*)pkt+14,data,npacket);
  31. break;
  32. default:
  33. npacket->n_other++;
  34. return -1;
  35. break;
  36. }
  37. return 1;
  38. }
  39. ///*分析网络层:ARP*/
  40. int analyze_arp(const u_char* pkt,datapkt *data,pktcount* npacket)
  41. {
  42. int i;
  43. arphdr *arph = (arphdr*)pkt;
  44. data->arph = (arphdr*)malloc(sizeof(arphdr));
  45. if(NULL == data->arph)
  46. return -1;
  47. //复制IP及MAC
  48. for(i=0;i<6;i++)
  49. {
  50. if(i<4)
  51. {
  52. data->arph->ar_destip[i] = arph->ar_destip[i];
  53. data->arph->ar_srcip[i] = arph->ar_srcip[i];
  54. }
  55. data->arph->ar_destmac[i] = arph->ar_destmac[i];
  56. data->arph->ar_srcmac[i]= arph->ar_srcmac[i];
  57. }
  58. npacket->n_arp++;
  59. data->arph->ar_hln = arph->ar_hln;
  60. data->arph->ar_hrd = ntohs(arph->ar_hrd);
  61. data->arph->ar_op = ntohs(arph->ar_op);
  62. data->arph->ar_pln = arph->ar_pln;
  63. data->arph->ar_pro = ntohs(arph->ar_pro);
  64. // qDebug(""+data->arph->ar_hln);
  65. strcpy(data->pktType,"ARP");
  66. return 1;
  67. }
  68. ///*分析网络层:IP*/
  69. int analyze_ip(const u_char* pkt,datapkt *data,pktcount *npacket)
  70. {
  71. int i;
  72. iphdr *iph = (iphdr*)pkt;
  73. data->iph = (iphdr*)malloc(sizeof(iphdr));
  74. if(NULL == data->iph)
  75. return -1;
  76. data->iph->check = iph->check;
  77. npacket->n_ip++;
  78. /*for(i = 0;i<4;i++)
  79. {
  80. data->iph->daddr[i] = iph->daddr[i];
  81. data->iph->saddr[i] = iph->saddr[i];
  82. }*/
  83. data->iph->saddr = iph->saddr;
  84. data->iph->daddr = iph->daddr;
  85. data->iph->frag_off = iph->frag_off;
  86. data->iph->id = iph->id;
  87. data->iph->proto = iph->proto;
  88. data->iph->tlen = ntohs(iph->tlen);
  89. data->iph->tos = iph->tos;
  90. data->iph->ttl = iph->ttl;
  91. data->iph->ihl = iph->ihl;
  92. data->iph->version = iph->version;
  93. //data->iph->ver_ihl= iph->ver_ihl;
  94. data->iph->op_pad = iph->op_pad;
  95. int iplen = iph->ihl*4; //ip头长度
  96. switch(iph->proto)
  97. {
  98. case PROTO_ICMP:
  99. return analyze_icmp((u_char*)iph+iplen,data,npacket);
  100. break;
  101. case PROTO_TCP:
  102. return analyze_tcp((u_char*)iph+iplen,data,npacket);
  103. break;
  104. case PROTO_UDP:
  105. return analyze_udp((u_char*)iph+iplen,data,npacket);
  106. break;
  107. default :
  108. return-1;
  109. break;
  110. }
  111. return 1;
  112. }
  113. ///*分析传输层:ICMP*/
  114. int analyze_icmp(const u_char* pkt,datapkt *data,pktcount *npacket)
  115. {
  116. icmphdr* icmph = (icmphdr*)pkt;
  117. data->icmph = (icmphdr*)malloc(sizeof(icmphdr));
  118. if(NULL == data->icmph)
  119. return -1;
  120. data->icmph->chksum = icmph->chksum;
  121. data->icmph->code = icmph->code;
  122. data->icmph->seq =icmph->seq;
  123. data->icmph->type = icmph->type;
  124. strcpy(data->pktType,"ICMP");
  125. npacket->n_icmp++;
  126. return 1;
  127. }
  128. ///*分析传输层:TCP*/
  129. int analyze_tcp(const u_char* pkt,datapkt *data,pktcount *npacket)
  130. {
  131. tcphdr *tcph = (tcphdr*)pkt;
  132. data->tcph = (tcphdr*)malloc(sizeof(tcphdr));
  133. if(NULL == data->tcph)
  134. return -1;
  135. data->tcph->ack_seq = tcph->ack_seq;
  136. data->tcph->check = tcph->check;
  137. data->tcph->doff = tcph->doff;
  138. data->tcph->res1 = tcph->res1;
  139. data->tcph->cwr = tcph->cwr;
  140. data->tcph->ece = tcph->ece;
  141. data->tcph->urg = tcph->urg;
  142. data->tcph->ack = tcph->ack;
  143. data->tcph->psh = tcph->psh;
  144. data->tcph->rst = tcph->rst;
  145. data->tcph->syn = tcph->syn;
  146. data->tcph->fin = tcph->fin;
  147. //data->tcph->doff_flag = tcph->doff_flag;
  148. data->tcph->dport = ntohs(tcph->dport);
  149. data->tcph->seq = tcph->seq;
  150. data->tcph->sport = ntohs(tcph->sport);
  151. data->tcph->urg_ptr = tcph->urg_ptr;
  152. data->tcph->window= tcph->window;
  153. data->tcph->opt = tcph->opt;
  154. if(ntohs(tcph->dport) == 80 || ntohs(tcph->sport)==80)
  155. {
  156. npacket->n_http++;
  157. strcpy(data->pktType,"HTTP");
  158. }
  159. else{
  160. npacket->n_tcp++;
  161. strcpy(data->pktType,"TCP");
  162. }
  163. return 1;
  164. }
  165. /*分析传输层:UDP*/
  166. int analyze_udp(const u_char* pkt,datapkt *data,pktcount *npacket)
  167. {
  168. udphdr* udph = (udphdr*)pkt;
  169. data->udph = (udphdr*)malloc(sizeof(udphdr));
  170. if(NULL == data->udph )
  171. return -1;
  172. data->udph->check = udph->check;
  173. data->udph->dport = ntohs(udph->dport);
  174. data->udph->len = ntohs(udph->len);
  175. data->udph->sport = ntohs(udph->sport);
  176. strcpy(data->pktType,"UDP");
  177. npacket->n_udp++;
  178. return 1;
  179. }

运行结果示例:

IP数据包

UDP数据包

TCP数据包

ARP数据包

ICMP数据数据包

上传的附件 cloud_download sniffer.7z ( 1.04mb, 6次下载 )
error_outline 下载需要9点积分

发送私信

成功其实很简单,就是当你坚持不住的时候,再坚持一下

10
文章数
8
评论数
最近文章
eject