import struct
from datetime import datetime

def parse_pcap_with_headers(filename):
    with open(filename, 'rb') as f:
        global_header = f.read(24)
        packets = []
        while True:
            packet_header = f.read(16)
            if len(packet_header) < 16:
                break
            ts_sec, ts_usec, incl_len, orig_len = struct.unpack('IIII', packet_header)
            packet_data = f.read(incl_len)
            if len(packet_data) < incl_len:
                break
            packets.append({
                'timestamp': ts_sec + ts_usec / 1000000,
                'length': incl_len,
                'orig_len': orig_len,
                'data': packet_data
            })
        return packets

packets = parse_pcap_with_headers('sniffed.pcap')

print("=" * 80)
print("TESTING NON-PAYLOAD METHODS")
print("=" * 80)

# Method 1: Inter-packet timing (differences)
print("\n[1] INTER-PACKET TIMING (microseconds difference):")
if len(packets) > 1:
    timing_diffs = []
    for i in range(1, min(50, len(packets))):
        diff = int((packets[i]['timestamp'] - packets[i-1]['timestamp']) * 1000000)
        timing_diffs.append(diff)
    print(f"First 20 timing differences: {timing_diffs[:20]}")
    # Try to extract ASCII
    timing_chars = [chr(d % 128) if 32 <= (d % 128) <= 126 else '.' for d in timing_diffs]
    timing_msg = ''.join([c for c in timing_chars if c != '.'])
    print(f"As ASCII: {timing_msg[:50]}")

# Method 2: Packet size differences
print("\n[2] PACKET SIZE DIFFERENCES:")
size_diffs = []
for i in range(1, min(50, len(packets))):
    diff = abs(packets[i]['length'] - packets[i-1]['length'])
    size_diffs.append(diff)
print(f"First 20 size diffs: {size_diffs[:20]}")
size_chars = [chr(d) if 32 <= d <= 126 else '.' for d in size_diffs]
size_msg = ''.join([c for c in size_chars if c != '.'])
print(f"As ASCII: {size_msg[:50]}")

# Method 3: Alternating packet sizes
print("\n[3] PATTERN: Even/Odd packet sizes:")
even_packets = [p for i, p in enumerate(packets) if i % 2 == 0]
odd_packets = [p for i, p in enumerate(packets) if i % 2 == 1]
even_last = [chr(p['data'][-1]) if 32 <= p['data'][-1] <= 126 else '.' for p in even_packets[:50]]
odd_last = [chr(p['data'][-1]) if 32 <= p['data'][-1] <= 126 else '.' for p in odd_packets[:50]]
print(f"Even packets: {''.join([c for c in even_last if c != '.'])}")
print(f"Odd packets:  {''.join([c for c in odd_last if c != '.'])}")

# Method 4: Large vs Small packets
print("\n[4] PATTERN: Large packets (>1000 bytes) vs Small:")
large_packets = [p for p in packets if p['length'] > 1000]
small_packets = [p for p in packets if p['length'] <= 1000]
print(f"Large packets ({len(large_packets)}): ", end='')
large_chars = [chr(p['data'][-1]) if 32 <= p['data'][-1] <= 126 else '.' for p in large_packets]
print(''.join([c for c in large_chars if c != '.']))
print(f"Small packets ({len(small_packets)}): ", end='')
small_chars = [chr(p['data'][-1]) if 32 <= p['data'][-1] <= 126 else '.' for p in small_packets]
print(''.join([c for c in small_chars if c != '.']))

# Method 5: Packet count sequence
print("\n[5] SEQUENCE NUMBERS (packet 1=1, packet 2=2, etc as ASCII):")
seq_chars = [chr(i) if 32 <= i <= 126 else '.' for i in range(1, min(140, len(packets)+1))]
seq_msg = ''.join([c for c in seq_chars if c != '.'])
print(f"Message: {seq_msg}")

# Method 6: Look at actual protocol headers
print("\n[6] EXAMINING IP/TCP/UDP HEADERS:")
for i in range(min(15, len(packets))):
    pkt = packets[i]['data']
    if len(pkt) > 30:
        # Skip Linux cooked capture header (16 bytes) if present
        offset = 0
        if len(pkt) >= 2:
            # Check for Linux SLL (0x00 0x04 or similar)
            if pkt[0] == 0 and pkt[1] in [0x01, 0x04]:
                offset = 16  # Linux cooked capture
        
        if len(pkt) > offset + 20:
            # Try to parse as IP
            ip_version = (pkt[offset] >> 4) & 0x0F
            if ip_version == 4:
                ttl = pkt[offset + 8]
                protocol = pkt[offset + 9]
                ip_id = (pkt[offset + 4] << 8) | pkt[offset + 5]
                if 32 <= ttl <= 126 and i < 15:
                    print(f"Packet {i+1}: TTL={ttl} ({chr(ttl)}), Proto={protocol}, IP_ID=0x{ip_id:04x}")
