第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > go 调用winapi_Go调用Window SendARP() 方法

go 调用winapi_Go调用Window SendARP() 方法

时间:2019-01-22 16:14:05

相关推荐

go 调用winapi_Go调用Window SendARP() 方法

首先用了walk里面的一个winapi.go

// Copyright The go-winapi Authors. All rights reserved.

// Use of this source code is governed by a BSD-style

// license that can be found in the LICENSE file.

package winapi

import (

"runtime"

"syscall"

"unsafe"

)

func init() {

runtime.LockOSThread()

}

const (

S_OK = 0x00000000

S_FALSE = 0x00000001

E_UNEXPECTED = 0x8000FFFF

E_NOTIMPL = 0x80004001

E_OUTOFMEMORY = 0x8007000E

E_INVALIDARG = 0x80070057

E_NOINTERFACE = 0x80004002

E_POINTER = 0x80004003

E_HANDLE = 0x80070006

E_ABORT = 0x80004004

E_FAIL = 0x80004005

E_ACCESSDENIED = 0x80070005

E_PENDING = 0x8000000A

)

const (

FALSE = 0

TRUE = 1

)

type (

BOOL int32

HRESULT int32

)

type GUID struct {

Data1 uint32

Data2 uint16

Data3 uint16

Data4 [8]byte

}

func MustLoadLibrary(name string) uintptr {

lib, err := syscall.LoadLibrary(name)

if err != nil {

panic(err)

}

return uintptr(lib)

}

func MustGetProcAddress(lib uintptr, name string) uintptr {

addr, err := syscall.GetProcAddress(syscall.Handle(lib), name)

if err != nil {

panic(err)

}

return uintptr(addr)

}

func SUCCEEDED(hr HRESULT) bool {

return hr >= 0

}

func FAILED(hr HRESULT) bool {

return hr < 0

}

func MAKELONG(lo, hi uint16) uint32 {

return uint32(uint32(lo) | ((uint32(hi)) << 16))

}

func LOWORD(dw uint32) uint16 {

return uint16(dw)

}

func HIWORD(dw uint32) uint16 {

return uint16(dw >> 16 & 0xffff)

}

func UTF16PtrToString(s *uint16) string {

return syscall.UTF16ToString((*[1 << 29]uint16)(unsafe.Pointer(s))[0:])

}

func MAKEINTRESOURCE(id uintptr) *uint16 {

return (*uint16)(unsafe.Pointer(id))

}

func BoolToBOOL(value bool) BOOL {

if value {

return 1

}

return 0

}

具体的SendARP实现

package winapi

import (

"syscall"

"unsafe"

)

var (

// Library

libIphlpapi uintptr

libWs2_32 uintptr

// Functions

sendARP uintptr

inet_addr uintptr

)

func init() {

// library

libIphlpapi = MustLoadLibrary("Iphlpapi.dll")

libWs2_32 = MustLoadLibrary("Ws2_32.dll")

// Functions

/** SendARP(DestIp IPAddr, SrcIp IPAddr, &MacAddr, &PhysAddrLen ULONG) **/

sendARP = MustGetProcAddress(libIphlpapi, "SendARP")

inet_addr = MustGetProcAddress(libWs2_32, "inet_addr")

}

/**

* macAddr是目标的MAC地址

*/

func SendARP(destIP, srcIP int32, macAddr *int64, physAddrLen *int) int {

ret, _, _ := syscall.Syscall6(sendARP, 4,

uintptr(destIP),

uintptr(srcIP),

uintptr(unsafe.Pointer(macAddr)),

uintptr(unsafe.Pointer(physAddrLen)),

0,

0)

return int(ret)

}

func Inet_addr(ipaddr string) (result int32) {

ret, _, _ := syscall.Syscall(inet_addr, 1, // 1表示有一个参数

uintptr(unsafe.Pointer(syscall.StringBytePtr(ipaddr))),

0,

0)

return int32(ret)

}

调用

package main

import (

"lqz/system/winapi"

// "strconv"

// "strings"

// "os"

"log"

"fmt"

)

func main() {

for i := 1; i <= 100; i++ {

getMac(fmt.Sprintf("192.168.2.%d", i))

}

}

func getMac(ip string) {

var macLen int = 6

var mac int64 = 0

destIP := winapi.Inet_addr(ip)

result := winapi.SendARP(destIP, 0, &mac, &macLen)

if result == 0 {

log.Print(ip)

pyMac := fmt.Sprintf("%012X", mac)

x := 2 * macLen

var tempMac string

for i := 0; i < macLen; i++ {

if i == (macLen - 1) {

tempMac = tempMac + pyMac[x-2:x]

} else {

tempMac = tempMac + pyMac[x-2:x] + "-"

}

x -= 2

}

log.Println(tempMac)

}

}

感觉还有点缺陷,比如说那个0, 应该在上面定义好的,但是我不知道这个面的值,都表示什么意思,只知道0是NOERROR,还有其他信息,但是我看MSDN上面的SendARP里面没有给出值,这个以后补上

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。