golang获取网卡信息操作

 更新时间:2020年12月24日 15:11:35   作者:路人99527  
这篇文章主要介绍了golang获取网卡信息操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

我就废话不多说了,大家还是直接看代码吧~

package main
import (
	"fmt"
	"os/exec"
	"strings"
	"github.com/safchain/ethtool"
)
func main() {
	baseNicPath := "/sys/class/net/"
	cmd := exec.Command("ls", baseNicPath)
	buf, err := cmd.Output()
	if err != nil {
		//fmt.Println("Error:", err)
		return
	}
	output := string(buf)
	for _, device := range strings.Split(output, "\n") {
		if len(device) > 1 {
			fmt.Println(device)
			ethHandle, err := ethtool.NewEthtool()
			if err != nil {
				panic(err.Error())
			}
			defer ethHandle.Close()
			stats, err := ethHandle.LinkState(device)
			if err != nil {
				panic(err.Error())
			}
			fmt.Printf("LinkName: %s LinkState: %d\n", device, stats)
		}
	}
}
©

补充:GO 语言取得 Ethernet 类型的网卡地址

在 C# 中取得 Ethernet 类型的网卡地址

在 C# 中,因为有 NetworkInterface .NetworkInterfaceType == NetworkInterfaceType.Ethernet 所以,很容易在代码中进行判断。

public static PhysicalAddress GetMacAddress()
{
  foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
  {
    // Only consider Ethernet network interfaces
    if (nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet) // nic.OperationalStatus == OperationalStatus.Up
    {
      return nic.GetPhysicalAddress();
    }
  }
  return null;
}

在 GO 中的处理办法

搜索百度百十回,没有找到答案,无奈,搜索 net 包的源码,找到蛛丝马迹,在未公开的方法中,找到一个类型的判断语句。net/interface_windows.go 中,有 case windows.IF_TYPE_ETHERNET_CSMACD 的类型判断。

再查找 IF_TYPE_ETHERNET_CSMACD 的资料,正是这里所需要的。

参考:IP_INTERFACE_NAME_INFO_W2KSP1 structure

于是,将需要的部分复制出来加以改造,得到 IsEthernet 方法,结合 net 包中已有的方法,参数使用 net.Interface 的 Index 来使用。

完整代码如下:

package machine 
import (
  "errors"
  "net"
  "os"
  "strings"
  "syscall"
  "unsafe" 
  "golang.org/x/sys/windows"
)
 
func GetMACAddress() (string, error) {
  netInterfaces, err := net.Interfaces()
  if err != nil {
    panic(err.Error())
  }
 
  mac, macerr := "", errors.New("no valid mac address")
  for i := 0; i < len(netInterfaces); i++ {
    if (netInterfaces[i].Flags&net.FlagLoopback) == 0 && strings.Contains(netInterfaces[i].Flags.String(), "broadcast") {
      index := netInterfaces[i].Index
 
      if isEthernet(index) {
        mac = netInterfaces[i].HardwareAddr.String()
        return mac, nil
      }
    }
  }
  return mac, macerr
}
 
// 根据网卡接口 Index 判断其是否为 Ethernet 网卡
func isEthernet(ifindex int) bool {
  aas, err := adapterAddresses()
  if err != nil {
    return false
  }
  result := false
  for _, aa := range aas {
    index := aa.IfIndex
    if ifindex == int(index) {
      switch aa.IfType {
      case windows.IF_TYPE_ETHERNET_CSMACD:
        result = true
      }
 
      if result {
        break
      }
    }
  }
  return result
}
 
// 从 net/interface_windows.go 中复制过来
func adapterAddresses() ([]*windows.IpAdapterAddresses, error) {
  var b []byte
  l := uint32(15000) // recommended initial size
  for {
    b = make([]byte, l)
    err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
    if err == nil {
      if l == 0 {
        return nil, nil
      }
      break
    }
    if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
      return nil, os.NewSyscallError("getadaptersaddresses", err)
    }
    if l <= uint32(len(b)) {
      return nil, os.NewSyscallError("getadaptersaddresses", err)
    }
  }
  var aas []*windows.IpAdapterAddresses
  for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next {
    aas = append(aas, aa)
  }
  return aas, nil
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • 使用Go初始化Struct的方法详解

    使用Go初始化Struct的方法详解

    面向对象编程语言最基础的概念就是类(class),不过Go语言并没有类的概念,所以使用Go语言开发时,我们一般会用struct(结构体)来模拟面向对象中的类,下面我们来介绍几种创建struct类型变量的方法,需要的朋友可以参考下
    2024-01-01
  • 解决Go语言time包数字与时间相乘的问题

    解决Go语言time包数字与时间相乘的问题

    这篇文章主要介绍了Go语言time包数字与时间相乘的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • win7下配置GO语言环境 + eclipse配置GO开发

    win7下配置GO语言环境 + eclipse配置GO开发

    这篇文章主要介绍了win7下配置GO语言环境 + eclipse配置GO开发,需要的朋友可以参考下
    2014-10-10
  • 解析golang中的并发安全和锁问题

    解析golang中的并发安全和锁问题

    本文我们来学习一下golang中的并发安全和锁问题,文章通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-11-11
  • golang Gorm与数据库完整性约束详解

    golang Gorm与数据库完整性约束详解

    这篇文章主要介绍了golang Gorm与数据库完整性约束详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go语言实现配置热加载的方法分享

    Go语言实现配置热加载的方法分享

    web项目,经常需要热启动各种各样的配置信息,一旦这些服务发生变更,我们需要重新启动web server,以使配置生效,实现配置热加载,本文为大家整理了几个方法实现这个需求,需要的可以参考下
    2023-05-05
  • Golang中漏洞数据库的使用详解

    Golang中漏洞数据库的使用详解

    govulncheck是Golang中的漏洞扫描工具,它强大功能的背后,离不开 Go 漏洞数据库(Go vulnerability database)的支持,所以本文就来为大家详细讲解下 Go 漏洞数据库相关的知识
    2023-09-09
  • Go语言性能监控和调优的工具和方法

    Go语言性能监控和调优的工具和方法

    本文介绍了Go语言性能监控和调优的工具和方法,包括 pprof、expvar 和 trace 等工具的使用方法和注意事项,以及性能调优的一些常见方法,如减少内存分配、避免频繁的垃圾回收、避免过度查询数据库等,针对不同的程序,应该根据实际情况采用不同的优化方法
    2024-01-01
  • 深入探究Golang中log标准库的使用

    深入探究Golang中log标准库的使用

    Go 语言标准库中的 log 包设计简洁明了,易于上手,可以轻松记录程序运行时的信息、调试错误以及跟踪代码执行过程中的问题等。本文主要来深入探究 log 包的使用和原理,帮助读者更好地了解和掌握它
    2023-05-05
  • Go语言中循环语句使用的示例详解

    Go语言中循环语句使用的示例详解

    在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。本文将通过示例详细为大家讲讲Go语言中的循环语句,需要的可以参考一下
    2022-04-04

最新评论