/* * Procedures to operate on pcap/pcapng file format * * (C) 2025 by sysmocom - s.f.m.c. GmbH * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * */ #pragma once #include #include enum osmo_pcap_fmt { OSMO_PCAP_FMT_PCAP = 0, OSMO_PCAP_FMT_PCAPNG, }; int osmo_pcap_file_discover_fmt(const uint8_t *data, size_t data_len, enum osmo_pcap_fmt *result_fmt); /*********************************************************** * Libpcap File Format (.pcap) * https://wiki.wireshark.org/Development/LibpcapFileFormat ***********************************************************/ #define OSMO_PCAP_FILE_MAGIC 0xa1b2c3d4 int osmo_pcap_file_msgb_append_global_header(struct msgb *msg, uint32_t snaplen, uint32_t linktype); unsigned int osmo_pcap_file_record_size(const struct pcap_pkthdr *in_hdr); int osmo_pcap_file_msgb_append_record(struct msgb *msg, const struct pcap_pkthdr *in_hdr, const uint8_t *data); /*********************************************************** * PCAP Next Generation (pcapng) Capture File Format * https://wiki.wireshark.org/Development/PcapNg * https://ietf-opsawg-wg.github.io/draft-ietf-opsawg-pcap/draft-ietf-opsawg-pcapng.html * Related: wireshark.git: wiretap/{pcapng.*, pcapio.c, pcapng_module.h}, wtap_opttypes.h, dumpcap.c ***********************************************************/ #define OSMO_PCAPNG_FILE_MAGIC 0x1A2B3C4D #define OSMO_PCAPNG_FILE_MAGIC_SWAPPED 0x4D3C2B1A #define BLOCK_TYPE_SHB 0x0A0D0D0A /* Section Header Block */ #define BLOCK_TYPE_IDB 0x00000001 /* Interface Description Block */ #define BLOCK_TYPE_PB 0x00000002 /* Packet Block (obsolete) */ #define BLOCK_TYPE_SPB 0x00000003 /* Simple Packet Block */ #define BLOCK_TYPE_EPB 0x00000006 /* Enhanced Packet Block */ /* Options for all blocks */ #define OPT_EOFOPT 0 #define OPT_COMMENT 1 /* Section Header block (SHB) */ #define OPT_SHB_HARDWARE 2 #define OPT_SHB_OS 3 #define OPT_SHB_USERAPPL 4 /* Interface Description block (IDB) */ #define OPT_IDB_NAME 2 #define OPT_IDB_DESCRIPTION 3 #define OPT_IDB_IP4ADDR 4 #define OPT_IDB_IP6ADDR 5 #define OPT_IDB_MACADDR 6 #define OPT_IDB_FILTER 11 /* filter Option: */ enum osmo_pcapng_file_if_filter_type { IF_FILTER_CAP = 0, /* pcap filter string */ IF_FILTER_BPF = 1 /* BPF program */ }; /* pcapng: common block header file encoding for every block type */ struct pcapng_block_header { uint32_t block_type; uint32_t block_total_length; uint8_t block_body[0]; /* x bytes block_body */ /* uint32_t block_total_length */ } __attribute__((packed)); struct pcapng_option_header { uint16_t type; uint16_t value_length; } __attribute__((packed)); /* pcapng: section header block file encoding */ struct pcapng_section_header_block { /* pcapng_block_header_t */ uint32_t magic; uint16_t version_major; uint16_t version_minor; uint64_t section_length; /* might be -1 for unknown */ /* ... Options ... */ } __attribute__((packed)); /* pcapng: interface description block file encoding */ struct pcapng_iface_descr_block { uint16_t linktype; uint16_t reserved; uint32_t snaplen; /* ... Options ... */ } __attribute__((packed)); /* pcapng: enhanced packet block file encoding */ struct pcapng_enhanced_packet_block { uint32_t interface_id; uint32_t timestamp_high; uint32_t timestamp_low; uint32_t captured_len; uint32_t packet_len; uint8_t packet_data[0]; /* ... Packet Data ... */ /* ... Padding ... */ /* ... Options ... */ } __attribute__((packed)); int osmo_pcapng_file_is_swapped(const uint8_t *data, size_t data_len); uint16_t osmo_pcapng_file_read_uint16(const uint8_t *data, bool endian_swapped); uint32_t osmo_pcapng_file_read_uint32(const uint8_t *data, bool endian_swapped); uint64_t osmo_pcapng_file_read_uint64(const uint8_t *data, bool endian_swapped); /* Helper APIs to encode blocks: */ struct osmo_pcapng_file_shb_pars { const char *hardware; const char *os; const char *userappl; }; unsigned int osmo_pcapng_file_shb_size(const struct osmo_pcapng_file_shb_pars *pars); int osmo_pcapng_file_msgb_append_shb(struct msgb *msg, const struct osmo_pcapng_file_shb_pars *pars); struct osmo_pcapng_file_idb_pars { const char *name; const char *filter; int link_type; int snap_len; }; unsigned int osmo_pcapng_file_idb_size(const struct osmo_pcapng_file_idb_pars *pars); int osmo_pcapng_file_msgb_append_idb(struct msgb *msg, const struct osmo_pcapng_file_idb_pars *pars); struct osmo_pcapng_file_epb_pars { uint64_t timestamp_usec; uint32_t interface_id; const uint8_t *captured_data; uint32_t captured_len; uint32_t packet_len; }; unsigned int osmo_pcapng_file_epb_size(const struct osmo_pcapng_file_epb_pars *pars); int osmo_pcapng_file_msgb_append_epb(struct msgb *msg, const struct osmo_pcapng_file_epb_pars *pars);