我用winpcap 将数据包存在一个文件里,如何分析包里的数据呢? 我知道怎么得到象IP 地址这类的信息,但如何将包里真正有用的数据分析出来? 请高手指教! 有源码更好.
非常感谢!

解决方案 »

  1.   

    typedef struct _IP_HEADER
    {
    __u8            h_lenver;//4位首部长度+4位IP版本号
        __u8            tos;//8位服务类型TOS
        __u16           tot_len;//16位总长度(字节)
        __u16           id;//16位标识
        __u16           frag_off;//3位标志位
        __u8            ttl;//8位生存时间 TTL
        __u8            protocol;//8位协议 (TCP, UDP 或其他)
        __u16           check;//16位IP首部校验和
        __u32           saddr;//32位源IP地址
        __u32           daddr;//32位目的IP地址
    }IP_HEADER;
    analyse IP package,and consult TestApp example
      

  2.   

    建议看 《TCP IP详解 协议》
      

  3.   

    BOOL CNetListener::InterpretPacket(struct pcap_pkthdr *m_pPacketHead, // 输入参数
       unsigned char *m_strPacketData, // 输入参数
              struct structTCPPacketData *m_pIPHeadResult) // 输出参数
    {
    struct structIPPacketHead *m_pIPHeader;
    int m_nProtocol,m_nUserDataBytes = 0;
    SOCKADDR_IN m_structSockAdd; m_pIPHeader = (struct structIPPacketHead *)(m_strPacketData + 14); // check protocol
    m_nProtocol = m_pIPHeader->proto;
    if (CheckProtocol(m_nProtocol,m_pIPHeadResult->m_strProtocolName) == FALSE)
    return FALSE; // Get Source IP and Dest IP address
    m_structSockAdd.sin_addr.s_addr = m_pIPHeader->sourceIP;
    strcpy(m_pIPHeadResult->m_strSourceIP,inet_ntoa(m_structSockAdd.sin_addr));
    m_structSockAdd.sin_addr.s_addr = m_pIPHeader->destIP;
    strcpy(m_pIPHeadResult->m_strDestIP,inet_ntoa(m_structSockAdd.sin_addr)); // Get IP head infomation
    m_pIPHeadResult->m_strExistTime   = m_pIPHeader->ttl;
    m_pIPHeadResult->m_nHeadLength    = sizeof(unsigned long)*(m_pIPHeader->h_lenver & 0xf);
    m_pIPHeadResult->m_nIPVersion     = (unsigned short)(m_pIPHeader->h_lenver & 0xf0);
    m_pIPHeadResult->m_nID            = (unsigned int)m_pIPHeader->ident;
    m_pIPHeadResult->m_nFlagsBit      = m_pIPHeader->frag_and_flags;
    m_pIPHeadResult->m_nCheckSum      = m_pIPHeader->checksum;
    m_pIPHeadResult->m_nOption   = m_pIPHeader->option;
    // m_pIPHeadResult->m_nTotalLength   = m_pIPHeader->total_len;  //  ntohl(...) 
    m_pIPHeadResult->m_nTotalLength   = ntohs(m_pIPHeader->total_len);
    m_pIPHeadResult->m_nUserDataLen   = m_pIPHeadResult->m_nTotalLength - m_pIPHeadResult->m_nHeadLength - 20;
    m_pIPHeadResult->m_strServiceType = m_pIPHeader->tos; if (m_pIPHeadResult->m_nUserDataLen > MAX_USER_DATA - 1)
    m_pIPHeadResult->m_nUserDataLen = MAX_USER_DATA - 1; // 14 bytes for ethenet head;20 bytes for ip head;20 bytes for tcp head
    // so i write down code like this : "(m_strPacketData+54)"
    memset(m_pIPHeadResult->m_strPacketUserData,0,MAX_USER_DATA);
    memcpy(m_pIPHeadResult->m_strPacketUserData,(void *)(m_strPacketData + 54),m_pIPHeadResult->m_nUserDataLen);
    m_pIPHeadResult->m_strPacketUserData[m_pIPHeadResult->m_nUserDataLen] = NULL; // Decode Sub Protocol:TCP, UDP, ICMP, etc
    /*
    switch(iProtocol)
    {
    case IPPROTO_TCP :DecodeTcpPack(buf+iIphLen);break;
    case IPPROTO_UDP :DecodeUdpPack(buf+iIphLen);break;
    case IPPROTO_ICMP :DecodeIcmpPack(buf+iIphLen);break;
    default :break;
    }
    */
    return TRUE;
    }BOOL CNetListener::CheckProtocol(int m_nProtocol,char *m_strProtocol)
    {
    struct ProtoMap structProtoMap[MAX_PROTO_NUM] = { // 为子协议映射表赋值
    {IPPROTO_IP ,"IP "},{IPPROTO_ICMP,"ICMP"},{IPPROTO_IGMP,"IGMP"},
    {IPPROTO_GGP,"GGP "},{IPPROTO_TCP ,"TCP "},{IPPROTO_PUP ,"PUP "},
    {IPPROTO_UDP,"UDP "},{IPPROTO_IDP ,"IDP "},{IPPROTO_ND  ,"NP "},
    {IPPROTO_RAW,"RAW "},{IPPROTO_MAX ,"MAX "},{NULL        ,"    "}}; if (m_strProtocol == NULL || m_nProtocol < 0)
    return FALSE; for (int i = 0;i < MAX_PROTO_NUM; i++)
    {
    if (structProtoMap[i].m_nProtoNum == m_nProtocol)
    {
    strcpy(m_strProtocol,structProtoMap[i].m_strProtoText);
    return TRUE;
    }
    } return FALSE;
    }struct ProtoMap  // 定义子协议映射表
    {
    int  m_nProtoNum;
    char m_strProtoText[MAX_PROTO_TEXT_LEN];
    };// 4 bytes IP address
    typedef struct ip_address
    {
    u_char byte1;
        u_char byte2;
        u_char byte3;
        u_char byte4;
    }ip_address;struct structTCPPacketData
    {
    // Below TCP packet head info
    int  m_nIPVersion; // IP 版本号
    int  m_nHeadLength; // 首部长度
    int  m_nFlagsBit; // 标志位 
    int  m_nCheckSum; // IP 首部校验和
    int  m_nOption; // 附加选项
    unsigned int m_nID; // 位标识  long m_nTotalLength; // 总长度(字节)
    long m_strExistTime; // 生存时间 TTL char m_strProtocolType[16]; // 协议类型
    char m_strServiceType; // 服务类型
    char m_strProtocolName[16]; // 协议 (TCP, UDP 或其他)
    char m_strSourceIP[16]; // 源 IP 地址
    char m_strDestIP[16]; // 目的 IP 地址 // Above TCP packet head info char m_strPacketUserData[MAX_USER_DATA]; // 一个包中用户发送的数据
    int  m_nUserDataLen; // 用户发送数据的实际长度
    };struct structTCPPacketHead // 定义 TCP 首部
    {
    unsigned short th_sport;  // 16 位源端口
    unsigned short th_dport;  // 16 位目的端口
    unsigned int th_seq;  // 32 位序列号
    unsigned int th_ack;  // 32 位确认号
    unsigned char th_lenres;  //  4 位首部长度/6 位保留字
    unsigned char th_flag;  //  6 位标志位
    unsigned short th_win;  // 16 位窗口大小
    unsigned short th_sum;  // 16 位校验和
    unsigned short th_urp;  // 16 位紧急数据偏移量
    };struct structIPPacketHead
    {
    unsigned char h_lenver;  // 4 位首部长度 +4 位 IP 版本号
    unsigned char tos;  // 8 位服务类型 TOS
    unsigned short total_len;  // 16 位总长度(字节)
    unsigned short ident;  // 16 位标识
    unsigned short frag_and_flags;  // 3 位标志位
    unsigned char ttl;  // 8 位生存时间 TTL
    unsigned char proto;  // 8 位协议 (TCP, UDP 或其他)
    unsigned short checksum;  // 16 位 IP 首部校验和
    unsigned int sourceIP;  // 32 位源 IP 地址
    unsigned int destIP;  // 32 位目的 IP 地址
    unsigned int option; // 附加选项
    };