Skip to content
This repository has been archived by the owner on May 8, 2023. It is now read-only.

Commit

Permalink
Merge pull request #78 from Ultraporing/with_mac_filter
Browse files Browse the repository at this point in the history
Rewrote interface filtering for windows and split files into win,
  • Loading branch information
regner authored Aug 21, 2017
2 parents b598294 + f395396 commit ebd23ad
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 77 deletions.
36 changes: 2 additions & 34 deletions client/albion_watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"strings"
"time"

"github.com/google/gopacket/pcap"
"github.com/regner/albiondata-client/log"
)

Expand Down Expand Up @@ -98,38 +97,7 @@ func (apw *albionProcessWatcher) updateListeners() {
}

func (apw *albionProcessWatcher) getDevices() []string {
devices, err := pcap.FindAllDevs()

// Filter out devices that we aren't able to listen to.
// they bring error's like "NFLOG link-layer type filtering not implemented"
blacklisted := []string{"nflog", "nfqueue", "usbmon1", "usbmon2", "usbmon3", "usbmon4", "oracle"}

for _, bl := range blacklisted {
found := false
id1 := -1
for id2, device := range devices {
if device.Name == bl {
found = true
id1 = id2
break
}
}
if found {
devices = append(devices[:id1], devices[id1+1:]...)
}
}

if err != nil {
log.Fatal(err)
}
if len(devices) == 0 {
log.Fatal("Unable to find network device.")
}

strDevices := []string{}
for _, dev := range devices {
strDevices = append(strDevices, dev.Name)
}
nIfaces := GetAllPhysicalInterface()

return strDevices
return nIfaces
}
45 changes: 2 additions & 43 deletions client/net_interface_filter.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package client

import (
"net"
"strings"

"github.com/regner/albiondata-client/log"
)

// Mac Address parts to look for, and identify non physical devices. There may be more, update me!
Expand All @@ -24,50 +21,12 @@ var macAddrPartsToFilter []string = []string{

// Filters the possible physical interface address by comparing it to known popular VM Software adresses
// and Teredo Tunneling Pseudo-Interface.
func isPhysicalInterface(addr *net.HardwareAddr) bool {
func isPhysicalInterface(addr string) bool {
for _, macPart := range macAddrPartsToFilter {
if strings.HasPrefix(strings.ToLower((*addr).String()), strings.ToLower(macPart)) {
if strings.HasPrefix(strings.ToLower(addr), strings.ToLower(macPart)) {
return false
}
}

return true
}

// Gets the first physical interface based on filter results, ignoring all VM, Loopback and Tunnel interfaces
func GetFirstPhysicalInterface() *net.Interface {
ifaces, err := net.Interfaces()

if err != nil {
log.Fatal(err)
return nil
}

for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && isPhysicalInterface(&element.HardwareAddr) {
return &element
}
}

return nil
}

// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces.
func GetAllPhysicalInterface() *[]net.Interface {
ifaces, err := net.Interfaces()

if err != nil {
log.Fatal(err)
return nil
}

var outInterfaces []net.Interface

for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && isPhysicalInterface(&element.HardwareAddr) {
outInterfaces = append(outInterfaces, element)
}
}

return &outInterfaces
}
47 changes: 47 additions & 0 deletions client/net_interface_filter_nix_darw.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// +build linux darwin

package client

import (
"net"

"github.com/regner/albionmarket-client/log"
)

// Gets the first physical interface based on filter results, ignoring all VM, Loopback and Tunnel interfaces
func GetFirstPhysicalInterface() string {
ifaces, err := net.Interfaces()

if err != nil {
log.Fatal(err)
return ""
}

for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == 1 && isPhysicalInterface(element.HardwareAddr.String()) {
return element.Name
}
}

return ""
}

// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces.
func GetAllPhysicalInterface() []string {
ifaces, err := net.Interfaces()

if err != nil {
log.Fatal(err)
return nil
}

var outInterfaces []string

for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == 1 && isPhysicalInterface(element.HardwareAddr.String()) {
outInterfaces = append(outInterfaces, element.Name)
}
}

return outInterfaces
}
104 changes: 104 additions & 0 deletions client/net_interface_filter_win.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// +build windows

package client

import (
"os"
"syscall"
"unsafe"

"golang.org/x/sys/windows"
)

const (
IfOperStatusUp = 1
IF_TYPE_SOFTWARE_LOOPBACK = 24
)

const hexDigit = "0123456789abcdef"

func adapterAddresses() ([]*windows.IpAdapterAddresses, error) {
var b []byte
l := uint32(15000) // recommended initial size
for {
b = make([]byte, l)
err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
if err == nil {
if l == 0 {
return nil, nil
}
break
}
if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
return nil, os.NewSyscallError("getadaptersaddresses", err)
}
if l <= uint32(len(b)) {
return nil, os.NewSyscallError("getadaptersaddresses", err)
}
}
var aas []*windows.IpAdapterAddresses
for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next {
aas = append(aas, aa)
}
return aas, nil
}

func bytePtrToString(p *uint8) string {
a := (*[10000]uint8)(unsafe.Pointer(p))
i := 0
for a[i] != 0 {
i++
}
return string(a[:i])
}

func physicalAddrToString(physAddr [8]byte) string {
if len(physAddr) == 0 {
return ""
}
buf := make([]byte, 0, len(physAddr)*3-1)
for i, b := range physAddr {
if i > 0 {
buf = append(buf, ':')
}
buf = append(buf, hexDigit[b>>4])
buf = append(buf, hexDigit[b&0xF])
}
return string(buf)
}

// Gets the first physical interface based on filter results, ignoring all VM, Loopback and Tunnel interfaces
func GetFirstPhysicalInterface() string {
aa, _ := adapterAddresses()

for _, pa := range aa {
mac := physicalAddrToString(pa.PhysicalAddress)
name := "\\Device\\NPF_" + bytePtrToString(pa.AdapterName)
var flags uint32 = pa.Flags

if flags&uint32(IF_TYPE_SOFTWARE_LOOPBACK) == 0 && flags&uint32(IfOperStatusUp) == 1 && isPhysicalInterface(mac) {
return name
}
}

return ""
}

// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces.
func GetAllPhysicalInterface() []string {
aa, _ := adapterAddresses()

var outInterfaces []string

for _, pa := range aa {
mac := physicalAddrToString(pa.PhysicalAddress)
name := "\\Device\\NPF_" + bytePtrToString(pa.AdapterName)
var flags uint32 = pa.Flags

if flags&uint32(IF_TYPE_SOFTWARE_LOOPBACK) == 0 && flags&uint32(IfOperStatusUp) == 1 && isPhysicalInterface(mac) {
outInterfaces = append(outInterfaces, name)
}
}

return outInterfaces
}

0 comments on commit ebd23ad

Please sign in to comment.