Vendor github.com/mdlayher/wifi and dependencies
This commit is contained in:
parent
e9cea11553
commit
82a2b8fc02
34 changed files with 8970 additions and 0 deletions
139
vendor/github.com/mdlayher/netlink/genetlink/conn.go
generated
vendored
Normal file
139
vendor/github.com/mdlayher/netlink/genetlink/conn.go
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
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
|
||||
|
||||
// Protocol is the netlink protocol constant used to specify generic netlink.
|
||||
const Protocol = 0x10
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// Dial dials a generic netlink connection. Config specifies optional
|
||||
// configuration for the underlying netlink connection. If config is
|
||||
// nil, a default configuration will be used.
|
||||
func Dial(config *netlink.Config) (*Conn, error) {
|
||||
c, err := netlink.Dial(Protocol, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Close closes the connection.
|
||||
func (c *Conn) Close() error {
|
||||
return c.c.Close()
|
||||
}
|
||||
|
||||
// JoinGroup joins a netlink multicast group by its ID.
|
||||
func (c *Conn) JoinGroup(group uint32) error {
|
||||
return c.c.JoinGroup(group)
|
||||
}
|
||||
|
||||
// LeaveGroup leaves a netlink multicast group by its ID.
|
||||
func (c *Conn) LeaveGroup(group uint32) error {
|
||||
return c.c.LeaveGroup(group)
|
||||
}
|
||||
|
||||
// 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
|
||||
// later validation.
|
||||
func (c *Conn) Send(m Message, family uint16, flags netlink.HeaderFlags) (netlink.Message, error) {
|
||||
nm := netlink.Message{
|
||||
Header: netlink.Header{
|
||||
Type: netlink.HeaderType(family),
|
||||
Flags: flags,
|
||||
},
|
||||
}
|
||||
|
||||
mb, err := m.MarshalBinary()
|
||||
if err != nil {
|
||||
return netlink.Message{}, err
|
||||
}
|
||||
nm.Data = mb
|
||||
|
||||
reqnm, err := c.c.Send(nm)
|
||||
if err != nil {
|
||||
return netlink.Message{}, err
|
||||
}
|
||||
|
||||
return reqnm, nil
|
||||
}
|
||||
|
||||
// Receive receives one or more Messages from netlink. The netlink.Messages
|
||||
// used to wrap each Message are available for later validation.
|
||||
func (c *Conn) Receive() ([]Message, []netlink.Message, error) {
|
||||
msgs, err := c.c.Receive()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gmsgs := make([]Message, 0, len(msgs))
|
||||
for _, nm := range msgs {
|
||||
var gm Message
|
||||
if err := (&gm).UnmarshalBinary(nm.Data); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gmsgs = append(gmsgs, gm)
|
||||
}
|
||||
|
||||
return gmsgs, msgs, nil
|
||||
}
|
||||
|
||||
// Execute sends a single Message to netlink using Conn.Send, receives one or
|
||||
// more replies using Conn.Receive, and then checks the validity of the replies
|
||||
// against the request using netlink.Validate.
|
||||
//
|
||||
// See the documentation of Conn.Send, Conn.Receive, and netlink.Validate for
|
||||
// details about each function.
|
||||
func (c *Conn) Execute(m Message, family uint16, flags netlink.HeaderFlags) ([]Message, error) {
|
||||
req, err := c.Send(m, family, flags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgs, replies, err := c.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := netlink.Validate(req, replies); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return msgs, nil
|
||||
}
|
||||
2
vendor/github.com/mdlayher/netlink/genetlink/doc.go
generated
vendored
Normal file
2
vendor/github.com/mdlayher/netlink/genetlink/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Package genetlink implements generic netlink interactions and data types.
|
||||
package genetlink
|
||||
208
vendor/github.com/mdlayher/netlink/genetlink/family.go
generated
vendored
Normal file
208
vendor/github.com/mdlayher/netlink/genetlink/family.go
generated
vendored
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
package genetlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"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
|
||||
)
|
||||
|
||||
var (
|
||||
// errInvalidFamilyVersion is returned when a family's version is greater
|
||||
// than an 8-bit integer.
|
||||
errInvalidFamilyVersion = errors.New("invalid family version attribute")
|
||||
|
||||
// errInvalidMulticastGroupArray is returned when a multicast group array
|
||||
// of attributes is malformed.
|
||||
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) {
|
||||
b, err := netlink.MarshalAttributes([]netlink.Attribute{{
|
||||
Type: attrFamilyName,
|
||||
Data: nlenc.Bytes(name),
|
||||
}})
|
||||
if err != nil {
|
||||
return Family{}, err
|
||||
}
|
||||
|
||||
req := Message{
|
||||
Header: Header{
|
||||
Command: ctrlCommandGetFamily,
|
||||
Version: ctrlVersion,
|
||||
},
|
||||
Data: b,
|
||||
}
|
||||
|
||||
msgs, err := s.c.Execute(req, Controller, netlink.HeaderFlagsRequest)
|
||||
if err != nil {
|
||||
return Family{}, err
|
||||
}
|
||||
|
||||
// TODO(mdlayher): consider interpreting generic netlink header values
|
||||
|
||||
families, err := buildFamilies(msgs)
|
||||
if err != nil {
|
||||
return Family{}, err
|
||||
}
|
||||
if len(families) != 1 {
|
||||
// If this were to ever happen, netlink must be in a state where
|
||||
// its answers cannot be trusted
|
||||
panic(fmt.Sprintf("netlink returned multiple families for name: %q", name))
|
||||
}
|
||||
|
||||
return families[0], nil
|
||||
}
|
||||
|
||||
// List retrieves all registered generic netlink families.
|
||||
func (s *FamilyService) List() ([]Family, error) {
|
||||
req := Message{
|
||||
Header: Header{
|
||||
Command: ctrlCommandGetFamily,
|
||||
Version: ctrlVersion,
|
||||
},
|
||||
}
|
||||
|
||||
flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump
|
||||
msgs, err := s.c.Execute(req, Controller, flags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buildFamilies(msgs)
|
||||
}
|
||||
|
||||
// buildFamilies builds a slice of Families by parsing attributes from the
|
||||
// input Messages.
|
||||
func buildFamilies(msgs []Message) ([]Family, error) {
|
||||
families := make([]Family, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
attrs, err := netlink.UnmarshalAttributes(m.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var f Family
|
||||
if err := (&f).parseAttributes(attrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
families = append(families, f)
|
||||
}
|
||||
|
||||
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:
|
||||
f.ID = nlenc.Uint16(a.Data)
|
||||
case attrFamilyName:
|
||||
f.Name = nlenc.String(a.Data)
|
||||
case attrVersion:
|
||||
v := nlenc.Uint32(a.Data)
|
||||
if v > math.MaxUint8 {
|
||||
return errInvalidFamilyVersion
|
||||
}
|
||||
|
||||
f.Version = uint8(v)
|
||||
case attrMulticastGroups:
|
||||
groups, err := parseMulticastGroups(a.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.Groups = groups
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseMulticastGroups parses an array of multicast group nested attributes
|
||||
// into a slice of MulticastGroups.
|
||||
func parseMulticastGroups(b []byte) ([]MulticastGroup, error) {
|
||||
attrs, err := netlink.UnmarshalAttributes(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groups := make([]MulticastGroup, 0, len(attrs))
|
||||
for i, a := range attrs {
|
||||
// The type attribute is essentially an array index here; it starts
|
||||
// at 1 and should increment for each new array element
|
||||
if int(a.Type) != i+1 {
|
||||
return nil, errInvalidMulticastGroupArray
|
||||
}
|
||||
|
||||
nattrs, err := netlink.UnmarshalAttributes(a.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var g MulticastGroup
|
||||
for _, na := range nattrs {
|
||||
switch na.Type {
|
||||
case attrMGName:
|
||||
g.Name = nlenc.String(na.Data)
|
||||
case attrMGID:
|
||||
g.ID = nlenc.Uint32(na.Data)
|
||||
}
|
||||
}
|
||||
|
||||
groups = append(groups, g)
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
20
vendor/github.com/mdlayher/netlink/genetlink/fuzz.go
generated
vendored
Normal file
20
vendor/github.com/mdlayher/netlink/genetlink/fuzz.go
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//+build gofuzz
|
||||
|
||||
package genetlink
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
return fuzzMessage(data)
|
||||
}
|
||||
|
||||
func fuzzMessage(data []byte) int {
|
||||
var m Message
|
||||
if err := (&m).UnmarshalBinary(data); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
if _, err := m.MarshalBinary(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
65
vendor/github.com/mdlayher/netlink/genetlink/message.go
generated
vendored
Normal file
65
vendor/github.com/mdlayher/netlink/genetlink/message.go
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package genetlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// errInvalidMessage is returned when a Message is malformed.
|
||||
errInvalidMessage = errors.New("generic netlink message is invalid or too short")
|
||||
)
|
||||
|
||||
// A Header is a generic netlink header. A Header is sent and received with
|
||||
// each generic netlink message to indicate metadata regarding a Message.
|
||||
type Header struct {
|
||||
// Command specifies a command to issue to netlink.
|
||||
Command uint8
|
||||
|
||||
// Version specifies the version of a command to use.
|
||||
Version uint8
|
||||
}
|
||||
|
||||
// headerLen is the length of a Header.
|
||||
const headerLen = 4
|
||||
|
||||
// A Message is a generic netlink message. It contains a Header and an
|
||||
// arbitrary byte payload, which may be decoded using information from the
|
||||
// Header.
|
||||
//
|
||||
// Data is encoded using the native endianness of the host system. Use
|
||||
// the netlink.Uint* and netlink.PutUint* functions to encode and decode
|
||||
// integers.
|
||||
type Message struct {
|
||||
Header Header
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// MarshalBinary marshals a Message into a byte slice.
|
||||
func (m Message) MarshalBinary() ([]byte, error) {
|
||||
b := make([]byte, headerLen)
|
||||
|
||||
b[0] = m.Header.Command
|
||||
b[1] = m.Header.Version
|
||||
|
||||
// b[2] and b[3] are padding bytes and set to zero
|
||||
|
||||
return append(b, m.Data...), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary unmarshals the contents of a byte slice into a Message.
|
||||
func (m *Message) UnmarshalBinary(b []byte) error {
|
||||
if len(b) < headerLen {
|
||||
return errInvalidMessage
|
||||
}
|
||||
|
||||
// Don't allow reserved pad bytes to be set
|
||||
if b[2] != 0 || b[3] != 0 {
|
||||
return errInvalidMessage
|
||||
}
|
||||
|
||||
m.Header.Command = b[0]
|
||||
m.Header.Version = b[1]
|
||||
|
||||
m.Data = b[4:]
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue