# ZMap: stateless IPv4 scanning and when it is the wrong tool

> ZMap is a single packet network scanner built for Internet-wide surveys. This covers what it does, how it installs, what the stateless design rules out, and how it differs from Nmap and Masscan.

**zmap/zmap** — ZMap is a fast single packet network scanner designed for Internet-wide network surveys.

- Repository: https://github.com/zmap/zmap
- Website: https://zmap.io
- Stars: 6,388 · Forks: 990
- Language: C
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/zmap-zmap

## The problem ZMap solves: one port, every IPv4 address, under an hour

Most scanners are built around a conversation. They open a socket to a host, wait for a reply, record it, and move to the next host. That model collapses when the target list is the entire public IPv4 space, because per-host state and per-host timeouts dominate the runtime. ZMap inverts the design. It is stateless: it sends one packet per address and never keeps a connection table for the probes it has sent. The README states that on a typical desktop with gigabit Ethernet the tool can scan the entire public IPv4 space on a single port in under 45 minutes, and that with 10gigE plus netmap or PF_RING the same sweep takes under 5 minutes.

The audience follows from that number. This is a measurement tool for researchers and network operators who need a census rather than a diagnosis: how many hosts respond on port 25, how many answer a DNS query, how many expose UPnP or BACNET. The README's own example is a TCP SYN packet to every IPv4 address on port 25 to find potential SMTP servers. If your question is "what is running on this one machine," ZMap is the wrong shape of tool, and the project says so by pointing at its sister project ZGrab 2 for stateful application-layer handshakes.

## Statelessness as an architecture, and what it costs you

The mechanism is visible in the repository layout and the README. Probes are generated by probe modules, and the README lists fully implemented modules for TCP SYN scans, ICMP, DNS queries, UPnP and BACNET, with a large number of UDP probes documented under examples/udp-probes. The examples/ directory also holds forge-socket and probe-modules, which is where the extension surface lives: if you need a new probe type, you write a module rather than a script.

Because nothing is remembered per target, the scanner can drive packets at line rate. The cost is that the response stream arrives detached from the request stream. The sample output in the README shows a running counter line with send rate, receive rate, drops and hitrate, then bare IP addresses printed as they come back. There is no per-host state to consult, so the tool cannot tell you that the host which answered is the host you asked, and it cannot retry a lost probe. Loss is expected and visible only as the gap between send and receive counts. For a census that is acceptable: you want the population, not the individual. For anything where a missing reply matters, it is not.

The caution block in the README is unusually blunt for a project README, and it is worth quoting rather than paraphrasing: it says performing Internet-wide scans can have serious ethical and operational implications, that it is your responsibility to be a good internet citizen, and gives three rules of thumb, scan at the slowest speed necessary, scan slower if you are scanning a smaller target space, and provide a way for network operators to opt-out. The wiki page linked from that block is on scanning rate. Treat the rate flag as the first thing you learn, not the last.

## Installing ZMap and running a first scan

The README names 4.4.0 as the latest stable release and says it supports Linux, macOS and BSD, with installation through a package manager or from source described in INSTALL.md. For a container-based run, the repository ships a Dockerfile that builds on ubuntu:24.04, compiles with CMake, installs to /opt/zmap, and sets the entrypoint to dumb-init followed by /opt/zmap/sbin/zmap. The comment block at the top of that file gives the build and run commands directly:

```bash
docker build -t zmap .
docker run -it --rm --net=host ghcr.io/zmap/zmap <zmap args>
```

The build installs the toolchain the project expects, including libpcap-dev, libjudy-dev, libjson-c-dev, libgmp3-dev, gengetopt, flex and byacc, so a source build outside Docker needs those dependencies present. The run command uses --net=host, which the Dockerfile comment shows as the intended invocation; the container needs raw network access, so a bridged network will not give the scanner what it needs.

Once installed, the README's own first command is a full IPv4 sweep of port 80, and it notes that root privileges are required:

```bash
sudo zmap -p 80
```

The expected output is the progress line followed by responding addresses, as the README's sample shows: a counter with send, recv, drops and hitrate percentages, then lines such as 52.8.107.196. If you see the progress line but no addresses, the scan is running and nothing is answering, which is a result rather than a failure. If you see drops climbing, the rate is above what your link or NIC can carry.

Before pointing this at the Internet, the README's Getting Started Guide is the documented walkthrough, and the wiki carries the option reference and a Scanning Best Practices page. The README also asks that usage and support questions go to GitHub Discussions rather than the issue tracker.

## Two limitations that decide whether ZMap fits

The first is that ZMap cannot do stateful work. The README is explicit: for more involved scans such as banner grab or TLS handshake, use ZGrab 2, described as the sister project that performs stateful application-layer handshakes. So the common pipeline is two-stage, ZMap produces the address list and ZGrab2 interrogates it. If you were hoping for one binary that both finds hosts and reads their banners, this is not it, and the split is deliberate rather than a missing feature.

The second is the ethical and operational exposure, which the README frames as the user's responsibility rather than something the tool enforces. The defaults are described as usually safe, but a stateless scanner at full rate looks like a flood from the receiving side, and the README's guidance to scan slower for smaller target spaces cuts against the tool's main selling point. On a /24 you gain nothing from ZMap's throughput and lose the per-host fidelity a conventional scanner gives you. That is the case where it is simply the wrong tool, not a tool used badly.

There is a practical constraint too: root privileges are required, and the container path expects host networking. Neither is negotiable, so environments that forbid raw sockets or require bridged container networking cannot run it as documented.

## ZMap against Nmap and Masscan

Nmap is the general-purpose scanner most people reach for first, and the difference is intent rather than speed. Nmap builds a picture of a host or a set of hosts: service and version detection, OS fingerprinting, scripted checks, and a per-host result you can act on. ZMap has no service detection and no per-host state, and its output is a stream of addresses that answered one specific probe. Choosing between them is choosing between a diagnosis and a census.

Masscan is the closer comparison, because it also targets high-rate stateless scanning. The design difference is what each optimizes for and how each is extended. ZMap's probe set is modular and research-oriented, with documented modules for TCP SYN, ICMP, DNS, UPnP and BACNET plus a UDP probe collection under examples/udp-probes, and the project publishes its architecture in papers linked from the README, including the original 2013 USENIX paper and a follow-up on scanning at 10 Gbps. That publication trail, and the ZGrab2 pairing, is the ecosystem argument. If your need is a quick high-rate port sweep with a familiar flag set, Masscan's model may suit you better; if you are producing a measurement that will be cited, ZMap's probe modules and its citation file are the reason to pick it.

Note that the README does not present a feature-by-feature comparison with either tool. The comparison above is drawn from what each project is documented to do, not from a benchmark run.

## Maintenance, releases and the Apache-2.0 licence

The repository is not archived, and the last push was on 2026-08-28, which is recent enough that describing it as actively maintained matches the record. Releases are not frequent: v4.4.0 landed on 2026-05-29, following v4.3.4 on 2025-05-12 and v4.3.3 on 2025-04-29. That cadence suggests a stable tool where you should not expect rapid flag churn, and the CHANGELOG.md at the repository root is where upgrade differences between those tags are recorded. Read it before moving a working scan pipeline from 4.3.x to 4.4.0.

The upgrade cost is mostly operational rather than API-shaped. A source build tracks a long dependency list (libpcap, Judy, json-c, GMP, gengetopt, flex, byacc, unistring), so distribution packaging and your own build image both need to keep pace. The Dockerfile pins ubuntu:24.04 as the base for both stages, which means the container path is the one with the fewest moving parts.

Licensing: the README states ZMap is copyright 2024 Regents of the University of Michigan and licensed under the Apache License, Version 2.0, with the full text in LICENSE and the distribution provided on an "AS IS" BASIS without warranties or conditions. Apache-2.0 is permissive and includes an explicit patent grant, but it also carries notice and attribution conditions, and the README asks that published research cite the 2013 paper. Whether your redistribution or your publication triggers those conditions is a question for your own counsel, not for this article.

## Conclusion

Adopt ZMap when you need a full IPv4 sweep on one port and you have root, a raw socket capable host, and a reason to be scanning. Do not adopt it for host discovery on a small subnet, for banner grabbing, or for any scan where you need to know which host answered and which ping was lost, because the stateless design cannot give you that. Before running anything, read the scanning rate warning in the wiki and set the rate deliberately rather than accepting the default, and confirm your upstream or hosting provider permits the traffic.

## FAQ

### What is ZMap used for?

It is a fast stateless single packet network scanner designed for Internet-wide network surveys. The README's example is sending a TCP SYN packet to every IPv4 address on port 25 to find potential SMTP servers.

### What are the key differences between ZMap and Nmap?

ZMap is stateless and sends one packet per address to survey a large space quickly, and it keeps no per-host state. Nmap is not described in the ZMap material, and the README instead directs users who need stateful application-layer work such as banner grabs or TLS handshakes to its sister project ZGrab 2.

### What is ZGrab?

ZGrab 2 is described in the README as ZMap's sister project, which performs stateful application-layer handshakes. The README points to it for more involved scans such as banner grabs or TLS handshakes.

## Sources

- [License: Apache-2.0](https://github.com/zmap/zmap/blob/main/LICENSE)
- [Project website](https://zmap.io)
- [README](https://github.com/zmap/zmap/blob/main/README.md)
- [Releases](https://github.com/zmap/zmap/releases)
- [zmap/zmap on GitHub](https://github.com/zmap/zmap)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/zmap-zmap
