fix: using iw if available to get supported wifi frequencies (fixes #743)

This commit is contained in:
Simone Margaritelli 2021-03-29 17:55:33 +02:00
parent c4bbc129b6
commit 6dd86c44fa
2 changed files with 68 additions and 9 deletions

View file

@ -16,7 +16,6 @@ var IPv4RouteParser = regexp.MustCompile(`^(default|[0-9]+\.[0-9]+\.[0-9]+\.[0-9
var IPv4RouteTokens = 4
var IPv4RouteCmd = "ip"
var IPv4RouteCmdOpts = []string{"route"}
var WiFiFreqParser = regexp.MustCompile(`^\s+Channel.([0-9]+)\s+:\s+([0-9\.]+)\s+GHz.*$`)
func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (*Endpoint, error)) (*Endpoint, error) {
ifname2 := tokens[3]
@ -65,15 +64,20 @@ func SetInterfaceChannel(iface string, channel int) error {
return nil
}
func processSupportedFrequencies(output string, err error) ([]int, error) {
freqs := make([]int, 0)
var iwlistFreqParser = regexp.MustCompile(`^\s+Channel.([0-9]+)\s+:\s+([0-9\.]+)\s+GHz.*$`)
func iwlistSupportedFrequencies(iface string) ([]int, error) {
out, err := core.Exec("iwlist", []string{iface, "freq"})
if err != nil {
return freqs, err
} else if output != "" {
return err
}
freqs := make([]int, 0)
if output != "" {
scanner := bufio.NewScanner(strings.NewReader(output))
for scanner.Scan() {
line := scanner.Text()
matches := WiFiFreqParser.FindStringSubmatch(line)
matches := iwlistFreqParser.FindStringSubmatch(line)
if len(matches) == 3 {
if freq, err := strconv.ParseFloat(matches[2], 64); err == nil {
freqs = append(freqs, int(freq*1000))
@ -81,10 +85,65 @@ func processSupportedFrequencies(output string, err error) ([]int, error) {
}
}
}
return freqs, nil
}
var iwPhyParser = regexp.MustCompile(`^\s*wiphy\s+(\d+)$`)
var iwFreqParser = regexp.MustCompile(`^\s+\*\s+(\d+)\s+MHz.+$`)
func iwSupportedFrequencies(iface string) ([]int, error) {
// first determine phy index
out, err := core.Exec("iw", []string{iface, "info"})
if err != nil {
return nil, fmt.Errorf("error getting %s phy index: %v", iface, err)
}
phy := int64(-1)
scanner := bufio.NewScanner(strings.NewReader(out))
for scanner.Scan() {
line := scanner.Text()
matches := iwPhyParser.FindStringSubmatch(line)
if len(matches) == 2 {
if phy, err = strconv.ParseInt(matches[1], 10, 32); err != nil {
return nil, fmt.Errorf("error parsing %s phy index: %v (line: %s)", iface, err, line)
}
}
}
if phy == -1 {
return nil, fmt.Errorf("could not find %s phy index", iface)
}
// then get phyN info
phyName := fmt.Sprintf("phy%d", phy)
out, err = core.Exec("iw", []string{phyName, "info"})
if err != nil {
return nil, fmt.Errorf("error getting %s (%s) info: %v", phyName, iface, err)
}
freqs := []int{}
scanner = bufio.NewScanner(strings.NewReader(out))
for scanner.Scan() {
line := scanner.Text()
matches := iwFreqParser.FindStringSubmatch(line)
if len(matches) == 2 {
if freq, err := strconv.ParseInt(matches[1], 10, 64); err != nil {
return nil, fmt.Errorf("error parsing %s freq: %v (line: %s)", iface, err, line)
} else {
freqs = append(freqs, int(freq))
}
}
}
return freqs, nil
}
func GetSupportedFrequencies(iface string) ([]int, error) {
out, err := core.Exec("iwlist", []string{iface, "freq"})
return processSupportedFrequencies(out, err)
if core.HasBinary("iw") {
return iwSupportedFrequencies(iface)
} else if core.HasBinary("iwlist") {
return iwlistSupportedFrequencies(iface)
}
return fmt.Errorf("no iw or iwlist binaries found in $PATH")
}