Friendly multicast send/receive tools for lab environments
Project description
mcast-tools
Friendly multicast send/receive tools for lab environments. Hides the
complexity of iperf / raw socket plumbing behind three simple commands,
and adds capabilities iperf can't provide — source-specific (SSM) joins,
IGMP version control, hop-count and DSCP-remark visibility via embedded
metadata, and live dashboards that update in real time.
Why not just iperf?
iperf is great, but for a teaching lab a few limitations matter:
- No SSM joins.
iperf -s -B <group>only does any-source(*,G)joins. No flag fixes this — it's a socket-level capability iperf doesn't expose. - No IGMP version control. That's a kernel sysctl, not an iperf knob.
- No visibility into TTL or DSCP. iperf doesn't tell you which interface the join went out on, what IGMP version was actually sent, what TTL or DSCP arrived, or how many hops away the sender is.
- Output is built for log scraping, not live UX.
mcast-tools keeps iperf's "two commands, easy to remember" feel while
adding the things you actually want in a lab.
Install
pip install mcast-tools
Or from source:
git clone https://github.com/mitchv85/mcast-tools.git
cd mcast-tools
pip install .
Provides three commands: mcast-send, mcast-receive, mcast-status.
Root is recommended for
mcast-receiveso it can force the IGMP version via/proc/sys/net/ipv4/conf/<iface>/force_igmp_version. It will still run without root, but the kernel will use whatever IGMP version it's currently configured for.
Quick start
# Sender — defaults to 10 minutes, TTL 100, 25pps, DSCP=BE
mcast-send 239.0.10.101
# Receiver — defaults to ASM (*,G) join, IGMPv3
mcast-receive 239.0.10.101
# What groups is this host joined to?
mcast-status
mcast-send
mcast-send <group> [duration] [ttl]
mcast-send <group> --rate 1Mbps --dscp ef --interface eth1
| Option | Default | Purpose |
|---|---|---|
group |
(required) | IPv4 multicast group, e.g. 239.0.10.101 |
duration |
600 |
Seconds to send. 0 = forever |
ttl |
100 |
IP TTL on outgoing packets |
--rate |
25pps |
Npps, Nkbps, NMbps, etc. |
--size |
200 |
Datagram size in bytes (header + payload) |
--dscp |
be |
0-63 or name (ef, af41, cs5, ...) |
--interface |
(routing default) | Egress interface override |
--no-loopback |
off | Disable IP_MULTICAST_LOOP |
--quiet / --json |
off | Suppress dashboard / emit JSON summary on exit |
Each packet carries a 32-byte custom header with magic MCAS, a sequence
number, a monotonic nanosecond timestamp, a random per-invocation sender ID,
and the original TTL/DSCP the sender configured. mcast-receive uses these
fields to compute loss, duplicates, reordering, hop count, and DSCP remarks.
mcast-receive
mcast-receive <group> # ASM (*,G)
mcast-receive <group> <source> # SSM (S,G), IGMPv3
mcast-receive <group> --igmp-version 2 --interface eth1
| Option | Default | Purpose |
|---|---|---|
group |
(required) | IPv4 multicast group |
source |
(none) | Source IP for SSM (S,G) join |
igmp_version |
3 |
1, 2, or 3. Must be 3 if a source is specified. |
--interface |
(routing default) | Interface to join on |
--stall-timeout |
3.0 |
Seconds without a packet before flagging STALLED |
--duration |
0 |
Auto-stop after N seconds (0 = run forever) |
--quiet / --json |
off | Suppress dashboard / emit JSON summary on exit |
The receiver continuously displays:
- Status:
WAITING→RECEIVING→STALLEDbased on packet arrival - Received TTL with hop-count interpretation (
recv 96, sender set 100 — 4 hops away) - Received DSCP with remark detection (
BE, sender set EF — REMARKED) - Loss / Duplicates / Reordered counters
- Sender restart detection (new
sender_id→ restart counter increments) - Gap log — recent stall events with duration
Why IGMPv3 is mandatory for SSM
Only IGMPv3 Membership Reports carry the per-source state needed to
communicate (S,G) filtering up to the querier. v1/v2 reports only express
(*,G). mcast-receive enforces this with a clear error message rather
than silently doing the wrong thing.
mcast-status
mcast-status # current memberships, excluding kernel defaults
mcast-status --all # include 224.0.0.1 etc.
mcast-status -i eth0 # one interface only
Reads /proc/net/igmp and pretty-prints which interfaces are joined to
which groups, the operational IGMP version, and the current
force_igmp_version value if any.
End-to-end example
In one terminal:
mcast-receive 239.0.10.101
In another:
mcast-send 239.0.10.101 --rate 50pps --ttl 64 --dscp ef
The receiver will show 50 pps, EF DSCP preserved, and a hop count derived from the difference between the sender-stamped original TTL (64) and the TTL observed on arrival. If anything in the path remarks DSCP or decrements TTL more than expected, you'll see it immediately.
Behind-the-scenes details (worth knowing for a lab)
- Destination UDP port is
19779(0x4D43="MC"). Choose this if you need to filter in tcpdump:tcpdump 'udp port 19779 and host 239.0.10.101'. - Default datagram size is 200 bytes (32-byte header + 168-byte payload).
Configure with
--size. Minimum is 32 bytes (header only). - Packet padding is
0xA5repeated — easy to eyeball in a capture. - Sender ID randomization means restarting a sender looks like a brand-new sender on the receiver, which is exactly the right semantic — we don't want the receiver to interpret a restart as a giant burst of packet loss.
- Per-sender sequence tracking means a receiver listening to multiple senders (or one sender across restarts) doesn't conflate their sequence spaces.
- Stall detection is interval-based, not packet-rate-based — we don't need a control channel to know the sender's target rate.
- Foreign packet counter counts UDP datagrams on the group that don't
start with the
MCASmagic header. Useful for detecting when something else (real video, iperf, etc.) is sharing the group.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcast_tools-0.1.0.tar.gz.
File metadata
- Download URL: mcast_tools-0.1.0.tar.gz
- Upload date:
- Size: 25.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8610726a421140b311de32254f4b8c4897d3d9b3adc189c92c8b3e7f094ea99
|
|
| MD5 |
2d81b2aae00268f09236b912b1cb2805
|
|
| BLAKE2b-256 |
e67779840028407ee2de75aa3b9533287762c1757e2eb0e8b5b00af435a44fbe
|
Provenance
The following attestation bundles were made for mcast_tools-0.1.0.tar.gz:
Publisher:
release.yml on mitchv85/mcast-tools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcast_tools-0.1.0.tar.gz -
Subject digest:
b8610726a421140b311de32254f4b8c4897d3d9b3adc189c92c8b3e7f094ea99 - Sigstore transparency entry: 1604622319
- Sigstore integration time:
-
Permalink:
mitchv85/mcast-tools@b68a700db2b80568c30aeff9efccca4fec572438 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mitchv85
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b68a700db2b80568c30aeff9efccca4fec572438 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file mcast_tools-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcast_tools-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4669fa67174ffc20a04580066cae06f66da677700e87639b17749d28c6d6628f
|
|
| MD5 |
335db6e3e249f8ce8e9f986fdf589677
|
|
| BLAKE2b-256 |
2776aa8eba2ffc29ed6787976f6cb35ed9661ed9ca69909f863b810e056225ec
|
Provenance
The following attestation bundles were made for mcast_tools-0.1.0-py3-none-any.whl:
Publisher:
release.yml on mitchv85/mcast-tools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcast_tools-0.1.0-py3-none-any.whl -
Subject digest:
4669fa67174ffc20a04580066cae06f66da677700e87639b17749d28c6d6628f - Sigstore transparency entry: 1604622539
- Sigstore integration time:
-
Permalink:
mitchv85/mcast-tools@b68a700db2b80568c30aeff9efccca4fec572438 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mitchv85
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b68a700db2b80568c30aeff9efccca4fec572438 -
Trigger Event:
workflow_dispatch
-
Statement type: