code: 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
  }
docs: // FeatureNames shows supported features by their name.