基于Winpcap捕获网卡数据包,分析报文还原邮件数据内容

1.目前根据tcp协议,端口号(993),imap协议,过滤出收到邮件的数据。
2.怎么根据收到的数据报文,还原出邮件的内容?????

相关代码


void packet_handler(u_char* param, const pcap_pkthdr* header, const u_char* pkt_data)
{

    pcap_dump(param, header, pkt_data);

    struct tm* ltime;
    char timestr[16];
    time_t local_tv_sec;

    ip_header* ih;
    udp_header* uh;
    u_int ip_len;
    u_short sport, dport;
    
    //数据部分的长度
    int dataLength;
    dataLength = header->caplen;

    //tcp的头指针=tcp的头指针=ip头指针+ip包头的长度
    tcp_header* tcph;

    //Tcp数据的头指针  tcp数据头指针=tcp的头指针+tcp包头长度
    u_char* datantry;

    int tcp_len;

    /* 将时间戳转换成可识别的格式 */
    local_tv_sec = header->ts.tv_sec;
    ltime = localtime(&local_tv_sec);
    strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

    //printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);

    /* 打印数据包的时间戳和长度 */
    printf("时间戳:%s.%.6d 数据包长度:%d ", timestr, header->ts.tv_usec, header->len);

    /* 获得IP数据包头部的位置 */
    ih = (ip_header*)(pkt_data +
        14); //以太网头部长度  
    //printf("协议类型:%d\r\n", ih->proto);

    
     /* 获得TCP首部的位置 */
    ip_len = (ih->ver_ihl & 0xf) * 4;

    uh = (udp_header*)((u_char*)ih + ip_len);

    tcph = (tcp_header*)((u_char*)ih + ip_len);        //tcp的头指针=ip头指针+ip包头的长度
    tcp_len = (tcph->th_lenres & 0xf0) / 4;               //tcp->ver_thl & 0xf0表示取四位tcp_len
    datantry = (u_char*)((u_char*)tcph + tcp_len);         //tcp数据头指针=tcp的头指针+tcp包头长度



    /* 将网络字节序列转换成主机字节序列 */
    sport = ntohs(uh->sport);
    dport = ntohs(uh->dport);


    dataLength = dataLength - 14 - ip_len - tcp_len;  //这个2指(0d0a)


    bool is_pause = false;

    //判断tcp协议类型协议
    char http_type[4096] = "未知";
    if (ih->proto == 6)  //说明是tcp协议  6tcp  17udp  icmp1 igmp2  
    {
        printf("\n开始分析tcp/ip数据包...\n");
        int ip_len = ntohs(ih->tlen); /* get ip length, it contains header and body */

        int find_http = false;
        char* ip_pkt_data = (char*)ih;
        int n = 0;
        char buffer[65535];
        int bufsize = 0;

        //判断是HTTP的请求报文,还是响应报文  1请求(POST/GET)  2 响应(HTTP/1.1)  0不是http协议的报文
        int is_req_res = 0;

        //根据端口分析是那种类型25smtp(发送协议)  110 pop3(接受协议)
        if (dport == 80)  //http协议
        {
            for (; n < ip_len; n++)
            {
                /* http get or post request */
                if (!find_http && ((n + 3 < ip_len && strncmp(ip_pkt_data + n, "GET", strlen("GET")) == 0)
                    || (n + 4 < ip_len && strncmp(ip_pkt_data + n, "POST", strlen("POST")) == 0)))
                {
                    find_http = true;
                    is_req_res = 1;
                }




                /* http response */
                if (!find_http && n + 8 < ip_len && strncmp(ip_pkt_data + n, "HTTP/1.1", strlen("HTTP/1.1")) == 0)
                {
                    find_http = true;
                    is_req_res = 2;
                }

                /* if http is found */
                if (find_http)
                {
                    buffer[bufsize] = ip_pkt_data[n]; /* copy http data to buffer */
                    bufsize++;
                }
            }

            /* print http content */
            if (find_http)
            {

                buffer[bufsize] = '\0';
                printf("%s\n", buffer);
                printf("\n**********************************************\n");
                is_pause = true;
                //system("pause");

               


            }
        }

       


        if (dport == 25)
        {
            printf("\r\n\r\n检测到发送邮件\r\n");
#if 1
            system("pause");
#endif  //是否遇到发送邮件暂停

        }

        if (dport == 143)  //pop3协议  邮件接受协议
        {
            printf("\r\n\r\n检测到收到邮件1\r\n");
            system("pause");
        }
      


        if ( dport == 993 )  //pop3协议  邮件接受协议  993
        {
            printf("\r\n\r\n检测到收到邮件2\r\n");

            //对邮件的处理还原
            printf("DATA:%d\r\n", pkt_data);
            



#if 1
                system("pause");
#endif  //是否遇收到邮件暂停

        }

    }


        /* 打印IP地址和UDP端口 */
        printf("源ip:%d.%d.%d.%d.源端口;%d -> 目的ip:%d.%d.%d.%d.目的端口:%d ------协议类型:%d\r\n\n\n",
            ih->saddr.byte1,
            ih->saddr.byte2,
            ih->saddr.byte3,
            ih->saddr.byte4,
            sport,
            ih->daddr.byte1,
            ih->daddr.byte2,
            ih->daddr.byte3,
            ih->daddr.byte4,
            dport, ih->proto
        );

        //保存每帧的数据包
        //pcap_dump(param, header, pkt_data);



#if 0
        if (is_pause)
            system("pause");
#endif  //是否遇到HTTP报文暂停



    
}

运行相关截图:

img

img

解析为utf-8的方式进行解析。