Can anyone help. This is the first time I’ve got involved in sockets.
I’m trying to set up a socket that joins a multicast group.
Do I need to configure QNX in some way to handle multicasting?
The following code should set up the socket to both receive and send and is
based on code in W. Richard Stevens’ UNIX Network Programming book. In
mcast_join the setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq))); call fails…
const int on = 1;
socklen_t salen;
struct sockaddr *sasend, *sarecv;
m_sendsockFd = Udp_client(p_host, p_portNo, (void **) &sasend, &salen);
socket is called in Udp_client and errno is set to 3 (no such process) as a
result
m_recvsockFd = socket(sasend->sa_family, SOCK_DGRAM, 0);
After this call to socket errno is again set to 3 (no such process)
setsockopt (m_recvsockFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
sarecv = (sockaddr *)malloc(salen);
memcpy(sarecv, sasend, salen);
bind (m_recvsockFd, sarecv, salen);
int fail = mcast_join(m_recvsockFd, sasend, salen, NULL, 0);
mcast_join calls setsockopt which fails (-1) and errno is set to 249 (Can’t
assign requested address)
fail = mcast_set_loop(m_sendsockFd, 0);
Udp_client, mcast_join and mcast_set_loop are below.
int Udp_client(const char * host, const char * serv, void ** saptr,
socklen_t * lenp) {
int sockfd, n;
struct addrinfo hints, *res, *ressave;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)
{
return (-1);
}
ressave = res;
do
{
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd >= 0)
{
break;
}
} while ( (res = res->ai_next) != NULL);
if (res == NULL)
{
return (-1);
}
*saptr = malloc(res->ai_addrlen);
memcpy(*saptr, res->ai_addr, res->ai_addrlen);
*lenp = res->ai_addrlen;
freeaddrinfo(ressave);
return (sockfd);
}
int mcast_join(int sockfd, struct sockaddr * sa, socklen_t salen, const
char * ifname, u_int ifindex) {
struct ip_mreq mreq;
struct ifreq ifreq;
memcpy(&mreq.imr_multiaddr, &((struct sockaddr_in *)sa)->sin_addr,
sizeof(struct in_addr));
if (ifindex > 0)
{
if (if_indextoname(ifindex, ifreq.ifr_name) == NULL)
{
return(-1);
}
goto doioctl;
} else if (ifname != NULL)
{
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
doioctl:
if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)
{
return(-1);
}
memcpy(&mreq.imr_interface,
&((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
sizeof(struct in_addr));
} else
{
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
}
return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof(mreq)));
}
int mcast_set_loop(int sockfd, int onoff) {
u_char flag;
flag = onoff;
return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
&flag, sizeof(flag)));
}