Shows how to do Multicast with the BSD apis (written in CLIB but should be able to compile with LIBC w/minimal changes).
#include<stdio.h>
#include<sys/types.h>
#include<nlm/sys/socket.h>
#include<nlm/sys/bsdskt.h>
#include<errno.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#define MCAST_ADDRESS "224.0.0.1"
#define SERVER_ADDR "192.168.228.10"
int NLM_Exiting = FALSE;
int NLM_Threads;
int NLM_ServerSocket;
void sigHnd(void)
{
NLM_Exiting = TRUE;
}
void main(void)
{
int clientSocket;
int sizeofClientAddr;
int iPort = 997;
char buff[300];
struct sockaddr_in serverAddr, clientAddr, remoteAddr;
struct ip_mreq mcastReq;
int iAddrReuse = TRUE, iTTLValue = 8, iLoop = FALSE;
NLM_Threads = 1;
memset((char *)&serverAddr, '\0', sizeof(struct sockaddr_in));
memset((char *)&clientAddr, '\0', sizeof(struct sockaddr_in));
memset((char *)&remoteAddr, '\0', sizeof(struct sockaddr_in));
memset((char *)&mcastReq, '\0', sizeof(struct ip_mreq));
memset(buff, '\0', sizeof(buff));
errno = 0;
if(( NLM_ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == (-1)){
perror("socket");
goto END_ERR;
}
printf("Setting SOL_SOCET/SO_REUSEADDR\r\n");
if(setsockopt(NLM_ServerSocket, SOL_SOCKET, SO_REUSEADDR,
(char *)&iAddrReuse, sizeof(iAddrReuse)) == (-1)){
perror("setsockopt SO_REUSEADDR");
goto END_ERR;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(iPort);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("binding to port: %d\r\n", iPort);
if(( bind(NLM_ServerSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr))) == (-1)){
perror("bind");
goto END_ERR;
}
remoteAddr.sin_family = AF_INET;
remoteAddr.sin_port = htons(iPort);
remoteAddr.sin_addr.s_addr = inet_addr(MCAST_ADDRESS);
mcastReq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDRESS);
mcastReq.imr_interface.s_addr = inet_addr(SERVER_ADDR);
printf("Setting IPPROTO_IP/IP_ADD_MEMBERSHIP\r\n");
if(setsockopt(NLM_ServerSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,/* 12, 5 */
(char *)&mcastReq, sizeof(mcastReq)) == (-1)){
perror("setsockopt IP_ADD_MEMBERSHIP");
printf("errorno = %d", errno);
goto END_ERR;
}
printf("turning off multicast loopback with IPPROTO_IP/IP_MULTICAST_LOOP\r\n");
if(setsockopt(NLM_ServerSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
(char *)&iLoop, sizeof(iLoop)) == (-1)){
perror("setsockopt IP_MULTICAST_LOOP");
goto END_ERR;
}
printf("Setting TTL value to %d with IPPROTO_IP/IP_MULTICAST_TTL\r\n", iTTLValue);
if(setsockopt(NLM_ServerSocket, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&iTTLValue, sizeof(iTTLValue)) == (-1)){
perror("setsockopt IP_MULTICAST_TTL");
goto END_ERR;
}
while(!NLM_Exiting)
{
sizeofClientAddr = sizeof(clientAddr);
if(( clientSocket = accept(NLM_ServerSocket, (struct sockaddr *)&clientAddr, &sizeofClientAddr)) == (-1)){
perror("accept");
goto END_ERR;
}
if(( recv(clientSocket, buff, sizeof(buff), 0)) == (-1)){
perror("recv");
goto END_ERR;
}
printf("recv: %s\r\n", buff);
if(( send(clientSocket, buff, strlen(buff), 0)) == (-1)){
perror("send");
goto END_ERR;
}
close(clientSocket);
}
printf("All turned out o.k.\r\n");
END_ERR:
//close(clientSocket);
close(NLM_ServerSocket);
}
© 2008 Novell, Inc. All Rights Reserved.