// Copyright 2015 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 syscall_test

import (
	"fmt"
	"net"
	"os"
	"syscall"
	"testing"
	"time"
)

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

func TestRouteMonitor(t *testing.T) {
	if testing.Short() || os.Getuid() != 0 {
		t.Skip("must be root")
	}

	s, err := syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
	if err != nil {
		t.Fatal(err)
	}
	defer syscall.Close(s)

	tmo := time.After(30 * time.Second)
	go func() {
		b := make([]byte, os.Getpagesize())
		for {
			n, err := syscall.Read(s, b)
			if err != nil {
				return
			}
			msgs, err := syscall.ParseRoutingMessage(b[:n])
			if err != nil {
				t.Error(err)
				return
			}
			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
				}
				t.Log(flags, sockaddrs(sas))
			}
		}
	}()
	<-tmo
}

var parseInterfaceMessageTests = []*syscall.InterfaceMessage{
	// with link-layer address
	{
		Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP},
		Data: []uint8{
			0x11, 0x12, 0x2, 0x0, 0x6, 0x3, 0x6, 0x0,
			0x77, 0x6d, 0x31, 0x01, 0x23, 0x45, 0xab, 0xcd,
			0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
		},
	},
	// without link-layer address
	{
		Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP},
		Data: []uint8{
			0xe, 0x12, 0x4, 0x0, 0xf5, 0x6, 0x0, 0x0,
			0x70, 0x66, 0x6c, 0x6f, 0x67, 0x30, 0x0, 0x0,
		},
	},
	// no data
	{
		Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP},
		Data: []uint8{
			0x8, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0,
		},
	},
}

func TestParseInterfaceMessage(t *testing.T) {
	for i, tt := range parseInterfaceMessageTests {
		if _, err := syscall.ParseRoutingSockaddr(tt); err != nil {
			t.Errorf("#%d: %v", i, err)
		}
	}
}

type addrFamily byte

func (f addrFamily) String() string {
	switch f {
	case syscall.AF_UNSPEC:
		return "unspec"
	case syscall.AF_LINK:
		return "link"
	case syscall.AF_INET:
		return "inet4"
	case syscall.AF_INET6:
		return "inet6"
	default:
		return fmt.Sprintf("unknown %d", f)
	}
}

type addrFlags uint32

var addrFlagNames = [...]string{
	"dst",
	"gateway",
	"netmask",
	"genmask",
	"ifp",
	"ifa",
	"author",
	"brd",
	"mpls1,tag,src", // sockaddr_mpls=dragonfly,netbsd, sockaddr_in/in6=openbsd
	"mpls2,srcmask", // sockaddr_mpls=dragonfly, sockaddr_in/in6=openbsd
	"mpls3,label",   // sockaddr_mpls=dragonfly, sockaddr_rtlabel=openbsd
}

func (f addrFlags) String() string {
	var s string
	for i, name := range addrFlagNames {
		if f&(1<<uint(i)) != 0 {
			if s != "" {
				s += "|"
			}
			s += name
		}
	}
	if s == "" {
		return "<nil>"
	}
	return s
}

type sockaddrs []syscall.Sockaddr

func (sas sockaddrs) String() string {
	var s string
	for _, sa := range sas {
		if sa == nil {
			continue
		}
		if len(s) > 0 {
			s += " "
		}
		switch sa := sa.(type) {
		case *syscall.SockaddrDatalink:
			s += fmt.Sprintf("[%v/%v/%v t/n/a/s=%v/%v/%v/%v]", sa.Len, addrFamily(sa.Family), sa.Index, sa.Type, sa.Nlen, sa.Alen, sa.Slen)
		case *syscall.SockaddrInet4:
			s += fmt.Sprintf("%v", net.IP(sa.Addr[:]).To4())
		case *syscall.SockaddrInet6:
			s += fmt.Sprintf("%v", net.IP(sa.Addr[:]).To16())
		}
	}
	if s == "" {
		return "<nil>"
	}
	return s
}

func (sas sockaddrs) match(flags addrFlags) error {
	var f addrFlags
	family := syscall.AF_UNSPEC
	for i := range sas {
		if sas[i] != nil {
			f |= 1 << uint(i)
		}
		switch sas[i].(type) {
		case *syscall.SockaddrInet4:
			if family == syscall.AF_UNSPEC {
				family = syscall.AF_INET
			}
			if family != syscall.AF_INET {
				return fmt.Errorf("got %v; want %v", sockaddrs(sas), family)
			}
		case *syscall.SockaddrInet6:
			if family == syscall.AF_UNSPEC {
				family = syscall.AF_INET6
			}
			if family != syscall.AF_INET6 {
				return fmt.Errorf("got %v; want %v", sockaddrs(sas), family)
			}
		}
	}
	if f != flags {
		return fmt.Errorf("got %v; want %v", f, flags)
	}
	return nil
}
