first time poster, hopefully this is an easy one:
I need to send a broadcast packet to a piece of hardware which, when it powers up, is on a different subnet than my machine, in order to tell it to reset its IP address to one that's on my network. But, I can't seem to broadcast off my own subnet unless I'm using DHCP, which ultimately I won't be able to do. There is no router on the network, just a simple switch between my machine and the box I'm trying to talk to, plus a couple other Linux machines on the network.
So basically this example code WORKS on Fedora 19 in a test environment (on a larger network where I have DHCP enabled), until I try to statically set my IP address:
int main(int argc, char *argv[])
{
int sock;
if( (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
perror("socket : ");
return -1;
}
int broadcast = 1;
if( setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) != 0 )
{
perror("setsockopt : ");
close(sock);
return -1;
}
char *ip = "255.255.255.255";
char * msg = "Hello World!";
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons( 4444 );
inet_aton( ip, &si.sin_addr.s_addr );
/* send data */
size_t nBytes = sendto(sock, msg, strlen(msg), 0,
(struct sockaddr*) &si, sizeof(si));
printf("Sent msg: %s, %d bytes with socket %d to %s\n", msg, nBytes, sock, ip);
return 0;
}
If I'm using DHCP, the output is:
Sent msg: Hello World!, 12 bytes with socket 3 to 255.255.255.255
And I can see the packet go out in Wireshark.
Then if I set my IP statically to say, 192.168.100.1, I get:
Sent msg: Hello World!, -1 bytes with socket 3 to 255.255.255.255
And I don't see the packet in Wireshark. And I can confirm that the number of TX packets shown in ifconfig doesn't increment. I tried disabling the firewall:
sudo iptables -F
but that didn't do anything. Anybody see something that I'm missing? I can broadcast to 192.168.100.255, but that won't make it to the box I need to talk to, which for example might be at 192.168.200.10, 255.255.255.0 by default. I could make it work by changing the network parameters of everything else on the network, but that's not really an option.
EDIT: In regards to some of the comments and answers, note that I'm not using a router and can replicate the behaviour with nothing but a wire between my computer and the other box. So, really the question is, why isn't Linux sending the packets? I don't know obviously, but I'm suspecting that Linux itself drops cross-subnet broadcast packets unless it can delegate that decision to another authority on the network. In any event, given that my network is so small I'll just have to work around it.
I just ran into this issue. Everything worked fine until I removed the gateway and then I get a network unreachable error when trying to send from the socket.
Since I am using the broadcast messages to configure the network settings of my box it is not an alternative for me to configure the gateway address to get it working. However since my box only has a single network interface I found the following solution:
// Bind to the proper interface to be able to send without default gateway
char netif[] = "eth0";
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, netif, sizeof(netif));
With this I am able to send to the broadcast 255.255.255.255 address on the socket regardless of any default gateway. This solution should work with multiple network interfaces as long as you know what interface you want to use.