diff options
Diffstat (limited to 'vendor/golang.org/x/sys/unix')
93 files changed, 4437 insertions, 4316 deletions
diff --git a/vendor/golang.org/x/sys/unix/ifreq_linux.go b/vendor/golang.org/x/sys/unix/ifreq_linux.go new file mode 100644 index 000000000..934af313c --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ifreq_linux.go @@ -0,0 +1,149 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build linux +// +build linux + +package unix + +import ( + "bytes" + "unsafe" +) + +// Helpers for dealing with ifreq since it contains a union and thus requires a +// lot of unsafe.Pointer casts to use properly. + +// An Ifreq is a type-safe wrapper around the raw ifreq struct. An Ifreq +// contains an interface name and a union of arbitrary data which can be +// accessed using the Ifreq's methods. To create an Ifreq, use the NewIfreq +// function. +// +// Use the Name method to access the stored interface name. The union data +// fields can be get and set using the following methods: +// - Uint16/SetUint16: flags +// - Uint32/SetUint32: ifindex, metric, mtu +type Ifreq struct{ raw ifreq } + +// NewIfreq creates an Ifreq with the input network interface name after +// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required) +// bytes. +func NewIfreq(name string) (*Ifreq, error) { + // Leave room for terminating NULL byte. + if len(name) >= IFNAMSIZ { + return nil, EINVAL + } + + var ifr ifreq + copy(ifr.Ifrn[:], name) + + return &Ifreq{raw: ifr}, nil +} + +// TODO(mdlayher): get/set methods for hardware address sockaddr, char array, etc. + +// Name returns the interface name associated with the Ifreq. +func (ifr *Ifreq) Name() string { + // BytePtrToString requires a NULL terminator or the program may crash. If + // one is not present, just return the empty string. + if !bytes.Contains(ifr.raw.Ifrn[:], []byte{0x00}) { + return "" + } + + return BytePtrToString(&ifr.raw.Ifrn[0]) +} + +// According to netdevice(7), only AF_INET addresses are returned for numerous +// sockaddr ioctls. For convenience, we expose these as Inet4Addr since the Port +// field and other data is always empty. + +// Inet4Addr returns the Ifreq union data from an embedded sockaddr as a C +// in_addr/Go []byte (4-byte IPv4 address) value. If the sockaddr family is not +// AF_INET, an error is returned. +func (ifr *Ifreq) Inet4Addr() ([]byte, error) { + raw := *(*RawSockaddrInet4)(unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0])) + if raw.Family != AF_INET { + // Cannot safely interpret raw.Addr bytes as an IPv4 address. + return nil, EINVAL + } + + return raw.Addr[:], nil +} + +// SetInet4Addr sets a C in_addr/Go []byte (4-byte IPv4 address) value in an +// embedded sockaddr within the Ifreq's union data. v must be 4 bytes in length +// or an error will be returned. +func (ifr *Ifreq) SetInet4Addr(v []byte) error { + if len(v) != 4 { < |