209 lines
5.5 KiB
Go
209 lines
5.5 KiB
Go
|
package ipv4
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net"
|
||
|
|
||
|
"git.loafle.net/commons_go/logging"
|
||
|
|
||
|
"git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
|
||
|
"git.loafle.net/overflow/overflow_discovery/service"
|
||
|
"git.loafle.net/overflow/overflow_discovery/service/matcher"
|
||
|
)
|
||
|
|
||
|
func scanServiceTCP(port *model.Port, ds *model.DiscoveryService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) bool {
|
||
|
|
||
|
hostIP := port.Host.IP
|
||
|
portNumber := port.PortNumber
|
||
|
info := matcher.NewMatchInfo(hostIP, portNumber)
|
||
|
var s *model.Service
|
||
|
|
||
|
scs := []serviceConnector{
|
||
|
&normalServiceConn{
|
||
|
t: model.PortTypeTCP,
|
||
|
},
|
||
|
&tlsServiceConn{
|
||
|
t: model.CryptoTypeTLS,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for i := 0; i < len(scs); i++ {
|
||
|
sc := scs[i]
|
||
|
|
||
|
conn, err := sc.Dial(hostIP, portNumber)
|
||
|
if err != nil {
|
||
|
errChan <- fmt.Errorf("Discovery: Service scan[%s] on %s:%d error has occurred %v ", sc.Type(), hostIP, portNumber, err)
|
||
|
break
|
||
|
}
|
||
|
buf := make([]byte, 1024)
|
||
|
rn, err := conn.Read(buf)
|
||
|
if err != nil {
|
||
|
rn = 0
|
||
|
}
|
||
|
if rn != 0 {
|
||
|
s = hadlePrePacket(info, sc, conn, matcher.NewPacket(buf, rn))
|
||
|
} else {
|
||
|
conn.Close()
|
||
|
s = hadlePostPacket(info, sc)
|
||
|
}
|
||
|
|
||
|
if nil != s {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if nil != s {
|
||
|
s.Port = port
|
||
|
resultChan <- s
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func hadlePrePacket(info matcher.MatchInfo, sc serviceConnector, conn net.Conn, packet *matcher.Packet) *model.Service {
|
||
|
defer func() {
|
||
|
conn.Close()
|
||
|
}()
|
||
|
|
||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan pre packet length[%d], buf[%v]", packet.Len, packet.Buffer))
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan pre packet length[%d]", packet.Len))
|
||
|
|
||
|
ms := service.GetTCPMatchers(true)
|
||
|
buf := make([]byte, 1024)
|
||
|
var s *model.Service
|
||
|
|
||
|
Loop:
|
||
|
for i := 0; i < len(ms); i++ {
|
||
|
m := ms[i]
|
||
|
|
||
|
if m.Match(info, 0, packet) {
|
||
|
packetCount := m.PacketCount()
|
||
|
|
||
|
if 0 == packetCount {
|
||
|
s = &model.Service{
|
||
|
ServiceName: m.ServiceName(),
|
||
|
CryptoType: sc.Type(),
|
||
|
}
|
||
|
break Loop
|
||
|
}
|
||
|
|
||
|
found := false
|
||
|
|
||
|
for j := 0; j < packetCount; j++ {
|
||
|
tPacket := m.Packet(j)
|
||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer))
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d]", tPacket.Len))
|
||
|
wn, err := conn.Write(tPacket.Buffer)
|
||
|
if nil != err {
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet error %v", err))
|
||
|
break
|
||
|
}
|
||
|
if wn != tPacket.Len {
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d] not same with %d", wn, tPacket.Len))
|
||
|
break
|
||
|
}
|
||
|
|
||
|
rn, err := conn.Read(buf)
|
||
|
if nil != err {
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive packet error %v", err))
|
||
|
break
|
||
|
}
|
||
|
|
||
|
if m.Match(info, j+1, matcher.NewPacket(buf, rn)) {
|
||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf))
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d]", rn))
|
||
|
found = true
|
||
|
} else {
|
||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf))
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d]", rn))
|
||
|
found = false
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if found {
|
||
|
s = &model.Service{
|
||
|
ServiceName: m.ServiceName(),
|
||
|
CryptoType: sc.Type(),
|
||
|
}
|
||
|
break Loop
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return s
|
||
|
}
|
||
|
|
||
|
func hadlePostPacket(info matcher.MatchInfo, sc serviceConnector) *model.Service {
|
||
|
ms := service.GetTCPMatchers(false)
|
||
|
buf := make([]byte, 1024)
|
||
|
var s *model.Service
|
||
|
|
||
|
Loop:
|
||
|
for i := 0; i < len(ms); i++ {
|
||
|
m := ms[i]
|
||
|
|
||
|
conn, err := sc.Dial(info.IP(), info.Port())
|
||
|
if err != nil {
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan socket[%s:%d] dial error %v", info.IP(), info.Port(), err))
|
||
|
break Loop
|
||
|
}
|
||
|
|
||
|
packetCount := m.PacketCount()
|
||
|
for j := 0; j < packetCount; j++ {
|
||
|
tPacket := m.Packet(j)
|
||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer))
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d]", tPacket.Len))
|
||
|
wn, err := conn.Write(tPacket.Buffer)
|
||
|
if nil != err {
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet error %v", err))
|
||
|
break
|
||
|
}
|
||
|
if wn != tPacket.Len {
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d] not same with %d", wn, tPacket.Len))
|
||
|
break
|
||
|
}
|
||
|
|
||
|
rn, err := conn.Read(buf)
|
||
|
if nil != err {
|
||
|
if !m.HasResponse(j) {
|
||
|
s = &model.Service{
|
||
|
ServiceName: m.ServiceName(),
|
||
|
CryptoType: sc.Type(),
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive packet error %v", err))
|
||
|
break
|
||
|
}
|
||
|
|
||
|
if m.Match(info, j, matcher.NewPacket(buf, rn)) {
|
||
|
if packetCount-1 == j {
|
||
|
s = &model.Service{
|
||
|
ServiceName: m.ServiceName(),
|
||
|
CryptoType: sc.Type(),
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
|
||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf))
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d]", rn))
|
||
|
continue
|
||
|
} else {
|
||
|
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf))
|
||
|
logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d]", rn))
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
conn.Close()
|
||
|
|
||
|
if nil != s {
|
||
|
break Loop
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return s
|
||
|
}
|