dougou8458
2017-04-16 07:17
浏览 68
已采纳

通过在Go中调用Windows DLL发送ARP请求不起作用

I'm trying to call a Windows API SendARP from Go to send arp request on Windows, but it always returns 1168, AKA ERROR_NOT_FOUND, description by MSDN on this error code:

Element not found. This error is returned on Windows Vista if the the SrcIp parameter does not specify a source IPv4 address on an interface on the local computer or the INADDR_ANY IP address (an IPv4 address of 0.0.0.0).

but I'm on Windows 7, moreover I do specify a right source IPv4 address. And I see no ARP packet sent in Wireshark. So where is the problem?

package main

import (
    "fmt"
    "syscall"
    "net"
    "unsafe"
)

var (
    iphlp, _   = syscall.LoadLibrary("iphlpapi.dll")
    SendARP, _ = syscall.GetProcAddress(iphlp, "SendARP")
)

func sendARP(src, dst net.IP) {
    //var nargs uintptr = 4
    var len uint = 6
    mac := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
    ret, _, callErr := syscall.Syscall6(
    uintptr(SendARP), 4,
    uintptr(unsafe.Pointer(&dst[0])),
    uintptr(unsafe.Pointer(&src[0])),
    uintptr(unsafe.Pointer(&mac[0])),
    uintptr(unsafe.Pointer(&len)),
    0,
    0)

    if callErr == 0 {
        fmt.Printf("result %v
", int(ret))
    }
}

func main() {
    defer syscall.FreeLibrary(iphlp)

    fmt.Printf("addr: %v
", sendARP)

    dst := net.IPv4(192,168,1,1)
    src := net.IPv4(192,168,1,103)
    sendARP(src, dst)   
}
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • drwdvftp423507 2017-04-17 04:57
    已采纳

    Please, try this

    package main
    
    import (
        "fmt"
        "log"
        "net"
        "syscall"
        "unsafe"
    )
    
    var SendARP = syscall.MustLoadDLL("iphlpapi.dll").MustFindProc("SendARP")
    
    func ip4ToUint32(ip net.IP) (uint32, error) {
        ip = ip.To4()
        if ip == nil {
            return 0, fmt.Errorf("ip address %v is not ip4", ip)
        }
        var ret uint32
        for i := 4; i > 0; i-- {
            ret <<= 8
            ret += uint32(ip[i-1])
        }
        return ret, nil
    }
    
    func sendARP(ip net.IP) (net.HardwareAddr, error) {
        dst, err := ip4ToUint32(ip)
        if err != nil {
            return nil, err
        }
        mac := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
        n := uint32(len(mac))
        ret, _, _ := SendARP.Call(
            uintptr(dst),
            0,
            uintptr(unsafe.Pointer(&mac[0])),
            uintptr(unsafe.Pointer(&n)))
        if ret != 0 {
            return nil, syscall.Errno(ret)
        }
        return mac, nil
    }
    func main() {
        ip := net.IPv4(192, 168, 1, 1)
        mac, err := sendARP(ip)
        if err != nil {
            log.Fatalf("could not find MAC for %q: %v", ip, err)
        }
        fmt.Printf("MAC address for %v is %v
    ", ip, mac)
    }
    

    it works for me.

    Alex

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题