// Getifaddrs returns a list of IfData. Unlike with getifaddrs(3) the // IfData has merged link level and interface address data. func Getifaddrs() ([]IfData, error) { var ifaces *C.struct_ifaddrs if rc, err := C.getifaddrs(&ifaces); rc != 0 { return []IfData{}, err } defer C.freeifaddrs(ifaces) ips := make(map[string]string) ifs := []IfData{} for fi := ifaces; fi != nil; fi = fi.ifa_next { if fi.ifa_addr == nil { continue } ifaName := C.GoString(fi.ifa_name) if ip, ok := ntop(fi); ok { ips[ifaName] = ip continue // fi.ifa_addr.sa_family == C.AF_INET } if fi.ifa_addr.sa_family != C.AF_LINK { continue } data := fi.ifa_data it := IfData{ Name: ifaName, InBytes: uint(C.Ibytes(data)), OutBytes: uint(C.Obytes(data)), InPackets: uint(C.Ipackets(data)), OutPackets: uint(C.Opackets(data)), InErrors: uint(C.Ierrors(data)), OutErrors: uint(C.Oerrors(data)), } if ip, ok := ips[ifaName]; ok { it.IP = ip } ifs = append(ifs, it) } for i, ifdata := range ifs { if ifdata.IP != "" { continue } if ip, ok := ips[ifdata.Name]; ok { ifs[i].IP = ip } } return ifs, nil }
func NewInterfaces(CH chan InterfacesInfo) { var ifaces *C.struct_ifaddrs if getrc, _ := C.getifaddrs(&ifaces); getrc != 0 { CH <- InterfacesInfo{} return } defer C.freeifaddrs(ifaces) ifs := []InterfaceInfo{} IP := "" for fi := ifaces; fi != nil; fi = fi.ifa_next { if fi.ifa_addr == nil { continue } ifa_name := C.GoString(fi.ifa_name) if IP == "" && fi.ifa_addr.sa_family == C.AF_INET && !rx_lo.Match([]byte(ifa_name)) && realInterfaceName(ifa_name) { sa_in := (*C.struct_sockaddr_in)(unsafe.Pointer(fi.ifa_addr)) if C.inet_ntop( C.int(fi.ifa_addr.sa_family), // C.AF_INET, unsafe.Pointer(&sa_in.sin_addr), &C.ADDR[0], C.socklen_t(unsafe.Sizeof(C.ADDR))) != nil { IP = C.GoString((*C.char)(unsafe.Pointer(&C.ADDR))) } } if fi.ifa_addr.sa_family != C.AF_LINK { continue } data := fi.ifa_data it := InterfaceInfo{ Name: ifa_name, InBytes: uint(C.Ibytes(data)), OutBytes: uint(C.Obytes(data)), InPackets: uint(C.Ipackets(data)), OutPackets: uint(C.Opackets(data)), InErrors: uint(C.Ierrors(data)), OutErrors: uint(C.Oerrors(data)), } if it.InBytes == 0 && it.OutBytes == 0 && it.InPackets == 0 && it.OutPackets == 0 && it.InErrors == 0 && it.OutErrors == 0 { continue } ifs = append(ifs, it) } CH <- InterfacesInfo{ List: ifs, IP: IP, } }