Vendor github.com/mdlayher/wifi and dependencies

This commit is contained in:
Matt Layher 2017-01-09 14:33:55 -05:00
commit 82a2b8fc02
No known key found for this signature in database
GPG key ID: 77BFE531397EDE94
34 changed files with 8970 additions and 0 deletions

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

@ -0,0 +1,10 @@
MIT License
===========
Copyright (C) 2016 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.

13
vendor/github.com/mdlayher/wifi/README.md generated vendored Normal file
View file

@ -0,0 +1,13 @@
wifi [![Build Status](https://travis-ci.org/mdlayher/wifi.svg?branch=master)](https://travis-ci.org/mdlayher/wifi) [![GoDoc](https://godoc.org/github.com/mdlayher/wifi?status.svg)](https://godoc.org/github.com/mdlayher/wifi) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/wifi)](https://goreportcard.com/report/github.com/mdlayher/wifi)
====
Package `wifi` provides access to IEEE 802.11 WiFi device actions and statistics.
MIT Licensed.
At this time, package `wifi` supports the following operating systems:
- **Linux**: using netlink, generic netlink, and nl80211.
If you would like to contribute support for another operating system, your
contributions would be very welcome! Feel free to file an issue to discuss
your plans.

36
vendor/github.com/mdlayher/wifi/client.go generated vendored Normal file
View file

@ -0,0 +1,36 @@
package wifi
// A Client is a type which can access WiFi device actions and statistics
// using operating system-specific operations.
type Client struct {
c osClient
}
// New creates a new Client.
func New() (*Client, error) {
c, err := newClient()
if err != nil {
return nil, err
}
return &Client{
c: c,
}, nil
}
// Interfaces returns a list of the system's WiFi network interfaces.
func (c *Client) Interfaces() ([]*Interface, error) {
return c.c.Interfaces()
}
// StationInfo retrieves statistics about a WiFi interface operating in
// station mode.
func (c *Client) StationInfo(ifi *Interface) (*StationInfo, error) {
return c.c.StationInfo(ifi)
}
// An osClient is the operating system-specific implementation of Client.
type osClient interface {
Interfaces() ([]*Interface, error)
StationInfo(ifi *Interface) (*StationInfo, error)
}

347
vendor/github.com/mdlayher/wifi/client_linux.go generated vendored Normal file
View file

@ -0,0 +1,347 @@
//+build linux
package wifi
import (
"errors"
"math"
"net"
"os"
"time"
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/genetlink"
"github.com/mdlayher/netlink/nlenc"
"github.com/mdlayher/wifi/internal/nl80211"
)
// Errors which may occur when interacting with generic netlink.
var (
errMultipleMessages = errors.New("expected only one generic netlink message")
errInvalidCommand = errors.New("invalid generic netlink response command")
errInvalidFamilyVersion = errors.New("invalid generic netlink response family version")
)
var _ osClient = &client{}
// A client is the Linux implementation of osClient, which makes use of
// netlink, generic netlink, and nl80211 to provide access to WiFi device
// actions and statistics.
type client struct {
c genl
familyID uint16
familyVersion uint8
}
// genl is an interface over generic netlink, so netlink interactions can
// be stubbed in tests.
type genl interface {
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) {
c, err := genetlink.Dial(nil)
if err != nil {
return nil, err
}
g := &sysGENL{Conn: c}
return initClient(g)
}
// initClient is the internal constructor for a client, used in tests.
func initClient(c genl) (*client, error) {
family, err := c.GetFamily(nl80211.GenlName)
if err != nil {
return nil, err
}
return &client{
c: c,
familyID: family.ID,
familyVersion: family.Version,
}, nil
}
// Interfaces requests that nl80211 return a list of all WiFi interfaces present
// on this system.
func (c *client) Interfaces() ([]*Interface, error) {
// Ask nl80211 to dump a list of all WiFi interfaces
req := genetlink.Message{
Header: genetlink.Header{
Command: nl80211.CmdGetInterface,
Version: c.familyVersion,
},
}
flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump
msgs, err := c.c.Execute(req, c.familyID, flags)
if err != nil {
return nil, err
}
if err := c.checkMessages(msgs, nl80211.CmdNewInterface); err != nil {
return nil, err
}
return parseInterfaces(msgs)
}
// StationInfo requests that nl80211 return station info for the specified
// Interface.
func (c *client) StationInfo(ifi *Interface) (*StationInfo, error) {
b, err := netlink.MarshalAttributes(ifi.stationInfoAttrs())
if err != nil {
return nil, err
}
// Ask nl80211 to retrieve station info for the interface specified
// by its attributes
req := genetlink.Message{
Header: genetlink.Header{
// From nl80211.h:
// * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
// * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
Command: nl80211.CmdGetStation,
Version: c.familyVersion,
},
Data: b,
}
flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump
msgs, err := c.c.Execute(req, c.familyID, flags)
if err != nil {
return nil, err
}
if len(msgs) > 1 {
return nil, errMultipleMessages
}
if err := c.checkMessages(msgs, nl80211.CmdNewStation); err != nil {
return nil, err
}
return parseStationInfo(msgs[0].Data)
}
// checkMessages verifies that response messages from generic netlink contain
// the command and family version we expect.
func (c *client) checkMessages(msgs []genetlink.Message, command uint8) error {
for _, m := range msgs {
if m.Header.Command != command {
return errInvalidCommand
}
if m.Header.Version != c.familyVersion {
return errInvalidFamilyVersion
}
}
return nil
}
// parseInterfaces parses zero or more Interfaces from nl80211 interface
// messages.
func parseInterfaces(msgs []genetlink.Message) ([]*Interface, error) {
ifis := make([]*Interface, 0, len(msgs))
for _, m := range msgs {
attrs, err := netlink.UnmarshalAttributes(m.Data)
if err != nil {
return nil, err
}
var ifi Interface
if err := (&ifi).parseAttributes(attrs); err != nil {
return nil, err
}
ifis = append(ifis, &ifi)
}
return ifis, nil
}
// stationInfoAttrs returns the netlink attributes required from an Interface
// to retrieve a StationInfo.
func (ifi *Interface) stationInfoAttrs() []netlink.Attribute {
return []netlink.Attribute{
{
Type: nl80211.AttrIfindex,
Data: nlenc.Uint32Bytes(uint32(ifi.Index)),
},
{
Type: nl80211.AttrMac,
Data: ifi.HardwareAddr,
},
}
}
// parseAttributes parses netlink attributes into an Interface's fields.
func (ifi *Interface) parseAttributes(attrs []netlink.Attribute) error {
for _, a := range attrs {
switch a.Type {
case nl80211.AttrIfindex:
ifi.Index = int(nlenc.Uint32(a.Data))
case nl80211.AttrIfname:
ifi.Name = nlenc.String(a.Data)
case nl80211.AttrMac:
ifi.HardwareAddr = net.HardwareAddr(a.Data)
case nl80211.AttrWiphy:
ifi.PHY = int(nlenc.Uint32(a.Data))
case nl80211.AttrIftype:
// NOTE: InterfaceType copies the ordering of nl80211's interface type
// constants. This may not be the case on other operating systems.
ifi.Type = InterfaceType(nlenc.Uint32(a.Data))
case nl80211.AttrWdev:
ifi.Device = int(nlenc.Uint64(a.Data))
case nl80211.AttrWiphyFreq:
ifi.Frequency = int(nlenc.Uint32(a.Data))
}
}
return nil
}
// parseStationInfo parses StationInfo attributes from a byte slice of
// netlink attributes.
func parseStationInfo(b []byte) (*StationInfo, error) {
attrs, err := netlink.UnmarshalAttributes(b)
if err != nil {
return nil, err
}
for _, a := range attrs {
// The other attributes that are returned here appear to indicate the
// interface index and MAC address, which is information we already
// possess. No need to parse them for now.
if a.Type != nl80211.AttrStaInfo {
continue
}
nattrs, err := netlink.UnmarshalAttributes(a.Data)
if err != nil {
return nil, err
}
var info StationInfo
if err := (&info).parseAttributes(nattrs); err != nil {
return nil, err
}
return &info, nil
}
// No station info found
return nil, os.ErrNotExist
}
// parseAttributes parses netlink attributes into a StationInfo's fields.
func (info *StationInfo) parseAttributes(attrs []netlink.Attribute) error {
for _, a := range attrs {
switch a.Type {
case nl80211.StaInfoConnectedTime:
// Though nl80211 does not specify, this value appears to be in seconds:
// * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
info.Connected = time.Duration(nlenc.Uint32(a.Data)) * time.Second
case nl80211.StaInfoInactiveTime:
// * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs)
info.Inactive = time.Duration(nlenc.Uint32(a.Data)) * time.Millisecond
case nl80211.StaInfoRxBytes64:
info.ReceivedBytes = nlenc.Uint64(a.Data)
case nl80211.StaInfoTxBytes64:
info.TransmittedBytes = nlenc.Uint64(a.Data)
case nl80211.StaInfoSignal:
// Converted into the typical negative strength format
// * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
info.Signal = int(a.Data[0]) - math.MaxUint8
case nl80211.StaInfoRxPackets:
info.ReceivedPackets = nlenc.Uint32(a.Data)
case nl80211.StaInfoTxPackets:
info.TransmittedPackets = nlenc.Uint32(a.Data)
case nl80211.StaInfoTxRetries:
info.TransmitRetries = nlenc.Uint32(a.Data)
case nl80211.StaInfoTxFailed:
info.TransmitFailed = nlenc.Uint32(a.Data)
case nl80211.StaInfoBeaconLoss:
info.BeaconLoss = nlenc.Uint32(a.Data)
case nl80211.StaInfoRxBitrate, nl80211.StaInfoTxBitrate:
rate, err := parseRateInfo(a.Data)
if err != nil {
return err
}
// TODO(mdlayher): return more statistics if they end up being
// generally useful
switch a.Type {
case nl80211.StaInfoRxBitrate:
info.ReceiveBitrate = rate.Bitrate
case nl80211.StaInfoTxBitrate:
info.TransmitBitrate = rate.Bitrate
}
}
// Only use 32-bit counters if the 64-bit counters are not present.
// If the 64-bit counters appear later in the slice, they will overwrite
// these values.
if info.ReceivedBytes == 0 && a.Type == nl80211.StaInfoRxBytes {
info.ReceivedBytes = uint64(nlenc.Uint32(a.Data))
}
if info.TransmittedBytes == 0 && a.Type == nl80211.StaInfoTxBytes {
info.TransmittedBytes = uint64(nlenc.Uint32(a.Data))
}
}
return nil
}
// rateInfo provides statistics about the receive or transmit rate of
// an interface.
type rateInfo struct {
// Bitrate in bits per second.
Bitrate int
}
// parseRateInfo parses a rateInfo from netlink attributes.
func parseRateInfo(b []byte) (*rateInfo, error) {
attrs, err := netlink.UnmarshalAttributes(b)
if err != nil {
return nil, err
}
var info rateInfo
for _, a := range attrs {
switch a.Type {
case nl80211.RateInfoBitrate32:
info.Bitrate = int(nlenc.Uint32(a.Data))
}
// Only use 16-bit counters if the 32-bit counters are not present.
// If the 32-bit counters appear later in the slice, they will overwrite
// these values.
if info.Bitrate == 0 && a.Type == nl80211.RateInfoBitrate {
info.Bitrate = int(nlenc.Uint16(a.Data))
}
}
// Scale bitrate to bits/second as base unit instead of 100kbits/second.
// * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
info.Bitrate *= 100 * 1000
return &info, nil
}
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)
}

35
vendor/github.com/mdlayher/wifi/client_others.go generated vendored Normal file
View file

@ -0,0 +1,35 @@
//+build !linux
package wifi
import (
"fmt"
"runtime"
)
var (
// errUnimplemented is returned by all functions on platforms that
// do not have package wifi implemented.
errUnimplemented = fmt.Errorf("package wifi not implemented on %s/%s",
runtime.GOOS, runtime.GOARCH)
)
var _ osClient = &client{}
// A conn is the no-op implementation of a netlink sockets connection.
type client struct{}
// newClient always returns an error.
func newClient() (*client, error) {
return nil, errUnimplemented
}
// Interfaces always returns an error.
func (c *client) Interfaces() ([]*Interface, error) {
return nil, errUnimplemented
}
// StationInfo always returns an error.
func (c *client) StationInfo(ifi *Interface) (*StationInfo, error) {
return nil, errUnimplemented
}

2
vendor/github.com/mdlayher/wifi/doc.go generated vendored Normal file
View file

@ -0,0 +1,2 @@
// Package wifi provides access to IEEE 802.11 WiFi device actions and statistics.
package wifi

1692
vendor/github.com/mdlayher/wifi/internal/nl80211/const.go generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
// Package nl80211 is an auto-generated package which contains constants and
// types used to access nl80211 information using generic netlink.
//
// Special thanks to Maxim Kupriianov for the cgogen tool, which makes the
// automatic generation of Go constants possible.
//
// https://github.com/xlab/cgogen
//
// Maxim was also kind enough to provide the cgogen example configuration which
// was used to create this package.
//
// https://github.com/xlab/nl80211
package nl80211
//go:generate cgogen -out ../ -nocgo nl80211.yml

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
---
GENERATOR:
PackageName: nl80211
PARSER:
IncludePaths: [/usr/include]
SourcesPaths: [nl80211.h]
TRANSLATOR:
ConstRules:
defines: expand
enum: expand
Rules:
const:
- {transform: lower}
- {action: accept, from: "(?i)nl80211_"}
- {action: replace, from: "(?i)nl80211_", to: _}
- {transform: export}
post-global:
- {load: snakecase}

127
vendor/github.com/mdlayher/wifi/wifi.go generated vendored Normal file
View file

@ -0,0 +1,127 @@
package wifi
import (
"net"
"time"
)
// An InterfaceType is the operating mode of an Interface.
type InterfaceType int
const (
// InterfaceTypeUnspecified indicates that an interface's type is unspecified
// and the driver determines its function.
InterfaceTypeUnspecified InterfaceType = iota
// InterfaceTypeAdHoc indicates that an interface is part of an independent
// basic service set (BSS) of client devices without a controlling access
// point.
InterfaceTypeAdHoc
// InterfaceTypeStation indicates that an interface is part of a managed
// basic service set (BSS) of client devices with a controlling access point.
InterfaceTypeStation
// InterfaceTypeAP indicates that an interface is an access point.
InterfaceTypeAP
// InterfaceTypeAPVLAN indicates that an interface is a VLAN interface
// associated with an access point.
InterfaceTypeAPVLAN
// InterfaceTypeWDS indicates that an interface is a wireless distribution
// interface, used as part of a network of multiple access points.
InterfaceTypeWDS
// InterfaceTypeMonitor indicates that an interface is a monitor interface,
// receiving all frames from all clients in a given network.
InterfaceTypeMonitor
// InterfaceTypeMeshPoint indicates that an interface is part of a wireless
// mesh network.
InterfaceTypeMeshPoint
// InterfaceTypeP2PClient indicates that an interface is a client within
// a peer-to-peer network.
InterfaceTypeP2PClient
// InterfaceTypeP2PGroupOwner indicates that an interface is the group
// owner within a peer-to-peer network.
InterfaceTypeP2PGroupOwner
// InterfaceTypeP2PDevice indicates that an interface is a device within
// a peer-to-peer client network.
InterfaceTypeP2PDevice
// InterfaceTypeOCB indicates that an interface is outside the context
// of a basic service set (BSS).
InterfaceTypeOCB
// InterfaceTypeNAN indicates that an interface is part of a near-me
// area network (NAN).
InterfaceTypeNAN
)
// An Interface is a WiFi network interface.
type Interface struct {
// The index of the interface.
Index int
// The name of the interface.
Name string
// The hardware address of the interface.
HardwareAddr net.HardwareAddr
// The physical device that this interface belongs to.
PHY int
// The virtual device number of this interface within a PHY.
Device int
// The operating mode of the interface.
Type InterfaceType
// The interface's wireless frequency in MHz.
Frequency int
}
// StationInfo contains statistics about a WiFi interface operating in
// station mode.
type StationInfo struct {
// The time since the station last connected.
Connected time.Duration
// The time since wireless activity last occurred.
Inactive time.Duration
// The number of bytes received by this station.
ReceivedBytes uint64
// The number of bytes transmitted by this station.
TransmittedBytes uint64
// The number of packets received by this station.
ReceivedPackets uint32
// The number of packets transmitted by this station.
TransmittedPackets uint32
// The current data receive bitrate, in bits/second.
ReceiveBitrate int
// The current data transmit bitrate, in bits/second.
TransmitBitrate int
// The signal strength of this station's connection, in dBm.
Signal int
// The number of times the station has had to retry while sending a packet.
TransmitRetries uint32
// The number of times a packet transmission failed.
TransmitFailed uint32
// The number of times a beacon loss was detected.
BeaconLoss uint32
}