DNS resolvers, recursive caches, DPI engines and UDP front ends are often tested with well-formed queries. Deployments also see truncated lengths, mismatched section counts, bad checksums and forged mDNS or LLMNR answers. To exercise those paths you need packets you control — and a clear rule for when lengths and checksums stay correct versus when they stay wrong on purpose.

This article compares options and a lab-only workflow with Cat KARAT Packet Builder. Send only on an authorized, isolated lab network. Prefer loopback or a dedicated test segment, keep rates low, and never aim traffic at third-party systems.

Automatic repair versus deliberate invalid fields

Packet builders usually do one of two things:

  1. Keep the packet self-consistent. Lengths and checksums are computed from the assembled bytes — right for traffic that should pass a careful checker.
  2. Leave a field wrong on purpose. You override a length or checksum, or you declare a DNS section count that does not match the records — right for negative tests.

Mixing those modes by accident is common: you change a payload, the tool recomputes the checksum, and the "error case" becomes valid again.

In KARAT, the User Guide states the default: checksums and lengths are computed automatically unless an Override is checked. On the UDP tab the controls are Length Override and Checksum Override (hex). On the IPv4 tab they include Header Length Override, Total Length Override and Checksum Override (hex). Leave them unchecked when you want consistent outer headers.

For DNS section counts, the DNS tab Counts group lists Questions, Answers, Authority and Additional, each with an Auto checkbox. With Auto on (default), the count follows the real record list. Switching Auto off lets you type a count that does not match — a documented malformed-packet path. If Override is off, KARAT will not preserve a stale wrong checksum after you edit the packet.

Option 1: Scapy

Scapy’s DNS layer (DNS, DNSQR, DNSRR) builds queries and answers in Python. Official usage docs show IP()/UDP()/DNS(...) stacking. When Scapy assembles a packet it fills calculated fields such as checksums (show2() notes that the checksum is calculated). You can still force unusual values by setting header fields (docs show malformed IP examples) or use fuzz(), which randomizes defaults while keeping checksums calculated.

Good for: scripted suites and embedding DNS cases in a Python harness.
Trade-off: you own every deliberate mismatch yourself; there is no clickable Packet View.

Option 2: Hex-edit a capture

Change bytes in an exported DNS/UDP frame without a protocol-aware editor and you either break unintended fields or leave a correct checksum over wrong data. Useful for a classroom demo of Wireshark warnings, weak for a repeatable negative-test library.

Option 3: KARAT with explicit overrides

According to the product page and User Guide, KARAT:

  • builds stacks visually, including Ethernet, VLAN, IPv4/IPv6, UDP, TCP, DNS, mDNS and LLMNR;
  • shows a field-level Packet View with hex highlighting;
  • computes checksums and lengths automatically unless Override is checked;
  • offers InfoSec presets dns/mdns_query, dns/mdns_spoof and dns/llmnr_poison (File > Traffic Profiles > InfoSec Presets, or { "infosec": "dns/mdns_query" } in a script), with TEST-NET sources;
  • can write a pcap (--output) without sending, print the would-be frame with --dry-run, and restrict live send with Safety: loopback only (Options or --safety-loopback);
  • sends a finite burst via Packets per Burst / Start Transmit, or a fixed count from the CLI (--run / --send N).

KARAT is free for personal, educational and commercial use on Windows; a Linux build is available on request. Live send needs Npcap (Windows) or libpcap (Linux).

Lab workflow (authorized isolated network only)

Prefer a few packets per burst, or write a pcap and replay under your own lab controls. Do not aim high-count "storm" profiles at anything you do not fully control.

  1. Isolate. Enable Safety: loopback only, or use a dedicated lab adapter with no path to production or the public Internet.
  2. Compose a baseline. Select IPv4, UDP and DNS. Leave Override boxes unchecked. Confirm the frame in Packet View.
  3. Build an error case with documented controls, for example: check UDP Checksum Override (hex) and enter a wrong value; check UDP Length Override and set a length that does not match the DNS payload; or uncheck DNS Auto for Answers and declare a count that does not match the Answer list.
  4. Inspect before send. Optionally --dry-run or --output bad-dns.pcap and open the file in Wireshark.
  5. Send a bounded burst with Start Transmit (or Karat --run … --send N) only toward the lab target.
  6. Optional InfoSec presets. Apply dns/mdns_query, dns/mdns_spoof or dns/llmnr_poison, review fields, then send only where authorized.

Which tool when?

Need Good fit
Scripted DNS in Python CI Scapy
Click-built UDP/DNS with field/hex link KARAT Packet View
Deliberate bad UDP length/checksum KARAT Override (or hand-set Scapy fields)
Deliberate DNS count mismatch KARAT Counts with Auto off (or Scapy counts vs lists)
mDNS / LLMNR lab presets KARAT InfoSec dns/* (authorized lab only)
Pcap only, no live send KARAT --output / --dry-run, or Scapy wrpcap

Limitations

  • Overrides cover documented fields (UDP length/checksum, IPv4 header/total length/checksum, DNS Auto counts). Not every tab exposes every mismatch.
  • GRE checksum is not auto-computed in KARAT (hex field); do not assume tunnel behaviour from the UDP/IPv4 rules.
  • High-count traffic profiles exist for lab rate-limit work; they are out of scope for careful negative tests and must not target third parties.
  • You alone are responsible for authorized use (KARAT responsibility notice and license).

Explore Cat KARAT Packet Builder →

FAQ

If I edit the DNS payload, will a wrong UDP checksum I typed earlier remain?
Only while Checksum Override (hex) stays checked. With Override off, the checksum is recomputed.

How do I claim two DNS answers but carry one?
Add one Answer record, uncheck Auto for Answers, and set the count to 2.

Can I try a preset without sending?
Yes: --output writes a pcap; --dry-run prints the frame a send would use. --output remains allowed with loopback-only safety.

Is live send required?
No. Building and saving a capture does not need live I/O privileges; live send needs Npcap/libpcap and may need elevation.

Does this recommend flooding a resolver?
No. Use small finite bursts on an authorized lab target only.