Discussion:
Multicast & Tunnel devices
(too old to reply)
Dirk-Willem van Gulik
2024-04-28 19:33:45 UTC
Permalink
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
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);
}
Rodney W. Grimes
2024-04-29 01:09:17 UTC
Permalink
Post by Dirk-Willem van Gulik
Would anyone know if there is something special with tunnel devices and multicast ?
tun0: flags=8043<UP,BROADCAST,RUNNING,MULTICAST> metric 0 mtu 1500
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.

IIRC you have to join multicast group on all interfaces you expect to receive mustcast packets on.
Post by Dirk-Willem van Gulik
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 ***@freebsd.org


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Dirk-Willem van Gulik
2024-04-29 14:36:20 UTC
Permalink
Post by Rodney W. Grimes
Post by Dirk-Willem van Gulik
Would anyone know if there is something special with tunnel devices and multicast ?
tun0: flags=8043<UP,BROADCAST,RUNNING,MULTICAST> metric 0 mtu 1500
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.
Post by Rodney W. Grimes
IIRC you have to join multicast group on all interfaces you expect to receive mustcast packets on.
Post by Dirk-Willem van Gulik
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);
}
Rodney W. Grimes
2024-04-29 17:52:28 UTC
Permalink
Post by Dirk-Willem van Gulik
Post by Rodney W. Grimes
Post by Dirk-Willem van Gulik
Would anyone know if there is something special with tunnel devices and multicast ?
tun0: flags=8043<UP,BROADCAST,RUNNING,MULTICAST> metric 0 mtu 1500
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.
Post by Rodney W. Grimes
IIRC you have to join multicast group on all interfaces you expect to receive mustcast packets on.
Post by Dirk-Willem van Gulik
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 ***@freebsd.org


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Dirk-Willem van Gulik
2024-04-29 19:03:06 UTC
Permalink
Post by Dirk-Willem van Gulik
Post by Rodney W. Grimes
Post by Dirk-Willem van Gulik
Would anyone know if there is something special with tunnel devices and multicast ?
tun0: flags=8043<UP,BROADCAST,RUNNING,MULTICAST> metric 0 mtu 1500
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.
Thanks for your reply - it did make play with the several /30’s aliases I was running in parallel on tun0.

And found by accident that if I remove them - things spring to life. Which is actually possible - as I can split the tun0 up into 8 separate /24’s tunnels; one for each connection pair. With that - IP_ADD_MEMBERSHIP does exactly what it says on the tin.

Dw



--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...