How to get current public IP address using UCI?

I have tried uci get network.wan.ipaddr, but it says "uci: Entry not found".

OpenWrt 18.06.3
BusyBox 1.28.4

UCI is for configuration not runtime status. uci get will only read what is stored in a config file.

Thus the answer is that you don't use UCI. You might look at the scripts in the ddns-scripts package for ways to do it. Ultimately it likely comes down to an ip addr show or for a more OpenWrt specific implementation, some sort of ubus call on network.interface.wan.

2 Likes

For IPv4

ip -4 addr show ${link_name} | sed -Ene 's/^.*inet ([0-9.]+)\/.*$/\1/p'
1 Like
ifstatus wan |  jsonfilter -e '@["ipv4-address"][0].address'

ifstatus wan is the same as ubus call network.interface.wan status

4 Likes

This is obsolete. /var/state/network doesn't contain IP.

https://openwrt.org/docs/guide-developer/network-scripting#get_wan_address

3 Likes

This should work, but it's too complex to get an IP, isn't it? ubus is a bit easier.

  • It is the officially recommended method.
  • This API should be more stable than ubus.
  • It can give you both IPv4/IPv6 addresses.
  • It doesn't depend on the WAN/WAN6 interface names.

That's funny. Look into /lib/functions/network.sh and you'll see where it gets IPs from :wink:

network_get_ipaddr() {
	__network_ifstatus "$1" "$2" "['ipv4-address'][0].address";
}
__network_ifstatus() {
	local __tmp

	[ -z "$__NETWORK_CACHE" ] && {
		__tmp="$(ubus call network.interface dump 2>&1)"
		case "$?" in
			4) : ;;
			0) export __NETWORK_CACHE="$__tmp" ;;
			*) echo "$__tmp" >&2 ;;
		esac
	}

	__tmp="$(jsonfilter ${4:+-F "$4"} ${5:+-l "$5"} -s "${__NETWORK_CACHE:-{}}" -e "$1=@.interface${2:+[@.interface='$2']}$3")"

	[ -z "$__tmp" ] && \
		unset "$1" && \
		return 1

	eval "$__tmp"
}

etc.

1 Like

That's true :wink: But this is too simple a case to argue on API levels.

1 Like

Thanks. To be honest, I had seen that source before posting this, but since I'm not familiar with shell script, I could not understand the code (looked like just a bunch of variable declarations), and the "uci get" seemed more understandable, so I had tried to use that.

Anyways, I am not interested in IP6 (my ISP doesn't support it anyway), I removed the IP6 three lines and ran the code. It worked but it seems that I cannot refresh the value. I was trying to print the IP before and after the MAC address change (my ISP assigns a new IP for that), but running the same three lines of code again gave me the same old IP, not the new IP. Can I get the current one, again?

#!/bin/sh

source /lib/functions/network.sh
network_find_wan NET_IF
network_get_ipaddr NET_ADDR "${NET_IF}"
echo "IP before = ${NET_ADDR}"

NEWMAC=$(dd if=/dev/urandom bs=1024 count=1 2>/dev/null | md5sum | sed -e 's/^\(
uci set network.wan.macaddr=${NEWMAC}
uci commit network
/etc/init.d/network restart

network_find_wan NET_IF
network_get_ipaddr NET_ADDR "${NET_IF}"
echo "IP after = ${NET_ADDR}"

It prints the same IP address.

Just my two cents: OpenWrt has DDNS support, and scripts that obtain he public address; perhaps it would be a good idea to see how it was done on those scripts.

2 Likes

How about just
curl https://api.ipify.org/ ?

3 Likes

run network_flush_cache to refresh the cache before trying to get the WAN IP again.

1 Like

/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'

Just parse it. Seems to be accurate and fast.

You do not need UCI for this, and as far as I know, UCI commands that used to do this are all deprecated (meaning, no longer existing).

If you just want to get the IP address, you need a command to use that prints the current IP address (WAN address).

You can use the below two commands on the router. Tested with latest OpenWrt 18.06.6.

The below one-liners work in router terminal as well as in scripts:

For ipv4:
. /lib/functions/network.sh; network_find_wan NET_IF; network_get_ipaddr NET_ADDR "${NET_IF}"; echo "${NET_ADDR}"

For ipv6:
. /lib/functions/network.sh; network_find_wan6 NET_IF6; network_get_ipaddr6 NET_ADDR6 "${NET_IF6}"; echo "${NET_ADDR6}"

( Previously the command used to be this below, but it does not work anymore, result is empty.. but maybe someone is using an older OpenWrt and needs the command for that router: )

. /lib/functions/network.sh; network_get_ipaddr ip wan; echo $ip

2 Likes

don't want to be that guy but 19.07 stable was released just a day before your post :joy:

No worries: it works

The below one-liners work in router terminal as well as in scripts, for 18.06.6 and 19.07.0:

For ipv4:

. /lib/functions/network.sh; network_find_wan NET_IF; network_get_ipaddr NET_ADDR "${NET_IF}"; echo "${NET_ADDR}"

For ipv6:

. /lib/functions/network.sh; network_find_wan6 NET_IF6; network_get_ipaddr6 NET_ADDR6 "${NET_IF6}"; echo "${NET_ADDR6}"

1 Like