示例#1
0
// AddrList gets a list of IP addresses in the system.
// Equivalent to: `ip addr show`.
// The list can be filtered by link and ip family.
func AddrList(link Link, family int) ([]Addr, error) {
	req := nl.NewNetlinkRequest(syscall.RTM_GETADDR, syscall.NLM_F_DUMP)
	msg := nl.NewIfInfomsg(family)
	req.AddData(msg)

	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWADDR)
	if err != nil {
		return nil, err
	}

	index := 0
	if link != nil {
		base := link.Attrs()
		ensureIndex(base)
		index = base.Index
	}

	res := make([]Addr, 0)
	for _, m := range msgs {
		msg := nl.DeserializeIfAddrmsg(m)

		if link != nil && msg.Index != uint32(index) {
			// Ignore messages from other interfaces
			continue
		}

		attrs, err := nl.ParseRouteAttr(m[msg.Len():])
		if err != nil {
			return nil, err
		}

		var addr Addr
		for _, attr := range attrs {
			switch attr.Attr.Type {
			case syscall.IFA_ADDRESS:
				addr.IPNet = &net.IPNet{
					IP:   attr.Value,
					Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
				}
			case syscall.IFA_LABEL:
				addr.Label = string(attr.Value[:len(attr.Value)-1])
			}
		}
		res = append(res, addr)
	}

	return res, nil
}
示例#2
0
func parseAddr(m []byte) (addr Addr, family, index int, err error) {
	msg := nl.DeserializeIfAddrmsg(m)

	family = -1
	index = -1

	attrs, err1 := nl.ParseRouteAttr(m[msg.Len():])
	if err1 != nil {
		err = err1
		return
	}

	family = int(msg.Family)
	index = int(msg.Index)

	var local, dst *net.IPNet
	for _, attr := range attrs {
		switch attr.Attr.Type {
		case syscall.IFA_ADDRESS:
			dst = &net.IPNet{
				IP:   attr.Value,
				Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
			}
			addr.Peer = dst
		case syscall.IFA_LOCAL:
			local = &net.IPNet{
				IP:   attr.Value,
				Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
			}
			addr.IPNet = local
		case syscall.IFA_LABEL:
			addr.Label = string(attr.Value[:len(attr.Value)-1])
		case IFA_FLAGS:
			addr.Flags = int(native.Uint32(attr.Value[0:4]))
		}
	}

	// IFA_LOCAL should be there but if not, fall back to IFA_ADDRESS
	if local != nil {
		addr.IPNet = local
	} else {
		addr.IPNet = dst
	}
	addr.Scope = int(msg.Scope)

	return
}
示例#3
0
// AddrList gets a list of IP addresses in the system.
// Equivalent to: `ip addr show`.
// The list can be filtered by link and ip family.
func AddrList(link Link, family int) ([]Addr, error) {
	req := nl.NewNetlinkRequest(syscall.RTM_GETADDR, syscall.NLM_F_DUMP)
	msg := nl.NewIfInfomsg(family)
	req.AddData(msg)

	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWADDR)
	if err != nil {
		return nil, err
	}

	index := 0
	if link != nil {
		base := link.Attrs()
		ensureIndex(base)
		index = base.Index
	}

	var res []Addr
	for _, m := range msgs {
		msg := nl.DeserializeIfAddrmsg(m)

		if link != nil && msg.Index != uint32(index) {
			// Ignore messages from other interfaces
			continue
		}

		attrs, err := nl.ParseRouteAttr(m[msg.Len():])
		if err != nil {
			return nil, err
		}

		var local, dst *net.IPNet
		var addr Addr
		for _, attr := range attrs {
			switch attr.Attr.Type {
			case syscall.IFA_ADDRESS:
				dst = &net.IPNet{
					IP:   attr.Value,
					Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
				}
			case syscall.IFA_LOCAL:
				local = &net.IPNet{
					IP:   attr.Value,
					Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
				}
			case syscall.IFA_LABEL:
				addr.Label = string(attr.Value[:len(attr.Value)-1])
			case IFA_FLAGS:
				addr.Flags = int(native.Uint32(attr.Value[0:4]))
			}
		}

		// IFA_LOCAL should be there but if not, fall back to IFA_ADDRESS
		if local != nil {
			addr.IPNet = local
		} else {
			addr.IPNet = dst
		}
		addr.Scope = int(msg.Scope)

		res = append(res, addr)
	}

	return res, nil
}