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

// Network interface identification for Linux

package net

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

// 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, os.Error) {
	var (
		ift  []Interface
		tab  []byte
		msgs []syscall.NetlinkMessage
		e    int
	)

	tab, e = syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
	if e != 0 {
		return nil, os.NewSyscallError("netlink rib", e)
	}

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

	for _, m := range msgs {
		switch m.Header.Type {
		case syscall.NLMSG_DONE:
			goto done
		case syscall.RTM_NEWLINK:
			ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
			if ifindex == 0 || ifindex == int(ifim.Index) {
				attrs, e := syscall.ParseNetlinkRouteAttr(&m)
				if e != 0 {
					return nil, os.NewSyscallError("netlink routeattr", e)
				}
				ifi := newLink(attrs, ifim)
				ift = append(ift, ifi)
			}
		}
	}

done:
	return ift, nil
}

func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interface {
	ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
	for _, a := range attrs {
		switch a.Attr.Type {
		case syscall.IFLA_ADDRESS:
			var nonzero bool
			for _, b := range a.Value {
				if b != 0 {
					nonzero = true
				}
			}
			if nonzero {
				ifi.HardwareAddr = a.Value[:]
			}
		case syscall.IFLA_IFNAME:
			ifi.Name = string(a.Value[:len(a.Value)-1])
		case syscall.IFLA_MTU:
			ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0]))
		}
	}
	return ifi
}

func linkFlags(rawFlags uint32) 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 ifindex is zero, interfaceAddrTable returns addresses
// for all network interfaces.  Otherwise it returns addresses
// for a specific interface.
func interfaceAddrTable(ifindex int) ([]Addr, os.Error) {
	var (
		ifat4 []Addr
		ifat6 []Addr
		tab   []byte
		msgs4 []syscall.NetlinkMessage
		msgs6 []syscall.NetlinkMessage
		e     int
		err   os.Error
	)

	tab, e = syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_INET)
	if e != 0 {
		return nil, os.NewSyscallError("netlink rib", e)
	}
	msgs4, e = syscall.ParseNetlinkMessage(tab)
	if e != 0 {
		return nil, os.NewSyscallError("netlink message", e)
	}
	ifat4, err = addrTable(msgs4, ifindex)
	if err != nil {
		return nil, err
	}

	tab, e = syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_INET6)
	if e != 0 {
		return nil, os.NewSyscallError("netlink rib", e)
	}
	msgs6, e = syscall.ParseNetlinkMessage(tab)
	if e != 0 {
		return nil, os.NewSyscallError("netlink message", e)
	}
	ifat6, err = addrTable(msgs6, ifindex)
	if err != nil {
		return nil, err
	}

	return append(ifat4, ifat6...), nil
}

func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, os.Error) {
	var ifat []Addr

	for _, m := range msgs {
		switch m.Header.Type {
		case syscall.NLMSG_DONE:
			goto done
		case syscall.RTM_NEWADDR:
			ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
			if ifindex == 0 || ifindex == int(ifam.Index) {
				attrs, e := syscall.ParseNetlinkRouteAttr(&m)
				if e != 0 {
					return nil, os.NewSyscallError("netlink routeattr", e)
				}
				ifat = append(ifat, newAddr(attrs, int(ifam.Family))...)
			}
		}
	}

done:
	return ifat, nil
}

func newAddr(attrs []syscall.NetlinkRouteAttr, family int) []Addr {
	var ifat []Addr

	for _, a := range attrs {
		switch a.Attr.Type {
		case syscall.IFA_ADDRESS:
			ifa := IPAddr{}
			switch family {
			case syscall.AF_INET:
				ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])
			case syscall.AF_INET6:
				ifa.IP = make(IP, IPv6len)
				copy(ifa.IP, a.Value[:])
			}
			ifat = append(ifat, ifa.toAddr())
		}
	}

	return ifat
}
