Code Monkey home page Code Monkey logo

udp-broadcast-relay-redux's People

Contributors

accwebs avatar ajkavanagh avatar delitants avatar efirestone avatar frots avatar kk7ds avatar mmorrisontx avatar mneitsabes avatar nomeata avatar patrislav1 avatar sonicsnes 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

udp-broadcast-relay-redux's Issues

Dynamic interface changes

First of all, great work! I was able to use two of these to get Steam in-home streaming working across a VPN (one server listens on the local subnets and a TAP site-to-site and the other server listens on the TAP site-to-site and a OpenVPN remote access TAP). I'm using Redux instead of the upstream since I am working on adding other protocols that Redux supports

Would it be possible add functionality to specify a wildcard interface (ex: vpns* which would accept vpns0, vpns1, ... vpnsN), and then an option to turn on a "dynamic interface" feature that automatically added new interfaces matching the pattern? Alternatively, rather than monitor when interfaces change, I could send udp-broadcast-relay a SIGHUP or SIGUSR1 from OpenConnect since I can set scripts for client connect and disconnect events. Right now I use the scripts to add and remove the client interfaces in firewalld.

The program could then be called as udp-broadcast-relay-redux --id 1 --port 27036 --dev tap0 --dev vpns* --dyn-int. It would then start work on the tap0 interface, and add or remove any interface matching the pattern vpns* as the were created or destroyed.

I work in IT with computer networking and know a bit of network programming, so I know that this is not a simple ask for these two problems. As an interim solution, I am working on a wrapper program/script that can kill and restart udp-broadcast-relay when the interface config changes, but this means that there is a chance of missing a packet on an already active interface in the narrow window that it goes down.


Background:

Recently, I was experimenting with the OpenConnect VPN server, which is an open-source implementation of Cisco's AnyConnect software. Internal to the VPN server, OpenConnect appears to dynamically create point-to-point links with each device. Even though they are point-to-point links, I found out via packet capture that they still support broadcast traffic. So, before any clients connect, the server looks like this (I don't actually have 80 interfaces, the server just has a really high uptime and weathered a lot of OpenConnect and OpenVPN restarts):

61: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/ether 4e:4d:6c:bc:14:3d brd ff:ff:ff:ff:ff:ff
    inet 10.77.0.254/27 brd 10.77.0.255 scope global tap0
       valid_lft forever preferred_lft forever
    inet6 fe80::4c4d:6cff:febc:143d/64 scope link
       valid_lft forever preferred_lft forever
67: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/ether 0e:03:8d:b4:01:da brd ff:ff:ff:ff:ff:ff
    inet 10.77.4.126/26 brd 10.77.4.127 scope global tap1
       valid_lft forever preferred_lft forever
    inet6 fe80::c03:8dff:feb4:1da/64 scope link
       valid_lft forever preferred_lft forever
70: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.77.4.190/26 brd 10.77.4.191 scope global tun0
       valid_lft forever preferred_lft forever

Then, after the first OpenConnect client connects, this interface is added to the list:

81: vpns0: <POINTOPOINT,UP,LOWER_UP> mtu 1353 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 10.77.4.193 peer 10.77.4.233/32 scope global vpns0
       valid_lft forever preferred_lft forever

Second client added:

82: vpns1: <POINTOPOINT,UP,LOWER_UP> mtu 1341 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 10.77.4.193 peer 10.77.4.231/32 scope global vpns1
       valid_lft forever preferred_lft forever

First client disconnected and reconnected, noting that the interface index changed:

83: vpns0: <POINTOPOINT,UP,LOWER_UP> mtu 1353 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 10.77.4.193 peer 10.77.4.233/32 scope global vpns0
       valid_lft forever preferred_lft forever

Doesn't work with VLAN ? -> Yes, it do

Hi,

I try to use your program on my pfSense to relay UDP brodcasted message from two networks.

My pfSense is connected to a switch with a LAG. I have VLAN on this LAG so my interfaces are :

  • lagg0 (untagged)
  • lagg0.10 (clients)
  • lagg0.201 (domotica)

The software used to control the domotica, which is running on the VLAN 10, is broadcasting a single byte in a UDP packet on the port 10000. So I tried this one :

$ ./udp-broadcast-relay -d --id 1 --port 10000 --dev lagg0.10 --dev lagg0.201
ID set to 1
Port set to 1
ID: 1 (ttl: 65), Port 100
lagg0.10: 11 / 10.37.10.1 / 10.37.10.255
lagg0.201: 17 / 10.37.201.1 / 10.37.201.255
found 2 interfaces total
Done Initializing

(Note that "Port set to 1" is a error in the code. The variable 'id' is used instead of 'port')

But it doesn't work. I see the broadcasted packet with tcpdump on the lagg0.10 but nothing is relayed. I edit your code to add a "print" after receiving a packet (line 434) and I saw that nothing was captured. Then I tried on the untagged interface like that :

./udp-broadcast-relay -d --id 1 --port 10000 --dev lagg0 --dev lagg0.201

and using hping3 to simulate the packet and I see the packet captured but nothing is relayed.

It seems that the code doesn't work with VLAN but silently fails.

Best regards,

PlayFi App Spotify control issues. UDP packets not being forwarded because of "Message too long" issue

First just wanted to say thanks for putting this all together for pfsense!
Here is my issue and i'm not sure how to trouble shoot.

I have three subnets. i have playfi speakers installed on two different subnets. This program/service made them all discover-able from any of my subnets. Awesome.
Prior to installing udp-broadcast-relay-redux i was only able to see the three play-fi speakers that were on my wifi network/subnet. And i could only see them using the playfi app on my phones which were on the same subnet as the playfi speakers. I could not see them using my computer that was on a wired subnet. After installing this awesome package i could see all my speakers across all subnets!
Here is my issue:
The playfi app has a feature that allows you to see within the playfi app what is playing on spotify and what speakers are being used by spotify connect. I can control the volume and add or remove speakers to what is playing via spotify connect.
This feature was working fine prior to installing this udp broadcast relay service. That is it was working fine for the single wifi subnet and the speakers on that subnet.
After installing udp-broadcast-relay-redux, here is what happens when i play spotify on my speakers across subnets. I play music via spotify connect and open up the playfi app. The spotify window with info on what is playing currently and what speakers spotify is using pops up for a brief second and disappears. Then comes back after a while and disappears very quickly.
Any idea what could cause that?

Mac OS X support

For Mac OS X it generally works if FreeBSD is defined, but one thing needs changing as the ioctl does not exist on Mac OS. However there is a standard API function even supported on Windows:

@@ -202,6 +204,7 @@ int main(int argc,char **argv) {
                strncpy(basereq.ifr_name,interfaceNames[i],IFNAMSIZ);
 
                /* Request index for this interface */
+/*
                {
                        struct ifreq req;
                        memcpy(&req, &basereq, sizeof(req));
@@ -215,6 +218,8 @@ int main(int argc,char **argv) {
                        iface->ifindex = req.ifr_ifindex;
                        #endif
                }
+*/
+               iface->ifindex = if_nametoindex(interfaceNames[i]);

obviously should remove the code, not just comment out. If I have more time, I might be able to send a PR.

And also:

@@ -552,13 +560,13 @@ int main(int argc,char **argv) {
                        *(u_short*)(gram+20)=htons(fromPort);
                        *(u_short*)(gram+22)=htons(toPort);
                        // This is only needed for FreeBSD <= 10 | pfSense <= 2.3.*
-                       //#ifdef __FreeBSD__
-                       //*(u_short*)(gram+24)=htons(UDPHEADER_LEN + len);
-                       //*(u_short*)(gram+2)=HEADER_LEN + len;
-                       //#else
+                       #ifdef ___APPLE__
+                       *(u_short*)(gram+24)=htons(UDPHEADER_LEN + len);
+                       *(u_short*)(gram+2)=HEADER_LEN + len;
+                       #else
                        *(u_short*)(gram+24)=htons(UDPHEADER_LEN + len);
                        *(u_short*)(gram+2)=htons(HEADER_LEN + len);
-                       //#endif
+                       #endif
                        struct sockaddr_in sendAddr;
                        sendAddr.sin_family = AF_INET;
                        sendAddr.sin_port = htons(toPort);

as Mac OS still has the older pf.

IPv6 support?

When trying to join an IPv6 multicast group, udp-broadcast-relay-redux tries to add it to the IPv4 address for the interface.

$ sudo ./udp-broadcast-relay-redux  -d --dev eno0 --dev eno0.2 --id 5 --port 5353 --multicast f02::fb
ID set to 5
Port set to 5353
ID: 5 (ttl: 69), Port 5353
eno0: 2 / 192.168.1.4 / 192.168.1.255
eno0.2: 4 / 192.168.2.4 / 192.168.2.255
found 2 interfaces total
IP_ADD_MEMBERSHIP:              192.168.1.4 f02::fb
IP_ADD_MEMBERSHIP on rcv: Invalid argument

-broadcast-relay_env: bad variable name

I believe I have configured this on pfsense 2.5.2 following the pfsense-config/README.md after making on freebsd 12.2. When attempting to start the service using sudo service udp-broadcast-relay.sh start the response is export: -broadcast-relay_env: bad variable name

I'll confess I don't really know what I'm doing but have had a dig through udp-broadcast-relay-redux.conf, udp-broadcast-relay.sh and main.c with no luck on finding where this variable is being set/exported.

@ajkavanagh what am I missing? There is a closed issue https://github.com/udp-redux/udp-broadcast-relay-redux/issues/14 which appears to show my exact problem

Support destination IP override?

In the case of trying to forward broadcast packets over tun-based VPNs, the tun interfaces unfortunately don't support broadcast packets. A workaround is to rewrite the outbound packet's destination address to be the remote router's IP address. And then that router would rewrite the packet's destination address to the broadcast address.

I have this working on a fork. About to raise a PR in case you see this as useful.

Not relaying broadcast 255.255.255.255 across vlans

Running pfsense 2.6.0-RELEASE (amd64)
built on Mon Jan 31 19:57:53 UTC 2022
FreeBSD 12.3-STABLE

Have a WeatherFlow Tempest hub:
tcpdump -vvnn -i re1.900 udp port 50222

tcpdump: listening on re1.900, link-type EN10MB (Ethernet), capture size 262144 bytes
01:32:52.978060 IP (tos 0x0, ttl 255, id 3629, offset 0, flags [none], proto UDP (17), length 127)
10.0.9.22.50222 > 255.255.255.255.50222: [udp sum ok] UDP, length 99

udpbroadcastrelay --id 42 --port 50222 --dev re1.900 --dev re1.10 -d -f

ID set to 42
Port set to 50222
Forking Mode enabled
ID: 42 (DSCP: 42, ToS: 0xa8), Port 50222
re1.900: 15 / 10.0.9.1 / 10.0.9.63
re1.10: 17 / 10.0.0.65 / 10.0.0.127
found 2 interfaces total
Done Initializing

I can verify the process is still running. But not sure how to verify it properly binds to the udp port or if it needs to since this is broadcast, and not multicast.

The issue is...
tcpdump -vvnn -i re1.10 udp port 50222
returns nothing.

The kernel itself can do this

In trying to debug my Google Cast issues last night, I discovered your daemon. It works great, presumably because it doesn't ingest and then create new mDNS payloads like avahi-daemon does. But then I realized nftables can do the same thing. To wit:

table ip mangle {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;
        ip daddr 224.0.0.251 iif enp2s0.30 ip saddr set 192.168.1.1 dup to 224.0.0.251 device enp2s0.10 notrack
        ip daddr 224.0.0.251 iif enp2s0.10 ip saddr set 192.168.3.1 dup to 224.0.0.251 device enp2s0.30 notrack
    }
}

table ip6 mangle {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;
        ip6 daddr ff02::fb iif enp2s0.30 ip6 saddr set fd20:1111:1111:1::1 dup to ff02::fb device enp2s0.10 notrack
        ip6 daddr ff02::fb iif enp2s0.10 ip6 saddr set fd20:1111:1111::3::1 dup to ff02::fb device enp2s0.30 notrack
    }
}

The above repeats mDNS packets from enp2s0.10 to enp2s0.30 and vice versa. Works great. Kinda nuts how simple this is.

nftables can do this

In trying to debug my Google Cast issues last night, I discovered your daemon. It works great, presumably because it doesn't ingest and then create new (and presumably somehow mangled) mDNS payloads like avahi-daemon does. But then I realized nftables can do the same thing. To wit:

table ip mangle {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;
        ip daddr 224.0.0.251 iif enp2s0.30 ip saddr set 192.168.1.1 dup to 224.0.0.251 device enp2s0.10 notrack
        ip daddr 224.0.0.251 iif enp2s0.10 ip saddr set 192.168.3.1 dup to 224.0.0.251 device enp2s0.30 notrack
    }
}

table ip6 mangle {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;
        ip6 daddr ff02::fb iif enp2s0.30 ip6 saddr set fd20:1111:1111:1::1 dup to ff02::fb device enp2s0.10 notrack
        ip6 daddr ff02::fb iif enp2s0.10 ip6 saddr set fd20:1111:1111::3::1 dup to ff02::fb device enp2s0.30 notrack
    }
}

The above repeats mDNS packets from enp2s0.10 to enp2s0.30 and vice versa. Works great. Kinda nuts how simple this is.

PS5 Remote Play + Wireguard

Not a bug but could be something to add to the readme. I was able to get PS5 Remote Play (both discovery and the actual video stream) working over Wireguard with the following:

./udp-broadcast-relay-redux --id 1 --port 9302 --dev wg0 --dev eno1 -t 192.168.0.255
./udp-broadcast-relay-redux --id 2 --port 9303 --dev eno1 --dev wg0 -t 10.69.0.2

Both instances of udp-broadcast-relay-redux are running on a Wireguard server on the same physical network as the PS5 (192.168.0.0/24). 10.69.0.2 is the IP of the Wireguard client.

Key benefit of this over normal automatic connection is that it can wake the PS5 without any port forwarding/upnp on the PS5 end

Thanks!

Not an issue, but this little utility just sorted out a whole load of issues I was having on my home network. Never had SSDP running reliably between vlans. If you have a donate page or anything I'll send you something.

Also, I have this running on a Ubiquiti Edge Route Lite, (cross-)compiled for the mips64 processor, without any issues.

Support to use the source port with dynamic spoofed IP + port

@@ -515,6 +520,9 @@ int main(int argc,char **argv) {
                        if (spoof_addr == inet_addr("1.1.1.1")) {
                                fromAddress = iface->ifaddr;
                                fromPort = port;
+                       } else if (spoof_addr == inet_addr("2.2.2.2")) {
+                               fromAddress = iface->ifaddr;
+                               fromPort = origFromPort;
                        } else if (spoof_addr) {
                                fromAddress.s_addr = spoof_addr;
                                fromPort = origFromPort;

it would be great to support to use origFromPort even with the dynamic spoofed IP, based on the interface address.

Packets forwarding to original interface

Running on an Alpine 3.12 x86_64 VM it appears to correctly identify the three interfaces i have connected but when relaying the packets it looks like it is sending it back out the interface it received it from.

`udp-relay:~# ./udp-broadcast-relay-redux --id 10 --port 30050 --dev eth0 --dev eth1 --dev eth2 -d
ID set to 10
Port set to 30050
ID: 10 (ttl: 74), Port 30050
eth0: 2 / 192.168.10.5 / 0.0.0.0
eth1: 3 / 192.168.11.5 / 0.0.0.0
eth2: 4 / 192.168.12.5 / 0.0.0.0
found 3 interfaces total
Done Initializing

<- [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=4 len=28 ttl=64)
-> [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=2)
-> [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=3)

<- [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=4 len=28 ttl=64)
-> [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=2)
-> [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=3)

<- [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=4 len=28 ttl=64)
-> [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=2)
-> [ 192.168.12.245:30000 -> 192.168.12.255:30050 (iface=3)
`

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.