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 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 }