Read and parse unsolicited messages

Currently only handling CTRL-EVENT-* messages and parses them to WPAEvent.
This commit is contained in:
Matias Doyle 2017-10-16 11:26:17 +02:00
parent 0402bbb5de
commit becc4580a5
No known key found for this signature in database
GPG Key ID: D8D001818E21F4D1
2 changed files with 55 additions and 4 deletions

View File

@ -58,6 +58,7 @@ type unixgramConn struct {
c *net.UnixConn
fd uintptr
solicited, unsolicited chan message
wpaEvents chan WPAEvent
}
// socketPath is where to find the the AF_UNIX sockets for each interface. It
@ -91,12 +92,15 @@ func Unixgram(ifName string) (Conn, error) {
uc.solicited = make(chan message)
uc.unsolicited = make(chan message)
uc.wpaEvents = make(chan WPAEvent)
go uc.readLoop()
// TODO: issue an ACCEPT command so as to receive unsolicited
// messages. (We don't do this yet, since we don't yet have any way
// to consume them.)
go uc.readUnsolicited()
// Issue an ATTACH command to start receiving unsolicited events.
err = uc.runCommand("ATTACH")
if err != nil {
return nil, err
}
return uc, nil
}
@ -160,6 +164,42 @@ func (uc *unixgramConn) readLoop() {
}
}
// readUnsolicited handles messages sent to the unsolicited channel and parse them
// into a WPAEvent. At the moment we only handle `CTRL-EVENT-*` events and only events
// where the 'payload' is formatted with key=val.
func (uc *unixgramConn) readUnsolicited() {
for {
mgs := <-uc.unsolicited
data := bytes.NewBuffer(mgs.data).String()
parts := strings.Split(data, " ")
if len(parts) == 0 {
continue
}
if strings.Index(parts[0], "CTRL-") != 0 {
continue
}
event := WPAEvent{
Event: strings.TrimPrefix(parts[0], "CTRL-EVENT-"),
Arguments: make(map[string]string),
}
for _, args := range parts[1:] {
if strings.Contains(args, "=") {
keyval := strings.Split(args, "=")
if len(keyval) != 2 {
continue
}
event.Arguments[keyval[0]] = keyval[1]
}
}
uc.wpaEvents <- event
}
}
// cmd executes a command and waits for a reply.
func (uc *unixgramConn) cmd(cmd string) ([]byte, error) {
// TODO: block if any other commands are running
@ -199,6 +239,10 @@ func (err *ParseError) Error() string {
return b.String()
}
func (uc *unixgramConn) EventQueue() chan WPAEvent {
return uc.wpaEvents
}
func (uc *unixgramConn) Close() error {
return uc.c.Close()
}

View File

@ -140,6 +140,11 @@ func (r *configuredNetwork) BSSID() string { return r.bssid }
func (r *configuredNetwork) SSID() string { return r.ssid }
func (r *configuredNetwork) Flags() []string { return r.flags }
type WPAEvent struct {
Event string
Arguments map[string]string
}
// Conn is a connection to wpa_supplicant over one of its communication
// channels.
type Conn interface {
@ -197,4 +202,6 @@ type Conn interface {
// of scanned BSSs, and/or a slice of errors representing problems
// communicating with wpa_supplicant or parsing its output.
ScanResults() ([]ScanResult, []error)
EventQueue() chan WPAEvent
}