

  • 3









// usb client will be provided
private static final String USB_NEAR_IFACE_ADDR      = "";
private static final String USB_NETMASK              = "";

// FYI - the default wifi is and

private String[] mDhcpRange;
private static final String DHCP_DEFAULT_RANGE1_START = "";
private static final String DHCP_DEFAULT_RANGE1_STOP  = "";
private static final String DHCP_DEFAULT_RANGE2_START = "";
private static final String DHCP_DEFAULT_RANGE2_STOP  = "";

And Later on we see those ranges used, AS BACKUPS.

    mDhcpRange = context.getResources().getStringArray(
        mDhcpRange = new String[4];
        mDhcpRange[0] = DHCP_DEFAULT_RANGE1_START;
        mDhcpRange[1] = DHCP_DEFAULT_RANGE1_STOP;
        mDhcpRange[2] = DHCP_DEFAULT_RANGE2_START;
        mDhcpRange[3] = DHCP_DEFAULT_RANGE2_STOP;




Look for <array name="config_tether_dhcp_range" />

Change to:

<string-array name="config_tether_dhcp_range">





  • 2
  • 1





NOTE: Root is required.

Default DHCP IP address range is hard-coded (1), you can't change it without rebuilding ROM with modified source code. Or use a little hack.

When you switch on tethering, what happens (at least):

  • hostapd - the daemon which manages access points - is started.
  • Network interfaces are set up, IP address is added to Wi-Fi interface (hard-coded before Android Pie (2, 3), randomized afterwards (4)), and routing table is added (5) for local network (6).
  • dnsmasq - the DHCP/DNS server (up to Pie) - is started with hard-coded commandline arguments (7) (which can be set through /etc/dnsmasq.conf (8) otherwise).

So we can replace /system/bin/dnsmasq with a custom shell script, taking control of the process in between. Rename the original binary to something else:

# mv /system/bin/dnsmasq /system/bin/dnsmasq.bin

Create script /system/bin/dnsmasq:



export PATH=/system/bin

# delete old route, add new
ip route del ${OLD_SUBNET}.0/24 dev ${WIFI_INTERFACE} table $LOCAL_TABLE
ip route add ${NEW_SUBNET}.0/24 dev ${WIFI_INTERFACE} table $LOCAL_TABLE

# set new IP address on Wi-Fi interface
ip address add ${NEW_SUBNET}.1/24 dev $WIFI_INTERFACE

# inject new subnet in hard-coded arguments received from netd
set -- $(printf '%s' "$*" | sed 's/'${OLD_SUBNET}'/'${NEW_SUBNET}'/g')

# execute original binary with new arguments
exec dnsmasq.bin $*

Confirm the name of your Wi-Fi interface (wlan0 usually). Check with ip link or ls /sys/class/net/.

Also confirm your local network routing table is 97: grep local_network /data/misc/net/rt_tables. Android's routing is a mess, getting more complex with every new release. So I'm not sure if this has been persistent or not. Also before making any changes, check your routing policies and tables to figure out what you should put in your script:

~# RULES="$(ip rule | grep -vE 'unreachable|local')"
~# echo "$RULES"
~# for t in $(echo "$RULES" | awk '{print $NF}' | uniq); do ip r s table $t; done

SELinux rules also need to be defined if (all or some) not already defined and if status is enforcing. Use Magisk's suploicy or some other similar tool like sepolicy-inject:

# execute binaries from /system/bin
allow netd system_file dir { read open getattr search }
allow netd system_file file { read gettattr open execute execute_no_trans }

# execute /system/bin/sh
allow netd shell_exec file { read getattr open execute execute_no_trans }

# execute /system/bin/toolbox and its applets
allow netd toolbox_exec file { read gettattr open execute execute_no_trans }

# configure RPDB rules / routing tables
allow netd netd capability { sys_admin }

* not persistent across reboots, use some init.d script or replace /sepolicy in ramdisk

Set permissions on files:

~# chown 0.0 /system/bin/dnsmasq*
~# chmod 0755 /system/bin/dnsmasq*
~# chcon u:object_r:dnsmasq_exec:s0 /system/bin/dnsmasq*


Or you can setup complete tethering from commandline, running your own processes. This answer includes the instructions, though the question is different.


Your Answer

