zoukankan      html  css  js  c++  java
  • pcap文件格式解析

    头文件pcap_format.h代码: 

    /* 分析解析pcap文件协议格式。
     * pcap格式文件可由tcpdump或者wireshark生成,文件格式组成如下:
     *      file header
     *      packet header
     *      packet data
     *      packet header
     *      packet data
     *      ......
     * 其中,file header为24字节,packet header为16字节,packet data为
     * 变长数据,其长度由packet header中数据帧长度字段(caplen)决定。
     *
     * 本代码主要为了解决数字测试仪回放数字录波器的录波文件(pcap格式文
     * 件)而编写的。
     *
     * 本代码支持win32平台和linux平台。
     *
     * Copyright,lizhi<ibox>
     *
     * 2012-10-10 V1.0 lizhi<QQ:252240557,msn:ddgooo@hotmail.com> created
     *
     
    */


    #ifndef __INCLUDE_PCAP_FORMAT_H
    #define __INCLUDE_PCAP_FORMAT_H

    /*
     * 头文件
     
    */
    #include "base_type.h"


    #if defined (__cplusplus)
    extern "C" {
    #endif /* defined (__cplusplus) */

    /*
     * 宏开关 定义为文件读写
     
    */
    #define PCAP_IOFILE

    /*
     * 宏定义文件的读写操作,可以根据需要改写该接口,如重定义
     * 为网口的recv\send、串口r\w等。
     *
     * _my_read_pcap_bufn/_my_read_pcap_bufn/_my_check_pcap_ptr - pcap的读写操作以及句柄检查接口
     * @pfd: 读写地址,可以为文件的fd、或者buffer地址等
     * @buf: 缓冲区地址
     * @count: 需要读写的字节数
     *
     
    */
    #if defined(PCAP_IOFILE)
    typedef int _my_pcap_ioptr;
    #define _my_read_pcap_bufn(pfd, buf, count)                     \
            do {                                                    \
                    if (read((pfd), (buf), (count)) <= 0) {         \
                            (pfd) = -1;                             \
                    }                                               \
            } while(0);
    #define _my_write_pcap_bufn(pfd, buf, count)                    \
            do {                                                    \
                    if (write((pfd), (buf), (count)) <= 0) {        \
                            (pfd) = -1;                             \
                    }                                               \
            } while(0);
    #define _my_check_pcap_ptr(pfd)                                    \
            (((pfd) != -1) && ((pfd) != 0))
    #elif defined(PCAP_IOBUFFER)
    typedef u8* _my_pcap_ioptr;
    #define _my_read_pcap_bufn(pfd, buf, count)                     \
            do {                                                    \
                    memcpy((buf), (pfd), (count));                  \
                    (pfd) += (count);                               \
            } while(0);
    #define _my_write_pcap_bufn(pfd, buf, count)                    \
            do {                                                    \
                    memcpy((pfd), (buf), (count));                  \
                    (pfd) += (count);                               \
            } while(0);
    #define _my_check_pcap_ptr(pfd)                                    \
            (((pfd) != -1) && ((pfd) != 0))
    #endif


    /*
     * 定义pcap文件格式中的头部信息(文件头部、数据包头部)的长度。
     *
     
    */
    #define PCAP_FILE_HEAD_SIZE     24
    #define PCAP_PACKET_HEAD_SIZE   16

    /*
     * pcap文件版本号(主版本号、次版本号)定义。
     *
     
    */
    #define PCAP_FILE_VERSION_MAJOR 2
    #define PCAP_FILE_VERSION_MINOR 4

    /*
     * pcap文件常用链路类型定义,最常用类型为1;基本描述:
     *      0:BSD loopback devices, except for later OpenBSD
     *      1:Ethernet, and Linux loopback devices
     *      6:802.5 Token Ring
     *      7:ARCnet
     *      8:SLIP
     *      9:PPP
     *      10:FDDI
     *      100:LLC/SNAP-encapsulated ATM
     *      101:“raw IP”, with no link
     *      102:BSD/OS SLIP
     *      103:BSD/OS PPP
     *      104:Cisco HDLC
     *      105:802.11
     *      108:later OpenBSD loopback devices (with the AF_value in network byte order)
     *      113:special Linux “cooked” capture
     *      114:LocalTalk
     *
     
    */
    #define PCAP_FILE_LINK_TYPE_BSD                 0
    #define PCAP_FILE_LINK_TYPE_ETHERNET            1
    #define PCAP_FILE_LINK_TYPE_802D5               6
    #define PCAP_FILE_LINK_TYPE_ARCNET              7
    #define PCAP_FILE_LINK_TYPE_SLIP                8
    #define PCAP_FILE_LINK_TYPE_PPP                 9
    #define PCAP_FILE_LINK_TYPE_FDDI                10
    #define PCAP_FILE_LINK_TYPE_LLC_SNAPATM         100
    #define PCAP_FILE_LINK_TYPE_RAW_IP              101
    #define PCAP_FILE_LINK_TYPE_BSD_OSSLIP          102
    #define PCAP_FILE_LINK_TYPE_BSD_OSPPP           103
    #define PCAP_FILE_LINK_TYPE_CISCOHDLC           104
    #define PCAP_FILE_LINK_TYPE_802D11              105
    #define PCAP_FILE_LINK_TYPE_OPENBSD             108
    #define PCAP_FILE_LINK_TYPE_LINUXCOOKED         113
    #define PCAP_FILE_LINK_TYPE_LOCALTALK           114

    /*
     * pcap_file_head - pcap(文件)头结构体,由24字节组成.
     * @magic:   4字节, 用来识别文件自己和字节顺序。0xa1b2c3d4用来表示按照原来的顺序读取,
     *            0xd4c3b2a1表示下面的字节都要交换顺序读取。一般,我们使用0xa1b2c3d4;
     *            保持网络字节顺序;
     * @major:   2字节, 主版本号;
     * @minor:   2字节, 次版本号;
     * @thiszone:4字节, 时区。GMT和本地时间的相差,用秒来表示。如果本地的时区是GMT,那么这
     *            个值就设置为0.这个值一般也设置为0
     * @sigfigs: 4字节, 精确时间戳,并未使用,目前全为0;
     * @snaplen: 4字节, 抓包最大长度,如果要抓全,设为0x0000ffff(65535),tcpdump -s 0就
     *            是设置这个参数,缺省为68字节;
     * @linktype:4字节, 链路类型, 一般都是1,类型说明见宏定义;
     *
     
    */
    struct pcap_file_head {
            u8  magic[4];
            u16 version_major;
            u16 version_minor;
            s32 thiszone;
            u32 sigfigs;
            u32 snaplen;
            u32 linktype;
    };

    /*
     * pcap_time_stamp - pcap包头中的时间戳结构体,由8字节组成
     * @second:时间戳高位,精确到秒
     * @microsecond:时间戳低位,精确到微秒
     *
     
    */
    struct pcap_time_stamp {
            u32 second;
            u32 microsecond;
    };

    /*
     * pcap_packet_head: pcap包头结构体,数据包头由16字节组成.
     * @timestamp:时间戳
     * @caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
     * @len:离线数据长度:网络中实际数据帧的长度,一般不大于caplen,多数情况下和caplen数值相等
     *
     * Packet 数据,即 Packet(通常就是链路层的数据帧)具体内容,长度为caplen,这个长
     * 度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就是说:PCAP文件里面
     * 并没有规定捕获的Packet数据包之间有什么间隔字符串,下一组数据在文件中的起始位
     * 置。我们需要靠第一个Packet包确定。
     *
     
    */
    struct pcap_packet_head {
            struct pcap_time_stamp ts;
            u32 caplen;
            u32 len;
    };

    /*
     * read_pcap_file_head - 读pcap(文件)头数据到结构体中。
     * @pfd: 输入参数,读地址;
     * @len: 输入参数,读数据长度;
     * @pfh:输出参数,pcap(文件)头结构体;
     * @counter: 输出参数,成功读入字节计数器;
     *
     * 读成功返回当前读地址,否则返回NULL;
     * 解析读取完成后的数据(pcap_file_head)采用主机字节顺序。
     *
     
    */
    _my_pcap_ioptr read_pcap_file_head(_my_pcap_ioptr pfd, int len, struct pcap_file_head *pfh, int *counter);

    /*
     * read_pcap_packet_head - 读pcap数据包头到结构体中。
     * @pfd: 输入参数,读地址;
     * @len: 输入参数,读数据长度;
     * @magic: 字节顺序标识;
     * @pfh:输出参数,pcap(文件)头结构体;
     * @counter: 输出参数,成功读入字节计数器;
     *
     * 读成功返回当前buf地址,否则返回NULL;
     * 解析读取完成后的数据(pcap_packet_head)采用主机字节顺序。
     *
     
    */
    _my_pcap_ioptr read_pcap_packet_head(_my_pcap_ioptr pfd, int len, u8 magic[4], struct pcap_packet_head *pph, int *counter);

    /*
     * read_pcap_packet_data - 读pcap数据包数据
     * @pfd: 输入参数,读地址;
     * @ppd:输出参数,数据;
     * @len: 输入参数,读数据长度;
     * @counter: 输出参数,成功读入字节计数器;
     *
     * 读成功返回当前buf地址,否则返回NULL;ppd的空间大小必须不小于len值,否则失败。
     *
     
    */
    _my_pcap_ioptr read_pcap_packet_data(_my_pcap_ioptr pfd, u8* ppd, int len, int *counter);


    /*
     * write_pcap_file_head - 写pcap头到文件中
     * @pfd: 输入参数,读地址;
     * @pfh:输入参数,pcap(文件)头结构体;
     * @count: 输出参数,成功写入的字节个数;
     *
     * 返回当前pfd指针,写失败返回NULL
     *
     
    */
    _my_pcap_ioptr write_pcap_file_head(_my_pcap_ioptr pfd, struct pcap_file_head *pfh, int *counter);

    /*
     * write_pcap_packet_head - 写pcap数据包头到文件中
     * @pfd: 输入参数,读地址;
     * @magic: 输入参数,字节顺序标识;
     * @pph:输入参数,数据包头结构体
     * @counter: 输出参数,成功写入字节计数器;
     *
     * 返回当前pfd指针,写失败返回NULL;
     *
     
    */
    _my_pcap_ioptr write_pcap_packet_head(_my_pcap_ioptr pfd, u8 magic[4], struct pcap_packet_head *pph, int* counter);

    /*
     * write_pcap_packet_data - 写pcap数据包数据到文件中
     * @pfd: 输入参数,读地址;
     * @ppd:输入参数,数据包数据;
     * @ppdlen: 输入参数,数据包数据长度;
     * @counter: 输出参数,成功写入字节计数器;
     *
     * 返回当前pfd指针,写失败返回NULL;
     *
     
    */
    _my_pcap_ioptr write_pcap_packet_data(_my_pcap_ioptr pfd, u8* ppd, int ppdlen, int* counter);



    /*
     * print_pcap_file_head - 打印pcap文件头数据
     * @pfh:输入参数,pcap(文件)头结构体;
     *
     
    */
    void print_pcap_file_head(struct pcap_file_head *pfh);

    /*
     * print_pcap_packet_head - 打印pcap数据包头数据
     * @pph:输入参数,pcap数据包头数据
     *
     
    */
    void print_pcap_packet_head(struct pcap_packet_head *pph);


    /*
     * print_pcap_packet_data - 打印pcap文件头数据
     * @ppd:输入参数,pcap数据包数据;
     * @ppdlen:输入参数,pcap数据包数据的长度;
     *
     
    */
    void print_pcap_packet_data(u8* ppd, int ppdlen);



    #if defined (__cplusplus)
    }
    #endif /* defined (__cplusplus) */


    #endif /* __INCLUDE_PCAP_FORMAT_H */

    c文件pcap_format.c代码: 

    /*
     * 分析解析pcap文件协议格式。
     *
     * 本代码支持win32平台和linux平台。
     *
     * Copyright,lizhi[ibox]
     *
     * 2012-10-10 V1.0 lizhi<QQ:252240557,msn:ddgooo@hotmail.com> created
     *
     
    */


    /*
     * 头文件
     
    */
    #include "base_type.h"
    #include "base_include.h"
    #include "base_debug.h"
    #include "base_endian.h"
    #include "base_function.h"
    #include "pcap_format.h"

    /*
     * 测试宏开关,pcap文件demo
     
    */
    /*
    #define PCAP_CONSOLE_DEMO
    // 
    */

    /*
     * _my_read_pcap_data/_my_write_pcap_data - 读取/写入并且转换pcap数据。
     * @src: 读写地址,为buffer地址;
     * @data:  读取/写入的数据;
     * @count: 需要读取/写入的字节个数;
     * @counter:  读取/写入的字节计数器;
     *
     
    */
    #define _my_read_pcap_data(src, data, count, counter)                   \
            do {                                                            \
                    if (_my_check_pcap_ptr(src)) {                          \
                            _my_read_pcap_bufn((src), (data), (count));     \
                            (counter) += (count);                           \
                    }                                                       \
            } while(0);
    #define _my_write_pcap_data(src, data, count, counter)                  \
            do {                                                            \
                    if (_my_check_pcap_ptr(src)) {                          \
                            _my_write_pcap_bufn((src), (data), (count));    \
                            (counter) +=(count);                            \
                    }                                                       \
            } while(0);


    /*
     * _my_read_pcap_to_host16/_my_read_pcap_to_host32 - 读取并且转换pcap数据。
     * @src: 读写地址,为buffer地址;
     * @data:  读取的数据;
     * @magic: 顺序标识,来自pcap文件中的magic标识;
     * @counter:  读取的字节计数器;
     *
     * 从pcap读取2字节或者4字节数据,并且根据magic顺序转换pcap数据到host顺序。
     *
     
    */
    #define _my_read_pcap_to_host16(src, data, magic, counter)              \
            do {                                                            \
                    if (_my_check_pcap_ptr(src)) {                          \
                            _my_read_pcap_bufn((src), &(data), 2);          \
                            if (0xA1 == *(magic)) {                         \
                                    data = _my_btoh16(data);                \
                            } else {                                        \
                                    data = _my_ltoh16(data);                \
                            }                                               \
                            (counter) += 2;                                 \
                    }                                                       \
            } while(0);
    #define _my_read_pcap_to_host32(src, data, magic, counter)              \
            do {                                                            \
                    if (_my_check_pcap_ptr(src)) {                          \
                            _my_read_pcap_bufn((src), &(data), 4);          \
                            if (0xA1 == *(magic)) {                         \
                                    data = _my_btoh32(data);                \
                            } else {                                        \
                                    data = _my_ltoh32(data);                \
                            }                                               \
                            (counter) += 4;                                 \
                    }                                                       \
            } while(0);

    /*
     * _my_write_host_to_pcap16/_my_write_host_to_pcap32 - 转换pcap数据并且写入。
     * @src: 写入地址,为buffer地址;
     * @data:  写入的数据;
     * @magic: 顺序标识,来自pcap文件中的magic标识;
     * @counter:  写入的字节计数器;
     *
     * 根据magic顺序转换pcap数据到host顺序,并且写入2字节或者4字节pcap数据。
     *
     
    */
    #define _my_write_host_to_pcap16(src, data, magic, counter)             \
            do {                                                            \
                    if (_my_check_pcap_ptr(src)) {                          \
                            u16 temp = data;                                \
                            if (0xA1 == *(magic)) {                         \
                                    temp = _my_htob16(data);                \
                            } else {                                        \
                                    temp = _my_htol16(data);                \
                            }                                               \
                            _my_write_pcap_bufn((src), &(temp), 2);         \
                            (counter) += 2;                                 \
                    }                                                       \
            } while(0);
    #define _my_write_host_to_pcap32(src, data, magic, counter)             \
            do {                                                            \
                    if (_my_check_pcap_ptr(src)) {                          \
                            u32 temp = data;                                \
                            if (0xA1 == *(magic)) {                         \
                                    temp = _my_htob32(data);                \
                            } else {                                        \
                                    temp = _my_htol32(data);                \
                            }                                               \
                            _my_write_pcap_bufn((src), &(temp), 4);         \
                            (counter) += 4;                                 \
                    }                                                       \
            } while(0);



    /*
     * read_pcap_file_head - 读pcap(文件)头数据到结构体中。
     * @pfd: 输入参数,读地址;
     * @len: 输入参数,数据缓冲区长度;
     * @pfh:输出参数,pcap(文件)头结构体;
     * @counter:  输出参数,读取的字节计数器;
     *
     * 读成功返回当前读地址,否则返回NULL;
     * 解析读取完成后的数据(pcap_file_head)采用主机字节顺序。
     *
     
    */
    _my_pcap_ioptr read_pcap_file_head(_my_pcap_ioptr pfd, int len, struct pcap_file_head *pfh, int *counter)
    {
            int oldnum = 0;
            _my_pcap_ioptr ptr = pfd;
            if (ptr && pfh && (PCAP_FILE_HEAD_SIZE <= len) && counter) {
                    oldnum = (*counter);
                    _my_read_pcap_data(ptr, pfh->magic, 4, *counter);
                    _my_read_pcap_to_host16(ptr, pfh->version_major, pfh->magic, *counter);
                    _my_read_pcap_to_host16(ptr, pfh->version_minor, pfh->magic, *counter);
                    _my_read_pcap_to_host32(ptr, pfh->thiszone, pfh->magic, *counter);
                    _my_read_pcap_to_host32(ptr, pfh->sigfigs, pfh->magic, *counter);
                    _my_read_pcap_to_host32(ptr, pfh->snaplen, pfh->magic, *counter);
                    _my_read_pcap_to_host32(ptr, pfh->linktype, pfh->magic, *counter);
                    if (PCAP_FILE_HEAD_SIZE == ((*counter) - oldnum)) {
                            return ptr;
                    }
            }
            return 0;
    }


    /*
     * read_pcap_packet_head - 读pcap数据包头到结构体中。
     * @pfd: 输入参数,读地址;
     * @len: 输入参数,读数据长度;
     * @magic: 字节顺序标识;
     * @pfh:输出参数,pcap(文件)头结构体;
     * @counter:  输出参数,读取的字节计数器;
     *
     * 读成功返回当前buf地址,否则返回NULL;
     * 解析读取完成后的数据(pcap_packet_head)采用主机字节顺序。
     *
     
    */
    _my_pcap_ioptr read_pcap_packet_head(_my_pcap_ioptr pfd, int len, u8 magic[4], struct pcap_packet_head *pph, int *counter)
    {
            int oldnum = 0;
            _my_pcap_ioptr ptr = pfd;
            if (ptr && pph && (PCAP_PACKET_HEAD_SIZE <= len) && counter) {
                    oldnum = (*counter);
                    _my_read_pcap_to_host32(ptr, pph->ts.second, magic, *counter);
                    _my_read_pcap_to_host32(ptr, pph->ts.microsecond, magic, *counter);
                    _my_read_pcap_to_host32(ptr, pph->caplen, magic, *counter);
                    _my_read_pcap_to_host32(ptr, pph->len, magic, *counter);
                    if (PCAP_PACKET_HEAD_SIZE == ((*counter) - oldnum)) {
                            return ptr;
                    }
            }
            return 0;
    }


    /*
     * read_pcap_packet_data - 读pcap数据包数据
     * @pfd: 输入参数,读地址;
     * @ppd:输出参数,数据;
     * @len: 输入参数,读数据长度;
     * @counter:  输出参数,读取的字节计数器;
     *
     * 读成功返回当前buf地址,否则返回NULL;ppd的空间大小必须不小于len值,否则失败。
     *
     
    */
    _my_pcap_ioptr read_pcap_packet_data(_my_pcap_ioptr pfd, u8* ppd, int len, int *counter)
    {
            _my_pcap_ioptr ptr = pfd;
            if ( ptr && ppd && (0 <= len) && counter) {
                    _my_read_pcap_data(ptr, ppd, len, *counter);
                    return ptr;
            }
            return 0;
    }



    /*
     * write_pcap_file_head - 写pcap头到文件中
     * @pfd: 输入参数,读地址;
     * @pfh:输入参数,pcap(文件)头结构体;
     * @counter: 输出参数,成功写入字节计数器;
     *
     * 返回当前pfd指针,写失败返回NULL
     *
     
    */
    _my_pcap_ioptr write_pcap_file_head(_my_pcap_ioptr pfd, struct pcap_file_head *pfh, int *counter)
    {
            u16 temp = 0;
            int oldnum = 0;
            _my_pcap_ioptr ptr = pfd;
            if (ptr && pfh && counter) {
                    oldnum = (*counter);
                    _my_write_pcap_data(ptr, pfh->magic, 4, *counter);
                    _my_write_host_to_pcap16(ptr, pfh->version_major, pfh->magic, *counter);
                    _my_write_host_to_pcap16(ptr, pfh->version_minor, pfh->magic, *counter);
                    _my_write_host_to_pcap32(ptr, pfh->thiszone, pfh->magic, *counter);
                    _my_write_host_to_pcap32(ptr, pfh->sigfigs, pfh->magic, *counter);
                    _my_write_host_to_pcap32(ptr, pfh->snaplen, pfh->magic, *counter);
                    _my_write_host_to_pcap32(ptr, pfh->linktype, pfh->magic, *counter);
                    if (PCAP_FILE_HEAD_SIZE == ((*counter) - oldnum)) {
                            return ptr;
                    }
            }
            return 0;

    }


    /*
     * write_pcap_packet_head - 写pcap数据包头到文件中
     * @pfd: 输入参数,读地址;
     * @magic: 输入参数,字节顺序标识;
     * @pph:输入参数,数据包头结构体
     * @counter: 输出参数,成功写入字节计数器;
     *
     * 返回当前pfd指针,写失败返回NULL;
     *
     
    */
    _my_pcap_ioptr write_pcap_packet_head(_my_pcap_ioptr pfd, u8 magic[4], struct pcap_packet_head *pph, int* counter)
    {
            int oldnum = 0;
            _my_pcap_ioptr ptr = pfd;
            if (ptr && pph && counter) {
                    oldnum = (*counter);
                    _my_write_host_to_pcap32(ptr, pph->ts.second, magic, *counter);
                    _my_write_host_to_pcap32(ptr, pph->ts.microsecond, magic, *counter);
                    _my_write_host_to_pcap32(ptr, pph->caplen, magic, *counter);
                    _my_write_host_to_pcap32(ptr, pph->len, magic, *counter);
                    if (PCAP_PACKET_HEAD_SIZE == ((*counter) - oldnum)) {
                            return ptr;
                    }
            }
            return 0;
    }


    /*
     * write_pcap_packet_data - 写pcap数据包数据到文件中
     * @pfd: 输入参数,读地址;
     * @ppd:输入参数,数据包数据;
     * @ppdlen: 输入参数,数据包数据长度;
     * @counter: 输出参数,成功写入字节计数器;
     *
     * 返回当前pfd指针,写失败返回NULL;
     *
     
    */
    _my_pcap_ioptr write_pcap_packet_data(_my_pcap_ioptr pfd, u8* ppd, int ppdlen, int* counter)
    {
            _my_pcap_ioptr ptr = pfd;
            if ( ptr && ppd && counter && (ppdlen > 0)) {
                    _my_write_pcap_data(ptr, ppd, ppdlen, *counter);
                    return ptr;
            }
            return 0;
    }



    /*
     * print_pcap_file_head - 打印pcap文件头数据
     * @pfh:输入参数,pcap(文件)头结构体;
     *
     
    */
    void print_pcap_file_head(struct pcap_file_head *pfh)
    {
            if ( pfh ) {
                    _my_printf("=====================\n");
                    _my_printf("magic:%02x%02x%02x%02x\n", pfh->magic[0], pfh->magic[1], pfh->magic[2], pfh->magic[3]);
                    _my_printf("version_major:%u [0x%08x]\n", pfh->version_major, pfh->version_major);
                    _my_printf("version_minor:%u [0x%08x]\n", pfh->version_minor, pfh->version_minor);
                    _my_printf("thiszone:%d [0x%08x]\n", pfh->thiszone, (u32)(pfh->thiszone));
                    _my_printf("sigfigs:%u [0x%08x]\n", pfh->sigfigs, pfh->sigfigs);
                    _my_printf("snaplen:%u [0x%08x]\n", pfh->snaplen, pfh->snaplen);
                    _my_printf("linktype:%u [0x%08x]\n", pfh->linktype, pfh->linktype);
                    _my_printf("=====================\n");
            }
    }


    /*
     * print_pcap_packet_head - 打印pcap数据包头数据
     * @pph:输入参数,pcap数据包头数据
     *
     
    */
    void print_pcap_packet_head(struct pcap_packet_head *pph)
    {
            if ( pph ) {
                    _my_printf("=====================\n");
                    _my_printf("ts.second:%u [0x%08x]\n", pph->ts.second, pph->ts.second);
                    _my_printf("ts.microsecond:%u [0x%08x]\n", pph->ts.microsecond, pph->ts.microsecond);
                    _my_printf("caplen:%u [0x%08x]\n", pph->caplen, pph->caplen);
                    _my_printf("len:%u [0x%08x]\n", pph->len, pph->len);
                    _my_printf("=====================\n");
            }
    }


    /*
     * print_pcap_packet_data - 打印pcap文件头数据
     * @ppd:输入参数,pcap数据包数据;
     * @ppdlen:输入参数,pcap数据包数据的长度;
     *
     
    */
    void print_pcap_packet_data(u8* ppd, int ppdlen)
    {
            u32 ipos = 0;
            if ( ppd ) {
                    _my_printf("\n====ppd:0x%x,len:%u=====", (int)ppd, ppdlen);
                    for (ipos=0; ipos < ppdlen; ipos++) {
                            if ((ipos % 16) ==0) {
                                    _my_printf("\n");
                            }
                            _my_printf("%02X ",(int)(*(ppd + ipos)));
                    }
                    _my_printf("\n=====================");
            }
    }


    #ifdef PCAP_CONSOLE_DEMO


    /*
     * _my_pcap_openrb/_my_pcap_openwb/_my_pcap_openab/_my_pcap_close
     *              - 可以根据需要改写该接口,如重定义为网口的recv\send、串口r\w等
     * @pfd:  文件地址、缓冲区地址、或者socket地址等
     * @str:  文件路径或者联机ip或者串口地址或者共享内存名称
     *
     
    */
    #ifdef PCAP_IOFILE
    #define _my_pcap_openrb(str)    (open((str), O_RDONLY | O_BINARY, S_IWRITE | S_IREAD))
    #define _my_pcap_openwb(str)    (open((str), O_CREAT | O_RDWR | O_BINARY, S_IWRITE | S_IREAD))
    #define _my_pcap_openab(str)    (open((str), O_CREAT | O_APPEND | O_RDWR | O_BINARY, S_IWRITE | S_IREAD))
    #define _my_pcap_close(pfd)     (close(pfd))
    #else /* 定义其他的io*/
    #endif



    /*
     * pcap_test_demo - 测试函数
     * @pcap_pathname:  pcap文件路径
     * @packet_pathname:  pcaket文件路径
     *
     
    */
    void pcap_test_demo(const char* pcap_pathname, const char* packet_pathname)
    {
            int read_count = 0;
            int pckt_count = 0;
            u8* ppd = 0;
            struct pcap_file_head pfh;
            struct pcap_packet_head pph;

            char chget;

            _my_pcap_ioptr fdpcap = 0;
            _my_pcap_ioptr fdpckt = 0;

            memset(&pfh, 0sizeof(struct pcap_file_head));
            memset(&pph, 0sizeof(struct pcap_packet_head));

            pckt_count = 0;
            read_count = 0;
            fdpcap =  _my_pcap_openrb(pcap_pathname);
            fdpckt =  _my_pcap_openab(packet_pathname);
            if ( fdpcap ) {
                    fdpcap = read_pcap_file_head(fdpcap, PCAP_FILE_HEAD_SIZE, &pfh, &read_count);
                    if (0 != fdpcap) {
                            _my_printf("press [s] to break, any other keys to show pcap file header data.....\n");
                            chget = getchar();
                            if (chget == 's') {
                                    return;
                            }
                            print_pcap_file_head(&pfh);
                            fdpckt = write_pcap_file_head(fdpckt, &pfh, &pckt_count);

                            while (!(chget == 's')) {
                                    _my_printf("press [s] to break, any other keys to continue showing pcap packet header data......\n");
                                    chget = getchar();
                                    if (chget == 's') {
                                            break;
                                    }
                                    fdpcap = read_pcap_packet_head(fdpcap, PCAP_PACKET_HEAD_SIZE, pfh.magic, &pph, &read_count);
                                    if (0 != fdpcap) {
                                            _my_printf("pcap data packet header count %d\n", pckt_count);
                                            print_pcap_packet_head(&pph);
                                            fdpckt = write_pcap_packet_head(fdpckt, pfh.magic, &pph, &pckt_count);
                                            _my_printf("press [s] to break, any other keys to continue showing pcap packet content data.......\n");
                                            chget = getchar();
                                            if (chget == 's') {
                                                    break;
                                            }
                                            ppd = (u8 *)_my_buf_malloc((size_t)(pph.caplen));
                                            fdpcap = read_pcap_packet_data(fdpcap, ppd, pph.caplen, &read_count);
                                            if ( 0 != fdpcap) {
                                                    print_pcap_packet_data(ppd, pph.caplen);
                                                    fdpckt = write_pcap_packet_data(fdpckt, ppd, pph.caplen, &pckt_count);
                                                    free(ppd);
                                                    ppd = 0;
                                                    continue;
                                            }
                                            _my_buf_free(ppd);
                                            ppd = 0;
                                    }
                                    break;
                            }
                    }
                    _my_pcap_close(fdpcap);
            }
    }


    /*
     * main - 测试main函数
     *
     
    */
    int main(int argc, char* argv[])
    {
            char pcap_pathname[255];
            char packet_pathname[255];

            pcap_test_demo(
                           "D:/09160016",
                           "D:/09160016.dat"
                           );



            return 0;
    }


    #endif /* PCAP_CONSOLE_DEMO */

    .


  • 相关阅读:
    2020重新出发,NOSQL,MongoDB分布式集群架构
    2020重新出发,NOSQL,MongoDB的操作和索引
    2020重新出发,NOSQL,MongoDB是什么?
    2020重新出发,NOSQL,redis高并发系统的分析和设计
    2020重新出发,NOSQL,redis互联网架构分析
    2020重新出发,NOSQL,Redis和数据库结合
    2020重新出发,NOSQL,Redis主从复制
    collections模块
    常用模块
    python面向对象的内置函数和反射
  • 原文地址:https://www.cnblogs.com/lizhi0755/p/2740061.html
Copyright © 2011-2022 走看看