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?
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.