PcapFileEx.Merge.InterfaceMapper (pcap_file_ex v0.5.5)

View Source

PCAPNG 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

build_mapping(file_states)

@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 merge
  • file_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}

remap_packet(packet, file_idx, mapping)

Remaps a packet's interface ID using the global mapping.

Parameters

  • packet - Packet struct to remap
  • file_idx - Index of the file this packet came from
  • mapping - 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}