import struct
import sys

path = r"D:\RoshEmulator\captures\karos_live3.pcapng"

def read_blocks(data):
    off = 0
    blocks = []
    while off < len(data):
        block_type, block_len = struct.unpack_from("<II", data, off)
        block_data = data[off:off+block_len]
        blocks.append((block_type, block_data))
        off += block_len
    return blocks

data = open(path, "rb").read()
blocks = read_blocks(data)
print(f"total blocks: {len(blocks)}")

pkt_index = 0
for btype, bdata in blocks:
    if btype == 0x00000006:  # Enhanced Packet Block
        pkt_index += 1
        # header: block_type(4) block_len(4) if_id(4) ts_hi(4) ts_lo(4) caplen(4) origlen(4)
        if_id, ts_hi, ts_lo, caplen, origlen = struct.unpack_from("<IIIII", bdata, 8)
        pkt = bdata[28:28+caplen]
        # parse ethernet
        if len(pkt) < 14:
            continue
        eth_type = struct.unpack_from(">H", pkt, 12)[0]
        if eth_type != 0x0800:
            continue
        ip = pkt[14:]
        if len(ip) < 20:
            continue
        ver_ihl = ip[0]
        ihl = (ver_ihl & 0x0F) * 4
        proto = ip[9]
        src = ".".join(str(b) for b in ip[12:16])
        dst = ".".join(str(b) for b in ip[16:20])
        if proto != 6:  # TCP
            continue
        tcp = ip[ihl:]
        if len(tcp) < 20:
            continue
        sport, dport = struct.unpack_from(">HH", tcp, 0)
        seq, ack = struct.unpack_from(">II", tcp, 4)
        data_off = (tcp[12] >> 4) * 4
        flags = tcp[13]
        payload = tcp[data_off:]
        flagstr = ""
        if flags & 0x02: flagstr += "SYN "
        if flags & 0x10: flagstr += "ACK "
        if flags & 0x08: flagstr += "PSH "
        if flags & 0x01: flagstr += "FIN "
        if flags & 0x04: flagstr += "RST "
        print(f"\n#{pkt_index} {src}:{sport} -> {dst}:{dport}  flags={flagstr.strip()}  payload_len={len(payload)}")
        if payload:
            hx = payload.hex()
            for i in range(0, len(hx), 32):
                chunk = hx[i:i+32]
                bs = bytes.fromhex(chunk)
                ascii_part = "".join(chr(b) if 32<=b<127 else "." for b in bs)
                print(f"  {chunk[:16]} {chunk[16:]}   {ascii_part}")
