使用LightPcapNg输出pcapng报文文件

下载LightPcapNg

GitHub - hyh19962008/LightPcapNg: PcapNg read, write and manipulation API.

编译

cd src
make

或者
mkdir build
cd build
cmake ..
make

编译后可以在目录下找到liblight_pcapng.so和liblight_pcapng.a两个文件

pcapng文件格式

1. 文件整体结构

pcapng文件是由一个一个的Block组成的:

 2. Block结构

每个Block有四个部分,其中Block Type指定了这个Block的类型

3. Block类型

必要的Block类型, 它们在每个文件中至少应出现一次:

- Section Header Block: it defines the most important characteristics of the capture file.

- Interface Description Block: it defines the most important characteristics of the interface(s) used for capturing traffic.

可选的Block类型:

- Enhanced Packet Block: it contains a single captured packet, or a portion of it. It represents an evolution of the original Packet Block.

- Simple Packet Block: it contains a single captured packet, or a portion of it, with only a minimal set of information about it.

- Name Resolution Block: it defines the mapping from numeric addresses present in the packet dump and the canonical name counterpart.

- Interface Statistics Block: it defines how to store some statistical data (e.g. packet dropped, etc) which can be useful to undestand the conditions in which the capture has been made.

Block Type CodeDescription
0x00000000Reserved ???
0x00000001Interface Description Block
0x00000002Packet Block
0x00000003Simple Packet Block
0x00000004Name Resolution Block
0x00000005Interface Statistics Block
0x00000006Enhanced Packet Block
0x0A0D0D0ASection Header Block

4. 文件逻辑结构

4.1 Section Header块

Section Header中的属性为所有出现在其之后的Block所共享,你可以使用一个SHB来配置整个文件的属性:

 你也可以使用多个SHB分别配置不同的属性段:

4.2 Interface Description块

在同一个Section中可以配置多个Interface Description块,按照在Section中出现的顺序,他们分别拥有一个Interface ID,这个ID从0开始。

在Enhanced Packet Block中有一个Interface ID的字段,在其中填入相应的ID便可以使用对应的IDB的属性。

4.3 Section逻辑结构

4.4 文件逻辑结构示例1 - 最简单的数据报文组成

 4.5 文件逻辑结构示例2 - 复杂组成

5. Option属性

在每一个Block中都可以嵌入可选的Option属性,它们出现的位置在Block Body中,据此可以将Block Body分成两部分:Main和Option。其中Main是必须的,而Option是可选的。

> 注:草案中并没有使用Block Body Main这个称呼。

程序代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
#include "include/light_internal.h"
#include "include/light_pcapng.h"

#define LINKTYPE_ETHERNET 1
#define PCAPNG_OPTION_LEN_VARIABLE -1   // length is variable

    enum global_option_code_e {
        global_option_opt_code_endofopt,
        global_option_opt_code_comment
    };

    enum global_option_len_e {
        global_option_opt_len_endofopt = 0,
        global_option_opt_len_comment = PCAPNG_OPTION_LEN_VARIABLE
    };

    enum inface_desc_option_code_e {
        inface_desc_option_code_if_name = 2,
        inface_desc_option_code_if_description = 3,
        inface_desc_option_code_if_IPv4addr = 4,
        inface_desc_option_code_if_IPv6addr = 5,
        inface_desc_option_code_if_MACaddr = 6,
        inface_desc_option_code_if_EUIaddr = 7,
        inface_desc_option_code_if_speed = 8,
        inface_desc_option_code_if_ts_resol = 9,
        inface_desc_option_code_if_tzone = 10,
        inface_desc_option_code_if_filter = 11,
        inface_desc_option_code_if_os = 12,
        inface_desc_option_code_if_fcseln = 13,
        inface_desc_option_code_tsoffset = 14
    };

    enum inface_desc_option_len_e {
        inface_desc_option_len_if_name = PCAPNG_OPTION_LEN_VARIABLE,
        inface_desc_option_len_if_description = PCAPNG_OPTION_LEN_VARIABLE,
        inface_desc_option_len_if_IPv4addr = 8,
        inface_desc_option_len_if_IPv6addr = 17,
        inface_desc_option_len_if_MACaddr = 6,
        inface_desc_option_len_if_EUIaddr = 8,
        inface_desc_option_len_if_speed = 8,
        inface_desc_option_len_if_ts_resol = 1,
        inface_desc_option_len_if_tzone = 4,
        inface_desc_option_len_if_filter = PCAPNG_OPTION_LEN_VARIABLE,
        inface_desc_option_len_if_os = PCAPNG_OPTION_LEN_VARIABLE,
        inface_desc_option_len_if_fcseln = 1,
        inface_desc_option_len_tsoffset = 8
    };

    // 4 * 32bit = 16B
    typedef struct {
        uint32_t byte_order;
        uint16_t major_ver;
        uint16_t minor_ver;
        uint64_t section_length;
    }pcapng_section_header_body;

    // 2 * 32bit = 8B
    typedef struct {
        uint16_t linktype;
        uint16_t reserved;
        uint32_t snaplen;
        // options
    }pcapng_inface_desc_body;

    // 5 * 32bit = 20B
    typedef struct {
        uint32_t interface_id;
        uint32_t ts_high;
        uint32_t ts_low;
        uint32_t caplen;
        uint32_t len;
        // data PAD to 32bit
    }pcapng_enhanced_packet_body;

    /**
     * return a pointer to newly allocated memory,
     * putting pkt_hdr and packet_data in sequence
     * 
     */ 
    uint32_t *get_full_packet_block(pcapng_enhanced_packet_body *hdr, uint8_t *data, int data_len) {
        int size = sizeof(pcapng_enhanced_packet_body) + data_len;
        uint8_t *block = (uint8_t *)malloc(size);
        memset(block, 0, size);
        memcpy(block, hdr, sizeof(pcapng_enhanced_packet_body));
        memcpy(block + sizeof(pcapng_enhanced_packet_body), data, data_len);

        return (uint32_t *)block;
    }

    // 2 * block_len + block_type = 12B
    // opt_header = 4B 
    // opt_ending = 4B

    int main() { 
        uint8_t packet[] = {0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x08, 0x00, 0x45, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xf6, 0x63, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, 0x02, 0x02, 0xc0, 0x00, 0x0e, 0xc8, 0x00, 0x22, 0xa9, 0x49, 0x20, 0x40, 0x01, 0x18, 0x00, 0x00, 0x09, 0xcf, 0x00, 0x00, 0x11, 0x2f, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00}; 
        uint32_t option_value = 0;
        clock_t time = clock();
        pcapng_enhanced_packet_body pkt_hdr = {0, 0, clock(), sizeof(packet), sizeof(packet)};
        uint32_t *pkt_block;
        char option_str[255] = {};

        // pointer
        light_pcapng pcapng_file = NULL;
        light_pcapng prev_block = NULL;
        light_pcapng current_block = NULL;
        light_option option = NULL;    

        // SHB
        pcapng_section_header_body section_body = {BYTE_ORDER_MAGIC, 1, 0, 200};
        pcapng_file = light_alloc_block(LIGHT_SECTION_HEADER_BLOCK, (uint32_t *)&section_body, sizeof(pcapng_section_header_body));
        prev_block = pcapng_file;
        light_add_block(prev_block, current_block);
        // printf("%d\n", pcapng_file->block_total_lenght);

        // IDB
        pcapng_inface_desc_body inface_body = {LINKTYPE_ETHERNET, 0, 65535};
        current_block = light_alloc_block(LIGHT_INTERFACE_BLOCK, (uint32_t *)&inface_body, sizeof(pcapng_inface_desc_body));
        option_value = 6;   // ts_resolution 10^-6
        option = light_create_option(inface_desc_option_code_if_ts_resol, inface_desc_option_len_if_ts_resol, &option_value);
        light_add_option(pcapng_file, current_block, option, LIGHT_FALSE);
        light_add_block(prev_block, current_block);
        prev_block = current_block;
        // printf("%d\n", current_block->block_total_lenght);

        // Packets
        pkt_block = get_full_packet_block(&pkt_hdr, packet, sizeof(packet));
        current_block = light_alloc_block(LIGHT_ENHANCED_PACKET_BLOCK, (uint32_t *)pkt_block, sizeof(packet) + sizeof(pcapng_enhanced_packet_body));
        free(pkt_block);
        strcpy(option_str, "hello world");    // option 字段可用于输出调试信息
        option = light_create_option(global_option_opt_code_comment, strlen(option_str), &option_str);
        light_add_option(pcapng_file, current_block, option, LIGHT_FALSE);
        light_add_block(prev_block, current_block);
        prev_block = current_block;
        // printf("%d\n", current_block->block_total_lenght);

        pkt_hdr.ts_low = clock();
        pkt_block = get_full_packet_block(&pkt_hdr, packet, sizeof(packet));
        current_block = light_alloc_block(LIGHT_ENHANCED_PACKET_BLOCK, (uint32_t *)pkt_block, sizeof(packet) + sizeof(pcapng_enhanced_packet_body));
        free(pkt_block);
        light_add_block(prev_block, current_block);
        prev_block = current_block;

        // auto calc section lenght
        light_pcapng_to_file("output.pcapng", pcapng_file);

        light_pcapng_release(pcapng_file);

        return 0;
    }

参考资料

.pcapng文件格式和.pcap文件格式_书伯的博客-CSDN博客_pcapng

PCAP Next Generation Dump File Format

GitHub - pcapng/pcapng: PCAP next generation file format specification

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值