使用GO语言通过原始套接字读取TCP数据包

3
我正在研究GO中的原始套接字。我想要能够读取所有发送到我的计算机(OSX,en0:192.168.1.65)的TCP数据包。
如果我将协议从TCP切换到ICMP,我会得到数据包。为什么我的代码没有读取到数据包呢?
package main

import (
"fmt"
"net"
)

func main() {

    netaddr, err := net.ResolveIPAddr("ip4", "192.168.1.65")
    if err != nil {
        fmt.Println(err)
    }

    conn, err := net.ListenIP("ip4:tcp", netaddr)
    if err != nil {
        fmt.Println(err)
    }

    buf := make([]byte, 2048)
    for {
        numRead, recvAddr, err := conn.ReadFrom(buf)
        if err != nil {
            fmt.Println(err)
        }
        if recvAddr != nil {
            fmt.Println(recvAddr)
        }
        s := string(buf[:numRead])
        fmt.Println(s)
    }
}

2
先检查错误并查看它们是否有任何提示。如果没有错误,只需更新您的代码示例以反映它 - 如果您这样做,人们更有可能回答。 - twotwotwo
仅从搜索结果来看,我认为Go本身并不支持原始套接字。对于比正常网络访问略低级别的访问,有ipv4(以及等效的ipv6)。显然,有人正在努力使用pcap和Go(通过上一个问题的最后一个答案)。我不是这个领域的专家,只是在寻找可能帮助您的东西。 - twotwotwo
谢谢,我刚刚做了那个。 :) - Jonathan Eustace
看起来完全相同的代码在 Fedora 21 上运行时可以实现我想要的功能。但是在 OSX 上,它没有输出任何 UDP 或 TCP 相关的内容。 - Jonathan Eustace
1个回答

1
这样做的问题在于,OS X基于BSD,而BSD不允许您在TCP级别上编写原始套接字程序。您必须下降到以太网级别才能这样做。
我正在使用pcap库和gopackets来完成工作。

https://godoc.org/code.google.com/p/gopacket/pcap


1
我同意。只需添加参考链接:http://www.darkcoding.net/software/raw-sockets-in-go-link-layer/ 如果你有Richard Stevens的《UNIX网络编程》一书,你可能会像我一样困惑于第28.4节声称“接收到的TCP数据包永远不会传递到原始套接字”。这显然是不正确的。这是与BSD相关的历史注释。man 7原始套接字说,“原始套接字可以在Linux中截取所有IP协议,甚至是ICMP或TCP等协议”,但“在可移植程序中不应依赖于此” - liudanking

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