Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 侦听所有IP数据包,包括ICMP、TCP和UDP?_Sockets_Networking_Go_Tcp - Fatal编程技术网

Sockets 侦听所有IP数据包,包括ICMP、TCP和UDP?

Sockets 侦听所有IP数据包,包括ICMP、TCP和UDP?,sockets,networking,go,tcp,Sockets,Networking,Go,Tcp,特别是在golang,有像net.ListenIP和net.ListenTCP这样的接口 我想知道,如果进程p1ListenIP(192.168.1.1)和进程p2ListenTCP(192.168.1.1:80),那么所有发送到192.168.1.1的数据包(无论是TCP还是UDP)都会被p1截获,而p2永远不会接受TCP连接吗?这是net.ListenIP()的源代码: 它创建了一个原始套接字,在linux上,它是只发送的。TCP和UDP数据包永远不会传递到原始套接字,它们总是由内核协议栈处

特别是在golang,有像
net.ListenIP
net.ListenTCP
这样的接口


我想知道,如果进程p1
ListenIP(192.168.1.1)
和进程p2
ListenTCP(192.168.1.1:80)
,那么所有发送到192.168.1.1的数据包(无论是TCP还是UDP)都会被p1截获,而p2永远不会接受TCP连接吗?

这是
net.ListenIP()
的源代码:


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

您可能想改用一个。这是拦截所有IP流量的唯一方法


您可以使用类似的库。

为什么不自己测试它呢?“设置起来应该不难。”雷芬斯皮尔,谢谢。我已经做了测试,结果表明p2仍然可以接受TCP连接。这让人困惑。那些可以由内核tcp/ip堆栈(如tcp、udp)处理的数据包将被传送到内核堆栈,而那些不能由内核堆栈处理的数据包将被传送到原始套接字。我的理解是对的吗?请注意,ICMP数据包的副本被传送到匹配的原始套接字。例如,您可以调用
net.ListenIP(“ip4:icmp”,laddr)
来获取icmp回显数据包(ping请求),但内核已经向发送方发送了回复(默认情况下)。如果我想截获所有数据包(发送到ip地址或网络接口),以便其他进程永远不会接收tcp或udp数据包。可能吗?我正在用户空间中实现一个交换机/路由器。
// 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 
}