...

Source file src/net/interface_bsd.go

Documentation: net

		 1  // Copyright 2011 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  
		 5  //go:build darwin || dragonfly || freebsd || netbsd || openbsd
		 6  // +build darwin dragonfly freebsd netbsd openbsd
		 7  
		 8  package net
		 9  
		10  import (
		11  	"syscall"
		12  
		13  	"golang.org/x/net/route"
		14  )
		15  
		16  // If the ifindex is zero, interfaceTable returns mappings of all
		17  // network interfaces. Otherwise it returns a mapping of a specific
		18  // interface.
		19  func interfaceTable(ifindex int) ([]Interface, error) {
		20  	msgs, err := interfaceMessages(ifindex)
		21  	if err != nil {
		22  		return nil, err
		23  	}
		24  	n := len(msgs)
		25  	if ifindex != 0 {
		26  		n = 1
		27  	}
		28  	ift := make([]Interface, n)
		29  	n = 0
		30  	for _, m := range msgs {
		31  		switch m := m.(type) {
		32  		case *route.InterfaceMessage:
		33  			if ifindex != 0 && ifindex != m.Index {
		34  				continue
		35  			}
		36  			ift[n].Index = m.Index
		37  			ift[n].Name = m.Name
		38  			ift[n].Flags = linkFlags(m.Flags)
		39  			if sa, ok := m.Addrs[syscall.RTAX_IFP].(*route.LinkAddr); ok && len(sa.Addr) > 0 {
		40  				ift[n].HardwareAddr = make([]byte, len(sa.Addr))
		41  				copy(ift[n].HardwareAddr, sa.Addr)
		42  			}
		43  			for _, sys := range m.Sys() {
		44  				if imx, ok := sys.(*route.InterfaceMetrics); ok {
		45  					ift[n].MTU = imx.MTU
		46  					break
		47  				}
		48  			}
		49  			n++
		50  			if ifindex == m.Index {
		51  				return ift[:n], nil
		52  			}
		53  		}
		54  	}
		55  	return ift[:n], nil
		56  }
		57  
		58  func linkFlags(rawFlags int) Flags {
		59  	var f Flags
		60  	if rawFlags&syscall.IFF_UP != 0 {
		61  		f |= FlagUp
		62  	}
		63  	if rawFlags&syscall.IFF_BROADCAST != 0 {
		64  		f |= FlagBroadcast
		65  	}
		66  	if rawFlags&syscall.IFF_LOOPBACK != 0 {
		67  		f |= FlagLoopback
		68  	}
		69  	if rawFlags&syscall.IFF_POINTOPOINT != 0 {
		70  		f |= FlagPointToPoint
		71  	}
		72  	if rawFlags&syscall.IFF_MULTICAST != 0 {
		73  		f |= FlagMulticast
		74  	}
		75  	return f
		76  }
		77  
		78  // If the ifi is nil, interfaceAddrTable returns addresses for all
		79  // network interfaces. Otherwise it returns addresses for a specific
		80  // interface.
		81  func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
		82  	index := 0
		83  	if ifi != nil {
		84  		index = ifi.Index
		85  	}
		86  	msgs, err := interfaceMessages(index)
		87  	if err != nil {
		88  		return nil, err
		89  	}
		90  	ifat := make([]Addr, 0, len(msgs))
		91  	for _, m := range msgs {
		92  		switch m := m.(type) {
		93  		case *route.InterfaceAddrMessage:
		94  			if index != 0 && index != m.Index {
		95  				continue
		96  			}
		97  			var mask IPMask
		98  			switch sa := m.Addrs[syscall.RTAX_NETMASK].(type) {
		99  			case *route.Inet4Addr:
	 100  				mask = IPv4Mask(sa.IP[0], sa.IP[1], sa.IP[2], sa.IP[3])
	 101  			case *route.Inet6Addr:
	 102  				mask = make(IPMask, IPv6len)
	 103  				copy(mask, sa.IP[:])
	 104  			}
	 105  			var ip IP
	 106  			switch sa := m.Addrs[syscall.RTAX_IFA].(type) {
	 107  			case *route.Inet4Addr:
	 108  				ip = IPv4(sa.IP[0], sa.IP[1], sa.IP[2], sa.IP[3])
	 109  			case *route.Inet6Addr:
	 110  				ip = make(IP, IPv6len)
	 111  				copy(ip, sa.IP[:])
	 112  			}
	 113  			if ip != nil && mask != nil { // NetBSD may contain route.LinkAddr
	 114  				ifat = append(ifat, &IPNet{IP: ip, Mask: mask})
	 115  			}
	 116  		}
	 117  	}
	 118  	return ifat, nil
	 119  }
	 120  

View as plain text