0

I'm trying to fix the IP address of my Pi Zero W when it connects to my mobile phone hotspot.

From what I have gathered, the way to do this would be to specify a static ip_address entry in /etc/dhcpcd.conf. The problem is that the gateway IP changes every time, so I can't set the static routers entry.

# My network
ssid MYHOTSPOT
static ip_address=192.168.1.101/24
# static routers=<IP changes everytime>
# static domain_name_servers=<IP changes everytime>

I tried leaving the router entry blank, but doing so meant that my Pi wouldn't be able to access the internet since there is no gateway specified.

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.43.0    0.0.0.0         255.255.255.0   U     302    0        0 wlan0

Am I looking in the wrong place? I'd appreciate some pointers.

9
  • Since the mobile phones hotspot ip address is in the 192.168.43.x subnet, creating a static 192.168.1.x address is doomed to failure - also, what if the phone picks the same 192.168.43.x address you've chosen as a static address? then you'll also fail - why do you need a static address on the pi when connecting through a mobile phone in the first place? Jun 16, 2020 at 9:37
  • Thanks for the reply. I would like to have a static IP so that I can connect to it SSH/HTTP without changing the IP address. I was able to achieve the same with another device (ESP32 microcontroller) and I hope I can do the same with Pi.
    – bot1131357
    Jun 16, 2020 at 9:44
  • 1
    This is natures way of telling you not to try setting a static IP address. If the hotspot keeps changing NOTHING you can do on the Pi is going to help
    – Milliways
    Jun 16, 2020 at 9:51
  • having a static private IP (like any 192.168.x.x address) won't allow you to SSH into it from "the internet" ... only from other devices connected to the same hotspot ... but, if that's all you want to do (from other devices connected to the same hotspot) then zeronconf/bonjour/avahi/some other name should allow you to connect to "hostname.local" ... where hostname is the hostname of your raspberry pi - no fixed IP required ... Jun 16, 2020 at 9:58
  • further to the above ... raspberry pi OS comes configured out of the box to "respond" to raspberrypi.local ... so ssh [email protected] should work unless you've done something else wrong Jun 16, 2020 at 10:08

1 Answer 1

0

Leaving this for my future self:

Basically I need to get the IP address that was assigned to the Pi on the wlan0 interface, and then change the last octet of the assigned IP soon after.

Let me break it down:

Get IP from DHCP

I needed to get the IP, extract the subnet part and change the last octet to what I want:

ifconfig wlan0 | grep -P inet[^6][0-9]\+.[0-9]\+.[0-9]\+.[0-9]\+ | sed 's/^ *//g' | cut -d' ' -f 2

This returns my IP address: 192.168.43.101

Put into a script

Here is a test script where I extract the IP, replace the last octet with 27:

nano /home/pi/service/run_on_startup.sh

#!/bin/bash
# get current IP
old_ip=$(ifconfig wlan0 | grep -P inet[^6][0-9]\+.[0-9]\+.[0-9]\+.[0-9]\+ | sed 's/^ *//g' | cut -d' ' -f 2)
echo current ip is $old_ip

# make new IP
new_ip=$(echo $old_ip | cut -d'.' -f 1,2,3).27/24
echo new ip is $new_ip

# change IP
ip addr add $new_ip dev wlan0

Running the script shows:

old_ip is 192.168.43.101/24
new_ip is 192.168.43.27/24

Call this script on startup

I added a systemd service sudo nano /lib/systemd/system/mystartup.service which fires my script on startup:

[Unit]
Description=Startup Settings
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/bin/bash /home/pi/service/run_on_startup.sh

[Install]
WantedBy=multi-user.target

Reload and enable the new service:

sudo systemctl daemon-reload
sudo systemctl enable mystartup.service

Minor gotcha...

One thing I discovered - was that when this script fires on startup, IP on wlan0 wasn't available yet, causing the ip change script to fail. Adding After=network-online.target did not seem to make any difference.

I had to add an additional while loop to wait for the IP to become available.

So here's the added loop:

#!/bin/bash
function get_ip() {
  old_ip=$(ifconfig wlan0 | grep -P inet[^6][0-9]\+.[0-9]\+.[0-9]\+.[0-9]\+ | sed 's/^ *//g' | cut -d' ' -f 2)
  echo $old_ip
}

# loop and wait till network ip is available 
time {
while [ -z "$(get_ip)" ]
do
  sleep 5
done
}

old_ip=$(get_ip)
new_ip=$(echo $old_ip | cut -d'.' -f 1,2,3).27/24
echo new_ip is $new_ip
ip addr add $new_ip dev wlan0

# kick start apache
wget http://127.0.0.1/call_logging -O /dev/null

Check if it's working as intended

Restart

sudo shutdown -r now

Check if the IP is available:

hostname -I
192.168.43.27

Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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