#!/usr/bin/env python3
"""
Generate svcb-port-malformed.pcap with a DNS HTTPS/SVCB response
containing a port SvcParam with an invalid value length (3 instead of 2).

Generated by Claude Opus 4.6 (Anthropic).
"""

import struct
from pathlib import Path

from scapy.all import DNS, DNSQR, DNSRR, IP, UDP, Ether, wrpcap

SVCB_KEY_PORT = 3


def build_svcb_rdata(priority, target, svc_params_bytes):
    """Build raw SVCB/HTTPS RDATA from components."""
    target_wire = b""
    if target == ".":
        target_wire = b"\x00"
    else:
        for label in target.rstrip(".").split("."):
            target_wire += bytes([len(label)]) + label.encode()
        target_wire += b"\x00"

    return struct.pack("!H", priority) + target_wire + svc_params_bytes


def build_svc_param(key, value):
    """Build a single SvcParam TLV."""
    return struct.pack("!HH", key, len(value)) + value


def dns_query(qname):
    return (
        Ether()
        / IP(src="10.0.0.2", dst="10.0.0.1")
        / UDP(sport=1234, dport=53)
        / DNS(
            id=0x1234,
            qr=0,
            qd=DNSQR(qname=qname, qtype=65),
        )
    )


def dns_response(qname, rdata):
    return (
        Ether()
        / IP(src="10.0.0.1", dst="10.0.0.2")
        / UDP(sport=53, dport=1234)
        / DNS(
            id=0x1234,
            qr=1,
            qd=DNSQR(qname=qname, qtype=65),
            an=DNSRR(rrname=qname, type=65, ttl=300, rdata=rdata),
        )
    )


def main():
    qname = "example.com"

    # Port SvcParam with value_len=3 (should be 2): 3 bytes of port data
    port_value = struct.pack("!H", 443) + b"\x00"
    svc_params = build_svc_param(SVCB_KEY_PORT, port_value)
    rdata = build_svcb_rdata(1, ".", svc_params)

    out = Path(__file__).with_suffix("")
    wrpcap(str(out), [dns_query(qname), dns_response(qname, rdata)])
    print(f"Wrote 2 packets to {out}")


if __name__ == "__main__":
    main()
