1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package net
6
7import (
8	"syscall"
9
10	"golang.org/x/net/lif"
11)
12
13// If the ifindex is zero, interfaceTable returns mappings of all
14// network interfaces. Otherwise it returns a mapping of a specific
15// interface.
16func interfaceTable(ifindex int) ([]Interface, error) {
17	lls, err := lif.Links(syscall.AF_UNSPEC, "")
18	if err != nil {
19		return nil, err
20	}
21	var ift []Interface
22	for _, ll := range lls {
23		if ifindex != 0 && ifindex != ll.Index {
24			continue
25		}
26		ifi := Interface{Index: ll.Index, MTU: ll.MTU, Name: ll.Name, Flags: linkFlags(ll.Flags)}
27		if len(ll.Addr) > 0 {
28			ifi.HardwareAddr = HardwareAddr(ll.Addr)
29		}
30		ift = append(ift, ifi)
31	}
32	return ift, nil
33}
34
35func linkFlags(rawFlags int) Flags {
36	var f Flags
37	if rawFlags&syscall.IFF_UP != 0 {
38		f |= FlagUp
39	}
40	if rawFlags&syscall.IFF_RUNNING != 0 {
41		f |= FlagRunning
42	}
43	if rawFlags&syscall.IFF_BROADCAST != 0 {
44		f |= FlagBroadcast
45	}
46	if rawFlags&syscall.IFF_LOOPBACK != 0 {
47		f |= FlagLoopback
48	}
49	if rawFlags&syscall.IFF_POINTOPOINT != 0 {
50		f |= FlagPointToPoint
51	}
52	if rawFlags&syscall.IFF_MULTICAST != 0 {
53		f |= FlagMulticast
54	}
55	return f
56}
57
58// If the ifi is nil, interfaceAddrTable returns addresses for all
59// network interfaces. Otherwise it returns addresses for a specific
60// interface.
61func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
62	var name string
63	if ifi != nil {
64		name = ifi.Name
65	}
66	as, err := lif.Addrs(syscall.AF_UNSPEC, name)
67	if err != nil {
68		return nil, err
69	}
70	var ifat []Addr
71	for _, a := range as {
72		var ip IP
73		var mask IPMask
74		switch a := a.(type) {
75		case *lif.Inet4Addr:
76			ip = IPv4(a.IP[0], a.IP[1], a.IP[2], a.IP[3])
77			mask = CIDRMask(a.PrefixLen, 8*IPv4len)
78		case *lif.Inet6Addr:
79			ip = make(IP, IPv6len)
80			copy(ip, a.IP[:])
81			mask = CIDRMask(a.PrefixLen, 8*IPv6len)
82		}
83		ifat = append(ifat, &IPNet{IP: ip, Mask: mask})
84	}
85	return ifat, nil
86}
87
88// interfaceMulticastAddrTable returns addresses for a specific
89// interface.
90func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
91	return nil, nil
92}
93