I need to send a multicast udp from multihomed computer. Found that in case socket is not bound to some specific interface, default interface will be used (whatever it could mean). My question: is it possible to specify something like inaddr_any to send multicast udp from all available interfaces or is it only possible to do that by enumerating all interfaces and manually send from each? Is there a standard for that?
Thank you
You can set which network interface IPv4 multicast packets leave from by setting the IP_MULTICAST_IF socket option. The value passed to setsockopt should be the address of a struct in_addr containing the IP address of the interface in question.
If you want to send a multicast packet on multiple interfaces, you'll need to call sendto multiple times, setting the IP_MULTICAST_IF option before each one.
Related
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
I need to multicast a packet through all the interfaces that have multicast capabilities in my machine. By setting IP_MULTICAST_IF with setsockopt() I can choose through which interface I'd like to multicast my packets. Unfortunately I can only choose one (can't I?). A possible solution would be to set IP_MULTICAST_IF, multicast the packet through that interface reset IP_MULTICAST_IF, send another packet and so on. Unfortunately, socket options cannot be modified while the socket is connected... what could be a possible solution to my problem?
The simplest solution is to have a socket per interface, but I would question your network setup where you "need to multicast a packet through all the interfaces" - that usually is a sign of bad design.
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.
How do I send UDP packet from a specific interface on Linux using C? Should I use bind? Is it possible to send UDP from the interface not having IP address?
Thanks.
Use bind. You cannot send UDP packets via an interface that does not have an IP address, because UDP uses the Internet Protocol and the Internet Protocol requires an IP address.
You can bind a socket to a specific interface by using the SO_BINDTODEVICE socket option, however this requires root privileges.
Alternately, you can set the IP_PKTINFO option, and use sendmsg for sending, setting the in_pktinfo's ipi_ifindex to the index of your interface.
You need to use socket option IP_MULTICAST_IF.
See here: Multicast-HOWTO-6.html
I have used SO_REUSEADDR to have my server which got terminated to restart without complaining that the socket is already in use. I was wondering: are there other uses of SO_REUSEADDR? Has anyone used the socket option for other than said purpose?
For TCP, the primary purpose is to restart a closed/killed process on the same address.
The flag is needed because the port goes into a TIME_WAIT state to ensure all data is transferred.
If two sockets are bound to the same interface and port, and they are members of the same multicast group, data will be delivered to both sockets.
I guess an alternative use would be a security attack to try to intercept data.
(Source)
For UDP, SO_REUSEADDR is used for multicast.
More than one process may bind to the same SOCK_DGRAM UDP port if the bind() is preceded by:
int one = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
In this case, every incoming multicast or broadcast UDP datagram destined to
the shared port is delivered to all sockets bound to the port.
(Source)
The other main use is to allow multiple sockets to bind() to the same port on UDP. You might not think that would come up, but sometimes multiple apps may want to listen on broadcast/multicast addresses with a given port number. It also allows one to bind to the wildcard address, while also binding to a specific address. For instance, Apache might bind to *:80 and 10.11.12.13:80