Comments (7)
Hi @EstebanBorai ,
Supplementary Information:
1.Can you check the output from ifconfig?
A:
$ sudo ip netns exec ns0 ifconfig
veth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.80.10 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::b87c:bcff:fe65:ef76 prefixlen 64 scopeid 0x20
ether ba:7c:bc:65:ef:76 txqueuelen 1000 (以太网)
RX packets 229 bytes 27434 (27.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 463 bytes 25562 (25.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
$ ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::9cf5:bcff:fe1a:b3b8 prefixlen 64 scopeid 0x20
ether 6a:2c:4d:34:44:10 txqueuelen 1000 (以太网)
RX packets 514 bytes 21988 (21.9 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 75 bytes 10928 (10.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
br-c23034e83273: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
inet6 fe80::42:faff:fed3:a101 prefixlen 64 scopeid 0x20
ether 02:42:fa:d3:a1:01 txqueuelen 0 (以太网)
RX packets 29 bytes 3228 (3.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 87241 bytes 18084048 (18.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:7fff:fedb:8ee prefixlen 64 scopeid 0x20
ether 02:42:7f:db:08:ee txqueuelen 0 (以太网)
RX packets 372769 bytes 148146869 (148.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 400780 bytes 340925162 (340.9 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.119 netmask 255.255.248.0 broadcast 192.168.7.255
inet6 fe80::3e4f:72f:6826:9529 prefixlen 64 scopeid 0x20
ether 56:6f:81:7f:00:8b txqueuelen 1000 (以太网)
RX packets 14809847 bytes 8713412808 (8.7 GB)
RX errors 0 dropped 496504 overruns 0 frame 0
TX packets 9378993 bytes 14889855580 (14.8 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens7: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.17 netmask 255.255.248.0 broadcast 192.168.7.255
inet6 fe80::2581:4548:56c8:b69e prefixlen 64 scopeid 0x20
ether 56:6f:81:7f:00:35 txqueuelen 1000 (以太网)
RX packets 4245525 bytes 583538856 (583.5 MB)
RX errors 0 dropped 496504 overruns 0 frame 0
TX packets 134210 bytes 21766228 (21.7 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1000 (本地环回)
RX packets 555192 bytes 1088226330 (1.0 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 555192 bytes 1088226330 (1.0 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2.Can you see your network interfaces using list_afinet_netifas?
A:
rust code as following:
let ipaddr = local_ip_address::list_afinet_netifas().unwrap();
println!("ipaddr:{:?}", ipaddr);
Output:
ipaddr:[("lo", 127.0.0.1), ("veth0", 192.168.80.10), ("veth0", fe80::b87c:bcff:fe65:ef76)]
3.In order to find the default network interface for local IP address, we use netlink by sending a packet to the local network, given the error message we can discard the source of the issue is the missing C header in your system. Do you have a custom configuration?
A: No, i don't have any custom configuration.
By the way, Maybe, I can use list_afinet_netifas to achieve the goal of obtaining the local IP address. hahaha..
(I will read linux.rs code and try to find the answer!)
from local-ip-address.
Hi @EstebanBorai ,
I found the root cause.
Root cause:
In ns0 virtual network space, i don't add the default route. Looks like as:
$ sudo ip netns exec ns0 ip route
192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10
So, this is the reason why the error 'err.error == -libc::ENETUNREACH' occurred.
When i add the default route into ns0, the rust program can work normally.
$ sudo ip netns exec ns0 ip route add default via 192.168.80.1 dev veth0
$ sudo ip netns exec ns0 ip route
default via 192.168.80.1 dev veth0
192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10
$ sudo ip netns exec ns0 target/debug/measure-device
This is my local IP address: 192.168.80.10
My solution:
fn get_local_ip() -> Result<IpAddr, local_ip_address::Error> {
use local_ip_address::{list_afinet_netifas, local_ip, Error};
let lip = local_ip();
match lip {
Ok(ip) => Ok(ip),
Err(_error) => {
let s_lip = list_afinet_netifas();
match s_lip {
Ok(v_lip) => {
match v_lip
.iter()
.find(|(_, ip)| ip != &IpAddr::V4("127.0.0.1".parse().unwrap()))
{
Some((_, ip)) => Ok(ip.clone()),
_ => Err(Error::LocalIpAddressNotFound),
}
}
Err(error) => Err(error),
}
}
}
}
Another question:
Why can't Rmt::GetAddr be used instead of Rmt::GetRoute to retrieve local IP address by Netlink socket?
Such as the examples/getips.rs code of neli-0.6.4.
from local-ip-address.
Hi @EstebanBorai ,
I found the root cause.
Root cause:
In ns0 virtual network space, i don't add the default route. Looks like as:
$ sudo ip netns exec ns0 ip route 192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10
So, this is the reason why the error 'err.error == -libc::ENETUNREACH' occurred.
When i add the default route into ns0, the rust program can work normally.
$ sudo ip netns exec ns0 ip route add default via 192.168.80.1 dev veth0 $ sudo ip netns exec ns0 ip route default via 192.168.80.1 dev veth0 192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10 $ sudo ip netns exec ns0 target/debug/measure-device This is my local IP address: 192.168.80.10
My solution:
fn get_local_ip() -> Result<IpAddr, local_ip_address::Error> { use local_ip_address::{list_afinet_netifas, local_ip, Error}; let lip = local_ip(); match lip { Ok(ip) => Ok(ip), Err(_error) => { let s_lip = list_afinet_netifas(); match s_lip { Ok(v_lip) => { match v_lip .iter() .find(|(_, ip)| ip != &IpAddr::V4("127.0.0.1".parse().unwrap())) { Some((_, ip)) => Ok(ip.clone()), _ => Err(Error::LocalIpAddressNotFound), } } Err(error) => Err(error), } } } }
Another question:
Why can't Rmt::GetAddr be used instead of Rmt::GetRoute to retrieve local IP address by Netlink socket?
Such as the examples/getips.rs code of neli-0.6.4.
Hi @jsydliuqing!
This is great progress on debugging, thanks so much for taking the time!
These constants are mapped to Netlink's message header type's in libc here:
https://docs.rs/neli/0.6.4/src/neli/consts/rtnl.rs.html#409-458
Which you can find documentation for each of them in the Linux manual pages here: https://man7.org/linux/man-pages/man7/rtnetlink.7.html
I think we could use a fallback on attempting to find localhost via Rmt::GetAddr
if current approach fails.
I dont have a strong opinion on sticking with Rmt::GetRoute
but I think its important to keep consistent behavior with current minor (semver) version.
Are you willing to open a PR using this approach in case local IP is
not found on Linux?
from local-ip-address.
Hi @EstebanBorai !
I open a PR , please review it. Thanks!
from local-ip-address.
This issue has been fixed in version v0.6.1!
from local-ip-address.
Hi @jsydliuqing!
Thanks for opening this issue, theres many reasons on why you could have this issue.
In order to narrow down the range of possible causes, can you try the following?
- Can you check the output from
ifconfig
? - Can you see your network interfaces using
list_afinet_netifas
? - In order to find the default network interface for local IP address, we use
netlink
by sending a packet to the local network (Source), given the error message we can discard the source of the issue is the missing C header in your system. Do you have a custom configuration?
Hope these tests help you find out more details.
from local-ip-address.
Hi @EstebanBorai !
I use gdb debug the rust program. Find the error code in linux.rs file and line 210.
The code:
for response in netlink_socket.iter(false) {
let header: Nlmsghdr<Rtm, Rtmsg> = response.map_err(|err| {
if let Nlmsgerr(ref err) = err {
if err.error == -libc::ENETUNREACH {
return Error::LocalIpAddressNotFound; // Here is error!
}
}
Error::StrategyError(format!(
"An error occurred retrieving Netlink's socket response: {err}",
))
})?;
...
}
As you say: given the error message we can discard the source of the issue is the missing C header in your system.
I don't think it is root cause.
Because, i use "target/debug/your-rust-demo" instead of "sudo ip netns exec ns0 target/debug/your-rust-demo", it can get the right local ip address.
$ ../target/debug/measure-device
This is my local IP address: 192.168.0.119
$ sudo ip netns exec ns0 ../target/debug/measure-device
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: LocalIpAddressNotFound', measure-device/src/main.rs:29:52
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace_
from local-ip-address.
Related Issues (20)
- Compilation error with version local-ip-address-0.5.2 HOT 7
- error: build failed HOT 1
- Unexpected "\0" in the network interface name HOT 3
- failed to resolve: use of undeclared crate or module `env` HOT 2
- New release for windows-sys 0.48 HOT 3
- [linux] ipv6 address reported on wrong (moving) interface alias
- Feature Request: Determining Netmask HOT 1
- Why local_ip() return IpAddr? HOT 1
- Cannot compile for Windows MSVC on Linux HOT 5
- Incorrect local IP address got on Windows HOT 4
- Hope to support FreeBSD OS HOT 3
- Use Os Error HOT 5
- Release HOT 6
- Use `std::alloc::alloc` instead of `libc::malloc` HOT 2
- Misleading error message when using non-`en0` interface on macOS HOT 1
- Update `neli` to latest version or change approach
- Determine the primary outbound local IP if multiple present in interfaces HOT 1
- conditional compilation for WebAssembly HOT 1
- MacOS bug on 0.5.0 HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from local-ip-address.