100 lines
1.8 KiB
Go
100 lines
1.8 KiB
Go
package ping
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
|
|
csm "git.loafle.net/overflow/service_matcher-go"
|
|
opm "git.loafle.net/overflow_scanner/probe/matcher"
|
|
)
|
|
|
|
type Res struct {
|
|
Matcher csm.Matcher
|
|
Error error
|
|
}
|
|
|
|
func Ping(ch chan *Res, ip string, port int, tls bool, portType, key string) {
|
|
go func() {
|
|
conn, err := getConnection(ip, port, portType, tls)
|
|
if err != nil {
|
|
ch <- &Res{nil, err}
|
|
close(ch)
|
|
}
|
|
defer conn.Close()
|
|
|
|
m := opm.GetMatcherByKey(key)
|
|
if m.IsPrePacket() {
|
|
processPrepacket(ch, conn, m)
|
|
}
|
|
processPostpacket(ch, conn, m)
|
|
}()
|
|
}
|
|
|
|
func processPrepacket(ch chan *Res, conn net.Conn, m csm.Matcher) {
|
|
for i := 0; i < m.PacketCount(); i++ {
|
|
bytes := make([]byte, 1024)
|
|
n, _ := conn.Read(bytes)
|
|
p := csm.NewPacket(bytes, n)
|
|
|
|
_, err := conn.Write(m.Packet(i).Buffer)
|
|
if err != nil {
|
|
ch <- &Res{nil, err}
|
|
close(ch)
|
|
}
|
|
|
|
if err := m.Match(nil, i, p); err != nil {
|
|
ch <- &Res{nil, err}
|
|
close(ch)
|
|
}
|
|
}
|
|
|
|
ch <- &Res{m, nil}
|
|
close(ch)
|
|
}
|
|
|
|
func processPostpacket(ch chan *Res, conn net.Conn, m csm.Matcher) {
|
|
for i := 0; i < m.PacketCount(); i++ {
|
|
_, err := conn.Write(m.Packet(i).Buffer)
|
|
if err != nil {
|
|
ch <- &Res{nil, err}
|
|
close(ch)
|
|
}
|
|
|
|
bytes := make([]byte, 1024)
|
|
n, _ := conn.Read(bytes)
|
|
p := csm.NewPacket(bytes, n)
|
|
|
|
if err := m.Match(nil, i, p); err != nil {
|
|
ch <- &Res{nil, err}
|
|
close(ch)
|
|
}
|
|
}
|
|
ch <- &Res{m, nil}
|
|
close(ch)
|
|
}
|
|
|
|
func getConnection(ip string, port int, portType string, isTLS bool) (net.Conn, error) {
|
|
addr := fmt.Sprintf("%s:%d", ip, port)
|
|
portType = strings.ToLower(portType)
|
|
|
|
if isTLS {
|
|
dialer := &net.Dialer{
|
|
Timeout: 5 * time.Second,
|
|
}
|
|
|
|
return tls.DialWithDialer(
|
|
dialer,
|
|
portType,
|
|
addr,
|
|
&tls.Config{
|
|
InsecureSkipVerify: true,
|
|
ServerName: ip,
|
|
},
|
|
)
|
|
}
|
|
return net.Dial(portType, addr)
|
|
}
|