bug fix & netconn add
parent
fd5cf2c1f6
commit
d981a03b14
@ -0,0 +1,21 @@
|
||||
//+build darwin
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||
}
|
||||
|
||||
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctimespec)
|
||||
}
|
||||
|
||||
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atimespec)
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
// +build windows
|
||||
|
||||
package staros
|
||||
|
||||
import "b612.me/win32api"
|
||||
|
||||
// Memory 系统内存信息
|
||||
func Memory() (MemStatus, error) {
|
||||
var mem MemStatus
|
||||
ram := new(win32api.MEMORYSTATUSEX)
|
||||
_, err := win32api.GlobalMemoryStatusEx(ram)
|
||||
if err != nil {
|
||||
return mem, err
|
||||
}
|
||||
mem.All = uint64(ram.UllTotalPhys)
|
||||
mem.Free = uint64(ram.UllAvailPhys)
|
||||
mem.Available = uint64(ram.UllAvailPhys)
|
||||
mem.Used = uint64(mem.All - mem.Free)
|
||||
mem.SwapAll = uint64(ram.UllTotalPageFile)
|
||||
mem.SwapFree = uint64(ram.UllAvailPageFile)
|
||||
mem.SwapUsed = mem.SwapAll - mem.SwapFree
|
||||
mem.VirtualAll = uint64(mem.VirtualAll)
|
||||
mem.VirtualAvail = uint64(mem.VirtualAvail)
|
||||
mem.VirtualUsed = mem.VirtualAll - mem.VirtualUsed
|
||||
return mem, nil
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NetUsage() ([]NetAdapter, error) {
|
||||
data, err := ioutil.ReadFile("/proc/net/dev")
|
||||
if err != nil {
|
||||
return []NetAdapter{}, err
|
||||
}
|
||||
sps := strings.Split(strings.TrimSpace(string(data)), "\n")
|
||||
if len(sps) < 3 {
|
||||
return []NetAdapter{}, errors.New("No Adaptor")
|
||||
}
|
||||
var res []NetAdapter
|
||||
netLists := sps[2:]
|
||||
for _, v := range netLists {
|
||||
v = strings.ReplaceAll(v, " ", " ")
|
||||
for strings.Contains(v, " ") {
|
||||
v = strings.ReplaceAll(v, " ", " ")
|
||||
}
|
||||
v = strings.TrimSpace(v)
|
||||
card := strings.Split(v, " ")
|
||||
name := strings.ReplaceAll(card[0], ":", "")
|
||||
recvBytes, _ := strconv.Atoi(card[1])
|
||||
sendBytes, _ := strconv.Atoi(card[9])
|
||||
res = append(res, NetAdapter{name, uint64(recvBytes), uint64(sendBytes)})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func NetUsageByname(name string) (NetAdapter, error) {
|
||||
ada, err := NetUsage()
|
||||
if err != nil {
|
||||
return NetAdapter{}, err
|
||||
}
|
||||
for _, v := range ada {
|
||||
if v.Name == name {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return NetAdapter{}, errors.New("Not Found")
|
||||
}
|
||||
|
||||
func NetSpeeds(duration time.Duration) ([]NetSpeed, error) {
|
||||
list1, err := NetUsage()
|
||||
if err != nil {
|
||||
return []NetSpeed{}, err
|
||||
}
|
||||
time.Sleep(duration)
|
||||
list2, err := NetUsage()
|
||||
if err != nil {
|
||||
return []NetSpeed{}, err
|
||||
}
|
||||
if len(list1) > len(list2) {
|
||||
return []NetSpeed{}, errors.New("NetWork Adaptor Num Not ok")
|
||||
}
|
||||
var res []NetSpeed
|
||||
for k, v := range list1 {
|
||||
recv := float64(list2[k].RecvBytes-v.RecvBytes) / duration.Seconds()
|
||||
send := float64(list2[k].SendBytes-v.SendBytes) / duration.Seconds()
|
||||
res = append(res, NetSpeed{v.Name, recv, send})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
|
||||
ada, err := NetSpeeds(duration)
|
||||
if err != nil {
|
||||
return NetSpeed{}, err
|
||||
}
|
||||
for _, v := range ada {
|
||||
if v.Name == name {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return NetSpeed{}, errors.New("Not Found")
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package staros
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_TrimSpace(t *testing.T) {
|
||||
|
||||
}
|
@ -0,0 +1,248 @@
|
||||
// +build !windows
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NetUsage() ([]NetAdapter, error) {
|
||||
data, err := ioutil.ReadFile("/proc/net/dev")
|
||||
if err != nil {
|
||||
return []NetAdapter{}, err
|
||||
}
|
||||
sps := strings.Split(strings.TrimSpace(string(data)), "\n")
|
||||
if len(sps) < 3 {
|
||||
return []NetAdapter{}, errors.New("No Adaptor")
|
||||
}
|
||||
var res []NetAdapter
|
||||
netLists := sps[2:]
|
||||
for _, v := range netLists {
|
||||
v = strings.ReplaceAll(v, " ", " ")
|
||||
for strings.Contains(v, " ") {
|
||||
v = strings.ReplaceAll(v, " ", " ")
|
||||
}
|
||||
v = strings.TrimSpace(v)
|
||||
card := strings.Split(v, " ")
|
||||
name := strings.ReplaceAll(card[0], ":", "")
|
||||
recvBytes, _ := strconv.Atoi(card[1])
|
||||
sendBytes, _ := strconv.Atoi(card[9])
|
||||
res = append(res, NetAdapter{name, uint64(recvBytes), uint64(sendBytes)})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func NetUsageByname(name string) (NetAdapter, error) {
|
||||
ada, err := NetUsage()
|
||||
if err != nil {
|
||||
return NetAdapter{}, err
|
||||
}
|
||||
for _, v := range ada {
|
||||
if v.Name == name {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return NetAdapter{}, errors.New("Not Found")
|
||||
}
|
||||
|
||||
func NetSpeeds(duration time.Duration) ([]NetSpeed, error) {
|
||||
list1, err := NetUsage()
|
||||
if err != nil {
|
||||
return []NetSpeed{}, err
|
||||
}
|
||||
time.Sleep(duration)
|
||||
list2, err := NetUsage()
|
||||
if err != nil {
|
||||
return []NetSpeed{}, err
|
||||
}
|
||||
if len(list1) > len(list2) {
|
||||
return []NetSpeed{}, errors.New("NetWork Adaptor Num Not ok")
|
||||
}
|
||||
var res []NetSpeed
|
||||
for k, v := range list1 {
|
||||
recv := float64(list2[k].RecvBytes-v.RecvBytes) / duration.Seconds()
|
||||
send := float64(list2[k].SendBytes-v.SendBytes) / duration.Seconds()
|
||||
res = append(res, NetSpeed{v.Name, recv, send})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
|
||||
ada, err := NetSpeeds(duration)
|
||||
if err != nil {
|
||||
return NetSpeed{}, err
|
||||
}
|
||||
for _, v := range ada {
|
||||
if v.Name == name {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return NetSpeed{}, errors.New("Not Found")
|
||||
}
|
||||
|
||||
// NetConnections return all TCP/UDP/UNIX DOMAIN SOCKET Connections
|
||||
// if your uid != 0 ,and analysePid==true ,you should have CAP_SYS_PRTACE and CAP_DAC_OVERRIDE/CAP_DAC_READ_SEARCH Caps
|
||||
func NetConnections(analysePid bool) ([]NetConn, error) {
|
||||
var result []NetConn
|
||||
var inodeMap map[string]int64
|
||||
var err error
|
||||
fileList := []string{
|
||||
"/proc/net/tcp",
|
||||
"/proc/net/tcp6",
|
||||
"/proc/net/udp",
|
||||
"/proc/net/udp6",
|
||||
"/proc/net/unix",
|
||||
}
|
||||
if analysePid {
|
||||
inodeMap, err = GetInodeMap()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
for _, file := range fileList {
|
||||
data, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
tmpRes, err := analyseNetFiles(data, inodeMap, file[strings.LastIndex(file, "/")+1:])
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result = append(result, tmpRes...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func GetInodeMap() (map[string]int64, error) {
|
||||
res := make(map[string]int64)
|
||||
paths, err := ioutil.ReadDir("/proc")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range paths {
|
||||
if v.IsDir() && Exists("/proc/"+v.Name()+"/fd") {
|
||||
fds, err := ioutil.ReadDir("/proc/" + v.Name() + "/fd")
|
||||
if err != nil && Exists("/proc/"+v.Name()+"/fd") {
|
||||
return nil, err
|
||||
}
|
||||
for _, fd := range fds {
|
||||
socket, err := os.Readlink("/proc/" + v.Name() + "/fd/" + fd.Name())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
start := strings.Index(socket, "[")
|
||||
if start < 0 {
|
||||
continue
|
||||
}
|
||||
pid, err := strconv.ParseInt(v.Name(), 10, 64)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
res[socket[start+1:len(socket)-1]] = pid
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func analyseNetFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) {
|
||||
if typed == "unix" {
|
||||
return analyseUnixFiles(data, inodeMap, typed)
|
||||
}
|
||||
var result []NetConn
|
||||
strdata := strings.TrimSpace(string(data))
|
||||
strdata = remainOne(strdata, " ", " ")
|
||||
csvData := strings.Split(strdata, "\n")
|
||||
pidMap := make(map[int64]*Process)
|
||||
for line, lineData := range csvData {
|
||||
if line == 0 {
|
||||
continue
|
||||
}
|
||||
v := strings.Split(strings.TrimSpace(lineData), " ")
|
||||
var res NetConn
|
||||
ip, port, err := parseHexIpPort(v[1])
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
res.LocalAddr = ip
|
||||
res.LocalPort = port
|
||||
ip, port, err = parseHexIpPort(v[2])
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
res.RemoteAddr = ip
|
||||
res.RemotePort = port
|
||||
res.Uid, err = strconv.ParseInt(v[7], 10, 64)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
res.Inode = v[9]
|
||||
if inodeMap != nil && len(inodeMap) > 0 {
|
||||
var ok bool
|
||||
res.Pid, ok = inodeMap[res.Inode]
|
||||
if !ok {
|
||||
res.Pid = -1
|
||||
} else {
|
||||
_, ok := pidMap[res.Pid]
|
||||
if !ok {
|
||||
tmp, err := FindProcessByPid(res.Pid)
|
||||
if err != nil {
|
||||
pidMap[res.Pid] = nil
|
||||
} else {
|
||||
pidMap[res.Pid] = &tmp
|
||||
}
|
||||
}
|
||||
res.Process = pidMap[res.Pid]
|
||||
}
|
||||
}
|
||||
res.Typed = typed
|
||||
result = append(result, res)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func analyseUnixFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) {
|
||||
var result []NetConn
|
||||
strdata := strings.TrimSpace(string(data))
|
||||
strdata = remainOne(strdata, " ", " ")
|
||||
csvData := strings.Split(strdata, "\n")
|
||||
pidMap := make(map[int64]*Process)
|
||||
for line, lineData := range csvData {
|
||||
if line == 0 {
|
||||
continue
|
||||
}
|
||||
v := strings.Split(strings.TrimSpace(lineData), " ")
|
||||
var res NetConn
|
||||
res.Inode = v[6]
|
||||
if len(v) == 8 {
|
||||
res.Socket = v[7]
|
||||
}
|
||||
if inodeMap != nil && len(inodeMap) > 0 {
|
||||
var ok bool
|
||||
res.Pid, ok = inodeMap[res.Inode]
|
||||
if !ok {
|
||||
res.Pid = -1
|
||||
} else {
|
||||
_, ok := pidMap[res.Pid]
|
||||
if !ok {
|
||||
tmp, err := FindProcessByPid(res.Pid)
|
||||
if err != nil {
|
||||
pidMap[res.Pid] = nil
|
||||
} else {
|
||||
pidMap[res.Pid] = &tmp
|
||||
}
|
||||
}
|
||||
res.Uid = int64(pidMap[res.Pid].RUID)
|
||||
res.Process = pidMap[res.Pid]
|
||||
}
|
||||
}
|
||||
res.Typed = typed
|
||||
result = append(result, res)
|
||||
}
|
||||
return result, nil
|
||||
}
|
Loading…
Reference in New Issue