Re: Multicast & Tunnel devices

From: Rodney W. Grimes <freebsd-rwg_at_gndrsh.dnsmgr.net>
Date: Mon, 29 Apr 2024 17:52:28 UTC
> 
> 
> > On 29 Apr 2024, at 03:09, Rodney W. Grimes <freebsd-rwg@gndrsh.dnsmgr.net> wrote:
> > 
> >> Would anyone know if there is something special with tunnel devices and multicast ? 
> >> 
> >> I?ve got some code that happily processes multicast packets on a normal interface; but appears not to do this on a tunnel interface. Tun0 shows multicast enabled:
> >> 	
> >> 	tun0: flags=8043<UP,BROADCAST,RUNNING,MULTICAST> metric 0 mtu 1500
> >> 
> >> Tcpdump on that interface gives the expected thing (here with mDNS):
> >> 
> >> 	tcpdump -n -i tun0 port 5353
> >> 	listening on tun0, link-type NULL (BSD loopback), capture size 262144 bytes
> >> 	19:26:03.976259 IP 10.31.0.6.5353 > 224.0.0.251.5353: 0 PTR (QM)? _raop._tcp.local. (34)
> >> 
> >> And code, with a simple IP_ADD_MEMBERSHIP  of the MC group on the IP of the local interface below works on a normal interface (e.g. igb0/10.0.0.1/24). 
> >> 
> >> 	./listener 10.0.0.1 224.0.0.251 5353
> > 
> > Is 10.0.0.1 the IP address of tun0, or is it the address of some other interface?
> > I suspect that the IP address of the tun0 interface is 10.31.0.6 from your tcpdump above.
> 
> That is correct 10.0.0.1/8. 10.31.0.6 is another machine at the other end of the tunnel broadcasting.
> 
> > IIRC you have to join multicast group on all interfaces you expect to receive mustcast packets on.
> > 
> >> 	Received packet, len=128
> >> 	etc
> >> 
> >> But yields no output if ran against above tun0 interface (while tcpdump on same is fine). Does that ring a bell with anyone ?
> >> 
> >> Dw
> >> 
> >> 
> >> int main(int argc, char *argv[])
> >> {
> >>    struct sockaddr_in addr;
> >>    struct ip_mreq mreq;
> >> 
> >> 	// skip error trapping command line arguments
> >> 
> >>    char* ip = argv[1]; 
> >>    char* group = argv[2]; 
> >>    int port = atoi(argv[3]); // 0 if error, which is an invalid port
> >> 
> >>    memset(&addr, 0, sizeof(addr));
> >>    addr.sin_family = AF_INET;
> >>    addr.sin_addr.s_addr = htonl(INADDR_ANY);
> >>    addr.sin_port = htons(port);
> >> 
> >>    mreq.imr_interface.s_addr = inet_addr(ip); 
> >>    mreq.imr_multiaddr.s_addr = inet_addr(group);
> >> 
> >> 	// skip error trapping on inet_addr
> >> 
> >>    int fd = socket(AF_INET, SOCK_DGRAM, 0);
> >> 	// skip error trapping socket
> >> 
> >>    if (bind(fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
> >> 	// skip error trapping
> >> 
> >>    if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq)) < 0 ){
> >> 	// skip error trapping argumetns
> >> 
> >>    while (1) {
> >> 	..
> >>        int nbytes = recvfrom(fd,msgbuf,MSGBUFSIZE,0,(struct sockaddr *) &addr,&addrlen);
> >>        if (nbytes < 0) {
> >>            perror("recvfrom");
> >>            return 1;
> >>        }
> >> 	printf(?Received packet, len=%d\n", nbytes);
> >>     }
> >> 
> 

-- 
Rod Grimes                                                 rgrimes@freebsd.org