Update vendoring (#722)

* Update vendor github.com/beevik/ntp@v0.2.0

* Update vendor github.com/mdlayher/netlink/...

* Update vendor github.com/mdlayher/wifi/...

Adds vendor github.com/mdlayher/genetlink

* Update vendor github.com/prometheus/common/...

* Update vendor github.com/prometheus/procfs/...

* Update vendor golang.org/x/sys/unix

* Update vendor golang.org/x/sys/windows
This commit is contained in:
Ben Kochie 2017-11-02 12:30:34 +01:00 committed by GitHub
commit 4d7aa57da0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 587 additions and 283 deletions

10
vendor/github.com/mdlayher/genetlink/LICENSE.md generated vendored Normal file
View file

@ -0,0 +1,10 @@
MIT License
===========
Copyright (C) 2016-2017 Matt Layher
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

8
vendor/github.com/mdlayher/genetlink/README.md generated vendored Normal file
View file

@ -0,0 +1,8 @@
genetlink [![Build Status](https://travis-ci.org/mdlayher/genetlink.svg?branch=master)](https://travis-ci.org/mdlayher/genetlink) [![GoDoc](https://godoc.org/github.com/mdlayher/genetlink?status.svg)](https://godoc.org/github.com/mdlayher/genetlink) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/genetlink)](https://goreportcard.com/report/github.com/mdlayher/genetlink)
=========
Package `genetlink` implements generic netlink interactions and data types.
MIT Licensed.
For more information about how netlink and generic netlink work,
check out my blog series on [Linux, Netlink, and Go](https://medium.com/@mdlayher/linux-netlink-and-go-part-1-netlink-4781aaeeaca8).

View file

@ -1,32 +1,18 @@
package genetlink
import "github.com/mdlayher/netlink"
// Controller is the generic netlink controller family ID, used to issue
// requests to the controller.
const Controller = 0x10
import (
"github.com/mdlayher/netlink"
"golang.org/x/net/bpf"
)
// Protocol is the netlink protocol constant used to specify generic netlink.
const Protocol = 0x10
const Protocol = 0x10 // unix.NETLINK_GENERIC
// A Conn is a generic netlink connection. A Conn can be used to send and
// receive generic netlink messages to and from netlink.
type Conn struct {
// Family provides functions to help retrieve generic netlink families.
Family *FamilyService
c conn
}
var _ conn = &netlink.Conn{}
// A conn is a netlink connection, which can be swapped for tests.
type conn interface {
Close() error
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
Send(m netlink.Message) (netlink.Message, error)
Receive() ([]netlink.Message, error)
// Operating system-specific netlink connection.
c *netlink.Conn
}
// Dial dials a generic netlink connection. Config specifies optional
@ -38,18 +24,16 @@ func Dial(config *netlink.Config) (*Conn, error) {
return nil, err
}
return newConn(c), nil
return NewConn(c), nil
}
// newConn is the internal constructor for Conn, used in tests.
func newConn(c conn) *Conn {
gc := &Conn{
c: c,
}
gc.Family = &FamilyService{c: gc}
return gc
// NewConn creates a Conn that wraps an existing *netlink.Conn for
// generic netlink communications.
//
// NewConn is primarily useful for tests. Most applications should use
// Dial instead.
func NewConn(c *netlink.Conn) *Conn {
return &Conn{c: c}
}
// Close closes the connection.
@ -57,6 +41,17 @@ func (c *Conn) Close() error {
return c.c.Close()
}
// GetFamily retrieves a generic netlink family with the specified name. If the
// family does not exist, the error value can be checked using os.IsNotExist.
func (c *Conn) GetFamily(name string) (Family, error) {
return c.getFamily(name)
}
// ListFamilies retrieves all registered generic netlink families.
func (c *Conn) ListFamilies() ([]Family, error) {
return c.listFamilies()
}
// JoinGroup joins a netlink multicast group by its ID.
func (c *Conn) JoinGroup(group uint32) error {
return c.c.JoinGroup(group)
@ -67,6 +62,11 @@ func (c *Conn) LeaveGroup(group uint32) error {
return c.c.LeaveGroup(group)
}
// SetBPF attaches an assembled BPF program to a Conn.
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return c.c.SetBPF(filter)
}
// Send sends a single Message to netlink, wrapping it in a netlink.Message
// using the specified generic netlink family and flags. On success, Send
// returns a copy of the netlink.Message with all parameters populated, for

17
vendor/github.com/mdlayher/genetlink/family.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
package genetlink
// A Family is a generic netlink family.
type Family struct {
ID uint16
Version uint8
Name string
Groups []MulticastGroup
}
// A MulticastGroup is a generic netlink multicast group, which can be joined
// for notifications from generic netlink families when specific events take
// place.
type MulticastGroup struct {
ID uint32
Name string
}

View file

@ -1,3 +1,5 @@
//+build linux
package genetlink
import (
@ -7,14 +9,7 @@ import (
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/nlenc"
)
// Constants used to request information from generic netlink controller.
// Reference: http://lxr.free-electrons.com/source/include/linux/genetlink.h?v=3.3#L35
const (
ctrlVersion = 1
ctrlCommandGetFamily = 3
"golang.org/x/sys/unix"
)
var (
@ -27,32 +22,10 @@ var (
errInvalidMulticastGroupArray = errors.New("invalid multicast group attribute array")
)
// A Family is a generic netlink family.
type Family struct {
ID uint16
Version uint8
Name string
Groups []MulticastGroup
}
// A MulticastGroup is a generic netlink multicast group, which can be joined
// for notifications from generic netlink families when specific events take
// place.
type MulticastGroup struct {
ID uint32
Name string
}
// A FamilyService is used to retrieve generic netlink family information.
type FamilyService struct {
c *Conn
}
// Get retrieves a generic netlink family with the specified name. If the
// family does not exist, the error value can be checked using os.IsNotExist.
func (s *FamilyService) Get(name string) (Family, error) {
// getFamily retrieves a generic netlink family with the specified name.
func (c *Conn) getFamily(name string) (Family, error) {
b, err := netlink.MarshalAttributes([]netlink.Attribute{{
Type: attrFamilyName,
Type: unix.CTRL_ATTR_FAMILY_NAME,
Data: nlenc.Bytes(name),
}})
if err != nil {
@ -61,13 +34,14 @@ func (s *FamilyService) Get(name string) (Family, error) {
req := Message{
Header: Header{
Command: ctrlCommandGetFamily,
Version: ctrlVersion,
Command: unix.CTRL_CMD_GETFAMILY,
// TODO(mdlayher): grab nlctrl version?
Version: 1,
},
Data: b,
}
msgs, err := s.c.Execute(req, Controller, netlink.HeaderFlagsRequest)
msgs, err := c.Execute(req, unix.GENL_ID_CTRL, netlink.HeaderFlagsRequest)
if err != nil {
return Family{}, err
}
@ -87,17 +61,18 @@ func (s *FamilyService) Get(name string) (Family, error) {
return families[0], nil
}
// List retrieves all registered generic netlink families.
func (s *FamilyService) List() ([]Family, error) {
// listFamilies retrieves all registered generic netlink families.
func (c *Conn) listFamilies() ([]Family, error) {
req := Message{
Header: Header{
Command: ctrlCommandGetFamily,
Version: ctrlVersion,
Command: unix.CTRL_CMD_GETFAMILY,
// TODO(mdlayher): grab nlctrl version?
Version: 1,
},
}
flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump
msgs, err := s.c.Execute(req, Controller, flags)
msgs, err := c.Execute(req, unix.GENL_ID_CTRL, flags)
if err != nil {
return nil, err
}
@ -126,38 +101,22 @@ func buildFamilies(msgs []Message) ([]Family, error) {
return families, nil
}
// Attribute IDs mapped to specific family fields.
const (
// TODO(mdlayher): parse additional attributes
// Family attributes
attrUnspecified = 0
attrFamilyID = 1
attrFamilyName = 2
attrVersion = 3
attrMulticastGroups = 7
// Multicast group-specific attributes
attrMGName = 1
attrMGID = 2
)
// parseAttributes parses netlink attributes into a Family's fields.
func (f *Family) parseAttributes(attrs []netlink.Attribute) error {
for _, a := range attrs {
switch a.Type {
case attrFamilyID:
case unix.CTRL_ATTR_FAMILY_ID:
f.ID = nlenc.Uint16(a.Data)
case attrFamilyName:
case unix.CTRL_ATTR_FAMILY_NAME:
f.Name = nlenc.String(a.Data)
case attrVersion:
case unix.CTRL_ATTR_VERSION:
v := nlenc.Uint32(a.Data)
if v > math.MaxUint8 {
return errInvalidFamilyVersion
}
f.Version = uint8(v)
case attrMulticastGroups:
case unix.CTRL_ATTR_MCAST_GROUPS:
groups, err := parseMulticastGroups(a.Data)
if err != nil {
return err
@ -194,9 +153,9 @@ func parseMulticastGroups(b []byte) ([]MulticastGroup, error) {
var g MulticastGroup
for _, na := range nattrs {
switch na.Type {
case attrMGName:
case unix.CTRL_ATTR_MCAST_GRP_NAME:
g.Name = nlenc.String(na.Data)
case attrMGID:
case unix.CTRL_ATTR_MCAST_GRP_ID:
g.ID = nlenc.Uint32(na.Data)
}
}

25
vendor/github.com/mdlayher/genetlink/family_others.go generated vendored Normal file
View file

@ -0,0 +1,25 @@
//+build !linux
package genetlink
import (
"fmt"
"runtime"
)
var (
// errUnimplemented is returned by all functions on platforms that
// cannot make use of generic netlink.
errUnimplemented = fmt.Errorf("generic netlink not implemented on %s/%s",
runtime.GOOS, runtime.GOARCH)
)
// getFamily always returns an error.
func (c *Conn) getFamily(name string) (Family, error) {
return Family{}, errUnimplemented
}
// listFamilies always returns an error.
func (c *Conn) listFamilies() ([]Family, error) {
return nil, errUnimplemented
}

View file

@ -20,7 +20,7 @@ type Header struct {
}
// headerLen is the length of a Header.
const headerLen = 4
const headerLen = 4 // unix.GENL_HDRLEN
// A Message is a generic netlink message. It contains a Header and an
// arbitrary byte payload, which may be decoded using information from the

View file

@ -1,7 +1,7 @@
MIT License
===========
Copyright (C) 2016 Matt Layher
Copyright (C) 2016-2017 Matt Layher
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View file

@ -4,6 +4,12 @@ netlink [![Build Status](https://travis-ci.org/mdlayher/netlink.svg?branch=maste
Package `netlink` provides low-level access to Linux netlink sockets.
MIT Licensed.
For more information about how netlink works, check out my blog series
on [Linux, Netlink, and Go](https://medium.com/@mdlayher/linux-netlink-and-go-part-1-netlink-4781aaeeaca8).
If you're looking for package `genetlink`, it's been moved to its own
repository at [`github.com/mdlayher/genetlink`](https://github.com/mdlayher/genetlink).
Why?
----
@ -18,4 +24,4 @@ I wanted in a netlink package:
- Doesn't need root to work
My goal for this package is to use it as a building block for the creation
of other netlink protocol family packages.
of other netlink family packages.

View file

@ -9,10 +9,13 @@ import (
var (
// errInvalidAttribute specifies if an Attribute's length is incorrect.
errInvalidAttribute = errors.New("invalid attribute; length too short or too large")
// errInvalidAttributeFlags specifies if an Attribute's flag configuration is invalid.
// From a comment in Linux/include/uapi/linux/netlink.h, Nested and NetByteOrder are mutually exclusive.
errInvalidAttributeFlags = errors.New("invalid attribute; type cannot have both nested and net byte order flags")
)
// An Attribute is a netlink attribute. Attributes are packed and unpacked
// to and from the Data field of Message for some netlink protocol families.
// to and from the Data field of Message for some netlink families.
type Attribute struct {
// Length of an Attribute, including this field and Type.
Length uint16
@ -22,19 +25,50 @@ type Attribute struct {
// An arbitrary payload which is specified by Type.
Data []byte
// Whether the attribute's data contains nested attributes. Note that not
// all netlink families set this value. The programmer should consult
// documentation and inspect an attribute's data to determine if nested
// attributes are present.
Nested bool
// Whether the attribute's data is in network (true) or native (false) byte order.
NetByteOrder bool
}
// #define NLA_F_NESTED
const nlaNested uint16 = 0x8000
// #define NLA_F_NET_BYTE_ORDER
const nlaNetByteOrder uint16 = 0x4000
// Masks all bits except for Nested and NetByteOrder.
const nlaTypeMask = ^(nlaNested | nlaNetByteOrder)
// MarshalBinary marshals an Attribute into a byte slice.
func (a Attribute) MarshalBinary() ([]byte, error) {
if int(a.Length) < nlaHeaderLen {
return nil, errInvalidAttribute
}
if a.NetByteOrder && a.Nested {
return nil, errInvalidAttributeFlags
}
b := make([]byte, nlaAlign(int(a.Length)))
nlenc.PutUint16(b[0:2], a.Length)
nlenc.PutUint16(b[2:4], a.Type)
copy(b[4:], a.Data)
switch {
case a.Nested:
nlenc.PutUint16(b[2:4], a.Type|nlaNested)
case a.NetByteOrder:
nlenc.PutUint16(b[2:4], a.Type|nlaNetByteOrder)
default:
nlenc.PutUint16(b[2:4], a.Type)
}
copy(b[nlaHeaderLen:], a.Data)
return b, nil
}
@ -46,23 +80,33 @@ func (a *Attribute) UnmarshalBinary(b []byte) error {
}
a.Length = nlenc.Uint16(b[0:2])
a.Type = nlenc.Uint16(b[2:4])
// Only hold the rightmost 14 bits in Type
a.Type = nlenc.Uint16(b[2:4]) & nlaTypeMask
// Boolean flags extracted from the two leftmost bits of Type
a.Nested = (nlenc.Uint16(b[2:4]) & nlaNested) > 0
a.NetByteOrder = (nlenc.Uint16(b[2:4]) & nlaNetByteOrder) > 0
if nlaAlign(int(a.Length)) > len(b) {
return errInvalidAttribute
}
if a.NetByteOrder && a.Nested {
return errInvalidAttributeFlags
}
switch {
// No length, no data
case a.Length == 0:
a.Data = make([]byte, 0)
// Not enough length for any data
case a.Length < 4:
case int(a.Length) < nlaHeaderLen:
return errInvalidAttribute
// Data present
case a.Length >= 4:
a.Data = make([]byte, len(b[4:a.Length]))
copy(a.Data, b[4:a.Length])
case int(a.Length) >= nlaHeaderLen:
a.Data = make([]byte, len(b[nlaHeaderLen:a.Length]))
copy(a.Data, b[nlaHeaderLen:a.Length])
}
return nil

View file

@ -2,7 +2,9 @@ package netlink
import (
"errors"
"io"
"math/rand"
"os"
"sync/atomic"
"golang.org/x/net/bpf"
@ -15,12 +17,20 @@ var (
errShortErrorMessage = errors.New("not enough data for netlink error code")
)
// Errors which can be returned by a Socket that does not implement
// all exposed methods of Conn.
var (
errReadWriteCloserNotSupported = errors.New("raw read/write/closer not supported")
errMulticastGroupsNotSupported = errors.New("multicast groups not supported")
errBPFFiltersNotSupported = errors.New("BPF filters not supported")
)
// A Conn is a connection to netlink. A Conn can be used to send and
// receives messages to and from netlink.
type Conn struct {
// osConn is the operating system-specific implementation of
// sock is the operating system-specific implementation of
// a netlink sockets connection.
c osConn
sock Socket
// seq is an atomically incremented integer used to provide sequence
// numbers when Conn.Send is called.
@ -30,44 +40,45 @@ type Conn struct {
pid uint32
}
// An osConn is an operating-system specific implementation of netlink
// A Socket is an operating-system specific implementation of netlink
// sockets used by Conn.
type osConn interface {
type Socket interface {
Close() error
Send(m Message) error
Receive() ([]Message, error)
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
SetBPF(filter []bpf.RawInstruction) error
}
// Dial dials a connection to netlink, using the specified protocol number.
// Dial dials a connection to netlink, using the specified netlink family.
// Config specifies optional configuration for Conn. If config is nil, a default
// configuration will be used.
func Dial(proto int, config *Config) (*Conn, error) {
// Use OS-specific dial() to create osConn
c, pid, err := dial(proto, config)
func Dial(family int, config *Config) (*Conn, error) {
// Use OS-specific dial() to create Socket
c, pid, err := dial(family, config)
if err != nil {
return nil, err
}
return newConn(c, pid), nil
return NewConn(c, pid), nil
}
// newConn is the internal constructor for Conn, used in tests.
func newConn(c osConn, pid uint32) *Conn {
// NewConn creates a Conn using the specified Socket and PID for netlink
// communications.
//
// NewConn is primarily useful for tests. Most applications should use
// Dial instead.
func NewConn(c Socket, pid uint32) *Conn {
seq := rand.Uint32()
return &Conn{
c: c,
seq: &seq,
pid: pid,
sock: c,
seq: &seq,
pid: pid,
}
}
// Close closes the connection.
func (c *Conn) Close() error {
return c.c.Close()
return c.sock.Close()
}
// Execute sends a single Message to netlink using Conn.Send, receives one or more
@ -127,7 +138,7 @@ func (c *Conn) Send(m Message) (Message, error) {
m.Header.PID = c.pid
}
if err := c.c.Send(m); err != nil {
if err := c.sock.Send(m); err != nil {
return Message{}, err
}
@ -145,8 +156,13 @@ func (c *Conn) Receive() ([]Message, error) {
return nil, err
}
// When using nltest, it's possible for zero messages to be returned by receive.
if len(msgs) == 0 {
return msgs, nil
}
// Trim the final message with multi-part done indicator if
// present
// present.
if m := msgs[len(msgs)-1]; m.Header.Flags&HeaderFlagsMulti != 0 && m.Header.Type == HeaderTypeDone {
return msgs[:len(msgs)-1], nil
}
@ -157,7 +173,7 @@ func (c *Conn) Receive() ([]Message, error) {
// receive is the internal implementation of Conn.Receive, which can be called
// recursively to handle multi-part messages.
func (c *Conn) receive() ([]Message, error) {
msgs, err := c.c.Receive()
msgs, err := c.sock.Receive()
if err != nil {
return nil, err
}
@ -190,19 +206,93 @@ func (c *Conn) receive() ([]Message, error) {
return append(msgs, mmsgs...), nil
}
// An fder is a Socket that supports retrieving its raw file descriptor.
type fder interface {
Socket
FD() int
}
var _ io.ReadWriteCloser = &fileReadWriteCloser{}
// A fileReadWriteCloser is a limited *os.File which only allows access to its
// Read and Write methods.
type fileReadWriteCloser struct {
f *os.File
}
// Read implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Read(b []byte) (int, error) { return rwc.f.Read(b) }
// Write implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Write(b []byte) (int, error) { return rwc.f.Write(b) }
// Close implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Close() error { return rwc.f.Close() }
// ReadWriteCloser returns a raw io.ReadWriteCloser backed by the connection
// of the Conn.
//
// ReadWriteCloser is intended for advanced use cases, such as those that do
// not involve standard netlink message passing.
//
// Once invoked, it is the caller's responsibility to ensure that operations
// performed using Conn and the raw io.ReadWriteCloser do not conflict with
// each other. In almost all scenarios, only one of the two should be used.
func (c *Conn) ReadWriteCloser() (io.ReadWriteCloser, error) {
fc, ok := c.sock.(fder)
if !ok {
return nil, errReadWriteCloserNotSupported
}
return &fileReadWriteCloser{
// Backing the io.ReadWriteCloser with an *os.File enables easy reading
// and writing without more system call boilerplate.
f: os.NewFile(uintptr(fc.FD()), "netlink"),
}, nil
}
// A groupJoinLeaver is a Socket that supports joining and leaving
// netlink multicast groups.
type groupJoinLeaver interface {
Socket
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
}
// JoinGroup joins a netlink multicast group by its ID.
func (c *Conn) JoinGroup(group uint32) error {
return c.c.JoinGroup(group)
gc, ok := c.sock.(groupJoinLeaver)
if !ok {
return errMulticastGroupsNotSupported
}
return gc.JoinGroup(group)
}
// LeaveGroup leaves a netlink multicast group by its ID.
func (c *Conn) LeaveGroup(group uint32) error {
return c.c.LeaveGroup(group)
gc, ok := c.sock.(groupJoinLeaver)
if !ok {
return errMulticastGroupsNotSupported
}
return gc.LeaveGroup(group)
}
// A bpfSetter is a Socket that supports setting BPF filters.
type bpfSetter interface {
Socket
bpf.Setter
}
// SetBPF attaches an assembled BPF program to a Conn.
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return c.c.SetBPF(filter)
bc, ok := c.sock.(bpfSetter)
if !ok {
return errBPFFiltersNotSupported
}
return bc.SetBPF(filter)
}
// nextSequence atomically increments Conn's sequence number and returns

View file

@ -17,7 +17,7 @@ var (
errInvalidFamily = errors.New("received invalid netlink family")
)
var _ osConn = &conn{}
var _ Socket = &conn{}
// A conn is the Linux implementation of a netlink sockets connection.
type conn struct {
@ -29,6 +29,7 @@ type conn struct {
type socket interface {
Bind(sa unix.Sockaddr) error
Close() error
FD() int
Getsockname() (unix.Sockaddr, error)
Recvmsg(p, oob []byte, flags int) (n int, oobn int, recvflags int, from unix.Sockaddr, err error)
Sendmsg(p, oob []byte, to unix.Sockaddr, flags int) error
@ -154,6 +155,11 @@ func (c *conn) Close() error {
return c.s.Close()
}
// FD retrieves the file descriptor of the Conn.
func (c *conn) FD() int {
return c.s.FD()
}
// JoinGroup joins a multicast group by ID.
func (c *conn) JoinGroup(group uint32) error {
return c.s.SetSockopt(
@ -211,6 +217,7 @@ type sysSocket struct {
func (s *sysSocket) Bind(sa unix.Sockaddr) error { return unix.Bind(s.fd, sa) }
func (s *sysSocket) Close() error { return unix.Close(s.fd) }
func (s *sysSocket) FD() int { return s.fd }
func (s *sysSocket) Getsockname() (unix.Sockaddr, error) { return unix.Getsockname(s.fd) }
func (s *sysSocket) Recvmsg(p, oob []byte, flags int) (int, int, int, unix.Sockaddr, error) {
return unix.Recvmsg(s.fd, p, oob, flags)

View file

@ -16,14 +16,14 @@ var (
runtime.GOOS, runtime.GOARCH)
)
var _ osConn = &conn{}
var _ Socket = &conn{}
// A conn is the no-op implementation of a netlink sockets connection.
type conn struct{}
// dial is the entry point for Dial. dial always returns an error.
func dial(family int, config *Config) (*conn, error) {
return nil, errUnimplemented
func dial(family int, config *Config) (*conn, uint32, error) {
return nil, 0, errUnimplemented
}
// Send always returns an error.

View file

@ -5,6 +5,16 @@ import (
"unsafe"
)
// PutUint8 encodes a uint8 into b.
// If b is not exactly 1 byte in length, PutUint8 will panic.
func PutUint8(b []byte, v uint8) {
if l := len(b); l != 1 {
panic(fmt.Sprintf("PutUint8: unexpected byte slice length: %d", l))
}
b[0] = v
}
// PutUint16 encodes a uint16 into b using the host machine's native endianness.
// If b is not exactly 2 bytes in length, PutUint16 will panic.
func PutUint16(b []byte, v uint16) {
@ -35,6 +45,26 @@ func PutUint64(b []byte, v uint64) {
*(*uint64)(unsafe.Pointer(&b[0])) = v
}
// PutInt32 encodes a int32 into b using the host machine's native endianness.
// If b is not exactly 4 bytes in length, PutInt32 will panic.
func PutInt32(b []byte, v int32) {
if l := len(b); l != 4 {
panic(fmt.Sprintf("PutInt32: unexpected byte slice length: %d", l))
}
*(*int32)(unsafe.Pointer(&b[0])) = v
}
// Uint8 decodes a uint8 from b.
// If b is not exactly 1 byte in length, Uint8 will panic.
func Uint8(b []byte) uint8 {
if l := len(b); l != 1 {
panic(fmt.Sprintf("Uint8: unexpected byte slice length: %d", l))
}
return b[0]
}
// Uint16 decodes a uint16 from b using the host machine's native endianness.
// If b is not exactly 2 bytes in length, Uint16 will panic.
func Uint16(b []byte) uint16 {
@ -75,6 +105,14 @@ func Int32(b []byte) int32 {
return *(*int32)(unsafe.Pointer(&b[0]))
}
// Uint8Bytes encodes a uint8 into a newly-allocated byte slice. It is a
// shortcut for allocating a new byte slice and filling it using PutUint8.
func Uint8Bytes(v uint8) []byte {
b := make([]byte, 1)
PutUint8(b, v)
return b
}
// Uint16Bytes encodes a uint16 into a newly-allocated byte slice using the
// host machine's native endianness. It is a shortcut for allocating a new
// byte slice and filling it using PutUint16.
@ -101,3 +139,12 @@ func Uint64Bytes(v uint64) []byte {
PutUint64(b, v)
return b
}
// Int32Bytes encodes a int32 into a newly-allocated byte slice using the
// host machine's native endianness. It is a shortcut for allocating a new
// byte slice and filling it using PutInt32.
func Int32Bytes(v int32) []byte {
b := make([]byte, 4)
PutInt32(b, v)
return b
}

View file

@ -11,8 +11,8 @@ import (
"time"
"unicode/utf8"
"github.com/mdlayher/genetlink"
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/genetlink"
"github.com/mdlayher/netlink/nlenc"
"github.com/mdlayher/wifi/internal/nl80211"
)
@ -30,19 +30,11 @@ var _ osClient = &client{}
// netlink, generic netlink, and nl80211 to provide access to WiFi device
// actions and statistics.
type client struct {
c genl
c *genetlink.Conn
familyID uint16
familyVersion uint8
}
// genl is an interface over generic netlink, so netlink interactions can
// be stubbed in tests.
type genl interface {
Close() error
GetFamily(name string) (genetlink.Family, error)
Execute(m genetlink.Message, family uint16, flags netlink.HeaderFlags) ([]genetlink.Message, error)
}
// newClient dials a generic netlink connection and verifies that nl80211
// is available for use by this package.
func newClient() (*client, error) {
@ -51,12 +43,10 @@ func newClient() (*client, error) {
return nil, err
}
g := &sysGENL{Conn: c}
return initClient(g)
return initClient(c)
}
// initClient is the internal constructor for a client, used in tests.
func initClient(c genl) (*client, error) {
func initClient(c *genetlink.Conn) (*client, error) {
family, err := c.GetFamily(nl80211.GenlName)
if err != nil {
// Ensure the genl socket is closed on error to avoid leaking file
@ -479,15 +469,3 @@ func decodeSSID(b []byte) string {
return buf.String()
}
var _ genl = &sysGENL{}
// sysGENL is the system implementation of genl, using generic netlink.
type sysGENL struct {
*genetlink.Conn
}
// GetFamily is a small adapter to make *genetlink.Conn implement genl.
func (g *sysGENL) GetFamily(name string) (genetlink.Family, error) {
return g.Conn.Family.Get(name)
}