Repository: go
Issue: proposal: x/net/ipv4: add wrappers for Write/WriteToIP and Read/ReadFromIP
Labels: Proposal

# Brief for proposal
Add four wrapper function on `ipv4.RawConn` with **detailed documentation**.
Current doc is inferred from embed field, it is misleading even wrong in the context of `ipv4.RawConn`.

Described as below.
```golang
// Write writes a raw IPv4 datagram to the underlying socket.
// It will NOT prepend IPv4 header to the datagram, and it is caller's
// responsibility to provide correct IPv4 header on the wire per platform bias.
// See "x/net/ipv4/header.go" for details.
func (c *RawConn) Write(b []byte) (int, error) {
	// wrapper fn act same as before
}

// WriteToIP acts like Write but takes a *net.IPAddr as target for writing.
// It will NOT prepend IPv4 header to the datagram, and it is caller's
// responsibility to provide correct IPv4 header on the wire per platform bias.
// See "x/net/ipv4/header.go" for details.
func (c *RawConn) WriteToIP(b []byte, addr *net.IPAddr) (int, error) {
	// wrapper fn act same as before
}

// Read reads a raw IPv4 datagram into b, including IPv4 header, 
// returns the length read or an error.
// It's callers responsibility to parse IPv4 header per platform bias.
// See "x/net/ipv4/header.go" for details.
func (c *RawConn) Read(b []byte) (int, error) {
	// wrapper fn act same as before
}

// ReadFromIP reads an IPv4 datagram and write its payload into b,
// returns the length of payload and remote IPAddr.
func (c *RawConn) ReadFromIP(b []byte) (int, *net.IPAddr, error) {
	// wrapper fn act same as before
}

```

# Proposal detail
Currently, functions on `ipv4.RawConn` are mostly provided by anonymous embed field, so with its doc.
I am confused with similar function names, but things they do completely different. 

For example:
`Read`, `ReadFrom` and `ReadFromIP`. 
`Write`, `WriteTo` and `WriteToIP`.
I just list fn signature and its doc below for quick reference.

## Here is WHAT I HAVE OBSERVED
`Read`/`Write` is provided by *net.conn embed in field "packetHandler.IPConn"
`ReadFrom`/`WriteTo` is directly provided by embed field "packetHandler"
`ReadFromIP`/`WriteToIP` is provided by *net.IPConn embed in field "packetHandler"

The doc for `ReadFromIP` is not correct in the context of `ipv4.RawConn`, also the doc for `Read` is not very useful, and does not warn user that the wire format of IPv4 header may vary between platforms.
This is also true for `Write***` situations.

eg: Some BSD-like systme including macOS have the ip_len and ip_off fields converted to host byte order after packets recived, and expcting host byte order for ip_len and ip_off fields while sending packets.
Those cases are already handled in `x/net/ipv4/header.go`, but we also should warn users about the differences while manipulating raw IPv4 datagrams. 

```golang
type RawConn struct {
	genericOpt
	dgramOpt
	packetHandler
}

// Read implements the Conn Read method.
func (c *conn) Read(b []byte) (int, error)

// ReadFrom reads an IPv4 datagram from the endpoint c, copying the
// datagram into b. It returns the received datagram as the IPv4
// header h, the payload p and the control message cm.
func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error)

// ReadFromIP acts like ReadFrom but returns an IPAddr.
func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error)

// Write implements the Conn Write method.
func (c *conn) Write(b []byte) (int, error)

// WriteTo writes an IPv4 datagram through the endpoint c, copying the
// datagram from the IPv4 header h and the payload p. The control
// message cm allows the datagram path and the outgoing interface to be
// specified.  Currently only Darwin and Linux support this. The cm
// may be nil if control of the outgoing datagram is not required.
//
// The IPv4 header h must contain appropriate fields that include:
//
//	Version       = <must be specified>
//	Len           = <must be specified>
//	TOS           = <must be specified>
//	TotalLen      = <must be specified>
//	ID            = platform sets an appropriate value if ID is zero
//	FragOff       = <must be specified>
//	TTL           = <must be specified>
//	Protocol      = <must be specified>
//	Checksum      = platform sets an appropriate value if Checksum is zero
//	Src           = platform sets an appropriate value if Src is nil
//	Dst           = <must be specified>
//	Options       = optional
func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error

// WriteToIP acts like [IPConn.WriteTo] but takes an [IPAddr].
func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error)

```