27

When connecting my PC to Android Wi-Fi hotspot, it assigned a 192.168.42.x address to my PC. I really need to change this as it conflicts with one of our work subnets - is this possible?

  • 2
    My mobile is rooted. I don't mind changing system files if required. – VVK Jun 4 '13 at 5:20
  • Just as response to nuances in some of the above great answers, in my practice the 192.168.43.0/24 range is by Android/vendor default assigned for WiFi tethering and 192.168.42.0/24 is for USB tethering. – Jim Klimov May 29 '17 at 5:39
25

Unfortunately, there is no way to change the IP address range for the builtin tethering support, even in CyanogenMod. The Wi-Fi hotspot IP is hardcoded in android.net.wifi.WifiStateMachine.startTethering(); the USB tethering IP is hardcoded in com.android.server.connectivity.Tethering.

However, if your phone is rooted, you can try using third-party apps for tethering which have the option to change the IP address range. E.g., when the builtin USB tethering was broken in CyanogenMod alphas for Samsung Galaxy W, I used Wired Tether for Root Users, which has such option. For Wi-Fi tethering you can try the Wireless Tether for Root Users app from the same authors, which also has the option to change the IP address range.


Because Google Code was shut down, the above links no longer work. Some people exported the source code from those repositories to GitHub:

However, there was no further development activity, and the apps probably no longer work on recent Android versions.

Just in case someone wants to try those obsolete apps, I have been able to find some APK files in the Google Code Archive:

  • +1 for the info. My device is rooted, but Wireless Tether for Root Users app is not working on my mobile. There should be some way to change the IP range on the rooted phone, C'Mon Man!, Android is an open OS after all. – VVK Jun 4 '13 at 5:18
  • @VVK There is a way. Just recompile the source. – Syakur Rahman Nov 29 '16 at 10:51
  • The apps you mention seem to no longer exist. Can you find any new versions online, since you know the name of the publishers? I found some others, but none of them was free... – pgr Oct 27 '17 at 17:53
  • @pgr Found some working links, but no newer versions. – Sergey Vlasov Oct 30 '17 at 7:17
20

The Android builtin wifi tethering is designed to use 192.168.43.1/24 as the server, with netd handling the tethering, using dnsmasq. First DNS range is 192.168.42.1-254 and and 2nd DNS range is 192.168.43.1-254.

Netd is not easy to change. It requires a socket to communicate with it, and that socket is taken when android starts tethering. But going through the source files for Tethering.java (I used Froyo) we see:

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

// FYI - the default wifi is 192.168.43.1 and 255.255.255.0

private String[] mDhcpRange;
private static final String DHCP_DEFAULT_RANGE1_START = "192.168.42.2";
private static final String DHCP_DEFAULT_RANGE1_STOP  = "192.168.42.254";
private static final String DHCP_DEFAULT_RANGE2_START = "192.168.43.2";
private static final String DHCP_DEFAULT_RANGE2_STOP  = "192.168.43.254";

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

    mDhcpRange = context.getResources().getStringArray(
            com.android.internal.R.array.config_tether_dhcp_range);
    if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) {
        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;
    }

The main source for the dhcp ranges is not the hardcoded 42 and 43, but read from array.config_tether_dhcp_range, an internal string array. But it is currently empty.

You could edit the android framework. On my phone, it is /system/framework/framework-res.apk. There are a ton of tutorials online for editing framework-res.apk, from simple strings to full theming. Find one for your phone and android version.

Main thing you want to change is the /res/values/arrays.xml

Look for <array name="config_tether_dhcp_range" />

Change to:

<string-array name="config_tether_dhcp_range">
     <item>192.168.x.y</item>
     <item>192.168.x.z</item>
</string-array>

compile/zip/sign as needed (follow a tutorial), then reinstall.

If you want more than one range, just copy the two items over and over. You always need to provide a start and a stop for each range. Try to keep it in the same /24, ie 192.168.50.5 and 192.168.50.99 or whatever. You can confirm it is working with busybox ps | grep dnsmasq or if you don't have busybox ps dnsmasq then use the pid in cat /proc/pid/cmdline. You should get (or similar):

/system/bin/dnsmasq --no-daemon --no-poll -no-resolv --dhcp-range=192.168.50.5,192.168.50.99,1h

FWIW, my WIFI tethering uses the default dnsmasq ranges, yet my computer was assigned 192.168.43.147/24 and gateway 192.168.43.1/24. Not sure why yours defaulted to a 42.x address.

  • 1
    42 is for USBNET 43 is for wifi – Zibri Jul 6 '18 at 15:19
  • nice find, where you see that? – cde Jul 6 '18 at 17:35
  • Because if you tether by usb you get 42. If you tether by wifi you get 43. – Zibri Jul 7 '18 at 18:57
5

I know this is an old post, but thought I would provide an update. It appears some manufacturers and versions of Android now DO allow for the changing of the IP subnet range for the DHCP server through the UI when using WiFi hotspot feature. Here's where to find it on an HTC One M8 running Android 6.0. YMMV.

From the Mobile Hotspot screen, click the 3 dots icon (more), go to Advanced, then LAN settings. Under "Local IP" change the IP address to your desired IP. Under "Local DHCP" change the starting IP to match the subnet of your IP address.

Trent

  • Do you know if new HTC phones also have this option? – Arya Aug 22 '18 at 2:05
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:

#!/system/bin/sh

OLD_SUBNET='192.168.43'
NEW_SUBNET='192.168.1'
WIFI_INTERFACE='wlan0'
LOCAL_TABLE='97'

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')
unset OLD_SUBNET NEW_SUBNET WIFI_INTERFACE LOCAL_TABLE

# 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*

Enjoy!

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

RELATED:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.