Skip to content

Commit

Permalink
Merge pull request #1 from BryanCoxwell/wip_add_nl_commands
Browse files Browse the repository at this point in the history
Wip add nl commands
  • Loading branch information
bryancoxwell committed Nov 30, 2022
2 parents a44c70b + d5d9044 commit aaca3e9
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
24 changes: 24 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package wifi

import "fmt"

// A Client is a type which can access WiFi device actions and statistics
// using operating system-specific operations.
type Client struct {
Expand Down Expand Up @@ -43,6 +45,12 @@ func (c *Client) Interfaces() ([]*Interface, error) {
return c.c.Interfaces()
}

// InterfaceByName calls Interfaces() and returns one interface or nil
// if the requested interface doesn't exist.
func (c *Client) InterfaceByName(name string) (*Interface, error) {
return c.c.InterfaceByName(name)
}

// BSS retrieves the BSS associated with a WiFi interface.
func (c *Client) BSS(ifi *Interface) (*BSS, error) {
return c.c.BSS(ifi)
Expand All @@ -52,3 +60,19 @@ func (c *Client) BSS(ifi *Interface) (*BSS, error) {
func (c *Client) StationInfo(ifi *Interface) ([]*StationInfo, error) {
return c.c.StationInfo(ifi)
}

// SetFrequency sets the frequency of a wireless interface.
func (c *Client) SetFrequency(ifi *Interface, freq int) error {
return c.c.SetFrequency(ifi, freq)
}

//SetModeMonitor sets a wireless interface iftype to MONITOR.
func (c *Client) SetModeMonitor(ifi *Interface) error {
fmt.Printf("Setting monitor mode on interface %v\n", ifi)
return c.c.SetModeMonitor(ifi)
}

//SetModeStation sets a wireless interface iftype to Station.
func (c *Client) SetModeStation(ifi *Interface) error {
return c.c.SetModeStation(ifi)
}
79 changes: 78 additions & 1 deletion client_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"os"
"time"
"unicode/utf8"

"github.com/mdlayher/genetlink"
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/nlenc"
Expand Down Expand Up @@ -85,6 +85,18 @@ func (c *client) Interfaces() ([]*Interface, error) {
return parseInterfaces(msgs)
}

// InterfaceByName calls Interfaces() and returns one interface or nil
// if the requested interface doesn't exist.
func (c *client) InterfaceByName(name string) (*Interface, error) {
interfaces, err := c.Interfaces()
if err != nil { return nil, err }

for _, i := range interfaces {
if i.Name == name { return i, nil }
}
return nil, nil
}

// Connect starts connecting the interface to the specified ssid.
func (c *client) Connect(ifi *Interface, ssid string) error {
// Ask nl80211 to connect to the specified SSID.
Expand Down Expand Up @@ -198,6 +210,71 @@ func (c *client) StationInfo(ifi *Interface) ([]*StationInfo, error) {
return stations, nil
}

// SetFrequency sets the frequency of a wireless interface.
// Does nothing if frequency is already passed in value.
func (c *client) SetFrequency(ifi *Interface, freq int) error {
if ifi.Frequency == freq { return nil }
_, err := c.get(
unix.NL80211_CMD_SET_WIPHY,
netlink.Acknowledge,
ifi,
func(ae *netlink.AttributeEncoder) {
ae.Int32(unix.NL80211_ATTR_WIPHY_FREQ, int32(freq))
},
)
if err == nil { ifi.Frequency = freq }
return err
}

// SetChannelWidth sets the channel of a wireless interface.
func (c *client) SetChannelWidth(ifi *Interface, width int) error {
_, err := c.get(
unix.NL80211_CMD_SET_WIPHY,
netlink.Acknowledge,
ifi,
func(ae *netlink.AttributeEncoder) {
ae.Int32(unix.NL80211_ATTR_CHANNEL_WIDTH, int32(width))
},
)
return err
}

// SetModeMonitor sets the interface iftype to InterfaceTypeMonitor.
// Does nothing if interface type is already InterfaceTypeMonitor.
func (c *client) SetModeMonitor(ifi *Interface) error {
if ifi.Type == InterfaceTypeMonitor { return nil }
_, err := c.setInterface(ifi, InterfaceTypeMonitor)
return err
}

// SetModeStation sets the interface iftype to InterfaceTypeStation.
// Does nothing if the interface type is already InterfaceTypeStation.
func (c *client) SetModeStation(ifi *Interface) error {
if ifi.Type == InterfaceTypeStation { return nil }
_, err := c.setInterface(ifi, InterfaceTypeStation)
return err
}

// setInterface sets the interface iftype
func (c *client) setInterface(ifi *Interface, iftype InterfaceType) ([]genetlink.Message, error) {
msgs, err := c.get(
unix.NL80211_CMD_SET_INTERFACE,
netlink.Acknowledge,
ifi,
func(ae *netlink.AttributeEncoder) {
ae.Int32(unix.NL80211_ATTR_IFTYPE, int32(iftype))
},
)
if err != nil {
return nil, err
}
ifi.Type = iftype
if len(msgs) == 0 {
return nil, os.ErrNotExist
}
return msgs, nil
}

// get performs a request/response interaction with nl80211.
func (c *client) get(
cmd uint8,
Expand Down
5 changes: 5 additions & 0 deletions client_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ func (*client) StationInfo(_ *Interface) ([]*StationInfo, error) { return nil, e
func (*client) Connect(_ *Interface, _ string) error { return errUnimplemented }
func (*client) Disconnect(_ *Interface) error { return errUnimplemented }
func (*client) ConnectWPAPSK(_ *Interface, _, _ string) error { return errUnimplemented }

func (*client) SetFrequency(_ *Interface, _ int) { return errUnimplemented }
func (*client) SetChannelWidth(_ *Interface, _ int) { return errUnimplemented }
func (*client) SetModeMonitor(_ *Interface) { return errUnimplemented }
func (*client) SetModeStation(_ *Interface) { return errUnimplemented }

0 comments on commit aaca3e9

Please sign in to comment.