268 lines
6.6 KiB
Go
268 lines
6.6 KiB
Go
package wifi
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
// errInvalidIE is returned when one or more IEs are malformed.
|
|
errInvalidIE = errors.New("invalid 802.11 information element")
|
|
)
|
|
|
|
// 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
|
|
)
|
|
|
|
// String returns the string representation of an InterfaceType.
|
|
func (t InterfaceType) String() string {
|
|
switch t {
|
|
case InterfaceTypeUnspecified:
|
|
return "unspecified"
|
|
case InterfaceTypeAdHoc:
|
|
return "ad-hoc"
|
|
case InterfaceTypeStation:
|
|
return "station"
|
|
case InterfaceTypeAP:
|
|
return "access point"
|
|
case InterfaceTypeWDS:
|
|
return "wireless distribution"
|
|
case InterfaceTypeMonitor:
|
|
return "monitor"
|
|
case InterfaceTypeMeshPoint:
|
|
return "mesh point"
|
|
case InterfaceTypeP2PClient:
|
|
return "P2P client"
|
|
case InterfaceTypeP2PGroupOwner:
|
|
return "P2P group owner"
|
|
case InterfaceTypeP2PDevice:
|
|
return "P2P device"
|
|
case InterfaceTypeOCB:
|
|
return "outside context of BSS"
|
|
case InterfaceTypeNAN:
|
|
return "near-me area network"
|
|
default:
|
|
return fmt.Sprintf("unknown(%d)", t)
|
|
}
|
|
}
|
|
|
|
// 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 hardware address of the station.
|
|
HardwareAddr net.HardwareAddr
|
|
|
|
// 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 int
|
|
|
|
// The number of bytes transmitted by this station.
|
|
TransmittedBytes int
|
|
|
|
// The number of packets received by this station.
|
|
ReceivedPackets int
|
|
|
|
// The number of packets transmitted by this station.
|
|
TransmittedPackets int
|
|
|
|
// 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 int
|
|
|
|
// The number of times a packet transmission failed.
|
|
TransmitFailed int
|
|
|
|
// The number of times a beacon loss was detected.
|
|
BeaconLoss int
|
|
}
|
|
|
|
// A BSS is an 802.11 basic service set. It contains information about a wireless
|
|
// network associated with an Interface.
|
|
type BSS struct {
|
|
// The service set identifier, or "network name" of the BSS.
|
|
SSID string
|
|
|
|
// The BSS service set identifier. In infrastructure mode, this is the
|
|
// hardware address of the wireless access point that a client is associated
|
|
// with.
|
|
BSSID net.HardwareAddr
|
|
|
|
// The frequency used by the BSS, in MHz.
|
|
Frequency int
|
|
|
|
// The interval between beacon transmissions for this BSS.
|
|
BeaconInterval time.Duration
|
|
|
|
// The time since the client last scanned this BSS's information.
|
|
LastSeen time.Duration
|
|
|
|
// The status of the client within the BSS.
|
|
Status BSSStatus
|
|
}
|
|
|
|
// A BSSStatus indicates the current status of client within a BSS.
|
|
type BSSStatus int
|
|
|
|
const (
|
|
// BSSStatusAuthenticated indicates that a client is authenticated with a BSS.
|
|
BSSStatusAuthenticated BSSStatus = iota
|
|
|
|
// BSSStatusAssociated indicates that a client is associated with a BSS.
|
|
BSSStatusAssociated
|
|
|
|
// BSSStatusIBSSJoined indicates that a client has joined an independent BSS.
|
|
BSSStatusIBSSJoined
|
|
)
|
|
|
|
// String returns the string representation of a BSSStatus.
|
|
func (s BSSStatus) String() string {
|
|
switch s {
|
|
case BSSStatusAuthenticated:
|
|
return "authenticated"
|
|
case BSSStatusAssociated:
|
|
return "associated"
|
|
case BSSStatusIBSSJoined:
|
|
return "IBSS joined"
|
|
default:
|
|
return fmt.Sprintf("unknown(%d)", s)
|
|
}
|
|
}
|
|
|
|
// List of 802.11 Information Element types.
|
|
const (
|
|
ieSSID = 0
|
|
)
|
|
|
|
// An ie is an 802.11 information element.
|
|
type ie struct {
|
|
ID uint8
|
|
// Length field implied by length of data
|
|
Data []byte
|
|
}
|
|
|
|
// parseIEs parses zero or more ies from a byte slice.
|
|
// Reference:
|
|
// https://www.safaribooksonline.com/library/view/80211-wireless-networks/0596100523/ch04.html#wireless802dot112-CHP-4-FIG-31
|
|
func parseIEs(b []byte) ([]ie, error) {
|
|
var ies []ie
|
|
var i int
|
|
for {
|
|
if len(b[i:]) == 0 {
|
|
break
|
|
}
|
|
if len(b[i:]) < 2 {
|
|
return nil, errInvalidIE
|
|
}
|
|
|
|
id := b[i]
|
|
i++
|
|
l := int(b[i])
|
|
i++
|
|
|
|
if len(b[i:]) < l {
|
|
return nil, errInvalidIE
|
|
}
|
|
|
|
ies = append(ies, ie{
|
|
ID: id,
|
|
Data: b[i : i+l],
|
|
})
|
|
|
|
i += l
|
|
}
|
|
|
|
return ies, nil
|
|
}
|