167 lines
4.4 KiB
Go
167 lines
4.4 KiB
Go
package upnp
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
omd "git.loafle.net/overflow/model/discovery"
|
|
omm "git.loafle.net/overflow/model/meta"
|
|
omu "git.loafle.net/overflow/model/util"
|
|
oun "git.loafle.net/overflow/util-go/net"
|
|
"git.loafle.net/overflow_scanner/probe/discovery/session"
|
|
"github.com/huin/goupnp"
|
|
)
|
|
|
|
const (
|
|
TargetRootDevice = "upnp:rootdevice"
|
|
TargetSSDPAll = "ssdp:all"
|
|
)
|
|
|
|
var (
|
|
deviceTypes = map[string]omm.MetaHostTypeEnum{
|
|
"urn:schemas-upnp-org:device:InternetGatewayDevice:1": omm.MetaHostTypeEnumRouter,
|
|
"urn:schemas-upnp-org:device:InternetGatewayDevice:2": omm.MetaHostTypeEnumRouter,
|
|
"urn:schemas-upnp-org:device:WLANAccessPointDevice:1": omm.MetaHostTypeEnumWLANAccessPoint,
|
|
"urn:schemas-upnp-org:device:MediaServer:1": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:schemas-upnp-org:device:MediaRenderer:1": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:schemas-upnp-org:device:MediaServer:2": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:schemas-upnp-org:device:MediaRenderer:2": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:schemas-upnp-org:device:MediaServer:3": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:schemas-upnp-org:device:MediaRenderer:3": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:schemas-upnp-org:device:MediaServer:4": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:schemas-upnp-org:device:MediaRenderer:4": omm.MetaHostTypeEnumMediaServer,
|
|
"urn:dial-multiscreen-org:device:dial:1": omm.MetaHostTypeEnumMultiScreen,
|
|
"urn:dial-multiscreen-org:device:dial:2": omm.MetaHostTypeEnumMultiScreen,
|
|
"urn:schemas-upnp-org:device:ScreenDevice:1": omm.MetaHostTypeEnumMultiScreen,
|
|
"urn:schemas-upnp-org:device:ScreenDevice:2": omm.MetaHostTypeEnumMultiScreen,
|
|
}
|
|
)
|
|
|
|
func Scan(discoverySession session.DiscoverySession) error {
|
|
devs, err := goupnp.DiscoverDevices(TargetRootDevice)
|
|
if nil != err {
|
|
fmt.Println("DiscoverDevices: ", err)
|
|
return nil
|
|
}
|
|
metaIPTypeEnum := omm.ToMetaIPTypeEnum(discoverySession.Zone().MetaIPType)
|
|
|
|
LOOP:
|
|
for _, dev := range devs {
|
|
rd := dev.Root.Device
|
|
if !rd.PresentationURL.Ok {
|
|
continue LOOP
|
|
}
|
|
|
|
pURL := rd.PresentationURL.URL
|
|
|
|
ip := oun.ParseIP(pURL.Hostname())
|
|
if nil == ip {
|
|
continue LOOP
|
|
}
|
|
|
|
switch metaIPTypeEnum {
|
|
case omm.MetaIPTypeEnumV4:
|
|
if 4 != ip.Version() {
|
|
continue LOOP
|
|
}
|
|
case omm.MetaIPTypeEnumV6:
|
|
if 6 != ip.Version() {
|
|
continue LOOP
|
|
}
|
|
default:
|
|
continue LOOP
|
|
}
|
|
|
|
meta := map[string]string{
|
|
"DeviceType": rd.DeviceType,
|
|
"FriendlyName": rd.FriendlyName,
|
|
"Manufacturer": rd.Manufacturer,
|
|
"ManufacturerURL": rd.ManufacturerURL.Str,
|
|
"ModelName": rd.ModelName,
|
|
"ModelDescription": rd.ModelDescription,
|
|
"ModelNumber": rd.ModelNumber,
|
|
"SerialNumber": rd.SerialNumber,
|
|
"UDN": rd.UDN,
|
|
"UPC": rd.UPC,
|
|
}
|
|
|
|
h := omd.NewHost(
|
|
discoverySession.Zone(),
|
|
discoverySession.Zone().MetaIPType,
|
|
ip.String(),
|
|
)
|
|
h.Name = rd.ModelName
|
|
h.DiscoveredDate = omu.NowPtr()
|
|
|
|
mht, ok := deviceTypes[rd.DeviceType]
|
|
if ok {
|
|
h.HostType = mht.String()
|
|
} else {
|
|
h.HostType = omm.MetaHostTypeEnumHost.String()
|
|
}
|
|
|
|
discoverySession.AddHost(
|
|
omm.ToMetaDiscovererType(omm.MetaDiscovererTypeEnumUPnP),
|
|
h,
|
|
meta,
|
|
)
|
|
|
|
portNumber, err := strconv.Atoi(pURL.Port())
|
|
if nil != err {
|
|
continue LOOP
|
|
}
|
|
|
|
p := omd.NewPort(
|
|
h,
|
|
omm.ToMetaPortType(omm.MetaPortTypeEnumTCP),
|
|
portNumber,
|
|
)
|
|
p.DiscoveredDate = omu.NowPtr()
|
|
|
|
p = discoverySession.AddPort(
|
|
omm.ToMetaDiscovererType(omm.MetaDiscovererTypeEnumUPnP),
|
|
p,
|
|
meta,
|
|
)
|
|
|
|
metaCryptoType := omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE)
|
|
serviceType := omm.MetaServiceTypeEnumUNKNOWN.String()
|
|
serviceKey := "UNKNOWN"
|
|
|
|
switch strings.ToLower(pURL.Scheme) {
|
|
case "http":
|
|
serviceKey = "HTTP"
|
|
serviceType = omm.MetaServiceTypeEnumWeb.String()
|
|
case "https":
|
|
serviceKey = "HTTPS"
|
|
metaCryptoType = omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumTLS)
|
|
serviceType = omm.MetaServiceTypeEnumWeb.String()
|
|
default:
|
|
}
|
|
|
|
s := omd.NewService(
|
|
p,
|
|
metaCryptoType,
|
|
serviceKey,
|
|
)
|
|
s.Name = pURL.Scheme
|
|
s.ServiceType = serviceType
|
|
s.DiscoveredDate = omu.NowPtr()
|
|
|
|
discoverySession.AddService(
|
|
omm.ToMetaDiscovererType(omm.MetaDiscovererTypeEnumUPnP),
|
|
s,
|
|
meta,
|
|
)
|
|
|
|
select {
|
|
case <-discoverySession.StopChan():
|
|
return nil
|
|
default:
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|