Skip to content

Instantly share code, notes, and snippets.

@blinksmith
Forked from picatz/port_scanner.go
Created July 23, 2019 14:56
Show Gist options
  • Save blinksmith/da0fd8919746e2d45ac88f055afe0096 to your computer and use it in GitHub Desktop.
Save blinksmith/da0fd8919746e2d45ac88f055afe0096 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"net"
"os/exec"
"strconv"
"strings"
"sync"
"time"
"golang.org/x/sync/semaphore"
)
type PortScanner struct {
ip string
lock *semaphore.Weighted
}
func Ulimit() int64 {
out, err := exec.Command("ulimit", "-n").Output()
if err != nil {
panic(err)
}
s := strings.TrimSpace(string(out))
i, err := strconv.ParseInt(s, 10, 64)
if err != nil {
panic(err)
}
return i
}
func ScanPort(ip string, port int, timeout time.Duration) {
target := fmt.Sprintf("%s:%d", ip, port)
conn, err := net.DialTimeout("tcp", target, timeout)
if err != nil {
if strings.Contains(err.Error(), "too many open files") {
time.Sleep(timeout)
ScanPort(ip, port, timeout)
} else {
fmt.Println(port, "closed")
}
return
}
conn.Close()
fmt.Println(port, "open")
}
func (ps *PortScanner) Start(f, l int, timeout time.Duration) {
wg := sync.WaitGroup{}
defer wg.Wait()
for port := f; port <= l; port++ {
ps.lock.Acquire(context.TODO(), 1)
wg.Add(1)
go func(port int) {
defer ps.lock.Release(1)
defer wg.Done()
ScanPort(ps.ip, port, timeout)
}(port)
}
}
func main() {
ps := &PortScanner{
ip: "127.0.0.1",
lock: semaphore.NewWeighted(Ulimit()),
}
ps.Start(1, 65535, 500*time.Millisecond)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment