package ingest import ( "encoding/json" "fmt" "net" "strconv" "strings" "time" "github.com/gosnmp/gosnmp" ) type timeWindow struct { Days []int `json:"days"` Start string `json:"start"` End string `json:"end"` } func ipMatchesCIDR(ip net.IP, cidr string) bool { cidr = strings.TrimSpace(cidr) if cidr == "" { return false } if !strings.Contains(cidr, "/") { p := net.ParseIP(cidr) return p != nil && p.Equal(ip) } _, network, err := net.ParseCIDR(cidr) if err != nil { return false } return network.Contains(ip) } func inTimeWindows(now time.Time, jsonStr string) bool { s := strings.TrimSpace(jsonStr) if s == "" || s == "null" { return true } var windows []timeWindow if err := json.Unmarshal([]byte(s), &windows); err != nil || len(windows) == 0 { return true } tod := now.Hour()*60 + now.Minute() wd := int(now.Weekday()) for _, w := range windows { if len(w.Days) > 0 { ok := false for _, d := range w.Days { if d == wd { ok = true break } } if !ok { continue } } start := parseHHMM(w.Start) end := parseHHMM(w.End) if start < 0 || end < 0 { continue } if start <= end { if tod >= start && tod <= end { return true } } else { if tod >= start || tod <= end { return true } } } return false } func parseHHMM(s string) int { s = strings.TrimSpace(s) if s == "" { return -1 } parts := strings.Split(s, ":") if len(parts) != 2 { return -1 } h, err1 := strconv.Atoi(parts[0]) m, err2 := strconv.Atoi(parts[1]) if err1 != nil || err2 != nil || h < 0 || h > 23 || m < 0 || m > 59 { return -1 } return h*60 + m } func varbindFingerprint(pkt *gosnmp.SnmpPacket) string { var b strings.Builder for _, v := range pkt.Variables { b.WriteString(v.Name) b.WriteByte('=') b.WriteString(fmtVarbindValue(v)) b.WriteByte(';') } return b.String() } func fmtVarbindValue(v gosnmp.SnmpPDU) string { switch v.Type { case gosnmp.OctetString: if bb, ok := v.Value.([]byte); ok { return string(bb) } } return fmt.Sprintf("%v", v.Value) }