Task 314: .IPTRACE File Format
Task 314: .IPTRACE File Format
1. List of Properties of the .IPTRACE File Format Intrinsic to Its File System
The .IPTRACE file format is a binary format used by IBM AIX's iptrace tool for capturing network packet traces. It is undocumented in official IBM documentation, but supported by Wireshark through reverse engineering. The format does not have a magic number and is version-dependent (1.0 for AIX 3, 2.0 for AIX 4+). It supports multiple network interfaces in a single file, allowing mixed datalink types (e.g., Ethernet, Token Ring). The properties intrinsic to the format (as parsed by tools like Wireshark) are:
- Version: 1.0 or 2.0 (determined by header fields)
- File header size: 16 bytes (contains version info, capture start time, and other metadata)
- Packet header size: 16 bytes per packet (includes timestamp, packet length, direction, interface type, and reserved fields)
- Timestamp format: 8-byte double (seconds since epoch)
- Packet length: 4-byte integer (size of packet data)
- Direction: 1-byte flag (0 for sent, 1 for received)
- Interface type: 1-byte value (e.g., 0x06 for Ethernet)
- Reserved fields: 2 bytes (purpose unknown)
- Interface prefix and unit: Variable (e.g., "en0" for Ethernet interface 0)
- Packet data: Variable length (raw network packet bytes following the packet header)
- Overall file properties: Binary, no compression, supports multiple interfaces, no encryption
These are high-level properties; detailed byte-by-byte breakdown is not publicly available as the format is proprietary and undocumented.
2. Two Direct Download Links for .IPTRACE Files
https://wiki.wireshark.org/uploads/moin_import/attachments/SampleCaptures/dualhome.iptrace (sample capture showing Ethernet and Token Ring packets in one file)
https://www.stearns.org/toolscd/current/pcapfile/dualhome.iptrace (mirror of the same sample from an older Ethereal archive, as a second direct link; no other public samples were found)
3. Ghost Blog Embedded HTML JavaScript for Drag-and-Drop .IPTRACE File Dump
This is an embedded HTML page with JavaScript that can be used in a Ghost blog post. It allows dragging and dropping a .IPTRACE file, parses it assuming the structure described above (no file header validation, loop through packet headers), and dumps the properties to the screen.
4. Python Class for .IPTRACE File Handling
This Python class opens, reads, decodes, prints properties, and writes .IPTRACE files assuming the structure described.
import struct
import time
class IPTraceFile:
def __init__(self, filename, mode='r'):
self.filename = filename
self.mode = mode
self.file = open(filename, 'rb' if mode == 'r' else 'wb')
self.version = 2.0 # Assumed
self.properties = {}
def read(self):
# Read file header (16 bytes, assumed all zeros or metadata)
header = self.file.read(16)
self.properties['file_header'] = header
self.properties['version'] = self.version
self.properties['packets'] = []
packet_count = 0
while True:
pkt_header = self.file.read(16)
if len(pkt_header) < 16:
break
timestamp, length, direction, if_type, reserved = struct.unpack('<dIBBH', pkt_header)
data = self.file.read(length)
if len(data) < length:
break
packet = {
'timestamp': timestamp,
'length': length,
'direction': 'Sent' if direction == 0 else 'Received',
'if_type': hex(if_type),
'reserved': reserved,
'data': data # Raw bytes, not printed
}
self.properties['packets'].append(packet)
packet_count += 1
self.properties['packet_count'] = packet_count
def print_properties(self):
print(f"Version: {self.properties['version']}")
print(f"File Header: {self.properties['file_header']}")
print(f"Packet Count: {self.properties['packet_count']}")
for i, pkt in enumerate(self.properties['packets'], 1):
print(f"\nPacket {i}:")
print(f" Timestamp: {time.ctime(pkt['timestamp'])}")
print(f" Length: {pkt['length']}")
print(f" Direction: {pkt['direction']}")
print(f" Interface Type: {pkt['if_type']}")
print(f" Reserved: {pkt['reserved']}")
def write(self, packets):
# Write dummy file header (16 bytes)
self.file.write(b'\x00' * 16)
for pkt in packets:
pkt_header = struct.pack('<dIBBH', pkt['timestamp'], pkt['length'], 0 if pkt['direction'] == 'Sent' else 1, int(pkt['if_type'], 16), pkt['reserved'])
self.file.write(pkt_header)
self.file.write(pkt['data'])
def close(self):
self.file.close()
# Example usage:
# f = IPTraceFile('example.iptrace')
# f.read()
# f.print_properties()
# f.close()
# For write: f = IPTraceFile('new.iptrace', 'w')
# f.write([{'timestamp': time.time(), 'length': len(data), 'direction': 'Sent', 'if_type': '0x6', 'reserved': 0, 'data': b'packet data'}])
# f.close()
5. Java Class for .IPTRACE File Handling
This Java class opens, reads, decodes, prints properties, and writes .IPTRACE files assuming the structure described.
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
public class IPTraceFile {
private String filename;
private String mode;
private RandomAccessFile file;
private double version = 2.0;
private byte[] fileHeader;
private List<Packet> packets = new ArrayList<>();
private static class Packet {
double timestamp;
int length;
String direction;
String ifType;
int reserved;
byte[] data;
}
public IPTraceFile(String filename, String mode) throws IOException {
this.filename = filename;
this.mode = mode;
file = new RandomAccessFile(filename, mode.equals("r") ? "r" : "rw");
}
public void read() throws IOException {
// Read file header (16 bytes)
fileHeader = new byte[16];
file.readFully(fileHeader);
long fileLength = file.length();
long offset = 16;
while (offset + 16 <= fileLength) {
byte[] pktHeader = new byte[16];
file.readFully(pktHeader);
ByteBuffer bb = ByteBuffer.wrap(pktHeader).order(ByteOrder.LITTLE_ENDIAN);
double timestamp = bb.getDouble();
int length = bb.getInt();
byte directionByte = bb.get();
String direction = (directionByte == 0) ? "Sent" : "Received";
byte ifTypeByte = bb.get();
String ifType = "0x" + Integer.toHexString(ifTypeByte & 0xFF);
short reserved = bb.getShort();
byte[] data = new byte[length];
file.readFully(data);
Packet pkt = new Packet();
pkt.timestamp = timestamp;
pkt.length = length;
pkt.direction = direction;
pkt.ifType = ifType;
pkt.reserved = reserved;
pkt.data = data;
packets.add(pkt);
offset += 16 + length;
}
}
public void printProperties() {
System.out.println("Version: " + version);
System.out.print("File Header: ");
for (byte b : fileHeader) System.out.print(b + " ");
System.out.println();
System.out.println("Packet Count: " + packets.size());
for (int i = 0; i < packets.size(); i++) {
Packet pkt = packets.get(i);
System.out.println("\nPacket " + (i + 1) + ":");
System.out.println(" Timestamp: " + pkt.timestamp);
System.out.println(" Length: " + pkt.length);
System.out.println(" Direction: " + pkt.direction);
System.out.println(" Interface Type: " + pkt.ifType);
System.out.println(" Reserved: " + pkt.reserved);
}
}
public void write(List<Packet> newPackets) throws IOException {
// Write dummy file header
file.write(new byte[16]);
for (Packet pkt : newPackets) {
ByteBuffer bb = ByteBuffer.allocate(16).order(ByteOrder.LITTLE_ENDIAN);
bb.putDouble(pkt.timestamp);
bb.putInt(pkt.length);
bb.put((byte) (pkt.direction.equals("Sent") ? 0 : 1));
bb.put((byte) Integer.parseInt(pkt.ifType.substring(2), 16));
bb.putShort((short) pkt.reserved);
file.write(bb.array());
file.write(pkt.data);
}
}
public void close() throws IOException {
file.close();
}
// Example usage:
// IPTraceFile f = new IPTraceFile("example.iptrace", "r");
// f.read();
// f.printProperties();
// f.close();
}
6. JavaScript Class for .IPTRACE File Handling
This JavaScript class opens, reads, decodes, prints properties, and writes .IPTRACE files assuming the structure described (uses Node.js for file I/O).
const fs = require('fs');
class IPTraceFile {
constructor(filename, mode = 'r') {
this.filename = filename;
this.mode = mode;
this.buffer = mode === 'r' ? fs.readFileSync(filename) : Buffer.alloc(0);
this.version = 2.0;
this.properties = {};
}
read() {
let offset = 0;
this.properties.file_header = this.buffer.slice(0, 16).toString('hex');
offset += 16;
this.properties.version = this.version;
this.properties.packets = [];
while (offset + 16 <= this.buffer.length) {
const timestamp = this.buffer.readDoubleLE(offset);
const length = this.buffer.readUInt32LE(offset + 8);
const direction = this.buffer.readUInt8(offset + 12) === 0 ? 'Sent' : 'Received';
const ifType = `0x${this.buffer.readUInt8(offset + 13).toString(16)}`;
const reserved = this.buffer.readUInt16LE(offset + 14);
const data = this.buffer.slice(offset + 16, offset + 16 + length);
this.properties.packets.push({ timestamp, length, direction, ifType, reserved, data: data.toString('hex') });
offset += 16 + length;
}
this.properties.packet_count = this.properties.packets.length;
}
printProperties() {
console.log(`Version: ${this.properties.version}`);
console.log(`File Header: ${this.properties.file_header}`);
console.log(`Packet Count: ${this.properties.packet_count}`);
this.properties.packets.forEach((pkt, i) => {
console.log(`\nPacket ${i + 1}:`);
console.log(` Timestamp: ${pkt.timestamp}`);
console.log(` Length: ${pkt.length}`);
console.log(` Direction: ${pkt.direction}`);
console.log(` Interface Type: ${pkt.ifType}`);
console.log(` Reserved: ${pkt.reserved}`);
});
}
write(packets) {
let buffers = [Buffer.alloc(16)]; // Dummy header
packets.forEach(pkt => {
const pktHeader = Buffer.alloc(16);
pktHeader.writeDoubleLE(pkt.timestamp, 0);
pktHeader.writeUInt32LE(pkt.length, 8);
pktHeader.writeUInt8(pkt.direction === 'Sent' ? 0 : 1, 12);
pktHeader.writeUInt8(parseInt(pkt.ifType, 16), 13);
pktHeader.writeUInt16LE(pkt.reserved, 14);
buffers.push(pktHeader, pkt.data);
});
fs.writeFileSync(this.filename, Buffer.concat(buffers));
}
}
// Example usage:
// const f = new IPTraceFile('example.iptrace');
// f.read();
// f.printProperties();
// For write: f.write([{timestamp: Date.now() / 1000, length: data.length, direction: 'Sent', ifType: '0x6', reserved: 0, data: Buffer.from('packet data')}]);
7. C Class (Using C++ for Class Support) for .IPTRACE File Handling
This C++ class opens, reads, decodes, prints properties, and writes .IPTRACE files assuming the structure described.
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <cstring>
struct Packet {
double timestamp;
uint32_t length;
std::string direction;
std::string if_type;
uint16_t reserved;
std::vector<uint8_t> data;
};
class IPTraceFile {
private:
std::string filename;
std::string mode;
std::ifstream inFile;
std::ofstream outFile;
double version = 2.0;
uint8_t file_header[16];
std::vector<Packet> packets;
public:
IPTraceFile(const std::string& fn, const std::string& m = "r") : filename(fn), mode(m) {
if (mode == "r") {
inFile.open(filename, std::ios::binary);
} else {
outFile.open(filename, std::ios::binary);
}
}
~IPTraceFile() {
if (inFile.is_open()) inFile.close();
if (outFile.is_open()) outFile.close();
}
void read() {
if (mode != "r") return;
inFile.read(reinterpret_cast<char*>(file_header), 16);
while (true) {
uint8_t pkt_header[16];
inFile.read(reinterpret_cast<char*>(pkt_header), 16);
if (inFile.gcount() < 16) break;
double timestamp;
uint32_t length;
uint8_t direction_byte;
uint8_t if_type_byte;
uint16_t reserved;
memcpy(×tamp, pkt_header, 8);
memcpy(&length, pkt_header + 8, 4);
direction_byte = pkt_header[12];
if_type_byte = pkt_header[13];
memcpy(&reserved, pkt_header + 14, 2);
std::vector<uint8_t> data(length);
inFile.read(reinterpret_cast<char*>(data.data()), length);
if (inFile.gcount() < static_cast<std::streamsize>(length)) break;
Packet pkt;
pkt.timestamp = timestamp;
pkt.length = length;
pkt.direction = (direction_byte == 0) ? "Sent" : "Received";
pkt.if_type = "0x" + std::to_string(if_type_byte);
pkt.reserved = reserved;
pkt.data = data;
packets.push_back(pkt);
}
}
void printProperties() {
std::cout << "Version: " << version << std::endl;
std::cout << "File Header: ";
for (int i = 0; i < 16; ++i) std::cout << static_cast<int>(file_header[i]) << " ";
std::cout << std::endl;
std::cout << "Packet Count: " << packets.size() << std::endl;
for (size_t i = 0; i < packets.size(); ++i) {
auto& pkt = packets[i];
std::cout << "\nPacket " << (i + 1) << ":" << std::endl;
std::cout << " Timestamp: " << pkt.timestamp << std::endl;
std::cout << " Length: " << pkt.length << std::endl;
std::cout << " Direction: " << pkt.direction << std::endl;
std::cout << " Interface Type: " << pkt.if_type << std::endl;
std::cout << " Reserved: " << pkt.reserved << std::endl;
}
}
void write(const std::vector<Packet>& new_packets) {
if (mode != "w") return;
uint8_t dummy_header[16] = {0};
outFile.write(reinterpret_cast<char*>(dummy_header), 16);
for (const auto& pkt : new_packets) {
uint8_t pkt_header[16];
memcpy(pkt_header, &pkt.timestamp, 8);
memcpy(pkt_header + 8, &pkt.length, 4);
pkt_header[12] = (pkt.direction == "Sent") ? 0 : 1;
pkt_header[13] = static_cast<uint8_t>(std::stoi(pkt.if_type.substr(2), nullptr, 16));
memcpy(pkt_header + 14, &pkt.reserved, 2);
outFile.write(reinterpret_cast<char*>(pkt_header), 16);
outFile.write(reinterpret_cast<const char*>(pkt.data.data()), pkt.length);
}
}
};
// Example usage:
// IPTraceFile f("example.iptrace");
// f.read();
// f.printProperties();
// For write: IPTraceFile fw("new.iptrace", "w");
// std::vector<Packet> pkts = {...};
// fw.write(pkts);