func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
	if !c.ok() {
		return 0, nil, nil, syscall.EINVAL
	}
	oob := newControlMessage(&c.rawOpt)
	var oobn int
	switch c := c.PacketConn.(type) {
	case *net.UDPConn:
		if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
			return 0, nil, nil, err
		}
	case *net.IPConn:
		if _, ok := sockOpts[ssoStripHeader]; ok {
			if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
				return 0, nil, nil, err
			}
		} else {
			nb := make([]byte, maxHeaderLen+len(b))
			if n, oobn, _, src, err = c.ReadMsgIP(nb, oob); err != nil {
				return 0, nil, nil, err
			}
			hdrlen := int(nb[0]&0x0f) << 2
			copy(b, nb[hdrlen:])
			n -= hdrlen
		}
	default:
		return 0, nil, nil, errInvalidConnType
	}
	if cm, err = parseControlMessage(oob[:oobn]); err != nil {
		return 0, nil, nil, err
	}
	if cm != nil {
		cm.Src = netAddrToIP4(src)
	}
	return
}
ReadFrom reads a payload of the received IPv4 datagram, from the
endpoint c, copying the payload into b. It returns the number of
bytes copied into b, the control message cm and the source address
src of the received datagram.
package ipv4
import (
	"net"
	"syscall"
)