mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 13:18:53 +00:00
netstat, portlist: update Windows implementation to disambiguate svchost processes
We change our invocations of GetExtendedTcpTable to request additional information about the "module" responsible for the port. In addition to pid, this output also includes sufficient metadata to enable Windows to resolve process names and disambiguate svchost processes. We store the OS-specific output in an OSMetadata field in netstat.Entry, which portlist may then use as necessary to actually resolve the process/module name. Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This commit is contained in:
@@ -5,12 +5,8 @@
|
||||
package portlist
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"tailscale.com/net/netstat"
|
||||
)
|
||||
|
||||
@@ -26,7 +22,7 @@ func init() {
|
||||
type famPort struct {
|
||||
proto string
|
||||
port uint16
|
||||
pid uintptr
|
||||
pid uint32
|
||||
}
|
||||
|
||||
type windowsImpl struct {
|
||||
@@ -69,19 +65,25 @@ func (im *windowsImpl) AppendListeningPorts(base []Port) ([]Port, error) {
|
||||
fp := famPort{
|
||||
proto: "tcp", // TODO(bradfitz): UDP too; add to netstat
|
||||
port: e.Local.Port(),
|
||||
pid: uintptr(e.Pid),
|
||||
pid: uint32(e.Pid),
|
||||
}
|
||||
pm, ok := im.known[fp]
|
||||
if ok {
|
||||
pm.keep = true
|
||||
continue
|
||||
}
|
||||
var process string
|
||||
if e.OSMetadata != nil {
|
||||
if module, err := e.OSMetadata.GetModule(); err == nil {
|
||||
process = module
|
||||
}
|
||||
}
|
||||
pm = &portMeta{
|
||||
keep: true,
|
||||
port: Port{
|
||||
Proto: "tcp",
|
||||
Port: e.Local.Port(),
|
||||
Process: procNameOfPid(e.Pid),
|
||||
Process: process,
|
||||
},
|
||||
}
|
||||
im.known[fp] = pm
|
||||
@@ -94,27 +96,6 @@ func (im *windowsImpl) AppendListeningPorts(base []Port) ([]Port, error) {
|
||||
}
|
||||
ret = append(ret, m.port)
|
||||
}
|
||||
|
||||
return sortAndDedup(ret), nil
|
||||
}
|
||||
|
||||
func procNameOfPid(pid int) string {
|
||||
const da = windows.PROCESS_QUERY_LIMITED_INFORMATION
|
||||
h, err := syscall.OpenProcess(da, false, uint32(pid))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer syscall.CloseHandle(h)
|
||||
|
||||
var buf [512]uint16
|
||||
var size = uint32(len(buf))
|
||||
if err := windows.QueryFullProcessImageName(windows.Handle(h), 0, &buf[0], &size); err != nil {
|
||||
return ""
|
||||
}
|
||||
name := filepath.Base(windows.UTF16ToString(buf[:]))
|
||||
if name == "." {
|
||||
return ""
|
||||
}
|
||||
name = strings.TrimSuffix(name, ".exe")
|
||||
name = strings.TrimSuffix(name, ".EXE")
|
||||
return name
|
||||
}
|
||||
|
Reference in New Issue
Block a user