3

Background

I have a local network and I want to have my mobile serve as an internet gateway when entering the network.

What I'm asking is asked here, here and here. An advanced version has also been asked here but all of them have no answers leading me to a conclusion this might not be possible. With this post, trying to list down what I tried, problems faced so as to open a discussion for a possible solution to this problem. Have tried this with relatively recent android 9, 10 and 11.

Some obvious steps

  • Have static IP for the mobile which will serve as a gateway.
  • Setup router to use the gateway.

Problems

  • Android connects to wifi and gives a warning that access point doesn't have internet access. We can switch to mobile data but the local network is inaccessible as wifi is disconnected. Changing to always use mobile data in developer options also behaves the same.
  • Let's suppose android is used as gateway and other devices are able to access internet, how will the device access local network? A probable solution is to make a middleware that decides to send packets to internet or intranet, or perhaps use internet as a fallback. I'm pretty sure mobile will need to be rooted for this kind of control. Is there anything developed which can be used directly?
3
  • You don't need a middleware. While already connected to Mobile Data, on a rooted device, connect to the WiFi network manually from commandline (and not let the Android decide which network interface it should select as the default gateway) and then also set routing table and IP forwarding manually (using ip and iptables commands). I've used my Android device for years this way to avoid the burden of hotspot on battery life. Commented May 6, 2021 at 20:30
  • 1
    An even more complicated but robust solution: How to assign Mobile Data's public IP to host connected on hotspot? (one of my most researched and lengthy answers but the least recognized ;). You can connect to an existing WiFi network instead of creating hotspot. That won't make much difference in the overall approach. Commented May 6, 2021 at 20:32
  • Your problem description is still very high-level and unclear what you actually did. We can help you best if you explain all the details what you configured on the different devices. This means the IP addresses you have set-up, configured gateway and so on. Just posting "does not work" will not get you closer to a solution. Please edit your question and add those details.
    – Robert
    Commented May 6, 2021 at 20:33

1 Answer 1

3

With some help from the answers by @Irfan Latif linked in the comment and here, and by examining the output of iptables -L and iptables -t nat -L in various scenarios like Hotspot, BT tethering, USB tethering etc., I managed to write a script that helps me to share my mobile data connection to the local Wi-Fi network by using a static IP for the phone, and setting it as the gateway in the Wi-Fi router or in individual devices.

Here is the script I wrote, it must be run in a root shell or by prefixing su -c:

#!/bin/sh

echo "(Re-)creating iptables NAT and Forward rules..."
for i in 0 1 2 3 4 5 6 7 8 9 10 ; do
        iptables -t nat -D POSTROUTING -o rmnet_data$i -j MASQUERADE
        iptables -t nat -I POSTROUTING -o rmnet_data$i -j MASQUERADE

        iptables -D FORWARD -i rmnet_data$i -o wlan0 -m state --state RELATED,ESTABLISHED
        iptables -D FORWARD -i rmnet_data$i -o wlan0 -j ACCEPT
        iptables -D FORWARD -i wlan0 -o rmnet_data$i -j ACCEPT
        #iptables -D FORWARD -i wlan0 -o rmnet_data$i -m state --state INVALID -j DROP

        iptables -I FORWARD -i rmnet_data$i -o wlan0 -m state --state RELATED,ESTABLISHED
        iptables -I FORWARD -i rmnet_data$i -o wlan0 -j ACCEPT
        iptables -I FORWARD -i wlan0 -o rmnet_data$i -j ACCEPT
        #iptables -I FORWARD -i wlan0 -o rmnet_data$i -m state --state INVALID -j DROP
done

echo "Enabling forwarding for wlan and rmnet_data interfaces..."
echo 1 >/proc/sys/net/ipv4/conf/wlan0/forwarding
echo 1 >/proc/sys/net/ipv6/conf/wlan0/forwarding
for i in 0 1 2 3 4 5 6 7 8 9 10 ; do
        echo 1 >/proc/sys/net/ipv4/conf/rmnet_data$i/forwarding
        echo 1 >/proc/sys/net/ipv6/conf/rmnet_data$i/forwarding
done

echo "Emptying the main route table..."
ip route flush table main

echo "Copying rmnet_data interface routes to main table..."
IFS=$'\n'; for i in $(
        ip route show table all |
        grep "table rmnet_data" |
        grep -v "expires" |
        sed -Er 's/table rmnet_data[0-9]* /table main /g'
); do
        eval "ip route add $i"
done

echo "Copying wifi interface routes to main table (except default)..."
ip route del default table wlan0
IFS=$'\n'; for i in $( ip route show table wlan0 | grep -vE 'expires|default' ); do
        eval "ip route add $i table main"
done

echo "Replacing lookup routes for main table..."
while ip rule del from all lookup main ; do "" ; done 2>/dev/null
ip rule add lookup main

echo "Clearing routing cache..."
ip route flush cache

(I don't usually write shell scripts, so some things might not be the best here 🙃)


Some notes and assumptions:

  1. I have only tested this on a rooted Android 10 phone running MIUI 12, not sure if it works for others.

  2. In the Developer options of the phone, I have the Mobile data always active setting switched on, to prevent turning off mobile data when Wi-Fi is connected.

  3. I've written the script such that I am also able to continue accessing devices on the local Wi-Fi network while acting as a gateway. The icon in the status bar might wrongly indicate that Wi-Fi is being used for internet, however it can be verified in a browser, that mobile data is being used for internet.

  4. The changes done by this script are not permanent. When Wi-Fi or mobile data disconnects or if USB tethering / Wi-Fi hotspot / BT tethering is toggled, some of the above changes are removed by Android and the script has to be run again. This can be automated using apps like Automate / Tasker. 😉

  5. Mobile data interfaces: In the output of ip addr, I see that my (dual-SIM Qualcomm modem) phone has 11 interfaces named rmnet_data0..10 and 9 interfaces named r_rmnet_data0..8. I wasn't sure which one is responsible for mobile data. On toggling airplane mode on/off multiple times, I saw that r_rmnet_data never gets assigned an address but the phone randomly picks 2 interfaces from the 11 rmnet_data interfaces and assigns an IPv4 and v6 address to them (I guess SIM 1 uses the first 5, and SIM 2 uses the rest 5 but I'm not sure).
    For the sake of simplicity, I decided to enable forwarding for all the interfaces. The names of interfaces might vary for different devices, so the for loops in the above script will need to be adjusted/removed accordingly.

  6. The name of the Wi-Fi interface was wlan0 on my phone. It might be different for others, and hence will need to be adjusted in the above script.

  7. Wrong data usage counters: The data usage counters in Android settings might not show any account of the mobile data used by Wi-Fi devices in this manner, or the total data usage counter might not match with the sum of data usage counts of all apps. I believe this can be fixed by using the tetherctrl_FORWARD chain instead of FORWARD to make it count this usage as mobile hotspots, but am yet to try this out.

  8. Although I have enabled forwarding for IPv6 in the above script, I have not been able to find out how to either propogate the delegated prefix to devices on the local Wi-Fi network or use the phone as an IPv6 NAT gateway (not even sure if Android supports this). I'm currently happy with just IPv4, so I might not update the script for IPv6, unless someone is interested (comment please).

  9. Battery drain: The battery of the phone drains considerably when using it as a gateway with the above script, just as it does while using Wi-Fi hotspot.

3
  • Tip: If the removal of the default route on the Wi-Fi interface (as done in my script) does not work as expected, you might have better luck setting an invalid/non-existent device IP address as the gateway in Android Wi-Fi settings, to force Android to detect that an internet connection is not available on Wi-Fi Commented May 7, 2022 at 11:30
  • Unable to get this working on Android 12 (MIUI 13) :(
    – Oenotria
    Commented Jun 11, 2022 at 14:36
  • @Oenotria I might be able to help you if you provide more details. Did you check the name of your mobile data and WiFi interfaces? Did you try manually adding the routes and iptables rules for a single interface (which has been assigned an IP address by mobile data) first, in the phone's shell? What is the observed behaviour? Commented Jun 12, 2022 at 5:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .