Receiving UDP multicast issues (unicast is fine)

While the stack nicely responds to incoming UDPs on its own IP address (hardcoded or aquired through DHCP) I have some trouble gettting the same to be true for addresses sent out on the multicast address (224,0,0,251).

Code below works like a dream when the address is set to (10,1,2,3 -- i.e. a local address) - and onUDPSockEvent() fires and passes the right packet.:

Host localhost(IpAddr(MCAST), MDNS_PORT, NULL /* fqdn */);

 

 

 

m_pUDPSocket = new UDPSocket;

m_pUDPSocket->bind(localhost);

m_pUDPSocket->setOnEvent(this, &mDNSResponder::onUDPSocketEvent);

But when the actual MC address is used (224,0,0,251) - it does not wake up the stack; even though ip_addr.h and the processing in ip4/ip.c looks to check both 'own' IP and multicast.
Is this expected to work and am I doing something silly ? Or is there something missing ?
Thanks,
Dw.

 

 

 

Hmm - am starting to wonder/conclude that the stack is not quite configured for it - and that it needs something along the lines of below in ipv4/ip.c its ip_input() hander.

 

Dw.

 

 

/* interface is up and configured? */

if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {

/* unicast to this interface address? */

if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||

/* or broadcast on this interface network address? */

ip_addr_isbroadcast(&(iphdr->dest), netif) ||

/* or is this to our multicast interface? --- Added DIRKX */

ip_addr_ismulticast(&(iphdr->dest))

) {

LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",

 

21 Jul 2010

Hi Dirk-Willem,

I actually haven't tested the stack with multicast yet. I am going to give it a try today and see what goes wrong.

Donatien

Thanks. With above change I can get my RendezVous/Bonjour advertizer to work (so that the web, snmp and temperature server on the mbed are automatically discovered, appearing in the list, etc).

21 Jul 2010 . Edited: 21 Jul 2010

Hacked  a more complete version in

http://mbed.org/users/dirkx/programs/Bonjour

http://mbed.org/users/dirkx/notebook/simple-mdns-responder/

based on some old code.

23 Jul 2010 . Edited: 23 Jul 2010

Hi Dirk,

I went through the ip.c source code.

(ip.c, ip_input)

#if LWIP_IGMP
  if (ip_addr_ismulticast(&current_iphdr_dest)) {
    if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &current_iphdr_dest))) {
      netif = inp;
    } else {
      netif = NULL;
    }
  } else
#endif /* LWIP_IGMP */

 

Looks like LwIP does support multicast, you just have to use IGMP and to join the multicast group first.

I'll have a look at how to implement this nicely in the next version of the stack.

Donatien

Right - so this is where I got stuck - as you'd expect the canonical/default/routing group to be already joined when activated (and have the higher groups up till 254 joined on demand as applications needed so).

And that does not seem to be the case.

Wondering now if perhaps the issue here is more that a sensible default is missing*.

Thanks,

Dw.

 

*: I guess one would really expect an embedded device to sort of understand its role; have DHCP interact with mDNS and have the standard services (http, snmp, etc) auto-advertize; and have the device provide in a <foo>.local, where foo is llink or the DHCP-ed name, regardless.

26 Jul 2010 . Edited: 26 Jul 2010

.

26 Jul 2010

Hi Dirk,

Multicast support will be added to the UDPSocket class.

However, I think that autodiscovery and the way of doing it is still really application-specific. It's really up to anyone to choose to implement it or not.

That said, I think that mDNS support for instance would fit really well in the "services".

Donatien

26 Jul 2010

Hi again,

Could you give a go to this new beta version? I enabled IGMP support, you should now be able to use UDPSocket without any modification (the multicast network is joined in the bind method):

http://mbed.org/users/donatien/programs/EthernetNetIfBeta

Cheers

Donatien

27 Jul 2010

I just updated and tested the EthernetNetIfBeta library, it's now working fine with multicast.

http://mbed.org/users/donatien/programs/EthernetNetIfBeta/

Here is a simple example that both receives and send data:

http://mbed.org/users/donatien/programs/UDPMulticastDemo/

Ok - got this working in two ways

1) patching lwip with the casts (see published project - is there an easy way I can diff that?)

2) with above library.

Both work with the services/mDNS service.

Thanks,

Dw.


user avatar
Donatien Garnier wrote:

However, I think that autodiscovery and the way of doing it is still really application-specific. It's really up to anyone to choose to implement it or not.

That said, I think that mDNS support for instance would fit really well in the "services".

 

Not sure I quite agree - if you have a hardcode IP - then yes -see the point. But the moment you run DHCP and any service (e.g. a webservice) you'd allmost want to make it the default.
Dw.
17 Nov 2011

Donatien,

First, congrats on a great EthernetNetIf stack.

I have been doing multicast IGMP, etc. just fine for some time now but I recently did a wireshark trace and noticed that the header in the IGMP join group request is malformed, specifically the checksum on the header is wrong. I think this is causing my switch (HP Procurve 4000M) to ignore the join group request from the mBed because my packets from the other end are being ignored and not routed to the port the mBed is connected to, unless I turn on a feature in the switch that forwards everything. When you get a chance can you take a look at the code (I don't seem to have access to it) that forms the IGMP Join request? I actually don't see the IGMP join group command coming from the mBed for a long time after it starts up after the udp.bind command (probably 1 minute or so before it is seen on the network). I don't think the udp.bind command is sending the IGMP join in a timely manner either.

Thought you should know.

Thanks!

21 Nov 2011

I figured out part of the problem (it took me 1.5 days). I got a hold of the source code for EthernetNetIf, it's called "NetServicesSource" and it's available in the "Code" area on the site. I managed to clean up some minor errors that were preventing it from compiling through mBed's online compiler and then proceeded to track down how a packet flows through this massive beast of an interface.

Somewhere just before the IGMP packet is sent, the IP header checksum is getting mangled, I don't know where yet. I hacked in a workaround/fix for this by modifying the code in eth_drv.cpp to just intercept these packets and recalculate the correct checksum just before transmission.

Insert the below code just before the pEth->write command on line 58 in eth_drv.cpp :

    // recalculate the ip header checksum again, for some reason it got mangled on the way here
    // but only for IGMP type messages
    static u16_t new_chksum = 0;
    new_chksum = 0;
    static unsigned char ip_header_len;
    ip_header_len = 24; // always 24?  let's assume so for now
    // determine if this is an IGMP message
    if (*((char *)p->payload+23) == 0x02) {
        // clear bytes 24 and 25 (these are the old incorrect ip header checksum values)
        *((char *)p->payload+24) = 0x00;
        *((char *)p->payload+25) = 0x00;
        // calculate new checksum for ip header section starting at position 14 for 24 bytes
        new_chksum = inet_chksum( ((char *)p->payload+14), ip_header_len);
        // insert the checksum
        *((char *)p->payload+24) = (unsigned char)(new_chksum);
        *((char *)p->payload+25) = (unsigned char)(new_chksum >> 8);
    }

Also be sure to add #include "lwip/inet_chksum.h" at the top somewhere.

Now my mBed correctly joins the multicast group via a well formed IGMP join request and the switch correctly routes traffic between host and client.

Thanks, Errol Burrow (using John R's account, with permission :) )

30 Apr 2012

Hi,

I just tried Donatien's UDPSocket demo http://mbed.org/users/donatien/programs/EthernetNetIfBeta

I adjusted the port and multicast group address accordingly. It does not seem see a multicasting device on my LAN that I *can* see from my desktop machine.

I am wondering whether this is still in beta? Perhaps there is a new version given that 2 years has elapsed since that beta was created?

It now looks as if this is not working either in the above beta or in the current version of EthernetIf.

Continued on http://mbed.org/forum/mbed/topic/3486 where I am using the latest library but still hitting problems.

My guess is that the bug identified by John R is still extant.

Thx Paul

09 Feb 2013

I have also been trying to pick up Multicast data packets with the UDPSocket from the latest official mbed library and I can't get it working. I am using a lightly modified version of the UDP Echo Client example.

I'm not clear on how you join the group address with the API as it stands. Any tips on getting this working would be gratefully received!