1
0
mirror of https://github.com/golang/go synced 2024-11-21 18:14:42 -07:00

net: export all fields in Interface

Fixes #1942.

R=fullung, rsc
CC=golang-dev
https://golang.org/cl/4602044
This commit is contained in:
Mikio Hara 2011-06-14 13:32:52 -04:00 committed by Russ Cox
parent 0ce57a73c5
commit c4dfc55be9
5 changed files with 82 additions and 146 deletions

View File

@ -34,7 +34,41 @@ type Interface struct {
MTU int // maximum transmission unit MTU int // maximum transmission unit
Name string // e.g., "en0", "lo0", "eth0.100" Name string // e.g., "en0", "lo0", "eth0.100"
HardwareAddr HardwareAddr // IEEE MAC-48, EUI-48 and EUI-64 form HardwareAddr HardwareAddr // IEEE MAC-48, EUI-48 and EUI-64 form
rawFlags int Flags Flags // e.g., FlagUp, FlagLoopback, FlagMulticast
}
type Flags uint
const (
FlagUp Flags = 1 << iota // interface is up
FlagBroadcast // interface supports broadcast access capability
FlagLoopback // interface is a loopback interface
FlagPointToPoint // interface belongs to a point-to-point link
FlagMulticast // interface supports multicast access capability
)
var flagNames = []string{
"up",
"broadcast",
"loopback",
"pointtopoint",
"multicast",
}
func (f Flags) String() string {
s := ""
for i, name := range flagNames {
if f&(1<<uint(i)) != 0 {
if s != "" {
s += "|"
}
s += name
}
}
if s == "" {
s = "0"
}
return s
} }
// Addrs returns interface addresses for a specific interface. // Addrs returns interface addresses for a specific interface.

View File

@ -12,49 +12,6 @@ import (
"unsafe" "unsafe"
) )
// IsUp returns true if ifi is up.
func (ifi *Interface) IsUp() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_UP != 0
}
// IsLoopback returns true if ifi is a loopback interface.
func (ifi *Interface) IsLoopback() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_LOOPBACK != 0
}
// CanBroadcast returns true if ifi supports a broadcast access
// capability.
func (ifi *Interface) CanBroadcast() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_BROADCAST != 0
}
// IsPointToPoint returns true if ifi belongs to a point-to-point
// link.
func (ifi *Interface) IsPointToPoint() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_POINTOPOINT != 0
}
// CanMulticast returns true if ifi supports a multicast access
// capability.
func (ifi *Interface) CanMulticast() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_MULTICAST != 0
}
// If the ifindex is zero, interfaceTable returns mappings of all // If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces. Otheriwse it returns a mapping of a specific // network interfaces. Otheriwse it returns a mapping of a specific
// interface. // interface.
@ -106,7 +63,7 @@ func newLink(m *syscall.InterfaceMessage) ([]Interface, os.Error) {
// NOTE: SockaddrDatalink.Data is minimum work area, // NOTE: SockaddrDatalink.Data is minimum work area,
// can be larger. // can be larger.
m.Data = m.Data[unsafe.Offsetof(v.Data):] m.Data = m.Data[unsafe.Offsetof(v.Data):]
ifi := Interface{Index: int(m.Header.Index), rawFlags: int(m.Header.Flags)} ifi := Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
var name [syscall.IFNAMSIZ]byte var name [syscall.IFNAMSIZ]byte
for i := 0; i < int(v.Nlen); i++ { for i := 0; i < int(v.Nlen); i++ {
name[i] = byte(m.Data[i]) name[i] = byte(m.Data[i])
@ -125,6 +82,26 @@ func newLink(m *syscall.InterfaceMessage) ([]Interface, os.Error) {
return ift, nil return ift, nil
} }
func linkFlags(rawFlags int32) Flags {
var f Flags
if rawFlags&syscall.IFF_UP != 0 {
f |= FlagUp
}
if rawFlags&syscall.IFF_BROADCAST != 0 {
f |= FlagBroadcast
}
if rawFlags&syscall.IFF_LOOPBACK != 0 {
f |= FlagLoopback
}
if rawFlags&syscall.IFF_POINTOPOINT != 0 {
f |= FlagPointToPoint
}
if rawFlags&syscall.IFF_MULTICAST != 0 {
f |= FlagMulticast
}
return f
}
// If the ifindex is zero, interfaceAddrTable returns addresses // If the ifindex is zero, interfaceAddrTable returns addresses
// for all network interfaces. Otherwise it returns addresses // for all network interfaces. Otherwise it returns addresses
// for a specific interface. // for a specific interface.

View File

@ -12,49 +12,6 @@ import (
"unsafe" "unsafe"
) )
// IsUp returns true if ifi is up.
func (ifi *Interface) IsUp() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_UP != 0
}
// IsLoopback returns true if ifi is a loopback interface.
func (ifi *Interface) IsLoopback() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_LOOPBACK != 0
}
// CanBroadcast returns true if ifi supports a broadcast access
// capability.
func (ifi *Interface) CanBroadcast() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_BROADCAST != 0
}
// IsPointToPoint returns true if ifi belongs to a point-to-point
// link.
func (ifi *Interface) IsPointToPoint() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_POINTOPOINT != 0
}
// CanMulticast returns true if ifi supports a multicast access
// capability.
func (ifi *Interface) CanMulticast() bool {
if ifi == nil {
return false
}
return ifi.rawFlags&syscall.IFF_MULTICAST != 0
}
// If the ifindex is zero, interfaceTable returns mappings of all // If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces. Otheriwse it returns a mapping of a specific // network interfaces. Otheriwse it returns a mapping of a specific
// interface. // interface.
@ -98,7 +55,7 @@ done:
} }
func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interface { func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interface {
ifi := Interface{Index: int(ifim.Index), rawFlags: int(ifim.Flags)} ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
for _, a := range attrs { for _, a := range attrs {
switch a.Attr.Type { switch a.Attr.Type {
case syscall.IFLA_ADDRESS: case syscall.IFLA_ADDRESS:
@ -112,7 +69,7 @@ func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interfac
ifi.HardwareAddr = a.Value[:] ifi.HardwareAddr = a.Value[:]
} }
case syscall.IFLA_IFNAME: case syscall.IFLA_IFNAME:
ifi.Name = string(a.Value[:]) ifi.Name = string(a.Value[:len(a.Value)-1])
case syscall.IFLA_MTU: case syscall.IFLA_MTU:
ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0])) ifi.MTU = int(uint32(a.Value[3])<<24 | uint32(a.Value[2])<<16 | uint32(a.Value[1])<<8 | uint32(a.Value[0]))
} }
@ -120,6 +77,26 @@ func newLink(attrs []syscall.NetlinkRouteAttr, ifim *syscall.IfInfomsg) Interfac
return ifi return ifi
} }
func linkFlags(rawFlags uint32) Flags {
var f Flags
if rawFlags&syscall.IFF_UP != 0 {
f |= FlagUp
}
if rawFlags&syscall.IFF_BROADCAST != 0 {
f |= FlagBroadcast
}
if rawFlags&syscall.IFF_LOOPBACK != 0 {
f |= FlagLoopback
}
if rawFlags&syscall.IFF_POINTOPOINT != 0 {
f |= FlagPointToPoint
}
if rawFlags&syscall.IFF_MULTICAST != 0 {
f |= FlagMulticast
}
return f
}
// If the ifindex is zero, interfaceAddrTable returns addresses // If the ifindex is zero, interfaceAddrTable returns addresses
// for all network interfaces. Otherwise it returns addresses // for all network interfaces. Otherwise it returns addresses
// for a specific interface. // for a specific interface.

View File

@ -8,34 +8,6 @@ package net
import "os" import "os"
// IsUp returns true if ifi is up.
func (ifi *Interface) IsUp() bool {
return false
}
// IsLoopback returns true if ifi is a loopback interface.
func (ifi *Interface) IsLoopback() bool {
return false
}
// CanBroadcast returns true if ifi supports a broadcast access
// capability.
func (ifi *Interface) CanBroadcast() bool {
return false
}
// IsPointToPoint returns true if ifi belongs to a point-to-point
// link.
func (ifi *Interface) IsPointToPoint() bool {
return false
}
// CanMulticast returns true if ifi supports a multicast access
// capability.
func (ifi *Interface) CanMulticast() bool {
return false
}
// If the ifindex is zero, interfaceTable returns mappings of all // If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces. Otheriwse it returns a mapping of a specific // network interfaces. Otheriwse it returns a mapping of a specific
// interface. // interface.

View File

@ -19,30 +19,6 @@ func sameInterface(i, j *Interface) bool {
return false return false
} }
func interfaceFlagsString(ifi *Interface) string {
fs := "<"
if ifi.IsUp() {
fs += "UP,"
}
if ifi.CanBroadcast() {
fs += "BROADCAST,"
}
if ifi.IsLoopback() {
fs += "LOOPBACK,"
}
if ifi.IsPointToPoint() {
fs += "POINTOPOINT,"
}
if ifi.CanMulticast() {
fs += "MULTICAST,"
}
if len(fs) > 1 {
fs = fs[:len(fs)-1]
}
fs += ">"
return fs
}
func TestInterfaces(t *testing.T) { func TestInterfaces(t *testing.T) {
ift, err := Interfaces() ift, err := Interfaces()
if err != nil { if err != nil {
@ -69,11 +45,11 @@ func TestInterfaces(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Interface.Addrs() failed: %v", err) t.Fatalf("Interface.Addrs() failed: %v", err)
} }
t.Logf("%s: flags %s, ifindex %v, mtu %v\n", ifi.Name, interfaceFlagsString(&ifi), ifi.Index, ifi.MTU) t.Logf("%q: flags %q, ifindex %v, mtu %v\n", ifi.Name, ifi.Flags.String(), ifi.Index, ifi.MTU)
for _, ifa := range ifat { for _, ifa := range ifat {
t.Logf("\tinterface address %s\n", ifa.String()) t.Logf("\tinterface address %q\n", ifa.String())
} }
t.Logf("\thardware address %v", ifi.HardwareAddr.String()) t.Logf("\thardware address %q", ifi.HardwareAddr.String())
} }
} }
@ -85,6 +61,6 @@ func TestInterfaceAddrs(t *testing.T) {
t.Logf("table: len/cap = %v/%v\n", len(ifat), cap(ifat)) t.Logf("table: len/cap = %v/%v\n", len(ifat), cap(ifat))
for _, ifa := range ifat { for _, ifa := range ifat {
t.Logf("interface address %s\n", ifa.String()) t.Logf("interface address %q\n", ifa.String())
} }
} }