diff --git a/network/corewlan_bridge.m b/network/corewlan_bridge.m new file mode 100644 index 00000000..871a1777 --- /dev/null +++ b/network/corewlan_bridge.m @@ -0,0 +1,49 @@ +#import +#import + +const char *GetSupportedFrequencies(const char *iface) { + @autoreleasepool { + NSString *interfaceName = [NSString stringWithUTF8String:iface]; + CWInterface *interface = [CWInterface interfaceWithName:interfaceName]; + if (!interface) { + return NULL; + } + + NSSet *supportedChannels = [interface supportedWLANChannels]; + NSMutableArray *frequencies = [NSMutableArray arrayWithCapacity:[supportedChannels count]]; + + for (CWChannel *channel in supportedChannels) { + [frequencies addObject:@(channel.frequency)]; + } + + NSError *error = nil; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:frequencies options:0 error:&error]; + if (!jsonData) { + NSLog(@"Failed to serialize frequencies: %@", error); + return NULL; + } + + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + return strdup([jsonString UTF8String]); + } +} + +bool SetInterfaceChannel(const char *iface, int channel) { + @autoreleasepool { + NSString *interfaceName = [NSString stringWithUTF8String:iface]; + CWInterface *interface = [CWInterface interfaceWithName:interfaceName]; + if (!interface) { + return false; + } + + NSError *error = nil; + CWChannel *newChannel = [[CWChannel alloc] initWithChannelNumber:channel channelWidth:kCWChannelWidthUnknown]; + [interface setWLANChannel:newChannel error:&error]; + if (error) { + NSLog(@"Failed to set channel: %@", error); + return false; + } + + return true; + } +} diff --git a/network/net_darwin.go b/network/net_darwin.go index 5d339c36..f96a872d 100644 --- a/network/net_darwin.go +++ b/network/net_darwin.go @@ -1,60 +1,55 @@ package network +/* +#cgo LDFLAGS: -framework CoreWLAN +#include +#include + +const char *GetSupportedFrequencies(const char *iface); +bool SetInterfaceChannel(const char *iface, int channel); +*/ + +import "C" import ( - "fmt" + "encoding/json" + "errors" "net" - "regexp" - "strconv" - - "github.com/bettercap/bettercap/core" - - "github.com/evilsocket/islazy/str" + "unsafe" ) -const airPortPath = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport" - -var WiFiChannelParser = regexp.MustCompile(`(?m)^.*Supported Channels: (.*)$`) - -// see Windows version to understand why .... func getInterfaceName(iface net.Interface) string { return iface.Name } func SetInterfaceChannel(iface string, channel int) error { - curr := GetInterfaceChannel(iface) - // the interface is already on this channel - if curr == channel { - return nil - } + cIface := C.CString(iface) + defer C.free(unsafe.Pointer(cIface)) - _, err := core.Exec(airPortPath, []string{iface, fmt.Sprintf("-c%d", channel)}) - if err != nil { - return err + success := C.SetInterfaceChannel(cIface, C.int(channel)) + if !success { + return errors.New("failed to set interface channel") } SetInterfaceCurrentChannel(iface, channel) return nil } -func getFrequenciesFromChannels(output string) ([]int, error) { - freqs := make([]int, 0) - if output != "" { - if matches := WiFiChannelParser.FindStringSubmatch(output); len(matches) == 2 { - for _, channel := range str.Comma(matches[1]) { - re := regexp.MustCompile(`\d+`) - if channel, err := strconv.Atoi(re.FindString(channel)); err == nil { - freqs = append(freqs, Dot11Chan2Freq(channel)) - } - } - } - } - return freqs, nil -} - func GetSupportedFrequencies(iface string) ([]int, error) { - out, err := core.Exec("system_profiler", []string{"SPAirPortDataType"}) + cIface := C.CString(iface) + defer C.free(unsafe.Pointer(cIface)) + + cFrequencies := C.GetSupportedFrequencies(cIface) + if cFrequencies == nil { + return nil, errors.New("failed to get supported frequencies") + } + defer C.free(unsafe.Pointer(cFrequencies)) + + frequenciesStr := C.GoString(cFrequencies) + var frequencies []int + err := json.Unmarshal([]byte(frequenciesStr), &frequencies) if err != nil { return nil, err } - return getFrequenciesFromChannels(out) -} + + return frequencies, nil +} \ No newline at end of file