vendor: bump github.com/mdlayher/wifi and dependencies (#1045)

Signed-off-by: Matt Layher <mdlayher@gmail.com>
This commit is contained in:
Matt Layher 2018-08-14 15:15:07 -04:00 committed by Ben Kochie
parent 60c827231a
commit d84873727f
10 changed files with 609 additions and 183 deletions

View file

@ -67,6 +67,16 @@ func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return c.c.SetBPF(filter)
}
// RemoveBPF removes a BPF filter from a Conn.
func (c *Conn) RemoveBPF() error {
return c.c.RemoveBPF()
}
// SetOption enables or disables a netlink socket option for the Conn.
func (c *Conn) SetOption(option netlink.ConnOption, enable bool) error {
return c.c.SetOption(option, enable)
}
// 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

View file

@ -16,10 +16,6 @@ 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")
)
// getFamily retrieves a generic netlink family with the specified name.
@ -85,13 +81,8 @@ func (c *Conn) listFamilies() ([]Family, error) {
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 {
if err := (&f).parseAttributes(m.Data); err != nil {
return nil, err
}
@ -101,66 +92,79 @@ func buildFamilies(msgs []Message) ([]Family, error) {
return families, nil
}
// parseAttributes parses netlink attributes into a Family's fields.
func (f *Family) parseAttributes(attrs []netlink.Attribute) error {
for _, a := range attrs {
switch a.Type {
// parseAttributes decodes netlink attributes into a Family's fields.
func (f *Family) parseAttributes(b []byte) error {
ad, err := netlink.NewAttributeDecoder(b)
if err != nil {
return err
}
for ad.Next() {
switch ad.Type() {
case unix.CTRL_ATTR_FAMILY_ID:
f.ID = nlenc.Uint16(a.Data)
f.ID = ad.Uint16()
case unix.CTRL_ATTR_FAMILY_NAME:
f.Name = nlenc.String(a.Data)
f.Name = ad.String()
case unix.CTRL_ATTR_VERSION:
v := nlenc.Uint32(a.Data)
v := ad.Uint32()
if v > math.MaxUint8 {
return errInvalidFamilyVersion
}
f.Version = uint8(v)
case unix.CTRL_ATTR_MCAST_GROUPS:
groups, err := parseMulticastGroups(a.Data)
if err != nil {
return err
}
ad.Do(func(b []byte) error {
groups, err := parseMulticastGroups(b)
if err != nil {
return err
}
f.Groups = groups
f.Groups = groups
return nil
})
}
}
return nil
return ad.Err()
}
// 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)
ad, err := netlink.NewAttributeDecoder(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 unix.CTRL_ATTR_MCAST_GRP_NAME:
g.Name = nlenc.String(na.Data)
case unix.CTRL_ATTR_MCAST_GRP_ID:
g.ID = nlenc.Uint32(na.Data)
var groups []MulticastGroup
for ad.Next() {
ad.Do(func(b []byte) error {
adi, err := netlink.NewAttributeDecoder(b)
if err != nil {
return err
}
}
groups = append(groups, g)
var g MulticastGroup
for adi.Next() {
switch adi.Type() {
case unix.CTRL_ATTR_MCAST_GRP_NAME:
g.Name = adi.String()
case unix.CTRL_ATTR_MCAST_GRP_ID:
g.ID = adi.Uint32()
}
}
if err := ad.Err(); err != nil {
return err
}
groups = append(groups, g)
return nil
})
}
if err := ad.Err(); err != nil {
return nil, err
}
return groups, nil

View file

@ -1,7 +1,9 @@
package netlink
import (
"encoding/binary"
"errors"
"fmt"
"github.com/mdlayher/netlink/nlenc"
)
@ -9,9 +11,6 @@ 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
@ -25,48 +24,18 @@ 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)
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)
}
nlenc.PutUint16(b[2:4], a.Type)
copy(b[nlaHeaderLen:], a.Data)
@ -80,22 +49,12 @@ func (a *Attribute) UnmarshalBinary(b []byte) error {
}
a.Length = nlenc.Uint16(b[0:2])
// 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
a.Type = nlenc.Uint16(b[2:4])
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:
@ -139,6 +98,9 @@ func MarshalAttributes(attrs []Attribute) ([]byte, error) {
}
// UnmarshalAttributes unpacks a slice of Attributes from a single byte slice.
//
// It is recommend to use the AttributeDecoder type where possible instead of calling
// UnmarshalAttributes and using package nlenc functions directly.
func UnmarshalAttributes(b []byte) ([]Attribute, error) {
var attrs []Attribute
var i int
@ -164,3 +126,173 @@ func UnmarshalAttributes(b []byte) ([]Attribute, error) {
return attrs, nil
}
// An AttributeDecoder provides a safe, iterator-like, API around attribute
// decoding.
//
// It is recommend to use an AttributeDecoder where possible instead of calling
// UnmarshalAttributes and using package nlenc functions directly.
//
// The Err method must be called after the Next method returns false to determine
// if any errors occurred during iteration.
type AttributeDecoder struct {
// ByteOrder defines a specific byte order to use when processing integer
// attributes. ByteOrder should be set immediately after creating the
// AttributeDecoder: before any attributes are parsed.
//
// If not set, the native byte order will be used.
ByteOrder binary.ByteOrder
// The attributes being worked on, and the iterator index into the slice of
// attributes.
attrs []Attribute
i int
// Any error encountered while decoding attributes.
err error
}
// NewAttributeDecoder creates an AttributeDecoder that unpacks Attributes
// from b and prepares the decoder for iteration.
func NewAttributeDecoder(b []byte) (*AttributeDecoder, error) {
attrs, err := UnmarshalAttributes(b)
if err != nil {
return nil, err
}
return &AttributeDecoder{
// By default, use native byte order.
ByteOrder: nlenc.NativeEndian(),
attrs: attrs,
}, nil
}
// Next advances the decoder to the next netlink attribute. It returns false
// when no more attributes are present, or an error was encountered.
func (ad *AttributeDecoder) Next() bool {
if ad.err != nil {
// Hit an error, stop iteration.
return false
}
ad.i++
if len(ad.attrs) < ad.i {
// No more attributes, stop iteration.
return false
}
return true
}
// Type returns the Attribute.Type field of the current netlink attribute
// pointed to by the decoder.
func (ad *AttributeDecoder) Type() uint16 {
return ad.attr().Type
}
// attr returns the current Attribute pointed to by the decoder.
func (ad *AttributeDecoder) attr() Attribute {
return ad.attrs[ad.i-1]
}
// data returns the Data field of the current Attribute pointed to by the decoder.
func (ad *AttributeDecoder) data() []byte {
return ad.attr().Data
}
// Err returns the first error encountered by the decoder.
func (ad *AttributeDecoder) Err() error {
return ad.err
}
// String returns the string representation of the current Attribute's data.
func (ad *AttributeDecoder) String() string {
if ad.err != nil {
return ""
}
return nlenc.String(ad.data())
}
// Uint8 returns the uint8 representation of the current Attribute's data.
func (ad *AttributeDecoder) Uint8() uint8 {
if ad.err != nil {
return 0
}
b := ad.data()
if len(b) != 1 {
ad.err = fmt.Errorf("netlink: attribute %d is not a uint8; length: %d", ad.Type(), len(b))
return 0
}
return uint8(b[0])
}
// Uint16 returns the uint16 representation of the current Attribute's data.
func (ad *AttributeDecoder) Uint16() uint16 {
if ad.err != nil {
return 0
}
b := ad.data()
if len(b) != 2 {
ad.err = fmt.Errorf("netlink: attribute %d is not a uint16; length: %d", ad.Type(), len(b))
return 0
}
return ad.ByteOrder.Uint16(b)
}
// Uint32 returns the uint32 representation of the current Attribute's data.
func (ad *AttributeDecoder) Uint32() uint32 {
if ad.err != nil {
return 0
}
b := ad.data()
if len(b) != 4 {
ad.err = fmt.Errorf("netlink: attribute %d is not a uint32; length: %d", ad.Type(), len(b))
return 0
}
return ad.ByteOrder.Uint32(b)
}
// Uint64 returns the uint64 representation of the current Attribute's data.
func (ad *AttributeDecoder) Uint64() uint64 {
if ad.err != nil {
return 0
}
b := ad.data()
if len(b) != 8 {
ad.err = fmt.Errorf("netlink: attribute %d is not a uint64; length: %d", ad.Type(), len(b))
return 0
}
return ad.ByteOrder.Uint64(b)
}
// Do is a general purpose function which allows access to the current data
// pointed to by the AttributeDecoder.
//
// Do can be used to allow parsing arbitrary data within the context of the
// decoder. Do is most useful when dealing with nested attributes, attribute
// arrays, or decoding arbitrary types (such as C structures) which don't fit
// cleanly into a typical unsigned integer value.
//
// The function fn should not retain any reference to the data b outside of the
// scope of the function.
func (ad *AttributeDecoder) Do(fn func(b []byte) error) {
if ad.err != nil {
return
}
b := ad.data()
if err := fn(b); err != nil {
ad.err = err
}
}

View file

@ -6,6 +6,7 @@ import (
"math/rand"
"os"
"sync/atomic"
"time"
"golang.org/x/net/bpf"
)
@ -23,6 +24,7 @@ var (
errReadWriteCloserNotSupported = errors.New("raw read/write/closer not supported")
errMulticastGroupsNotSupported = errors.New("multicast groups not supported")
errBPFFiltersNotSupported = errors.New("BPF filters not supported")
errOptionsNotSupported = errors.New("options not supported")
)
// A Conn is a connection to netlink. A Conn can be used to send and
@ -42,6 +44,9 @@ type Conn struct {
// pid is the PID assigned by netlink.
pid uint32
// d provides debugging capabilities for a Conn if not nil.
d *debugger
}
// A Socket is an operating-system specific implementation of netlink
@ -49,6 +54,7 @@ type Conn struct {
type Socket interface {
Close() error
Send(m Message) error
SendMessages(m []Message) error
Receive() ([]Message, error)
}
@ -71,15 +77,33 @@ func Dial(family int, config *Config) (*Conn, error) {
// NewConn is primarily useful for tests. Most applications should use
// Dial instead.
func NewConn(c Socket, pid uint32) *Conn {
seq := rand.Uint32()
// Seed the sequence number using a random number generator.
r := rand.New(rand.NewSource(time.Now().UnixNano()))
seq := r.Uint32()
// Configure a debugger if arguments are set.
var d *debugger
if len(debugArgs) > 0 {
d = newDebugger(debugArgs)
}
return &Conn{
sock: c,
seq: &seq,
pid: pid,
d: d,
}
}
// debug executes fn with the debugger if the debugger is not nil.
func (c *Conn) debug(fn func(d *debugger)) {
if c.d == nil {
return
}
fn(c.d)
}
// Close closes the connection.
func (c *Conn) Close() error {
return c.sock.Close()
@ -109,6 +133,51 @@ func (c *Conn) Execute(m Message) ([]Message, error) {
return replies, nil
}
func (c *Conn) fixMsg(m *Message, ml int) {
if m.Header.Length == 0 {
m.Header.Length = uint32(nlmsgAlign(ml))
}
if m.Header.Sequence == 0 {
m.Header.Sequence = c.nextSequence()
}
if m.Header.PID == 0 {
m.Header.PID = c.pid
}
}
// SendMessages sends multiple Messages to netlink. The handling of
// m.Header.Length, Sequence and PID is the same as when calling Send.
func (c *Conn) SendMessages(messages []Message) ([]Message, error) {
for idx, m := range messages {
ml := nlmsgLength(len(m.Data))
// TODO(mdlayher): fine-tune this limit.
if ml > (1024 * 32) {
return nil, errors.New("netlink message data too large")
}
c.fixMsg(&messages[idx], ml)
}
c.debug(func(d *debugger) {
for _, m := range messages {
d.debugf(1, "send msgs: %+v", m)
}
})
if err := c.sock.SendMessages(messages); err != nil {
c.debug(func(d *debugger) {
d.debugf(1, "send msgs: err: %v", err)
})
return nil, err
}
return messages, nil
}
// Send sends a single Message to netlink. In most cases, m.Header's Length,
// Sequence, and PID fields should be set to 0, so they can be populated
// automatically before the Message is sent. On success, Send returns a copy
@ -130,19 +199,17 @@ func (c *Conn) Send(m Message) (Message, error) {
return Message{}, errors.New("netlink message data too large")
}
if m.Header.Length == 0 {
m.Header.Length = uint32(nlmsgAlign(ml))
}
c.fixMsg(&m, ml)
if m.Header.Sequence == 0 {
m.Header.Sequence = c.nextSequence()
}
if m.Header.PID == 0 {
m.Header.PID = c.pid
}
c.debug(func(d *debugger) {
d.debugf(1, "send: %+v", m)
})
if err := c.sock.Send(m); err != nil {
c.debug(func(d *debugger) {
d.debugf(1, "send: err: %v", err)
})
return Message{}, err
}
@ -157,9 +224,19 @@ func (c *Conn) Send(m Message) (Message, error) {
func (c *Conn) Receive() ([]Message, error) {
msgs, err := c.receive()
if err != nil {
c.debug(func(d *debugger) {
d.debugf(1, "recv: err: %v", err)
})
return nil, err
}
c.debug(func(d *debugger) {
for _, m := range msgs {
d.debugf(1, "recv: %+v", m)
}
})
// When using nltest, it's possible for zero messages to be returned by receive.
if len(msgs) == 0 {
return msgs, nil
@ -177,37 +254,40 @@ 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.sock.Receive()
if err != nil {
return nil, err
}
// If this message is multi-part, we will need to perform an recursive call
// to continue draining the socket
var multi bool
for _, m := range msgs {
// Is this a multi-part message and is it not done yet?
if m.Header.Flags&HeaderFlagsMulti != 0 && m.Header.Type != HeaderTypeDone {
multi = true
}
if err := checkMessage(m); err != nil {
var res []Message
for {
msgs, err := c.sock.Receive()
if err != nil {
return nil, err
}
}
if !multi {
return msgs, nil
}
// If this message is multi-part, we will need to perform an recursive call
// to continue draining the socket
var multi bool
// More messages waiting
mmsgs, err := c.receive()
if err != nil {
return nil, err
}
for _, m := range msgs {
if err := checkMessage(m); err != nil {
return nil, err
}
return append(msgs, mmsgs...), nil
// Does this message indicate a multi-part message?
if m.Header.Flags&HeaderFlagsMulti == 0 {
// No, check the next messages.
continue
}
// Does this message indicate the last message in a series of
// multi-part messages from a single read?
multi = m.Header.Type != HeaderTypeDone
}
res = append(res, msgs...)
if !multi {
// No more messages coming.
return res, nil
}
}
}
// An fder is a Socket that supports retrieving its raw file descriptor.
@ -283,10 +363,11 @@ func (c *Conn) LeaveGroup(group uint32) error {
return gc.LeaveGroup(group)
}
// A bpfSetter is a Socket that supports setting BPF filters.
// A bpfSetter is a Socket that supports setting and removing BPF filters.
type bpfSetter interface {
Socket
bpf.Setter
RemoveBPF() error
}
// SetBPF attaches an assembled BPF program to a Conn.
@ -299,6 +380,45 @@ func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return bc.SetBPF(filter)
}
// RemoveBPF removes a BPF filter from a Conn.
func (c *Conn) RemoveBPF() error {
s, ok := c.sock.(bpfSetter)
if !ok {
return errBPFFiltersNotSupported
}
return s.RemoveBPF()
}
// A ConnOption is a boolean option that may be set for a Conn.
type ConnOption int
// Possible ConnOption values. These constants are equivalent to the Linux
// setsockopt boolean options for netlink sockets.
const (
PacketInfo ConnOption = iota
BroadcastError
NoENOBUFS
ListenAllNSID
CapAcknowledge
)
// An optionSetter is a Socket that supports setting netlink options.
type optionSetter interface {
Socket
SetOption(option ConnOption, enable bool) error
}
// SetOption enables or disables a netlink socket option for the Conn.
func (c *Conn) SetOption(option ConnOption, enable bool) error {
fc, ok := c.sock.(optionSetter)
if !ok {
return errOptionsNotSupported
}
return fc.SetOption(option, enable)
}
// nextSequence atomically increments Conn's sequence number and returns
// the incremented value.
func (c *Conn) nextSequence() uint32 {

View file

@ -94,6 +94,25 @@ func bind(s socket, config *Config) (*conn, uint32, error) {
}, pid, nil
}
// SendMessages serializes multiple Messages and sends them to netlink.
func (c *conn) SendMessages(messages []Message) error {
var buf []byte
for _, m := range messages {
b, err := m.MarshalBinary()
if err != nil {
return err
}
buf = append(buf, b...)
}
addr := &unix.SockaddrNetlink{
Family: unix.AF_NETLINK,
}
return c.s.Sendmsg(buf, nil, addr, 0)
}
// Send sends a single Message to netlink.
func (c *conn) Send(m Message) error {
b, err := m.MarshalBinary()
@ -112,7 +131,10 @@ func (c *conn) Send(m Message) error {
func (c *conn) Receive() ([]Message, error) {
b := make([]byte, os.Getpagesize())
for {
// Peek at the buffer to see how many bytes are available
// Peek at the buffer to see how many bytes are available.
//
// TODO(mdlayher): deal with OOB message data if available, such as
// when PacketInfo ConnOption is true.
n, _, _, _, err := c.s.Recvmsg(b, nil, unix.MSG_PEEK)
if err != nil {
return nil, err
@ -204,6 +226,58 @@ func (c *conn) SetBPF(filter []bpf.RawInstruction) error {
)
}
// RemoveBPF removes a BPF filter from a conn.
func (c *conn) RemoveBPF() error {
// dummy is ignored as argument to SO_DETACH_FILTER
// but SetSockopt requires it as an argument
var dummy uint32
return c.s.SetSockopt(
unix.SOL_SOCKET,
unix.SO_DETACH_FILTER,
unsafe.Pointer(&dummy),
uint32(unsafe.Sizeof(dummy)),
)
}
// SetOption enables or disables a netlink socket option for the Conn.
func (c *conn) SetOption(option ConnOption, enable bool) error {
o, ok := linuxOption(option)
if !ok {
// Return the typical Linux error for an unknown ConnOption.
return unix.ENOPROTOOPT
}
var v uint32
if enable {
v = 1
}
return c.s.SetSockopt(
unix.SOL_NETLINK,
o,
unsafe.Pointer(&v),
uint32(unsafe.Sizeof(v)),
)
}
// linuxOption converts a ConnOption to its Linux value.
func linuxOption(o ConnOption) (int, bool) {
switch o {
case PacketInfo:
return unix.NETLINK_PKTINFO, true
case BroadcastError:
return unix.NETLINK_BROADCAST_ERROR, true
case NoENOBUFS:
return unix.NETLINK_NO_ENOBUFS, true
case ListenAllNSID:
return unix.NETLINK_LISTEN_ALL_NSID, true
case CapAcknowledge:
return unix.NETLINK_CAP_ACK, true
default:
return 0, false
}
}
// sysToHeader converts a syscall.NlMsghdr to a Header.
func sysToHeader(r syscall.NlMsghdr) Header {
// NB: the memory layout of Header and syscall.NlMsgHdr must be
@ -247,10 +321,20 @@ func newSysSocket(lockThread bool) *sysSocket {
// But since this is very experimental, we'll leave it as a configurable at
// this point.
if lockThread {
// Never unlock the OS thread, so that the thread will terminate when
// the goroutine exits starting in Go 1.10:
// The intent is to never unlock the OS thread, so that the thread
// will terminate when the goroutine exits starting in Go 1.10:
// https://go-review.googlesource.com/c/go/+/46038.
//
// However, due to recent instability and a potential bad interaction
// with the Go runtime for threads which are not unlocked, we have
// elected to temporarily unlock the thread:
// https://github.com/golang/go/issues/25128#issuecomment-410764489.
//
// If we ever allow a Conn to set its own network namespace, we must
// either ensure that the namespace is restored on exit here or that
// the thread is properly terminated at some point in the future.
runtime.LockOSThread()
defer runtime.UnlockOSThread()
}
defer wg.Done()

View file

@ -5,14 +5,12 @@ package netlink
import (
"fmt"
"runtime"
"golang.org/x/net/bpf"
)
var (
// errUnimplemented is returned by all functions on platforms that
// cannot make use of netlink sockets.
errUnimplemented = fmt.Errorf("netlink sockets not implemented on %s/%s",
errUnimplemented = fmt.Errorf("netlink: not implemented on %s/%s",
runtime.GOOS, runtime.GOARCH)
)
@ -21,42 +19,13 @@ 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, uint32, error) {
return nil, 0, errUnimplemented
}
// All cross-platform functions and Socket methods are unimplemented outside
// of Linux.
// Send always returns an error.
func (c *conn) Send(m Message) error {
return errUnimplemented
}
func dial(_ int, _ *Config) (*conn, uint32, error) { return nil, 0, errUnimplemented }
func newError(_ int) error { return errUnimplemented }
// Receive always returns an error.
func (c *conn) Receive() ([]Message, error) {
return nil, errUnimplemented
}
// Close always returns an error.
func (c *conn) Close() error {
return errUnimplemented
}
// JoinGroup always returns an error.
func (c *conn) JoinGroup(group uint32) error {
return errUnimplemented
}
// LeaveGroup always returns an error.
func (c *conn) LeaveGroup(group uint32) error {
return errUnimplemented
}
// SetBPF always returns an error.
func (c *conn) SetBPF(filter []bpf.RawInstruction) error {
return errUnimplemented
}
// newError always returns an error.
func newError(errno int) error {
return errUnimplemented
}
func (c *conn) Send(_ Message) error { return errUnimplemented }
func (c *conn) SendMessages(_ []Message) error { return errUnimplemented }
func (c *conn) Receive() ([]Message, error) { return nil, errUnimplemented }
func (c *conn) Close() error { return errUnimplemented }

71
vendor/github.com/mdlayher/netlink/debug.go generated vendored Normal file
View file

@ -0,0 +1,71 @@
package netlink
import (
"fmt"
"log"
"os"
"strconv"
"strings"
)
var (
// Arguments used to create a debugger.
debugArgs []string
)
func init() {
// Is netlink debugging enabled?
s := os.Getenv("NLDEBUG")
if s == "" {
return
}
debugArgs = strings.Split(s, ",")
}
// A debugger is used to provide debugging information about a netlink connection.
type debugger struct {
Log *log.Logger
Level int
}
// newDebugger creates a debugger by parsing key=value arguments.
func newDebugger(args []string) *debugger {
d := &debugger{
Log: log.New(os.Stderr, "nl: ", 0),
Level: 1,
}
for _, a := range args {
kv := strings.Split(a, "=")
if len(kv) != 2 {
// Ignore malformed pairs and assume callers wants defaults.
continue
}
switch kv[0] {
// Select the log level for the debugger.
case "level":
level, err := strconv.Atoi(kv[1])
if err != nil {
panicf("netlink: invalid NLDEBUG level: %q", a)
}
d.Level = level
}
}
return d
}
// debugf prints debugging information at the specified level, if d.Level is
// high enough to print the message.
func (d *debugger) debugf(level int, format string, v ...interface{}) {
if d.Level >= level {
d.Log.Printf(format, v...)
}
}
func panicf(format string, a ...interface{}) {
panic(fmt.Sprintf(format, a...))
}

View file

@ -1,2 +1,22 @@
// Package netlink provides low-level access to Linux netlink sockets.
//
//
// Debugging
//
// This package supports rudimentary netlink connection debugging support.
// To enable this, run your binary with the NLDEBUG environment variable set.
// Debugging information will be output to stderr with a prefix of "nl:".
//
// To use the debugging defaults, use:
//
// $ NLDEBUG=1 ./nlctl
//
// To configure individual aspects of the debugger, pass key/value options such
// as:
//
// $ NLDEBUG=level=1 ./nlctl
//
// Available key/value debugger options include:
//
// level=N: specify the debugging level (only "1" is currently supported)
package netlink

16
vendor/github.com/mdlayher/netlink/nlenc/endian.go generated vendored Normal file
View file

@ -0,0 +1,16 @@
package nlenc
import (
"encoding/binary"
)
// NativeEndian returns the native byte order of this system.
func NativeEndian() binary.ByteOrder {
// Determine endianness by storing a uint16 in a byte slice.
b := Uint16Bytes(1)
if b[0] == 1 {
return binary.LittleEndian
}
return binary.BigEndian
}

22
vendor/vendor.json vendored
View file

@ -85,28 +85,28 @@
"versionExact": "v1.0.0"
},
{
"checksumSHA1": "VZIJG8dML/XqZbL9bpeDNgkazcg=",
"checksumSHA1": "zLH8BV9kYzpqGB5PS4VDjADFvVM=",
"path": "github.com/mdlayher/genetlink",
"revision": "76fecce4c787fb8eaa21a8755f722d67c53038e1",
"revisionTime": "2017-09-01T18:19:24Z"
"revision": "ca85b5a307448462b0aa7a07c67c0846bc12568f",
"revisionTime": "2018-07-28T17:03:40Z"
},
{
"checksumSHA1": "S6NatJYh1aOFzSIs6Agp2R0ydtM=",
"checksumSHA1": "ybkJbYD6wyjdoPp/KncnDpCyYiU=",
"path": "github.com/mdlayher/netlink",
"revision": "756e798fb38fac19fb2234d3acc32e902bc1af44",
"revisionTime": "2017-12-14T18:12:53Z"
"revision": "80a6f93efd374ddee4e0ea862ca0085ef42eed65",
"revisionTime": "2018-08-10T15:28:04Z"
},
{
"checksumSHA1": "9nig0WuuiTICStI/8S+pIGqYksc=",
"checksumSHA1": "P7eEo2V7/kQEkt2ihW+26S39eEw=",
"path": "github.com/mdlayher/netlink/nlenc",
"revision": "756e798fb38fac19fb2234d3acc32e902bc1af44",
"revisionTime": "2017-12-14T18:12:53Z"
"revision": "80a6f93efd374ddee4e0ea862ca0085ef42eed65",
"revisionTime": "2018-08-10T15:28:04Z"
},
{
"checksumSHA1": "Y7cjrOeOvA/ic+B8WCp2JyLEuvs=",
"path": "github.com/mdlayher/wifi",
"revision": "9a2549315201616119128afe421d1601ef3506f9",
"revisionTime": "2018-06-15T12:49:15Z"
"revision": "efdf3f4195d9fc8b73013b3706fe626b7fb807d8",
"revisionTime": "2018-07-27T16:38:19Z"
},
{
"checksumSHA1": "VzutdH69PUqRqhrDVv6F91ebQd4=",