Home | History | Annotate | Download | only in 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 package net
      6 
      7 import "errors"
      8 
      9 var (
     10 	errInvalidInterface         = errors.New("invalid network interface")
     11 	errInvalidInterfaceIndex    = errors.New("invalid network interface index")
     12 	errInvalidInterfaceName     = errors.New("invalid network interface name")
     13 	errNoSuchInterface          = errors.New("no such network interface")
     14 	errNoSuchMulticastInterface = errors.New("no such multicast network interface")
     15 )
     16 
     17 // Interface represents a mapping between network interface name
     18 // and index.  It also represents network interface facility
     19 // information.
     20 type Interface struct {
     21 	Index        int          // positive integer that starts at one, zero is never used
     22 	MTU          int          // maximum transmission unit
     23 	Name         string       // e.g., "en0", "lo0", "eth0.100"
     24 	HardwareAddr HardwareAddr // IEEE MAC-48, EUI-48 and EUI-64 form
     25 	Flags        Flags        // e.g., FlagUp, FlagLoopback, FlagMulticast
     26 }
     27 
     28 type Flags uint
     29 
     30 const (
     31 	FlagUp           Flags = 1 << iota // interface is up
     32 	FlagBroadcast                      // interface supports broadcast access capability
     33 	FlagLoopback                       // interface is a loopback interface
     34 	FlagPointToPoint                   // interface belongs to a point-to-point link
     35 	FlagMulticast                      // interface supports multicast access capability
     36 )
     37 
     38 var flagNames = []string{
     39 	"up",
     40 	"broadcast",
     41 	"loopback",
     42 	"pointtopoint",
     43 	"multicast",
     44 }
     45 
     46 func (f Flags) String() string {
     47 	s := ""
     48 	for i, name := range flagNames {
     49 		if f&(1<<uint(i)) != 0 {
     50 			if s != "" {
     51 				s += "|"
     52 			}
     53 			s += name
     54 		}
     55 	}
     56 	if s == "" {
     57 		s = "0"
     58 	}
     59 	return s
     60 }
     61 
     62 // Addrs returns interface addresses for a specific interface.
     63 func (ifi *Interface) Addrs() ([]Addr, error) {
     64 	if ifi == nil {
     65 		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
     66 	}
     67 	ifat, err := interfaceAddrTable(ifi)
     68 	if err != nil {
     69 		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
     70 	}
     71 	return ifat, err
     72 }
     73 
     74 // MulticastAddrs returns multicast, joined group addresses for
     75 // a specific interface.
     76 func (ifi *Interface) MulticastAddrs() ([]Addr, error) {
     77 	if ifi == nil {
     78 		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
     79 	}
     80 	ifat, err := interfaceMulticastAddrTable(ifi)
     81 	if err != nil {
     82 		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
     83 	}
     84 	return ifat, err
     85 }
     86 
     87 // Interfaces returns a list of the system's network interfaces.
     88 func Interfaces() ([]Interface, error) {
     89 	ift, err := interfaceTable(0)
     90 	if err != nil {
     91 		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
     92 	}
     93 	return ift, err
     94 }
     95 
     96 // InterfaceAddrs returns a list of the system's network interface
     97 // addresses.
     98 func InterfaceAddrs() ([]Addr, error) {
     99 	ifat, err := interfaceAddrTable(nil)
    100 	if err != nil {
    101 		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
    102 	}
    103 	return ifat, err
    104 }
    105 
    106 // InterfaceByIndex returns the interface specified by index.
    107 func InterfaceByIndex(index int) (*Interface, error) {
    108 	if index <= 0 {
    109 		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceIndex}
    110 	}
    111 	ift, err := interfaceTable(index)
    112 	if err != nil {
    113 		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
    114 	}
    115 	ifi, err := interfaceByIndex(ift, index)
    116 	if err != nil {
    117 		err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
    118 	}
    119 	return ifi, err
    120 }
    121 
    122 func interfaceByIndex(ift []Interface, index int) (*Interface, error) {
    123 	for _, ifi := range ift {
    124 		if index == ifi.Index {
    125 			return &ifi, nil
    126 		}
    127 	}
    128 	return nil, errNoSuchInterface
    129 }
    130 
    131 // InterfaceByName returns the interface specified by name.
    132 func InterfaceByName(name string) (*Interface, error) {
    133 	if name == "" {
    134 		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceName}
    135 	}
    136 	ift, err := interfaceTable(0)
    137 	if err != nil {
    138 		return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
    139 	}
    140 	for _, ifi := range ift {
    141 		if name == ifi.Name {
    142 			return &ifi, nil
    143 		}
    144 	}
    145 	return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errNoSuchInterface}
    146 }
    147