// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd netbsd openbsd

package net

import (
	"os"
	"syscall"
	"unsafe"
)

// 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)
}

func parseInterfaceTable(ifindex int, msgs []syscall.RoutingMessage) ([]Interface, error) {
	var ift []Interface
loop:
	for _, m := range msgs {
		switch m := m.(type) {
		case *syscall.InterfaceMessage:
			if ifindex == 0 || ifindex == int(m.Header.Index) {
				ifi, err := newLink(m)
				if err != nil {
					return nil, err
				}
				ift = append(ift, *ifi)
				if ifindex == int(m.Header.Index) {
					break loop
				}
			}
		}
	}
	return ift, nil
}

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
}

func linkFlags(rawFlags int32) Flags {
	var f Flags
	if rawFlags&syscall.IFF_UP != 0 {
		f |= FlagUp
	}
	if rawFlags&syscall.IFF_BROADCAST != 0 {
		f |= FlagBroadcast
	}
	if rawFlags&syscall.IFF_LOOPBACK != 0 {
		f |= FlagLoopback
	}
	if rawFlags&syscall.IFF_POINTOPOINT != 0 {
		f |= FlagPointToPoint
	}
	if rawFlags&syscall.IFF_MULTICAST != 0 {
		f |= FlagMulticast
	}
	return f
}

// 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
}

func newAddr(ifi *Interface, 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.IP[2], ifa.IP[3] = 0, 0
				}
			}
		default: // Sockaddrs contain syscall.SockaddrDatalink on NetBSD
			return nil, nil
		}
	}
	return ifa, nil
}
