Code Monkey home page Code Monkey logo

mcjoin's Introduction

m c j o i n - tiny multicast testing tool

License Badge GitHub Status Coverity Status

mcjoin(1) is a simple and easy-to-use tool to test IPv4 and IPv6 multicast, featuring:

  • a multicast generator (server)
  • a multicast data sink (client)
  • support for join/send to one or more groups
  • support for both any source and source specific multicast:
    • ASM (*,G)
    • SSM (S,G)
  • support for both IPv4 & IPv6
  • support for the following operating systems:
    • Linux (GLIBC, musl libc)
    • FreeBSD
    • Apple macOS
    • OpenSolaris/Illumos
  • no support for the following due to lack of RFC3678 support:
    • NetBSD
    • OpenBSD

latest release available here: https://github.com/troglobit/mcjoin/releases

example

this is a fairly odd example, joining multiple ipv6 asm groups and a single ipv4 ssm group. the purpose is only to show that it's possible.

mcjoin ff2e::42 ff2e::43 ff2e::44 ff2e::45 225.1.2.3

mcjoin receiver

the sender needs to have an ipv6 (and ipv4) address on the egressing interface. here the system only has an ipv6 address.

mcjoin -s ff2e::42

mcjoin sender

by default, mcjoin use the ipv4 group 225.1.2.3 (which is very easy to spot also when translated to mac multicast, RFC1112). however, for testing purposes you may want to instead use the MCAST_TEST_NET from RFC5771, 233.252.0.0/24, or possibly test group 232.43.211.234, UDP port 4321, as defined in this IETF draft.

for testing IPv6 you can use ff2e::42. for ipv6 groups the ipv6 address of the outbound interface will be used.

remember: to set ipv4 and/or ipv6 address on the outbound interface!

usage

without any arguments mcjoin defaults to act as a receiver, performing an IPv4 ASM join (*,G) of group 225.1.2.3, UDP port 1234. to act as a sender of the same group and port, add -s to the command line.

$ mcjoin -h

Usage: mcjoin [-dhjosv] [-c COUNT] [-f MSEC] [-i IFACE] [-l LEVEL]
              [-p PORT] [-t TTL] [-w SEC]
              [[SOURCE,]GROUP0 .. [SOURCE,]GROUPN | [SOURCE,]GROUP+NUM]

Options:
  -b BYTES    Payload in bytes over IP/UDP header (42 bytes), default: 100
  -c COUNT    Stop sending/receiving after COUNT number of packets
  -d          Run as daemon in background, output except progress to syslog
  -f MSEC     Frequency, poll/send every MSEC milliseconds, default: 100
  -h          This help text
  -i IFACE    Interface to use for sending/receiving multicast, default: eth0
  -j          Join groups, default unless acting as sender
  -l LEVEL    Set log level; none, notice*, debug
  -o          Old (plain/ordinary) output, no fancy progress bars
  -p PORT     UDP port number to listen to, default: 1234
  -s          Act as sender, sends packets to select groups
  -t TTL      TTL to use when sending multicast packets, default 1
  -v          Display program version
  -w SEC      Initial wait before opening sockets
  -W SEC      Timeout, in seconds, before mcjoin exits

Bug report address : https://github.com/troglobit/mcjoin/issues
Project homepage   : https://github.com/troglobit/mcjoin/

the SOURCE argument is optional, but when used it must be of the same address family as the group. to join multiple groups, either list them all on the command line, separated with space, or use the +NUM syntax. at the moment max 2048 groups can be joined.

troubleshooting

the multicast producer, mcjoin -s, can send without a default route, but the sink (your receiver) need a net route back to the sender (or a default route), or reverse-path filtering (RPF) disabled to be able to receive the UDP stream. the sink will be able to start without an IP address or route, as long as the interface is UP and allows MULTICAST, the IGMP or MLD join frames will also be sent while you wait for an address+route, but the kernel will (likely) not forward any frames to mcjoin even though it may be arriving at the interface if you check with tcpdump.

in particular, this issue will arise if you run mcjoin in isolated network namespaces in Linux. e.g.

ip netns add sink
ip link set eth2 netns sink
ip netns exec sink /bin/bash
ip address add 127.0.0.1/8 dev lo
ip link set lo up
ip link set eth2 name eth0
ip address add 10.0.0.42/24 dev eth0
ip link set eth0 up
ip route add default via 10.0.0.1
mcjoin

depending on the route setup, and number of interfaces on a multihomed system, you may also need to verify that you don't have strict reverse path filtering (RPF) enabled. on Linux rp_filter can be set to either 0 (no filtering), 1 (strict), or 2 (loose filtering), the latter is the most common for distributions today. the difference between 1 and 2 is that 1 (strict) checks for the best route, while 2 checks for any route back to the sender. see RFC3704 for more on reverse path filtering.

caveat

usually there is a limit of 20 group joins per socket in UNIX, this is the IP_MAX_MEMBERSHIPTS define. on Linux this can be tweaked using a /proc setting:

echo 40 > /proc/sys/net/ipv4/igmp_max_memberships

mcjoin has a different approach, it opens a unique socket per each group to join and for each socket disables the odd IP_MULTICAST_ALL socket option, which is enabled by default. Citing the Linux ip(7) man page, emphasis added:

IP_MULTICAST_ALL (since Linux 2.6.31)

This option can be used to modify the delivery policy of multicast messages to sockets bound to the wildcard INADDR_ANY address. The argument is a boolean integer (defaults to 1). If set to 1, the socket will receive messages from all the groups that have been joined globally on the whole system. Otherwise, it will deliver messages only from the groups that have been explicitly joined (for example via the IP_ADD_MEMBERSHIP option) on this particular socket.

the same applies to ipv6(7), although the IPV6_MULTICAST_ALL socket option has only existed since Linux 4.20.

hence, by default all multicast applications in UNIX will receive all multicast frames from all groups joined by all other applications on the same system ...

... which IMO is a weird default since multicast by default is opt-in, not opt-out, which is what POSIX makes it. OK, maybe it's not mandated by POSIX, and (unregulated) multicast is akin to broadcast, but still! I bet most developer's don't know about this.

testing on the same machine

in many cases while using mcjoin for testing networking equipment, you need to use at least two local network interfaces (nics): one acting as multicast sender and one as receiver. (often you need multiple sender interfaces, which can be physical, virtual or vlan interfaces.)

        .-------.
        |       |
    .---+  dut  +---.
    |   |       |   |
    |   '-------'   |
    |               |
.- eth0 ---------- eth1 -.
|                        |
|           pc           |
|                        |
'------------------------'

to get this to work on linux you need to disable the rp_filter and enable accept_local sysctl settings for the involved interfaces. here is an example of how to adjust this for all interfaces. use with care, this can cause a lot of other problems if you use the same pc for other purposes as well:

$ cd /etc/sysctl.d/
$ cat 10-network-security.conf
# Allow receiving IP packets from local interfaces, useful for testing
# rigs where looping packets via networking infrastructure.
net.ipv4.conf.default.accept_all=1
net.ipv4.conf.all.accept_all=1

# Disable Source Address Verification in all interfaces to, usually set
# to 1 to prevent some spoofing attacks.  But for a testing rig this is
# usually the source of many woes, in particular for multicast testing.
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=0

build & install

the GNU Configure & Build system use /usr/local as the default install prefix. for most use-cases this is fine, but if you want to change this to /usr use the --prefix=/usr configure option:

$ ./configure --prefix=/usr
$ make -j5
$ sudo make install-strip

building from git

if you want to contribute, or simply just try out the latest but unreleased features, then you need to know a few things about the GNU Configure & Build system:

  • configure.ac and a per-directory Makefile.am are key files
  • configure and Makefile.in are generated from autogen.sh, they are not stored in GIT but automatically generated for the release tarballs
  • Makefile is generated by configure script

to build from GIT; clone the repository and run the autogen.sh script. this requires automake and autoconf to be installed on your system. (if you build from a released tarball you don't need them.)

git clone https://github.com/troglobit/mcjoin.git
cd mcjoin/
./autogen.sh
./configure && make
sudo make install-strip

mcjoin's People

Contributors

ayoung-lhft avatar ceclinux avatar forst avatar gclawes avatar jklare avatar rlibby avatar torstein-eide avatar troglobit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mcjoin's Issues

Receiver does not stop after count received packets

Hi Nilsson,

Many thanks for your sharing, that's a great util for mcast testing!

After doing fork the branch, I found -c parameter doesn't work on my local setup, I changed the code and move a size_t total = count * group_num to the top of loop() function as below commit.

chenxy1988@f729596

Thanks!
Xiangyu

mcjoin -s in docker container fails with: No interface (eth0), or no IPv6 address yet, rc 0: No error information

Hi

When I run mcjoin -s in a container it reports: No interface (eth0), or no IPv6 address yet, rc 0: No error information

Do I need to give special rights to the container?

Reproduction:

  1. git pull
  2. docker build .
  3. docker run -it xxx sh
  4. run it in the container
mcjoin -s -l debug
Found default intefaces eth0
NOFILE: current 1048576 max 1048576
NOFILE: set new current 2058 max 1048576
Found eth0 addr 172.17.0.2
Valid iface eth0, ifindex 118, addr 172.17.0.2
Sending on iface eth0 addr 172.17.0.2 ifindex 118
No interface (eth0), or no IPv6 address yet, rc 0: No error information
No interface (eth0), or no IPv6 address yet, rc 0: Interrupted system call
No interface (eth0), or no IPv6 address yet, rc 0: Interrupted system call
No interface (eth0), or no IPv6 address yet, rc 0: Interrupted system call
...

I've tried it on an Ubuntu 18.04 host and a Fedora 30 host.

Thanks

100% cpu usage in daemon mode

mcjoin -s -d results in 100 cpu usage. A quick ptrace shows mainly:

pselect6(5, [0 4], NULL, NULL, NULL, NULL) = 1 (in [0])
read(0, "", 1) = 0

IGMP/MLD monitoring

Hi,

I need to know if I could do a monitoring of IGMP/MLD messages (joins/leaves to groups) using the mcjoin tool. Or if I can do this with another tool. My objective is to start/stop some scripts based on the group state.

Thank you.

mcjoin (receiver) not receiving the multicast packet

Hi,

I'm trying to run the mcjoin on RHEL 7.4 in GNS3 and from the RHEL, I run tcpdump and can see the udp packet from the sender. However the mcjoin program shows 0 packets. Is there anything I missed?

Sender: mcjoin -s -t 100 -p 50500
Receiver: mcjoin -p 50500

Doesn't send IPv4 packets if IPv6 is not available

I have Ubuntu 20.04 with disabled Ipv6 and no Ipv6 address on interfaces. In that cast sender just can't send ipv4 packets with error like: No interface enp2s0, or no IPv6 address yet...
My simple workaround was just comment these:

mcjoin/src/mcjoin.c

Lines 254 to 255 in 0e287ee

if (sd4 == -1)
return;

and these

mcjoin/src/mcjoin.c

Lines 260 to 261 in 0e287ee

if (sd6 == -1)
return;

lines, and make appropriate check after this line:
int sd = groups[i].grp.ss_family == AF_INET ? sd4 : sd6;

Debian package

Hi there,

Would be possible to make mcjoin an official Debian package?
Looks like it is already possible to create a package, what would be needed to make it available over apt?

Issue with dots in debug mode

Hey @troglobit,

first I want to say that mcjoin is a great program for testing multicast.
Especially with the new interface it looks really sleek.

We are using the program to test our network setup with multiple clients joining in different locations.
For these tests we run the program 'headless' and we use the debug flag to save the stdout of each of the clients.
However the following line:

groups[id].status[STATUS_POS] = '.'; /* XXX: Use increasing dot size for more hits? */

gives weird (backspace?) characters in the saved redirected output, on my machine it shows up as ^H

e.g.

Count     0, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 850, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 850, freq: 100
group seq 0 vs seq 850
Count     1, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 850, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 850, freq: 100
group seq 851 vs seq 850
Count     2, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 851, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 851, freq: 100
Count     3, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 851, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 851, freq: 100
group seq 852 vs seq 851
Count     4, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 852, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 852, freq: 100
Count     5, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 852, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 852, freq: 100
group seq 853 vs seq 852
Count     6, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 853, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 853, freq: 100
Count     7, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 853, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 853, freq: 100
group seq 854 vs seq 853
Count     8, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 854, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 854, freq: 100
Count     9, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 854, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 854, freq: 100
group seq 855 vs seq 854
Count    10, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 855, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 855, freq: 100
Count    11, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 855, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 855, freq: 100
group seq 856 vs seq 855
Count    12, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 856, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 856, freq: 100
Count    13, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 856, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 856, freq: 100
group seq 857 vs seq 856
Count    14, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 857, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 857, freq: 100
Count    15, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 857, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 857, freq: 100
group seq 858 vs seq 857
Count    16, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 858, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 858, freq: 100
Count    17, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 858, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 858, freq: 100
group seq 859 vs seq 858
Count    18, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 859, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 859, freq: 100
Count    19, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 859, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 859, freq: 100
group seq 860 vs seq 859
..�Count    20, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 860, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 860, freq: 100
Count    21, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 860, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 860, freq: 100
group seq 861 vs seq 860
o�Count    22, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 861, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 861, freq: 100
Count    23, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 861, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 861, freq: 100
group seq 862 vs seq 861
O�Count    24, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 862, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 862, freq: 100
Count    25, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 862, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 862, freq: 100
group seq 863 vs seq 862
O�Count    26, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 863, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 863, freq: 100
Count    27, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 863, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 863, freq: 100
group seq 864 vs seq 863
o�Count    28, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 864, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 864, freq: 100
Count    29, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 864, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 864, freq: 100
group seq 865 vs seq 864
.�Count    30, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 865, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 865, freq: 100
Count    31, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 865, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 865, freq: 100
group seq 866 vs seq 865
..�Count    32, our PID 283957, sender PID 80618, group 225.1.2.3, seq: 866, msg: Sender PID 80618, MC group 225.1.2.3 ... count: 866, freq: 100


It happens from around count 20 upwards.
Compiled without that line gives us the consistent output we use.

p.s.:
Would you consider adding a 'timeout' flag that stops the program after x seconds?
Because we are testing link failures and in these cases the numbers of counts don't get hit in which case the program never quits.

Calculate and show gaps in summary output

We could do quite a bit of statistical analysis, but at least increment a counter every time we don't receive the next expected sequence number (counter).

Like this, for example:

root@n2:/usr/src/mcjoin# ./src/mcjoin -j 225.1.2.4 225.4.3.2
joined group 225.1.2.4 on eth0 ...
joined group 225.4.3.2 on eth0 ...
..................^C
Group 225.1.2.4 received 54 packets, gaps: 0
Group 225.4.3.2 received 54 packets, gaps: 30

Received total: 108 packets

Publish docker image

It's useful in container environments to have mcjoin for testing. I've created a PR #2 to build mcjoin in docker and package it in an image based on debian:stretch. This could be published to https://hub.docker.com/u/troglobit with DockerHub automated builds.

Enhance mcjoin to ease integration into test automation

I'd like to use mcjoin in my automated tests, and as such wanted to ask whether the following enhancements are possible?

  1. Have JSON output at the end of a run (such as iperf3 has).
  2. Have no-output mode (no progress bar at all).
  3. Compile mcjoin as library for integration into test software (e.g. into a robot-framework test library).
  4. Support explicit IGMP/MLD version . I know this can be done through sysctl, the question is can it be done through the application?

I'm opening this as one ticket as to not flood you with many new ticket suddenly :) If accepted, I can open separate tickets, and even try to contribute some of the code changes.

Receiving multicast on docker

Have you successfully received the multicast stream on docker? Is there anything to do to allow it? I'm running on EVE-NG.

Seperate listen port per group ?

Would it be possible to add a way to have mcjoin use a differnet listen port per group when joining multiple groups ? Maybe use the stnadard syntax group:port or group+num:port

Thanks for a great tool.

No feedback in receiver mode when mcjoin is used as sender

When running two instances of mcjoin the receiver sometimes doesn't print feedback for each packet it receives from the sender mcjoin. Unclear atm. why and for what use-cases this happens. Should be fixed before v2.7.

Receiving multiple groups could also be illustrated better, but might need some other type of output (ncurses?)

Source/group parser cuts of group addresses when using IPv6 SSM

Groups are cut off when the argument exceeds 49 characters:

mcjoin fd6f:7b5e:3918:9728:d8fa:2afd:d864:e944,ff3e::f2ce:7765 results in joining group ff3e::f2c instead of ff3e::f2ce:7765

The issue is caused at the following line:

char buf[INET_ADDRSTR_LEN + 1];

buf size has to be at least: 2 addresses, 3 delimiters, 2 brackets, 5 port digits and 1 zero terminator to support mcjoin source,[group0]:port+num

suggested change:
char buf[2 * INET_ADDRSTR_LEN + 11];

Thank you for a great tool and suggestion for improvement.

I have been looking for and testing tools for testing multicast for years and this is simply the very best I have come across. Keep up the good work,

Especially I really like the newer animated view.

I would like to suggest making it possible to view packet and byte throughput numbers (not just counter) for each joined group. Looks like some throughput information is already calculated to control the speed of the "spinner".

Maybe add an option to control sampling interval and scale of the byte throughput numbers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.