diff options
Diffstat (limited to 'vendor/github.com/safchain/ethtool/ethtool.go')
-rw-r--r-- | vendor/github.com/safchain/ethtool/ethtool.go | 541 |
1 files changed, 0 insertions, 541 deletions
diff --git a/vendor/github.com/safchain/ethtool/ethtool.go b/vendor/github.com/safchain/ethtool/ethtool.go deleted file mode 100644 index 8dcc78c05..000000000 --- a/vendor/github.com/safchain/ethtool/ethtool.go +++ /dev/null @@ -1,541 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -// Package ethtool aims to provide a library giving a simple access to the -// Linux SIOCETHTOOL ioctl operations. It can be used to retrieve informations -// from a network device like statistics, driver related informations or -// even the peer of a VETH interface. -package ethtool - -import ( - "bytes" - "encoding/hex" - "fmt" - "strings" - "syscall" - "unsafe" -) - -// Maximum size of an interface name -const ( - IFNAMSIZ = 16 -) - -// ioctl ethtool request -const ( - SIOCETHTOOL = 0x8946 -) - -// ethtool stats related constants. -const ( - ETH_GSTRING_LEN = 32 - ETH_SS_STATS = 1 - ETH_SS_FEATURES = 4 - ETHTOOL_GDRVINFO = 0x00000003 - ETHTOOL_GSTRINGS = 0x0000001b - ETHTOOL_GSTATS = 0x0000001d - // other CMDs from ethtool-copy.h of ethtool-3.5 package - ETHTOOL_GSET = 0x00000001 /* Get settings. */ - ETHTOOL_SSET = 0x00000002 /* Set settings. */ - ETHTOOL_GMSGLVL = 0x00000007 /* Get driver message level */ - ETHTOOL_SMSGLVL = 0x00000008 /* Set driver msg level. */ - /* Get link status for host, i.e. whether the interface *and* the - * physical port (if there is one) are up (ethtool_value). */ - ETHTOOL_GLINK = 0x0000000a - ETHTOOL_GMODULEINFO = 0x00000042 /* Get plug-in module information */ - ETHTOOL_GMODULEEEPROM = 0x00000043 /* Get plug-in module eeprom */ - ETHTOOL_GPERMADDR = 0x00000020 - ETHTOOL_GFEATURES = 0x0000003a /* Get device offload settings */ - ETHTOOL_SFEATURES = 0x0000003b /* Change device offload settings */ - ETHTOOL_GFLAGS = 0x00000025 /* Get flags bitmap(ethtool_value) */ - ETHTOOL_GSSET_INFO = 0x00000037 /* Get string set info */ -) - -// MAX_GSTRINGS maximum number of stats entries that ethtool can -// retrieve currently. -const ( - MAX_GSTRINGS = 1000 - MAX_FEATURE_BLOCKS = (MAX_GSTRINGS + 32 - 1) / 32 - EEPROM_LEN = 640 - PERMADDR_LEN = 32 -) - -type ifreq struct { - ifr_name [IFNAMSIZ]byte - ifr_data uintptr -} - -// following structures comes from uapi/linux/ethtool.h -type ethtoolSsetInfo struct { - cmd uint32 - reserved uint32 - sset_mask uint32 - data uintptr -} - -type ethtoolGetFeaturesBlock struct { - available uint32 - requested uint32 - active uint32 - never_changed uint32 -} - -type ethtoolGfeatures struct { - cmd uint32 - size uint32 - blocks [MAX_FEATURE_BLOCKS]ethtoolGetFeaturesBlock -} - -type ethtoolSetFeaturesBlock struct { - valid uint32 - requested uint32 -} - -type ethtoolSfeatures struct { - cmd uint32 - size uint32 - blocks [MAX_FEATURE_BLOCKS]ethtoolSetFeaturesBlock -} - -type ethtoolDrvInfo struct { - cmd uint32 - driver [32]byte - version [32]byte - fw_version [32]byte - bus_info [32]byte - erom_version [32]byte - reserved2 [12]byte - n_priv_flags uint32 - n_stats uint32 - testinfo_len uint32 - eedump_len uint32 - regdump_len uint32 -} - -type ethtoolGStrings struct { - cmd uint32 - string_set uint32 - len uint32 - data [MAX_GSTRINGS * ETH_GSTRING_LEN]byte -} - -type ethtoolStats struct { - cmd uint32 - n_stats uint32 - data [MAX_GSTRINGS]uint64 -} - -type ethtoolEeprom struct { - cmd uint32 - magic uint32 - offset uint32 - len uint32 - data [EEPROM_LEN]byte -} - -type ethtoolModInfo struct { - cmd uint32 - tpe uint32 - eeprom_len uint32 - reserved [8]uint32 -} - -type ethtoolLink struct { - cmd uint32 - data uint32 -} - -type ethtoolPermAddr struct { - cmd uint32 - size uint32 - data [PERMADDR_LEN]byte -} - -type Ethtool struct { - fd int -} - -// DriverName returns the driver name of the given interface name. -func (e *Ethtool) DriverName(intf string) (string, error) { - info, err := e.getDriverInfo(intf) - if err != nil { - return "", err - } - return string(bytes.Trim(info.driver[:], "\x00")), nil -} - -// BusInfo returns the bus information of the given interface name. -func (e *Ethtool) BusInfo(intf string) (string, error) { - info, err := e.getDriverInfo(intf) - if err != nil { - return "", err - } - return string(bytes.Trim(info.bus_info[:], "\x00")), nil -} - -// ModuleEeprom returns Eeprom information of the given interface name. -func (e *Ethtool) ModuleEeprom(intf string) ([]byte, error) { - eeprom, _, err := e.getModuleEeprom(intf) - if err != nil { - return nil, err - } - - return eeprom.data[:eeprom.len], nil -} - -// ModuleEeprom returns Eeprom information of the given interface name. -func (e *Ethtool) ModuleEepromHex(intf string) (string, error) { - eeprom, _, err := e.getModuleEeprom(intf) - if err != nil { - return "", err - } - - return hex.EncodeToString(eeprom.data[:eeprom.len]), nil -} - -// DriverInfo returns driver information of the given interface name. -func (e *Ethtool) DriverInfo(intf string) (ethtoolDrvInfo, error) { - drvInfo, err := e.getDriverInfo(intf) - if err != nil { - return ethtoolDrvInfo{}, err - } - - return drvInfo, nil -} - -// PermAddr returns permanent address of the given interface name. -func (e *Ethtool) PermAddr(intf string) (string, error) { - permAddr, err := e.getPermAddr(intf) - if err != nil { - return "", err - } - - if permAddr.data[0] == 0 && permAddr.data[1] == 0 && - permAddr.data[2] == 0 && permAddr.data[3] == 0 && - permAddr.data[4] == 0 && permAddr.data[5] == 0 { - return "", nil - } - - return fmt.Sprintf("%x:%x:%x:%x:%x:%x", - permAddr.data[0:1], - permAddr.data[1:2], - permAddr.data[2:3], - permAddr.data[3:4], - permAddr.data[4:5], - permAddr.data[5:6], - ), nil -} - -func (e *Ethtool) ioctl(intf string, data uintptr) error { - var name [IFNAMSIZ]byte - copy(name[:], []byte(intf)) - - ifr := ifreq{ - ifr_name: name, - ifr_data: data, - } - - _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) - if ep != 0 { - return syscall.Errno(ep) - } - - return nil -} - -func (e *Ethtool) getDriverInfo(intf string) (ethtoolDrvInfo, error) { - drvinfo := ethtoolDrvInfo{ - cmd: ETHTOOL_GDRVINFO, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&drvinfo))); err != nil { - return ethtoolDrvInfo{}, err - } - - return drvinfo, nil -} - -func (e *Ethtool) getPermAddr(intf string) (ethtoolPermAddr, error) { - permAddr := ethtoolPermAddr{ - cmd: ETHTOOL_GPERMADDR, - size: PERMADDR_LEN, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&permAddr))); err != nil { - return ethtoolPermAddr{}, err - } - - return permAddr, nil -} - -func (e *Ethtool) getModuleEeprom(intf string) (ethtoolEeprom, ethtoolModInfo, error) { - modInfo := ethtoolModInfo{ - cmd: ETHTOOL_GMODULEINFO, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&modInfo))); err != nil { - return ethtoolEeprom{}, ethtoolModInfo{}, err - } - - eeprom := ethtoolEeprom{ - cmd: ETHTOOL_GMODULEEEPROM, - len: modInfo.eeprom_len, - offset: 0, - } - - if modInfo.eeprom_len > EEPROM_LEN { - return ethtoolEeprom{}, ethtoolModInfo{}, fmt.Errorf("eeprom size: %d is larger than buffer size: %d", modInfo.eeprom_len, EEPROM_LEN) - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&eeprom))); err != nil { - return ethtoolEeprom{}, ethtoolModInfo{}, err - } - - return eeprom, modInfo, nil -} - -func isFeatureBitSet(blocks [MAX_FEATURE_BLOCKS]ethtoolGetFeaturesBlock, index uint) bool { - return (blocks)[index/32].active&(1<<(index%32)) != 0 -} - -func setFeatureBit(blocks *[MAX_FEATURE_BLOCKS]ethtoolSetFeaturesBlock, index uint, value bool) { - blockIndex, bitIndex := index/32, index%32 - - blocks[blockIndex].valid |= 1 << bitIndex - - if value { - blocks[blockIndex].requested |= 1 << bitIndex - } else { - blocks[blockIndex].requested &= ^(1 << bitIndex) - } -} - -// FeatureNames shows supported features by their name. -func (e *Ethtool) FeatureNames(intf string) (map[string]uint, error) { - ssetInfo := ethtoolSsetInfo{ - cmd: ETHTOOL_GSSET_INFO, - sset_mask: 1 << ETH_SS_FEATURES, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&ssetInfo))); err != nil { - return nil, err - } - - length := uint32(ssetInfo.data) - if length == 0 { - return map[string]uint{}, nil - } else if length > MAX_GSTRINGS { - return nil, fmt.Errorf("ethtool currently doesn't support more than %d entries, received %d", MAX_GSTRINGS, length) - } - - gstrings := ethtoolGStrings{ - cmd: ETHTOOL_GSTRINGS, - string_set: ETH_SS_FEATURES, - len: length, - data: [MAX_GSTRINGS * ETH_GSTRING_LEN]byte{}, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&gstrings))); err != nil { - return nil, err - } - - var result = make(map[string]uint) - for i := 0; i != int(length); i++ { - b := gstrings.data[i*ETH_GSTRING_LEN : i*ETH_GSTRING_LEN+ETH_GSTRING_LEN] - key := string(bytes.Trim(b, "\x00")) - if key != "" { - result[key] = uint(i) - } - } - - return result, nil -} - -// Features retrieves features of the given interface name. -func (e *Ethtool) Features(intf string) (map[string]bool, error) { - names, err := e.FeatureNames(intf) - if err != nil { - return nil, err - } - - length := uint32(len(names)) - if length == 0 { - return map[string]bool{}, nil - } - - features := ethtoolGfeatures{ - cmd: ETHTOOL_GFEATURES, - size: (length + 32 - 1) / 32, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&features))); err != nil { - return nil, err - } - - var result = make(map[string]bool, length) - for key, index := range names { - result[key] = isFeatureBitSet(features.blocks, index) - } - - return result, nil -} - -// Change requests a change in the given device's features. -func (e *Ethtool) Change(intf string, config map[string]bool) error { - names, err := e.FeatureNames(intf) - if err != nil { - return err - } - - length := uint32(len(names)) - - features := ethtoolSfeatures{ - cmd: ETHTOOL_SFEATURES, - size: (length + 32 - 1) / 32, - } - - for key, value := range config { - if index, ok := names[key]; ok { - setFeatureBit(&features.blocks, index, value) - } else { - return fmt.Errorf("unsupported feature %q", key) - } - } - - return e.ioctl(intf, uintptr(unsafe.Pointer(&features))) -} - -// Get state of a link. -func (e *Ethtool) LinkState(intf string) (uint32, error) { - x := ethtoolLink{ - cmd: ETHTOOL_GLINK, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&x))); err != nil { - return 0, err - } - - return x.data, nil -} - -// Stats retrieves stats of the given interface name. -func (e *Ethtool) Stats(intf string) (map[string]uint64, error) { - drvinfo := ethtoolDrvInfo{ - cmd: ETHTOOL_GDRVINFO, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&drvinfo))); err != nil { - return nil, err - } - - if drvinfo.n_stats*ETH_GSTRING_LEN > MAX_GSTRINGS*ETH_GSTRING_LEN { - return nil, fmt.Errorf("ethtool currently doesn't support more than %d entries, received %d", MAX_GSTRINGS, drvinfo.n_stats) - } - - gstrings := ethtoolGStrings{ - cmd: ETHTOOL_GSTRINGS, - string_set: ETH_SS_STATS, - len: drvinfo.n_stats, - data: [MAX_GSTRINGS * ETH_GSTRING_LEN]byte{}, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&gstrings))); err != nil { - return nil, err - } - - stats := ethtoolStats{ - cmd: ETHTOOL_GSTATS, - n_stats: drvinfo.n_stats, - data: [MAX_GSTRINGS]uint64{}, - } - - if err := e.ioctl(intf, uintptr(unsafe.Pointer(&stats))); err != nil { - return nil, err - } - - var result = make(map[string]uint64) - for i := 0; i != int(drvinfo.n_stats); i++ { - b := gstrings.data[i*ETH_GSTRING_LEN : i*ETH_GSTRING_LEN+ETH_GSTRING_LEN] - key := string(b[:strings.Index(string(b), "\x00")]) - if len(key) != 0 { - result[key] = stats.data[i] - } - } - - return result, nil -} - -// Close closes the ethool handler -func (e *Ethtool) Close() { - syscall.Close(e.fd) -} - -// NewEthtool returns a new ethtool handler -func NewEthtool() (*Ethtool, error) { - fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_IP) - if err != nil { - return nil, err - } - - return &Ethtool{ - fd: int(fd), - }, nil -} - -// BusInfo returns bus information of the given interface name. -func BusInfo(intf string) (string, error) { - e, err := NewEthtool() - if err != nil { - return "", err - } - defer e.Close() - return e.BusInfo(intf) -} - -// DriverName returns the driver name of the given interface name. -func DriverName(intf string) (string, error) { - e, err := NewEthtool() - if err != nil { - return "", err - } - defer e.Close() - return e.DriverName(intf) -} - -// Stats retrieves stats of the given interface name. -func Stats(intf string) (map[string]uint64, error) { - e, err := NewEthtool() - if err != nil { - return nil, err - } - defer e.Close() - return e.Stats(intf) -} - -// PermAddr returns permanent address of the given interface name. -func PermAddr(intf string) (string, error) { - e, err := NewEthtool() - if err != nil { - return "", err - } - defer e.Close() - return e.PermAddr(intf) -} |