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 5package net 6 7import "errors" 8 9var ( 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. 20type 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 28type Flags uint 29 30const ( 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 38var flagNames = []string{ 39 "up", 40 "broadcast", 41 "loopback", 42 "pointtopoint", 43 "multicast", 44} 45 46func (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. 63func (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. 76func (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. 88func 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. 98func 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. 107func 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 122func 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. 132func 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