How to broadcast a message in a network? - c

I'm working on a client-server application written in C. I want to broadcast a message to all the machines available on the local network.
How can I do that using the usual socket system calls in C?

Just send the message to the broadcast address of your subnet, which for 192.168.0.0/24 is 192.168.0.255, or just broadcast to 255.255.255.255.

you have to use UDP to send a broadcast message over a network. when creating your socket using the socket() function, specify AF_INET for the family parameter and SOCK_DGRAM for the type parameter. on some systems, you have to enable the sending of broadcast packet by setting the SO_BROADCAST socket option to 1, using setsockopt().
then use the sendto() function call to send a datagram, and use 255.255.255.255 as the destination address. (for datagram sockets, you don't need to call connect(), since there is no 'connection').
in standard implementations, this address broadcasts to all computer in the local network, this means that the packet will not cross gateway boundaries and will not be received by computers using a network mask diferent from the network mask of the sending computer.

Have a look at UDP sockets.
I recomend Beej's Guide to Network Programming. Have a look at 6.3 Datagram Sockets

You can use the special address of 255.255.255.255 to send a broadcast message to every computer on the local network.
For more info see section IP Network Broadcasting.

Related

How to duplicate UDP packets to two or more sockets

I'm attempting to have two daemons running on the same port and IP but one is a server and the other is a client. Is there a method using socket options that would allow each socket to have a copy of the packet and let the daemons filter out the messages based on the protocol? It looks like reuse address blocks the first configured port and reuse port might just balance the packet between the two daemons.
Otherwise, I guess create another daemons to read the socket and send the packets to the correct daemon.
Thanks
You are correct at the end, you will need to have a third part that binds to the port and forwards the packets to the correct daemon.
The other way to do it would be to use three ports and use a firewall to redirect from the front end port to the backend ports; but that is a lot more complicated and not portable. But in the end you could use QOS or something. There is a wide range of possible types of use case behind the word protocol.
If the UDP packets you are receiving are multicast or broadcast packets, then you can set SO_REUSEADDR (and, for BSD-based OS's, SO_REUSEPORT) on the socket (using setsockopt()) before bind()-ing the socket, and then both sockets will receive a copy of each incoming UDP packet. (If the UDP packets are regular old unicast packets, OTOH, then doing the above will result in each received packet being received by only one of the two UDP sockets, which isn't what you want).
Note, however: You refer to the two daemons as being a "client" and a "server" -- the implication of those terms is that the two daemons are going to communicate with each other. If that is the case, then the typical approach would be to have the server-daemon bind to a well-known port number, and the client-daemon could bind to any port number (e.g. it could pass 0 as the port-number to bind(), and let the OS choose an available port-number for it). Then the client-daemon could start the conversation by sending one or more UDP packets to the server's well-known port number, and the server can find out which port the client is sending from (and therefore what port to send reply packets to) by examining the fifth argument of its recvfrom() call. In this case there is no need for the two programs to bind to the same port, and therefore no need for packet-forwarding.

Check incoming interface on TCP socket

In network programming (C & Linux) with a TCP socket, how can I check the interface that received the packet. I know this can be done very easily with a SOCK_DGRAM and the IP option IP_PKTINFO, but this option does not work on SOCK_STREAM. In this case (for what im programming) I must know the interface that received the packet (the respond that gives back the server depends on that).
One possible solution that I found is to use SOCK_RAW and IPPROTO_TCP (with SOCK_RAW I can set the IP_PKTINFO option) but that implies that i'll be receiving all the TCP traffic that arrives to the machine and i don't want that. Another possible solution that I'm thinking is to check the destination IP against the routing table and get the exit interface from there but what about IPv6? What if the destiny IP its IPv6 link-local?
If anyone has another solution or idea I'll be glad to read it. Thanks in advance
When your TCP server accepted a client connection, you will have a socket to represent the connection, you could call getsockname on the socket, it will give you the address associated on the socket, namely the ip addresses on your side.
Next step, you can call getifaddrs to get all the interfaces and their information on your system, including name(like eth0) and ip address. At this point, you can search this list with the ip obtained previously via getsockname, you can get the interface you want as a result.
reference:
http://linux.die.net/man/2/getsockname
http://linux.die.net/man/3/getifaddrs

raw socket listener

This is a quick question for linux c programming raw sockets. If I wanted to just listen to any interface with a raw socket, must I actually bind to an ip address or interface to listen to traffic? From what I understand, I feel like I should be able to just call sock(); and then start recvfrom() traffic. Maybe I'm wrong, but I've seen some programs that don't use it.
You are right, the only thing you will need to do is call socket() and then recvfrom(). Nevertheless be aware of the fact that there are some limitations with listening using SOCK_RAW.
If you're not using raw sockets on a "send-and-forget" basis, you will
be interested in reading the reply packet(s) for your raw packet(s).
The decision logic for whether a packet will be delivered to a raw
socket can be enumarated as such:
TCP and UDP packets are never delivered to raw sockets, they are always handled by the kernel protocol stack.
Copies of ICMP packets are delivered to a matching raw socket. For some of the ICMP types (ICMP echo request, ICMP timestamp request,
mask request) the kernel, at the same time, may wish to do some
processing and generate replies.
All IGMP packets are delivered to raw sockets: e.g. OSPF packets.
All other packets destined for protocols that are not processed by a kernel subsystem are delivered to raw sockets.
The fact that you're dealing with a protocol for which reply packets
are delivered to your raw socket does not necessarily mean that you'll
get the reply packet. For this you may also need to consider:
setting the protocol accordingly while creating your socket via socket(2)system call. For instance, if you're sending an ICMP
echo-request packet, and want to receive ICMP echo-reply, you can set
the protocol argument (3rd argument) to IPPROTO_ICMP).
setting the protocol argument in socket(2) to 0, so any protocol number in the received packet header will match.
defining a local address for your socket (via e.g. bind(2)), so if the destination address matches the socket's local address, it'll be
delivered to your application also.
For more details you can read e.g. this.
If you meant to capture the traffic on a interface, you can use libpcap.

bind()-ing UDP sockets to different addresses

I have a very simple question that I cannot seem to find an answer for anywhere:
Using Linux C sockets, is it possible to bind() and then recvfrom() UDP packets on an IP address other than the local address?
i.e, if a host has been given the LAN address 10.0.0.4, and I want it to be able to receive UDP packets sent to the address 10.0.0.5 on port 5505 (for example) how would this be achieved?
I simply cannot find any examples of this use of bind/recvfrom, which seems like it should be quite commonplace.
Update
I am trying to communicate packet streams between multiple hosts. Each host streams UDP packets on its own address, and any of the other hosts can listen in by recvfrom()ing on a specific address.
No, you can't generally bind to a non-local unicast address. On an Ethernet, such packets would be addressed to the hardware address of the owner of that IP address, and by default you NIC won't even forward such packets to your kernel.
You can achieve the effect you want by using IP Multicast. You would pick a particular multicast address for your application and bind to that, and then use the IP_ADD_MEMBERSHIP socket option to join the multicast group. You can then use recvfrom() in the usual way.

Finding IP address and port number using socket api?

I am working on a code where I have need to find the sender's IP address,sender's port no and application layer packet sent by it.
I did it using Raw Sockets (SOCK_RAW), it runs fine and did the job for me but its too much clumsy.
Question: I can use SOCK_STREAM and get the application layer packet directly and that's really clean and simple method than using Raw socket but this way I won't be able to find the IP address and port number of the client. Is there any function to which I pass the socket descriptor and it tells me the IP address and port number of the other end. I read a few man pages but I could not find any.
I am using linux socket api in C language.
Thanks in advance. :)
When you call accept() to accept an incoming connection, *address is a structure that is filled in with the sender's IP address and port number.
the BSD socket implementation defines a function named getpeername() which allows to know the ip address and the port of the remote side of a tcp socket.
when you have any SOCK_STREAM connected socket, no matter which side first established the connection, you can call this function to get the informations you need. (this is far easier than a raw socket).

Resources