lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 23 Apr 2018 13:22:07 +0000
From:   "Klebsch, Mario" <Mario.Klebsch@...-actia.de>
To:     "netdev@...r.kernel.org" <netdev@...r.kernel.org>
Subject: IP_ADD_MEMBERSHIP with imr_ifindex!=0 for multiple processes with
 different interfaces

Hi, 

I have a problem with multicast reception in the linux kernel and I hope, this is the right place to ask for help or to report a bug.

I need to receive multicasts on a single interface. I have written a small program, which executes IP_ADD_MEMBERSHIP with imr.imr_ifindex set to the interface index. The program works well, as long as only a single instance of this program is running. If I start a second instance on a different network interface, both programs receive multicast frames from both interfaces. 

When called without argument, the test program list the network interfaces. When called with an interface name as argument, if starts receiving multicasts on that interface.

I am running vanilla Linux kernel 4.12.0.

# uname -a
Linux c627 4.12.0 #1 SMP Mon Apr 23 14:08:24 CEST 2018 i686 Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz GenuineIntel GNU/Linux
# 

P.S. The program runs fine on MacOSX.

73, Mario

----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<----
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <net/if.h>

#define MCAST_PORT  6154
#define MCAST_ADDR  "239.255.1.1"

void ListInterfaces(struct ifaddrs *Interfaces)
{
                for (struct ifaddrs *a=Interfaces; a; a=a->ifa_next)
                {
                               if (!(a->ifa_flags & IFF_UP))
                                               continue;
                               if (!a->ifa_addr || a->ifa_addr->sa_family != AF_INET)
                                               continue;
                               struct sockaddr_in *Addr = (struct sockaddr_in *)a->ifa_addr;
                               printf("%s: %s\n", a->ifa_name, inet_ntoa(Addr->sin_addr));
                }
}

int main(int argc, char *argv[])
{
                struct ifaddrs *Interfaces;
                if (getifaddrs(&Interfaces) < 0)
                {
                               perror("getifaddrs");
                               return -1;
                }

                struct sockaddr_in *MyIfAddr=NULL;
                int                MyIfIndex=0;
                if (argc > 1 && (MyIfIndex = if_nametoindex(argv[1])) )
                               for (struct ifaddrs *a=Interfaces; a; a=a->ifa_next)
                               {
                                               if (!(a->ifa_flags & IFF_UP))
                                                               continue;
                                               if (!a->ifa_addr || a->ifa_addr->sa_family != AF_INET)
                                                               continue;
                                               if (strcmp(argv[1], a->ifa_name)!= 0)
                                                               continue;
                                               MyIfAddr = (struct sockaddr_in *)a->ifa_addr;
                                               break;
                               }

                if (!MyIfAddr || !MyIfIndex)
                {
                               ListInterfaces(Interfaces);
                               return 0;
                }

                int s=socket(PF_INET, SOCK_DGRAM, 0);
                if (s<0)
                {
                               perror("socket");
                               return -1;
                }

                int off=0;
                if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &off, sizeof(off)) < 0)
                               perror("setsockopt(SO_REUSEADDR)");

                int on=1;
                if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
                               perror("setsockopt(SO_REUSEADDR)");

                struct sockaddr_in Addr;
                Addr.sin_family = AF_INET;
                Addr.sin_port = htons(MCAST_PORT);
                inet_aton(MCAST_ADDR, &Addr.sin_addr);
                if (bind(s, (struct sockaddr*)&Addr, sizeof(Addr)) < 0)
                               perror("bind");

                struct ip_mreqn imr;
                inet_aton(MCAST_ADDR, &imr.imr_multiaddr);
                imr.imr_address = MyIfAddr->sin_addr;
                imr.imr_ifindex = MyIfIndex;
                if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr)) < 0)
                               perror("setsockopt(IP_ADD_MEMBERSHIP)");

                for (;;)
                {              
                               struct sockaddr_in AddrBuffer;
                               int AddrLen = sizeof(AddrBuffer);
                               char Buffer[2048];
                               size_t BufferLen = recvfrom(s, &Buffer, sizeof(Buffer), 0, (struct sockaddr*)&AddrBuffer, & AddrLen);
                               if (BufferLen <= 0)
                               {
                                               if (BufferLen < 0)
                                                               perror("recvfrom");
                                               break;
                               }
                               printf("%s: Received %d bytes from %s\n", argv[1], BufferLen, inet_ntoa(AddrBuffer.sin_addr));
                }
}
----8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<----

-- 
Mario Klebsch				Actia I+ME GmbH
Mario.klebsch@...-actia.de		Dresdenstrasse 17/18
Fon: +49 531 38 701 716			38124 Braunschweig
Fax: +49 531 38 701 88			Germany


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ