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

huangapple go评论73阅读模式
英文:

Listen all IP packets including ICMP, TCP and UDP?

问题

在Go语言中,有一些接口,比如net.ListenIPnet.ListenTCP

我想知道,如果进程p1调用ListenIP(192.168.1.1),而进程p2调用ListenTCP(192.168.1.1:80),那么所有发送到192.168.1.1的数据包(无论是TCP还是UDP)是否都会被p1拦截,而p2将无法接受TCP连接?

英文:

Specially in golang, there are interfaces like net.ListenIP and net.ListenTCP.

I'm wondering that, if process p1 ListenIP(192.168.1.1) and process p2 ListenTCP(192.168.1.1:80), will all packets dest to 192.168.1.1 (no matter TCP or UDP) are intercepted by p1, and p2 will never accept a TCP connection?

答案1

得分: 2

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

// ListenIP 监听发送到本地地址 laddr 的传入 IP 数据包。
// 返回的连接的 ReadFrom 和 WriteTo 方法可用于接收和发送具有逐个数据包寻址的 IP 数据包。
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 套接字 只能用于发送。TCP 和 UDP 数据包永远不会传递到原始套接字,它们总是由内核协议栈处理。ICMP 数据包的副本会传递到匹配的原始套接字。所有其他传递到未由内核子系统处理的协议的数据包都会传递到原始套接字。

英文:

Here is the source code of 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 
}

it creates a raw socket, on linux, an IPPROTO_RAW socket is send only. TCP and UDP packets are never delivered to raw sockets, they are always handled by the kernel protocol stack. Copies of ICMP packets are delivered to a matching raw socket. All other packets destined for protocols that are not processed by a kernel subsystem are delivered to raw sockets.

答案2

得分: 1

你可能想使用TUN设备。这实际上是拦截所有IP流量的唯一方法。

你可以使用像https://github.com/songgao/water这样的库。

英文:

You probably want to use a TUN device instead. That's really the only way to intercept all IP traffic.

You may use a library like https://github.com/songgao/water.

huangapple
  • 本文由 发表于 2017年3月31日 10:33:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/43131419.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定