Git Product home page Git Product logo

multicast-relay's People

Contributors

alsmith avatar dchesterton avatar joshuaspence avatar vvd170501 avatar yo8192 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

multicast-relay's Issues

One to one communication

Hi @alsmith
Nice work. However, I was wondering if there is any option to make it work in a way that only one client from one VLAN can see mDNS traffic only from one device from second VLAN?
What I've manage to do right now is that any client from one VLAN can see only one of many device from second VLAN (Chromecast). So, I was wondering if there is option to limit this even more, so we can define that only one device (IP or MAC address) can see exacly one device from second network?
Feel free to contact me on [email protected] also.

Multicast packets not being picked up at destination

I have multicast-relay running on my openwrt router at home. The output from it shows that SSDP packets are being forwarded by the mutlicast-relay and routed, but if I watch tcpdump on any of my endpoints, almost all of them are dropped. Maybe every few hours one of them will get through.

Let me know if you need anything to further look at this issue.

Alias

Error using alias

multicast-relay.py --wait --interfaces eth1 eth1:1

File "/webspot/webcast/multicast-relay.py", line 872, in
sys.exit(main())
File "/webspot/webcast/multicast-relay.py", line 867, in main
packetRelay.addListener(addr, port, relay[1])
File "/webspot/webcast/multicast-relay.py", line 273, in addListener
rx.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, packedAddress)
File "/usr/lib64/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use

LIFX Discovery fails.

First of all thank you for your awesome work!

Im trying to setup LIFX discovery on my UDM between my private an iot Lan but they just won't show up by auto discovery.

Setup: UDM with UDM Utilities by https://github.com/boostchicken/udm-utilities
This Multicast Relay Dockerized by: https://github.com/scyto/multicast-relay

Added Broadcast Address:

Broadcast Address: 255.255.255.255
Port:56700

My testing starting command:

podman run --rm -it --network=host -e OPTS="--relay 255.255.255.255:56700 --verbose" -e INTERFACES="br0 br30" scyto/multicast-relay

Am I doing something wrong?

Incorrect source address/port in logs (SSDP)

If multicast-relay is used with the --ssdpUnicastAddr option, all relayed SSDP multicast packets are logged with ssdpUnicastAddr:SSDP_UNICAST_PORT as source instead of the original address and port.

Steps to reproduce: run multicast-relay.py --verbose --foreground --interfaces $IFACE1 $IFACE2 --ssdpUnicastAddr $IFACE1_ADDR, send SSDP multicast packets from another machine connected to the same network

Expected behaviour: original source address is logged

Actual behaviour: $IFACE1_ADDR is logged instead of original address

Relevant part of code:

self.logger.info('%s%s %s byte%s from %s:%s on %s [ttl %s] to %s:%s via %s/%s' % (tx['service'] and '[%s] ' % tx['service'] or '',
tx['interface'] in self.masquerade and 'Masqueraded' or 'Relayed',
len(data),
len(data) != 1 and 's' or '',
srcAddr,
srcPort,

Log example (with options --interfaces eth0 eth1 --ssdpUnicastAddr 192.168.0.123)

...
INFO: Last SSDP search source: 10.0.0.11:43028
INFO: [SSDP] Relayed 125 bytes from 192.168.0.123:1901 on eth1 [ttl 1] to 239.255.255.250:1900 via eth0/192.168.0.123
...
INFO: Last SSDP search source: 192.168.1.100:1900
INFO: [SSDP] Relayed 409 bytes from 192.168.0.123:1901 on eth0 [ttl 4] to 239.255.255.250:1900 via eth1/10.0.0.123

Log example (678bafb, same options)

Last SSDP search source: 10.0.0.11:40074
INFO: [SSDP] Relayed 125 bytes from 10.0.0.11(192.168.0.123):1901 on eth1 [ttl 1] to 239.255.255.250:1900 via eth0/192.168.0.123

Possible solutions:

  • Log origSrcAddr and origSrcPort instead of srcAddr / srcPort
  • Log both origSrcAddr / origSrcPort and srcAddr / srcPort (see second log example)

Python3 compatibility issues

Hello Al,

Thanks for your python script to route traffic on multicast between
interface for Sonos!
I'm running zeroshell at home (UTM enabling loadbalacing, routing etc...)
but Sonos request are not forwarded from one lan to another one. I have my
speakers located in a "trusted" lan and I would like my controllers beeing
in a guest wifi lan.
therefore, I'm trying to set up your python script on zeroshell.
Unfortunatelly, that's not working :(
I have the following error:
root@zeroshell multicast-relay> ./multicast-relay.py --interfaces ETH00.212
ETH00.6 --verbose
File "./multicast-relay.py", line 103
print 'Error getting information about interface %s' % ifname
^
SyntaxError: Missing parentheses in call to 'print'
root@zeroshell multicast-relay>

Is there a problem with zeroshell? sorry I've no python knowledge at
all.... :(
I opened a thread here as well:
http://www.zeroshell.org/forum/viewtopic.php?t=8261

'relay' option doesn't capture UPD packets

I have an app sending multicast packets on 239.255.90.90. I can see the packets with tcpdump, but multicast-relay does not capture any packets...

python3 multicast-relay.py --interfaces eth0 --remote REMOTE_IP --foreground --verbose --remotePort 1990 --noSonosDiscovery --noSSDP --noMDNS --relay 239.255.90.90:APP_PORT

if I try the homebrewNetifaces instead, I get the following error:

Nov-25 22:30:52 multicast-relay.py INFO: Adding multicast relay for 239.255.90.90:APP_PORT
Traceback (most recent call last):
  File "multicast-relay.py", line 1014, in <module>
    sys.exit(main())
  File "multicast-relay.py", line 1009, in main
    packetRelay.addListener(addr, port, relay[1])
  File "multicast-relay.py", line 287, in addListener
    (ifname, mac, ip, netmask, broadcast) = self.getInterface(interface)
  File "multicast-relay.py", line 723, in getInterface
    if interface in self.nif.interfaces():
  File "multicast-relay.py", line 104, in interfaces
    ip        = socket.inet_ntoa(fcntl.ioctl(socket.socket(socket.AF_INET, socket.SOCK_DGRAM), 0x8915, struct.pack('256s', str(name)))[20:24]) # SIOCGIFADDR
struct.error: argument for 's' must be a bytes object

ssdpDiscover errors under python3

Noticed that the help ssdpDiscover.py script doesn't seem to run correctly under python3. The changes below seemed to get it to work correctly.
Thanks,

diff --git a/ssdpDiscover.py b/ssdpDiscover.py
index 4327c24..8d0ac57 100755
--- a/ssdpDiscover.py
+++ b/ssdpDiscover.py
@@ -25,16 +25,16 @@ def main():
         s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(args.ifAddr))
 
     s.settimeout(2)
-    s.sendto(msearch, ('239.255.255.250', 1900))
+    s.sendto(msearch.encode('utf-8'), ('239.255.255.250', 1900))
 
     try:
         while True:
             data, addr = s.recvfrom(65535)
             try:
-                print '%s [%s]' % (socket.gethostbyaddr(addr[0])[0], addr[0])
+                print ('%s [%s]' % (socket.gethostbyaddr(addr[0])[0], addr[0]))
             except socket.herror:
-                print addr[0]
-            print data
+                print (addr[0])
+            print (data)

Help for anyone moving to UDM Pro v2.4.23

Not an issue, but help for anyone moving over to the podman-less version of the UDM OS. You can easily get this up and running without containers as Python v3.5.3 is already installed by default.

Once you've downloaded multicast-relay.py to your UDM Pro, run as follows:

/usr/bin/python3 /data/multicast-relay/multicast-relay.py --interfaces brX brY brZ --noMDNS

where brX, brY etc are the interfaces you want to multicast. Obviously you can also pass parameters such as --noMDNS etc as you see fit.

I have also setup on_boot.d by using a slightly modified version from here: https://di-marco.net/blog/it/2022-01-22-unchain_the_udm_pro_se/. Modified in that I edited the script to point to "/data" instead of the old "/mnt/data" which doesn't exist anymore.

Alternatively, you can also follow the instructions to install podman (being mindful of using /data and not /mnt/data) but it'd be a complete pain to re-setup every time there was an UDM upgrade so I wanted to move away from that.

Connection not established

[via https://en.community.sonos.com/setting-up-sonos-228990/setting-up-sonos-on-different-subnets-or-vlans-6796745/index1.html#post16187975]

matthiserote
I am trying to use your code. I have set up a VM with an interface listening on each VLAN. I see packeta being relayed between the subnets but I cannot get the controller app on one subnet to reach the Sonos speakers on the other.

Use with wireguard interface? TypeError: ord() expected string of length 1

I'm trying to bridge / reflect / repeat SSDP traffic from a Wireguard connection to my home network. To check, is this something that should be possible?

I've tried running it and get the output error below. (I needed to add the allowNonEther option as otherwise it reported that it couldn't find out the MAC address for wg0).

(For reference I'm running it in Docker following https://github.com/scyto/multicast-relay)

Thanks,

starting multicast-relay

Using Interfaces: eth0 wg0
Using Options --foreground  --verbose --allowNonEther
Jun-05 09:20:25 /etc/app/multicast-relay/multicast-relay.py INFO: Adding broadcast relay for 255.255.255.255:6969 (Sonos Discovery)
Jun-05 09:20:25 /etc/app/multicast-relay/multicast-relay.py INFO: Adding multicast relay for 239.255.255.250:1900 (SSDP)
Jun-05 09:20:25 /etc/app/multicast-relay/multicast-relay.py INFO: Adding multicast relay for 224.0.0.251:5353 (mDNS)
Jun-05 09:21:13 /etc/app/multicast-relay/multicast-relay.py INFO: [SSDP] Relayed 356 bytes from 192.168.1.254:1900 on eth0 [ttl 4] to 239.255.255.250:1900 via wg0/10.6.0.1
Traceback (most recent call last):
  File "/etc/app/multicast-relay/multicast-relay.py", line 869, in <module>
    sys.exit(main())
  File "/etc/app/multicast-relay/multicast-relay.py", line 866, in main
    packetRelay.loop()
  File "/etc/app/multicast-relay/multicast-relay.py", line 595, in loop
    self.transmitPacket(tx['socket'], tx['mac'], destMac, ipHeaderLength, data)
  File "/etc/app/multicast-relay/multicast-relay.py", line 370, in transmitPacket
    dontFragment = (ord(ipPacket[6]) & 0x40) >> 6
TypeError: ord() expected string of length 1, but int found

Issues with mDNS and Airplay devices

Hi,

I'm currently trying to get some Airplay devices running over multiple subnets and Roon, but it doesn't work as expected.
I use on one side:
multicast-relay.py --interfaces eth0 --noSSDP --noSonosDiscovery --foreground --remote 192.168.1.1 --verbose

and on the other side:
multicast-relay.py --interfaces br0 --noSSDP --noSonosDiscovery --foreground --listen 192.168.2.1 --verbose

The devices are successfully discovered but they won't play any music. It doesn't start to play at all. Some Airplay devices want a code to authenticate it as playback device, but this code doesn't show up as normally on the same subnet.
Is there any additional relay I have to consider for Airplay/authentication/streaming?

Include relay of NOTIFY in addition to M-SEARCH?

if origDestinationAddress == PacketRelay.SSDP_MCAST_ADDR \

            if origDestinationAddress == PacketRelay.SSDP_MCAST_ADDR \
                    and origDestinationPort == PacketRelay.SSDP_MCAST_PORT:
                if  re.search(r'NOTIFY', data) or re.search(r'M-SEARCH', data):

This potentially decreases discovery time as a devices advertises itself and doesn't just respond to a search?

easy-install-3.5 TLS 1.2 error

Hi there,
I would love to enhance my zeroshell installation with the multicast-relay to get my Sonos controllers and speakers connected again. But when following the installation i struggle with

Searching for netifaces
Reading https://pypi.python.org/simple/netifaces/
Download error on https://pypi.python.org/simple/netifaces/: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:645) -- Some packages may not be found!
Couldn't find index page for 'netifaces' (maybe misspelled?)
Scanning index of all packages (this may take a while)
Reading https://pypi.python.org/simple/
Download error on https://pypi.python.org/simple/: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:645) -- Some packages may not be found!
No local packages or download links found for netifaces
error: Could not find suitable distribution for Requirement.parse('netifaces')

I know, that pypi.python.org has banned TLS 1.1 connection. I've checked the openssl version installed would support TLS 1.2 (OpenSSL 1.0.2o 27 Mar 2018), but I've no clue who to convince easy-install to use TLS 1.2.
Is there a way to either update easy-install or to configure it to use TLS 1.2?
Best regards
Jan

Any Chance to add Wake On Lan?

I did try adding "--relay 255.255.255.255:9 255.255.255.255:7" but it didnt work.
It would be great to add WOL into the script

log to file

is it possible to log the output to a file instead of the display like just out of interest

noTransmitInterfaces, ifFilter… Confusion

I have multi-cast relay up and running on a UniFi UDMP, thanks to boost chicken’s excellent on-boot-script. However, I've been unable to get it to do what I want, likely due to a lack of expertise.

I have a main LAN which hosts shared services, and multiple VLANs I would like to access it. The VLANs however, should not broadcast to other VLANs. In sum, VLAN clients should see only broadcasts from the LAN, and not those from other VLANs. I've tried dozens of configurations using noTransmitInterfaces and ifFilter, to no avail.

Thanks for any tips you care to provide.

Python Errors

Hello,

I am struggling to get this running having tried both Ubuntu 14.04 and 16.10. I have installed netifaces but am unsure as to what the error is:

multicast@multicast-manage:/multicast-relay$ python -V
Python 2.7.6
multicast@multicast-manage:
/multicast-relay$ pip install netifaces
Requirement already satisfied (use --upgrade to upgrade): netifaces in /usr/lib/python2.7/dist-packages
Cleaning up...
multicast@multicast-manage:~/multicast-relay$

multicast@multicast-manage:~/multicast-relay$ sudo ./multicast-relay.py --interfaces eth1 eth3 --foreground
^CTraceback (most recent call last):
File "./multicast-relay.py", line 447, in
sys.exit(main())
File "./multicast-relay.py", line 444, in main
packetRelay.loop()
File "./multicast-relay.py", line 168, in loop
(inputready, _, _) = select.select(self.receivers, [], [])
KeyboardInterrupt

Cannot relay packets with a TTL of 1

Thanks for this script. I'm trying to get it working with the Samsung TV remote app on my iPhone which is on a separate VLAN and subnet to the TV. Unfortunately, the multicast packets have a TTL of 1 and therefore they're dropped as soon as they're relayed and reach the router.

Would it be possible to have an option to increase the TTL so that packets can hop across subnets?

Devices not discoverable

Hi,

in my log I can find the following entries

starting multicast-relay
Using Interfaces: br0 br30 br40
Using Options --foreground  --verbose --noSSDP
Feb-28 12:05:35 //./multicast-relay/multicast-relay.py INFO: Adding broadcast relay for 255.255.255.255:6969 (Sonos Setup Discovery)
Feb-28 12:05:35 //./multicast-relay/multicast-relay.py INFO: Adding multicast relay for 224.0.0.251:5353 (mDNS)
Feb-28 12:12:20 //./multicast-relay/multicast-relay.py INFO: [mDNS] Relayed 308 bytes from 192.168.1.119:5353 on br0 [ttl 255] to 224.0.0.251:5353 via br30/192.168.30.1
Feb-28 12:12:20 //./multicast-relay/multicast-relay.py INFO: [mDNS] Relayed 308 bytes from 192.168.1.119:5353 on br0 [ttl 255] to 224.0.0.251:5353 via br40/192.168.40.1
Feb-28 12:10:29 //./multicast-relay/multicast-relay.py INFO: [mDNS] Relayed 798 bytes from 192.168.40.196:5353 on br40 [ttl 255] to 224.0.0.251:5353 via br0/192.168.1.1
Feb-28 12:10:29 //./multicast-relay/multicast-relay.py INFO: [mDNS] Relayed 798 bytes from 192.168.40.196:5353 on br40 [ttl 255] to 224.0.0.251:5353 via br30/192.168.30.1

but the sonos box (192.168.40.196) is not discoverable via airplay on my phone (192.168.1.119).

For both networks I have turned on mdns on my udm pro and I have a firewall rule that allows a connection from 192.168.40.196 to 192.168.1.0/24 any ports (for debugging, because its not working...).

I am not sure whether this is the correct place to report, because it seems that multicast-relay works fine, but maybe I have over looked a setting or so. I hope you can help!

VLAN Down and UP

Hello!

Me again! =)

If VLAN goes down and up again the script lost and don't find the interface : [Errno 6]

Jun-14 16:41:32 multicast-relay.py INFO: [mDNS] Relayed 233 bytes from 10.125.1.20:5353 on eth1.10 [ttl 255] to 224.0.0.251:5353 via eth1.5/10.125.128.1
Jun-14 16:41:32 multicast-relay.py INFO: Error sending packet: [Errno 6] No such device or address

Can this be used on interfaces without MAC address?

Hey,

First of all thanks for the code!
I see a mac address is required for this code to run.
Is it really required by the protocol itself, cause I wanted to give it a try through wireguard and the interface doesn't have a MAC address.

Thank you

OpenWRT and python3

Hi,

I've just tried running on openwrt 22.03.3 which only has python 3.10 available.
Without the openwrt-python-encodings supplied, I get:

('Adding broadcast relay for 255.255.255.255:6969 (Sonos Setup Discovery)',) {}
Traceback (most recent call last):
  File "/root/multicast-relay/./multicast-relay.py", line 1029, in <module>
    sys.exit(main())
  File "/root/multicast-relay/./multicast-relay.py", line 1024, in main
    packetRelay.addListener(addr, port, relay[1])
  File "/root/multicast-relay/./multicast-relay.py", line 298, in addListener
    (ifname, mac, ip, netmask, broadcast) = self.getInterface(interface)
  File "/root/multicast-relay/./multicast-relay.py", line 738, in getInterface
    if interface in self.nif.interfaces():
  File "/root/multicast-relay/./multicast-relay.py", line 98, in interfaces
    ifNames = ifNames.tostring()
AttributeError: 'array.array' object has no attribute 'tostring'

With them put in the /usr/lib/python3.10/encodings directory, it instead errors with:

Python path configuration:
  PYTHONHOME = (not set)
  PYTHONPATH = (not set)
  program name = 'python'
  isolated = 0
  environment = 1
  user site = 1
  import site = 1
  sys._base_executable = '/usr/bin/python'
  sys.base_prefix = '/usr'
  sys.base_exec_prefix = '/usr'
  sys.platlibdir = 'lib'
  sys.executable = '/usr/bin/python'
  sys.prefix = '/usr'
  sys.exec_prefix = '/usr'
  sys.path = [
    '/usr/lib/python310.zip',
    '/usr/lib/python3.10',
    '/usr/lib/python3.10/lib-dynload',
  ]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
  File "/usr/lib/python3.10/encodings/__init__.py", line 123
    raise CodecRegistryError,\
                            ^
SyntaxError: invalid syntax

Current thread 0x77ed5d80 (most recent call first):
  <no Python frame>

Are you able to provide any pointers?

Not all broadcast addresses are accepted

I am trying to relay broadcasts to 192.168.1.255 but these are rejected because the code is only allowing 255.255.255.255 as the broadcast address. According to Wikipedia:

The broadcast address for any IPv4 host can be obtained by taking the bit complement (bitwise NOT) of the subnet mask and then performing a bitwise OR operation with the host's IP address. A shortcut to this process (for common masks using only 0 and 1 bit placements) is to simply take the host's IP address and set all bits in the host identifier portion of the address (any bit positions which hold a 0 in the subnet mask) to 1.

Multicast UDP port 6668

This fine project allows my Home Assistant to connect with Sonos. I have one other multicast need, Home Assistant on one VPN needs to send multicast messages in UDP or TCP through port 6668 to another VLAN. Is there a way to set this with the "relay" option? Sorry I do not know enough about multicast or python to figure this out. Thanks!

Debian 11 compatibility

Been using this for over a year with great success, But since i upgraded Debian to version 11 it stopped working. I tried to satisfy all dependencies, but somehow it doesn't work. Can anyone point me in the right direction (and update documentation if needed)

As netifaces is required, i installed it:

me@host:~/scripts$ sudo pip install netifaces

Requirement already satisfied: netifaces in /usr/local/lib/python3.9/dist-packages (0.11.0)
me@host:~/scripts$ sudo /opt/multicast-relay/multicast-relay.py --interface enp3s0.2 enp3s0.3 --noMDNS

Traceback (most recent call last):
  File "/opt/multicast-relay/multicast-relay.py", line 1018, in <module>
    sys.exit(main())
  File "/opt/multicast-relay/multicast-relay.py", line 975, in main
    logger               = logger)
  File "/opt/multicast-relay/multicast-relay.py", line 194, in __init__
    self.nif = Netifaces(homebrewNetifaces, ifNameStructLen)
  File "/opt/multicast-relay/multicast-relay.py", line 73, in __init__
    import netifaces
ImportError: No module named netifaces

Tried to remove and install again, but somehow the script cannot import it.

problems with modern kernels that won't pass Sonos broadcasts (255.255.255.255:6969)

I found the broadcast IP was used but that never received any packets on a 4.19 kernel. T

diff --git a/multicast-relay.py b/multicast-relay.py
index 77b07a7..4fb7f83 100755
--- a/multicast-relay.py
+++ b/multicast-relay.py
@@ -8,6 +8,7 @@ import os
 import re
 import select
 import socket
+import IN
 import struct
 import sys
 import time
@@ -284,11 +285,12 @@ class PacketRelay():
                 rx = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
                 rx.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                 rx.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+                rx.setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, ifname)

-                rx.bind((broadcast, port))
+                rx.bind(('0.0.0.0', port))

                 self.receivers.append(rx)
-                listenIP = broadcast
+                listenIP = '255.255.255.255'

             elif self.isMulticast(addr):
                 packedAddress = struct.pack('4s4s', socket.inet_aton(addr), socket.inet_aton(ip))

Android client can't see Chromecast Speaker Groups

Hi,

I realize this is likely not a multicast-relay specific issue but I thought I'd ask since chromecast is mentioned in the readme.

Without multicast-relay on my Unifi UDM Pro, iOS in a different plan would only see my chromecast speaker groups in the Spotify app, and not other apps like Google Home or Plexamp. Android would never see them however.

When running scyto's docker container however, my iOS devices now see the speaker groups in Google Home and Plexamp while my Android devices still don't see them.

Any ideas as to what the deal is with Android clients and chromecast speaker groups in different vlans?

Thanks.

Issue with LinkPlay Devices

Not sure what the exact issue is here, but the relay works great for all my other devices from my IoT vlan to my normal vlan but my OSD Audio SRT4 which use https://www.linkplay.com do not work through their control app (mostly for merging for multiroom), I have temporarily allowed all ports and protocols from these devices through the firewall so I know it's not that, they work fine with Spotify connect and airplay just not the control app. Using Wireshark I do see the capture of the Multicast dns entry within the IoT subnet but nothing in the normal network when using the control app.

Here's a sample someone else posted of the entry and mine looks similar: home-assistant-libs/netdisco#251

Here's mine capture from my IoT network
image

Is there anything that would be preventing this from working?

I found some good on how they work here but it doesn't talk about the mDNS:
https://github.com/nagyrobi/home-assistant-custom-components-linkplay
https://github.com/n4archive/LinkPlayAPI/blob/master/api.md

DOCS: How (should / can?) I use this as broader multicast relay?

Hi love this, got it working in docker container on a ubiquiti router and i can see mDNS and SSDP on both sides of my two networks.

Do you intend this to be a broader IGMP Proxy (asking because of the name change). For example are there ways for me to say all ports on all 224.0.0.0/4. Or should i look at the IGMP proxy github project for that sort of thing?
(i like yours as you have recent updates)

--ifFilter

Hello,

I am returning this project but want to use--ifFilter to broadcast only who was in the filter.
If i remove --interface the script doesn't run.

Which way it the best for this communication? 2Way Mobile Chromecast.

{
"10.125.131.132/32": ["eth1.5", "eth1.10"],
"10.125.1.4": ["eth1.10", "eth1.5"]
}

latest commit broken

Hi,

Thanks for your handy script.

OS: Openwrt 22.03.5 / python3-light & python3-netifaces installed. (no need to follow th eold OWRT instructions for python2.7 it seems)

The previous commit 2c0e4c7 seems to work fine, but latest commit 030451 "additional mechanism for Sonos to dissover itself" returns the following ...

python /root/multicast-relay.py --interfaces br-lan br-iot

Traceback (most recent call last):
File "/root/multicast-relay.py", line 1030, in
sys.exit(main())
File "/root/multicast-relay.py", line 959, in main
relays.add(('%s:%d' % (PacketRelay.BROADCAST, '1900'), 'Sonos Discovery'))
TypeError: %d format: a real number is required, not str

set REMOTE_HOST to a subnet?

This is a fantastic project. I have a need to have the --listen flag able to receive connections from a subnet that is dynamically setup. For example "--listen 10.111.25.0/26".

Specify subnets rather than interfaces?

Thanks for making this script. I have two subnets each with Sonos speakers. Each device on both subnets can access the devices on the other subnet. I'd love to have all speakers in one controller.

I've got a Linux box (that isn't the router) that can access both subnets and all devices. Anyway to do something similar to this:

./multicast-relay.py --interfaces 192.168.0.1/24 192.168.1.1/24

Instead of specifying physical network interfaces?

Tutorial

Hi!

this plugin looks exactly like what I need but I’m wondering if a tutorial is available on how to install and how to use it?

I would like to install this in a docker container (via Portainer) on my raspberry Pi to route mdns traffic between my main lan and my VPN VLAN. Currently ubiquity does not forward mdns traffic to the VPN.

Couple of questions:

  • would that work with this plugin?
  • If my pi is only connected to the main LAN can it still broadcast to the other vlans?
  • Is it possible to install this in a docker container? And if so what network mode would I have to choose?

And if anyone knows any YouTube tutorials or step by step guides that would be wonderful! Right now I’m having a bit of a hard time getting everything to work.

Thanks so much!

Too many retransmissions for SSDP unicast packets

multicast-relay relays SSDP multicast packets (as well as any other multicast/broadcast packets) to all available interfaces.

If multicast-relay is used with --ssdpUnicastAddr, SSDP multicast packets are still relayed to all interfaces. This behaviour is not optimal - SSDP unicast listener is created only for --ssdpUnicastAddr, so unicast responses on interfaces with different addresses will be never received.

Steps to reproduce: run multicast-relay.py --verbose --foreground --interfaces $IFACE1 $IFACE2 --ssdpUnicastAddr $IFACE1_ADDR, send a SSDP multicast packet from another machine connected to the same network as $IFACE1

Expected behaviour: packet is not relayed to $IFACE2 (since the unicast listener listens on $IFACE1)

Actual behaviour: packet is relayed from $IFACE1 to $IFACE2

ifFilter

Its possible to have ifFilter.json at master?

To filter 2 ways multicast traffic?

Rceivers are not bound to a specific port

All listeners (broadcast / multicast / SSDP unicast) are of type SOCK_RAW and cannot be bound to any specific port. When rx.bind((addr, port)) is called, the sockets are bound only to the specified address and receive packets regardless of destination port.

For example, if Sonos discovery is enabled, then all UDP broadcast packets will be relayed.

Also, this can lead to infinite retransmission of packets.
Consider two machines connected by a Wireguard tunnel.
The first one has an Ethernet interface eth0 with address 192.168.0.10 and a Wireguard interface wg0 with address 10.0.0.1, which uses eth0 to connect to peers.
The second one has a Wireguard interface wg0 with address 10.0.0.2 and an interface lan1. Also, the second machine routes all requests to 192.168.0.0/24 via the Wireguard tunnel.
On the first machine, a relay is run with options --interfaces eth0 --ssdpUnicastAddr 192.168.0.10 --listen 10.0.0.2
On the second one, a relay is run with options --interfaces lan1 --remote 10.0.0.1
Possible cause of infinite retransmission in this setup:

  1. The second machine (or any other peer) sends some data to the first machine over the Wireguard tunnel.
  2. The unicast receiver (on the first machine) receives encrypted data encapsulated in UDP packets (with destination address 192.168.0.10). It retransmits these packets to the relay on the second machine.
  3. The second relay sends the packets to 192.168.0.10 (they are routed via the Wireguard tunnel).
  4. The unicast receiver receives new packets (with increased size). goto step 2
    This can possibly lead to a crash of the relay or the machine may run out of memory

Possible solutions:

  1. Use sockets of type SOCK_DGRAM as receivers (may break something)
  2. Check port for each incoming packet (this part of code may help, if used before relaying to remotes)
    dstPort = struct.unpack('!H', data[ipHeaderLength+2:ipHeaderLength+4])[0]

"bad udp cksum" on relay output (when relaying between wireguard wg0 and eth0)

Hi,

Not sure if it's expected or if I've set something up wrong. However when I'm trying to relay from wireguard vpn on wg0 and to local eth0, I'm not getting replies to the client (that is on wg0 / VPN) and when I look at the tcpdump it appears to show a bad checksum on the relayed broadcast message to eth0. I am using the experimental "allowNonEther", so perhaps it's related to that?

Thanks,

multicast-relay output:

starting multicast-relay
Using Interfaces: eth0 wg0
Using Options --foreground  --verbose --allowNonEther
Jun-06 10:19:27 /etc/app/multicast-relay/multicast-relay.py INFO: Adding multicast relay for 224.0.0.251:5353 (mDNS)
Jun-06 10:19:27 /etc/app/multicast-relay/multicast-relay.py INFO: Adding multicast relay for 239.255.255.250:1900 (SSDP)
Jun-06 10:19:27 /etc/app/multicast-relay/multicast-relay.py INFO: Adding broadcast relay for 255.255.255.255:6969 (Sonos Discovery)
Jun-06 10:22:51 /etc/app/multicast-relay/multicast-relay.py INFO: [SSDP] Relayed 129 bytes from 10.6.0.2:1900 on wg0 [ttl 5] to 239.255.255.250:1900 via eth0/192.168.1.112

eth0 tcpdump:

bash-4.4# tcpdump -i eth0  udp port 1900 -vv -X
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

10:22:51.319217 IP (tos 0x0, ttl 5, id 12513, offset 0, flags [DF], proto UDP (17), length 129)
    10.6.0.2.1900 > 239.255.255.250.1900: [bad udp cksum 0x43fa -> 0x032a!] UDP, length 101
	0x0000:  4500 0081 30e1 4000 0511 4a89 0a06 0002  [email protected].....
	0x0010:  efff fffa 076c 076c 006d 43fa 4d2d 5345  .....l.l.mC.M-SE
	0x0020:  4152 4348 202a 2048 5454 502f 312e 310d  ARCH.*.HTTP/1.1.
	0x0030:  0a4d 414e 3a20 2273 7364 703a 6469 7363  .MAN:."ssdp:disc
	0x0040:  6f76 6572 220d 0a48 4f53 543a 2032 3339  over"..HOST:.239
	0x0050:  2e32 3535 2e32 3535 2e32 3530 3a31 3930  .255.255.250:190
	0x0060:  300d 0a53 543a 2075 706e 703a 726f 6f74  0..ST:.upnp:root
	0x0070:  6465 7669 6365 0d0a 4d58 3a20 350d 0a0d  device..MX:.5...
	0x0080:  0a                                       .

wg0 tcpdump:

bash-4.4# tcpdump -i wg0 port 1900 -vv -X  
tcpdump: listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes

0:22:51.307452 IP (tos 0x0, ttl 5, id 12513, offset 0, flags [DF], proto UDP (17), length 129)
    10.6.0.2.1900 > 239.255.255.250.1900: [udp sum ok] UDP, length 101
	0x0000:  4500 0081 30e1 4000 0511 4a89 0a06 0002  [email protected].....
	0x0010:  efff fffa 076c 076c 006d 032a 4d2d 5345  .....l.l.m.*M-SE
	0x0020:  4152 4348 202a 2048 5454 502f 312e 310d  ARCH.*.HTTP/1.1.
	0x0030:  0a4d 414e 3a20 2273 7364 703a 6469 7363  .MAN:."ssdp:disc
	0x0040:  6f76 6572 220d 0a48 4f53 543a 2032 3339  over"..HOST:.239
	0x0050:  2e32 3535 2e32 3535 2e32 3530 3a31 3930  .255.255.250:190
	0x0060:  300d 0a53 543a 2075 706e 703a 726f 6f74  0..ST:.upnp:root
	0x0070:  6465 7669 6365 0d0a 4d58 3a20 350d 0a0d  device..MX:.5...
	0x0080:  0a                                       .

Breaking update for --listen

Just pulled the latest version which added changes for --listen. Unfortunately this option is now mandatory otherwise you see the following error as there is no check to see if the argument is being supplied in the 1st place:

[UDM] root@udmp:/mnt/data/containers# podman run --network=host --name ssdp-relay --restart=always -e INTERFACES="br50 b
r99" -e OPTS="" localhost/multicast-relay
Starting multicast-relay on  Mon May 2 16:52:34 UTC 2022
Using Interfaces: br50 br99
Using Options --foreground
Traceback (most recent call last):
  File "//./multicast-relay/multicast-relay.py", line 1028, in <module>
    sys.exit(main())
  File "//./multicast-relay/multicast-relay.py", line 967, in main
    packetRelay = PacketRelay(interfaces           = args.interfaces,
  File "//./multicast-relay/multicast-relay.py", line 208, in __init__
    for addr in listen:
TypeError: 'NoneType' object is not iterable

Adding in the --listen argument with a random IP bypasses the issue.

Multiple Networks?

Is it possible to connect multiple sets of vlans together? I will have my network (1), my tenant network (2), and a shared iot network (3).

I would want network 1 and 3 to share mdns as well as network 2 and 3 to share mdns. However, I don’t want network 1 and 2 to share mdns with each other.

Is that possible?

Proxy SSDP

Thanks for a great and straightforward solution to this problem space!

One issue I have, however, is how the responses for SSDP/DIAL are handled. A client on VLAN A (192.168.1.0/24) might multicast an SSDP/DIAL search, with its normal unicast source IP (192.168.1.100:34534 -> 239.255.255.250:1900). The relay retransmits this search as-is and an interested IOT device on VLAN B (192.168.2.0/24) responds from its unicast IP to the original unicast source IP (192.168.2.154:59423 -> 192.168.1.100:34534). The problem is that a stateful firewall handling traffic between the VLANs has not "seen" the original request (because it is not application-aware for SSDP/DIAL) and therefore the response is disallowed unless all traffic is permitted from the IOT VLAN to the client VLAN, but that is not really desirable.

I think this problem could be resolved by changing the relay's behavior with respect to SSDP/DIAL to allow a "proxy" mode in which the relay enqueues the SSDP request and transmits a new request on the forwarding VLANs using its own IP as the source. The relay could forward unicast responses back to the original client's unicast IP. Since SSDP/DIAL responses include the Location field inside the protocol message, the source IP of the reply shouldn't matter to the client. When the client attempts to connect to the IOT device at the Location address, the firewall can see this as an authorized user->IOT connection and track it appropriately.

Thoughts?

UnboundLocalError when using the ssdpUnicastAddr flag

Upgraded to the latest commit off master, and now my container immediately crashes when using the ssdpUnicastAddr flag. I like using this flag to make my firewall rules simpler to manage, so hoping it isn't dropped.

`
Traceback (most recent call last):

File "multicast-relay.py", line 990, in

sys.exit(main())

File "multicast-relay.py", line 985, in main

packetRelay.addListener(addr, port, relay[1])

File "multicast-relay.py", line 304, in addListener

self.transmitters.append({'relay': {'addr': listenIP, 'port': port}, 'interface': ifname, 'addr': ip, 'mac': mac, 'netmask': netmask, 'broadcast': broadcast, 'socket': tx, 'service': service})

UnboundLocalError: local variable 'listenIP' referenced before assignment
`

Devices from Excluded VLANs Show Up in Logs

Hi guys,

I installed multicast-relay on my Ubiquity Dream Machine pro with the following command:

podman run -it -d \
--restart=on-failure:10 \
--name="multicast-relay-10" \
--network=host \
--mount type=bind,src=/mnt/data/on_boot.d_support,dst=/multicast-relay-config \
-e OPTS="--verbose" \
-e INTERFACES="br10 br50" \
docker.io/scyto/multicast-relay

The only interfaces I have assigned are VLAN 10 (10.0.10.x) and VLAN 50 (10.0.50.x). However, when running a discovery tool I can see a few devices from VLAN 30 show. I can even see them in the logs (10.0.30.145 - AppleTV & 10.0.30.178 - HomePod & 10.0.30.249 -iPad):
log3.txt

I'm starting to lose my mind because I don't understand what could possibly be the problem. Does anyone have any ideas on how to trouble shoot this issue?

Here is my ifconfig output:
143946566-bf5255ef-4095-4958-b68d-c571c9b07955

modify udp packet is wrong and generates invalid udp

ipHeader = data[:ipHeaderLength-8] + socket.inet_aton(srcAddr) + socket.inet_aton(dstAddr) + data[ipHeaderLength:]

Hi!

The code above generates invalid, huge UDP packages.
The + data[ipHeaderLength:] adds the whole packet (all after the header). That summand needs to be removed.

So correct line should just look like:
ipHeader = data[:ipHeaderLength-8] + socket.inet_aton(srcAddr) + socket.inet_aton(dstAddr)

Best regards

Tino

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.