windows下无npcap驱动导致golang获取网卡失败问题

12 篇文章 0 订阅

window下无npcap驱动导致golang获取网卡失败问题

目录

window下无npcap驱动导致golang获取网卡失败问题

一、起源

二、查看pcap源码

三、查看环境

四、安装Npcap

五、运行demo程序

六、获取网卡的各个源码对比

1、golang自身的net库

2、google的pcap库

3、windows扩展库


一、起源

使用golang语言开发了一个网络安全检测的小工具,其中抓取报文模块使用的是google的gopacket包。
开发完成后编译打包成exe可执行文件,本机可以运行,结果一切正常。安装到另一台window10的时候,结果可以运行但是报错结束了。


经过debug定位发现获取网络接口的协程不能正常工作。

二、查看pcap源码

// github.com\google\gopacket\pcap\pcap.go  pcap.FindAllDevs()
// FindAllDevs attempts to enumerate all interfaces on the current machine.
func FindAllDevs() (ifs []Interface, err error) {
    alldevsp, err := pcapFindAllDevs()
    if err != nil {
        return nil, err
    }
    defer alldevsp.free()

    for alldevsp.next() {
        var iface Interface
        iface.Name = alldevsp.name()
        iface.Description = alldevsp.description()
        iface.Addresses = findalladdresses(alldevsp.addresses())
        iface.Flags = alldevsp.flags()
        ifs = append(ifs, iface)
    }
    return
}

func pcapFindAllDevs() (pcapDevices, error) {
    var alldevsp pcapDevices
    err := LoadWinPCAP()
    if err != nil {
        return alldevsp, err
    }

    buf := make([]byte, errorBufferSize)
    
    ret, _, _ := syscall.Syscall(pcapFindalldevsPtr, 2, 
        uintptr(unsafe.Pointer(&alldevsp.all)), 
        uintptr(unsafe.Pointer(&buf[0])), 0)
    
    if pcapCint(ret) < 0 {
        return pcapDevices{}, errors.New(byteSliceToString(buf))
    }
    return alldevsp, nil
}

加载kernel32.dll、wpcap.dll、msvcrt.dll依赖库
 

// LoadWinPCAP attempts to dynamically load the wpcap DLL and resolve necessary functions
func LoadWinPCAP() error {
    if pcapLoaded { //默认false,已经加载直接返回nil
        return nil
    }

    kernel32, err := syscall.LoadLibrary("kernel32.dll") //调用windows syscall API动态链接kernel32.dll
    if err != nil {
        return fmt.Errorf("couldn't load kernel32.dll")
    }
    defer syscall.FreeLibrary(kernel32)
    
    initDllPath(kernel32) //检查dll path是否存在并init
    
    if haveSearch, _ := syscall.GetProcAddress(kernel32, "AddDllDirectory"); haveSearch != 0 {
        // if AddDllDirectory is present, we can use LOAD_LIBRARY_* stuff with LoadLibraryEx to avoid wpcap.dll hijacking
        // see: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx
        const LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400
        const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
        wpcapHandle, err = windows.LoadLibraryEx("wpcap.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS|LOAD_LIBRARY_SEARCH_SYSTEM32)
        if err != nil {
            return fmt.Errorf("couldn't load wpcap.dll")
        }
    } else {
        // otherwise fall back to load it with the unsafe search cause by SetDllDirectory
        wpcapHandle, err = windows.LoadLibrary("wpcap.dll")
        if err != nil {
            return fmt.Errorf("couldn't load wpcap.dll")
        }
    }
    initLoadedDllPath(kernel32)
    msvcrtHandle, err = syscall.LoadLibrary("msvcrt.dll")
    if err != nil {
        return fmt.Errorf("couldn't load msvcrt.dll")
    }
    callocPtr, err = syscall.GetProcAddress(msvcrtHandle, "calloc")
    if err != nil {
        return fmt.Errorf("couldn't get calloc function")
    }
    
    pcapStrerrorPtr = mustLoad("pcap_strerror")
    pcapStatustostrPtr = mightLoad("pcap_statustostr") // not available on winpcap
    pcapOpenLivePtr = mustLoad("pcap_open_live")
    pcapOpenOfflinePtr = mustLoad("pcap_open_offline")
    pcapClosePtr = mustLoad("pcap_close")
    pcapGeterrPtr = mustLoad("pcap_geterr")
    pcapStatsPtr = mustLoad("pcap_stats")
    pcapCompilePtr = mustLoad("pcap_compile")
    pcapFreecodePtr = mustLoad("pcap_freecode")
    pcapLookupnetPtr = mustLoad("pcap_lookupnet")
    pcapOfflineFilterPtr = mustLoad("pcap_offline_filter")
    pcapSetfilterPtr = mustLoad("pcap_setfilter")
    pcapListDatalinksPtr = mustLoad("pcap_list_datalinks")
    pcapFreeDatalinksPtr = mustLoad("pcap_free_datalinks")
    pcapDatalinkValToNamePtr = mustLoad("pcap_datalink_val_to_name")
    pcapDatalinkValToDescriptionPtr = mustLoad("pcap_datalink_val_to_description")
    pcapOpenDeadPtr = mustLoad("pcap_open_dead")
    pcapNextExPtr = mustLoad("pcap_next_ex")
    pcapDatalinkPtr = mustLoad("pcap_datalink")
    pcapSetDatalinkPtr = mustLoad("pcap_set_datalink")
    pcapDatalinkNameToValPtr = mustLoad("pcap_datalink_name_to_val")
    pcapLibVersionPtr = mustLoad("pcap_lib_version")
    pcapFreealldevsPtr = mustLoad("pcap_freealldevs")
    pcapFindalldevsPtr = mustLoad("pcap_findalldevs")
    pcapSendpacketPtr = mustLoad("pcap_sendpacket")
    pcapSetdirectionPtr = mustLoad("pcap_setdirection")
    pcapSnapshotPtr = mustLoad("pcap_snapshot")
    //libpcap <1.2 doesn't have pcap_*_tstamp_* functions
    pcapTstampTypeValToNamePtr = mightLoad("pcap_tstamp_type_val_to_name")
    pcapTstampTypeNameToValPtr = mightLoad("pcap_tstamp_type_name_to_val")
    pcapListTstampTypesPtr = mightLoad("pcap_list_tstamp_types")
    pcapFreeTstampTypesPtr = mightLoad("pcap_free_tstamp_types")
    pcapSetTstampTypePtr = mightLoad("pcap_set_tstamp_type")
    pcapGetTstampPrecisionPtr = mightLoad("pcap_get_tstamp_precision")
    pcapSetTstampPrecisionPtr = mightLoad("pcap_set_tstamp_precision")
    pcapOpenOfflineWithTstampPrecisionPtr = mightLoad("pcap_open_offline_with_tstamp_precision")
    pcapHOpenOfflineWithTstampPrecisionPtr = mightLoad("pcap_hopen_offline_with_tstamp_precision")
    pcapActivatePtr = mustLoad("pcap_activate")
    pcapCreatePtr = mustLoad("pcap_create")
    pcapSetSnaplenPtr = mustLoad("pcap_set_snaplen")
    pcapSetPromiscPtr = mustLoad("pcap_set_promisc")
    pcapSetTimeoutPtr = mustLoad("pcap_set_timeout")
    //winpcap does not support rfmon
    pcapCanSetRfmonPtr = mightLoad("pcap_can_set_rfmon")
    pcapSetRfmonPtr = mightLoad("pcap_set_rfmon")
    pcapSetBufferSizePtr = mustLoad("pcap_set_buffer_size")
    //libpcap <1.5 does not have pcap_set_immediate_mode
    pcapSetImmediateModePtr = mightLoad("pcap_set_immediate_mode")
    pcapHopenOfflinePtr = mustLoad("pcap_hopen_offline")
    
    pcapLoaded = true
    return nil
}

三、查看环境

通过阅读pcap的源码,知道需要有至少kernel32.dll、wpcap.dll、msvcrt.dll依赖库才可以工作。

在window10上搜索这几个dll依赖库,发现kernel32.dll、msvcrt.dll是存在的,而且不同的应用程序也有自己的dll,搜索出来比较多。
但是wpcap.dll没有找到。

接下来考虑安装wpcap.dll,由于开发环境中安装了Wireshark抓包软件,而通过安装预置条件软件Npcap把wpcap.dll安装解压。

了解到windows X下有两种选择,一种是比较推荐的Npcap,另一种是Npcap的前身WinPcap,对于window10也有单独的Win10Pcap。

对应的官网下载链接和使用手册如下
Npcap   https://nmap.org/npcap/       https://nmap.org/npcap/guide/
WinPcap https://www.winpcap.org/      https://www.winpcap.org/docs/default.htm
Win10Pcap http://www.win10pcap.org/     http://www.win10pcap.org/howto/

四、安装Npcap

Npcap本身是开源项目,后来由Nmap项目维护,笔者还发现有Npcap的OEM版本,支持更多的特性,比如静默安装等等。
https://nmap.org/npcap/

可以下载最新的安装版本,现在是Npcap 1.50 installer for Windows 7/2008R2, 8/2012, 8.1/2012R2, 10/2016, 2019 (x86 and x64)。几乎支持windowX。
如下是安装Npcap的过程。

安装完成后,我们发现C盘下多了目录C:\Program Files\Npcap,里面有一些批处理脚本和组件的安装包,然后C:\Windows\System32\Npcap目录也是新增的,有dll链接库文件。

五、运行demo程序

现在dll都是存在的,而且安装了NPF(网络数据包过滤器)。代码层面不做任何变动立即执行,发现有结果输出。
demo程序可以正常工作,问题解决。

六、获取网卡的各个源码对比

1、golang自身的net库

package main

import (
    "fmt"
    "net"
    "time"
)

func main() {
    ifcs, err := net.Interfaces()
    if err != nil {
        fmt.Println(err)
        return
    }

    for k, v := range ifcs {
        fmt.Printf("%d:%+v\n", k, v)
    }
    
    time.Sleep(time.Hour)
}


输出
0:{Index:4 MTU:1500 Name:本地连接* 1 HardwareAddr:5c:c5:d4:xx:xx:xx Flags:broadcast|multicast}
1:{Index:2 MTU:1500 Name:WLAN HardwareAddr:5c:c5:d4:xx:xx:xx Flags:up|broadcast|multicast}
2:{Index:1 MTU:-1 Name:Loopback Pseudo-Interface 1 HardwareAddr: Flags:up|loopback|multicast}
3:{Index:6 MTU:1280 Name:isatap.mshome.net HardwareAddr:00:00:00:00:00:00:00:e0 Flags:pointtopoint|multicast}
4:{Index:8 MTU:1280 Name:Teredo Tunneling Pseudo-Interface HardwareAddr:00:00:00:00:00:00:00:e0 Flags:up|pointtopoint|multicast}

2、google的pcap库

package main

import (
    "fmt"
    "time"

    "github.com/google/gopacket/pcap"
)

func main() {
    ifcs, err := pcap.FindAllDevs()
    if err != nil {
        fmt.Println(err)
        return
    }

    for k, v := range ifcs {
        fmt.Printf("%d:%+v\n", k, v)
    }
    
    time.Sleep(time.Hour)
}


输出
0:{Name:\Device\NPF_{060xxxxx-7683-xxxx-BB7F-xxxxxxxxxxxx} Description:Intel(R) Wireless-N 7260 Flags:30 Addresses:[{IP:fe80::e9ab:7a6e:32ce:6529 Netmask:ffffffffffffffff0000000000000000 Broadaddr:fe80::ffff:ffff:ffff:ffff P2P:<nil>} {IP:192.168.137.121 Netmask:00ffffff Broadaddr:255.168.137.121 P2P:<nil>}]}
1:{Name:\Device\NPF_{8BFxxxxx-F154-xxxx-8ADB-xxxxxxxxxxxx} Description:Microsoft Wi-Fi Direct Virtual Adapter Flags:46 Addresses:[{IP:fe80::413:2b2e:5d2f:887e Netmask:ffffffffffffffff0000000000000000 Broadaddr:fe80::ffff:ffff:ffff:ffff P2P:<nil>} {IP:169.254.136.126 Netmask:0000ffff Broadaddr:255.255.136.126 P2P:<nil>}]}
2:{Name:\Device\NPF_Loopback Description:Adapter for loopback traffic capture Flags:55 Addresses:[]}

3、windows扩展库

package main

import (
    "fmt"
    "time"

    "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
)

func main() {
    ifcs, err := winipcfg.GetAdaptersAddresses(0, 0x10)
    if err != nil {
        fmt.Println(err)
        return
    }

    for k, v := range ifcs {
        fmt.Printf("%d:%+v\n", k, v)
    }
    
    time.Sleep(time.Hour)
}


输出
0:&{Length:448 IfIndex:4 Next:0xc00016xxxx adapterName:0xc00016xxxx FirstUnicastAddress:0xc00016xxxx FirstAnycastAddress:<nil> FirstMulticastAddress:0xc00016xxxx FirstDNSServerAddress:0xc00016xxxx dnsSuffix:0xc00016xxxx description:0xc00016xxxx friendlyName:0xc00016xxxx physicalAddress:[92 197 0 0 0 0 0 0] physicalAddressLength:6 Flags:453 MTU:1500 IfType:71 OperStatus:2 IPv6IfIndex:4 ZoneIndices:[4 4 4 4 1 1 1 1 1 1 1 1 1 1 0 1] FirstPrefix:0xc00016xxxx TransmitLinkSpeed:18446744073709551615 ReceiveLinkSpeed:18446744073709551615 FirstWINSServerAddress:<nil> FirstGatewayAddress:<nil> Ipv4Metric:5 Ipv6Metric:5 LUID:19985000000000000 DHCPv4Server:{Sockaddr:<nil> SockaddrLength:0} CompartmentID:1 NetworkGUID:{6BBxxxxx-2706-xxxx-9BBE-806xxxxxxxxx} ConnectionType:1 TunnelType:0 DHCPv6Server:{Sockaddr:<nil> SockaddrLength:0} dhcpv6ClientDUID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] dhcpv6ClientDUIDLength:0 DHCPv6IAID:0 FirstDNSSuffix:<nil>}
1:&{Length:448 IfIndex:2 Next:0xc00016xxxx adapterName:0xc00016xxxx FirstUnicastAddress:0xc00016xxxx FirstAnycastAddress:<nil> FirstMulticastAddress:0xc00016xxxx FirstDNSServerAddress:0xc00016xxxx dnsSuffix:0xc00016xxxx description:0xc00016xxxx friendlyName:0xc00016xxxx physicalAddress:[92 197 0 0 0 0 0 0] physicalAddressLength:6 Flags:453 MTU:1500 IfType:71 OperStatus:1 IPv6IfIndex:2 ZoneIndices:[2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 1] FirstPrefix:0xc00016xxxx TransmitLinkSpeed:144400000 ReceiveLinkSpeed:144400000 FirstWINSServerAddress:<nil> FirstGatewayAddress:<nil> Ipv4Metric:25 Ipv6Metric:25 LUID:19985000000000000 DHCPv4Server:{Sockaddr:0xc0001xxxxx SockaddrLength:16} CompartmentID:1 NetworkGUID:{6BBxxxxx-2706-xxxx-9BBE-806xxxxxxxxx} ConnectionType:1 TunnelType:0 DHCPv6Server:{Sockaddr:<nil> SockaddrLength:0} dhcpv6ClientDUID:[0 1 0 1 40 92 58 221 92 197 212 132 171 227 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] dhcpv6ClientDUIDLength:14 DHCPv6IAID:39634388 FirstDNSSuffix:<nil>}
2:&{Length:448 IfIndex:1 Next:0xc00016xxxx adapterName:0xc00016xxxx FirstUnicastAddress:0xc00016xxxx FirstAnycastAddress:<nil> FirstMulticastAddress:0xc00016xxxx FirstDNSServerAddress:0xc00016xxxx dnsSuffix:0xc00016xxxx description:0xc00016xxxx friendlyName:0xc00016xxxx physicalAddress:[0 0 0 0 0 0 0 0] physicalAddressLength:0 Flags:385 MTU:4294967295 IfType:24 OperStatus:1 IPv6IfIndex:1 ZoneIndices:[1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1] FirstPrefix:0xc00016xxxx TransmitLinkSpeed:1073741824 ReceiveLinkSpeed:1073741824 FirstWINSServerAddress:<nil> FirstGatewayAddress:<nil> Ipv4Metric:50 Ipv6Metric:50 LUID:6755000000000000 DHCPv4Server:{Sockaddr:<nil> SockaddrLength:0} CompartmentID:1 NetworkGUID:{6BBxxxxx-2706-xxxx-9BBE-806xxxxxxxxx} ConnectionType:1 TunnelType:0 DHCPv6Server:{Sockaddr:<nil> SockaddrLength:0} dhcpv6ClientDUID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] dhcpv6ClientDUIDLength:0 DHCPv6IAID:0 FirstDNSSuffix:<nil>}
3:&{Length:448 IfIndex:6 Next:0xc00016xxxx adapterName:0xc00016xxxx FirstUnicastAddress:0xc00016xxxx FirstAnycastAddress:<nil> FirstMulticastAddress:0xc00016xxxx FirstDNSServerAddress:0xc00016xxxx dnsSuffix:0xc00016xxxx description:0xc00016xxxx friendlyName:0xc00016xxxx physicalAddress:[0 0 0 0 0 0 0 0] physicalAddressLength:8 Flags:273 MTU:1280 IfType:131 OperStatus:2 IPv6IfIndex:6 ZoneIndices:[6 6 6 6 1 1 1 1 1 1 1 1 1 1 0 1] FirstPrefix:0xc00016xxxx TransmitLinkSpeed:100000 ReceiveLinkSpeed:100000 FirstWINSServerAddress:<nil> FirstGatewayAddress:<nil> Ipv4Metric:0 Ipv6Metric:50 LUID:36873000000000000 DHCPv4Server:{Sockaddr:<nil> SockaddrLength:0} CompartmentID:1 NetworkGUID:{6BBxxxxx-2706-xxxx-9BBE-806xxxxxxxxx} ConnectionType:1 TunnelType:13 DHCPv6Server:{Sockaddr:<nil> SockaddrLength:0} dhcpv6ClientDUID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] dhcpv6ClientDUIDLength:0 DHCPv6IAID:0 FirstDNSSuffix:<nil>}
4:&{Length:448 IfIndex:8 Next:<nil> adapterName:0xc00016xxxx FirstUnicastAddress:0xc00016xxxx FirstAnycastAddress:<nil> FirstMulticastAddress:0xc00016xxxx FirstDNSServerAddress:<nil> dnsSuffix:0xc00016xxxx description:0xc00016xxxx friendlyName:0xc00016xxxx physicalAddress:[0 0 0 0 0 0 0 0] physicalAddressLength:8 Flags:272 MTU:1280 IfType:131 OperStatus:1 IPv6IfIndex:8 ZoneIndices:[8 8 8 8 1 1 1 1 1 1 1 1 1 1 0 1] FirstPrefix:0xc00016xxxx TransmitLinkSpeed:100000 ReceiveLinkSpeed:100000 FirstWINSServerAddress:<nil> FirstGatewayAddress:<nil> Ipv4Metric:0 Ipv6Metric:50 LUID:36873000000000000 DHCPv4Server:{Sockaddr:<nil> SockaddrLength:0} CompartmentID:1 NetworkGUID:{6BBxxxxx-2706-xxxx-9BBE-806xxxxxxxxx} ConnectionType:1 TunnelType:14 DHCPv6Server:{Sockaddr:<nil> SockaddrLength:0} dhcpv6ClientDUID:[0 1 0 1 40 92 58 221 92 197 212 132 171 227 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] dhcpv6ClientDUIDLength:14 DHCPv6IAID:268435456 FirstDNSSuffix:<nil>}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
### 回答1: 如果要用Go语言获取网卡的IP,可以使用net.InterfaceAddrs函数。下面是一个示例代码:ifaces, err := net.InterfaceAddrs() if err != nil { log.Fatal(err) } for _, a := range ifaces { fmt.Println(a) } ### 回答2: 使用Golang获取网卡IP和网关的代码示例如下: ```go package main import ( "fmt" "net" ) func main() { interfaces, err := net.Interfaces() if err != nil { fmt.Println("Failed to get network interfaces:", err) return } for _, iface := range interfaces { addrs, err := iface.Addrs() if err != nil { fmt.Println("Failed to get addresses for interface", iface.Name, ":", err) continue } for _, addr := range addrs { ipNet, ok := addr.(*net.IPNet) if !ok { continue } // Check if it's an IPv4 address if ipNet.IP.To4() != nil { fmt.Println("IPv4 address:", ipNet.IP) // Get the associated network interface's default gateway if defaultRoute, err := net.InterfaceByName(iface.Name); err == nil { routes, err := defaultRoute.Addrs() if err != nil { fmt.Println("Failed to get default gateway for interface", iface.Name, ":", err) continue } for _, route := range routes { gateway, ok := route.(*net.IPNet) if !ok { continue } if !gateway.IP.IsLoopback() && gateway.IP.To4() != nil { fmt.Println("Default gateway:", gateway.IP) } } } } } } } ``` 这段代码通过使用`net.Interfaces()`函数获取所有的网络接口,然后遍历每个接口的地址。对于IPv4地址,它会打印出来,并通过`net.InterfaceByName()`函数获取关联网络接口的默认网关。然后,它遍历这些网关,并打印出IPv4格式的默认网关地址。 希望这可以帮助你获取网卡的IP和网关。 ### 回答3: 要获取网卡的IP和网关,在Golang中可以使用`net`和`os/exec`包来实现。以下是一个代码示例: ```go package main import ( "fmt" "net" "os/exec" "strings" ) func main() { // 获取所有网卡信息 interfaces, err := net.Interfaces() if err != nil { fmt.Println("获取网卡信息失败:", err) return } // 遍历网卡信息 for _, iface := range interfaces { // 排除回环接口和无效接口 if iface.Flags&net.FlagLoopback != 0 || iface.Flags&net.FlagUp == 0 { continue } // 获取网卡的IP地址 addrs, err := iface.Addrs() if err != nil { fmt.Println("获取网卡IP失败:", err) return } // 遍历IP地址 for _, addr := range addrs { ipnet, ok := addr.(*net.IPNet) if ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil { fmt.Printf("网卡%d的IP地址:%s\n", iface.Index, ipnet.IP.String()) } } // 获取网卡的网关 output, err := exec.Command("netstat", "-nr").Output() if err != nil { fmt.Println("执行netstat命令失败:", err) return } // 解析输出结果 lines := strings.Split(string(output), "\n") for _, line := range lines { fields := strings.Fields(line) if len(fields) > 1 && fields[0] == "0.0.0.0" { fmt.Printf("网卡%d的网关:%s\n", iface.Index, fields[1]) break } } } } ``` 这个代码会遍历所有的网卡获取每个网卡的IP地址,并使用`netstat`命令来获取网卡的网关。最后打印出每个网卡的IP地址和网关。请注意,在Windows系统和Linux系统中,`netstat`命令的输出格式可能不同,需要根据实际情况修改解析代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byzf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值