PcapFileEx.Merge.InterfaceMapper (pcap_file_ex v0.5.5)
View SourcePCAPNG interface ID remapping for multi-file merge.
When merging multiple PCAPNG files, interface IDs can collide (e.g., file1.pcapng and file2.pcapng both have interface 0). This module builds a global mapping: {file_idx, orig_id} -> remapped_id.
Example
# Two files, each with interfaces 0 and 1
mapping = InterfaceMapper.build_mapping(["f1.pcapng", "f2.pcapng"])
# => %{
# {0, 0} => 0, # File 0, interface 0 -> global 0
# {0, 1} => 1, # File 0, interface 1 -> global 1
# {1, 0} => 2, # File 1, interface 0 -> global 2
# {1, 1} => 3 # File 1, interface 1 -> global 3
# }Remapping Logic
For PCAP files (single interface):
- No remapping needed (interface_id is always nil/0)
- Mapping still created for consistency
For PCAPNG files (multi-interface):
- Each file's interface IDs are remapped to unique global IDs
- Remapping applied before packets enter merge heap
- Original interface ID preserved in annotation metadata
Summary
Functions
Builds a global interface ID mapping for all files.
Remaps a packet's interface ID using the global mapping.
Functions
@spec build_mapping([map()]) :: %{ required({non_neg_integer(), non_neg_integer()}) => non_neg_integer() }
Builds a global interface ID mapping for all files.
Scans each file to extract interface declarations and assigns unique global IDs to prevent collisions during merge.
Parameters
paths- List of file paths to mergefile_states- List of file state maps with reader and format info
Returns
Map of {file_idx, original_interface_id} => global_interface_id
Examples
mapping = InterfaceMapper.build_mapping(file_states)
# => %{{0, 0} => 0, {0, 1} => 1, {1, 0} => 2}
@spec remap_packet(PcapFileEx.Packet.t(), non_neg_integer(), map()) :: {PcapFileEx.Packet.t(), non_neg_integer()}
Remaps a packet's interface ID using the global mapping.
Parameters
packet- Packet struct to remapfile_idx- Index of the file this packet came frommapping- Global interface mapping
Returns
{remapped_packet, original_interface_id}
For PCAP packets (no interface_id field), returns {packet, 0} For PCAPNG packets, returns {packet_with_remapped_id, original_id}
Examples
mapping = %{{0, 0} => 0, {0, 1} => 1, {1, 0} => 2}
packet = %Packet{interface_id: 0, ...} # From file 1
{remapped, orig_id} = InterfaceMapper.remap_packet(packet, 1, mapping)
# => {%Packet{interface_id: 2, ...}, 0}