Go 能否使用无 ipv4 的网卡发送 UDP 数据包?

2023-03-08 23:16:24 +08:00
 wangsongyan

我使用网线将 N1 和台式机直连,N1 未设置静态 IP ,有 eth0 、wlan0 两个网卡。

eth0 网卡信息如下:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether de:93:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 3179  bytes 737340 (720.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 23709  bytes 4419840 (4.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 20  

我想使用 eth0 网卡发送 Wake-on-LAN 魔术包,做了以下尝试均无法唤醒主机,我猜测是因为 eth0 网卡没有 ipv4 ip 导致,我想问下能否使用上面 eth0 网卡发送 UDP 数据包?

尝试一:
inf, err := net.InterfaceByName("eth0")
addrs, err := inf.Addrs()//此处 addrs 为空切片
var localAddr = &net.UDPAddr{
	IP: addrs[0].(*net.IPNet).IP,
}
conn, err := net.DialUDP("udp", localAddr, udpAddr)

尝试二:(让系统自己选择本地地址)
conn, err := net.DialUDP("udp", nil, udpAddr)

(ps:同样环境下使用 etherwake 可以唤醒主机,所以很郁闷)

2066 次点击
所在节点    Go 编程语言
13 条回复
chuckzhou
2023-03-09 00:19:07 +08:00
你没有 IPv4 的 localAddr ,所以不能直接用 udp 。
你必须构造一个以太网包,源 ip 填 0 试试。
cdlnls
2023-03-09 00:47:58 +08:00
试试用 gopacket 这个包,构建一个 UDP 包直接发送。
jim9606
2023-03-09 03:15:27 +08:00
如果我没记错的话,发这种 WoL 包是要用 SOCK_RAW socket 直接构造 UDP 包的,不能走系统的 UDP 协议栈,所以基于 SOCK_DGRAM 的 UDP 封装应该不能用。
hingle
2023-03-09 08:41:26 +08:00
没用过 Wake-on-LAN 不清楚,但是没有 IP 的话应该只能走数据链路层了吧。
cq65617875
2023-03-09 08:44:12 +08:00
wol 不是直接用 mac 发的包么
lxz6597863
2023-03-09 09:22:51 +08:00
gopacket+1
911061873
2023-03-09 14:44:39 +08:00
下面是我用 python+fastapi+socket 实现的外网开机
主要是构建一个 UDP 的数据包,发给路由器,路由器做了端口转发,会 NAT 转成电脑网卡的 MAC 地址,然后就开机了。
```python
@app.get('/电脑开机')
def wakeonlan():
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = 'ff' * 6 + 'd85ed3454fe1' * 16
s.sendto(bytes.fromhex(data), ('xxxx.xxddns.cn', 7))
s.close()
return PlainTextResponse('成功')
```
911061873
2023-03-09 14:47:49 +08:00
WOL 是涉及不到三层( IP 层面)的,只到二层(数据链路层)因为电脑关机的时候网卡
zhangsanfeng2012
2023-03-10 15:14:10 +08:00
wangsongyan
2023-03-14 00:06:15 +08:00
@chuckzhou #1 试了源 ip 填 0 ,无法唤醒

@cdlnls #2
@lxz6597863 #6 我去看看 gopacket 怎么使用

@jim9606 #3 我在 Github 上搜到三个 go 写的 wol 相关的项目,都是发送的 UDP 数据包。我试了本机运行网卡灯是会闪一下的,我现在的情况确实不适合使用 UDP 来发

@hingle #4 是这样的,思路没打开

@cq65617875 #5 是直接发含 mac 地址的包,但是之前往哪儿发、怎么发不太清楚

@911061873 #7 正在安装 python 环境,准备跑一波,你的代码也太简洁了!卧槽奉上

@zhangsanfeng2012 #9 这正是我想要的代码,亲测可用

感谢各位大佬的热心帮助!
911061873
2023-03-14 02:02:28 +08:00
数据包是一样的,ff*6+macaddr*16
gitxuzan
2023-03-15 10:01:46 +08:00
我想问下这个是干嘛用的?局域网唤醒主机?
wangsongyan
2023-03-15 10:58:28 +08:00
@gitxuzan #12 是的,配合公网 IP 或者内网穿透就可以实现远程开机

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/922420

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX