Пример #1
0
// 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,
	}
}