Sending multicast message

Hi,

When I’m sending a multicast message (from ONX 6.3.2 host), the sendto() function always returns an error: “No route to host” and failed sending the message.
But the other network communication like ping is working well. Both hosts are connected direct with ethernet cress cable.
Here is the code where I’m calling the sendto():

ssize_t netSendEvent(Octet *buf, UInteger16 length, NetPath *netPath)
{
ssize_t ret;
struct sockaddr_in addr;
int err;

addr.sin_family = AF_INET;
addr.sin_port = htons(PTP_EVENT_PORT); // EVENT_PORT = 319
addr.sin_addr.s_addr = netPath->multicastAddr; // netPath->multicastAddr is 224.0.1.129

ret = sendto(netPath->eventSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
if(ret <= 0)
DBG(“error sending multi-cast event message, err: %s\n”,strerror(err));

return ret;
}

My en0 configuration is:

io-net -m -d i82544 -p tcpip
ifconfig en0 192.168.0.2 up

What else do I need to set up on QNX to make the multicast work? Are there any further issues?

Thanks,
Miro

Miro,

Your IP is 192.168.0.2.

The multi-cast IP is 224.0.1.129

These are on different subnets.

So you will have to have set up route/gateway information someplace in order to route traffic from your 192 address to the 224 address (usually the route/gateway information points to your router/gateway which in the case of a cross-over cable you don’t have because there is no router/gateway).

Does the other machine that is connected to you really have a 224 address?

Tim

Tim,

Addresses that start with 224 have a special meaning, they are multi-cast IP addresses.

Miroslave,

netPath->eventSock must be of type SOCK_DGRAM. Are you sure the receiver is running and has properly joined the multi-cast group?

The netPath->eventSock is type of SOCK_DGRAM.
But I’m not sure about the multicast group! I have checked with the Wireshark the communication between this two hosts (Ubuntu <—> QNX) if any IGMP messages (these messages register host to multic. group ) are send. Only the Ubuntu host has send IGMP message and has joined the multicast group. But there was no communication from the QNX site, and QNX host didn’t join the multicast group. I was testing Ubuntu <—> Ubuntu connection and both sides joined the group and all was working well.

I post the code where the initialization of the socket is.
Any ideas why multicast group registration in QNX fails??? How to set up the QNX ?

Boolean netInit(NetPath *netPath, RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
int i;
socklen_t temp;
#ifdef QNXNTO
unsigned char tempc;

define temp_value tempc

#else

define temp_value temp

#endif
struct in_addr interfaceAddr, netAddr;
struct sockaddr_in addr;
struct ip_mreq imr;
char addrStr[NET_ADDRESS_LENGTH];
char *s;

DBG(“netInit\n”);

/* open socket */
if( (netPath->eventSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0 ) {
PERROR(“failed to initalize sockets”);
return FALSE;
}

/* find a network interface */
if( !(interfaceAddr.s_addr = findIface(rtOpts->ifaceName, &ptpClock->port_communication_technology,
ptpClock->port_uuid_field, netPath)) )
return FALSE;

temp = 1; /* allow address reuse */
if( setsockopt(netPath->eventSock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(int)) < 0 ) {
DBG(“failed to set socket reuse\n”);
}

/* bind sockets /
/
need INADDR_ANY to allow receipt of multi-cast and uni-cast messages */
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(PTP_EVENT_PORT);

if(bind(netPath->eventSock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0){
PERROR(“failed to bind event socket”);
return FALSE;
}

/* set port address */
(Integer16)ptpClock->event_port_address = PTP_EVENT_PORT;

/* resolve PTP subdomain */
if(!lookupSubdomainAddress(rtOpts->subdomainName, addrStr))
return FALSE;

if(!inet_aton(addrStr, &netAddr)) {
ERROR(“failed to encode multi-cast address: %s\n”, addrStr);
return FALSE;
}

netPath->multicastAddr = netAddr.s_addr;

s = addrStr;
for(i = 0; i < SUBDOMAIN_ADDRESS_LENGTH; ++i) {
ptpClock->subdomain_address[i] = strtol(s, &s, 0);

if(!s)
  break;

++s;

}

/* multicast send only on specified interface */
imr.imr_multiaddr.s_addr = netAddr.s_addr;
imr.imr_interface.s_addr = interfaceAddr.s_addr;
if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0 ) {
PERROR(“failed to enable multi-cast on the interface”);
return FALSE;
}

/* join multicast group (for receiving) on specified interface */
if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq)) < 0 ) {
PERROR(“failed to join the multi-cast group”);
return FALSE;
}

/* set socket time-to-live to 1 */
temp_value = 1;
if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, &temp_value, sizeof(temp_value)) < 0 ) {
PERROR(“failed to set the multi-cast time-to-live”);
return FALSE;
}

/* enable loopback */
temp_value = 1;
if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp_value, sizeof(temp_value)) < 0 ) {
PERROR(“failed to enable multi-cast loopback”);
return FALSE;
}

/* make timestamps available through recvmsg() */
temp = 1;
if( setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0 ) {
PERROR(“failed to enable receive time stamps”);
return FALSE;
}

return TRUE;
}

The EHOSTUNREACH on the sender is independent
of joining a group on the receiver(s). You should
be able to send to the group and see it with your
sniffer with no receivers registered.

As the error indicates you have no route. Adding
a default route will catch all multicast groups in this
case on the sender:

route add default

-seanb

Great !

I have added a default route: # route add default 192.168.0.0
and its working! Both hosts ( 192.168.0.1 and 192.168.0.1 ) are sending and receiving multicast.

Thank you!

Miroslav