package moved

This commit is contained in:
crusader
2018-08-29 13:08:37 +09:00
parent 0f9f14aedc
commit 01b201266c
15 changed files with 0 additions and 87 deletions

View File

@@ -0,0 +1,177 @@
package dhcp
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"strings"
)
const (
MAGIC_COOKIE uint32 = 0x63825363
OPT_CODE_SERVER_IDENTIFIER uint8 = 54
OPT_CODE_SUBNET_MASK uint8 = 1
OPT_CODE_ROUTER uint8 = 3
OPT_CODE_DNS uint8 = 6
)
type dhcpDiscover struct {
MsgType byte
HwType byte
HwAddrLen byte
Hops byte
Xid uint32
Secs uint16
BootpFlags uint16
ClientIp uint32
YourIp uint32
NextServerIp uint32
RelayAgentIp uint32
ClientMacAddr [6]byte
ClientHwAddrPadding [10]byte
ServerHostName [64]byte
BootFileName [128]byte
MagicCookie uint32
Mtype byte
MtypeLen byte
MtypeVal byte
Opts [200]byte
End byte
Padding [16]byte
}
func doDiscover(address string) (map[string]string, error) {
localAddr, err := net.ResolveUDPAddr("udp", address+":68")
if err != nil {
return nil, err
}
conn, err := net.ListenUDP("udp", localAddr)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
defer conn.Close()
sendDiscover(conn) // broadcast 255.255.255.255:67
return readOffer(conn) // unicast
}
func sendDiscover(conn *net.UDPConn) error {
server := fmt.Sprintf("%s:%d", "255.255.255.255", 67)
serverAddr, err := net.ResolveUDPAddr("udp", server)
if err != nil {
return err
}
dhcp := dhcpDiscover{
MsgType: 0x01,
HwType: 0x01,
HwAddrLen: 0x06,
Hops: 0x00,
Xid: 0x00000000,
Secs: 0x0000,
ClientIp: 0x00000000,
YourIp: 0x00000000,
NextServerIp: 0x00000000,
RelayAgentIp: 0x00000000,
MagicCookie: MAGIC_COOKIE,
Mtype: 0x35,
MtypeLen: 0x01,
MtypeVal: 0x01,
End: 0xff,
}
var flag uint16 = 0
dhcp.BootpFlags = ^flag // flag = unicast , ^flag = broadcast
writer := new(bytes.Buffer)
if err := binary.Write(writer, binary.BigEndian, dhcp); err != nil {
return err
}
_, err = conn.WriteToUDP(writer.Bytes(), serverAddr)
if err != nil {
return err
}
return nil
}
func readOffer(conn *net.UDPConn) (map[string]string, error) {
offerOptions := make(map[string]string)
buf := make([]byte, 1024)
_, _, err := conn.ReadFromUDP(buf)
if err != nil {
return nil, err
}
offer := dhcpDiscover{}
reader := new(bytes.Buffer)
reader.Write(buf)
if err := binary.Read(reader, binary.BigEndian, &offer); err != nil {
return nil, err
}
if offer.MagicCookie != MAGIC_COOKIE {
return nil, err
}
//option searching
r := new(bytes.Buffer)
r.Write(offer.Opts[:])
for i := 0; i < r.Len(); i++ {
v := r.Next(1)[0]
if v == OPT_CODE_SUBNET_MASK && r.Next(1)[0] == 4 {
ipStr := byteToIPString(r.Next(4))
offerOptions["SUBNETMASK"] = ipStr
}
if v == OPT_CODE_ROUTER && r.Next(1)[0] == 4 {
ipStr := byteToIPString(r.Next(4))
offerOptions["ROUTER"] = ipStr
}
if v == OPT_CODE_DNS {
len := r.Next(1)[0]
var dns []string
var ipStr string
ipStr = byteToIPString(r.Next(4))
dns = append(dns, ipStr)
if len == 8 {
ipStr = byteToIPString(r.Next(4))
dns = append(dns, ipStr)
}
offerOptions["DNS"] = strings.Join(dns, ",")
}
if v == OPT_CODE_SERVER_IDENTIFIER && r.Next(1)[0] == 4 {
ipStr := byteToIPString(r.Next(4))
offerOptions["DHCP_SERVER"] = ipStr
}
}
return offerOptions, nil
}
func byteToIPString(b []byte) string {
var ipStr string
len := len(b)
for i := 0; i < len; i++ {
v := b[i]
ipStr += fmt.Sprintf("%d", v)
if i < len-1 {
ipStr += "."
}
}
return ipStr
}

View File

@@ -0,0 +1,13 @@
package dhcp
import (
"testing"
)
func TestDHCP(t *testing.T) {
offer, err := doDiscover("192.168.1.201")
if err != nil {
t.Errorf("ERROR : %s", err.Error())
}
t.Log(offer)
}

View File

@@ -0,0 +1,215 @@
package mdns
import (
"context"
"encoding/json"
"fmt"
"log"
"strconv"
"strings"
"sync/atomic"
"time"
omd "git.loafle.net/overflow/model/discovery"
omm "git.loafle.net/overflow/model/meta"
omu "git.loafle.net/overflow/model/util"
"git.loafle.net/overflow_scanner/probe/model"
"github.com/grandcat/zeroconf"
)
func Scan(discovered model.Discovered) {
serviceEntries, err := browse("_services._dns-sd._udp", "local")
if nil != err {
log.Print("Cannot find service ", err)
}
metaIPTypeEnum := omm.ToMetaIPTypeEnum(discovered.Zone().MetaIPType)
for _, serviceEntry := range serviceEntries {
name := removeDomainName(serviceEntry.Instance, serviceEntry.Domain)
entries, _err := browse(name, serviceEntry.Domain)
if nil != _err {
log.Print("Cannot find entry ", _err)
return
}
LOOP:
for _, entry := range entries {
log.Print("serviceEntry ", entry)
name := entry.Instance // HP\ LaserJet\ P1505n
service := entry.Service // _pdl-datastream._tcp
port := entry.Port // 9100
meta := toMeta(entry.Text)
hostName := removeDomainName(entry.HostName, entry.Domain) // NPIFACA9B
serviceName, portType, cryptoType := parseService(service)
var metaPortType *omm.MetaPortType
switch portType {
case "tcp":
metaPortType = omm.ToMetaPortType(omm.MetaPortTypeEnumTCP)
case "udp":
metaPortType = omm.ToMetaPortType(omm.MetaPortTypeEnumUDP)
}
metaCryptoType := omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumUNKNOWN)
switch cryptoType {
case "NONE":
metaCryptoType = omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE)
case "TLS":
metaCryptoType = omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumTLS)
}
switch metaIPTypeEnum {
case omm.MetaIPTypeEnumV4:
for _, ipv4 := range entry.AddrIPv4 {
h := discovered.AddHost(&omd.Host{
MetaIPType: omm.ToMetaIPType(metaIPTypeEnum),
Name: hostName,
Address: ipv4.String(),
Meta: meta,
Zone: discovered.Zone(),
DiscoveredDate: omu.NowPtr(),
})
if 1 > port {
continue LOOP
}
p := discovered.AddPort(&omd.Port{
MetaPortType: metaPortType,
PortNumber: json.Number(strconv.Itoa(port)),
Meta: meta,
Host: h,
})
discovered.AddService(&omd.Service{
MetaCryptoType: metaCryptoType,
Key: serviceName,
Name: name,
Port: p,
})
}
case omm.MetaIPTypeEnumV6:
for _, ipv6 := range entry.AddrIPv6 {
h := discovered.AddHost(&omd.Host{
MetaIPType: omm.ToMetaIPType(metaIPTypeEnum),
Name: hostName,
Address: ipv6.String(),
Meta: meta,
Zone: discovered.Zone(),
DiscoveredDate: omu.NowPtr(),
})
if 1 > port {
continue LOOP
}
p := discovered.AddPort(&omd.Port{
MetaPortType: metaPortType,
PortNumber: json.Number(strconv.Itoa(port)),
Meta: meta,
Host: h,
})
discovered.AddService(&omd.Service{
MetaCryptoType: metaCryptoType,
Key: serviceName,
Name: name,
Port: p,
})
}
}
}
}
}
func removeDomainName(instance string, domain string) (service string) {
_instance := strings.TrimRight(instance, ".")
return strings.TrimRight(_instance, fmt.Sprintf(".%s", domain))
}
func toMeta(text []string) map[string]string {
if nil == text || 0 == len(text) {
return nil
}
meta := make(map[string]string)
for _, v := range text {
ss := strings.SplitN(v, "=", 2)
if 2 != len(ss) {
continue
}
if nil != ss {
meta[ss[0]] = ss[1]
}
}
return meta
}
func parseService(service string) (name string, portType string, cryptoType string) {
ss := strings.SplitN(service, ".", 2)
if nil == ss {
return "UNKNOWN", "UNKNOWN", "UNKNOWN"
}
_name := strings.TrimLeft(ss[0], "_")
_portType := strings.TrimLeft(ss[1], "_")
name = _name
portType = _portType
cryptoType = "NONE"
return
}
func browse(service string, domain string) ([]*zeroconf.ServiceEntry, error) {
resolver, err := zeroconf.NewResolver(nil)
if err != nil {
return nil, fmt.Errorf("Failed to initialize resolver %v", err)
}
entryChan := make(chan *zeroconf.ServiceEntry)
timerStopped := make(chan struct{})
serviceEntries := make([]*zeroconf.ServiceEntry, 0)
go func(_entryChan <-chan *zeroconf.ServiceEntry) {
var delay atomic.Value
delay.Store(false)
ticker := time.NewTicker(time.Second * 1)
for {
select {
case entry, ok := <-_entryChan:
if !ok {
return
}
delay.Store(true)
serviceEntries = append(serviceEntries, entry)
case <-ticker.C:
if false == delay.Load().(bool) {
ticker.Stop()
timerStopped <- struct{}{}
return
}
delay.Store(false)
}
}
}(entryChan)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(30))
defer cancel()
err = resolver.Browse(ctx, service, domain, entryChan)
if err != nil {
return nil, fmt.Errorf("Failed to browse %v", err)
}
select {
case <-ctx.Done():
case <-timerStopped:
}
return serviceEntries, nil
}

View File

@@ -0,0 +1,139 @@
package mdns
import (
"reflect"
"testing"
omd "git.loafle.net/overflow/model/discovery"
omm "git.loafle.net/overflow/model/meta"
"git.loafle.net/overflow_scanner/probe/model"
"github.com/grandcat/zeroconf"
)
func TestScan(t *testing.T) {
type args struct {
discovered model.Discovered
}
tests := []struct {
name string
args args
}{
// TODO: Add test cases.
{
name: "1",
args: args{
discovered: model.New(
&omd.Zone{
Network: "192.168.1.0/24",
Iface: "enp3s0",
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
Address: "192.168.1.101",
Mac: "44:8a:5b:f1:f1:f3",
},
),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Scan(tt.args.discovered)
})
}
}
func Test_removeDomainName(t *testing.T) {
type args struct {
instance string
domain string
}
tests := []struct {
name string
args args
wantService string
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotService := removeDomainName(tt.args.instance, tt.args.domain); gotService != tt.wantService {
t.Errorf("removeDomainName() = %v, want %v", gotService, tt.wantService)
}
})
}
}
func Test_toMeta(t *testing.T) {
type args struct {
text []string
}
tests := []struct {
name string
args args
want map[string]string
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := toMeta(tt.args.text); !reflect.DeepEqual(got, tt.want) {
t.Errorf("toMeta() = %v, want %v", got, tt.want)
}
})
}
}
func Test_parseService(t *testing.T) {
type args struct {
service string
}
tests := []struct {
name string
args args
wantName string
wantPortType string
wantCryptoType string
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotName, gotPortType, gotCryptoType := parseService(tt.args.service)
if gotName != tt.wantName {
t.Errorf("parseService() gotName = %v, want %v", gotName, tt.wantName)
}
if gotPortType != tt.wantPortType {
t.Errorf("parseService() gotPortType = %v, want %v", gotPortType, tt.wantPortType)
}
if gotCryptoType != tt.wantCryptoType {
t.Errorf("parseService() gotCryptoType = %v, want %v", gotCryptoType, tt.wantCryptoType)
}
})
}
}
func Test_browse(t *testing.T) {
type args struct {
service string
domain string
}
tests := []struct {
name string
args args
want []*zeroconf.ServiceEntry
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := browse(tt.args.service, tt.args.domain)
if (err != nil) != tt.wantErr {
t.Errorf("browse() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("browse() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -0,0 +1,69 @@
package snmp
import (
"fmt"
omd "git.loafle.net/overflow/model/discovery"
"github.com/k-sone/snmpgo"
)
var defaultPort = 161
var defaultOIDs = []string{
"1.3.6.1.2.1.1.5.0", //sysName
}
type SNMPResponse struct {
Host *omd.Host
Value map[string]string
Error error
}
func ScanSNMP(host *omd.Host, community string, ch chan *SNMPResponse) {
go func() {
getV2(host, defaultPort, community, defaultOIDs, ch)
}()
}
func getV2(host *omd.Host, port int, community string, _oids []string, ch chan *SNMPResponse) {
address := fmt.Sprintf("%s:%d", host.Address, port)
snmp, err := snmpgo.NewSNMP(snmpgo.SNMPArguments{
Version: snmpgo.V2c,
Address: address,
Retries: 1,
Community: community,
})
if err != nil {
ch <- &SNMPResponse{host, nil, err}
return
}
defer snmp.Close()
oids, err := snmpgo.NewOids(_oids)
if err != nil {
ch <- &SNMPResponse{host, nil, err}
return
}
pdu, err := snmp.GetRequest(oids)
if err != nil {
ch <- &SNMPResponse{host, nil, err}
return
}
if pdu.ErrorStatus() != snmpgo.NoError {
ch <- &SNMPResponse{host, nil, fmt.Errorf("%s", pdu.ErrorStatus().String())}
return
}
if pdu == nil {
ch <- &SNMPResponse{host, nil, fmt.Errorf("%s", "Empty PDU")}
return
}
resMap := make(map[string]string)
for _, val := range pdu.VarBinds() {
resMap[val.Oid.String()] = val.Variable.String()
}
ch <- &SNMPResponse{host, resMap, nil}
return
}

View File

@@ -0,0 +1,23 @@
package snmp
import (
"testing"
omd "git.loafle.net/overflow/model/discovery"
omm "git.loafle.net/overflow/model/meta"
)
func TestSNMPScan(t *testing.T) {
host := &omd.Host{
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
Address: "192.168.1.229",
}
ch := make(chan *SNMPResponse)
defer close(ch)
ScanSNMP(host, "test1252serc", ch)
msg := <-ch
t.Log(msg)
}

View File

@@ -0,0 +1,49 @@
package upnp
import (
"fmt"
omd "git.loafle.net/overflow/model/discovery"
omu "git.loafle.net/overflow/model/util"
"git.loafle.net/overflow_scanner/probe/model"
"github.com/huin/goupnp"
)
const (
TargetRootDevice = "upnp:rootdevice"
TargetSSDPAll = "ssdp:all"
)
func Scan(discovered model.Discovered) {
devs, err := goupnp.DiscoverDevices(TargetRootDevice)
if nil != err {
fmt.Println("DeletePortMapping: ", err)
}
LOOP:
for _, dev := range devs {
rd := dev.Root.Device
if !rd.PresentationURL.Ok {
continue LOOP
}
discovered.AddHost(&omd.Host{
MetaIPType: discovered.Zone().MetaIPType,
Name: rd.FriendlyName,
Address: rd.PresentationURL.URL.Host,
Meta: map[string]string{
"DeviceType": rd.DeviceType,
"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,
},
Zone: discovered.Zone(),
DiscoveredDate: omu.NowPtr(),
})
}
}

View File

@@ -0,0 +1,40 @@
package upnp
import (
"testing"
omd "git.loafle.net/overflow/model/discovery"
omm "git.loafle.net/overflow/model/meta"
"git.loafle.net/overflow_scanner/probe/model"
)
func TestScan(t *testing.T) {
type args struct {
discovered model.Discovered
}
tests := []struct {
name string
args args
}{
// TODO: Add test cases.
{
name: "1",
args: args{
discovered: model.New(
&omd.Zone{
Network: "192.168.1.0/24",
Iface: "enp3s0",
MetaIPType: omm.ToMetaIPType(omm.MetaIPTypeEnumV4),
Address: "192.168.1.101",
Mac: "44:8a:5b:f1:f1:f3",
},
),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Scan(tt.args.discovered)
})
}
}