CastRepeat is a somehwhat robust multicast relay tool written in Rust that allows you to capture multicast traffic on one network and repeat it on another. It is designed for environments where multicast routing is not available or practical and you need to bridge multicast traffic across network boundaries via a reliable transfer protocol (TCP instead of UDP for example)
- Being a multicast relay: Capture and relay multicast packets between networks
- Group filtering: Configure specific multicast groups to relay
- Port filtering: Relay traffic on specific ports only
- Authentication: Secure communication between server and client
- NAT Traversal: Support for clients behind NAT firewalls
- Test Mode: View received multicast packets without relaying them
- Authorization Controls: Control which clients can access which multicast groups
CastRepeat uses a client-server architecture:
- Server: Captures multicast traffic on its network
- Client: Receives and retransmits multicast traffic locally
Network A Network B
+----------------+ +----------------+
| Multicast | | Multicast |
| Sources | | Receivers |
| | | |
| +--------+ +---------+ |
| | Server +----TCP-IP----+ Client | |
| +--------+ +---------+ |
| | | |
+----------------+ +----------------+
- Rust 1.52.0 or higher
libssl-dev
(OpenSSL development libraries)
- Network privileges for multicast (may require sudo/root)
If you don't have Rust installed, use rustup (the official Rust installer):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Then, follow the on-screen instructions to complete the installation. After installing, ensure that the Rust bin
directory is in your system's PATH
.
-
Clone the repository:
git clone https://git.teleco.ch/crt/castrepeat.git/
cd castrepeat
-
Build the project:
cargo build --release
-
The binaries will be available in target/release/
:
- castrepeat-server
: The server component
- castrepeat-client
: The client component
- castrepeat-mcast-test
: A simple tool for generating multicast test traffic
Create a server_config.toml
file:
secret = "your-shared-secret-key"
listen_ip = "0.0.0.0"
listen_port = 8989
simple_auth = true
allow_external_clients = true
[multicast_groups]
# Example group for some service
[multicast_groups.service1]
address = "239.192.55.1"
port = 1681
# Another group with a port range
[multicast_groups.service2]
address = "239.192.55.2"
port_range = [1680, 1685]
# Client authorization (optional when simple_auth = true which is needed for NAT traversal scenarios)
[[authorized_clients]]
name = "office-client"
ip_address = "192.168.1.100"
group_ids = ["service1"] # Only allow access to service1
Create a client_config.toml
file:
secret = "your-shared-secret-key"
server = "server.example.com" # Server hostname or IP address
port = 8989
multicast_group_ids = [] # Empty means subscribe to all available groups
test_mode = false
nat_traversal = true # Enable for NAT traversal features
reconnect_delay_secs = 5
# With default config location
sudo ./target/release/castrepeat-server
# With custom config path
sudo ./target/release/castrepeat-server --config /path/to/server_config.toml
# Generate default configs
./target/release/castrepeat-server --generate-default
# With default config location
./target/release/castrepeat-client
# With custom config path
./target/release/castrepeat-client --config /path/to/client_config.toml
# Generate default configs
./target/release/castrepeat-client --generate-default
Use the client's test mode to see multicast packets without relaying them:
# In client_config.toml:
test_mode = true
The bodeting.sh
script provides a simple way to start a server and debug client:
# Run the script
./bodeting.sh
This will:
1. Create configuration files in the configs/
directory
2. Start a tmux session with the server and client
3. Display the logs side-by-side for easy debugging
Generate test multicast traffic:
./target/release/castrepeat-mcast-test
./target/release/castrepeat-mcast-test --multicast-addr 239.192.55.1 --port 1681
./target/release/castrepeat-mcast-test --message "Custom packet data" --interval-ms 500 --duration-sec 120
./target/release/castrepeat-mcast-test --multicast-addr 239.192.55.2 --port 1681 --interval-ms 2000 --duration-sec 300 --message "Test packet"
For clients behind NAT firewalls:
- Forward server's TCP port (default 8989) to the server's internal IP
- Set
allow_external_clients = true
in the server's config
- Set
nat_traversal = true
in the client's config
- Use the server's public IP address in the client's config
- Ensure multicast routing is enabled on your router/switch
- Check firewall rules to allow multicast traffic
- Verify that you're using the correct multicast address and port
- Run
castrepeat-mcast-test
to verify multicast connectivity
- Check if the server is running and accessible
- Verify that the shared secret matches on both ends
- For clients behind NAT, ensure proper port forwarding is configured
- Make sure no other application is using the same ports
- Run the server with sudo/root privileges
- Try binding to a specific interface
- Bridging multicast traffic across networks
- Relaying multicast across VPNs or cloud environments
- Testing multicast applications in isolated environments
- Monitoring multicast traffic for debugging
-c, --config <FILE>
: Path to config file (default: server_config.toml)
-g, --generate-default
: Generate default config files
-c, --config <FILE>
: Path to config file (default: client_config.toml)
-g, --generate-default
: Generate default config files
--multicast-addr <ADDR>
: Multicast address to send to (default: 239.192.55.1)
--port <PORT>
: Port to send on (default: 1681)
--interval-ms <MS>
: Sending interval in milliseconds (default: 1000)
--duration-sec <SEC>
: How long to send packets (default: 60)
--message <MSG>
: Custom message to send (default: "Test packet")
This is my first more like real world usecase rust project, Therefore I do not guarantee anything.
All comments and documentation have been sanatized by Claude 3.7 Sonnet Thinking, as my personal ones tend to have some more aggresssive messages in them.
Alot of issues were also fixed by throwing spaghetti at the wall and hoping it magically achieves the results expected