golang获取网卡信息操作
程序员文章站
2022-08-12 16:48:03
我就废话不多说了,大家还是直接看代码吧~package mainimport ("fmt""os/exec""strings""github.com/safchain/ethtool")func ma...
我就废话不多说了,大家还是直接看代码吧~
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 }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。