Hi. I'm developing a client-server application, targeted at RHEL4 and RHEL5. I'd
*like* for it to run on Fedora 8 as well, but there appears to be an incompatibility
-- some would say bug -- between the values sendto() accepts for the broadcast address
between the three operating systems. Basically, this is what I've got thusfar:
1. CentOS 4 (sorry, its what I've got) *requires* INADDR_BROADCAST
2. Fedora 8 *requires* INADDR_ANY
3. CentOS 5 (yeah, yeah, yeah, I know) can use either INADDR_BROADCAST or INADDR_ANY
I'd like to know if this INADDR_BROADCAST vs. INADDR_ANY is a known issue, a known
upgrade requirment, ignorance on my part :-), or an oversight somewhere probably not too
deep in Fedora 8's libc. Either way, I doubt I'm the only one who will stumble over it.
If its any help, the Fedora 8 ip man page alludes:
"There are several special addresses: INADDR_LOOPBACK (127.0.0.1) always
refers to the local host via the loopback device; INADDR_ANY (0.0.0.0)
means any address for binding; INADDR_BROADCAST (255.255.255.255) means
any host and has the same effect on bind as INADDR_ANY for historical
reasons."
Here's a fragment of my server-side code that sets up a broadcast socket to get info
on all running clients, each of which has its own response server that replies to this
request on a connected socket (client-side code not shown):
Code:
/// Reference: Stevens pg 288
bool PingAllClients(){
int sockfd;
sockaddr_in serv_addr;
memset(&serv_addr, '\0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
#ifdef FEDORA8
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Works on F8 and CentOS-5, but not CentOS-4
#else
serv_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); // works on CentOS-4 and 5, but not Fedora 8
#endif
serv_addr.sin_port = htons(CLIENT_PINGSERVER_UDP_PORT); // Common port number for all clients (40002)
// get a socket to send ping request to remote client ping servers
if( (sockfd=socket(PF_INET, SOCK_DGRAM, 0)) < 0){
perror("socket");
exit(1);
}
// tell the socket we want to broadcast on it
int bcast = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast)) < 0){
perror("setsockopt");
}
// tell the socket not to let the datagram live too long, since our clients'
// ping-echo servers might only peek at the datagram, not actually receive it
int TimeToLive = 1; // set larger only if you want packet to leave local network
if(setsockopt(sockfd, IPPROTO_IP, IP_TTL, &TimeToLive, sizeof(TimeToLive)) < 0){
perror("setsockopt IP_TTL");
}
TimeToLive = 1; // set larger only if you want packet to leave local network
if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &TimeToLive, sizeof(TimeToLive)) < 0){
perror("setsockopt IP_MULTICAST_TTL");
}
(place about 100 bytes of stuff in buffer, set buflen appropriately)
// broadcast ping request:
if(sendto(sockfd, buffer, buflen, 0, (sockaddr*)&serv_addr, sizeof(serv_addr)) != buflen){
perror("sendto");
}
(etc)
}
Thanks!