Multicasting through all network interfaces by setting IP_MULTICAST_IF? - c

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.

Related

Sending multicast udp from multihomed computer

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.

Receiving Ethernet frames from an UDP port

I need to listen on multiple UDP ports and process received datagrams as Ethernet frames. I cannot think of any other solution than creating a SOCK_RAW socket to receive ethernet frames, check if what I received is an UDP datagram and then extract the datagram to identify the UDP port.
Is there a better way? Is there some kind of socket that would let me receive UDP datagrams on a specific port and still access the whole Ethernet frame?
I suggest you to use pcap library. It's not hard and it's portable between wide area of systems. You can simply filter and capture what you want.
libpcap and WinPcap provide the packet-capture and filtering engines
of many open source and commercial network tools, including protocol
analyzers (packet sniffers), network monitors, network intrusion
detection systems, traffic-generators and network-testers.
Another suggestions is libcrafter which is a high-level packet creator and decoder. Though it's C++ only.
Not sure if this is supported on your platform, but try:
int s=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL));
http://www.tldp.org/HOWTO/Ethernet-HOWTO-2.html

How do I send UDP packet from a specific interface on Linux?

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

Accessing data link layer packets

I want to create a socket for accessing IPv4 packets from data link layer. From unix network programming V1,
socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))
1)I am implementing a dhcp client, is this the correct way of doing that? (means without accessing data link layer, i cannot receive reply from dhcp server) or is there any other easier way?
also, since this socket will receive all IPv4 packets destined for my system, how should I distinguish dhcp reply packet from other packets?
2)please suggest me a good link/tuorial for network programming with data link layer access. In the above book, it is not detailed description.
This is my code
Did you tried looking at PCAP libraries?
It provides nice filtering functions on IP, port and other things.
Do you need the link layer headers too? If so, You need to use SOCK_RAW—SOCK_DGRAM will remove the link layer header before feeding it to your application.
You can identify DHCP requests by the source and destination ports, since DHCP generates traffic on UDP ports 67 and 68.

What are the use cases of SO_REUSEADDR?

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

Resources