• Parse Packets in Pcap format


    1. pcap_t* pcap_open_offline(const char* fname, char* errbuf)

    Open a savefile in the tcpdump/libpcap format to read packets.

    pcap_open_offline() is called to open a "savefile" for reading. fname specifies the name of the file to open. The file has the same format as those used by tcpdump(1) and tcpslice(1). The name "-" in a synonym for stdin. Alternatively, you may call pcap_fopen_offline() to read dumped data from an existing open stream fp. Note that on Windows, that stream should be opened in binary mode. errbuf is used to return error text and is only set when pcap_open_offline() or pcap_fopen_offline() fails and returns NULL.

    Regular Usage pcap_t * pcap = pcap_open_offline(file.c_str(), errbuff);

    2. pcap_next_ex

    read the next packet from a pcap_t

    #include <pcap/pcap.h>

    pcap_next_ex() returns 1 if the packet was read without problems, 0 if packets are being read from a live capture and the timeout expired, -1 if an error occurred while reading the packet, and -2 if packets are being read from a ``savefile'' and there are no more packets to read from the savefile. If -1 is returned,pcap_geterr() or pcap_perror() may be called with p as an argument to fetch or display the error text.

    Usage while(int returnValue = pcap_next_ex(pcap, &header, &data) >= 0)

    3. Pcap 文件格式

    上面介绍了两个用于解析 Pcap 文件的函数, 下面来分析下 Pcap 文件的具体格式

    Pcap 文件组成如下:

    Global Header

    Packet Header (1) /* 第一个数据包 */

    Packet Data (1)

    Packet Header (2)

    Packet Data (2)

    3.1 Global Header

    struct pcap_file_header {
            bpf_u_int32 magic;
            u_short version_major;
            u_short version_minor;
            bpf_int32 thiszone;    
            bpf_u_int32 sigfigs;   
            bpf_u_int32 snaplen;   
            bpf_u_int32 linktype;  
    };

    有了上面两个函数, 我们可以直接跳过 Global Header. 因此 global header 不需要关心.

     

    3.2 Packet Header

    Packet 指的是 Pcap Packet, Header 的定义是

    struct pcap_pkthdr {
            struct timeval ts;     
            bpf_u_int32 caplen;    
            bpf_u_int32 len;       
    };
    struct timeval {
            long            tv_sec;        
            suseconds_t     tv_usec;       
    };

    timeval , tv_sec 是秒, tv_usec 是毫秒, 使用的是 UTC 时间, 转化到大陆的时间需要加 8 小时.

     

    3.3 Packet Data

    Packet Data TCP/IP 协议意义上的数据包, Data 部分, 分别是

    以太网帧头 14 字节

    IP 20 字节

    TCP 一般 20 字节 or UDP (根据 IP 头的协议属性确定)

    Payload, 真正的数据.

     

    IP 头部协议类型:

     01    ICMP
     02    IGMP
     06    TCP
     17    UDP
     88    IGRP
     89    OSPF

     

    4. 需要注意

    [1] 描述了配置 visual studio 2010 + winpcap 环境具体步骤, 但需要注意最后一步把 winpcap.lib 改成 wpcap.lib 否则编译报错.

    [3] 给出了测试代码, 能够运行就表示配置成功, 注意, 假如创建的项目是 empty project, 那么需要在预处理器中额外添加 WIN32;

    [4] 有人在 stackoverflow 提问, 使用 [2] 给出的代码得出的记过不对. 有人回答网络流与大小端模式的转化关系, 比如使用ntohl, ntohs, inet_ntoa 函数.

     

    Reference

    [1] http://www.rhyous.com/2011/11/12/how-to-compile-winpcap-with-visual-studio-2010/

    [2] http://www.rhyous.com/2011/11/13/how-to-read-a-pcap-file-from-wireshark-with-c/

    [3] http://blog.csdn.net/caodesheng110/article/details/7670588

    [4] http://stackoverflow.com/questions/12999538/read-from-a-pcap-file-and-print-out-ip-addresses-and-port-numbers-in-c-but-my-r

  • 相关阅读:
    贪心法解活动安排问题
    求两个等长的已排序数组的中位数(《算法导论》P113习题9.3-8)
    0-1背包问题
    动态规划法解最长公共子序列问题
    动态规划法解矩阵链乘问题
    常见的算法设计策略
    A*算法与8数字谜题(参见《算法》P226习题2.5.32)
    keepalive+redis 主从高可用
    sharding-jdbc 读写分离+水平分表
    hash一致算法原理
  • 原文地址:https://www.cnblogs.com/zhouzhuo/p/3657576.html
Copyright © 2020-2023  润新知