Original post

Can someone tell me what I’m doing wrong? Currently this script looks like its just hanging and never returning. I’ve tested the snmp, and ip iteration independently and they worked. Once I introduced the go routine it looks like I’ve broken something. Can someone offer assistance as to what I’ve done wrong. Also I just read there is a better way of limiting go routines but in a pinch I just wanted to keep it under a thousand go routines.

package main

import (
        "encoding/binary"
        "fmt"
        "log"
        "net"
        "sync"

        g "github.com/gosnmp/gosnmp"
)

const snmpComm string = "public"

func poller(ip string, wg *sync.WaitGroup) {
        defer wg.Done()
        // Default is a pointer to a GoSNMP struct that contains sensible defaults
        // eg port 161, community public, etc
        g.Default.Target = ip
        g.Default.Community = snmpComm

        err := g.Default.Connect()
        if err != nil {
                log.Fatalf("Connect() err: %v", err)
        }
        defer g.Default.Conn.Close()

        oids := []string{"1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.5.0"}
        result, err2 := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDS
        if err2 != nil {
                log.Fatalf("Get() err: %v", err2)
        }

        for i, variable := range result.Variables {
                fmt.Printf("%d: oid: %s ", i, variable.Name)
        }
}

func main() {
        var wg sync.WaitGroup

        _, ipv4Net, err := net.ParseCIDR("10.201.0.0/16")
        if err != nil {
                fmt.Println(err)
        }

        // convert IPNet struct mask and address to uint32
        // network is BigEndian
        mask := binary.BigEndian.Uint32(ipv4Net.Mask)
        start := binary.BigEndian.Uint32(ipv4Net.IP)

        // find the final address
        finish := (start & mask) | (mask ^ 0xffffffff)

        // loop through addresses as uint32
        threadProtector := 0
        for i := start; i <= finish; i++ {
                if threadProtector <= 999 {
                        // convert back to net.IP
                        ip := make(net.IP, 4)
                        binary.BigEndian.PutUint32(ip, i)
                        ipstr := ip.String()
                        wg.Add(1)
                        go poller(ipstr, &wg)
                        threadProtector++
                } else if threadProtector == 1000 {
                        wg.Wait()
                        threadProtector = 0
                }
        }

}