Dirk-Willem van Gulik
2024-04-28 19:33:45 UTC
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);
}
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);
}