Capturing VM Switch‑Port Traffic with a simple script
When I’m troubleshooting a virtual machine’s network behavior, the first thing I reach for is a packet capture. In theory it’s simple: locate the switch‑port the VM is attached to, start a capture on that port, and save the results for later analysis. In practice I kept forgetting the exact commands—especially the quirky combination of pktcap-uw and tcpdump-uw that ESXi require.
To solve that, I wrote a tiny shell script that does everything in one go. Below I walk through the script, explain each step, so you can use it in your own environment.
The script can be found here over on Codeberg.org
Why This Script Exists
- Forgetfulness is real. Every time I needed a capture I’d open a terminal, remember the command
net‑stats -lor usingesxcliand whatever parameters is needed, extract the port number, remember the right flags forpktcap-uw, pipe it intotcpdump-uw, and finally name the output file and forget to give it a new one when doing multiple takes. - Consistency matters. Having a reproducible command chain eliminates human error—no more “oops, I used the wrong flag or command”
- Convenience. With a single argument (
<vm-name>) the script does all the heavy lifting, timestamps the output, ready for you to analyze the.pcapoutput.
How to Use It
Replace my-vm with any unique substring of the VM’s name. The script will:
- Find the correct switch‑port.
- Start capturing traffic.
- Save a timestamped
.pcapunder/tmp.
When you’re done, simply press Ctrl‑C. The capture ends, and you’ll see the location of the file printed to the console.
The Script, Line by Line
The header explains purpose, usage, and the three core steps.
Enables strict error handling: abort on any failure, treat unset variables as errors, and propagate failures through pipelines.
1️⃣ Argument Validation
We insist on a single argument – the (partial) VM name – and store it for later pattern matching.
2️⃣ Locate the Switch‑Port
net‑stats -llists all live interfaces.- We pipe the output through
awk, performing a case‑insensitive match against column 6 (the VM name). - The first match gives us two pieces of data: the PortNum (column 1) and the exact VM identifier.
cut -d '.' -f1strips any domain suffix that might appear.
If nothing matches, we bail out with a clear error:
3️⃣ Timestamped Filename
A unique filename prevents accidental overwrites and makes it easy to locate captures later.
4️⃣ Run the Capture
pktcap-uwgrabs raw packets from the specified switch‑port (--dir 2means both inbound and outbound).- The
-o -flag streams the output to stdout, which we pipe directly intotcpdump-uw. tcpdump-uwreads from stdin (-r -) and writes a proper.pcapfile (-w).
Because the whole pipeline runs inside a subshell, pressing Ctrl‑C cleanly terminates both processes.
5️⃣ Wrap‑Up Message
A friendly reminder of the next steps: analyze with tcpdump on the host or pull the file to a workstation and open it in Wireshark.
Takeaways
- One source of truth. By encapsulating the lookup and capture logic, you eliminate the mental overhead of remembering several unrelated commands.
- Safety first.
set -euo pipefailensures the script stops on any unexpected condition, protecting you from generating empty or misleading captures. - Reusability. Ready to troubleshoot VMs instantly.
Next time you’re staring at a VM and need to see what’s really happening on the wire, just run the script and let it do the heavy lifting. Happy sniffing! 🐶