unix: export Ifreq and add IoctlIfreq function

This CL expands upon CL 340369 by exporting the Ifreq type along with methods
for setting and getting data to/from the ifreq union in a type-safe way.
ifreqData remains unexported as we can keep adding helpers similar to the
IoctlGetEthtoolDrvinfo to expose those operations in a less error-prone way.

A test is also added to verify interface index data using IoctlIfreq against
the modern rtnetlink API used by the standard library.

Change-Id: Ic6980cbcd3792cc341cd614061cce32fa1f851e7
Reviewed-on: https://go-review.googlesource.com/c/sys/+/340370
Trust: Matt Layher <mdlayher@gmail.com>
Run-TryBot: Matt Layher <mdlayher@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Matt Layher
2021-08-17 19:03:40 +00:00
parent 7d9622a276
commit bfb29a6856
5 changed files with 271 additions and 22 deletions
+21 -3
View File
@@ -48,15 +48,15 @@ func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
// IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
// device specified by ifname.
func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
ifr, err := newIfreq(ifname)
ifr, err := NewIfreq(ifname)
if err != nil {
return nil, err
}
value := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO}
ifrd := ifr.SetData(unsafe.Pointer(&value))
ifrd := ifr.withData(unsafe.Pointer(&value))
err = ioctlPtr(fd, SIOCETHTOOL, unsafe.Pointer(&ifrd))
err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
return &value, err
}
@@ -176,3 +176,21 @@ func IoctlHIDGetRawUniq(fd int) (string, error) {
err := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0]))
return ByteSliceToString(value[:]), err
}
// IoctlIfreq performs an ioctl using an Ifreq structure for input and/or
// output. See the netdevice(7) man page for details.
func IoctlIfreq(fd int, req uint, value *Ifreq) error {
// It is possible we will add more fields to *Ifreq itself later to prevent
// misuse, so pass the raw *ifreq directly.
return ioctlPtr(fd, req, unsafe.Pointer(&value.raw))
}
// TODO(mdlayher): export if and when IfreqData is exported.
// ioctlIfreqData performs an ioctl using an ifreqData structure for input
// and/or output. See the netdevice(7) man page for details.
func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
// The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are
// identical so pass *IfreqData directly.
return ioctlPtr(fd, req, unsafe.Pointer(value))
}