Black Lives Matter. Support the Equal Justice Initiative.

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