325 lines
12 KiB
C++
325 lines
12 KiB
C++
#include "capthread.h"
|
|
#include <QDateTime>
|
|
#include <QDebug>
|
|
|
|
CapThread::CapThread(struct pcap *pcap, QObject *parent) : QThread(parent), pcap(pcap) {
|
|
connect(this, &QThread::finished, this, &QThread::deleteLater);
|
|
}
|
|
|
|
void CapThread::run() {
|
|
pcap_pkthdr *header;
|
|
const u_char *pkt_data;
|
|
|
|
// qDebug("The program is working......\n");
|
|
// qDebug("The capture file is saving as 'data.txt'\n");
|
|
// qDebug("You can input 'ctrl + C' to stop the program\n");
|
|
int res;
|
|
while((res = pcap_next_ex(pcap, &header, &pkt_data)) >= 0) {
|
|
if (res == 0) continue; //超时
|
|
packet.time = QDateTime::fromSecsSinceEpoch(header->ts.tv_sec).toString("yy-MM-dd HH:mm:ss.")+QString::number(header->ts.tv_usec);
|
|
packet.len = header->len;
|
|
//输出编号、时间戳和包长度
|
|
qDebug("=======================\n");
|
|
qDebug()<<packet.time<<" len:"<<header->caplen<<"/"<<header->len;
|
|
QString data_str;
|
|
char line[LINE_LEN + 1];
|
|
int l = 0;
|
|
for(uint i=0; i < header->caplen; i++) {
|
|
data_str.append(QString::asprintf("%.2x ", pkt_data[i]));
|
|
if(i > 13) {
|
|
if(isgraph(pkt_data[i]) || pkt_data[i] == ' ') line[l] = pkt_data[i];
|
|
else line[l] = '.';
|
|
if(l==15) {
|
|
line[16] = '\0';
|
|
data_str.append(" ");
|
|
data_str.append(line);
|
|
data_str.append("\n");
|
|
memset(line, 0, LINE_LEN);
|
|
l = 0;
|
|
} else l++;
|
|
} else if(i == 13) {
|
|
data_str.append("\n");
|
|
}
|
|
}
|
|
packet.data = data_str;
|
|
qDebug()<<packet.data.toUtf8().constData();
|
|
|
|
//分析数据包
|
|
//ethernet_protocol_packet_handle(NULL, header, pkt_data);
|
|
|
|
//packet_list->append(packet);
|
|
//emit newPacket();
|
|
}
|
|
qDebug("Error reading the packets: %s\n", pcap_geterr(pcap));
|
|
|
|
}
|
|
|
|
// TCP协议处理
|
|
//u_short sport;
|
|
//u_short dport;
|
|
//u_int sequence; // 序列码
|
|
//u_int ack; // 回复码
|
|
//u_char hdrLen; // 首部长度保留字
|
|
//u_char flags; // 标志
|
|
//u_short windows; // 窗口大小
|
|
//u_short checksum; // 校验和
|
|
//u_short urgent_pointer; // 紧急指针
|
|
void CapThread::tcp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content) {
|
|
packet.tcp_header = *(TcpHeader*) (pkt_content + 14 + 20);
|
|
// qDebug("===================TCP Protocol=================\n");
|
|
|
|
// qDebug("Source Port: %i\n", ntohs(tcp_protocol->sport));
|
|
// qDebug("Destination Port: %i\n", ntohs(tcp_protocol->dport));
|
|
// qDebug("Sequence number: %d\n", ntohl(tcp_protocol->sequence));
|
|
// qDebug("Acknowledgment number: %d\n", ntohl(tcp_protocol->ack));
|
|
// qDebug("Header Length: %d\n", (tcp_protocol->hdrLen >> 4) * 4);
|
|
// qDebug("Flags: 0x%.3x ", tcp_protocol->flags);
|
|
// if (tcp_protocol->flags & 0x08) qDebug("(PSH)");
|
|
// if (tcp_protocol->flags & 0x10) qDebug("(ACK)");
|
|
// if (tcp_protocol->flags & 0x02) qDebug("(SYN)");
|
|
// if (tcp_protocol->flags & 0x20) qDebug("(URG)");
|
|
// if (tcp_protocol->flags & 0x01) qDebug("(FIN)");
|
|
// if (tcp_protocol->flags & 0x04) qDebug("(RST)");
|
|
// qDebug("\n");
|
|
// qDebug("Windows Size: %i\n", ntohs(tcp_protocol->windows));
|
|
// qDebug("Checksum: 0x%.4x\n", ntohs(tcp_protocol->checksum));
|
|
// qDebug("Urgent Pointer: %i\n", ntohs(tcp_protocol->urgent_pointer));
|
|
}
|
|
|
|
// UDP协议处理
|
|
//u_short sport; // 源端口
|
|
//u_short dport; // 目标端口
|
|
//u_short datalen; // UDP数据长度
|
|
//u_short checksum; // 校验和
|
|
void CapThread::udp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content) {
|
|
packet.udp_header = *(UdpHeader*)(pkt_content + 14 + 20);
|
|
// qDebug("===================UDP Protocol=================\n");
|
|
// qDebug("Source Port: %i\n", ntohs(udp_protocol->sport));
|
|
// qDebug("Destination Port: %i\n", ntohs(udp_protocol->dport));
|
|
// qDebug("Datalen: %i\n", ntohs(udp_protocol->datalen));
|
|
// qDebug("Checksum: 0x%.4x\n", ntohs(udp_protocol->checksum));
|
|
}
|
|
|
|
// ICMP协议处理
|
|
//u_char type; // ICMP类型
|
|
//u_char code; // 代码
|
|
//u_short checksum; // 校验和
|
|
//u_short identification; // 标识
|
|
//u_short sequence; // 序列号
|
|
//u_long timestamp; // 时间戳
|
|
void CapThread::icmp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content) {
|
|
packet.icmp_header = *(IcmpHeader*)(pkt_content + 14 + 20);
|
|
// qDebug("==================ICMP Protocol=================\n");
|
|
// qDebug("Type: %d ", icmp_protocol->type);
|
|
// switch (icmp_protocol->type)
|
|
// {
|
|
// case 8:
|
|
// qDebug("(request)\n");
|
|
// break;
|
|
// case 0:
|
|
// qDebug("(reply)\n");
|
|
// break;
|
|
// default:
|
|
// qDebug("\n");
|
|
// break;
|
|
// }
|
|
// qDebug("Code: %d\n", icmp_protocol->code);
|
|
// qDebug("CheckSum: 0x%.4x\n", ntohs(icmp_protocol->checksum));
|
|
// qDebug("Identification: 0x%.4x\n", ntohs(icmp_protocol->identification));
|
|
// qDebug("Sequence: 0x%.4x\n", ntohs(icmp_protocol->sequence));
|
|
}
|
|
|
|
// ARP协议处理
|
|
//u_short hardware_type; // 格式化的硬件地址
|
|
//u_short protocol_type; // 协议地址格式
|
|
//u_char hardware_length; // 硬件地址长度
|
|
//u_char protocol_length; // 协议地址长度
|
|
//u_short operation_code; // 操作码
|
|
//u_char source_ethernet_address[6]; // 发送者硬件地址
|
|
//u_char source_ip_address[4]; // 发送者协议地址
|
|
//u_char destination_ethernet_address[6]; // 目的方硬件地址
|
|
//u_char destination_ip_address[4]; // 目的方协议地址
|
|
void CapThread::arp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content) {
|
|
packet.arp_header = *(ArpHeader*)(pkt_content + 14);
|
|
// qDebug("==================ARP Protocol==================\n");
|
|
// qDebug("Hardware Type: ");
|
|
// switch (ntohs(arp_protocol->hardware_type))
|
|
// {
|
|
// case 1:
|
|
// qDebug("Ethernet");
|
|
// break;
|
|
// default:
|
|
// break;
|
|
// }
|
|
// qDebug(" (%d)\n", ntohs(arp_protocol->hardware_type));
|
|
// qDebug("Protocol Type: \n");
|
|
// switch (ntohs(arp_protocol->protocol_type))
|
|
// {
|
|
// case 0x0800:
|
|
// qDebug("%s", "IP");
|
|
// break;
|
|
// case 0x0806:
|
|
// qDebug("%s", "ARP");
|
|
// break;
|
|
// case 0x0835:
|
|
// qDebug("%s", "RARP");
|
|
// break;
|
|
// default:
|
|
// qDebug("%s", "Unknown Protocol");
|
|
// break;
|
|
// }
|
|
// qDebug(" (0x%04x)\n", ntohs(arp_protocol->protocol_type));
|
|
// qDebug("Hardware Length: %d\n", arp_protocol->hardware_length);
|
|
// qDebug("Protocol Length: %d\n", arp_protocol->protocol_length);
|
|
// qDebug("Operation Code: ");
|
|
// switch (ntohs(arp_protocol->operation_code))
|
|
// {
|
|
// case 1:
|
|
// qDebug("request");
|
|
// break;
|
|
// case 2:
|
|
// qDebug("reply");
|
|
// break;
|
|
// default:
|
|
// break;
|
|
// }
|
|
// qDebug(" (%i)\n", ntohs(arp_protocol->operation_code));
|
|
}
|
|
|
|
// IP协议处理
|
|
//u_char version_hlen; // 首部长度 版本
|
|
//u_char tos; // 服务质量
|
|
//u_short tlen; // 总长度
|
|
//u_short identification; // 身份识别
|
|
//u_short flags_offset; // 标识 分组偏移
|
|
//u_char ttl; // 生命周期
|
|
//u_char proto; // 协议类型
|
|
//u_short checksum; // 包头测验码
|
|
//u_int saddr; // 源IP地址
|
|
//u_int daddr; // 目的IP地址
|
|
void CapThread::ip_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content) {
|
|
sockaddr_in source, dest;
|
|
char sourceIP[MAX_ADDR_LEN], destIP[MAX_ADDR_LEN];
|
|
|
|
auto ip_protocol = (IpHeader*)(pkt_content + 14);
|
|
source.sin_addr.s_addr = ip_protocol->saddr;
|
|
dest.sin_addr.s_addr = ip_protocol->daddr;
|
|
strncpy(sourceIP, inet_ntoa(source.sin_addr), MAX_ADDR_LEN);
|
|
strncpy(destIP, inet_ntoa(dest.sin_addr), MAX_ADDR_LEN);
|
|
|
|
packet.ip_header = *ip_protocol;
|
|
|
|
// qDebug("===================IP Protocol==================\n");
|
|
// qDebug("Version: %d\n", ip_protocol->version_hlen >> 4);
|
|
// qDebug("Header Length: %d bytes\n", (ip_protocol->version_hlen & 0x0f) * 4);
|
|
// qDebug("Tos: %d\n", ip_protocol->tos);
|
|
// qDebug("Total Length: %d\n", ntohs(ip_protocol->tlen));
|
|
// qDebug("Identification: 0x%.4x (%i)\n", ntohs(ip_protocol->identification), ntohs(ip_protocol->identification));
|
|
// qDebug("Flags: %d\n", ntohs(ip_protocol->flags_offset) >> 13);
|
|
// qDebug("---Reserved bit: %d\n", (ntohs(ip_protocol->flags_offset) & 0x8000) >> 15);
|
|
// qDebug("---Don't fragment: %d\n", (ntohs(ip_protocol->flags_offset) & 0x4000) >> 14);
|
|
// qDebug("---More fragment: %d\n", (ntohs(ip_protocol->flags_offset) & 0x2000) >> 13);
|
|
// qDebug("Fragment offset: %d\n", ntohs(ip_protocol->flags_offset) & 0x1fff);
|
|
// qDebug("Time to live: %d\n", ip_protocol->ttl);
|
|
// qDebug("Protocol Type: ");
|
|
switch (ip_protocol->proto)
|
|
{
|
|
case 1:
|
|
// qDebug("ICMP");
|
|
packet.protocol = "ICMP";
|
|
break;
|
|
case 6:
|
|
// qDebug("TCP");
|
|
packet.protocol = "TCP";
|
|
break;
|
|
case 17:
|
|
// qDebug("UDP");
|
|
packet.protocol = "UDP";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
// qDebug(" (%d)\n", ip_protocol->proto);
|
|
// qDebug("Header checkSum: 0x%.4x\n", ntohs(ip_protocol->checksum));
|
|
// qDebug("Source: %s\n", sourceIP);
|
|
// qDebug("Destination: %s\n", destIP);
|
|
|
|
if (ip_protocol->proto == htons(0x0600))
|
|
tcp_protocol_packet_handle(arg, pkt_header, pkt_content);
|
|
else if (ip_protocol->proto == htons(0x1100))
|
|
udp_protocol_packet_handle(arg, pkt_header, pkt_content);
|
|
else if (ip_protocol->proto == htons(0x0100))
|
|
icmp_protocol_packet_handle(arg, pkt_header, pkt_content);
|
|
}
|
|
// Ethernet协议处理
|
|
void CapThread::ethernet_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content) {
|
|
packet.ether_header = *(EtherHeader*)pkt_content;
|
|
u_short ethernet_type; //以太网类型
|
|
u_char *mac_string; //以太网地址
|
|
//获取以太网数据内容
|
|
ethernet_type = ntohs(packet.ether_header.ether_type);
|
|
|
|
// qDebug("==============Ethernet Protocol=================\n");
|
|
|
|
// //以太网目标地址
|
|
// mac_string = ethernet_protocol->ether_dhost;
|
|
|
|
// qDebug("Destination Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
// *mac_string,
|
|
// *(mac_string + 1),
|
|
// *(mac_string + 2),
|
|
// *(mac_string + 3),
|
|
// *(mac_string + 4),
|
|
// *(mac_string + 5));
|
|
|
|
// //以太网源地址
|
|
// mac_string = ethernet_protocol->ether_shost;
|
|
|
|
// qDebug("Source Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
// *mac_string,
|
|
// *(mac_string + 1),
|
|
// *(mac_string + 2),
|
|
// *(mac_string + 3),
|
|
// *(mac_string + 4),
|
|
// *(mac_string + 5));
|
|
|
|
// qDebug("Ethernet type: ");
|
|
switch (ethernet_type)
|
|
{
|
|
case 0x0800:
|
|
// qDebug("%s", "IP");
|
|
break;
|
|
case 0x0806:
|
|
// qDebug("%s", "ARP");
|
|
packet.protocol = "ARP";
|
|
break;
|
|
case 0x0835:
|
|
// qDebug("%s", "RARP");
|
|
// packet_data.setRarp_flag(true);
|
|
break;
|
|
default:
|
|
// qDebug("%s", "Unknown Protocol");
|
|
packet.protocol = "Unknown Protocol";
|
|
break;
|
|
}
|
|
// qDebug(" (0x%04x)\n", ethernet_type);
|
|
|
|
switch (ethernet_type)
|
|
{
|
|
case 0x0800:
|
|
ip_protocol_packet_handle(arg, pkt_header, pkt_content);
|
|
break;
|
|
case 0x0806:
|
|
arp_protocol_packet_handle(arg, pkt_header, pkt_content);
|
|
break;
|
|
// case 0x0835:
|
|
// qDebug("==============RARP Protocol=================\n");
|
|
// qDebug("RARP\n");
|
|
// break;
|
|
// default:
|
|
// qDebug("==============Unknown Protocol==============\n");
|
|
// qDebug("Unknown Protocol\n");
|
|
// break;
|
|
}
|
|
}
|