监听所有IP数据包,包括ICMP,TCP和UDP?

时间:2017-03-31 02:33:04

标签: sockets networking go tcp

特别是在golang中,有net.ListenIPnet.ListenTCP等接口。

我想知道,如果进程p1 ListenIP(192.168.1.1)和进程p2 ListenTCP(192.168.1.1:80),p1将截获所有目的地为192.168.1.1(无论是TCP还是UDP),p2将永远不会接受TCP连接?

2 个答案:

答案 0 :(得分:2)

以下是net.ListenIP()的源代码:

// ListenIP listens for incoming IP packets addressed to the local
// address laddr.  The returned connection's ReadFrom and WriteTo
// methods can be used to receive and send IP packets with per-packet
// addressing.
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
    net, proto, err := parseNetwork(netProto)
    if err != nil {
        return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr.opAddr(), Err: err}
    }   
    switch net {
    case "ip", "ip4", "ip6":
    default:
        return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(netProto)}
    }   
    fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen", noCancel)
    if err != nil {
        return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr.opAddr(), Err: err}
    }   
    return newIPConn(fd), nil 
}

它在linux上创建一个原始套接字,IPPROTO_RAW socket仅发送。 TCP和UDP数据包永远不会传递到原始套接字,它们总是由内核协议栈处理。 ICMP数据包的副本将传递到匹配的原始套接字。发往未由内核子系统处理的协议的所有其他数据包都将传递到原始套接字。

答案 1 :(得分:0)

您可能想改用TUN device。这实际上是拦截所有IP流量的唯一方法。

您可以使用https://github.com/songgao/water之类的库。