abstract
- question
- Can you change an Android phone's public IP from a PC alone, over ADB, without root?
- method
- Measure the public IP, change the network state over ADB, wait for it to reconnect, measure again, and keep the radio logs of every attempt
- result
- With
settings put global airplane_mode_on, no; withcmd connectivity airplane-mode, yes. Real test: new IP on the first try, in 20 s - limits
- One phone (Redmi Note 13 Pro+, Android 16) and one carrier (Claro Colombia). Under CGNAT, a new IP isn't guaranteed on every cycle
The question was a concrete one: can you change an Android phone's public IP from a PC alone, over ADB, without root? A lot of people take it for granted that airplane mode always gets you a new IP, and I wanted to check that with evidence
What people believe
The idea gets around a lot: if you want another IP, turn airplane mode on for a few seconds and turn it off again. And it often works, which is why people keep repeating it. The problem is the «always»: sometimes the IP comes back the same, and not always for the same reason
What actually happens
To understand it you have to separate two IPs that tend to get mixed up. When the phone uses mobile data, it opens a data session with the carrier's network (in LTE it's called a PDN connection), and the core of that network assigns it an IP. With many carriers that IP is private: the phone doesn't reach the internet with it, but through a CGNAT, a carrier-side NAT that shares a few public IPs among a huge number of users
phone
│ data session
▼
tower ──► carrier core
│ assigns a private IP (for example 10.x.x.x or 100.64.x.x)
▼
CGNAT
│ translates it to a shared public IP
▼
what the internet sees: 190.130.xxx.204The 100.64.0.0/10 range exists precisely for this: RFC 6598 reserved it for the space between a carrier and its CGNAT. And RFC 6888 requires that, by default, a CGNAT keep the same public IP for the same internal IP while it's in use («paired pooling»), so a user's connections don't go out through different addresses
When airplane mode really powers the radio off, that session closes. When it comes back, the phone opens a new session and the carrier assigns it an IP again, usually a different one. But what the internet sees depends on which public address the CGNAT hands it: it may be a new one, or the same one as before
That's why the result isn't guaranteed. There are at least three reasons for the IP to come back the same:
- The radio didn't really go off. If only a setting changes, the session stays open and the carrier has no reason to give you another IP. That's exactly what happened in my first attempt
- The CGNAT gives you the same public IP again. The session is new, but the shared address you get can repeat
- What's being measured isn't the mobile network. If Wi-Fi is still on, traffic goes out through the home internet, and that IP won't change no matter how many times you toggle airplane mode
ideaIn short: airplane mode isn't what changes the IP. What can change it is the data session closing and a new one opening; airplane mode is just one way to trigger that, and it doesn't always manage to
The first attempt
IP Rotator's modes A and B used this:
$ adb shell settings put global airplane_mode_on 1It looked like it worked, because the setting changed. But the radio logs (logcat -b radio) told a different story: the radio never let go of the tower. The command only flipped a stored value, so the carrier kept the same CGNAT session and the same IP
In December 2025 the verdict went into the v0.1.0 README: ADB couldn't do it without system permissions
The right command
Six months later, while I was building Goket (my network panel), Claude found another way:
$ adb shell cmd connectivity airplane-mode enable $ adb shell cmd connectivity airplane-mode disable
The difference is the path it takes. This command goes through ConnectivityService, the same path as the system toggle, and it really powers the radio off. It works without root since Android 12. On Android 16, the old AIRPLANE_MODE broadcast can't even be sent from ADB anymore: it throws SecurityException
The details that mattered
The command alone wasn't enough. It took three more things:
- The phone's Wi-Fi is switched off during the test (
svc wifi disable). Otherwise tethering goes out through the home internet and the measured IP isn't the carrier's - Under CGNAT a new IP isn't guaranteed on the first try, so it repeats short cycles: 7 s off, 12 s to settle, up to 5 times
- The IP is measured through the tethering interface (
curl --interface), so the PC never loses its own internet
In the real test on September 30, 2026, the IP changed on the first try, in 20 s. It shipped as v0.2.0
Other ideas, untested
If what changes the IP is the data session closing and a new one opening, airplane mode shouldn't be the only way. Two ideas I'm writing down, not tested yet:
- Turning only mobile data off and on. It would close the data session without powering off the whole radio, and it might be faster than a full airplane-mode cycle
- Switching the preferred network type. Going from 5G or 4G down to 3G and back would make the phone register with the network again, and so open a new session
If either one works, it would need to be checked the same way as airplane mode: measure the IP before and after, and look at the radio logs
Limits
- What was measured comes from a single phone and a single carrier. Another carrier may assign IPs differently, or even give a fixed IP per line
- How many cycles it takes to get a new IP depends on the carrier's CGNAT; the 5 attempts are a practical cap, not a number measured in general
- The two ideas above are hypotheses: there's no data yet
What stuck with me
December's verdict was true for that command: with it, it really couldn't be done. What was wrong was treating the question as closed when what had failed was the tool. And it was the radio logs, not intuition, that showed where the problem was
Frequently asked questions
Does airplane mode change your IP?
Sometimes. If the radio really goes off, the data session closes and the carrier assigns another IP when it comes back, but under CGNAT the public IP the internet sees can repeat. And if Wi-Fi is on, what you're measuring is your home IP, which doesn't change
Why doesn't my IP change when I turn on airplane mode?
The three most common causes: Wi-Fi was still connected, the carrier's CGNAT gave you the same public IP again, or the method didn't really turn the radio off (for example, flipping the airplane_mode_on setting over ADB)
What is CGNAT?
A NAT run by the carrier: many customers get a private IP and reach the internet sharing a few public IPs. That's why the IP a website sees isn't the one your phone has
How do you change an Android phone's IP from a PC without root?
Over ADB, with cmd connectivity airplane-mode enable and then disable, which goes through the system connectivity service and really turns the radio off. Turn the phone's Wi-Fi off during the test and repeat the cycle if the IP comes back the same
What ways are there to rotate a phone's IP?
The one tested in this note is a real airplane-mode cycle over ADB. Other ideas, not tested yet, are turning only mobile data off and on, or switching the preferred network type to force a new registration
References
- RFC 6888 · Common Requirements for Carrier-Grade NATs (CGNs) · rfc-editor.org/rfc/rfc6888
- RFC 6598 · IANA-Reserved IPv4 Prefix for Shared Address Space (100.64.0.0/10) · rfc-editor.org/rfc/rfc6598
- 3GPP TS 23.401 · GPRS enhancements for E-UTRAN access (PDN connections in LTE)
- Android Debug Bridge (adb) · official documentation · developer.android.com/tools/adb
- Nuulz/android-ip-rotator-adb · source code and v0.2.0 · github.com/Nuulz/android-ip-rotator-adb