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 */

.


原文地址:https://www.cnblogs.com/lizhi0755/p/2740061.html