package openwrt import ( "regexp" "strings" "time" ) // NONE contains the string for "none" const NONE = "none" // WifiScanner gives access to al OpenWRT Wifi Scan operations type WifiScanner struct { exec Executor iface string Cells []*WifiCell } // NewWifiScanner return an UCI instance to interact with UCI func NewWifiScanner(wIface string) *WifiScanner { exec := &localExecutor{} iface := wIface Cells := []*WifiCell{} return &WifiScanner{exec, iface, Cells} } // NewWifiWithExecutor returns a Wifi Instance an gives you the ability to provide // a different command executor than the default one. func NewWifiWithExecutor(exec Executor, wIface string) *WifiScanner { return &WifiScanner{exec, wIface, nil} } func (w *WifiScanner) getEncryption(line string) string { var enc string if strings.Contains(line, "PSK") { enc = "psk" } else if strings.Contains(line, NONE) { enc = NONE } else { enc = "unkn" } return enc } func (w *WifiScanner) parseWifiCells(stdout string) int { mac, ssid, enc := "", "", "" encOff := false macExpr := `([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])` for _, line := range strings.Split(strings.TrimSuffix(stdout, "\n"), "\n") { expr := regexp.MustCompile("^BSS") if expr.MatchString(line) { if len(mac) != 0 && len(ssid) != 0 && len(enc) == 0 { enc = NONE cell := NewWifiCell(ssid, mac, enc) w.Cells = append(w.Cells, cell) ssid, mac, enc = "", "", "" } macRegexp := regexp.MustCompile(macExpr) mac = macRegexp.FindString(line) } if strings.Contains(line, "SSID:") { ssid = strings.Split(line, ":")[1] ssid = strings.Trim(ssid, "\"") ssid = strings.Trim(ssid, " ") if ssid == "" { ssid = " " } } if strings.Contains(line, "Encryption key:off") { encOff = true } if strings.Contains(line, "Authentication suites") { enc = w.getEncryption(line) } if len(mac) > 0 && len(ssid) > 0 && (len(enc) > 0 || encOff) { if encOff { enc = NONE encOff = false } cell := NewWifiCell(ssid, mac, enc) w.Cells = append(w.Cells, cell) ssid, mac, enc = "", "", "" } } return 0 } // GetWifiCells retrieves all available wifi cells for a card ! func (w *WifiScanner) GetWifiCells() int { var res *CommandResult for try := 0; try != 20; try++ { res = w.exec.Run("iw", w.iface, "scan") if res.ReturnCode == 0 { parsing := w.parseWifiCells(res.Stdout) if parsing == 0 { if len(w.Cells) == 0 { return 242 } } return parsing } time.Sleep(time.Second * 2) } return res.ReturnCode } // GetCell retreives an WifiCell by SSID provided in parameter func (w *WifiScanner) GetCell(ssid string) *WifiCell { for _, v := range w.Cells { if v.Ssid == ssid { return v } } return nil } // Scan retreives a list of available wifi cells func (w *WifiScanner) Scan() []*WifiCell { _ = w.GetWifiCells() return w.Cells }