Broadcasting UDP packet to 255.255.255.255
Asked Answered
R

3

10

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.

Ronnaronnholm answered 4/11, 2013 at 15:47 Comment(7)
Do you adjust your settings in setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast) to not be a broadcast?Buoy
Can you print out errno, or at least do a perror("sendto") if the sendto() function fails, that'll provide some more hKarame
´DHCP´ is a very special case of broadcast, since the router acts as a relay agent and broadcasts the DHCP "message"again into other subnets. As explained here : en.wikipedia.org/wiki/Dhcp "DHCP clients and servers on the same subnet communicate via UDP broadcasts, initially. If the client and server are on different subnets, a DHCP Helper or DHCP Relay Agent may be used. Clients requesting renewal of an existing lease may communicate directly via UDP unicast, since the client already has an established IP address at that point."Gelsenkirchen
Thank you, I should have inspected errno in the original post. perror("sendto") prints out "Network is unreachable." That doesn't make sense to me -- I understand that the responsible thing for a router to do would be to drop the packet, but since there is no router, I would imagine anything on my switch to be able to receive the packet.Ronnaronnholm
@GPHoit is the switch connected to a router by any chance?Gelsenkirchen
@GPHoit on second thought, given you are using a simple common layer-2 switch, such a switch does not connect different subnets to each other. That is done by the network layer (layer 3), e.g. Router. So, what is happening in your case, the switch is receiving the broadcast message and forwarding it to all recipients in the same subnet (since it cannot connect multiple subnets), then it forwards the message to the router (you can say the router exists in multiple subnets, therefore it receives the message). However, the router drops the broadcast. As mentioned, earlier DHCP is a special case.Gelsenkirchen
@hhachem, but no .. there is NO ROUTER on my network :-) ... The problem is that my broadcast packets never get sent at all, i.e. sendto fails with "Network Unreachable." It seems to me that you cannot (at least in Linux) send a broadcast packet off your subnet in this configuration.Ronnaronnholm
C
6

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.

Climacteric answered 26/10, 2016 at 11:57 Comment(1)
I recently ran into this after an upgrade from Red Hat 6 to Red Hat 7. Turns out that the older linux's configured a default route in the route table. The newer ones do not auto-configure this route. The fix for me was to enter: #route add default <ethname>Ard
G
3

Broadcast by definition is limited to one subnet. It would be horrifying to see broadcast escape one's subnet and overflow the internet. If you are looking for a way to cross subnets, you should take a look at Multicast. Also check this. Good luck!

Gelsenkirchen answered 4/11, 2013 at 16:1 Comment(8)
The OP just sends to 255.255.255.255. but the sendto() fails. This should normally work. Also remember that you can broadcast to a different IP subnet, IF you both are on the same layer 2 broadcast domain (which you never should be, but the OP describes that he actually is).Karame
hmm. I'm a bit confused. He mentioned reaching a piece of hardware on a different subnet using broadcast. However, he continues by posting a code, which apparently does not do what it's supposed to when changing the IP address. Anyhow, the intended broadcast won't pass through the router unless he has a special router (cisco...), which he can configure to do so.Gelsenkirchen
@ nos: I believe that would be the case if the subnetmask is 255.255.0.0 (class B). But he is on a class C network. so broadcasting to 192.168.100.255 would reach 192.168.100.X but won't reach 192.168.200.10Gelsenkirchen
true, but he is using the broadcast address 255.255.255.255, which afaik, you should be able to do in linux - and he has no router. This means e.g. you take 1 dumb ethernet switch, you connect 1 PC to it which is on say 192.168.100.0/24 and 1 PC which is on 192.168.200.0/24. Those 2 PC's are now on the same ethernet broadcast domain, and should be able to see eachouters broadcast packets to 255.255.255.255. (They would even be able to see (atleast with e.g. wireshark) eachoters broadcast to 192.168.100.255 or 192.168.200.255, though they would normally be filtered out by the network card.)Karame
Thank you both for the comments. You are correct hhachem that I did not include any code to reset the hardware's network parameters, this is just a simple program that does effectively the same thing as far as the network side is concerned, there is no reference to the actual interface to that hardware here.Ronnaronnholm
@nos, I think you've understood my problem -- there is no router here, just a dumb switch. I could make it even simpler and just take the switch out and put a cable between my computer and the vendor's hardware. I understand hhachem that a router should responsibly drop broadcast packets, but I don't see why my computer itself would drop the packet. 255.255.255.255 being "unreachable" is puzzling since it's not an actual address that needs to be "reached" so to speak.Ronnaronnholm
@GPHoit Now I understand your issue. Well it could be that the device is configured to ignore icmp broadcasts. Does the device happen to be running Linux by any chance? If so, then Linux by default ignores icmp broadcast echos. However, you can change that by: "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts" as root. But that of course only works if the device is running Linux and you are able to access it.Gelsenkirchen
@hhachem I'm not sure if it's running Linux, but my guess is, probably not. I only have access to a very small interface over udp, part of which is this broadcast packet I need to send it. Again, it appears that the problem is on my computer, the packets never get sent. Thanks for the help!Ronnaronnholm
F
1

Please check your default gateway. If gateway's IP is in another subnet you would get error "Network is unreachable." after some time of broadcasting to 255.255.255.255 address, by the way sending directly to subnet broadcast (192.168.1.255 if your ip is 192.168.1.1 for example) will be work correctly even if gateway IP is in another subnet.

Fitts answered 18/4, 2016 at 11:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.