当前位置:网站首页>【QT】QT项目:自制Wireshark

【QT】QT项目:自制Wireshark

2022-08-10 01:26:00 Cappuccino-jay

一、项目总览

img

二、运行结果

img

img

img

三、项目源码

1、shark.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    capture.cpp \
    datapackage.cpp \
    main.cpp \
    mainwindow.cpp \
    readonlydelegate.cpp

HEADERS += \
    Format.h \
    capture.h \
    datapackage.h \
    mainwindow.h \
    readonlydelegate.h

FORMS += \
    mainwindow.ui

INCLUDEPATH += E:/QT/Code/QtPro/GitPro/Program/Network-capture/Network-capture/Include

LIBS += E:/QT/Code/QtPro/GitPro/Program/Network-capture/Network-capture/Lib/x64/wpcap.lib  #libws2_32
LIBS += E:/QT/Code/QtPro/GitPro/Program/Network-capture/Network-capture/Lib/x64/Packet.lib

# Default rules for deployment.
qnx: target.path = /tmp/$${
    TARGET}/bin
else: unix:!android: target.path = /opt/$${
    TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    src.qrc

2、capture.h

#ifndef CAPTURE_H
#define CAPTURE_H

#include <QThread>
#include <Format.h>
#include <QQueue>
#include "pcap.h"
#pragma comment(lib,"ws2_32.lib")
#include <QString>
#include "winsock2.h"
#include "datapackage.h"

class Capture : public QThread
{
    
     Q_OBJECT
public:
    Capture();
    bool setPointer(pcap_t *pointer);
    void setFlag();
    void resetFlag();
    int ethernetPackageHandle(const u_char *pkt_content,QString& info);
    int ipPackageHandle(const u_char *pkt_content,int&ipPackage);
    QString arpPackageHandle(const u_char *pkt_content);
    QString icmpPackageHandle(const u_char *pkt_content);
    int tcpPackageHandle(const u_char *pkt_content,QString &info,int ipPackage);
    int udpPackageHandle(const u_char *pkt_content,QString&info);
    QString dnsPackageHandle(const u_char *pkt_content);
protected:
    static QString byteToHex(u_char *str, int size);
    void run();

signals:
    void send(DataPackage data);

private:
    pcap_t *pointer;
    struct pcap_pkthdr*header;
    const u_char *pkt_data;
    time_t local_time_version_sec;
    struct tm local_time;
    char timeString[16];
    volatile bool isDone;// done flag
};

#endif // CAPTURE_H

3、capture.cpp

#include "capture.h"
#include <QDebug>
#include <QString>


Capture::Capture(){
    this->isDone = false;
    this->pointer = nullptr;
    this->header = nullptr;
    this->pkt_data = nullptr;
}
bool Capture::setPointer(pcap_t *pointer){
    this->pointer = pointer;
    if(pointer)
        return true;
    else return false;
}

void Capture::setFlag(){
    this->isDone = true;
}

void Capture::resetFlag(){
    this->isDone = false;
}

QString Capture::byteToHex(u_char *str, int size){
    QString res = "";
    for(int i = 0;i < size;i++){
        char one = str[i] >> 4;
        if(one >= 0x0A)
            one = one + 0x41 - 0x0A;
        else one = one + 0x30;
        char two = str[i] & 0xF;
        if(two >= 0x0A)
            two = two  + 0x41 - 0x0A;
        else two = two + 0x30;
        res.append(one);
        res.append(two);
    }
    return res;
}

void Capture::run(){
    unsigned int number_package = 0;
    while(true){
        if(isDone)
            break;
        int res = pcap_next_ex(pointer,&header,&pkt_data);
        if(res == 0)
            continue;
        local_time_version_sec = header->ts.tv_sec;
        localtime_s(&local_time,&local_time_version_sec);
        strftime(timeString,sizeof(timeString),"%H:%M:%S",&local_time);
        QString info = "";
        int type = ethernetPackageHandle(pkt_data,info);
        if(type){
            DataPackage data;
            int len = header->len;
            data.setPackageType(type);
            data.setTimeStamp(QString(timeString));
            data.setDataLength(len);
            data.setPackagePointer(pkt_data,len);
            data.setPackageInfo(info);
            if(data.pkt_content != nullptr){
                emit send(data);
                number_package++;
            }else continue;
        }
        else continue;
    }
    return;
}

int Capture::ethernetPackageHandle(const u_char *pkt_content,QString& info){
    ETHER_HEADER* ethernet;
    u_short ethernet_type;
    ethernet = (ETHER_HEADER*)pkt_content;
    ethernet_type = ntohs(ethernet->ether_type);

    switch(ethernet_type){
    case 0x0800:{// ip package
        int dataPackage = 0;
        int res = ipPackageHandle(pkt_content,dataPackage);
        switch (res) {
        case 1:{// icmp package
            info = icmpPackageHandle(pkt_content);
            return 2;
        }
        case 6:{// tcp package
            return tcpPackageHandle(pkt_content,info,dataPackage);

        }
        case 17:{ // udp package
            int type = udpPackageHandle(pkt_content,info);
            return type;
        }
        default:break;
        }
        break;
    }
    case 0x0806:{// arp package
        info = arpPackageHandle(pkt_content);
        return 1;
    }
    default:{// undefined package
        break;
    }
    }
    return 0;
}
// ip package
int Capture::ipPackageHandle(const u_char *pkt_content,int& ipPackage){
    /*
+------+-----+-----+
|   1  |  6  |  17 |
+------+-----+-----+
| ICMP | TCP | UDP |
+------+-----+-----+
*/
    IP_HEADER* ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    int protocol = ip->protocol;
    ipPackage = (htons(ip->total_length) - (ip->versiosn_head_length & 0x0F) * 4);
    return protocol;
}
// icmp package
/*
 * part of the protocol of type and code
 * if you need detail information, pls check the official documents
+------+------+------------------------------------------------+
| type | code |                   information                  |
+------+------+------------------------------------------------+
|  0   |   0  |     Echo response (ping command response)      |
+------+------+------------------------------------------------+
|      |   0  |             Network unreachable                |
+      +------+------------------------------------------------+
|      |   1  |             Host unreachable                   |
+      +------+------------------------------------------------+
|      |   2  |              Protocol unreachable              |
+      +------+------------------------------------------------+
|   3  |   3  |              Port unreachable                  |
+      +------+------------------------------------------------+
|      |   4  |    Fragmentation is required, but DF is set    |
+      +------+------------------------------------------------+
|      |   5  |        Source route selection failed           |
+      +------+------------------------------------------------+
|      |   6  |            Unknown target network              |
+------+------+------------------------------------------------+
|   4  |   0  | Source station suppression [congestion control]|
+------+------+------------------------------------------------+
|   5  |  any |                  Relocation                    |
+------+------+------------------------------------------------+
|  8   |   0  |       Echo request (ping command request)      |
+------+------+------------------------------------------------+
......

*/
QString Capture::icmpPackageHandle(const u_char *pkt_content){
    ICMP_HEADER*icmp;
    icmp = (ICMP_HEADER*)(pkt_content + 20 + 14);
    u_char type = icmp->type;
    u_char code = icmp->code;
    QString result = "";
    switch (type) {
    case 0:{
        if(!code)
            result = "Echo response (ping)";
        break;
    }
    case 3:{
        switch (code) {
        case 0:{
            result = "Network unreachable";
            break;
        }
        case 1:{
            result = "Host unreachable";
            break;
        }
        case 2:{
            result = "Protocol unreachable";
            break;
        }
        case 3:{
            result = "Port unreachable";
            break;
        }
        case 4:{
            result = "Fragmentation is required, but DF is set";
            break;
        }
        case 5:{
            result = "Source route selection failed";
            break;
        }
        case 6:{
            result = "Unknown target network";
            break;
        }
        default:break;
        }
        break;
    }
    case 4:{
        result = "Source station suppression [congestion control]";
        break;
    }
    case 5:{
        result = "Relocation";
        break;
    }
    case 8:{
        if(!code)
            result = "Echo request (ping)";
        break;
    }
    default:break;
    }
    return result;
}

int Capture::tcpPackageHandle(const u_char *pkt_content,QString &info,int ipPackage){
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    u_short src = ntohs(tcp->src_port);
    u_short des = ntohs(tcp->des_port);
    QString proSend = "";
    QString proRecv = "";
    int type = 3;
    int delta = (tcp->header_length >> 4) * 4;
    int tcpPayLoad = ipPackage - delta;
    if((src == 443 || des == 443) && (tcpPayLoad > 0)){
        if(src == 443)
            proSend = "(https)";
        else proRecv = "(https)";
        u_char *ssl;
        ssl = (u_char*)(pkt_content + 14 + 20 + delta);
        u_char isTls = *(ssl);
        ssl++;
        u_short*pointer = (u_short*)(ssl);
        u_short version = ntohs(*pointer);
        if(isTls >= 20 && isTls <= 23 && version >= 0x0301 && version <= 0x0304){
            type = 6;
            switch(isTls){
            case 20:{
                info = "Change Cipher Spec";
                break;
            }
            case 21:{
                info = "Alert";
                break;
            }
            case 22:{
                info = "Handshake";
                ssl += 4;
                u_char type = (*ssl);
                switch (type) {
                case 1: {
                    info += " Client Hello";
                    break;
                }
                case 2: {
                    info += " Server hello";
                    break;
                }
                case 4: {
                    info += " New Session Ticket";
                    break;
                }
                case 11:{
                    info += " Certificate";
                    break;
                }
                case 16:{
                    info += " Client Key Exchange";
                    break;
                }
                case 12:{
                    info += " Server Key Exchange";
                    break;
                }
                case 14:{
                    info += " Server Hello Done";
                    break;
                }
                default:break;
                }
                break;
            }
            case 23:{
                info = "Application Data";
                break;
            }
            default:{
                break;
            }
            }
            return type;
        }else type = 7;
    }

    if(type == 7){
        info = "Continuation Data";
    }
    else{
        info += QString::number(src) + proSend+ "->" + QString::number(des) + proRecv;
        QString flag = "";
        if(tcp->flags & 0x08) flag += "PSH,";
        if(tcp->flags & 0x10) flag += "ACK,";
        if(tcp->flags & 0x02) flag += "SYN,";
        if(tcp->flags & 0x20) flag += "URG,";
        if(tcp->flags & 0x01) flag += "FIN,";
        if(tcp->flags & 0x04) flag += "RST,";
        if(flag != ""){
            flag = flag.left(flag.length()-1);
            info += " [" + flag + "]";
        }
        u_int sequeue = ntohl(tcp->sequence);
        u_int ack = ntohl(tcp->ack);
        u_short window = ntohs(tcp->window_size);
        info += " Seq=" + QString::number(sequeue) + " Ack=" + QString::number(ack) + " win=" + QString::number(window) + " Len=" + QString::number(tcpPayLoad);
    }
    return type;
}

int Capture::udpPackageHandle(const u_char *pkt_content,QString&info){
    UDP_HEADER * udp;
    udp = (UDP_HEADER*)(pkt_content + 14 + 20);
    u_short desPort = ntohs(udp->des_port);
    u_short srcPort = ntohs(udp->src_port);
    if(desPort == 53){ // dns query
        info =  dnsPackageHandle(pkt_content);
        return 5;
    }
    else if(srcPort == 53){// dns reply
        info =  dnsPackageHandle(pkt_content);
        return 5;
    }
    else{
        QString res = QString::number(srcPort) + "->" + QString::number(desPort);
        res += " len=" + QString::number(ntohs(udp->data_length));
        info = res;
        return 4;
    }
}

QString Capture::arpPackageHandle(const u_char *pkt_content){
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    u_short op = ntohs(arp->op_code);
    QString res = "";
    u_char*addr = arp->des_ip_addr;

    QString desIp = QString::number(*addr) + "."
            + QString::number(*(addr+1)) + "."
            + QString::number(*(addr+2)) + "."
            + QString::number(*(addr+3));

    addr = arp->src_ip_addr;
    QString srcIp = QString::number(*addr) + "."
            + QString::number(*(addr+1)) + "."
            + QString::number(*(addr+2)) + "."
            + QString::number(*(addr+3));

    u_char* srcEthTemp = arp->src_eth_addr;
    QString srcEth = byteToHex(srcEthTemp,1) + ":"
            + byteToHex((srcEthTemp+1),1) + ":"
            + byteToHex((srcEthTemp+2),1) + ":"
            + byteToHex((srcEthTemp+3),1) + ":"
            + byteToHex((srcEthTemp+4),1) + ":"
            + byteToHex((srcEthTemp+5),1);

    switch (op){
    case 1:{
        res  = "Who has " + desIp + "? Tell " + srcIp;
        break;
    }
    case 2:{
        res = srcIp + " is at " + srcEth;
        break;
    }
    default:break;
    }
    return res;
}

QString Capture::dnsPackageHandle(const u_char *pkt_content){
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    u_short identification = ntohs(dns->identification);
    u_short type = ntohs(dns->flags);
    QString info = "";
    if((type & 0xf800) == 0x0000){
        info = "Standard query ";
    }
    else if((type & 0xf800) == 0x8000){
        info = "Standard query response ";
    }
    QString name = "";
    char*domain = (char*)(pkt_content + 14 + 20 + 8 + 12);
    while(*domain != 0x00){
        if(domain && (*domain) <= 64){
            int length = *domain;
            domain++;
            for(int k = 0;k < length;k++){
                name += (*domain);
                domain++;
            }
            name += ".";
        }else break;
    }
    // DNS_QUESITON *qus = (DNS_QUESITON*)(pkt_content + 14 + 20 + 8 + 12 + stringLength);
    // qDebug()<<ntohs(qus->query_type);
    // qDebug()<<ntohs(qus->query_class);
    name = name.left(name.length()-1);
    return info + "0x" + QString::number(identification,16) + " " + name;
}

4、datapackage.h

#ifndef DATAPACKAGE_H
#define DATAPACKAGE_H

#include <QString>
#include "Format.h"


/* * This class is describe the data package infomation * +-----+------------+ * | type| infomation | * +-----+------------+ * | 1 | arp | * +-----+------------+ * | 2 | icmp | * +-----+------------+ * | 3 | tcp | * +-----+------------+ * | 4 | udp | * +-----+------------+ * | 5 | dns | * +-----+------------+ * | 6 | tls | * +-----+------------+ * | 7 | ssl | * +-----+------------+ */
class DataPackage
{
    
private:
    u_int data_length; // data pakage length
    QString timeStamp; // timestamp of package
    QString info;      // a breif introduction of package
    int packageType;   // type

public:
    const u_char *pkt_content; // root pointer of package data

protected:
    /* * turn the byteArray to QString */
    static QString byteToHex(u_char*str,int size);
public:
    // Construction and destruction
    DataPackage();
    ~DataPackage() = default;

    // set the var
    void setDataLength(unsigned int length);                    // set the package length
    void setTimeStamp(QString timeStamp);                       // set timestamp
    void setPackageType(int type);                              // set package type
    void setPackagePointer(const u_char *pkt_content,int size); // set package pointer
    void setPackageInfo(QString info);                          // set package information

    // get the var
    QString getDataLength();                  // get package length
    QString getTimeStamp();                   // get timestamp
    QString getPackageType();                 // get package type
    QString getInfo();                        // get a breif package information
    QString getSource();                      // get the source address of package
    QString getDestination();                 // get the destination address of package

    // get the mac info
    QString getDesMacAddr();                  // get the destination MAC address
    QString getSrcMacAddr();                  // get the source MAC address
    QString getMacType();                     // get the type of MAC address

    // get the ip info
    QString getDesIpAddr();                   // get the destination ip address
    QString getSrcIpAddr();                   // get the source ip address
    QString getIpVersion();                   // get the ip version
    QString getIpHeaderLength();              // get the ip head length
    QString getIpTos();                       // get the ip tos
    QString getIpTotalLength();               // get the ip total package length
    QString getIpIdentification();            // get the ip identification
    QString getIpFlag();                      // get the ip flag
    QString getIpReservedBit();               // the reserved bit
    QString getIpDF();                        // Don't fragment
    QString getIpMF();                        // More fragment
    QString getIpFragmentOffset();            // get the offset of package
    QString getIpTTL();                       // get ip ttl [time to live]
    QString getIpProtocol();                  // get the ip protocol
    QString getIpCheckSum();                  // get the checksum

    // get the icmp info
    QString getIcmpType();                    // get the icmp type
    QString getIcmpCode();                    // get the icmp code
    QString getIcmpCheckSum();                // get the icmp checksum
    QString getIcmpIdentification();          // get the icmp identification
    QString getIcmpSequeue();                 // get the icmp sequence
    QString getIcmpData(int size);            // get the icmp data

    // get the arp info
    QString getArpHardwareType();             // get arp hardware type
    QString getArpProtocolType();             // get arp protocol type
    QString getArpHardwareLength();           // get arp hardware length
    QString getArpProtocolLength();           // get arp protocol length
    QString getArpOperationCode();            // get arp operation code
    QString getArpSourceEtherAddr();          // get arp source ethernet address
    QString getArpSourceIpAddr();             // get arp souce ip address
    QString getArpDestinationEtherAddr();     // get arp destination ethernet address
    QString getArpDestinationIpAddr();        // get arp destination ip address

    // get the tcp info
    QString getTcpSourcePort();               // get tcp source port
    QString getTcpDestinationPort();          // get tcp destination port
    QString getTcpSequence();                 // get tcp sequence
    QString getTcpAcknowledgment();           // get acknowlegment
    QString getTcpHeaderLength();             // get tcp head length
    QString getTcpRawHeaderLength();          // get tcp raw head length [default is 0x05]
    QString getTcpFlags();                    // get tcp flags
    QString getTcpPSH();                      // PSH flag
    QString getTcpACK();                      // ACK flag
    QString getTcpSYN();                      // SYN flag
    QString getTcpURG();                      // URG flag
    QString getTcpFIN();                      // FIN flag
    QString getTcpRST();                      // RST flag
    QString getTcpWindowSize();               // get tcp window size
    QString getTcpCheckSum();                 // get tcp checksum
    QString getTcpUrgentPointer();            // get tcp urgent pointer
    QString getTcpOperationKind(int kind);    // get tcp option kind
    int getTcpOperationRawKind(int offset);   // get tcp raw option kind

    /* * tcp optional parts */
    bool getTcpOperationMSS(int offset,u_short& mss);                          // kind = 2
    bool getTcpOperationWSOPT(int offset,u_char&shit);                         // kind = 3
    bool getTcpOperationSACKP(int offset);                                     // kind = 4
    bool getTcpOperationSACK(int offset,u_char&length,QVector<u_int>&edge);    // kind = 5
    bool getTcpOperationTSPOT(int offset,u_int& value,u_int&reply);            // kind = 8

    // get the udp info
    QString getUdpSourcePort();               // get udp source port
    QString getUdpDestinationPort();          // get udp destination port
    QString getUdpDataLength();               // get udp data length
    QString getUdpCheckSum();                 // get udp checksum

    // get the dns info
    QString getDnsTransactionId();            // get dns transaction id
    QString getDnsFlags();                    // get dns flags
    QString getDnsFlagsQR();                  // get dns flag QR
    QString getDnsFlagsOpcode();              // get dns flag operation code
    QString getDnsFlagsAA();                  // get dns flag AA
    QString getDnsFlagsTC();                  // get dns flag TC
    QString getDnsFlagsRD();                  // get dns flag RD
    QString getDnsFlagsRA();                  // get dns flag RA
    QString getDnsFlagsZ();                   // get dns flag Z [reserved]
    QString getDnsFlagsRcode();               // get dns flag Rcode
    QString getDnsQuestionNumber();           // get dns question number
    QString getDnsAnswerNumber();             // get dns answer number
    QString getDnsAuthorityNumber();          // get dns authority number
    QString getDnsAdditionalNumber();         // get dns addition number
    void getDnsQueriesDomain(QString&name,int&Type,int&Class);
    QString getDnsDomainType(int type);
    QString getDnsDomainName(int offset);
    int getDnsAnswersDomain(int offset,QString&name1,u_short&Type,u_short& Class,u_int&ttl,u_short&dataLength,QString& name2);

    // get the tls info
    bool getisTlsProtocol(int offset);
    void getTlsBasicInfo(int offset,u_char&contentType,u_short&version,u_short&length);
    void getTlsClientHelloInfo(int offset,u_char&handShakeType,int& length,u_short&version,QString&random,u_char&sessionIdLength,QString&sessionId,u_short&cipherLength,QVector<u_short>&cipherSuit,u_char& cmLength,QVector<u_char>&CompressionMethod,u_short&extensionLength);
    void getTlsServerHelloInfo(int offset,u_char&handShakeType,int&length,u_short&version,QString& random,u_char&sessionIdLength,QString&sessionId,u_short&cipherSuit,u_char&compressionMethod,u_short&extensionLength);
    void getTlsServerKeyExchange(int offset,u_char&handShakeType,int&length,u_char&curveType,u_short&curveName,u_char&pubLength,QString&pubKey,u_short&sigAlgorithm,u_short&sigLength,QString&sig);
    u_short getTlsExtensionType(int offset);
    void getTlsHandshakeType(int offset,u_char&type);

    /* * these functions are used to parse the extension parts * extension parts are common in handshake parts (client hello,server hello ...) * there are some extension types are not included in, maybe you should refer the official API */
    void getTlsExtensionServerName(int offset,u_short&type,u_short&length,u_short&listLength,u_char&nameType,u_short&nameLength,QString& name);
    void getTlsExtensionSignatureAlgorithms(int offset,u_short&type,u_short&length,u_short&algorithmLength,QVector<u_short>&signatureAlgorithm);
    void getTlsExtensionSupportGroups(int offset,u_short&type,u_short&length,u_short&groupListLength,QVector<u_short>&group);
    void getTlsExtensionEcPointFormats(int offset,u_short&type,u_short&length,u_char& ecLength,QVector<u_char>&EC);
    void getTlsExtensionSessionTicket(int offset,u_short&type,u_short&length);
    void getTlsExtensionEncryptThenMac(int offset,u_short&type,u_short&length);
    void getTlsExtensionSupportVersions(int offset,u_short&type,u_short&length,u_char&supportLength,QVector<u_short>&supportVersion);
    void getTlsExtensionPskKeyExchangeModes(int offset,u_short&type,u_short&length,u_char&modeLength,QVector<u_char>&mode);
    void getTlsExtensionKeyShare(int offset,u_short&type,u_short&length,u_short&shareLength,u_short&group,u_short&exchangeLength,QString& exchange);
    void getTlsExtensionOther(int offset,u_short&type,u_short&length,QString& data);
    void getTlsExtensionExtendMasterSecret(int offset,u_short&type,u_short&length);
    void getTlsExtensionPadding(int offset,u_short&type,u_short&length,QString&data);

    /* * when transfer data,some types will be encoded,like using 0x01 to represent the MD5 in extension hash part * to visual display these types,we need to decode and analysis * this functions are used to do these analisis * however,some types may be the custom types, so we can't decode * also,there are some rules not be included, maybe you should refer the official API */
    // Parsing the encode data
    static QString getTlsHandshakeType(int type);                          // Parsing TLS handshake type
    static QString getTlsContentType(int type);                            // Parsing TLS content type
    static QString getTlsVersion(int version);                             // Parsing TLS version
    static QString getTlsHandshakeCipherSuites(u_short code);              // Parsing TLS cipher suite
    static QString getTlsHandshakeCompression(u_char code);                // Parsing TLS compression
    static QString getTlsHandshakeExtension(u_short type);                 // Parsing TLS extension
    static QString getTlsHandshakeExtensionECPointFormat(u_char type);     // Parsing TLS EC point format
    static QString getTlsHandshakeExtensionSupportGroup(u_short type);     // Parsing TLS support group
    static QString getTlsHadshakeExtensionSignature(u_char type);          // Parsing TLS signature
    static QString getTlsHadshakeExtensionHash(u_char type);               // Parsing TLS hash

};

#endif // DATAPACKAGE_H

5、datapackage.cpp

	#include "datapackage.h"
#include <QMetaType>
#include "winsock.h"
#include <QVector>

DataPackage::DataPackage()
{
    
    // register the DataPackage type then
    qRegisterMetaType<DataPackage>("DataPackage");
    this->timeStamp = "";
    this->data_length = 0;
    this->packageType = 0;
    this->pkt_content = nullptr;
}

void DataPackage::setDataLength(unsigned int length){
    
    this->data_length = length;
}

void DataPackage::setTimeStamp(QString timeStamp){
    
    this->timeStamp = timeStamp;
}

void DataPackage::setPackageType(int type){
    
    this->packageType = type;
}

void DataPackage::setPackagePointer(const u_char *pkt_content,int size){
    
    this->pkt_content = (u_char*)malloc(size);
    if(this->pkt_content != nullptr)
        memcpy((char*)(this->pkt_content),pkt_content,size);
    else this->pkt_content = nullptr;
    // Do not use `this->pkt_content = pkt_content;`
}
void DataPackage::setPackageInfo(QString info){
    
    this->info = info;
}
QString DataPackage::byteToHex(u_char *str, int size){
    
    QString res = "";
    for(int i = 0;i < size;i++){
    
        char one = str[i] >> 4;
        if(one >= 0x0A)
            one = one + 0x41 - 0x0A;
        else one = one + 0x30;
        char two = str[i] & 0xF;
        if(two >= 0x0A)
            two = two  + 0x41 - 0x0A;
        else two = two + 0x30;
        res.append(one);
        res.append(two);
    }
    return res;
}

QString DataPackage::getTimeStamp(){
    
    return this->timeStamp;
}

QString DataPackage::getDataLength(){
    
    return QString::number(this->data_length);
}

QString DataPackage::getPackageType(){
    
    switch (this->packageType) {
    
    case 1:return ARP;
    case 2:return ICMP;
    case 3:return TCP;
    case 4:return UDP;
    case 5:return DNS;
    case 6:return TLS;
    case 7:return SSL;
    // TODU ...more protocol you can add
    default:{
    
        return "";
    }
    }
}

QString DataPackage::getInfo(){
    
    return info;
}

QString DataPackage::getSource(){
    
    if(this->packageType == 1)
        return getArpSourceIpAddr();
    else return getSrcIpAddr();
}
QString DataPackage::getDestination(){
    
    if(this->packageType == 1)
        return getArpDestinationIpAddr();
    else return getDesIpAddr();
}
/* Ether */
/********************** get destination ethenet address **********************/
QString DataPackage::getDesMacAddr(){
    
    ETHER_HEADER*ethernet;
    ethernet = (ETHER_HEADER*)pkt_content;
    u_char*addr;
    if(ethernet){
    
        addr = ethernet->ether_des_host;
        if(addr){
    
            QString res = byteToHex(addr,1) + ":"
                    + byteToHex((addr+1),1) + ":"
                    + byteToHex((addr+2),1) + ":"
                    + byteToHex((addr+3),1) + ":"
                    + byteToHex((addr+4),1) + ":"
                    + byteToHex((addr+5),1);
            if(res == "FF:FF:FF:FF:FF:FF") return "FF:FF:FF:FF:FF:FF(Broadcast)";
            else return res;
        }
    }
    return "";
}
/********************** get source ethenet address **********************/
QString DataPackage::getSrcMacAddr(){
    
    ETHER_HEADER*ethernet;
    ethernet = (ETHER_HEADER*)pkt_content;
    u_char*addr;
    if(ethernet){
    
        addr = ethernet->ether_src_host;
        if(addr){
    
            QString res = byteToHex(addr,1) + ":"
                    + byteToHex((addr+1),1) + ":"
                    + byteToHex((addr+2),1) + ":"
                    + byteToHex((addr+3),1) + ":"
                    + byteToHex((addr+4),1) + ":"
                    + byteToHex((addr+5),1);
            if(res == "FF:FF:FF:FF:FF:FF") return "FF:FF:FF:FF:FF:FF(Broadcast)";
            else return res;
        }
    }
    return "";
}
/********************** get ethenet type **********************/
QString DataPackage::getMacType(){
    
    ETHER_HEADER*ethernet;
    ethernet = (ETHER_HEADER*)pkt_content;
    u_short ethernet_type = ntohs(ethernet->ether_type);
    switch (ethernet_type) {
    
    case 0x0800: return "IPv4(0x800)";
    case 0x0806:return "ARP(0x0806)";
    default:{
    
        return "";
    }
    }
}

/* ip */
/********************** get destination ip address **********************/
QString DataPackage::getDesIpAddr(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    sockaddr_in desAddr;
    desAddr.sin_addr.s_addr = ip->des_addr;
    return QString(inet_ntoa(desAddr.sin_addr));
}
/********************** get source ip address **********************/
QString DataPackage::getSrcIpAddr(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    sockaddr_in srcAddr;
    srcAddr.sin_addr.s_addr = ip->src_addr;
    return QString(inet_ntoa(srcAddr.sin_addr));
}
/********************** get ip version **********************/
QString DataPackage::getIpVersion(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number(ip->versiosn_head_length >> 4);
}
/********************** get ip header length **********************/
QString DataPackage::getIpHeaderLength(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    QString res = "";
    int length = ip->versiosn_head_length & 0x0F;
    if(length == 5) res = "20 bytes (5)";
    else res = QString::number(length*5) + "bytes (" + QString::number(length) + ")";
    return res;
}

/********************** get ip TOS **********************/
QString DataPackage::getIpTos(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number(ntohs(ip->TOS));
}
/********************** get ip total length **********************/
QString DataPackage::getIpTotalLength(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number(ntohs(ip->total_length));
}
/********************** get ip indentification **********************/
QString DataPackage::getIpIdentification(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number(ntohs(ip->identification),16);
}
/********************** get ip flag **********************/
QString DataPackage::getIpFlag(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number((ntohs(ip->flag_offset)& 0xe000) >> 8,16);
}
/********************** get ip reverse bit **********************/
QString DataPackage::getIpReservedBit(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    int bit = (ntohs(ip->flag_offset) & 0x8000) >> 15;
    return QString::number(bit);
}
/********************** get ip DF flag[Don't Fragment] **********************/
QString DataPackage::getIpDF(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number((ntohs(ip->flag_offset) & 0x4000) >> 14);
}
/********************** get ip MF flag[More Fragment] **********************/
QString DataPackage::getIpMF(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number((ntohs(ip->flag_offset) & 0x2000) >> 13);
}
/********************** get ip Fragment Offset **********************/
QString DataPackage::getIpFragmentOffset(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number(ntohs(ip->flag_offset) & 0x1FFF);
}
/********************** get ip TTL **********************/
QString DataPackage::getIpTTL(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number(ip->ttl);
}
/********************** get ip protocol **********************/
QString DataPackage::getIpProtocol(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    int protocol = ip->protocol;
    switch (protocol) {
    
    case 1:return "ICMP (1)";
    case 6:return "TCP (6)";
    case 17:return "UDP (17)";
    default:{
    
        return "";
    }
    }
}
/********************** get ip checksum **********************/
QString DataPackage::getIpCheckSum(){
    
    IP_HEADER*ip;
    ip = (IP_HEADER*)(pkt_content + 14);
    return QString::number(ntohs(ip->checksum),16);
}

/* icmp */
/********************** get icmp type **********************/
QString DataPackage::getIcmpType(){
    
    ICMP_HEADER*icmp;
    icmp = (ICMP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(icmp->type));
}
/********************** get icmp code **********************/
QString DataPackage::getIcmpCode(){
    
    ICMP_HEADER*icmp;
    icmp = (ICMP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(icmp->code));

}
/********************** get icmp checksum **********************/
QString DataPackage::getIcmpCheckSum(){
    
    ICMP_HEADER*icmp;
    icmp = (ICMP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(icmp->checksum),16);
}
/********************** get icmp identification **********************/
QString DataPackage::getIcmpIdentification(){
    
    ICMP_HEADER*icmp;
    icmp = (ICMP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(icmp->identification));
}
/********************** get icmp sequence **********************/
QString DataPackage::getIcmpSequeue(){
    
    ICMP_HEADER*icmp;
    icmp = (ICMP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(icmp->sequence));
}
QString DataPackage::getIcmpData(int size){
    
    char*icmp;
    icmp = (char*)(pkt_content + 14 + 20 + 8);
    QString res= "";
    for(int i = 0;i < size;i++){
    
        res += (*icmp);
        icmp++;
    }
    return res;
}
/* arp info */
QString DataPackage::getArpHardwareType(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    int type = ntohs(arp->hardware_type);
    QString res = "";
    if(type == 0x0001) res = "Ethernet(1)";
    else res = QString::number(type);
    return res;
}
/********************** get arp protocol type **********************/
QString DataPackage::getArpProtocolType(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    int type = ntohs(arp->protocol_type);
    QString res = "";
    if(type == 0x0800) res = "IPv4(0x0800)";
    else res = QString::number(type);
    return res;
}
/********************** get hardware length **********************/
QString DataPackage::getArpHardwareLength(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    return QString::number(arp->mac_length);
}
/********************** get arp protocol length **********************/
QString DataPackage::getArpProtocolLength(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    return QString::number(arp->ip_length);
}
/********************** get arp operator code **********************/
QString DataPackage::getArpOperationCode(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    int code = ntohs(arp->op_code);
    QString res = "";
    if(code == 1) res  = "request(1)";
    else if(code == 2) res = "reply(2)";
    return res;
}
/********************** get arp source ethernet address **********************/
QString DataPackage::getArpSourceEtherAddr(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    u_char*addr;
    if(arp){
    
        addr = arp->src_eth_addr;
        if(addr){
    
            QString res = byteToHex(addr,1) + ":"
                    + byteToHex((addr+1),1) + ":"
                    + byteToHex((addr+2),1) + ":"
                    + byteToHex((addr+3),1) + ":"
                    + byteToHex((addr+4),1) + ":"
                    + byteToHex((addr+5),1);
            return res;
        }
    }
    return "";
}
/********************** get arp destination ethernet address **********************/
QString DataPackage::getArpDestinationEtherAddr(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    u_char*addr;
    if(arp){
    
        addr = arp->des_eth_addr;
        if(addr){
    
            QString res = byteToHex(addr,1) + ":"
                    + byteToHex((addr+1),1) + ":"
                    + byteToHex((addr+2),1) + ":"
                    + byteToHex((addr+3),1) + ":"
                    + byteToHex((addr+4),1) + ":"
                    + byteToHex((addr+5),1);
            return res;
        }
    }
    return "";
}
/********************** get arp source ip address **********************/
QString DataPackage::getArpSourceIpAddr(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    if(arp){
    
        u_char*addr = arp->src_ip_addr;
        QString srcIp = QString::number(*addr) + "."
                + QString::number(*(addr+1)) + "."
                + QString::number(*(addr+2)) + "."
                + QString::number(*(addr+3));
        return srcIp;
    }
    return "";
}
/********************** get arp destination ip address **********************/
QString DataPackage::getArpDestinationIpAddr(){
    
    ARP_HEADER*arp;
    arp = (ARP_HEADER*)(pkt_content + 14);
    if(arp){
    
        u_char*addr = arp->des_ip_addr;
        QString desIp = QString::number(*addr) + "."
                + QString::number(*(addr+1)) + "."
                + QString::number(*(addr+2)) + "."
                + QString::number(*(addr+3));
        return desIp;
    }
    return "";
}

/* tcp */
/********************** get tcp source port **********************/
QString DataPackage::getTcpSourcePort(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    int port = ntohs(tcp->src_port);
    if(port == 443) return "https(443)";
    return QString::number(port);
}
/********************** get tcp destination port **********************/
QString DataPackage::getTcpDestinationPort(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    int port = ntohs(tcp->des_port);
    if(port == 443) return "https(443)";
    return QString::number(port);
}
/********************** get tcp sequence **********************/
QString DataPackage::getTcpSequence(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohl(tcp->sequence));
}
/********************** get tcp acknowledgment **********************/
QString DataPackage::getTcpAcknowledgment(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohl(tcp->ack));
}
/********************** get tcp header length **********************/
QString DataPackage::getTcpHeaderLength(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    int length = (tcp->header_length >> 4);
    if(length == 5) return "20 bytes (5)";
    else return QString::number(length*4) + " bytes (" + QString::number(length) + ")";
}
QString DataPackage::getTcpRawHeaderLength(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(tcp->header_length >> 4);
}

/********************** get tcp flags **********************/
QString DataPackage::getTcpFlags(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(tcp->flags,16);
}

/********************** get tcp PSH **********************/
QString DataPackage::getTcpPSH(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(((tcp->flags) & 0x08) >> 3);
}
/********************** get tcp ACK **********************/
QString DataPackage::getTcpACK(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(((tcp->flags) & 0x10) >> 4);
}
/********************** get tcp SYN **********************/
QString DataPackage::getTcpSYN(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(((tcp->flags) & 0x02) >> 1);
}
/********************** get tcp UGR **********************/
QString DataPackage::getTcpURG(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(((tcp->flags) & 0x20) >> 5);
}
/********************** get tcp FIN **********************/
QString DataPackage::getTcpFIN(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number((tcp->flags) & 0x01);
}
/********************** get tcp RST **********************/
QString DataPackage::getTcpRST(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(((tcp->flags) & 0x04) >> 2);
}
/********************** get tcp window size **********************/
QString DataPackage::getTcpWindowSize(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(tcp->window_size));
}
/********************** get tcp checksum **********************/
QString DataPackage::getTcpCheckSum(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(tcp->checksum),16);
}
/********************** get tcp urgent pointer **********************/
QString DataPackage::getTcpUrgentPointer(){
    
    TCP_HEADER*tcp;
    tcp = (TCP_HEADER*)(pkt_content + 14 + 20);
    return QString::number(ntohs(tcp->urgent));
}

QString DataPackage::getTcpOperationKind(int kind){
    
    switch(kind){
    
    case 0:return "EOL";              // end of list
    case 1:return "NOP";              // no operation
    case 2:return "MSS";              // max segment
    case 3:return "WSOPT";            // window scaling factor
    case 4:return "SACK-Premitted";   // support SACK
    case 5:return "SACK";             // SACK Block
    case 8:return "TSPOT";            // Timestamps
    case 19:return "TCP-MD5";         // MD5
    case 28:return "UTP";             // User Timeout
    case 29:return "TCP-AO";          // authenticated
    }
}
int DataPackage::getTcpOperationRawKind(int offset){
    
    u_char*tcp;
    tcp = (u_char*)(pkt_content + 14 + 20 + offset + 20);
    return *tcp;
}
bool DataPackage::getTcpOperationSACK(int offset,u_char&length,QVector<u_int>&edge){
    
    u_char*tcp;
    tcp = (u_char*)(pkt_content + 14 + 20 + offset + 20);
    if(*tcp == 5){
    
        tcp++;
        length = *tcp;
        tcp++;
        u_int* pointer = (u_int*)tcp;
        for(int i = 0;i < (length - 2)/4;i++){
    
            u_int temp = htonl(*pointer);
            edge.push_back(temp);
            pointer++;
        }
        return true;
    }else return false;
}
bool DataPackage::getTcpOperationMSS(int offset, u_short &mss){
    
    u_char *tcp;
    tcp = (u_char*)(pkt_content + 14 + 20 + offset + 20);
    if(*tcp == 2){
    
        tcp++;
        if(*tcp == 4){
    
            tcp++;
            u_short* Mss = (u_short*)tcp;
            mss = ntohs(*Mss);
            return true;
        }
        else return false;
    }
    return false;
}
bool DataPackage::getTcpOperationSACKP(int offset){
    
    u_char *tcp;
    tcp = (u_char*)(pkt_content + 14 + 20 + offset + 20);
    if(*tcp == 4)
        return true;
    else return false;
}
bool DataPackage::getTcpOperationWSOPT(int offset, u_char &shit){
    
    u_char *tcp;
    tcp = (u_char*)(pkt_content + 14 + 20 + offset + 20);
    if(*tcp == 3){
    
        tcp++;
        if(*tcp == 3){
    
            tcp++;
            shit = *tcp;
        }else return false;
    }else return false;
}

bool DataPackage::getTcpOperationTSPOT(int offset, u_int &value, u_int &reply){
    
    u_char *tcp;
    tcp = (u_char*)(pkt_content + 14 + 20 + offset + 20);
    if(*tcp == 8){
    
        tcp++;
        if(*tcp == 10){
    
            tcp++;
            u_int *pointer = (u_int*)(tcp);
            value = ntohl(*pointer);
            pointer++;
            reply = ntohl(*pointer);
            return true;
        }else return false;
    }else return false;
}
/* udp */
/********************** get udp source port **********************/
QString DataPackage::getUdpSourcePort(){
    
    UDP_HEADER*udp;
    udp = (UDP_HEADER*)(pkt_content + 20 + 14);
    int port = ntohs(udp->src_port);
    if(port == 53) return "domain(53)";
    else return QString::number(port);
}
/********************** get udp destination port **********************/
QString DataPackage::getUdpDestinationPort(){
    
    UDP_HEADER*udp;
    udp = (UDP_HEADER*)(pkt_content + 20 + 14);
    int port = ntohs(udp->des_port);
    if(port == 53) return "domain(53)";
    else return QString::number(port);
}
/********************** get udp data length **********************/
QString DataPackage::getUdpDataLength(){
    
    UDP_HEADER*udp;
    udp = (UDP_HEADER*)(pkt_content + 20 + 14);
    return QString::number(ntohs(udp->data_length));

}
/********************** get udp checksum **********************/
QString DataPackage::getUdpCheckSum(){
    
    UDP_HEADER*udp;
    udp = (UDP_HEADER*)(pkt_content + 20 + 14);
    return QString::number(ntohs(udp->checksum),16);
}

/* dns */
/********************** get dns transaction **********************/
QString DataPackage::getDnsTransactionId(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number(ntohs(dns->identification),16);
}
/********************** get dns flag **********************/
QString DataPackage::getDnsFlags(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    int type = ntohs(dns->flags);
    QString info = "";
    if((type & 0xf800) == 0x0000){
    
        info = "(Standard query)";
    }
    else if((type & 0xf800) == 0x8000){
    
        info = "(Standard query response)";
    }
    return QString::number(type,16) + info;
}
/********************** get dns QR **********************/
QString DataPackage::getDnsFlagsQR(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x8000) >> 15);
}
/********************** get dns Operation code **********************/
QString DataPackage::getDnsFlagsOpcode(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x7800) >> 11);
}
/********************** get dns AA **********************/
QString DataPackage::getDnsFlagsAA(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x0400) >> 10);
}
/********************** get dns TC **********************/
QString DataPackage::getDnsFlagsTC(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x0200) >> 9);
}
/********************** get dns RD **********************/
QString DataPackage::getDnsFlagsRD(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x0100) >> 8);
}
/********************** get dns RA **********************/
QString DataPackage::getDnsFlagsRA(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x0080) >> 7);
}
/********************** get dns Z(reserved) **********************/
QString DataPackage::getDnsFlagsZ(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x0070) >> 4);
}
/********************** get dns Response code **********************/
QString DataPackage::getDnsFlagsRcode(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number((ntohs(dns->flags) & 0x000f));
}
/********************** get dns Question number **********************/
QString DataPackage::getDnsQuestionNumber(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number(ntohs(dns->question));
}
/********************** get dns Answer number **********************/
QString DataPackage::getDnsAnswerNumber(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number(ntohs(dns->answer));
}
/********************** get dns Authority number **********************/
QString DataPackage::getDnsAuthorityNumber(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number(ntohs(dns->authority));
}
/********************** get dns Additional number **********************/
QString DataPackage::getDnsAdditionalNumber(){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    return QString::number(ntohs(dns->additional));
}
/********************** get dns query result **********************/
void DataPackage::getDnsQueriesDomain(QString&name,int&Type,int&Class){
    
    DNS_HEADER*dns;
    dns = (DNS_HEADER*)(pkt_content + 14 + 20 + 8);
    char*domain = (char*)(pkt_content + 14 + 20 + 8 + 12);
    while(*domain != 0x00){
    
        if(domain && (*domain) <= 64){
    
            int length = *domain;
            domain++;
            for(int k = 0;k < length;k++){
    
                name += (*domain);
                domain++;
            }
            name += ".";
        }else break;
    }
    domain++;
    name = name.left(name.length() - 1);
    DNS_QUESITON *qus = (DNS_QUESITON*)(domain);
    Type = ntohs(qus->query_type);
    Class = ntohs(qus->query_class);
}
/********************** get dns domian name **********************/
QString DataPackage::getDnsDomainName(int offset){
    
    char*dns;
    dns = (char*)(pkt_content + 14 + 20 + 8 + offset);
    QString name = "";
    while(dns && *dns != 0x00){
    
        if((unsigned char)(*dns) <= 64){
    
            int length = *dns;
            dns++;
            for(int k = 0;k<length;k++){
    
                name += (*dns);
                dns++;
            }
            name += ".";
        }else if(((*dns) & 0xc0) == 0xc0){
    
            int accOffset = (((*dns) & 0x3f) << 8);
            dns++;
            accOffset += (unsigned char)(*dns);
            name += getDnsDomainName(accOffset) + ".";
            dns++;
            break;
        }
    }
    name = name.left(name.length() - 1);
    return name;
}
/********************** get dns answer result **********************/
int DataPackage::getDnsAnswersDomain(int offset, QString &name1, u_short &Type, u_short &Class, u_int &ttl, u_short &dataLength,QString&name2){
    
    char*dns = (char*)(pkt_content + 14 + 20 + 8 + 12 + offset);
    if(((*dns) & 0xc0) == 0xc0){
    
        int accOffset = (((*dns) & 0x3f) << 8);
        dns++; //
        accOffset += (*dns);
        name1 = getDnsDomainName(accOffset);
        dns++; //
        DNS_ANSWER*answer = (DNS_ANSWER*)(dns);
        Type = ntohs(answer->answer_type);
        Class = ntohs(answer->answer_class);
        ttl = ntohl(answer->TTL);
        dataLength = ntohs(answer->dataLength);
        dns += (2 + 2 + 4 + 2);
        if(dataLength == 4){
    
            for(int i = 0;i < 4;i++){
    
                name2 += QString::number((unsigned char)(*dns));
                name2 += ".";
                dns++;
            }
        }else{
    
            for(int k = 0;k<dataLength;k++){
    
                if((unsigned char)(*dns) <= 64){
    
                    int length = *dns;
                    dns++;
                    k++;
                    for(int j = 0;j < length;j++){
    
                        name2 += *dns;
                        dns++;
                        k++;
                    }
                    name2 += ".";
                }else if(((*dns) & 0xc0) == 0xc0){
    
                    int accOffset = (((*dns) & 0x3f) << 8);
                    dns++;
                    k++;
                    accOffset += (unsigned char)(*dns);
                    name2 += getDnsDomainName(accOffset) + ".";
                    dns++;
                    k++;
                }
            }
        }
        name2 = name2.left(name2.length() - 1);
        return dataLength + 2 + 2 + 2 + 4 + 2;

    }else{
    
        name1 = getDnsDomainName(offset + 12);
        DNS_ANSWER*answer = (DNS_ANSWER*)(dns + name1.size() + 2);
        Type = ntohs(answer->answer_type);
        Class = ntohs(answer->answer_class);
        ttl = ntohl(answer->TTL);
        dataLength = ntohs(answer->dataLength);
        if(dataLength == 4){
    
            dns += (2 + 2 + 4 + 2 + name1.size() + 1);
            for(int i = 0;i < 4;i++){
    
                name2 += (unsigned char)(*dns);
                dns++;
            }
        }else{
    
            for(int k = 0;k<dataLength;k++){
    
                if((unsigned char)(*dns) <= 64){
    
                    int length = *dns;
                    dns++;
                    k++;
                    for(int j = 0;j < length;j++){
    
                        name2 += *dns;
                        dns++;
                        k++;
                    }
                    name2 += ".";
                }else if(((*dns) & 0xc0) == 0xc0){
    
                    int accOffset = (((*dns) & 0x3f) << 8);
                    dns++;
                    k++;
                    accOffset += (*dns);
                    name2 += getDnsDomainName(accOffset);
                    dns++;
                    k++;
                }
            }
        }
        name2 = name2.left(name2.length() - 1);
        return dataLength + 2 + 2 + 2 + 4 + 2 + name1.size() + 2;
    }
}
/********************** get dns domain type **********************/
QString DataPackage::getDnsDomainType(int type){
    
    switch (type) {
    
    case 1: return "A (Host Address)";
    case 2:return "NS";
    case 5:return "CNAME (Canonical NAME for an alias)";
    case 6:return "SOA";
    case 11:return "WSK";
    case 12:return "PTR";
    case 13:return "HINFO";
    case 15:return "MX";
    case 28:return "AAAA";
    case 252:return "AXFR";
    case 255:return "ANY";
    default:return "";
    }
}

// tls
/********************** get tls protocol to check the data is meet this format or not **********************/
bool DataPackage::getisTlsProtocol(int offset){
    
    char*ssl;
    ssl = (char*)(pkt_content + 14 + 20 + 20 + offset);
    u_char type = (u_char)(*ssl);
    if(type >= 20 && type <= 23){
    
        u_short *point = (u_short*)(ssl+1);
        int version = ntohs(*point);
        if(version >= 0x0301 && version <= 0x0304)
            return true;
        else return false;
    }
    else return false;
}
/********************** get tls basic information **********************/
void DataPackage::getTlsBasicInfo(int offset, u_char &contentType, u_short &version, u_short &length){
    
    u_char*ssl;
    ssl = (u_char*)(pkt_content + 14 + 20 + offset);
    contentType = *ssl;
    ssl++;
    u_short* pointer = (u_short*)(ssl);
    version = ntohs(*pointer);
    pointer++;
    length = ntohs(*(pointer));
}

/********************** get tls handshake type **********************/
void DataPackage::getTlsHandshakeType(int offset, u_char &type){
    
    u_char*ssl;
    ssl = (u_char*)(pkt_content + 14 + 20 + offset);
    type = *ssl;
}
/********************** get tls client hello information **********************/
void DataPackage::getTlsClientHelloInfo(int offset, u_char &handShakeType, int &length, u_short &version, QString &random, u_char &sessionIdLength, QString &sessionId,u_short&cipherLength,QVector<u_short> &cipherSuit,u_char& cmLength,QVector<u_char>&CompressionMethod,u_short&extensionLength){
    
    u_char*ssl;
    ssl = (u_char*)(pkt_content + 14 + 20 + offset);
    handShakeType = *ssl;
    ssl++;
    length = (*ssl) * 4096 + (*(ssl+1)) * 256 + *(ssl + 2);
    ssl += 3;
    u_short* ver = (u_short*)(ssl);
    version = ntohs(*ver);
    ver++;
    ssl += 2;
    for(int i = 0;i < 32;i++){
    
        random += QString::number(*ssl,16);
        ssl++;
    }
    sessionIdLength = *ssl;
    ssl++;
    for(int k = 0;k < sessionIdLength;k++){
    
        sessionId += QString::number(*ssl,16);
        ssl++;
    }
    u_short* clen = (u_short*)(ssl);
    cipherLength = ntohs(*clen);
    clen++;
    for(int k = 0;k < cipherLength/2;k++){
    
        cipherSuit.push_back(ntohs(*clen));
        clen++;
    }
    ssl += (2 + cipherLength);
    cmLength = *ssl;
    ssl++;
    for(int k = 0;k<cmLength;k++){
    
        CompressionMethod.push_back(*ssl);
        ssl++;
    }
    extensionLength = (*(ssl)) * 256 + *(ssl + 1);
}

void DataPackage::getTlsServerHelloInfo(int offset, u_char &handShakeType, int &length, u_short &version, QString& random, u_char &sessionIdLength, QString &sessionId, u_short &cipherSuit, u_char &compressionMethod, u_short &extensionLength){
    
    u_char*ssl;
    ssl = (u_char*)(pkt_content + 14 + 20 + offset);
    handShakeType = *ssl;
    ssl++;
    length = (*ssl) * 4096 + (*(ssl + 1)) * 256 + *(ssl + 2);
    ssl += 3;
    u_short* ver = (u_short*)(ssl);
    version = ntohs(*ver);
    ver++;
    ssl += 2;
    for(int i = 0;i < 32;i++){
    
        random += QString::number(*ssl,16);
        ssl++;
    }
    sessionIdLength = *ssl;
    ssl++;
    for(int k = 0;k < sessionIdLength;k++){
    
        sessionId += QString::number(*ssl,16);
        ssl++;
    }
    u_short*point = (u_short*)(ssl);
    cipherSuit = ntohs(*point);
    ssl += 2;
    compressionMethod = *ssl;
    ssl++;
    extensionLength = (*ssl) * 256 + (*(ssl + 1));
}
void DataPackage::getTlsServerKeyExchange(int offset, u_char &handShakeType, int &length, u_char &curveType, u_short &curveName, u_char &pubLength, QString &pubKey, u_short &sigAlgorithm, u_short &sigLength, QString &sig){
    
    u_char*ssl;
    ssl = (u_char*)(pkt_content + 14 + 20 + offset);
    handShakeType = *ssl;
    ssl++;
    length = (*ssl) * 4096 + (*(ssl + 1)) * 256 + *(ssl + 2);
    ssl += 3;
    curveType = (*ssl);
    ssl++;
    u_short*point = (u_short*)(ssl);
    curveName = ntohs(*point);
    ssl += 2;
    pubLength = (*ssl);
    ssl++;
    for(int i = 0;i < pubLength;i++){
    
        pubKey += QString::number(*ssl,16);
        ssl++;
    }
    point = (u_short*)(ssl);
    sigAlgorithm = ntohs(*point);
    point++;
    sigLength = ntohs(*point);
    ssl += 4;
    for(int i = 0;i < sigLength;i++){
    
        sig += QString::number(*ssl,16);
        ssl++;
    }
}
/********************** get tls handshake type **********************/
QString DataPackage::getTlsHandshakeType(int type){
    
    switch (type) {
    
    case 1:return "Client Hello";
    case 2:return "Server hello";
    case 11:return "Certificate";
    case 16:return "Client Key Exchange";
    case 4:return "New Session Ticket";
    case 12:return "Server Key Exchange";
    case 14:return "Server Hello Done";

    default:return "";
    }
}
/********************** get tls content type **********************/
QString DataPackage::getTlsContentType(int type){
    
    switch (type) {
    
    case 20: return "Change Cipher Spec";
    case 21:return "Alert";
    case 22:return "Handshake";
    case 23:return "Application Data";
    default:return "";
    }
}
/********************** get tls version **********************/
QString DataPackage::getTlsVersion(int version){
    
    switch (version) {
    
    case 0x0300:return "SSL 3.0";
    case 0x0301:return "TLS 1.0";
    case 0x0302:return "TLS 1.1";
    case 0x0303:return "TLS 1.2";
    case 0x0304:return "TLS 1.3";
    default:return "Unkonwn";
    }
}
/********************** get tls handshake cipher suites **********************/
QString DataPackage::getTlsHandshakeCipherSuites(u_short code){
    
    switch (code) {
    
    case 0x00ff: return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)";
    case 0xc02c: return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)";
    case 0xc030: return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)";
    case 0x009f: return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)";
    case 0xc0ad: return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM (0xc0ad)";
    case 0xc09f: return "TLS_DHE_RSA_WITH_AES_256_CCM (0xc09f)";
    case 0xc024: return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)";
    case 0xc028: return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)";
    case 0x006b: return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006b)";
    case 0xc00a: return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)";
    case 0xc014: return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)";
    case 0x0039: return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)";
    case 0xc0af: return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 (0xc0af)";
    case 0xc0a3: return "TLS_DHE_RSA_WITH_AES_256_CCM_8 (0xc0a3)";
    case 0xc087: return "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 (0xc087)";
    case 0xc08b: return "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 (0xc08b)";
    case 0xc07d: return "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 (0xc07d)";
    case 0xc073: return "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 (0xc073)";
    case 0xc077: return "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 (0xc077)";
    case 0x00c4: return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 (0x00c4)";
    case 0x0088: return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088)";
    case 0xc02b: return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)";
    case 0xc02f: return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)";
    case 0x009e: return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)";
    case 0xc0ac: return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM (0xc0ac)";
    case 0xc09e: return "TLS_DHE_RSA_WITH_AES_128_CCM (0xc09e)";
    case 0xc023: return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)";
    case 0xc027: return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)";
    case 0x0067: return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)";
    case 0xc009: return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)";
    case 0xc013: return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)";
    case 0x0033: return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)";
    case 0xc0ae: return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 (0xc0ae)";
    case 0xc0a2: return "TLS_DHE_RSA_WITH_AES_128_CCM_8 (0xc0a2)";
    case 0xc086: return "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 (0xc086)";
    case 0xc08a: return "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 (0xc08a)";
    case 0xc07c: return "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 (0xc07c)";
    case 0xc072: return "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 (0xc072)";
    case 0xc076: return "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 (0xc076)";
    case 0x00be: return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 (0x00be)";
    case 0x0045: return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0045)";
    case 0xc008: return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)";
    case 0xc012: return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)";
    case 0x0016: return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016)";
    case 0x00ab: return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 (0x00ab)";
    case 0xc0a7: return "TLS_DHE_PSK_WITH_AES_256_CCM (0xc0a7)";
    case 0xc038: return "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 (0xc038)";
    case 0x00b3: return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 (0x00b3)";
    case 0xc036: return "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA (0xc036) ";
    case 0x0091: return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA (0x0091)";
    case 0xc091: return "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 (0xc091)";
    case 0xc09b: return "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 (0xc09b)";
    case 0xc097: return "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 (0xc097)";
    case 0xc0ab: return "TLS_PSK_DHE_WITH_AES_256_CCM_8 (0xc0ab)";
    case 0x00aa: return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 (0x00aa)";
    case 0xc0a6: return "TLS_DHE_PSK_WITH_AES_128_CCM (0xc0a6)";
    case 0xc037: return "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 (0xc037)";
    case 0x00b2: return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 (0x00b2)";
    case 0xc035: return "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA (0xc035)";
    case 0x0090: return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA (0x0090)";
    case 0xc090: return "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 (0xc090)";
    case 0xc096: return "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 (0xc096)";
    case 0xc09a: return "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 (0xc09a)";
    case 0xc0aa: return "TLS_PSK_DHE_WITH_AES_128_CCM_8 (0xc0aa)";
    case 0xc034: return "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA (0xc034)";
    case 0x008f: return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA (0x008f)";
    case 0x009d: return "TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)";
    case 0xc09d: return "TLS_RSA_WITH_AES_256_CCM (0xc09d)";
    case 0x003d: return "TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)";
    case 0x0035: return "TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)";
    case 0xc032: return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 (0xc032)";
    case 0xc02a: return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 (0xc02a)";
    case 0xc00f: return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f)";
    case 0xc02e: return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02e)";
    case 0xc026: return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 (0xc026)";
    case 0xc005: return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005)";
    case 0xc0a1: return "TLS_RSA_WITH_AES_256_CCM_8 (0xc0a1)";
    case 0xc07b: return "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 (0xc07b)";
    case 0x00c0: return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 (0x00c0)";
    case 0x0084: return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0084)";
    case 0xc08d: return "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 (0xc08d) ";
    case 0xc079: return "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 (0xc079) ";
    case 0xc089: return "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 (0xc089)";
    case 0xc075: return "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 (0xc075)";
    case 0x009c: return "TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)";
    case 0xc09c: return "TLS_RSA_WITH_AES_128_CCM (0xc09c)";
    case 0x003c: return "TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)";
    case 0x002f: return "TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)";
    case 0xc031: return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 (0xc031)";
    case 0xc029: return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 (0xc029)";
    case 0xc00e: return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)";
    case 0xc02d: return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02d)";
    case 0xc025: return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 (0xc025)";
    case 0xc004: return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)";
    case 0xc0a0: return "TLS_RSA_WITH_AES_128_CCM_8 (0xc0a0)";
    case 0xc07a: return "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 (0xc07a)";
    case 0x00ba: return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 (0x00ba)";
    case 0x0041: return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0041)";
    case 0xc08c: return "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 (0xc08c)";
    case 0xc078: return "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 (0xc078)";
    case 0xc088: return "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 (0xc088)";
    case 0xc074: return "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 (0xc074)";
    case 0x000a: return "TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)";
    case 0xc00d: return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d) ";
    case 0xc003: return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003)";
    case 0x00ad: return "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 (0x00ad)";
    case 0x00b7: return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 (0x00b7)";
    case 0x0095: return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA (0x0095)";
    case 0xc093: return "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 (0xc093)";
    case 0xc099: return "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 (0xc099)";
    case 0x00ac: return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 (0x00ac)";
    case 0x00b6: return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 (0x00b6)";
    case 0x0094: return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA (0x0094)";
    case 0xc092: return "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 (0xc092)";
    case 0xc098: return "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 (0xc098)";
    case 0x0093: return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA (0x0093)";
    case 0x00a9: return "TLS_PSK_WITH_AES_256_GCM_SHA384 (0x00a9)";
    case 0xc0a5: return "TLS_PSK_WITH_AES_256_CCM (0xc0a5)";
    case 0x00af: return "TLS_PSK_WITH_AES_256_CBC_SHA384 (0x00af)";
    case 0x008d: return "TLS_PSK_WITH_AES_256_CBC_SHA (0x008d)";
    case 0xc08f: return "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 (0xc08f)";
    case 0xc095: return "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 (0xc095)";
    case 0xc0a9: return "TLS_PSK_WITH_AES_256_CCM_8 (0xc0a9)";
    case 0x00a8: return "TLS_PSK_WITH_AES_128_GCM_SHA256 (0x00a8)";
    case 0xc0a4: return "TLS_PSK_WITH_AES_128_CCM (0xc0a4)";
    case 0x00ae: return "TLS_PSK_WITH_AES_128_CBC_SHA256 (0x00ae)";
    case 0x008c: return "TLS_PSK_WITH_AES_128_CBC_SHA (0x008c)";
    case 0xc08e: return "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 (0xc08e)";
    case 0xc094: return "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 (0xc094)";
    case 0xc0a8: return "TLS_PSK_WITH_AES_128_CCM_8 (0xc0a8)";
    case 0x008b: return "TLS_PSK_WITH_3DES_EDE_CBC_SHA (0x008b)";
    case 0xc007: return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007)";
    case 0xc011: return "TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011)";
    case 0xc033: return "TLS_ECDHE_PSK_WITH_RC4_128_SHA (0xc033)";
    case 0x008e: return "TLS_DHE_PSK_WITH_RC4_128_SHA (0x008e) ";
    case 0x0005: return "TLS_RSA_WITH_RC4_128_SHA (0x0005)";
    case 0x0004: return "TLS_RSA_WITH_RC4_128_MD5 (0x0004)";
    case 0xc00c: return "TLS_ECDH_RSA_WITH_RC4_128_SHA (0xc00c)";
    case 0xc002: return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA (0xc002) ";
    case 0x0092: return "TLS_RSA_PSK_WITH_RC4_128_SHA (0x0092)";
    case 0x008a: return "TLS_PSK_WITH_RC4_128_SHA (0x008a)";
    case 0x1302: return "TLS_AES_256_GCM_SHA384 (0x1302)";
    case 0x1303: return "TLS_CHACHA20_POLY1305_SHA256 (0x1303)";
    case 0x1301: return "TLS_AES_128_GCM_SHA256 (0x1301)";
    case 0xcca9: return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)";
    case 0xcca8: return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)";
    case 0xccaa: return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xccaa)";
    default:return "0x" + QString::number(code,16);
    }
}
/********************** get tls handshake compression **********************/
QString DataPackage::getTlsHandshakeCompression(u_char code){
    
    switch (code) {
    
    case 0:return "null";
    default:return "";
    }
}

QString DataPackage::getTlsHandshakeExtension(u_short type){
    
    switch (type) {
    
    case 0: return "server_name";
    case 5: return "status_request";
    case 11:return "ec_point_format";
    case 10:return "supported_groups";
    case 35:return "session_ticket";
    case 22:return "encrypt_then_mac";
    case 23:return "extended_master_secret";
    case 13:return "signature_algorithms";
    case 43:return "supported_versions";
    case 45:return "psk_key_exchange_modes";
    case 51:return "key_share";
    case 21:return "padding";
    case 18:return "signed_certificate_timestamp";
    case 39578:return "Reserved (GREASE) (39578)";
    default:return "Unknown type";
    }
}

QString DataPackage::getTlsHandshakeExtensionECPointFormat(u_char type){
    
    switch (type) {
    
    case 0:return "EC point format: uncompressed (0)";
    case 1:return "EC point format: ansiX962_compressed_prime (1)";
    case 2:return "EC point format: ansiX962_compressed_char2 (2)";
    default:return QString::number(type);
    }
}

QString DataPackage::getTlsHandshakeExtensionSupportGroup(u_short type){
    
    switch (type) {
    
    case 0x001d:return "x25519 (0x001d)";
    case 0x0017:return "secp256r1 (0x0017)";
    case 0x001e:return "x448 (0x001e)";
    case 0x0019:return "secp521r1 (0x0019)";
    case 0x0018:return "secp384r1 (0x0018)";
    case 0x001c:return "brainpoolP512r1 (0x001c)";
    case 0x001b:return "brainpoolP384r1 (0x001b)";
    case 0x0016:return "secp256k1 (0x0016)";
    case 0x001a:return "brainpoolP256r1 (0x001a)";
    case 0x0015:return "secp224r1 (0x0015)";
    case 0x0014:return "secp224k1 (0x0014)";
    case 0x0013:return "secp192r1 (0x0013)";
    case 0x0012:return "secp192k1 (0x0012)";
    default:return "0x" + QString::number(type,16);
    }
}

QString DataPackage::getTlsHadshakeExtensionHash(u_char type){
    
    switch (type) {
    
    case 4:return "SHA256";
    case 5:return "SHA384";
    case 6:return "SHA512";
    case 2:return "SHA1";
    case 3:return "SHA224";
    case 1:return "MD5";
    default:return "Unknown";
    }
}
QString DataPackage::getTlsHadshakeExtensionSignature(u_char type){
    
    switch (type) {
    
    case 1:return "RSA";
    case 2:return "DSA";
    case 3:return "ECDSA";
    default:return "Unknown";
    }
}
u_short DataPackage::getTlsExtensionType(int offset){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    return ntohs(*ssl);
}

void DataPackage::getTlsExtensionServerName(int offset, u_short &type, u_short &length, u_short &listLength, u_char &nameType, u_short &nameLength, QString &name){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    listLength = ntohs(*ssl);
    ssl++;
    u_char*p = (u_char*)ssl;
    nameType = *p;
    p++;
    nameLength = (*p) * 16 + *(p+1);
    p += 2;
    for(int i = 0;i < nameLength;i++){
    
        name += (*p);
        p++;
    }
    return;
}

void DataPackage::getTlsExtensionKeyShare(int offset, u_short &type, u_short &length, u_short &shareLength, u_short &group, u_short &exchangeLength,QString &exchange){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    shareLength = ntohs(*ssl);
    ssl++;
    group = ntohs(*ssl);
    ssl++;
    exchangeLength = ntohs(*ssl);
    ssl++;
    u_char*point = (u_char*)(ssl);
    for(int i = 0;i < exchangeLength;i++){
    
        exchange += QString::number(*point,16);
        point++;
    }
}

void DataPackage::getTlsExtensionEcPointFormats(int offset, u_short &type, u_short &length,u_char& ecLength,QVector<u_char> &EC){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    u_char* point = (u_char*)(ssl);
    ecLength = *point;
    point++;
    for(int i = 0;i < ecLength;i++){
    
        EC.push_back(*point);
        point++;
    }
}

void DataPackage::getTlsExtensionOther(int offset, u_short &type, u_short &length,QString&data){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    u_char*point = (u_char*)(ssl);
    for(int i = 0;i < length;i++){
    
        data += QString::number(*point,16);
        point++;
    }
}

void DataPackage::getTlsExtensionSupportGroups(int offset, u_short &type, u_short &length, u_short &groupListLength, QVector<u_short> &group){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    groupListLength = ntohs(*ssl);
    ssl++;
    for(int i = 0;i < groupListLength/2;i++){
    
        group.push_back(ntohs(*ssl));
        ssl++;
    }
}

void DataPackage::getTlsExtensionSessionTicket(int offset, u_short &type, u_short &length){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
}

void DataPackage::getTlsExtensionEncryptThenMac(int offset, u_short &type, u_short &length){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
}

void DataPackage::getTlsExtensionExtendMasterSecret(int offset, u_short &type, u_short &length){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
}

void DataPackage::getTlsExtensionSignatureAlgorithms(int offset, u_short &type, u_short &length, u_short &algorithmLength, QVector<u_short> &signatureAlgorithm){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    algorithmLength = ntohs(*ssl);
    ssl++;
    for(int i = 0;i < algorithmLength/2;i++){
    
        signatureAlgorithm.push_back(ntohs(*ssl));
        ssl++;
    }
}

void DataPackage::getTlsExtensionSupportVersions(int offset, u_short &type, u_short &length, u_char &supportLength, QVector<u_short> &supportVersion){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    u_char*point = (u_char*)(ssl);
    supportLength = *point;
    point++;
    ssl = (u_short*)(point);
    for(int i = 0;i < supportLength;i++){
    
        supportVersion.push_back(ntohs(*ssl));
        ssl++;
    }
}
void DataPackage::getTlsExtensionPadding(int offset, u_short &type, u_short &length,QString& data){
    
    u_short*ssl;
    ssl = (u_short*)(pkt_content + 14 + 20 + offset);
    type = ntohs(*ssl);
    ssl++;
    length = ntohs(*ssl);
    ssl++;
    u_char*point = (u_char*)(ssl);
    for(int i = 0;i < length;i++){
    
        data += QString::number(*point,16);
        point++;
    }
}

6、Format.h

#ifndef FORMAT_H
#define FORMAT_H

/* @ This head file is used to define format of packages @ auther DJH-sudo @ if you have any question,pls contact me at [email protected] */

// define some types and macro defination
typedef unsigned char u_char;     // 1 byte
typedef unsigned short u_short;   // 2 byte
typedef unsigned int u_int;       // 4 byte
typedef unsigned long u_long;     // 4 byte

#define ARP "ARP" //
#define TCP "TCP" //
#define UDP "UDP" //
#define ICMP "ICMP" //
#define DNS "DNS" //
#define TLS "TLS" //
#define SSL "SSL" //
// Ethernet protocol format
/* +-------------------+-----------------+------+ | 6 byte | 6 byte |2 byte| +-------------------+-----------------+------+ |destination address| source address | type | +-------------------+-----------------+------+ */
typedef struct ether_header{
       // 14 byte
    u_char ether_des_host[6];  // destination addr [6 byte]
    u_char ether_src_host[6];  // source addr [6 byte]
    u_short ether_type;        // type [2 byte]
}ETHER_HEADER;


// Ipv4 header
/* +-------+-----------+---------------+-------------------------+ | 4 bit | 4 bit | 8 bit | 16 bit | +-------+-----------+---------------+-------------------------+ |version|head length| TOS/DS_byte | total length | +-------------------+--+---+---+----+-+-+-+-------------------+ | identification |R|D|M| offset | +-------------------+---------------+-+-+-+-------------------+ | ttl | protocal | checksum | +-------------------+---------------+-------------------------+ | source ip address | +-------------------------------------------------------------+ | destination ip address | +-------------------------------------------------------------+ */
typedef struct ip_header{
               // 20 byte
    u_char versiosn_head_length;    // version [4 bit] and length of header [4 bit]
    u_char TOS;                     // TOS/DS_byte [1 byte]
    u_short total_length;           // ip package total length [2 byte]
    u_short identification;         // identification [2 byte]
    u_short flag_offset;            // flag [3 bit] and offset [13 bit]
    u_char ttl;                     // TTL [1 byte]
    u_char protocol;                // protocal [1 byte]
    u_short checksum;               // checksum [2 byte]
    u_int src_addr;                 // source address [4 byte]
    u_int des_addr;                 // destination address [4 byte]
}IP_HEADER;
// Tcp header
/* +----------------------+---------------------+ | 16 bit | 16 bit | +----------------------+---------------------+ | source port | destination port | +----------------------+---------------------+ | sequence number | +----------------------+---------------------+ | ack number | +----+---------+-------+---------------------+ |head| reserve | flags | window size | +----+---------+-------+---------------------+ | checksum | urgent pointer | +----------------------+---------------------+ */
typedef struct tcp_header{
        // 20 byte
    u_short src_port;         // source port [2 byte]
    u_short des_port;         // destination [2 byte]
    u_int sequence;           // sequence number [4 byte]
    u_int ack;                // Confirm serial number [4 byte]
    u_char header_length;     // header length [4 bit]
    u_char flags;             // flags [6 bit]
    u_short window_size;      // size of window [2 byte]
    u_short checksum;         // checksum [2 byte]
    u_short urgent;           // urgent pointer [2 byte]
}TCP_HEADER;

// Udp header
/* +---------------------+---------------------+ | 16 bit | 16 bit | +---------------------+---------------------+ | source port | destination port | +---------------------+---------------------+ | data package length | checksum | +---------------------+---------------------+ */
typedef struct udp_header{
     // 8 byte
    u_short src_port;      // source port [2 byte]
    u_short des_port;      // destination port [2 byte]
    u_short data_length;   // data length [2 byte]
    u_short checksum;      // checksum [2 byte]

}UDP_HEADER;
// Icmp header
/* +---------------------+---------------------+ | 1 byte | 1 byte | 2 byte | +---------------------+---------------------+ | type | code | checksum | +---------------------+---------------------+ | identification | sequence | +---------------------+---------------------+ | option | +-------------------------------------------+ */
typedef struct icmp_header{
             // at least 8 byte
    u_char type;                    // type [1 byte]
    u_char code;                    // code [1 byte]
    u_short checksum;               // checksum [2 byte]
    u_short identification;         // identification [2 byte]
    u_short sequence;               // sequence [2 byte]
}ICMP_HEADER;

//Arp
/* |<-------- ARP header ------------>| +------+--------+-----+------+-------+----------+---------+---------------+--------------+ |2 byte| 2 byte |1byte| 1byte|2 byte | 6 byte | 4 byte | 6 byte | 4 byte | +------+--------+-----+------+-------+----------+---------+---------------+--------------+ | type |protocol|e_len|ip_len|op_type|source mac|source ip|destination mac|destination ip| +------+--------+-----+------+-------+----------+---------+---------------+--------------+ */
typedef struct arp_header{
       // 28 byte
    u_short hardware_type;   // hardware type [2 byte]
    u_short protocol_type;   // protocol [2 byte]
    u_char mac_length;       // MAC address length [1 byte]
    u_char ip_length;        // IP address length [1 byte]
    u_short op_code;         // operation code [2 byte]

    u_char src_eth_addr[6];  // source ether address [6 byte]
    u_char src_ip_addr[4];   // source ip address [4 byte]
    u_char des_eth_addr[6];  // destination ether address [6 byte]
    u_char des_ip_addr[4];   // destination ip address [4 byte]

}ARP_HEADER;
// dns
/* +--------------------------+---------------------------+ | 16 bit |1b|4bit|1b|1b|1b|1b|3b|4bit| +--------------------------+--+----+--+--+--+--+--+----+ | identification |QR| OP |AA|TC|RD|RA|..|Resp| +--------------------------+--+----+--+--+--+--+--+----+ | Question | Answer RRs | +--------------------------+---------------------------+ | Authority RRs | Additional RRs | +--------------------------+---------------------------+ */
typedef struct dns_header{
      // 12 byte
    u_short identification; // Identification [2 byte]
    u_short flags;          // Flags [total 2 byte]
    u_short question;       // Question Number [2 byte]
    u_short answer;         // Answer RRs [2 byte]
    u_short authority;      // Authority RRs [2 byte]
    u_short additional;     // Additional RRs [2 byte]
}DNS_HEADER;

// dns question
typedef struct dns_question{
    
    // char* name; // Non-fixed
    u_short query_type;     // 2 byte
    u_short query_class;    // 2 byte
}DNS_QUESITON;

typedef struct dns_answer{
    
    // char* name // Non-fixed
    u_short answer_type;   // 2 byte
    u_short answer_class;  // 2 byte
    u_int TTL;             // 4 byte
    u_short dataLength;    // 2 byte
    //char* name // Non-fixed
}DNS_ANSWER;

#endif // FORMAT_H

7、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <stdio.h>
#include <pcap.h>
#pragma comment(lib,"ws2_32.lib")
#include "capture.h"
#include "readonlydelegate.h"
#include <QVector>

QT_BEGIN_NAMESPACE
namespace Ui {
     class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    
    Q_OBJECT

public:
    // construction and destruction
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    // show network card
    void showNetworkCard();
    // capture the data package
    int capture();

private slots:
    void on_comboBox_currentIndexChanged(int index);
    void on_tableWidget_cellClicked(int row, int column);
    void on_lineEdit_returnPressed();
    void on_lineEdit_textChanged(const QString &arg1);
    void on_tableWidget_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);
public slots:
    void handleMessage(DataPackage data);
private:
    Ui::MainWindow *ui;
    pcap_if_t *all_devices;                 // all adapter device
    pcap_if_t *device;                      // An adapter
    pcap_t *pointer;                        // data package pointer
    ReadOnlyDelegate* readOnlyDelegate;     // readonly detegate
    int countNumber;                        // countNumber
    int rowNumber;                          // rowNumber
    QVector<DataPackage>data;               // store data
    char errbuf[PCAP_ERRBUF_SIZE];          // error buffer
    bool isStart;                           // the thread is start or not
};
#endif // MAINWINDOW_H

8、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "pcap.h"
#include <QDebug>
#include "winsock.h"
#include "capture.h"
#include <QStringList>
#include <QColor>
#include <QMessageBox>
#include <QTreeWidgetItem>
#include <QStringList>

/* * MainWindow * Constructure function * initialize the variables and GUI */
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
    ui->setupUi(this);
    statusBar()->showMessage("welcome to shark!");
    // set the toolbar
    ui->toolBar->addAction(ui->actionstart_capture);
    ui->toolBar->addAction(ui->actionclear_all);
    ui->toolBar->addAction(ui->actionup);
    ui->toolBar->addAction(ui->actiondown);
    ui->toolBar->addAction(ui->actionTop);
    ui->toolBar->addAction(ui->actionEnd);
    // show network card
    showNetworkCard();
    // initialization
    Capture *thread = new Capture;
    ui->comboBox->setEnabled(true);
    isStart = false;
    static bool index = false;
    countNumber = 0;
    rowNumber = -1;
    data.clear();
    device = nullptr;
    pointer = nullptr;

    // add the signal-slot
    connect(ui->actionstart_capture,&QAction::triggered,this,[=]{
    
        index = !index;
        if(index){
    
            if(ui->tableWidget->rowCount()){
    
                int type = QMessageBox::information(NULL,"information","Before restarting do you want to save result?","Save","Continue","Cancel");
                if(type == 0)
                {
    
                    // save the file...
                }else if(type == 1){
    
                    qDebug()<<"not save";
                }else{
    
                    index = !index;
                    isStart = false;
                    return;
                }
            }
            ui->tableWidget->clearContents();
            ui->tableWidget->setRowCount(0);
            ui->treeWidget->clear();
            countNumber = 0;
            rowNumber = -1;
            int dataSize = this->data.size();
            for(int i = 0;i < dataSize;i++){
    
                free((char*)(this->data[i].pkt_content));
                this->data[i].pkt_content = nullptr;
            }
            QVector<DataPackage>().swap(data);
            int res = capture();
            if(pointer && res != -1){
    
                thread->resetFlag();
                thread->setPointer(pointer);
                ui->comboBox->setEnabled(false);
                thread->start();
                ui->actionstart_capture->setIcon(QIcon(":/stop.png"));
                countNumber = 0;
                isStart = true;
            }else{
     // fail to start
                index = !index;
                countNumber = 0;
                rowNumber = -1;
                isStart = false;
            }
        }else{
    
            thread->setFlag();
            ui->comboBox->setEnabled(true);
            thread->quit();
            thread->wait();
            pcap_close(pointer);
            ui->actionstart_capture->setIcon(QIcon(":/start.png"));
            isStart = false;
        }
    });

    connect(ui->actionclear_all,&QAction::triggered,this,[=]{
    
        if(!isStart){
    
            int type = QMessageBox::information(this,"information","Do you want to clear all?","Yes","Cancel");
            if(type == 0){
    
                ui->tableWidget->clearContents();
                ui->tableWidget->setRowCount(0);
                ui->treeWidget->clear();
                countNumber = 0;
                rowNumber = -1;
                int dataSize = this->data.size();
                for(int i = 0;i < dataSize;i++){
    
                    free((char*)(this->data[i].pkt_content));
                    this->data[i].pkt_content = nullptr;
                }
                QVector<DataPackage>().swap(data);
            }else return;
        }
    });

    connect(ui->actionup,&QAction::triggered,this,[=]{
    
        int index = ui->tableWidget->currentRow();
        if(index > 0){
    
            ui->tableWidget->setCurrentCell(index - 1,0);
            on_tableWidget_cellClicked(index - 1,0);
        }else return;
    });

    connect(ui->actiondown,&QAction::triggered,this,[=]{
    
        int index = ui->tableWidget->currentRow();
        if(index >= 0 && index < ui->tableWidget->rowCount() - 1){
    
            ui->tableWidget->setCurrentCell(index + 1,0);
            on_tableWidget_cellClicked(index + 1,0);
        }else return;
    });

    connect(ui->actionTop,&QAction::triggered,this,[=]{
    
        int index = ui->tableWidget->currentRow();
        if(index > 0){
    
            ui->tableWidget->setCurrentCell(0,0);
            on_tableWidget_cellClicked(0,0);
        }else return;
    });

    connect(ui->actionEnd,&QAction::triggered,this,[=]{
    
        int index = ui->tableWidget->rowCount() - 1;
        if(index > 0){
    
            ui->tableWidget->setCurrentCell(index,0);
            on_tableWidget_cellClicked(index,0);
        }
    });

    connect(thread,&Capture::send,this,&MainWindow::handleMessage);

    // initialization
    ui->tableWidget->setShowGrid(false);
    ui->toolBar->setMovable(false);
    ui->tableWidget->verticalHeader()->setVisible(false);
    ui->tableWidget->setColumnCount(7);
    readOnlyDelegate = new ReadOnlyDelegate();
    ui->tableWidget->setItemDelegate(readOnlyDelegate);
    QStringList title = {
    "NO.","Time","Source","Destination","Protocol","Length","Info"};
    ui->tableWidget->setHorizontalHeaderLabels(title);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(30);
    ui->tableWidget->setColumnWidth(0,50);
    ui->tableWidget->setColumnWidth(1,150);
    ui->tableWidget->setColumnWidth(2,300);
    ui->tableWidget->setColumnWidth(3,300);
    ui->tableWidget->setColumnWidth(4,100);
    ui->tableWidget->setColumnWidth(5,100);
    ui->tableWidget->setColumnWidth(6,1000);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->treeWidget->setHeaderHidden(true);
}

/* * ~MainWindow * Destructure function * free memory */
MainWindow::~MainWindow()
{
    
    // free the memory you have allocated!
    int dataSize = this->data.size();
    for(int i = 0;i<dataSize;i++){
    
        free((char*)(this->data[i].pkt_content));
        this->data[i].pkt_content = nullptr;
    }
    // do not use 'data.clear()' only,it can't free totally!
    QVector<DataPackage>().swap(data);
    delete readOnlyDelegate;
    delete ui;
}

/* * showNetworkCard * scan the network cards and show information about it at combox */
void MainWindow::showNetworkCard(){
    
    int n = pcap_findalldevs(&all_devices,errbuf);
    ui->comboBox->clear();
    if(n == -1){
    
        statusBar()->showMessage("There is something wrong" + QString(errbuf));
        ui->comboBox->addItem("Cannot find a matching network card, please restart and test");
        return;
    }
    ui->comboBox->clear();
    ui->comboBox->addItem("please chose the Network Card!");
    for(device = all_devices;device!= nullptr;device = device->next){
    
        QString device_name = device->name;
        device_name.replace("\\Device\\","");
        QString device_description = device->description;
        QString item = device_name + " " + device_description;
        ui->comboBox->addItem(item);
    }
}

/* * on_comboBox_currentIndexChanged * when item of combox changed,the device pointer will also change * this function could ensure device pointer point to the selected network card */
void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    
    int i = 0;
    if(index!=0){
    
        for(device = all_devices;i<index - 1;i++,device = device->next);
    }else{
    
        device = nullptr;
    }
    return;
}

/* * capture * starting capture the data package from card * the data package in data link layer must meet the IEEE 802.3 protocol * or it will be throwed away */
int MainWindow::capture(){
    
    // pcap_t * pcap_open_live(char*device,int snaplen,int promisc,int to_ms,char*errbuf);
    if(device)
        pointer = pcap_open_live(device->name,65536,1,1000,errbuf);
    else{
    
        statusBar()->showMessage("pls choose Network Card!");
        return -1;
    }
    if(!pointer){
    
        statusBar()->showMessage(errbuf);
        pcap_freealldevs(all_devices);
        device = nullptr;
        return -1;
    }else{
    
        // check the data link IEEE 802.3
        if(pcap_datalink(pointer) != DLT_EN10MB){
    
            pcap_close(pointer);
            pcap_freealldevs(all_devices);
            device = nullptr;
            return -1;
        }
        statusBar()->showMessage(device->name);
    }
    return 0;
}

/* * handleMessage * slot function Auto trigger * This function will analysis package it received and show in the table */
void MainWindow::handleMessage(DataPackage data){
    
    ui->tableWidget->insertRow(countNumber);
    this->data.push_back(data);
    QString type = data.getPackageType();
    QColor color;
    // show different color
    if(type == TCP){
    
        color = QColor(216,191,216);
    }else if(type == TCP){
    
        color = QColor(144,238,144);
    }
    else if(type == ARP){
    
        color = QColor(238,238,0);
    }
    else if(type == DNS){
    
        color = QColor(255,255,224);
    }else if(type == TLS || type == SSL){
    
        color = QColor(210,149,210);
    }else{
    
        color = QColor(255,218,185);
    }
    ui->tableWidget->setItem(countNumber,0,new QTableWidgetItem(QString::number(countNumber + 1)));
    ui->tableWidget->setItem(countNumber,1,new QTableWidgetItem(data.getTimeStamp()));
    ui->tableWidget->setItem(countNumber,2,new QTableWidgetItem(data.getSource()));
    ui->tableWidget->setItem(countNumber,3,new QTableWidgetItem(data.getDestination()));
    ui->tableWidget->setItem(countNumber,4,new QTableWidgetItem(type));
    ui->tableWidget->setItem(countNumber,5,new QTableWidgetItem(data.getDataLength()));
    ui->tableWidget->setItem(countNumber,6,new QTableWidgetItem(data.getInfo()));
    // set color
    for(int i = 0;i < 7;i++){
    
        ui->tableWidget->item(countNumber,i)->setBackground(color);
    }
    countNumber++;
}

/* * on_tableWidget_cellClicked * click the table item the detail inforamation will show at the bottom tree widget * this function will analysis data pakckage chosed in detail */
void MainWindow::on_tableWidget_cellClicked(int row, int column)
{
    
    if(rowNumber == row || row < 0){
    
        return;
    }else{
    
        ui->treeWidget->clear();
        rowNumber = row;
        if(rowNumber < 0 || rowNumber > data.size())
            return;
        QString desMac = data[rowNumber].getDesMacAddr();
        QString srcMac = data[rowNumber].getSrcMacAddr();
        QString type = data[rowNumber].getMacType();
        QString tree1 = "Ethernet, Src:" +srcMac + ", Dst:" + desMac;
        QTreeWidgetItem*item = new QTreeWidgetItem(QStringList()<<tree1);
        ui->treeWidget->addTopLevelItem(item);

        item->addChild(new QTreeWidgetItem(QStringList()<<"Destination:" + desMac));
        item->addChild(new QTreeWidgetItem(QStringList()<<"Source:" + srcMac));
        item->addChild(new QTreeWidgetItem(QStringList()<<"Type:" + type));

        QString packageType = data[rowNumber].getPackageType();
        // arp package analysis
        if(packageType == ARP){
    
            QString ArpType = data[rowNumber].getArpOperationCode();
            QTreeWidgetItem*item2 = new QTreeWidgetItem(QStringList()<<"Address Resolution Protocol " + ArpType);
            ui->treeWidget->addTopLevelItem(item2);
            QString HardwareType = data[rowNumber].getArpHardwareType();
            QString protocolType = data[rowNumber].getArpProtocolType();
            QString HardwareSize = data[rowNumber].getArpHardwareLength();
            QString protocolSize = data[rowNumber].getArpProtocolLength();
            QString srcMacAddr = data[rowNumber].getArpSourceEtherAddr();
            QString desMacAddr = data[rowNumber].getArpDestinationEtherAddr();
            QString srcIpAddr = data[rowNumber].getArpSourceIpAddr();
            QString desIpAddr = data[rowNumber].getArpDestinationIpAddr();

            item2->addChild(new QTreeWidgetItem(QStringList()<<"Hardware type:" + HardwareType));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Protocol type:" + protocolType));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Hardware size:" + HardwareSize));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Protocol size:" + protocolSize));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Opcode:" + ArpType));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Sender MAC address:" + srcMacAddr));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Sender IP address:" + srcIpAddr));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Target MAC address:" + desMacAddr));
            item2->addChild(new QTreeWidgetItem(QStringList()<<"Target IP address:" + desIpAddr));
            return;
        }else {
     // ip package analysis
            QString srcIp = data[rowNumber].getSrcIpAddr();
            QString desIp = data[rowNumber].getDesIpAddr();

            QTreeWidgetItem*item3 = new QTreeWidgetItem(QStringList()<<"Internet Protocol Version 4, Src:" + srcIp + ", Dst:" + desIp);
            ui->treeWidget->addTopLevelItem(item3);

            QString version = data[rowNumber].getIpVersion();
            QString headerLength = data[rowNumber].getIpHeaderLength();
            QString Tos = data[rowNumber].getIpTos();
            QString totalLength = data[rowNumber].getIpTotalLength();
            QString id = "0x" + data[rowNumber].getIpIdentification();
            QString flags = data[rowNumber].getIpFlag();
            if(flags.size()<2)
                flags = "0" + flags;
            flags = "0x" + flags;
            QString FragmentOffset = data[rowNumber].getIpFragmentOffset();
            QString ttl = data[rowNumber].getIpTTL();
            QString protocol = data[rowNumber].getIpProtocol();
            QString checksum = "0x" + data[rowNumber].getIpCheckSum();
            int dataLengthofIp = totalLength.toUtf8().toInt() - 20;
            item3->addChild(new QTreeWidgetItem(QStringList()<<"0100 .... = Version:" + version));
            item3->addChild(new QTreeWidgetItem(QStringList()<<".... 0101 = Header Length:" + headerLength));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"TOS:" + Tos));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Total Length:" + totalLength));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Identification:" + id));

            QString reservedBit = data[rowNumber].getIpReservedBit();
            QString DF = data[rowNumber].getIpDF();
            QString MF = data[rowNumber].getIpMF();
            QString FLAG = ",";

            if(reservedBit == "1"){
    
                FLAG += "Reserved bit";
            }
            else if(DF == "1"){
    
                FLAG += "Don't fragment";
            }
            else if(MF == "1"){
    
                FLAG += "More fragment";
            }
            if(FLAG.size() == 1)
                FLAG = "";
            QTreeWidgetItem*bitTree = new QTreeWidgetItem(QStringList()<<"Flags:" + flags + FLAG);
            item3->addChild(bitTree);
            QString temp = reservedBit == "1"?"Set":"Not set";
            bitTree->addChild(new QTreeWidgetItem(QStringList()<<reservedBit + "... .... = Reserved bit:" + temp));
            temp = DF == "1"?"Set":"Not set";
            bitTree->addChild(new QTreeWidgetItem(QStringList()<<"." + DF + ".. .... = Don't fragment:" + temp));
            temp = MF == "1"?"Set":"Not set";
            bitTree->addChild(new QTreeWidgetItem(QStringList()<<".." + MF + ". .... = More fragment:" + temp));

            item3->addChild(new QTreeWidgetItem(QStringList()<<"Fragment Offset:" + FragmentOffset));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Time to Live:" + ttl));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Protocol:" + protocol));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Header checksum:" + checksum));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Source Address:" + srcIp));
            item3->addChild(new QTreeWidgetItem(QStringList()<<"Destination Address:" + desIp));

            if(packageType == TCP || packageType == TLS || packageType == SSL){
    
                QString desPort = data[rowNumber].getTcpDestinationPort();
                QString srcPort = data[rowNumber].getTcpSourcePort();
                QString ack = data[rowNumber].getTcpAcknowledgment();
                QString seq = data[rowNumber].getTcpSequence();
                QString headerLength = data[rowNumber].getTcpHeaderLength();
                int rawLength = data[rowNumber].getTcpRawHeaderLength().toUtf8().toInt();
                dataLengthofIp -= (rawLength * 4);
                QString dataLength = QString::number(dataLengthofIp);
                QString flag = data[rowNumber].getTcpFlags();
                while(flag.size()<2)
                    flag = "0" + flag;
                flag = "0x" + flag;
                QTreeWidgetItem*item4 = new QTreeWidgetItem(QStringList()<<"Transmission Control Protocol, Src Port:" + srcPort + ", Dst Port:" + desPort + ",Seq:" + seq + ", Ack:" + ack + ", Len:" + dataLength);

                ui->treeWidget->addTopLevelItem(item4);
                item4->addChild(new QTreeWidgetItem(QStringList()<<"Source Port:" + srcPort));
                item4->addChild(new QTreeWidgetItem(QStringList()<<"Destination Port:" + desPort));
                item4->addChild(new QTreeWidgetItem(QStringList()<<"Sequence Number (raw) :" + seq));
                item4->addChild(new QTreeWidgetItem(QStringList()<<"Ackowledgment Number (raw) :" + ack));


                QString sLength = QString::number(rawLength,2);
                while(sLength.size()<4)
                    sLength = "0" + sLength;
                item4->addChild(new QTreeWidgetItem(QStringList()<<sLength + " .... = Header Length:" + headerLength));

                QString PSH = data[rowNumber].getTcpPSH();
                QString URG = data[rowNumber].getTcpURG();
                QString ACK = data[rowNumber].getTcpACK();
                QString RST = data[rowNumber].getTcpRST();
                QString SYN = data[rowNumber].getTcpSYN();
                QString FIN = data[rowNumber].getTcpFIN();
                QString FLAG = "";

                if(PSH == "1")
                    FLAG += "PSH,";
                if(URG == "1")
                    FLAG += "UGR,";
                if(ACK == "1")
                    FLAG += "ACK,";
                if(RST == "1")
                    FLAG += "RST,";
                if(SYN == "1")
                    FLAG += "SYN,";
                if(FIN == "1")
                    FLAG += "FIN,";
                FLAG = FLAG.left(FLAG.length()-1);
                if(SYN == "1"){
    
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Sequence Number: 0 (relative sequence number)"));
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Acknowledgment Number: 0 (relative ack number)"));
                }
                if(SYN == "1" && ACK == "1"){
    
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Sequence Number: 0 (relative sequence number)"));
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"Acknowledgment Number: 1 (relative ack number)"));
                }
                QTreeWidgetItem*flagTree = new QTreeWidgetItem(QStringList()<<"Flags:" + flag + " (" + FLAG + ")");
                item4->addChild(flagTree);
                QString temp = URG == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .." + URG + ". .... = Urgent(URG):" + temp));
                temp = ACK == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... ..." + ACK + " .... = Acknowledgment(ACK):" + temp));
                temp = PSH == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... " + PSH + "... = Push(PSH):" + temp));
                temp = RST == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... ." + RST + ".. = Reset(RST):" + temp));
                temp = SYN == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... .." + SYN + ". = Syn(SYN):" + temp));
                temp = FIN == "1"?"Set":"Not set";
                flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... ..." + FIN + " = Fin(FIN):" + temp));

                QString window = data[rowNumber].getTcpWindowSize();
                QString checksum = "0x" + data[rowNumber].getTcpCheckSum();
                QString urgent = data[rowNumber].getTcpUrgentPointer();
                item4->addChild(new QTreeWidgetItem(QStringList()<<"window:" + window));
                item4->addChild(new QTreeWidgetItem(QStringList()<<"checksum:" + checksum));
                item4->addChild(new QTreeWidgetItem(QStringList()<<"Urgent Pointer:" + urgent));
                if((rawLength * 4) > 20){
    
                    QTreeWidgetItem * optionTree = new QTreeWidgetItem(QStringList()<<"Options: (" + QString::number(rawLength * 4 - 20) + ") bytes");
                    item4->addChild(optionTree);
                    for(int j = 0;j < (rawLength * 4 - 20);){
    
                        int kind = data[rowNumber].getTcpOperationRawKind(j);
                        switch (kind) {
    
                        case 0:{
    
                            QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - End of List (EOL)");
                            optionTree->addChild(subTree);
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind:End of List (0)"));
                            optionTree->addChild(subTree);
                            j++;
                            break;
                        }case 1:{
    
                            QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - No-Operation (NOP)");
                            optionTree->addChild(subTree);
                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind: No-Operation (1)"));
                            optionTree->addChild(subTree);
                            j++;
                            break;
                        }
                        case 2:{
    
                            u_short mss;
                            if(data[rowNumber].getTcpOperationMSS(j,mss)){
    
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - Maximun Segment Size: " + QString::number(mss) + " bytes");
                                optionTree->addChild(subTree);
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind: Maximun Segment Size (2)"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 4"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"MSS Value: " + QString::number(mss)));
                                j += 4;
                            }
                            break;
                        }
                        case 3:{
    
                            u_char shift;
                            if(data[rowNumber].getTcpOperationWSOPT(j,shift)){
    
                                int factor = 1 << shift;
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - Window scale: " + QString::number(shift) + " (multiply by " + QString::number(factor) + ")");
                                optionTree->addChild(subTree);
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"kind: Window scale (3)"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 3"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Shift Count: " + QString::number(shift)));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"[Multiplier: " + QString::number(factor) + "]"));
                                j += 3;
                            }
                            break;
                        }
                        case 4:{
    
                            if(data[rowNumber].getTcpOperationSACKP(j)){
    
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - SACK Permitted");
                                optionTree->addChild(subTree);
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Kind: SCAK Permitted (4)"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 2"));
                                j += 2;
                            }
                            break;
                        }
                        case 5:{
    
                            u_char length = 0;
                            QVector<u_int>edge;
                            if(data[rowNumber].getTcpOperationSACK(j,length,edge)){
    
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - SACK");
                                optionTree->addChild(subTree);
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Kind: SCAK (5)"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(length)));
                                int num = edge.size();
                                for(int k = 0;k < num;k += 2){
    
                                    subTree->addChild(new QTreeWidgetItem(QStringList()<<"left edge = " + QString::number(edge[k])));
                                    subTree->addChild(new QTreeWidgetItem(QStringList()<<"right edge = " + QString::number(edge[k + 1])));
                                }
                                j += length;
                            }
                            break;
                        }
                        case 8:{
    
                            u_int value = 0;
                            u_int reply = 0;
                            if(data[rowNumber].getTcpOperationTSPOT(j,value,reply)){
    
                                QString val = QString::number(value);
                                QString rep = QString::number(reply);
                                QTreeWidgetItem * subTree = new QTreeWidgetItem(QStringList()<<"TCP Option - TimeStamps: TSval " +val + ", TSecr " + rep);
                                optionTree->addChild(subTree);
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Kind: Time Stamp Option (8)"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: 10"));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Timestamp value: " + val));
                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Timestamp echo reply: " + rep));
                                j += 10;
                            }
                            break;
                        }
                        case 19:{
    
                            j += 18;
                            break;
                        }
                        case 28:{
    
                            j += 4;
                            break;
                        }
                        default:{
    
                            j++;
                            break;
                        }
                        }
                    }
                }
                if(dataLengthofIp > 0){
    
                    item4->addChild(new QTreeWidgetItem(QStringList()<<"TCP Payload (" + QString::number(dataLengthofIp) + ")"));
                    if(packageType == TLS){
    
                        QTreeWidgetItem* tlsTree = new QTreeWidgetItem(QStringList()<<"Transport Layer Security");
                        ui->treeWidget->addTopLevelItem(tlsTree);
                        u_char contentType = 0;
                        u_short version = 0;
                        u_short length = 0;
                        data[rowNumber].getTlsBasicInfo((rawLength * 4),contentType,version,length);
                        QString type = data[rowNumber].getTlsContentType(contentType);
                        QString vs = data[rowNumber].getTlsVersion(version);
                        switch (contentType) {
    
                        case 20:{
    
                            // ... TODO
                            break;
                        }
                        case 21:{
    
                            QTreeWidgetItem* tlsSubree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: Encrypted Alert");
                            tlsTree->addChild(tlsSubree);
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Alert Message: Encrypted Alert"));
                            break;
                        }
                        case 22:{
     // handshake
                            u_char handshakeType = 0;
                            data[rowNumber].getTlsHandshakeType((rawLength * 4 + 5),handshakeType);
                            if(handshakeType == 1){
     // client hello
                                int tlsLength = 0;
                                u_short rawVersion = 0;
                                QString random = "";
                                u_char sessionLength = 0;
                                QString sessionId = "";
                                u_short cipherLength = 0;
                                QVector<u_short>cipher;
                                u_char cmLength = 0;
                                QVector<u_char>compressionMethod;
                                u_short extensionLength = 0;
                                data[rowNumber].getTlsClientHelloInfo((rawLength * 4 + 5),handshakeType,tlsLength,rawVersion,random,sessionLength,sessionId,cipherLength,cipher,cmLength,compressionMethod,extensionLength);

                                QString type = data[rowNumber].getTlsHandshakeType(handshakeType);
                                QString tlsVersion = data[rowNumber].getTlsVersion(rawVersion);

                                QTreeWidgetItem* tlsSubTree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: " + type);
                                tlsTree->addChild(tlsSubTree);
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));

                                QTreeWidgetItem* handshakeTree = new QTreeWidgetItem(QStringList()<<"Handshake Protocol: " + type);
                                tlsSubTree->addChild(handshakeTree);
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Handshake Type: " + type + "(" + QString::number(handshakeType) + ")"));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(tlsLength)));

                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + tlsVersion + " (0x0" + QString::number(rawVersion) + ")"));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Random: " + random));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID Length: " + QString::number(sessionLength)));
                                if(sessionLength > 0){
    
                                    handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID: " + sessionId));
                                }
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Cipher Suites Length: " + QString::number(cipherLength)));
                                if(cipherLength > 0){
    
                                    QTreeWidgetItem* cipherTree = new QTreeWidgetItem(QStringList()<<"Cipher Suites (" + QString::number(cipherLength/2) + " suites)");
                                    handshakeTree->addChild(cipherTree);
                                    for(int k = 0;k < cipherLength/2;k++){
    
                                        QString temp = data[rowNumber].getTlsHandshakeCipherSuites(cipher[k]);
                                        cipherTree->addChild(new QTreeWidgetItem(QStringList()<<"Cipher Suite: " + temp));
                                    }
                                }
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Compression Method Length: " + QString::number(cmLength)));
                                if(cmLength > 0){
    
                                    QTreeWidgetItem* cmTree = new QTreeWidgetItem(QStringList()<<"Compression Methods (" + QString::number(cmLength) + " method)");
                                    handshakeTree->addChild(cmTree);
                                    for(int k = 0;k < cmLength;k++){
    
                                        QString temp = data[rowNumber].getTlsHandshakeCompression(compressionMethod[k]);
                                        cmTree->addChild(new QTreeWidgetItem(QStringList()<<"Compression Methods: " + temp + " (" + QString::number(compressionMethod[k]) + ")"));
                                    }
                                }
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Extensions Length: " + QString::number(extensionLength)));
                                if(extensionLength > 0){
    
                                    int exOffset = (rawLength * 4) + (tlsLength - extensionLength + 5 + 4);
                                    for(int k = 0;k < extensionLength;){
    
                                        int code = data[rowNumber].getTlsExtensionType(exOffset);
                                        u_short exType = 0;
                                        u_short exLength = 0;
                                        switch (code) {
    
                                        case 0:{
     // server_name
                                            u_short listLength = 0;
                                            u_char nameType = 0;
                                            u_short nameLength = 0;
                                            QString name = "";
                                            data[rowNumber].getTlsExtensionServerName(exOffset,exType,exLength,listLength,nameType,nameLength,name);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            if(exLength > 0 && listLength > 0){
    
                                                QTreeWidgetItem*serverTree = new QTreeWidgetItem(QStringList()<<"Server Name Indication extension");
                                                extensionTree->addChild(serverTree);
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name list length: " + QString::number(listLength)));
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name Type: " + QString::number(nameType)));
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name length: " + QString::number(nameLength)));
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name: " + name));
                                            }
                                            break;
                                        }
                                        case 11:{
    // ec_point_format
                                            u_char ecLength = 0;
                                            QVector<u_char>EC;
                                            data[rowNumber].getTlsExtensionEcPointFormats(exOffset,exType,exLength,ecLength,EC);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"EC point formats Length: " + QString::number(ecLength)));
                                            QTreeWidgetItem* EXTree = new QTreeWidgetItem(QStringList()<<"Elliptic curves point formats (" + QString::number(ecLength) + ")");
                                            extensionTree->addChild(EXTree);
                                            for(int g = 0;g < ecLength;g++){
    
                                                QString temp = data[rowNumber].getTlsHandshakeExtensionECPointFormat(EC[g]);
                                                EXTree->addChild(new QTreeWidgetItem(QStringList()<<temp));
                                            }
                                            break;
                                        }
                                        case 10:{
    // supported_groups
                                            u_short groupListLength = 0;
                                            QVector<u_short>group;
                                            data[rowNumber].getTlsExtensionSupportGroups(exOffset,exType,exLength,groupListLength,group);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Groups List Length: " + QString::number(groupListLength)));
                                            QTreeWidgetItem* sptTree = new QTreeWidgetItem(QStringList()<<"Supported Groups (" + QString::number(groupListLength/2) + " groups)");
                                            extensionTree->addChild(sptTree);
                                            for(int g = 0;g < groupListLength/2;g++){
    
                                                QString temp = data[rowNumber].getTlsHandshakeExtensionSupportGroup(group[g]);
                                                sptTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Group: " + temp));
                                            }
                                            break;
                                        }
                                        case 35:{
    // session_ticket
                                            data[rowNumber].getTlsExtensionSessionTicket(exOffset,exType,exLength);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            break;
                                        }
                                        case 22:{
    // encrypt_then_mac
                                            data[rowNumber].getTlsExtensionEncryptThenMac(exOffset,exType,exLength);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            break;
                                        }
                                        case 23:{
    // extended_master_secret
                                            data[rowNumber].getTlsExtensionExtendMasterSecret(exOffset,exType,exLength);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            break;
                                        }
                                        case 13:{
    // signature_algorithms
                                            u_short algorithmLength = 0;
                                            QVector<u_short>algorithm;
                                            data[rowNumber].getTlsExtensionSignatureAlgorithms(exOffset,exType,exLength,algorithmLength,algorithm);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms Length: " + QString::number(algorithmLength)));
                                            QTreeWidgetItem* sigTree = new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms (" + QString::number(algorithmLength/2) + " algorithms)");
                                            extensionTree->addChild(sigTree);
                                            for(int g = 0;g < algorithmLength/2;g++){
    
                                                QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Signature Algorithm: 0x0" + QString::number(algorithm[g],16));
                                                sigTree->addChild(subTree);
                                                QString hash = data[rowNumber].getTlsHadshakeExtensionHash((algorithm[g] & 0xff00) >> 8);
                                                QString sig = data[rowNumber].getTlsHadshakeExtensionSignature((algorithm[g] & 0x00ff));
                                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Hash: " + hash + " (" + QString::number((algorithm[g] & 0xff00) >> 8) + ")"));
                                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Signature: " + sig + " (" + QString::number(algorithm[g] & 0x00ff) + ")"));
                                            }
                                            break;
                                        }
                                        case 43:{
    // supported_versions
                                            u_char supportLength = 0;
                                            QVector<u_short>supportVersion;
                                            data[rowNumber].getTlsExtensionSupportVersions(exOffset,exType,exLength,supportLength,supportVersion);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Versions length: " + QString::number(supportLength)));
                                            for(int g = 0;g < supportLength/2;g++){
    
                                                QString temp = data[rowNumber].getTlsVersion(supportVersion[g]);
                                                extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Version: " + temp));
                                            }
                                            break;
                                        }
                                        case 51:{
    // key_share
                                            u_short shareLength = 0;
                                            u_short group = 0;
                                            u_short exchangeLength = 0;
                                            QString exchange = "";
                                            data[rowNumber].getTlsExtensionKeyShare(exOffset,exType,exLength,shareLength,group,exchangeLength,exchange);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));

                                            QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Key Share extension");
                                            extensionTree->addChild(subTree);
                                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Client Key Share Length: " + QString::number(shareLength)));
                                            QTreeWidgetItem* entryTree = new QTreeWidgetItem(QStringList()<<"Key Share Entry: Group ");
                                            subTree->addChild(entryTree);
                                            entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Group: " + QString::number(group)));
                                            entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange Length: " + QString::number(exchangeLength)));
                                            entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange: " + exchange));
                                            break;
                                        }
                                        case 21:{
    // padding
                                            QString rdata = "";
                                            data[rowNumber].getTlsExtensionPadding(exOffset,exType,exLength,rdata);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (21)"));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Padding Data: " + rdata));
                                            break;
                                        }
                                        default:{
    
                                            QString rdata = "";
                                            data[rowNumber].getTlsExtensionOther(exOffset,exType,exLength,rdata);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (" + QString::number(exType) + ")"));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Data: " + rdata));

                                            break;
                                        }
                                        }
                                        k += (exLength + 4);
                                        exOffset += (exLength + 4);
                                    }
                                }
                            }
                            else if(handshakeType == 2){
    // Server hello
                                int tlsLength = 0;
                                u_short rawVersion = 0;
                                QString random = "";
                                u_char sessionLength = 0;
                                QString sessionId = "";
                                u_short cipher = 0;
                                u_char compressionMethod = 0;
                                u_short extensionLength = 0;
                                data[rowNumber].getTlsServerHelloInfo((rawLength * 4 + 5),handshakeType,tlsLength,rawVersion,random,sessionLength,sessionId,cipher,compressionMethod,extensionLength);
                                QString type = data[rowNumber].getTlsHandshakeType(handshakeType);
                                QString tlsVersion = data[rowNumber].getTlsVersion(rawVersion);

                                QTreeWidgetItem* tlsSubTree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: " + type);
                                tlsTree->addChild(tlsSubTree);
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));

                                QTreeWidgetItem* handshakeTree = new QTreeWidgetItem(QStringList()<<"Handshake Protocol: " + type);
                                tlsSubTree->addChild(handshakeTree);
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Handshake Type: " + type + "(" + QString::number(handshakeType) + ")"));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(tlsLength)));

                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + tlsVersion + " (0x0" + QString::number(rawVersion,16) + ")"));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Random: " + random));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID Length: " + QString::number(sessionLength)));
                                if(sessionLength > 0){
    
                                    handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Session ID: " + sessionId));
                                }
                                QString temp = data[rowNumber].getTlsHandshakeCipherSuites(cipher);
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Cipher Suites: " +temp));
                                temp = data[rowNumber].getTlsHandshakeCompression(compressionMethod);
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Compression Methods: " + temp + " (" + QString::number(compressionMethod) + ")"));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Extensions Length: " + QString::number(extensionLength)));
                                if(extensionLength > 0){
    
                                    int exOffset = (rawLength * 4) + (tlsLength - extensionLength + 5 + 4);
                                    for(int k = 0;k < extensionLength;){
    
                                        int code = data[rowNumber].getTlsExtensionType(exOffset);
                                        u_short exType = 0;
                                        u_short exLength = 0;
                                        switch (code) {
    
                                        case 0:{
     // server_name
                                            u_short listLength = 0;
                                            u_char nameType = 0;
                                            u_short nameLength = 0;
                                            QString name = "";
                                            data[rowNumber].getTlsExtensionServerName(exOffset,exType,exLength,listLength,nameType,nameLength,name);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            if(exLength > 0 && listLength > 0){
    
                                                QTreeWidgetItem*serverTree = new QTreeWidgetItem(QStringList()<<"Server Name Indication extension");
                                                extensionTree->addChild(serverTree);
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name list length: " + QString::number(listLength)));
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name Type: " + QString::number(nameType)));
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name length: " + QString::number(nameLength)));
                                                serverTree->addChild(new QTreeWidgetItem(QStringList()<<"Server Name: " + name));
                                            }
                                            break;
                                        }
                                        case 11:{
    // ec_point_format
                                            u_char ecLength = 0;
                                            QVector<u_char>EC;
                                            data[rowNumber].getTlsExtensionEcPointFormats(exOffset,exType,exLength,ecLength,EC);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"EC point formats Length: " + QString::number(ecLength)));
                                            QTreeWidgetItem* EXTree = new QTreeWidgetItem(QStringList()<<"Elliptic curves point formats (" + QString::number(ecLength) + ")");
                                            extensionTree->addChild(EXTree);
                                            for(int g = 0;g < ecLength;g++){
    
                                                QString temp = data[rowNumber].getTlsHandshakeExtensionECPointFormat(EC[g]);
                                                EXTree->addChild(new QTreeWidgetItem(QStringList()<<temp));
                                            }
                                            break;
                                        }
                                        case 10:{
    // supported_groups
                                            u_short groupListLength = 0;
                                            QVector<u_short>group;
                                            data[rowNumber].getTlsExtensionSupportGroups(exOffset,exType,exLength,groupListLength,group);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Groups List Length: " + QString::number(groupListLength)));
                                            QTreeWidgetItem* sptTree = new QTreeWidgetItem(QStringList()<<"Supported Groups (" + QString::number(groupListLength/2) + " groups)");
                                            extensionTree->addChild(sptTree);
                                            for(int g = 0;g < groupListLength/2;g++){
    
                                                QString temp = data[rowNumber].getTlsHandshakeExtensionSupportGroup(group[g]);
                                                sptTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Group: " + temp));
                                            }
                                            break;
                                        }
                                        case 35:{
    // session_ticket
                                            data[rowNumber].getTlsExtensionSessionTicket(exOffset,exType,exLength);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            break;
                                        }
                                        case 22:{
    // encrypt_then_mac
                                            data[rowNumber].getTlsExtensionEncryptThenMac(exOffset,exType,exLength);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            break;
                                        }
                                        case 23:{
    // extended_master_secret
                                            data[rowNumber].getTlsExtensionExtendMasterSecret(exOffset,exType,exLength);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            break;
                                        }
                                        case 13:{
    // signature_algorithms
                                            u_short algorithmLength = 0;
                                            QVector<u_short>algorithm;
                                            data[rowNumber].getTlsExtensionSignatureAlgorithms(exOffset,exType,exLength,algorithmLength,algorithm);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms Length: " + QString::number(algorithmLength)));
                                            QTreeWidgetItem* sigTree = new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithms (" + QString::number(algorithmLength/2) + " algorithms)");
                                            extensionTree->addChild(sigTree);
                                            for(int g = 0;g < algorithmLength/2;g++){
    
                                                QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Signature Algorithm: 0x0" + QString::number(algorithm[g],16));
                                                sigTree->addChild(subTree);
                                                QString hash = data[rowNumber].getTlsHadshakeExtensionHash((algorithm[g] & 0xff00) >> 8);
                                                QString sig = data[rowNumber].getTlsHadshakeExtensionSignature((algorithm[g] & 0x00ff));
                                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Hash: " + hash + " (" + QString::number((algorithm[g] & 0xff00) >> 8) + ")"));
                                                subTree->addChild(new QTreeWidgetItem(QStringList()<<"Signature Hash Algorithm Signature: " + sig + " (" + QString::number(algorithm[g] & 0x00ff) + ")"));
                                            }
                                            break;
                                        }
                                        case 43:{
    // supported_versions
                                            u_char supportLength = 0;
                                            QVector<u_short>supportVersion;
                                            data[rowNumber].getTlsExtensionSupportVersions(exOffset,exType,exLength,supportLength,supportVersion);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Versions length: " + QString::number(supportLength)));
                                            for(int g = 0;g < supportLength/2;g++){
    
                                                QString temp = data[rowNumber].getTlsVersion(supportVersion[g]);
                                                extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Supported Version: " + temp));
                                            }
                                            break;
                                        }
                                        case 51:{
    // key_share
                                            u_short shareLength = 0;
                                            u_short group = 0;
                                            u_short exchangeLength = 0;
                                            QString exchange = "";
                                            data[rowNumber].getTlsExtensionKeyShare(exOffset,exType,exLength,shareLength,group,exchangeLength,exchange);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));

                                            QTreeWidgetItem*subTree = new QTreeWidgetItem(QStringList()<<"Key Share extension");
                                            extensionTree->addChild(subTree);
                                            subTree->addChild(new QTreeWidgetItem(QStringList()<<"Client Key Share Length: " + QString::number(shareLength)));
                                            QTreeWidgetItem* entryTree = new QTreeWidgetItem(QStringList()<<"Key Share Entry: Group ");
                                            subTree->addChild(entryTree);
                                            entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Group: " + QString::number(group)));
                                            entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange Length: " + QString::number(exchangeLength)));
                                            entryTree->addChild(new QTreeWidgetItem(QStringList()<<"Key Exchange: " + exchange));
                                            break;
                                        }
                                        case 21:{
    // padding
                                            QString rdata = "";
                                            data[rowNumber].getTlsExtensionPadding(exOffset,exType,exLength,rdata);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (21)"));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Padding Data: " + rdata));
                                            break;
                                        }
                                        default:{
    
                                            QString rdata = "";
                                            data[rowNumber].getTlsExtensionOther(exOffset,exType,exLength,rdata);
                                            QString subType = data[rowNumber].getTlsHandshakeExtension(exType);
                                            QTreeWidgetItem*extensionTree = new QTreeWidgetItem(QStringList()<<"Extension: " + subType + " (len=" + QString::number(exLength) + ")");
                                            handshakeTree->addChild(extensionTree);
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Type: " + subType + " (" + QString::number(exType) + ")"));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(exLength)));
                                            extensionTree->addChild(new QTreeWidgetItem(QStringList()<<"Data: " + rdata));

                                            break;
                                        }
                                        }
                                        k += (exLength + 4);
                                        exOffset += (exLength + 4);
                                    }
                                }

                            }
                            else if(handshakeType == 12){
    // Server Key Exchange
                                int tlsLength = 0;
                                u_char curveType = 0;
                                u_short curveName = 0;
                                u_char pubLength = 0;
                                QString pubKey = "";
                                u_short sigAlgorithm = 0;
                                u_short sigLength = 0;
                                QString sig = "";
                                data[rowNumber].getTlsServerKeyExchange((rawLength * 4 + 5),handshakeType,tlsLength,curveType,curveName,pubLength,pubKey,sigAlgorithm,sigLength,sig);
                                QString type = data[rowNumber].getTlsHandshakeType(handshakeType);

                                QTreeWidgetItem* tlsSubTree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: " + type);
                                tlsTree->addChild(tlsSubTree);
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                                tlsSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));

                                QTreeWidgetItem* handshakeTree = new QTreeWidgetItem(QStringList()<<"Handshake Protocol: " + type);
                                tlsSubTree->addChild(handshakeTree);
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Handshake Type: " + type + "(" + QString::number(handshakeType) + ")"));
                                handshakeTree->addChild(new QTreeWidgetItem(QStringList()<<"Length: " + QString::number(tlsLength)));

                            }
                            // ... TODO
                            break;
                        }
                        case 23:{
    
                            QTreeWidgetItem* tlsSubree = new QTreeWidgetItem(QStringList()<<vs + " Record Layer: " + type + " Protocol: http-over-tls");
                            tlsTree->addChild(tlsSubree);
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Content Type: " + type + " (" + QString::number(contentType) + ")"));
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Version: " + vs + " (0x0" + QString::number(version,16) + ")"));
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Length " + QString::number(length)));
                            tlsSubree->addChild(new QTreeWidgetItem(QStringList()<<"Encrypted Application Data: ..."));
                            break;
                        }
                        default:break;
                        }
                    }else if(packageType == SSL){
    
                        ui->treeWidget->addTopLevelItem(new QTreeWidgetItem(QStringList()<<"Transport Layer Security"));
                    }
                }
            }else if(packageType == UDP || packageType == DNS){
    
                QString srcPort = data[rowNumber].getUdpSourcePort();
                QString desPort = data[rowNumber].getUdpDestinationPort();
                QString Length = data[rowNumber].getUdpDataLength();
                QString checksum = "0x" + data[rowNumber].getUdpCheckSum();
                QTreeWidgetItem*item5 = new QTreeWidgetItem(QStringList()<<"User Datagram Protocol, Src Port:" + srcPort + ", Dst Port:" + desPort);
                ui->treeWidget->addTopLevelItem(item5);
                item5->addChild(new QTreeWidgetItem(QStringList()<<"Source Port:" + srcPort));
                item5->addChild(new QTreeWidgetItem(QStringList()<<"Destination Port:" + desPort));
                item5->addChild(new QTreeWidgetItem(QStringList()<<"length:" + Length));
                item5->addChild(new QTreeWidgetItem(QStringList()<<"Checksum:" + checksum));
                int udpLength = Length.toUtf8().toInt();
                if(udpLength > 0){
    
                    item5->addChild(new QTreeWidgetItem(QStringList()<<"UDP PayLoad (" + QString::number(udpLength - 8) + " bytes)"));
                }
                if(packageType == DNS){
    
                    QString transaction = "0x" + data[rowNumber].getDnsTransactionId();
                    QString QR = data[rowNumber].getDnsFlagsQR();
                    QString temp = "";
                    if(QR == "0") temp = "query";
                    if(QR == "1") temp = "response";
                    QString flags = "0x" + data[rowNumber].getDnsFlags();
                    QTreeWidgetItem*dnsTree = new QTreeWidgetItem(QStringList()<<"Domain Name System (" + temp + ")");
                    ui->treeWidget->addTopLevelItem(dnsTree);
                    dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Transaction ID:" + transaction));
                    QTreeWidgetItem* flagTree = new QTreeWidgetItem(QStringList()<<"Flags:" + flags);
                    dnsTree->addChild(flagTree);
                    temp = QR == "1"?"Message is a response":"Message is a query";
                    flagTree->addChild(new QTreeWidgetItem(QStringList()<<QR + "... .... .... .... = Response:" + temp));
                    QString Opcode = data[rowNumber].getDnsFlagsOpcode();
                    if(Opcode == "0") temp = "Standard query (0)";
                    else if(Opcode == "1") temp = "Reverse query (1)";
                    else if(Opcode == "2") temp = "Status request (2)";
                    flagTree->addChild(new QTreeWidgetItem(QStringList()<<".000 " + Opcode + "... .... .... = Opcode:" + temp));
                    if(QR == "1"){
    
                        QString AA = data[rowNumber].getDnsFlagsAA();
                        temp = AA == "1"?"Server is an authority for domain":"Server is not an authority for domain";
                        flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... ." + AA + ".. .... .... = Authoritative:" + temp));
                    }
                    QString TC = data[rowNumber].getDnsFlagsTC();
                    temp = TC == "1"?"Message is truncated":"Message is not truncated";
                    flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .." + TC + ". .... .... = Truncated:" + temp));

                    QString RD = data[rowNumber].getDnsFlagsRD();
                    temp = RD == "1"?"Do query recursively":"Do query not recursively";
                    flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... ..." + RD + " .... .... = Recursion desired:" + temp));

                    if(QR == "1"){
    
                        QString RA = data[rowNumber].getDnsFlagsRA();
                        temp = RA == "1"?"Server can do recursive queries":"Server can not do recursive queries";
                        flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... " + RA + "... .... = Recursion available:" + temp));
                    }
                    QString Z = data[rowNumber].getDnsFlagsZ();
                    while(Z.size()<3)
                        Z = "0" + Z;
                    flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... ." + Z + " .... = Z:reserved(" + Z + ")"));
                    if(QR == "1"){
    
                        QString Rcode = data[rowNumber].getDnsFlagsRcode();
                        if(Rcode == "0")
                            temp = "No error (0)";
                        else if(Rcode == "1") temp = "Format error (1)";
                        else if(Rcode == "2") temp = "Server failure (2)";
                        else if(Rcode == "3") temp = "Name Error (3)";
                        else if(Rcode == "4") temp = "Not Implemented (4)";
                        else if(Rcode == "5") temp = "Refused (5)";
                        int code = Rcode.toUtf8().toInt();
                        QString bCode = QString::number(code,2);
                        while (bCode.size()<4)
                            bCode = "0" + bCode;
                        flagTree->addChild(new QTreeWidgetItem(QStringList()<<".... .... .... " + bCode + " = Reply code:" + temp));
                    }

                    QString question = data[rowNumber].getDnsQuestionNumber();
                    dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Questions:" + question));
                    QString answer = data[rowNumber].getDnsAnswerNumber();
                    dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Answer RRs:" + answer));
                    QString authority = data[rowNumber].getDnsAuthorityNumber();
                    dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Authority RRs:" + authority));
                    QString additional = data[rowNumber].getDnsAdditionalNumber();
                    dnsTree->addChild(new QTreeWidgetItem(QStringList()<<"Additional RRs:" + additional));
                    int offset = 0;
                    if(question == "1"){
    
                        QString domainInfo;
                        int Type;
                        int Class;
                        data[rowNumber].getDnsQueriesDomain(domainInfo,Type,Class);
                        QTreeWidgetItem*queryDomainTree = new QTreeWidgetItem(QStringList()<<"Queries");
                        dnsTree->addChild(queryDomainTree);
                        offset += (4 + domainInfo.size() + 2);
                        QString type = data[rowNumber].getDnsDomainType(Type);
                        QTreeWidgetItem*querySubTree = new QTreeWidgetItem(QStringList()<<domainInfo + " type " + type + ", class IN");
                        queryDomainTree->addChild(querySubTree);
                        querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"Name:" + domainInfo));
                        querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"[Name Length:" + QString::number(domainInfo.size()) + "]"));
                        querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"Type:" + type + "(" + QString::number(Type) + ")"));
                        querySubTree->addChild(new QTreeWidgetItem(QStringList()<<"Class: IN (0x000" + QString::number(Class) + ")"));
                    }
                    int answerNumber = answer.toUtf8().toInt();
                    if(answerNumber > 0){
    
                        QTreeWidgetItem*answerTree = new QTreeWidgetItem(QStringList()<<"Answers");
                        dnsTree->addChild(answerTree);
                        for(int i = 0;i< answerNumber;i++){
    
                            QString name1;
                            QString name2;
                            u_short type;
                            u_short Class;
                            u_int ttl;
                            u_short length;

                            int tempOffset = data[rowNumber].getDnsAnswersDomain(offset,name1,type,Class,ttl,length,name2);
                            QString sType = data[rowNumber].getDnsDomainType(type);
                            QString temp = "";
                            if(type == 1) temp = "addr";
                            else if(type == 5) temp = "cname";
                            QTreeWidgetItem*answerSubTree = new QTreeWidgetItem(QStringList()<<name1 + ": type " + sType + ",class IN, " + temp + ":" + name2);
                            answerTree->addChild(answerSubTree);
                            answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Name:" + name1));
                            answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Type:" + sType + "(" + QString::number(type) + ")"));
                            answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Class: IN (0x000" + QString::number(Class) + ")"));
                            answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Time to live:" + QString::number(ttl) + "(" + QString::number(ttl) + " second)"));
                            answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<"Data length:" + QString::number(length)));
                            answerSubTree->addChild(new QTreeWidgetItem(QStringList()<<sType + ":" + name2));

                            offset += tempOffset;
                        }
                    }
                }
            }else if(packageType == ICMP){
    
                dataLengthofIp -= 8;
                QTreeWidgetItem*item6 = new QTreeWidgetItem(QStringList()<<"Internet Message Protocol");
                ui->treeWidget->addTopLevelItem(item6);
                QString type = data[rowNumber].getIcmpType();
                QString code = data[rowNumber].getIcmpCode();
                QString info = ui->tableWidget->item(row,6)->text();
                QString checksum = "0x" + data[rowNumber].getIcmpCheckSum();
                QString id = data[rowNumber].getIcmpIdentification();
                QString seq = data[rowNumber].getIcmpSequeue();
                item6->addChild(new QTreeWidgetItem(QStringList()<<"type:" + type + "(" + info + ")"));
                item6->addChild(new QTreeWidgetItem(QStringList()<<"code:" + code));
                item6->addChild(new QTreeWidgetItem(QStringList()<<"Checksum:" + checksum));
                item6->addChild(new QTreeWidgetItem(QStringList()<<"type:" + type + "(" + info + ")"));
                item6->addChild(new QTreeWidgetItem(QStringList()<<"Identifier:" + id));
                item6->addChild(new QTreeWidgetItem(QStringList()<<"Sequence Number:" + seq));
                if(dataLengthofIp > 0){
    
                    QTreeWidgetItem* dataItem = new QTreeWidgetItem(QStringList()<<"Data (" + QString::number(dataLengthofIp) + ") bytes");
                    item6->addChild(dataItem);
                    QString icmpData = data[rowNumber].getIcmpData(dataLengthofIp);
                    dataItem->addChild(new QTreeWidgetItem(QStringList()<<icmpData));
                }
            }
        }
        // the ethernet may have padding to ensure that the minimum length of the data packet is greater than 46
        int macDataLength = data[rowNumber].getIpTotalLength().toUtf8().toInt();
        int dataPackageLength = data[rowNumber].getDataLength().toUtf8().toInt();
        int delta = dataPackageLength - macDataLength;
        if(delta > 14){
    
            int padding = delta - 14;
            QString pad = "";
            while (pad.size() < padding * 2) {
    
                pad += "00";
            }
            item->addChild(new QTreeWidgetItem(QStringList()<<"Padding: " + pad));
        }
    }
}

/* * on_lineEdit_returnPressed * if you press the enter key,when capture is stopped * table will Filter eligible item */
void MainWindow::on_lineEdit_returnPressed()
{
    
    QString text = ui->lineEdit->text();
    text = text.toUpper();
    QString target = "#";
    if(text == "" || text == "UDP" || text == "TCP" || text == "DNS" || text == "ARP"|| text == "ICMP"|| text == "SSL" || text == "TLS"){
    
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(154,255,154);}");
        target = text;
    }else{
    
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(250,128,114);}");
    }
    int count = 0;
    int number = ui->tableWidget->rowCount();
    if(!isStart && target != "#"){
    
        if(target!=""){
    
            for(int i = 0;i < number;i++){
    
                if(ui->tableWidget->item(i,4)->text() != target){
    
                    ui->tableWidget->setRowHidden(i,true);
                }else{
    
                    ui->tableWidget->setRowHidden(i,false);
                    count++;
                }
            }
        }else{
    
            int number = ui->tableWidget->rowCount();
            for(int i = 0;i < number;i++){
    
                ui->tableWidget->setRowHidden(i,false);
                count++;
            }
        }
    }

    double res = 0;
    if(number != 0)
        res = (count*100.0)/number;
    statusBar()->showMessage("Have show (" + QString::number(count) + ") " +QString::number(res,10,2) + "%");
}

/* * on_lineEdit_textChanged * when text at lineEdit changed,it will check input information is correct or not * if it is corrected,the color is green or it will be red */
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
    
    QString text = arg1;
    text = text.toLower();
    if(text == "" || text == "udp" || text == "tcp" || text == "dns" || text == "arp" || text == "icmp" || text == "tls" || text == "ssl"){
    
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(154,255,154);}");
    }else{
    
        ui->lineEdit->setStyleSheet("QLineEdit {background-color: rgb(250,128,114);}");
    }
}

/* * on_tableWidget_currentCellChanged * this fucntion can response to up-down key * when you use the keyboard to manipulate,this bottom treewidget will also show information as well as you use mouse */
void MainWindow::on_tableWidget_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{
    
    if((currentRow != previousRow) && previousRow >= 0){
    
        on_tableWidget_cellClicked(currentRow,currentColumn);
    }else return;
}

9、readonlydelegate.h

#ifndef READONLYDELEGATE_H
#define READONLYDELEGATE_H

#include<QWidget>
#include<QItemDelegate>
#include<QStyleOptionViewItem>
class ReadOnlyDelegate: public QItemDelegate
{
    
public:
    ReadOnlyDelegate(QWidget *parent = nullptr):QItemDelegate(parent)
    {
    }

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override //final
    {
    
        Q_UNUSED(parent)
        Q_UNUSED(option)
        Q_UNUSED(index)
        return nullptr;
    }
};

#endif // READONLYDELEGATE_H

10、main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    
    /* * pls modify the shark.pro: * INCLUDEPATH += yourpath/Include * LIBS += your path/Lib/wpcap.lib libws2_32 * or IDE will warn you can't find some headerfiles! * this step helps us to add winpcap to our project actually */
    QApplication a(argc, argv);
    MainWindow w;
    w.setWindowTitle("Shark - @copyright by 卡布诺奇");
    w.show();
    return a.exec();
}

11、mainwindow.ui

img

原网站

版权声明
本文为[Cappuccino-jay]所创,转载请带上原文链接,感谢
https://blog.csdn.net/Cappuccino_jay/article/details/126257763