使用golang从连接到网络接口的原始套接字中读取数据

7
我正在尝试使用golang读取我WiFi卡接收的链路层数据包。我编写的程序可以成功编译并运行,但它似乎在尝试从套接字中读取时被卡住了(syscall.Recvfrom(fd, data, 0 - 此处确切地说)。我做错了什么?
PS:wlx34e894f77905是我的WiFi设备名称。
以下是我用于尝试读取数据包的函数:
func readFromSocket() {
    fd, error := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, syscall.ETH_P_ALL)
    if error != nil {
        syscall.Close(fd)
        panic(error)
    }
    err := syscall.BindToDevice(fd, "wlx34e894f77905")
    if err != nil {
        syscall.Close(fd)
        panic(err)
    }
    data := make([]byte, 1024)
    for {
        syscall.Recvfrom(fd, data, 0)
        fmt.Println(data)
    }
}

netstat -r 输出:

default         _gateway        0.0.0.0         UG        0 0          0 wlx34e894f77905
link-local      0.0.0.0         255.255.0.0     U         0 0          0 wlx34e894f77905
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U         0 0          0 br-3d5c8c113e89
192.168.0.0     0.0.0.0         255.255.255.0   U         0 0          0 wlx34e894f77905

你的无线设备已配置并且在你执行此操作时,你的互联网流量是否通过它进行传输?请提供“netstat -r”输出。 - Jomu
@Jomu 是的,互联网流量正在通过我的WiFi卡路由。使用netstat命令输出更新原始问题。 - ashishmax31
1
许多年前,我曾使用TAP设备进行类似的工作。根据我记得的,你现在的做法会与内核争夺该设备的控制权,而且你会输掉这场争斗。重要的是你想要实现什么目标?你想要嗅探流量还是参与其中?如果你想要嗅探流量,那么你可以研究一下libpcap的工作原理;如果你想要参与其中,那么就需要使用TUN/TAP。 - Jomu
似乎罪魁祸首是字节顺序。@Jomu - ashishmax31
1个回答

7

类似于C/C++代码:

sock_raw=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));

那么,Golang 是:

syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, htons(syscall.ETH_P_ALL))

htons(syscall.ETH_P_ALL) => 0x0300(小端)

翻译:将syscall.ETH_P_ALL转换为网络字节序的值,结果为0x0300(小端)。

非常感谢,老兄。改变字节顺序之后它终于能运行了!干杯 - ashishmax31

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接