1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
package network
import (
"bufio"
"fmt"
"net"
"regexp"
"strconv"
"strings"
"github.com/bettercap/bettercap/core"
)
// see Windows version to understand why ....
func getInterfaceName(iface net.Interface) string {
return iface.Name
}
// See https://github.com/bettercap/bettercap/issues/819
func ForceMonitorMode(iface string) error {
_, _ = core.Exec("ip", []string{"link", "set", iface, "down"})
out, err := core.Exec("iw", []string{"dev", iface, "set", "type", "monitor"})
if err != nil {
return fmt.Errorf("iw: out=%s err=%s", out, err)
} else if out != "" {
return fmt.Errorf("Unexpected output while setting interface %s into monitor mode: %s", iface, out)
}
_, _ = core.Exec("ip", []string{"link", "set", iface, "up"})
return nil
}
func SetInterfaceChannel(iface string, channel int) error {
curr := GetInterfaceChannel(iface)
// the interface is already on this channel
if curr == channel {
return nil
}
if core.HasBinary("iw") {
// Debug("SetInterfaceChannel(%s, %d) iw based", iface, channel)
out, err := core.Exec("iw", []string{"dev", iface, "set", "channel", fmt.Sprintf("%d", channel)})
if err != nil {
return fmt.Errorf("iw: out=%s err=%s", out, err)
} else if out != "" {
return fmt.Errorf("Unexpected output while setting interface %s to channel %d: %s", iface, channel, out)
}
} else if core.HasBinary("iwconfig") {
// Debug("SetInterfaceChannel(%s, %d) iwconfig based")
out, err := core.Exec("iwconfig", []string{iface, "channel", fmt.Sprintf("%d", channel)})
if err != nil {
return fmt.Errorf("iwconfig: out=%s err=%s", out, err)
} else if out != "" {
return fmt.Errorf("Unexpected output while setting interface %s to channel %d: %s", iface, channel, out)
}
} else {
return fmt.Errorf("no iw or iwconfig binaries found in $PATH")
}
SetInterfaceCurrentChannel(iface, channel)
return nil
}
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 nil, err
}
freqs := make([]int, 0)
if out != "" {
scanner := bufio.NewScanner(strings.NewReader(out))
for scanner.Scan() {
line := scanner.Text()
matches := iwlistFreqParser.FindStringSubmatch(line)
if len(matches) == 3 {
if freq, err := strconv.ParseFloat(matches[2], 64); err == nil {
freqs = append(freqs, int(freq*1000))
}
}
}
}
return freqs, nil
}
var iwPhyParser = regexp.MustCompile(`^\s*wiphy\s+(\d+)$`)
var iwFreqParser = regexp.MustCompile(`^\s+\*\s+(\d+)\s+MHz.+dBm.+$`)
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) {
// give priority to iwlist because of https://github.com/bettercap/bettercap/issues/881
if core.HasBinary("iwlist") {
return iwlistSupportedFrequencies(iface)
} else if core.HasBinary("iw") {
return iwSupportedFrequencies(iface)
}
return nil, fmt.Errorf("no iw or iwlist binaries found in $PATH")
}
|