Пример #1
0
func parseRoutingSockaddrs(m syscall.RoutingMessage) ([]syscall.Sockaddr, error) {
	switch m := m.(type) {
	case *syscall.RouteMessage:
		sas, err := syscall.ParseRoutingSockaddr(m)
		if err != nil {
			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
		}
		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
			return nil, err
		}
		return sas, nil
	case *syscall.InterfaceMessage:
		sas, err := syscall.ParseRoutingSockaddr(m)
		if err != nil {
			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
		}
		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
			return nil, err
		}
		return sas, nil
	case *syscall.InterfaceAddrMessage:
		sas, err := syscall.ParseRoutingSockaddr(m)
		if err != nil {
			return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data)
		}
		if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil {
			return nil, err
		}
		return sas, nil
	default:
		panic(fmt.Sprintf("unknown routing message type: %T", m))
	}
}
Пример #2
0
func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, os.Error) {
	var ifmat []Addr

	sas, e := syscall.ParseRoutingSockaddr(m)
	if e != 0 {
		return nil, os.NewSyscallError("route sockaddr", e)
	}

	for _, s := range sas {
		switch v := s.(type) {
		case *syscall.SockaddrInet4:
			ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
			ifmat = append(ifmat, ifma.toAddr())
		case *syscall.SockaddrInet6:
			ifma := &IPAddr{IP: make(IP, IPv6len)}
			copy(ifma.IP, v.Addr[:])
			// NOTE: KAME based IPv6 protcol stack usually embeds
			// the interface index in the interface-local or link-
			// local address as the kernel-internal form.
			if ifma.IP.IsInterfaceLocalMulticast() ||
				ifma.IP.IsLinkLocalMulticast() {
				// remove embedded scope zone ID
				ifma.IP[2], ifma.IP[3] = 0, 0
			}
			ifmat = append(ifmat, ifma.toAddr())
		}
	}

	return ifmat, nil
}
Пример #3
0
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error) {
	sas, err := syscall.ParseRoutingSockaddr(m)
	if err != nil {
		return nil, os.NewSyscallError("route sockaddr", err)
	}
	var ifmat []Addr
	for _, sa := range sas {
		switch sa := sa.(type) {
		case *syscall.SockaddrInet4:
			ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
			ifmat = append(ifmat, ifma.toAddr())
		case *syscall.SockaddrInet6:
			ifma := &IPAddr{IP: make(IP, IPv6len)}
			copy(ifma.IP, sa.Addr[:])
			// NOTE: KAME based IPv6 protcol stack usually embeds
			// the interface index in the interface-local or link-
			// local address as the kernel-internal form.
			if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
				ifma.IP[2], ifma.IP[3] = 0, 0
			}
			ifmat = append(ifmat, ifma.toAddr())
		}
	}
	return ifmat, nil
}
Пример #4
0
func newLink(m *syscall.InterfaceMessage) (*Interface, error) {
	sas, err := syscall.ParseRoutingSockaddr(m)
	if err != nil {
		return nil, os.NewSyscallError("route sockaddr", err)
	}
	ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
	for _, sa := range sas {
		switch sa := sa.(type) {
		case *syscall.SockaddrDatalink:
			// NOTE: SockaddrDatalink.Data is minimum work area,
			// can be larger.
			m.Data = m.Data[unsafe.Offsetof(sa.Data):]
			var name [syscall.IFNAMSIZ]byte
			for i := 0; i < int(sa.Nlen); i++ {
				name[i] = byte(m.Data[i])
			}
			ifi.Name = string(name[:sa.Nlen])
			ifi.MTU = int(m.Header.Data.Mtu)
			addr := make([]byte, sa.Alen)
			for i := 0; i < int(sa.Alen); i++ {
				addr[i] = byte(m.Data[int(sa.Nlen)+i])
			}
			ifi.HardwareAddr = addr[:sa.Alen]
		}
	}
	return ifi, nil
}
Пример #5
0
func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) {
	sas, err := syscall.ParseRoutingSockaddr(m)
	if err != nil {
		return nil, os.NewSyscallError("parseroutingsockaddr", err)
	}
	ifa := &IPNet{}
	switch sa := sas[syscall.RTAX_NETMASK].(type) {
	case *syscall.SockaddrInet4:
		ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
	case *syscall.SockaddrInet6:
		ifa.Mask = make(IPMask, IPv6len)
		copy(ifa.Mask, sa.Addr[:])
	}
	switch sa := sas[syscall.RTAX_IFA].(type) {
	case *syscall.SockaddrInet4:
		ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
	case *syscall.SockaddrInet6:
		ifa.IP = make(IP, IPv6len)
		copy(ifa.IP, sa.Addr[:])
		// NOTE: KAME based IPv6 protcol stack usually embeds
		// the interface index in the interface-local or
		// link-local address as the kernel-internal form.
		if ifa.IP.IsLinkLocalUnicast() {
			ifa.IP[2], ifa.IP[3] = 0, 0
		}
	}
	if ifa.IP == nil || ifa.Mask == nil {
		return nil, nil // Sockaddrs contain syscall.SockaddrDatalink on NetBSD
	}
	return ifa, nil
}
Пример #6
0
func TestParseInterfaceMessage(t *testing.T) {
	for i, tt := range parseInterfaceMessageTests {
		if _, err := syscall.ParseRoutingSockaddr(tt); err != nil {
			t.Errorf("#%d: %v", i, err)
		}
	}
}
Пример #7
0
func newLink(m *syscall.InterfaceMessage) ([]Interface, os.Error) {
	var ift []Interface

	sas, e := syscall.ParseRoutingSockaddr(m)
	if e != 0 {
		return nil, os.NewSyscallError("route sockaddr", e)
	}

	for _, s := range sas {
		switch v := s.(type) {
		case *syscall.SockaddrDatalink:
			// NOTE: SockaddrDatalink.Data is minimum work area,
			// can be larger.
			m.Data = m.Data[unsafe.Offsetof(v.Data):]
			ifi := Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
			var name [syscall.IFNAMSIZ]byte
			for i := 0; i < int(v.Nlen); i++ {
				name[i] = byte(m.Data[i])
			}
			ifi.Name = string(name[:v.Nlen])
			ifi.MTU = int(m.Header.Data.Mtu)
			addr := make([]byte, v.Alen)
			for i := 0; i < int(v.Alen); i++ {
				addr[i] = byte(m.Data[int(v.Nlen)+i])
			}
			ifi.HardwareAddr = addr[:v.Alen]
			ift = append(ift, ifi)
		}
	}

	return ift, nil
}
Пример #8
0
func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
	sas, err := syscall.ParseRoutingSockaddr(m)
	if err != nil {
		return nil, os.NewSyscallError("route sockaddr", err)
	}
	switch sa := sas[syscall.RTAX_IFA].(type) {
	case *syscall.SockaddrInet4:
		return &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}, nil
	case *syscall.SockaddrInet6:
		ifma := IPAddr{IP: make(IP, IPv6len)}
		copy(ifma.IP, sa.Addr[:])
		// NOTE: KAME based IPv6 protcol stack usually embeds
		// the interface index in the interface-local or
		// link-local address as the kernel-internal form.
		if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
			ifma.IP[2], ifma.IP[3] = 0, 0
		}
		return &ifma, nil
	default:
		return nil, nil
	}
}
Пример #9
0
func newAddr(m *syscall.InterfaceAddrMessage) (Addr, error) {
	ifa := &IPNet{}

	sas, err := syscall.ParseRoutingSockaddr(m)
	if err != nil {
		return nil, os.NewSyscallError("route sockaddr", err)
	}

	for i, s := range sas {
		switch v := s.(type) {
		case *syscall.SockaddrInet4:
			switch i {
			case 0:
				ifa.Mask = IPv4Mask(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
			case 1:
				ifa.IP = IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
			}
		case *syscall.SockaddrInet6:
			switch i {
			case 0:
				ifa.Mask = make(IPMask, IPv6len)
				copy(ifa.Mask, v.Addr[:])
			case 1:
				ifa.IP = make(IP, IPv6len)
				copy(ifa.IP, v.Addr[:])
				// NOTE: KAME based IPv6 protcol stack usually embeds
				// the interface index in the interface-local or link-
				// local address as the kernel-internal form.
				if ifa.IP.IsLinkLocalUnicast() {
					// remove embedded scope zone ID
					ifa.IP[2], ifa.IP[3] = 0, 0
				}
			}
		}
	}

	return ifa, nil
}
Пример #10
0
func newAddr(m *syscall.InterfaceAddrMessage) (Addr, error) {
	sas, err := syscall.ParseRoutingSockaddr(m)
	if err != nil {
		return nil, os.NewSyscallError("route sockaddr", err)
	}
	ifa := &IPNet{}
	for i, sa := range sas {
		switch sa := sa.(type) {
		case *syscall.SockaddrInet4:
			switch i {
			case 0:
				ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
			case 1:
				ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
			}
		case *syscall.SockaddrInet6:
			switch i {
			case 0:
				ifa.Mask = make(IPMask, IPv6len)
				copy(ifa.Mask, sa.Addr[:])
			case 1:
				ifa.IP = make(IP, IPv6len)
				copy(ifa.IP, sa.Addr[:])
				// NOTE: KAME based IPv6 protcol stack usually embeds
				// the interface index in the interface-local or link-
				// local address as the kernel-internal form.
				if ifa.IP.IsLinkLocalUnicast() {
					ifa.Zone = zoneToString(int(ifa.IP[2]<<8 | ifa.IP[3]))
					ifa.IP[2], ifa.IP[3] = 0, 0
				}
			}
		default: // Sockaddrs contain syscall.SockaddrDatalink on NetBSD
			return nil, nil
		}
	}
	return ifa, nil
}