Files
tun2socks/common/lsof/lsof_windows.go
2019-08-13 12:05:00 +08:00

116 lines
2.7 KiB
Go

// +build windows
package lsof
import (
"fmt"
"syscall"
"unsafe"
win "github.com/xjasonlyu/tun2socks/common/lsof/windows"
)
func GetCommandNameBySocket(network string, addr string, port uint16) (string, error) {
switch network {
case "tcp":
tcpTable, err := getTcpTable()
if err != nil {
return "", fmt.Errorf("failed to get TCP table: %v", err)
}
for i := 0; i < int(tcpTable.NumEntries); i++ {
row := tcpTable.Table[i]
if win.NTOHS(uint16(row.LocalPort)) == port /* && win.IPAddrNTOA(uint32(row.LocalAddr)) == addr */ {
return getNameByPid(uint32(row.OwningPid))
}
}
return "", ErrNotFound
case "udp":
var udpTable win.MIB_UDPTABLE_OWNER_PID
err := getUdpTable(
uintptr(unsafe.Pointer(&udpTable)),
win.AF_INET,
)
if err != nil {
return "", fmt.Errorf("failed to get UDP table: %v", err)
}
for i := 0; i < int(udpTable.NumEntries); i++ {
row := udpTable.Table[i]
if win.NTOHS(uint16(row.LocalPort)) == port /* && win.IPAddrNTOA(uint32(row.LocalAddr)) == addr */ {
return getNameByPid(uint32(row.OwningPid))
}
}
// var udp6Table win.MIB_UDP6TABLE_OWNER_PID
// err = getUdpTable(
// uintptr(unsafe.Pointer(&udp6Table)),
// win.AF_INET6,
// )
// if err != nil {
// return "", fmt.Errorf("failed to get UDP table: %v", err)
// }
// for i := 0; i < int(udp6Table.NumEntries); i++ {
// row := udp6Table.Table[i]
// if win.NTOHS(uint16(row.LocalPort)) == port /* && win.IPAddrNTOA(uint32(row.LocalAddr)) == addr */ {
// return getNameByPid(uint32(row.OwningPid))
// }
// }
return "", ErrNotFound
default:
return "", ErrNotFound
}
}
func getNameByPid(pid uint32) (string, error) {
handle := win.CreateToolhelp32Snapshot(
win.TH32CS_SNAPMODULE,
pid,
)
if handle <= 0 {
return "", fmt.Errorf("failed to create snapshot: %v", handle)
}
defer win.CloseHandle(handle)
var me win.MODULEENTRY32
me.Size = uint32(unsafe.Sizeof(me))
success := win.Module32First(handle, &me)
if success {
return win.UTF16PtrToString(&me.Module[0]), nil
} else {
return "", fmt.Errorf("failed to get process entry: %v", syscall.GetLastError())
}
}
func getTcpTable() (win.MIB_TCPTABLE_OWNER_PID, error) {
var tcpTable win.MIB_TCPTABLE_OWNER_PID
var size uint32 = 64 * 1024
var order int32 = 0
ret := win.GetExtendedTcpTable(
uintptr(unsafe.Pointer(&tcpTable)),
&size,
order,
win.AF_INET,
win.TCP_TABLE_OWNER_PID_ALL,
)
if ret != 0 {
return tcpTable, fmt.Errorf("ret: %d", int(ret))
}
return tcpTable, nil
}
func getUdpTable(table uintptr, af uint32) error {
var size uint32 = 64 * 1024
var order int32 = 0
ret := win.GetExtendedUdpTable(
table,
&size,
order,
af,
win.UDP_TABLE_OWNER_PID,
)
if ret != 0 {
return fmt.Errorf("ret: %d", int(ret))
}
return nil
}