/* * Send UDP multicast message * Send UDP broadcast message */ // #define SEND_BCASTS_TOO Yes #ifdef SEND_BCASTS_TOO /* broadcast address for our network */ /* unsigned int brAddr = 0x818197ff; - only our network */ unsigned int brAddr[] = { 0x818197ff, /* 129.129.151.255 */ 0x818196ff, /* 129.129.150.255 - same router as our subnet */ 0x81818aff, /* 129.129.138.255 - same router as our subnet */ }; int nrBrAddr = sizeof(brAddr) / sizeof(unsigned int); #endif #include #include #include #include #include #include #include #include #include #include #include #ifndef vaxc # ifndef HP_RT # ifndef __osf__ # ifndef linux # include # endif # endif # else # include # endif #else # include #endif /* #define TESTING Yes */ #ifdef TESTING #define PERROR(x) perror(x) #else #define PERROR(x) #endif #include "dgrambroadcast.h" int McastSocket; /* multicast socket */ struct sockaddr_in McastDestination; /* multicast destination address */ /*********************************************************************/ // -DDESTINATION_MCAST="\"226.129.151.57\"" // which is acs-gateway with first byte replaced to 226 static char DESTINATION_MCAST[128] = { 0 }; // place to hold x.y.z.w IPv4 address void initDestMcastAddr() { struct hostent *hp; if (memcmp(DESTINATION_MCAST, "226.", 4) == 0) { return; // already initialized } hp = gethostbyname(SERVER_HOST); if (hp == (struct hostent *) 0) { printf("%s: unknown host", SERVER_HOST); exit(99); } sprintf(DESTINATION_MCAST, "226.%d.%d.%d", hp->h_addr[1] & 0xFF, hp->h_addr[2] & 0xFF, hp->h_addr[3] & 0xFF); //printf("Got DESTINATION_MCAST = '%s'\n", DESTINATION_MCAST); } /*********************************************************************/ void closeBroadcastSocket(sendSocket) int sendSocket; { #ifdef TESTING printf("closeBroadcastSocket()\n"); #endif close(sendSocket); if (McastSocket >= 0) close(McastSocket); } /*********************************************************************/ int openBroadcastSocket() { //unsigned char ttl; int ttl; int sendSocket; int enableBroadcast; int status; initDestMcastAddr(); #ifdef TESTING printf("openBroadcastSocket()\n"); #endif sendSocket = socket(AF_INET, SOCK_DGRAM, 0); if (sendSocket < 0) { PERROR("socket"); return sendSocket; } enableBroadcast = 1; status = setsockopt(sendSocket, SOL_SOCKET, SO_BROADCAST, (char *) &enableBroadcast, sizeof(enableBroadcast)); if (status < 0) { PERROR("setsockopt"); return status; } /* open multicast socket */ McastSocket = socket(AF_INET, SOCK_DGRAM, 0); if (McastSocket < 0) { PERROR("McastSocket"); } //else { printf("Multicast socket opened\n");} ttl = 4; // with less then 2 it does not work if (setsockopt (McastSocket, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &ttl, sizeof(ttl)) < 0) { perror("setsockopt() failed setting IP_MULTICAST_TTL"); } //else {printf("Multicast socket configured\n");} McastDestination.sin_family = AF_INET; McastDestination.sin_port = htons(SEND_PORT); McastDestination.sin_addr.s_addr = inet_addr(DESTINATION_MCAST); return sendSocket; } /*********************************************************************/ int openReceiveSocket(port) unsigned short port; { struct sockaddr_in name; int recvSocket; initDestMcastAddr(); #ifdef TESTING printf("openReceiveSocket()\n"); #endif recvSocket = socket(AF_INET, SOCK_DGRAM, 0); if (recvSocket < 0) { PERROR("socket"); return recvSocket; } { int sopt = 1; if (setsockopt (recvSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &sopt, sizeof(int)) != 0) { perror("SO_REUSEADDR"); printf("not fatal, continuing\n"); } } /* Create name with wildcards. */ name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = htons(port); if (bind(recvSocket, (struct sockaddr *) &name, sizeof(name))) { PERROR("bind"); recvSocket = -1; return recvSocket; } #ifdef USE_MULTICAST { char group[100]; // group address string struct ip_mreq McastReq; // multicast group request printf ("Receive on port 0x%04X=%d, use multicast group=\"%s\" addr=INADDR_ANY\n", port & 0xFFFF, port, DESTINATION_MCAST); // Join the multicast group from we want to receive datagrams. // Initialize the multicast request structure and then pass // it as an option to setsockopt(). The imr_multiaddr element // is initialized to the desired multicast group. The // imr_interface element is initilized to IPADDR_ANY which // causes the multcast receives to come from the default // interface. // Set defaults and get group address and port number if // specified in command line. strcpy(group, DESTINATION_MCAST); McastReq.imr_multiaddr.s_addr = inet_addr(group); McastReq.imr_interface.s_addr = INADDR_ANY; if (setsockopt (recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &McastReq, sizeof(McastReq)) < 0) perror("setsockopt failed for IP_ADD_MEMBERSHIP"); } #endif return recvSocket; } /*********************************************************************/ void receiveJoinMCast(recvSocket) int recvSocket; { struct ip_mreq McastReq; // multicast group request char *group; initDestMcastAddr(); group = DESTINATION_MCAST; McastReq.imr_multiaddr.s_addr = inet_addr(group); McastReq.imr_interface.s_addr = INADDR_ANY; if (setsockopt (recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &McastReq, sizeof(McastReq)) < 0) perror("setsockopt failed for IP_ADD_MEMBERSHIP"); } /*********************************************************************/ int selectReceiveSocket(recvSocket, usec) int recvSocket; int usec; { struct timeval tv; int nfds, rm, wm, em; int status; #ifdef TESTING printf("selectReceiveSocket()\n"); #endif nfds = 32; rm = 1 << recvSocket; wm = 0; em = 0; tv.tv_sec = 0; tv.tv_usec = usec; #ifndef vaxc status = select(nfds, (fd_set *) & rm, (fd_set *) & wm, (fd_set *) & em, &tv); #else status = select(nfds, &rm, &wm, &em, &tv); #endif return status; /* 0 = nothing to read, 1 = ready for read, -1 = error */ } int readReceiveSocket(recvSocket, buff, len) int recvSocket; unsigned char *buff; int len; { int status; #ifdef TESTING printf("readReceiveSocket()\n"); #endif memset(buff, '\0', len); status = read(recvSocket, buff, len); if (status < 0) PERROR("read"); return status; } /*********************************************************************/ int sendBroadcastMessage(sendSocket, sendPort, sndMsg, sndMsgLen) int sendSocket; unsigned short sendPort; unsigned char *sndMsg; int sndMsgLen; { int status; #ifdef SEND_BCASTS_TOO int i; int flags; struct sockaddr_in sendName; #endif #ifdef TESTING printf("sendBroadcastMessage(s=%d, 0x%04X, msg, len=%d)\n", sendSocket, sendPort, sndMsgLen); #endif /* send multicast message */ status = sendto(McastSocket, (char *) sndMsg, sndMsgLen, 0, (struct sockaddr *) &McastDestination, sizeof(McastDestination)); return status; #ifdef SEND_BCASTS_TOO /* send to all broadcast addresses from the list */ for (i = 0; i < nrBrAddr; i++) { sendName.sin_family = AF_INET; sendName.sin_addr.s_addr = htonl(brAddr[i]); sendName.sin_port = htons(sendPort); flags = 0; status = sendto(sendSocket, (char *) sndMsg, sndMsgLen, flags, (struct sockaddr *) &sendName, sizeof(sendName)); if (status != sndMsgLen) { /*printf("sendBroadcastMessage(s=%d, 0x%04X, msg, len=%d - FAILED)\n", brAddr[i], sendPort, sndMsgLen);*/ PERROR("sendto"); } /*else{printf("sendBroadcastMessage(s=%d, 0x%04X, msg, len=%d - OK)\n", brAddr[i], sendPort, sndMsgLen);}*/ } #endif return status; }