#ifndef CAPTHREAD_H
#define CAPTHREAD_H

#include <QThread>
#include <winsock2.h>
#include "pcap.h"
#include <QVector>

#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Ws2_32.lib")

#define LINE_LEN 16
#define MAX_ADDR_LEN 16

struct EtherHeader {
    u_char ether_dhost[6];		// 目标MAC地址
    u_char ether_shost[6];		// 源MAC地址
    u_short ether_type;			// 以太网类型
};
struct IpAddress {
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
};
struct IpHeader {
    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地址
};
struct TcpHeader {
    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;		// 紧急指针
};
struct UdpHeader {
    u_short sport;				// 源端口
    u_short dport;				// 目标端口
    u_short datalen;			// UDP数据长度
    u_short checksum;			// 校验和
};
struct IcmpHeader {
    u_char type;				// ICMP类型
    u_char code;				// 代码
    u_short checksum;			// 校验和
    u_short identification;		// 标识
    u_short sequence;			// 序列号
    u_long timestamp;			// 时间戳
};
struct ArpHeader {
    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];		// 目的方协议地址
};

struct Packet {
    QString time;
    QString data;
    u_int len;
    EtherHeader ether_header;
    IpHeader ip_header;
    TcpHeader tcp_header;
    UdpHeader udp_header;
    IcmpHeader icmp_header;
    ArpHeader arp_header;
    QString protocol;
};

class CapThread : public QThread {
    Q_OBJECT
public:
    explicit CapThread(pcap *pcap, QObject *parent = nullptr);
    void setPacketList(QList<Packet> *p){p->clear();packet_list=p;}
    pcap *pcap{0};
    QList<Packet> *packet_list;
    Packet packet;

private:
    void tcp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content);
    void udp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content);
    void icmp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content);
    void arp_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content);
    void ip_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content);
    void ethernet_protocol_packet_handle(u_char *arg, const struct pcap_pkthdr *pkt_header, const u_char *pkt_content);

protected:
    void run();

signals:
    void newPacket();

public slots:
};

#endif // CAPTHREAD_H
