from scapy.all import IP, TCP, Ether, Raw, wrpcapng

"""
Generates a packet capture with repeated IRC DCC Send commands without completing any of them.

Generated by Codex GPT-5.5
"""

CLIENT = "192.0.2.10"
SERVER = "192.0.2.20"
SPORT = 41000
DPORT = 6667
BASE_TS = 1_700_000_000.0


def pkt(seq, ack, flags, payload=b"", ts=0.0):
    p = (
        Ether(src="02:00:00:00:00:01", dst="02:00:00:00:00:02")
        / IP(src=CLIENT, dst=SERVER)
        / TCP(sport=SPORT, dport=DPORT, flags=flags, seq=seq, ack=ack)
    )
    if payload:
        p = p / Raw(payload)
    p.time = BASE_TS + ts
    return p


def server_pkt(seq, ack, flags, payload=b"", ts=0.0):
    p = (
        Ether(src="02:00:00:00:00:02", dst="02:00:00:00:00:01")
        / IP(src=SERVER, dst=CLIENT)
        / TCP(sport=DPORT, dport=SPORT, flags=flags, seq=seq, ack=ack)
    )
    if payload:
        p = p / Raw(payload)
    p.time = BASE_TS + ts
    return p


def main():
    packets = []
    cseq = 1000
    sseq = 5000

    packets.append(pkt(cseq, 0, "S", ts=0.000))
    cseq += 1
    packets.append(server_pkt(sseq, cseq, "SA", ts=0.001))
    sseq += 1
    packets.append(pkt(cseq, sseq, "A", ts=0.002))

    lines = [b"NICK loadbot\r\n", b"USER loadbot 0 * :load bot\r\n"]
    # 192.0.2.30 as the DCC target in IRC integer address form.
    dcc_addr = 3221226014
    for i in range(10):
        dcc_port = 20000 + i
        lines.append(
            f"PRIVMSG victim :\x01DCC SEND f{i}.bin {dcc_addr} {dcc_port} 1\x01\r\n".encode()
        )

    # 192.0.2.31 as the DCC target in IRC integer address form.
    dcc_addr = 3221226015
    for i in range(20):
        dcc_port = 21000 + i
        lines.append(
            f"PRIVMSG victim :\x01DCC SEND f{i}.bin {dcc_addr} {dcc_port} 1\x01\r\n".encode()
        )

    payload = b"".join(lines)
    offset = 0
    chunk_index = 0
    while offset < len(payload):
        chunk = payload[offset : offset + 1200]
        packets.append(pkt(cseq, sseq, "PA", chunk, ts=0.010 + chunk_index * 0.001))
        cseq += len(chunk)
        offset += len(chunk)
        chunk_index += 1

    packets.append(pkt(cseq, sseq, "FA", ts=1.000))
    cseq += 1
    packets.append(server_pkt(sseq, cseq, "FA", ts=1.001))
    sseq += 1
    packets.append(pkt(cseq, sseq, "A", ts=1.002))

    wrpcapng("irc-dcc-state-growth.pcapng", packets)


if __name__ == "__main__":
    main()
