rust - 如何检测源地址是 IPv4 还是 IPv6
问题描述
有什么方法可以检测到源地址是 IPv4 还是 IPv6?
我写了类似的东西
let listener = TcpListener::bind("[::]:33333").unwrap();
for res in listener.incoming() {
match res {
Ok(stream) => {thread::spawn(move||{handler(stream);},
Err(_) => {println!("error");},
}
}
处理函数如下:
fn handler(mut stream: TcpStream) -> Result<(),Error> {
if stream.peer_addr().unwrap().is_ipv4() {
println!("peer is IPv4");
}
else {
println!("peer is IPv6");
}
在处理函数中,我使用 stream.peer_addr().unwrap().is_ipv4() 来查找对等地址是 IPv4 还是 IPv6。但所有地址都是 IPv6。当我连接到 127.0.0.1 的服务器时,对等地址是 IPv4 映射的 IPv6 地址:V6([::ffff:127.0.0.1]:33333)。如果服务器绑定到 0.0.0.0:33333,我无法连接到其 IPv6 地址(例如 ::1)。无论如何,服务器是否接受来自 IPv4 和 IPv6 对等方的连接并且也不使用 IPv4 映射的 IPv6 地址?我正在使用 Ubuntu 20.04.1。谢谢你,ei
解决方案
不,它们是不兼容的协议,您必须将 IPv4 映射到 IPv6。
IPv6 不向后兼容,但映射到 IPv6 的 IPv4 有特殊表示。
80 位设置为 0,然后 16 位设置为 1,然后是 IPv4 地址的 32 位。
换句话说,您可以像这样检查它的 ipv4 是否映射到 ipv6:
fn is_mapped_to_ipv6(addr: SocketAddr) -> bool {
match addr {
SocketAddr::V6(v6) => match v6.ip().segments() {
// 5 * 16 `0` bits, 16 `1` bits, leftover is actual IPv4 addr
[0, 0, 0, 0, 0, 0xFFFF, ..] => true,
_ => false,
},
_ => false,
}
}
推荐阅读
- fat-free-framework - 在 Fat Free Framework 中,是否可以在模板中显示缺失的键?
- java - 在 OjAlgo 的 Primitive64Store 中的特定列和行处插入 Access2D 元素
- html - Fullcalendar 一半时间GridWeek 像一天一样查看GridWeek
- python - 如何在 Python 中打印字符串中的内容?
- python - 如何在python中导出虚拟环境设置
- mysql - MYSQL UPDATE 表上 INSERT 到同一个表
- angular - 在 Typescript 项目之间共享接口
- django - 为什么我们首先在 Django 表单中使用实例作为第二个参数而不是现有数据库条目
- node.js - 如何从 express +Node.js 中的 url 获取 {{id}}
- java - java.lang 的正式规范在哪里?