Example #1
0
// If the ifindex is zero, interfaceMulticastAddrTable returns
// addresses for all network interfaces.  Otherwise it returns
// addresses for a specific interface.
func interfaceMulticastAddrTable(ifindex int) ([]Addr, os.Error) {
	var (
		tab   []byte
		e     int
		msgs  []syscall.RoutingMessage
		ifmat []Addr
	)

	tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifindex)
	if e != 0 {
		return nil, os.NewSyscallError("route rib", e)
	}

	msgs, e = syscall.ParseRoutingMessage(tab)
	if e != 0 {
		return nil, os.NewSyscallError("route message", e)
	}

	for _, m := range msgs {
		switch v := m.(type) {
		case *syscall.InterfaceMulticastAddrMessage:
			if ifindex == 0 || ifindex == int(v.Header.Index) {
				ifma, err := newMulticastAddr(v)
				if err != nil {
					return nil, err
				}
				ifmat = append(ifmat, ifma...)
			}
		}
	}

	return ifmat, nil
}
Example #2
0
// interfaceMulticastAddrTable returns addresses for a specific
// interface.
func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifi.Index)
	if err != nil {
		return nil, os.NewSyscallError("route rib", err)
	}
	msgs, err := syscall.ParseRoutingMessage(tab)
	if err != nil {
		return nil, os.NewSyscallError("route message", err)
	}
	var ifmat []Addr
	for _, m := range msgs {
		switch m := m.(type) {
		case *syscall.InterfaceMulticastAddrMessage:
			if ifi.Index == int(m.Header.Index) {
				ifma, err := newMulticastAddr(ifi, m)
				if err != nil {
					return nil, err
				}
				if ifma != nil {
					ifmat = append(ifmat, ifma)
				}
			}
		}
	}
	return ifmat, nil
}
Example #3
0
// If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces.  Otheriwse it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
	var ift []Interface

	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
	if err != nil {
		return nil, os.NewSyscallError("route rib", err)
	}

	msgs, err := syscall.ParseRoutingMessage(tab)
	if err != nil {
		return nil, os.NewSyscallError("route message", err)
	}

	for _, m := range msgs {
		switch v := m.(type) {
		case *syscall.InterfaceMessage:
			if ifindex == 0 || ifindex == int(v.Header.Index) {
				ifi, err := newLink(v)
				if err != nil {
					return nil, err
				}
				ift = append(ift, ifi...)
			}
		}
	}

	return ift, nil
}
Example #4
0
// If the ifindex is zero, interfaceAddrTable returns addresses
// for all network interfaces.  Otherwise it returns addresses
// for a specific interface.
func interfaceAddrTable(ifindex int) ([]Addr, error) {
	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
	if err != nil {
		return nil, os.NewSyscallError("route rib", err)
	}

	msgs, err := syscall.ParseRoutingMessage(tab)
	if err != nil {
		return nil, os.NewSyscallError("route message", err)
	}

	var ifat []Addr
	for _, m := range msgs {
		switch v := m.(type) {
		case *syscall.InterfaceAddrMessage:
			if ifindex == 0 || ifindex == int(v.Header.Index) {
				ifa, err := newAddr(v)
				if err != nil {
					return nil, err
				}
				if ifa != nil {
					ifat = append(ifat, ifa)
				}
			}
		}
	}
	return ifat, nil
}
Example #5
0
// If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces.  Otherwise it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
	if err != nil {
		return nil, os.NewSyscallError("route rib", err)
	}
	msgs, err := syscall.ParseRoutingMessage(tab)
	if err != nil {
		return nil, os.NewSyscallError("route message", err)
	}
	return parseInterfaceTable(ifindex, msgs)
}
Example #6
0
// If the ifi is nil, interfaceAddrTable returns addresses for all
// network interfaces.  Otherwise it returns addresses for a specific
// interface.
func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
	index := 0
	if ifi != nil {
		index = ifi.Index
	}
	tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, index)
	if err != nil {
		return nil, os.NewSyscallError("route rib", err)
	}
	msgs, err := syscall.ParseRoutingMessage(tab)
	if err != nil {
		return nil, os.NewSyscallError("route message", err)
	}
	var ift []Interface
	if index == 0 {
		ift, err = parseInterfaceTable(index, msgs)
		if err != nil {
			return nil, err
		}
	}
	var ifat []Addr
	for _, m := range msgs {
		switch m := m.(type) {
		case *syscall.InterfaceAddrMessage:
			if index == 0 || index == int(m.Header.Index) {
				if index == 0 {
					var err error
					ifi, err = interfaceByIndex(ift, int(m.Header.Index))
					if err != nil {
						return nil, err
					}
				}
				ifa, err := newAddr(ifi, m)
				if err != nil {
					return nil, err
				}
				if ifa != nil {
					ifat = append(ifat, ifa)
				}
			}
		}
	}
	return ifat, nil
}
Example #7
0
func TestRouteRIB(t *testing.T) {
	for _, facility := range []int{syscall.NET_RT_DUMP, syscall.NET_RT_IFLIST} {
		for _, param := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} {
			var err error
			var b []byte
			// The VM allocator wrapper functions can
			// return ENOMEM easily.
			for i := 0; i < 3; i++ {
				b, err = syscall.RouteRIB(facility, param)
				if err != nil {
					time.Sleep(5 * time.Millisecond)
					continue
				}
				break
			}
			if err != nil {
				t.Error(facility, param, err)
				continue
			}
			msgs, err := syscall.ParseRoutingMessage(b)
			if err != nil {
				t.Error(facility, param, err)
				continue
			}
			var ipv4loopback, ipv6loopback bool
			for _, m := range msgs {
				flags, err := parseRoutingMessageHeader(m)
				if err != nil {
					t.Error(err)
					continue
				}
				sas, err := parseRoutingSockaddrs(m)
				if err != nil {
					t.Error(err)
					continue
				}
				if flags&(syscall.RTA_DST|syscall.RTA_IFA) != 0 {
					sa := sas[syscall.RTAX_DST]
					if sa == nil {
						sa = sas[syscall.RTAX_IFA]
					}
					switch sa := sa.(type) {
					case *syscall.SockaddrInet4:
						if net.IP(sa.Addr[:]).IsLoopback() {
							ipv4loopback = true
						}
					case *syscall.SockaddrInet6:
						if net.IP(sa.Addr[:]).IsLoopback() {
							ipv6loopback = true
						}
					}
				}
				t.Log(facility, param, flags, sockaddrs(sas))
			}
			if param == syscall.AF_UNSPEC && len(msgs) > 0 && !ipv4loopback && !ipv6loopback {
				t.Errorf("no loopback facility found: ipv4/ipv6=%v/%v, %v", ipv4loopback, ipv6loopback, len(msgs))
				continue
			}
		}
	}
}