Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - choose interface for UDP/multicast socket

I am trying to modify a multicast listener / sender example to bind the UDP / multicast socket to a specific interface and not using the INADDR_ANY macro.

I possess the IPv4 address of the interface. I tried the following, but the socket does not receive any UDP (unicast, broadcast, multicast) packets.

struct sockaddr_in addr;
int fd, nbytes;
socklen_t  addrlen;
struct ip_mreq mreq;

// my_ipv4Addr equals current IP as String, e.g. "89.89.89.89"

// create what looks like an ordinary UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket");
    exit(1);
}

// set up addresses
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
// [-]    addr.sin_addr.s_addr = htonl(INADDR_ANY); 
addr.sin_addr.s_addr = inet_addr(my_ipv4Addr); 
addr.sin_port = htons(port);

// bind socket
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
    perror("bind");
    exit(1);
}

// use setsockopt() to request that the kernel join a multicast group
mreq.imr_multiaddr.s_addr = inet_addr(group);
// [-]    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
mreq.imr_interface.s_addr = inet_addr(my_ipv4Addr);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))< 0) {
    perror("setsockopt");
    exit(1);
}

Edit:

Let me explain the purpose of my program. I am writing a little tool, which will check, if a network supports broadcast/multicast. Therefore I own a system with two interfaces and send via Interface1 a multicast Packet and try to receive it with Interface2. But: The packet shall go through the network, not the loopack device.

The idea is to block multicast-loopback on thread1/interface1 with:

u_char loop = 0;
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));

And to listen on thread2/interface 2 interface-specific. Tcpdump shows, that the packets are arriving, but are dropped with my config above.

like image 234
user22602 Avatar asked Oct 01 '12 21:10

user22602


People also ask

How do I enable UDP multicast?

To enable multicast traffic, you must first uncheck Block Multicast Packets in the Firewall > Attack Protection page, and then manually create firewall rules to allow multicast forwarding from a specific zone to other zones. The security appliance predefines a multicast address (IPv4_Multicast) for this purpose.

What is UDP multicast address?

The nodes in the network take care of replicating the packet to reach multiple receivers only when necessary. The most common transport layer protocol to use multicast addressing is User Datagram Protocol (UDP). By its nature, UDP is not reliable—messages may be lost or delivered out of order.

Does multicast use UDP?

Multicast uses IP delivery method – User Datagram Protocol (UDP) as the protocol. The multicast transport relies on multicast-enabled routers to forward the packets to a client subnet where multiple client devices are listening.


1 Answers

with
addr.sin_addr.s_addr=inet_addr(my_ipv4Addr);
bind(sockfd,(SA*)&addr,sizeof(addr));
you can only send out packets to the multicast group,
but you can't recv any packets, even those send out from `my_ipv4Addr'.

so addr.sin_addr.s_addr must be htonl(INADDR_ANY).

with
mreq.imr_interface.s_addr=inet_addr(my_ipv4Addr);
you can recv all packets from the multicast group,
but it send out packets with the default interface (maybe eth0),
not the one you specified (like eth1).
So this is no effect.

with
setsockopt(sockfd,SOL_SOCKET,SO_BINDTODEVICE,ETH1,strlen(ETH1));
you can send out packets through the interface ETH1,
but you can only recv packets send out from the ip associated with ETH1,
you can't recv any packets from other clients.

with
mreq.imr_interface.s_addr=inet_addr(my_ipv4Addr);
setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_IF,&mreq.imr_interface,sizeof(struct in_addr);
you can send out packets through the interface associated with my_ipv4addr,
also you can recv any packets from any clients in the multicast group.

like image 155
PLA Avatar answered Oct 06 '22 21:10

PLA