multicastnetstatss

ss and netstat show different multicast groups


On one of my systems at work good ol' netstat shows multicast group membership information, and ss is missing a couple. I wonder why. For example:

[root@myhost ~]# netstat -gn | egrep "Inter|239.192"
Interface       RefCnt Group  
em4.204         1      239.192.33.183
em1.16          2      239.192.35.1
em1.16          2      239.192.12.98
em1.16          1      239.192.32.1


[root@myhost ~]# ss -apu | egrep "State|239.192"
State      Recv-Q Send-Q Local Address:Port                 Peer Address:Port                
UNCONN     0      0      239.192.35.1:12965                    *:*                    
UNCONN     0      0      239.192.12.98:12965                    *:*                    
UNCONN     0      0      239.192.35.1:12965                    *:*                    
UNCONN     0      0      239.192.12.98:12965                    *:*                       

Notice that ss shows only those groups with a RefCnt of 2.

Technically, ip maddr show is the replacement for netstat -gn but it doesn't include the RefCnt, and its output is more cumbersome. Also, we're interested in the more detailed output of ss which can include the PID of the listening processes (not seen here because no processes are actually currently listening to the multicast, as show by netstat -ulpn:

[root@myhost ~]# netstat -ulpn | egrep "Proto|239.192"
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
udp        0      0 239.192.35.1:12965      0.0.0.0:*                           -                   
udp     4480      0 239.192.12.98:12965     0.0.0.0:*                           -                   
udp        0      0 239.192.35.1:12965      0.0.0.0:*                           -                   
udp        0      0 239.192.12.98:12965     0.0.0.0:*                           -                   

Solution

  • (I encountered this question looking for an answer to a similar one, which is how to list processes that joined a particular multicast group...)

    netstat -gn and ip maddr show multicast groups what are joined by the network interface, which roughly means that packets destined to the addresses will be accepted on the interface.

    netstat -nau | grep (…) and ss -au src 224.0.0.0/4 (notice the fancy filter in ss) will display the sockets bound to multicast addresses.

    These are two different and somewhat unrelated things.


    Just binding a socket to a multicast address so that it shows up in ss / netstat is fine, but it will not join the multicast group automatically.

    Try: socat udp4-l:12345,bind=239.1.2.3 -, which shows up in netstat as:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    udp        0      0 239.1.2.3:12345         0.0.0.0:*                           7604/socat 
    

    and such connection is completely useless until one joins the group – netstat -g and ip maddr do not mention this address.


    To receive a multicast message, you do not need to bind to a multicast address.

    Try this: socat udp4-listen:12345,ip-add-membership=239.1.2.3:br0 -

    Until you get a message, you show up in netstat as:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    udp        0      0 0.0.0.0:12345           0.0.0.0:*                           6132/socat
    

    Once you get a first message, you show up as:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    udp        0      0 10.0.0.2:12345          10.0.0.3:52036          ESTABLISHED 6132/socat      
    

    Notice that there is no mention of the multicast group you joined in the socket description, despite the multicast is running just fine.

    To see the multicast groups, you can use either netstat -g

    IPv6/IPv4 Group Memberships
    Interface       RefCnt Group
    --------------- ------ ---------------------
    br0             1      239.1.2.3
    

    or ip maddr:

    7:      br0
            link  01:00:5e:01:02:03
            inet  239.1.2.3
    

    (Only relevant lines are shown here.)

    The API of joining a multicast group is actually setting a socket option 'IP_ADD_MEMBERSHIP'. To get a multicast message two things must batch: ① the port to which the socket is bound (as in bind(…) function), and ② IP any of the joined groups on the specified interface.

    (The socat above uses a pseudoconnection mode for UDP; you can also try a conectionless mode by e.g., socat UDP-DATAGRAM:10.0.0.4:3000,bind=10.0.0.2:2000,ip-add-membership=239.1.2.3:br0 - which sends to 10.0.0.4:3000 and receives on both 10.0.0.2:2000 and 239.1.2.3:2000%br0, and always displays as the first netstat output)


    As I tested today, if multiple programs join the same group, you'd see a use count in ip maddr:

    7:      br0
            link  01:00:5e:01:02:03 users 2
            inet  239.1.2.3 users 2
    

    which means it now displays the RefCnt provided it's greater than 1.

    (You might need the reuseaddr option to test that with socat.)