bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/snmp_ips.go (about) 1 package collectors 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 "sort" 8 "strings" 9 "time" 10 11 "bosun.org/cmd/scollector/conf" 12 "bosun.org/metadata" 13 "bosun.org/opentsdb" 14 "bosun.org/slog" 15 ) 16 17 const ifIPAdEntAddr = ".1.3.6.1.2.1.4.20.1" 18 19 // SNMPIfaces registers a SNMP Interfaces collector for the given community and host. 20 func SNMPIPAddresses(cfg conf.SNMP) { 21 collectors = append(collectors, &IntervalCollector{ 22 F: func() (opentsdb.MultiDataPoint, error) { 23 return c_snmp_ips(cfg.Community, cfg.Host) 24 }, 25 Interval: time.Minute * 1, 26 name: fmt.Sprintf("snmp-ips-%s", cfg.Host), 27 }) 28 } 29 30 type ipAdEntAddr struct { 31 InterfaceId int64 32 net.IPNet 33 } 34 35 func c_snmp_ips(community, host string) (opentsdb.MultiDataPoint, error) { 36 ifIPAdEntAddrRaw, err := snmp_subtree(host, community, ifIPAdEntAddr) 37 if err != nil { 38 return nil, err 39 } 40 ipAdEnts := make(map[string]*ipAdEntAddr) 41 for id, value := range ifIPAdEntAddrRaw { 42 // Split entry type id from ip address 43 sp := strings.SplitN(id, ".", 2) 44 if len(sp) != 2 { 45 slog.Errorln("unexpected length of snmp resonse") 46 } 47 typeId := sp[0] 48 address := sp[1] 49 if _, ok := ipAdEnts[address]; !ok { 50 ipAdEnts[address] = &ipAdEntAddr{} 51 } 52 switch typeId { 53 case "1": 54 if v, ok := value.([]byte); ok { 55 ipAdEnts[address].IP = v 56 } 57 case "2": 58 if v, ok := value.(int64); ok { 59 ipAdEnts[address].InterfaceId = v 60 } 61 case "3": 62 if v, ok := value.([]byte); ok { 63 ipAdEnts[address].Mask = v 64 } 65 } 66 } 67 ipsByInt := make(map[int64][]net.IPNet) 68 for _, ipNet := range ipAdEnts { 69 ipsByInt[ipNet.InterfaceId] = append(ipsByInt[ipNet.InterfaceId], ipNet.IPNet) 70 } 71 for intId, ipNets := range ipsByInt { 72 var ips []string 73 for _, ipNet := range ipNets { 74 ips = append(ips, ipNet.String()) 75 } 76 sort.Strings(ips) 77 j, err := json.Marshal(ips) 78 if err != nil { 79 slog.Errorf("error marshaling ips for host %v: %v", host, err) 80 } 81 metadata.AddMeta("", opentsdb.TagSet{"host": host, "iface": fmt.Sprintf("%v", intId)}, "addresses", string(j), false) 82 } 83 return nil, nil 84 }