v2 init commit

This commit is contained in:
Toby Chui
2023-05-22 23:05:59 +08:00
parent 5ac0fdde1d
commit c07d5f85df
87 changed files with 273125 additions and 0 deletions

149
src/mod/ipscan/ipscan.go Normal file
View File

@@ -0,0 +1,149 @@
package ipscan
import (
"bytes"
"fmt"
"net"
"sort"
"strconv"
"sync"
"time"
"github.com/go-ping/ping"
)
/*
IP Scanner
This module scan the given network range and return a list
of nearby nodes.
*/
type DiscoveredHost struct {
IP string
Ping int
Hostname string
HttpPortDetected bool
HttpsPortDetected bool
}
//Scan an IP range given the start and ending ip address
func ScanIpRange(start, end string) ([]*DiscoveredHost, error) {
ipStart := net.ParseIP(start)
ipEnd := net.ParseIP(end)
if ipStart == nil || ipEnd == nil {
return nil, fmt.Errorf("Invalid IP address")
}
if bytes.Compare(ipStart, ipEnd) > 0 {
return nil, fmt.Errorf("Invalid IP range")
}
var wg sync.WaitGroup
hosts := make([]*DiscoveredHost, 0)
for ip := ipStart; bytes.Compare(ip, ipEnd) <= 0; inc(ip) {
wg.Add(1)
thisIp := ip.String()
go func(thisIp string) {
defer wg.Done()
host := &DiscoveredHost{IP: thisIp}
if err := host.CheckPing(); err != nil {
// skip if the host is unreachable
host.Ping = -1
hosts = append(hosts, host)
return
}
host.CheckHostname()
host.CheckPort("http", 80, &host.HttpPortDetected)
host.CheckPort("https", 443, &host.HttpsPortDetected)
fmt.Println("OK", host)
hosts = append(hosts, host)
}(thisIp)
}
//Wait until all go routine done
wg.Wait()
sortByIP(hosts)
return hosts, nil
}
func ScanCIDRRange(cidr string) ([]*DiscoveredHost, error) {
_, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}
ip := ipNet.IP.To4()
startIP := net.IPv4(ip[0], ip[1], ip[2], 1).String()
endIP := net.IPv4(ip[0], ip[1], ip[2], 254).String()
return ScanIpRange(startIP, endIP)
}
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
func sortByIP(discovered []*DiscoveredHost) {
sort.Slice(discovered, func(i, j int) bool {
return discovered[i].IP < discovered[j].IP
})
}
func (host *DiscoveredHost) CheckPing() error {
// ping the host and set the ping time in milliseconds
pinger, err := ping.NewPinger(host.IP)
if err != nil {
return err
}
pinger.Count = 4
pinger.Timeout = time.Second
pinger.SetPrivileged(true) // This line may help on some systems
pinger.Run()
stats := pinger.Statistics()
if stats.PacketsRecv == 0 {
return fmt.Errorf("Host unreachable for " + host.IP)
}
host.Ping = int(stats.AvgRtt.Milliseconds())
return nil
}
func (host *DiscoveredHost) CheckHostname() {
// lookup the hostname for the IP address
names, err := net.LookupAddr(host.IP)
fmt.Println(names, err)
if err == nil && len(names) > 0 {
host.Hostname = names[0]
}
}
func (host *DiscoveredHost) CheckPort(protocol string, port int, detected *bool) {
// try to connect to the specified port on the host
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host.IP, strconv.Itoa(port)), 1*time.Second)
if err == nil {
conn.Close()
*detected = true
}
}
func (host *DiscoveredHost) ScanPorts(startPort, endPort int) []int {
var openPorts []int
for port := startPort; port <= endPort; port++ {
target := fmt.Sprintf("%s:%d", host.IP, port)
conn, err := net.DialTimeout("tcp", target, time.Millisecond*500)
if err == nil {
conn.Close()
openPorts = append(openPorts, port)
}
}
return openPorts
}