add some iface fun and don't start dlna on loopback and tunnels

This commit is contained in:
nikk gitanes
2021-09-13 02:39:45 +03:00
parent 44f1cfbd9d
commit 02b749a4c4
5 changed files with 182 additions and 4 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/anacrolix/dms/dlna/dms"
"server/log"
"server/utils"
"server/web/pages/template"
)
@@ -21,11 +22,16 @@ func Start() {
dmsServer = &dms.Server{
Interfaces: func() (ifs []net.Interface) {
var err error
ifs, err = net.Interfaces()
ifaces, err := net.Interfaces()
if err != nil {
log.TLogln(err)
os.Exit(1)
}
for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == net.FlagUp && element.Flags&net.FlagMulticast == net.FlagMulticast && utils.IsPhysicalInterface(element.HardwareAddr.String()) {
ifs = append(ifs, element)
}
}
return
}(),
HTTPConn: func() net.Listener {
@@ -159,7 +165,7 @@ func getDefaultFriendlyName() string {
var list []string
for _, i := range ifaces {
addrs, _ := i.Addrs()
if i.Flags&net.FlagUp == net.FlagUp {
if i.Flags&net.FlagLoopback == 0 && i.Flags&net.FlagUp == net.FlagUp && i.Flags&net.FlagMulticast == net.FlagMulticast && utils.IsPhysicalInterface(i.HardwareAddr.String()) {
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {

View File

@@ -115,7 +115,7 @@ func getTorrent(path, host string) (ret []interface{}) {
func getTorrentMeta(path, host string) (ret interface{}) {
if path=="/" {
if path == "/" {
rootObj := upnpav.Object{
ID: "0",
ParentID: "-1",

View File

@@ -0,0 +1,38 @@
package utils
import (
"strings"
)
type PhysicalInterface struct {
MACAddress string
Name string
FriendlyName string
}
// Mac Address parts to look for, and identify non physical devices. There may be more, update me!
var macAddrPartsToFilter []string = []string{
"00:03:FF", // Microsoft Hyper-V, Virtual Server, Virtual PC
"0A:00:27", // VirtualBox
"00:00:00:00:00", // Teredo Tunneling Pseudo-Interface
"00:50:56", // VMware ESX 3, Server, Workstation, Player
"00:1C:14", // VMware ESX 3, Server, Workstation, Player
"00:0C:29", // VMware ESX 3, Server, Workstation, Player
"00:05:69", // VMware ESX 3, Server, Workstation, Player
"00:1C:42", // Microsoft Hyper-V, Virtual Server, Virtual PC
"00:0F:4B", // Virtual Iron 4
"00:16:3E", // Red Hat Xen, Oracle VM, XenSource, Novell Xen
"08:00:27", // Sun xVM VirtualBox
"7A:79", // Hamachi
}
// Filters the possible physical interface address by comparing it to known popular VM Software adresses
// and Teredo Tunneling Pseudo-Interface.
func IsPhysicalInterface(addr string) bool {
for _, macPart := range macAddrPartsToFilter {
if strings.HasPrefix(strings.ToLower(addr), strings.ToLower(macPart)) {
return false
}
}
return true
}

View File

@@ -0,0 +1,29 @@
//go:build linux || darwin
// +build linux darwin
package utils
import (
"fmt"
"net"
)
// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces.
func GetAllPhysicalInterfaces() []PhysicalInterface {
ifaces, err := net.Interfaces()
if err != nil {
fmt.Println(err)
return nil
}
var outInterfaces []PhysicalInterface
for _, element := range ifaces {
if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == 1 && isPhysicalInterface(element.HardwareAddr.String()) {
outInterfaces = append(outInterfaces, PhysicalInterface{MACAddress: element.HardwareAddr.String(), Name: element.Name, FriendlyName: element.Name})
}
}
return outInterfaces
}

View File

@@ -0,0 +1,105 @@
//go:build windows
// +build windows
package utils
import (
"os"
"syscall"
"unicode/utf16"
"unsafe"
"golang.org/x/sys/windows"
)
const (
IfOperStatusUp = 1
IF_TYPE_SOFTWARE_LOOPBACK = 24
IF_TYPE_TUNNEL = 131
)
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)
}
func cStringToString(cs *uint16) (s string) {
if cs != nil {
us := make([]uint16, 0, 256)
for p := uintptr(unsafe.Pointer(cs)); ; p += 2 {
u := *(*uint16)(unsafe.Pointer(p))
if u == 0 {
return string(utf16.Decode(us))
}
us = append(us, u)
}
}
return ""
}
// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces.
func GetAllPhysicalInterfaces() []PhysicalInterface {
aa, _ := adapterAddresses()
var outInterfaces []PhysicalInterface
for _, pa := range aa {
mac := physicalAddrToString(pa.PhysicalAddress)
name := "\\Device\\NPF_" + bytePtrToString(pa.AdapterName)
if pa.IfType != uint32(IF_TYPE_SOFTWARE_LOOPBACK) && pa.IfType != uint32(IF_TYPE_TUNNEL) &&
pa.OperStatus == uint32(IfOperStatusUp) && IsPhysicalInterface(mac) {
outInterfaces = append(outInterfaces, PhysicalInterface{MACAddress: mac, Name: name, FriendlyName: cStringToString(pa.FriendlyName)})
}
}
return outInterfaces
}