Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set static IP addresses (Android 11+) #193

Closed
knuxyl opened this issue Nov 12, 2020 · 53 comments
Closed

Set static IP addresses (Android 11+) #193

knuxyl opened this issue Nov 12, 2020 · 53 comments

Comments

@knuxyl
Copy link

knuxyl commented Nov 12, 2020

I don't know if it's the Pixel 5 Android 11, but before on my Moto X4 Android 10 the IPs given to clients was always 192.168.43.XXX. With my Pixel 5, it is now completely random every time I turn the hotspot on. I do not know if this is Android 11, Pixel 5, or a bug in VPN Hotspot. I need my IPs to be static.
What it did on Moto X4
Desktop - 192.168.43.125
Server - 192.168.43.100
What its doing now on Pixel 5
Desktop 192.168.170.125
Server - 192.168.170.100
The bold is random everytime, but it does keep the last digits the same.

If this isn't a ug, could this be a feature request to allow control over this?

@Mygod
Copy link
Owner

Mygod commented Nov 12, 2020

This is an intended feature of Android 11. You should complain to Google instead.

@Mygod Mygod added the vendor-specific Definitely not my fault label Nov 12, 2020
@Mygod Mygod closed this as completed Nov 12, 2020
@Mygod Mygod changed the title Possible bug : Randomized IP subnet Set static IP addresses (Android 11+) May 31, 2021
@Mygod
Copy link
Owner

Mygod commented May 31, 2021

Reopening since technically setStaticIpv4Addresses API addresses this, but it seems it will restrict the tethering to only one device.

@Mygod Mygod reopened this May 31, 2021
@seandepagnier
Copy link

This "feature" is really useless. Why did they do this?

@Mygod
Copy link
Owner

Mygod commented Feb 22, 2022

In principle, it is possible to hijack the DNS so that a fixed domain will point to the gateway. However, this requires root and I do not see a useful use case for now.

@worstperson
Copy link

worstperson commented Mar 17, 2022

This is an example of redirecting DHCP requests to your own instance of Dnsmasq serving on a non-standard port, in this case for usb tethering. This lets you set any local network, dns servers, static leases.

Clear and set addresses and add the route

ndc interface clearaddrs rndis0
ndc interface setcfg rndis0 192.168.42.1 24 up
ndc network route add 99 rndis0 192.168.42.0/24

Take broadcast udp traffic on port 67 and redirect it to 1067.

iptables -t nat -I PREROUTING -i rndis0 -s 0.0.0.0 -d 255.255.255.255 -p udp -m udp --dport 67 -j DNAT --to-destination 255.255.255.255:1067

Start a new Dnsmasq instance with the dhcp-alternate-port option to receive requests on our alternative port.

killall dnsmasq
dnsmasq --keep-in-foreground --no-resolv --no-poll --dhcp-authoritative --dhcp-range=192.168.42.10,192.168.42.99,1h --dhcp-option=6,8.8.8.8,8.8.4.4 --dhcp-leasefile=/sdcard/dnsmasq.leases --dhcp-alternate-port=1067,68 --dhcp-option-force=43,ANDROID_METERED --pid-file=/sdcard/dnsmasq.pid --listen-mark 0xf0063

Edit:
Dnsmasq still seems to be used for dns. Specifying the port gets around having to kill it.

dnsmasq --keep-in-foreground --no-resolv --no-poll --dhcp-authoritative --dhcp-range=192.168.42.10,192.168.42.99,1h --server=8.8.8.8 --server=8.8.4.4 --dhcp-leasefile=/sdcard/dnsmasq.leases --dhcp-alternate-port=1067,68 --port=1053 --dhcp-option-force=43,ANDROID_METERED --pid-file=/sdcard/dnsmasq.pid --listen-mark 0xf0063

And we can then redirect to the new dns server.

iptables -t nat -I PREROUTING -i rndis0 -s 192.168.42.0/24 -d 192.168.42.1 -p udp -m udp --dport 53 -j DNAT --to-destination 192.168.42.1:1053

@Mygod
Copy link
Owner

Mygod commented Mar 17, 2022

@worstperson Thanks for looking into this! However, I prefer to not kill dnsmasq since that may not work properly. (If I remember correctly, there are some interfacing between the Android netd services and dnsmasq.)

@worstperson
Copy link

Below "Edit:", I had fixed it by setting the DNS port to avoid conflicting and added a rule to point traffic to it.

@worstperson
Copy link

Sorry that wasn't very clear. I quickly realized that you wouldn't accept the original PoC shortly after posting, so I hurriedly fixed the dns server conflict and added it at the bottom of the post with inadequate description. Android seems to still use Dnsmasq as a dns cache, so I used the --port option to change the dns listening port and added an iptables rule to intercept dns requests from clients and redirect them to the port we're listening on. I also changed the dnsmasq command to direct clients to it's dns server, rather than sending them the remote servers to query directly.

ndc interface clearaddrs rndis0
ndc interface setcfg rndis0 192.168.42.1 24 up
ndc network route add 99 rndis0 192.168.42.0/24
# Redirect DHCP requests
iptables -t nat -I PREROUTING -i rndis0 -s 0.0.0.0 -d 255.255.255.255 -p udp -m udp --dport 67 -j DNAT --to-destination 255.255.255.255:1067
# Redirect DNS requests
iptables -t nat -I PREROUTING -i rndis0 -s 192.168.42.0/24 -d 192.168.42.1 -p udp -m udp --dport 53 -j DNAT --to-destination 192.168.42.1:1053
dnsmasq --keep-in-foreground --no-resolv --no-poll --dhcp-authoritative --dhcp-range=192.168.42.10,192.168.42.99,1h --server=8.8.8.8 --server=8.8.4.4 --dhcp-leasefile=/sdcard/dnsmasq.leases --dhcp-alternate-port=1067,68 --port=1053 --dhcp-option-force=43,ANDROID_METERED --pid-file=/sdcard/dnsmasq.pid --listen-mark 0xf0063

An example of how to reverse the changes made. The variable $NETWORK should be set to the ip that was originally assigned to the interface.

# Stop your Dnsmasq instance first
iptables -t nat -D PREROUTING -i rndis0 -s 192.168.42.0/24 -d 192.168.42.1 -p udp -m udp --dport 53 -j DNAT --to-destination 192.168.42.1:1053
iptables -t nat -D PREROUTING -i rndis0 -s 0.0.0.0 -d 255.255.255.255 -p udp -m udp --dport 67 -j DNAT --to-destination 255.255.255.255:1067
ndc network route remove 99 rndis0 192.168.42.0/24
ndc interface clearaddrs rndis0
ndc interface setcfg rndis0 $NETWORK 24 up

@Mygod
Copy link
Owner

Mygod commented Mar 25, 2022

Thanks for the POC. Still not sure if I want to implement all of that though. 🤣

@copystring
Copy link

For days I'm looking for a way to have a fixed DHCP range for my pixel 5.
In my very specific use case my car connects to my phones hotspot. Then Torque Pro installed on my car is supposed to connect to the app "Torque OBD2 Repeater". This would only ever work if the IP range is static otherwise every restart of my phone I'd have to enter the IP manually on my car.
But to make it useable for me this would also need the tasker implementation to turn on the hotspot when connect to my car via Bluetooth so yeah ... 🤷‍♂️

@Unnamed3
Copy link

It would be very nice if you implement this feature to reverse these annoying changes that Google made to Android.
I have a case too where I need to update the ip addresses everytime. Before Android 10 and 11, the android Wi-Fi tethering IP address was 192.168.43.0/24, and 192.168.42.0/24 for USB tehrering.
Even the gateway address is now random instead of 192.168.x.1.
Furthermore, this problem wouldn't be as annoying as it is now if the phone would have used its own DNS. But thats not the case, as I already tried. See this thread : https://android.stackexchange.com/questions/230983/the-phone-as-hotspot-doesnt-use-its-own-dns

@seandepagnier
Copy link

It does not add any meaningful security to my local network that is WPA encrypted anyway. I am not going to hijack my own dns. This is an annoying change that makes using android hot spot less convenient.

@Unnamed3
Copy link

Any news on this ? Really want this feature added, thanks

@GhettiGuru
Copy link

GhettiGuru commented Oct 19, 2023

Yes I had a similar issue, I was unable to set a IP address and I had to statically for ethernet for my USBC hub and I've never had the problem before I usually used kali Linux, on my phone as chroot o program routers and stuff before but I hadn't tried it on this device yet. There is no option for setting a static IP address for programming a router or something like I could not manually assign it at all plug up the USBC hub it gets what it gets like I couldn't figure it out for anything I finally gave up and went home and got my PC when I've done this before but not on this device Motorola generally was what I roll though outside of a few htcs the HTC One M8 and U11 other than that I've never had this problem before it's confusing wasn't an option anywhere for ethernet for that, there's a tether by (or hotspot)by ethernet in settings that was the only one I found. I was on Android 12 at the time but since I've taken a 13 update I would have to look, I doubt anything has changed. If there wasn't much trouble implementing a feature where you can assign your own IP ranges and addresses they would be helpful because I needed to give myself, on the host/server device an IP address and I was unable to.

@Mygod
Copy link
Owner

Mygod commented Oct 23, 2023

I think the best way to do this at the moment is to write an Xposed module to hook up relevant methods in IpServer.

@cleanerspam
Copy link

Can we please get this feature , I have read on here and stackexchange that it can be done by some hacky method .
Maybe some way to Permanently set the gateway as 192.168.1.xyz in VPN hotspot app

@worstperson
Copy link

Mygod is right, making a simple Xposed module or framework patcher is for sure the best approach, it's not VPN Hotspot's fault Android does this.

I spent some time to make a patch if you want to try. It's missing GUI options, ideally you'd set an IP per interface, but here it is hardcoded so you can only safely apply to one interface at a time. DNSMasq's pid file should also go into getFilesDir().getPath() rather than /sdcard/.

In be.mygod.vpnhotspot.net.Routing
Near the top I add variables to define the new IP/prefix and redefine hostAddress and hostSubnet so they can be reassigned later on

    val ipv4Addr = "192.168.1.129"
    val ipv4Prefix = ipv4Addr.substring(0, ipv4Addr.lastIndexOf("."))

    //private val hostAddress = try {
    private var hostAddress = try {
        val iface = NetworkInterface.getByName(downstream) ?: error("iface not found")
        val addresses = iface.interfaceAddresses!!.filter { it.address is Inet4Address && it.networkPrefixLength <= 32 }
        if (addresses.size > 1) error("More than one addresses was found: $addresses")
        addresses.first()
    } catch (e: Exception) {
        throw InterfaceNotFoundException(e)
    }
    //private val hostSubnet = "${hostAddress.address.hostAddress}/${hostAddress.networkPrefixLength}"
    private var hostSubnet = "${hostAddress.address.hostAddress}/${hostAddress.networkPrefixLength}"

And create a function to do the override, I placed it right under the function "masquerade"

    fun addressOveride() {
        // Collect the nfmark for the downstream interface
        val markCmd = transaction.execQuiet("iptables-save | grep '\\-i " + downstream + " \\-j MARK \\-\\-set\\-xmark'").out
        val mark = markCmd.substring(markCmd.indexOf("0x300") + 5, markCmd.indexOf("/"));

        // Add a new address to the interface
        transaction.exec("ip address add local " + ipv4Addr + "/24 broadcast " + ipv4Prefix + ".255 scope global dev " + downstream, "ip address del local " + ipv4Addr + "/24 broadcast " + ipv4Prefix + ".255 scope global dev " + downstream)

        // Add route for our address
        transaction.exec("ip route add " + ipv4Prefix + ".0/24 dev " + downstream + " table local_network proto static scope link", "ip route del " + ipv4Prefix + ".0/24 dev " + downstream + " table local_network proto static scope link")

        // Redirect DHCP to our own DNSMasq instance
        transaction.exec("iptables -t nat -A PREROUTING -i " + downstream + " -s 0.0.0.0 -d 255.255.255.255 -p udp --dport 67 -j DNAT --to-destination 255.255.255.255:6767", "iptables -t nat -D PREROUTING -i " + downstream + " -s 0.0.0.0 -d 255.255.255.255 -p udp --dport 67 -j DNAT --to-destination 255.255.255.255:6767")

        // Launch DNSMasq to serve DHCP only, VPN Hotspot does it's own DNS redirect
        transaction.exec("dnsmasq --keep-in-foreground --no-resolv --no-poll --dhcp-authoritative --dhcp-range=" + ipv4Prefix + ".10," + ipv4Prefix + ".99,1h --dhcp-alternate-port=6767,68 --port=0 --dhcp-option-force=43,ANDROID_METERED --listen-mark 0xf00" + mark + " --pid-file=/sdcard/dnsmasq-" + downstream + ".pid >&- 2>&- &", "kill -s 9 \$(cat /sdcard/dnsmasq-" + downstream + ".pid)")
        
        hostAddress = try {
            val iface = NetworkInterface.getByName(downstream) ?: error("iface not found")
            val addresses = iface.interfaceAddresses!!.filter { it.address is Inet4Address && ipv4Addr == it.address.hostAddress!!.toString() }
            if (addresses.size > 1) error("More than one addresses was found: $addresses")
            addresses.first()
        } catch (e: Exception) {
            throw InterfaceNotFoundException(e)
        }
        hostSubnet = "${hostAddress.address.hostAddress}/${hostAddress.networkPrefixLength}"
    }

In be.mygod.vpnhotspot.TetheringService
Add the call to do the override when the Downstream is configured

    private class Downstream(caller: Any, downstream: String, var monitor: Boolean = false) :
            RoutingManager(caller, downstream) {
        override fun Routing.configure() {
            addressOveride()
            forward()
            masquerade(masqueradeMode)
            if (app.pref.getBoolean("service.disableIpv6", true)) disableIpv6()
        }
    }

@Mygod
Copy link
Owner

Mygod commented Feb 18, 2024

Thanks a lot @worstperson! Unfortunately that patch seems to hacky to be merged (and having a way to configure this for multiple tethering interfaces is probably also needed). :)

@Mygod
Copy link
Owner

Mygod commented Feb 20, 2024

@worstperson What do you think of @poqdavid's script in #537? It seems to me that that seems like a better solution than hacking around dnsmasq if it works.

@poqdavid
Copy link

@worstperson What do you think of @poqdavid's script in #537? It seems to me that that seems like a better solution than hacking around dnsmasq if it works.

I have a suggestion maybe we could have both as an option like how IP Masquerade Mode works in the app for more compatibility

@Mygod
Copy link
Owner

Mygod commented Feb 20, 2024

I think it would be ideal to avoid keeping a separate instance of dnsmasq alive.

@worstperson
Copy link

@Mygod
It only supports static configurations, clients that have DHCP enabled will be served addresses from the original range.
It is not reversible(must disable and enable tethering) since it removes the original address from the interface which breaks DNSMasq's port 53 binding.
The 'ndc network route' command is unnecessary since the correct policy routing rules are already in place.

I think it might be better to just add the new address and route to the interface. Clients can use static addresses if they want to operate in that specific range and clients connecting with DHCP will still get a working connection and ip from the original range. Basically just my patch above without the lines to collect the nfmark, redirect DHCP, and spawn DNSMasq.

@Mygod
Copy link
Owner

Mygod commented Feb 21, 2024

Right. If all we want is a stable IP address for the clients to connect to, why not just create a new interface with a static IP (can make it /32 even)? This way we should break virtually zero things.

@worstperson
Copy link

worstperson commented Feb 21, 2024

Ok, scratch that. Added a cidr to the default address and it sets up the address and route correctly now. Still not getting any traffic to pass between the client and phone in either direction though.

@Mygod
Copy link
Owner

Mygod commented Feb 21, 2024

What do you mean? It works fine for me. What do you get if you run ip route get 10.78.2.173 from <client ip> iif <tethering iface>?

EDIT: Also check that ip route show table local displays the correct entry for staticip? Tested again on my phones and seemed fine.

@poqdavid
Copy link

btw with my script DHCP still sends the randomly generated IP is there a way to change or prevent that?

@Mygod
Copy link
Owner

Mygod commented Feb 21, 2024

@poqdavid I did not plan to support that. What is your use case?

@poqdavid
Copy link

@poqdavid I did not plan to support that. What is your use case?

Well, I use my phone's hotspot a lot to connect a lot to the internet and I run things like DNSCrypt, VBAN and it gets really difficult when the IP keeps changing so that's why I been using that script

@Mygod
Copy link
Owner

Mygod commented Feb 21, 2024

Okay but I don't see why you need all the clients to have static IPs?

@poqdavid
Copy link

Okay but I don't see why you need all the clients to have static IPs?

Well, I host things using Termux and every time IP changes, I got to change settings on both my phone and PC

@Mygod
Copy link
Owner

Mygod commented Feb 21, 2024

Just point your clients to the static IP instead and you'll be fine.

@worstperson
Copy link

Sorry for the late reply, was at work. I switched from rndis to wlan for testing today to see if it changes anything. I set Static IP to 10.0.0.1 to make things easier and assigned my computer to 10.0.0.2. Appending a cidr doesn't seem to effect the test results. The tests through wlan have no upstream, ethernet adapter is not available rn and I don't want to setup a reverse tether. Shouldn't matter though.

ocean:/ # ip route get 10.0.0.1 from 10.0.0.2 iif wlan0
local 10.0.0.1 from 10.0.0.2 dev lo table local
cache iif wlan0

ocean:/ # ip route show table local
local 10.0.0.1 dev staticip proto kernel scope host src 10.0.0.1
(truncated)

But no route to my computer

ocean:/ # ip r g 10.0.0.2 f 10.0.0.1 i wlan0
RTNETLINK answers: Network is unreachable

ocean:/ # ip r g 10.0.0.2
RTNETLINK answers: Network is unreachable

ocean:/ # ping -W 3 -c 1 10.0.0.2
connect: Network is unreachable

If I specify the interface it works?!

ocean:/ # ping -W 3 -c 1 -I wlan0 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 192.168.145.106 wlan0: 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=268 ms

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 268.658/268.658/268.658/0.000 ms

Now checking from my computer, I have a route to the phone

[user@SFF-PC ~]$ ip r g 10.0.0.1
10.0.0.1 dev wlp0s20f0u10 src 10.0.0.2 uid 1000
cache

But packets never get a response

[user@SFF-PC ~]$ ping -W 3 -c 1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.

--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms


Testing with another device, this time with rndis0 as the downstream and wlan0 as an upstream

kiev:/ # ping -W 3 -c 1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
From 192.168.42.129: icmp_seq=1 Destination Net Unreachable

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
You can see packets are getting routed to the upstream instead of downstream

Specifying the interface still works

kiev:/ # ping -W 3 -c 1 -I rndis0 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 192.168.115.73 rndis0: 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=1.64 ms

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.646/1.646/1.646/0.000 ms

And still no response from the phone

[user@SFF-PC ~]$ ping -W 3 -c 1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.

--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

@Mygod
Copy link
Owner

Mygod commented Feb 21, 2024

@worstperson You don't assign your computer a static IP. Just use DHCP and connect to the new static IP, for example 10.0.0.1.

@worstperson
Copy link

That works, I see what you were doing now. I didn't realize this was only for running services on the phone lol. Was thinking custom local ranges so I could (for example) block DHCP requests from reaching the phone and serve it on the client that forwards the tether to other devices, but fair enough. This is still a useful feature as-is.

@Mygod
Copy link
Owner

Mygod commented Feb 22, 2024

@worstperson Yes. Not sure why you would want to do that. If there is a reasonable use case, I can consider supporting it.

@worstperson
Copy link

worstperson commented Feb 22, 2024

The idea is to let me run servers with known fixed addresses from any arbitrary device(could be nfs or a webserver or a webclient for a torrent client, or any number of things) on my local network. DHCP was my example because I could use it to assign static addresses to devices on my network without having to set their network configuration. DoH/DoT servers and network wide adblocking are other great applications. If you additionally gave the option to drop DHCP requests from the static subnet in the app, it'd make it easy to just bridge the tether interface to ethernet in Windows and let any old router on the network provide that service.

But me personally, I'd just patch the framework and be done with it. It's not a big ask to just diy it from my point of view. What you've already implemented is great and I'm perfectly happy leaving it there.

@cleanerspam
Copy link

But me personally, I'd just patch the framework and be done with it. It's not a big ask to just diy it from my point of view. What you've already implemented is great and I'm perfectly happy leaving it there.

Please post the link of Lsposed(xposed) module if you build it to bypass this silly restriction of Android

@bohaman1
Copy link

bohaman1 commented Jan 9, 2025

May I ask how I can use the static IP toggle to get it working? I cannot keep my client on a static IP as it will always use the advertised IP address from the assigned IP address range since it is a dashcam. I was able to test on my desktop using a randomly assigned IP address (192.168.xxx.205), which is different from the advertised IP address from my phone hotspot, and was still able to connect. However, I was hoping to prevent the advertised IP address from my phone from changing as well. I've tried other tricks with Macrodroid and set the IP address in wlan2 as the static IP address, and it actually showed up, but since the advertised IP address takes precedence and I cannot delete the already established connection from my phone, my device still connects to the dynamic IP range. I hope someone can help guide me in the right direction. I'm more than happy to buy you a coffee or something. Thank you for your time.

@Mygod
Copy link
Owner

Mygod commented Jan 9, 2025

@bohaman1 Static IP is only for the hotspot device. What's your use case for giving clients static IP?

@bohaman1
Copy link

bohaman1 commented Jan 9, 2025

@bohaman1 Static IP is only for the hotspot device. What's your use case for giving clients static IP?

Hello,

Thank you so much for your reply. Oh I see, the static IP is only work if my phone is connect to a different network to repeat it. The reason I was hoping to keep the phone hotspot with a static range of IP to help me not have to update my client device if incase the phone need to be rebooted. Dashcam > phone hotspot > tailscale node > home network > PC (blue iris) to get the rtsp stream from my dashcam. Everything worked really well but it just everytime the phone is rebooted the 192.168.xxx.yyy/16 kept changing and I know this is an implementation of the new android system but I was hoping if there is a fix yet. I couldn't do a static IP on my dashcam since it is a closed system and there is very limited setting. I may just have to add an rpi in the middle since I really couldn't find a simple solution yet.

Thank you for your time

@Mygod
Copy link
Owner

Mygod commented Jan 9, 2025

How about this? #638 (comment)

@bohaman1
Copy link

How about this? #638 (comment)

I am sorry I'm a little bit confuse about this. do you mean I created a hotspot on my phone using the app and use the repeater function to connect my phone hotspot and then broadcast it again? I apologize if I misunderstood.

May I also ask for how can I autoactive the toggle after the wifi hotspot or the usb hotspot started and the device is connected? usually when the hotspot start and the device connect one more line appeared above the manage system tethering I have to toggle that manual for my devices to get internet.

I'm really thankful for your time to help me with this.

@Mygod
Copy link
Owner

Mygod commented Jan 10, 2025

There is a "Repeater" switch in this app (at the very top, above the "Static IP" switch). Try to use that, which should give you a static IP range.

May I also ask for how can I autoactive the toggle after the wifi hotspot or the usb hotspot started and the device is connected? usually when the hotspot start and the device connect one more line appeared above the manage system tethering I have to toggle that manual for my devices to get internet.

Use the monitor feature. Click the eye icon top right after hotspot is started.

@bohaman1
Copy link

bohaman1 commented Jan 11, 2025

There is a "Repeater" switch in this app (at the very top, above the "Static IP" switch). Try to use that, which should give you a static IP range.

May I also ask for how can I autoactive the toggle after the wifi hotspot or the usb hotspot started and the device is connected? usually when the hotspot start and the device connect one more line appeared above the manage system tethering I have to toggle that manual for my devices to get internet.

Use the monitor feature. Click the eye icon top right after hotspot is started.

Hello,

Thanks for your reply.

I just had to edited because I got it working, thank you so much for an amazing app. I didn't know I can do that. I thought I have to connect to a wifi first before I can use repeater function. May I ask if you know any app that can automate the repeater function like turning it on like tether when plug in ? Thank you so much for your time.

Edit 2: I was able to see the toggle for the saved setting and after reboot it when back straight to the repeater. It is amazing.

May I ask if I set up something wrong ? When I'm on tether mode my connected device were able to connect the vpn Tailscale on my phone however with the repeater mode when my end device connect it doesn't has my phone vpn connection like when my phone in hotspot mode. May I ask if I need to do something to get it fix? Thank you for your time.

@Mygod
Copy link
Owner

Mygod commented Jan 11, 2025

May I ask if I set up something wrong ? When I'm on tether mode my connected device were able to connect the vpn Tailscale on my phone however with the repeater mode when my end device connect it doesn't has my phone vpn connection like when my phone in hotspot mode. May I ask if I need to do something to get it fix? Thank you for your time.

Do your clients get to access network without VPN or no Internet at all? Try "clean/reapply rules" and if that still doesn't work, describe what happened and export debug information.

@bohaman1
Copy link

bohaman1 commented Jan 11, 2025

May I ask if I set up something wrong ? When I'm on tether mode my connected device were able to connect the vpn Tailscale on my phone however with the repeater mode when my end device connect it doesn't has my phone vpn connection like when my phone in hotspot mode. May I ask if I need to do something to get it fix? Thank you for your time.

Do your clients get to access network without VPN or no Internet at all? Try "clean/reapply rules" and if that still doesn't work, describe what happened and export debug information.

My client can connect internet it just doesn't share the "Tailscale" vpn connection like when I have hotspot on.

I have tried to do the clean/reapply rules but it didn't help.

Edit 1: for some reason I think it fixed itself, I remove and reinstalled Tailscale, and I think my end device is using vpn server from my phone. It is a little bit slower compare to when I access it from my phone directly but I think it worked !!

@worstperson
Copy link

worstperson commented Jan 11, 2025

It's always possible to patch Android to revert to pre-Android 11 behavior without recompiling Android. The file currently responsible for this is /apex/com.android.tethering/priv-app/Tethering*/Tethering*.apk under com/android/networkstack/tethering/PrivateAddressCoordinator.java requestDownstreamAddress(). After unpacking with apktool you can patch in extra checks for TETHERING_WIFI and TETHERING_USB at the beginning of the function something like this

.method public requestDownstreamAddress(Landroid/net/ip/IpServer;IZ)Landroid/net/LinkAddress;
    .locals 5

    invoke-virtual { p1 }, Landroid/net/ip/IpServer;->interfaceType()I
    move-result v0
    const/4 v1, 1
    if-ne v0, v1, :label_0
    new-instance p0, Landroid/net/LinkAddress;
    const-string p1, "192.168.42.1/24"
    invoke-direct { p0, p1 }, Landroid/net/LinkAddress;-><init>(Ljava/lang/String;)V
    return-object p0
    :label_0
    invoke-virtual { p1 }, Landroid/net/ip/IpServer;->interfaceType()I
    move-result v0
    const/4 v1, 0
    if-ne v0, v1, :label_1
    new-instance p0, Landroid/net/LinkAddress;
    const-string p1, "192.168.43.1/24"
    invoke-direct { p0, p1 }, Landroid/net/LinkAddress;-><init>(Ljava/lang/String;)V
    return-object p0
    :label_1

Then zipalign the resulting apk and copy the signatures over from the original package

zipalign  -p -v 4 TetheringNext_patched.apk TetheringNext_aligned.apk
apksigcopier copy TetheringNext_org.apk TetheringNext_aligned.apk TetheringNext.apk

Finally, to use it, make a Magisk module with a post-fs-data.sh script to bind mount over the original

#!/system/bin/sh
MODDIR=${0%/*}

mount -o ro,bind $MODDIR/TetheringNext.apk /apex/com.android.tethering/priv-app/TetheringNext@AP2A.240805.005/TetheringNext.apk

The system doesn't even bother to verify the signature, but if it did, there is always the LuckyPatcher system signature patch to bypass it.

@bohaman1
Copy link

It's always possible to patch Android to revert to pre-Android 11 behavior without recompiling Android. The file currently responsible for this is /apex/com.android.tethering/priv-app/Tethering*/Tethering*.apk under com/android/networkstack/tethering/PrivateAddressCoordinator.java requestDownstreamAddress(). After unpacking with apktool you can patch in extra checks for TETHERING_WIFI and TETHERING_USB at the beginning of the function something like this

.method public requestDownstreamAddress(Landroid/net/ip/IpServer;IZ)Landroid/net/LinkAddress;
    .locals 5

    invoke-virtual { p1 }, Landroid/net/ip/IpServer;->interfaceType()I
    move-result v0
    const/4 v1, 1
    if-ne v0, v1, :label_0
    new-instance p0, Landroid/net/LinkAddress;
    const-string p1, "192.168.42.1/24"
    invoke-direct { p0, p1 }, Landroid/net/LinkAddress;-><init>(Ljava/lang/String;)V
    return-object p0
    :label_0
    invoke-virtual { p1 }, Landroid/net/ip/IpServer;->interfaceType()I
    move-result v0
    const/4 v1, 0
    if-ne v0, v1, :label_1
    new-instance p0, Landroid/net/LinkAddress;
    const-string p1, "192.168.43.1/24"
    invoke-direct { p0, p1 }, Landroid/net/LinkAddress;-><init>(Ljava/lang/String;)V
    return-object p0
    :label_1

Then zipalign the resulting apk and copy the signatures over from the original package

zipalign  -p -v 4 TetheringNext_patched.apk TetheringNext_aligned.apk
apksigcopier copy TetheringNext_org.apk TetheringNext_aligned.apk TetheringNext.apk

Finally, to use it, make a Magisk module with a post-fs-data.sh script to bind mount over the original

#!/system/bin/sh
MODDIR=${0%/*}

mount -o ro,bind $MODDIR/TetheringNext.apk /apex/com.android.tethering/priv-app/TetheringNext@AP2A.240805.005/TetheringNext.apk

The system doesn't even bother to verify the signature, but if it did, there is always the LuckyPatcher system signature patch to bypass it.

Thank you so much for helping me with this guide. However, this is a little bit too complex for me and I didn't know how to start. But I was able to just use the repeater feature in the app and it worked. It started with a static ip xxx.xxx.49.x. However, I think the repeater function disabled itself after 48 hours. May I ask if there is a way for me to allow the repeater to not turn off itself? Thank you so much for your time.

@GhettiGuru
Copy link

It's always possible to patch Android to revert to pre-Android 11 behavior without recompiling Android.

Any idea if it's possible and what lines one would need to add for static tether by Ethernet? I have a USB c hub with Ethernet I would like to hotspot my phone to a Ethernet only device using a set and static IP, and as far as I'm aware android 14 (Red magic OS actually) has no settings at all for Ethernet. Also the xposed module called core patch would probably fair better for letting you overwrite system app signatures than lucky patcher, lp patch can have a wonky effects on later Android versions. I've lost Bluetooth connectivity once, and once on 12 it acted as though my sim card wasn't inserted as long as xposed was on to apply lp patch. The module hooks framework a little smoother and easier to disable lol

@worstperson
Copy link

worstperson commented Jan 21, 2025

Any idea if it's possible and what lines one would need to add for static tether by Ethernet?

Instead of comparing against a const of 0 for wifi or 1 for usb, compare against 5 for ethernet.

Also the xposed module called core patch would probably fair better for letting you overwrite system app signatures than lucky patcher, lp patch can have a wonky effects on later Android versions.

It's not required since Android doesn't verify the signature (it already did before extracting the apex archive), but even so, it takes more effort to support the MicroG patches. Defeats the purpose of an example meant to be concise.

Patching is kind of a waste of time if your just going to use Xposed anyway since it's trivial to just spin up a module to do it for you. I made an example here that supports Android (AOSP) 12-15. I didn't bother supporting Android 11 or implementing settings. LSPosed is also ignoring my scope (since I'm using the legacy api ig) so the Tethering app needs to be manually selected from the list. But it works and was easy to do.

@Mygod
Copy link
Owner

Mygod commented Jan 21, 2025

@worstperson LSPosed scope can be done like such: https://github.com/Xposed-Modules-Repo/be.mygod.oplus.batterywaster/blob/eadcbdaaf3869025d127dfcbd839fe17d8999cb8/app/src/main/res/values/arrays.xml#L3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants