From 7de2f6b8c7c24031ac5258b9bf5ad7ffdd13865f Mon Sep 17 00:00:00 2001 From: Diretnan Domnan Date: Fri, 25 Mar 2022 00:34:46 +0100 Subject: [PATCH 1/3] Darwin: Adding tcp inspector for Darwin --- inspector/inspector.go | 1 + inspector/tcp.go | 89 ++++++++++++++++++++++++++++ integration/integration_unix_test.go | 13 ++++ 3 files changed, 103 insertions(+) diff --git a/inspector/inspector.go b/inspector/inspector.go index c393853..3a7ad0a 100644 --- a/inspector/inspector.go +++ b/inspector/inspector.go @@ -26,6 +26,7 @@ var inspectorMap = map[string]NewInspector{ `process`: NewProcess, `custom`: NewCustom, `loadavg`: NewLoadAvg, + `tcp`: NewTcp, } // Init : initializes the specified inspector using name and driver diff --git a/inspector/tcp.go b/inspector/tcp.go index ffd41f2..8107078 100644 --- a/inspector/tcp.go +++ b/inspector/tcp.go @@ -1,2 +1,91 @@ // Check if TCP ports are open or not package inspector + +import ( + "errors" + "strconv" + "strings" + + "github.com/bisohns/saido/driver" + log "github.com/sirupsen/logrus" +) + +// TcpMetricsDarwin : Metrics obtained by tcp monitoring on darwin +type TcpMetricsDarwin struct { + // Ports map a port to a status string + // e.g {8081: "LISTEN"} + Ports map[int]string +} + +type TcpDarwin struct { + Command string + Driver *driver.Driver + Values TcpMetricsDarwin +} + +/* Parse : parsing the following kind of output +Active Internet connections (including servers) +Proto Recv-Q Send-Q Local Address Foreign Address (state) +tcp4 0 0 127.0.0.1.53300 127.0.0.1.59972 ESTABLISHED +tcp4 0 0 192.168.1.172.59964 162.247.243.147.443 SYN_SENT +tcp4 0 0 192.168.1.172.59931 13.224.227.146.443 ESTABLISHED +tcp4 0 0 127.0.0.1.59905 127.0.0.1.53300 CLOSE_WAIT +*/ +func (i *TcpDarwin) Parse(output string) { + ports := make(map[int]string) + lines := strings.Split(output, "\n") + for index, line := range lines { + // skip title lines + if index == 0 || index == 1 { + continue + } + columns := strings.Fields(line) + if len(columns) > 5 { + status := columns[5] + address := strings.Split(columns[3], ".") + portString := address[len(address)-1] + port, err := strconv.Atoi(portString) + if err != nil { + log.Fatal("Could not parse port number in TcpDarwin") + } + ports[port] = status + + } + } + i.Values.Ports = ports +} + +func (i *TcpDarwin) SetDriver(driver *driver.Driver) { + details := (*driver).GetDetails() + if !details.IsDarwin { + panic("Cannot use TcpDarwin on drivers outside (darwin)") + } + i.Driver = driver +} + +func (i TcpDarwin) driverExec() driver.Command { + return (*i.Driver).RunCommand +} + +func (i *TcpDarwin) Execute() { + output, err := i.driverExec()(i.Command) + if err == nil { + i.Parse(output) + } +} + +// NewTcp: Initialize a new Tcp instance +func NewTcp(driver *driver.Driver, _ ...string) (Inspector, error) { + var tcp Inspector + details := (*driver).GetDetails() + if !(details.IsLinux || details.IsDarwin || details.IsWindows) { + return nil, errors.New("Cannot use Tcp on drivers outside (linux, darwin, windows)") + } + if details.IsDarwin { + tcp = &TcpDarwin{ + Command: `netstat -anp tcp`, + } + } + tcp.SetDriver(driver) + return tcp, nil +} diff --git a/integration/integration_unix_test.go b/integration/integration_unix_test.go index 7d6a5ac..d7c3fd8 100644 --- a/integration/integration_unix_test.go +++ b/integration/integration_unix_test.go @@ -157,3 +157,16 @@ func TestUptimeonLocal(t *testing.T) { fmt.Printf("%#v", iConcreteDarwin.Values) } } + +func TestTcponLocal(t *testing.T) { + d := NewLocalForTest() + i, _ := inspector.Init(`tcp`, &d) + i.Execute() + iConcreteDarwin, ok := i.(*inspector.TcpDarwin) + if ok { + if len(iConcreteDarwin.Values.Ports) == 0 { + t.Errorf("%#v", iConcreteDarwin.Values.Ports) + } + fmt.Printf("%#v", iConcreteDarwin.Values.Ports) + } +} From 9e06cd76e4b9077e62a5b05b8925dd7690fb30f0 Mon Sep 17 00:00:00 2001 From: Diretnan Domnan Date: Fri, 25 Mar 2022 10:39:25 +0100 Subject: [PATCH 2/3] Linux: Adding tcp inspector using 'ss' --- inspector/tcp.go | 71 ++++++++++++++++++++++++++-- integration/integration_unix_test.go | 7 +++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/inspector/tcp.go b/inspector/tcp.go index 8107078..5de57b9 100644 --- a/inspector/tcp.go +++ b/inspector/tcp.go @@ -3,6 +3,7 @@ package inspector import ( "errors" + "fmt" "strconv" "strings" @@ -10,8 +11,8 @@ import ( log "github.com/sirupsen/logrus" ) -// TcpMetricsDarwin : Metrics obtained by tcp monitoring on darwin -type TcpMetricsDarwin struct { +// TcpMetrics : Metrics obtained by tcp monitoring on darwin +type TcpMetrics struct { // Ports map a port to a status string // e.g {8081: "LISTEN"} Ports map[int]string @@ -20,7 +21,13 @@ type TcpMetricsDarwin struct { type TcpDarwin struct { Command string Driver *driver.Driver - Values TcpMetricsDarwin + Values TcpMetrics +} + +type TcpLinux struct { + Command string + Driver *driver.Driver + Values TcpMetrics } /* Parse : parsing the following kind of output @@ -74,6 +81,60 @@ func (i *TcpDarwin) Execute() { } } +/* +Parse for output +State Recv-Q Send-Q Local Address:Port Peer Address:Port Process +LISTEN 0 5 127.0.0.1:45481 0.0.0.0:* +LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* +LISTEN 0 5 127.0.0.1:631 0.0.0.0:* +ESTAB 0 0 192.168.1.106:37986 198.252.206.25:443 +CLOSE-WAIT 1 0 127.0.0.1:54638 127.0.0.1:45481 + +*/ +func (i *TcpLinux) Parse(output string) { + ports := make(map[int]string) + lines := strings.Split(output, "\n") + for index, line := range lines { + // skip title lines + if index == 0 { + continue + } + columns := strings.Fields(line) + if len(columns) >= 5 { + fmt.Print(columns) + status := columns[0] + address := strings.Split(columns[3], ":") + portString := address[len(address)-1] + port, err := strconv.Atoi(portString) + if err != nil { + log.Fatal("Could not parse port number in TcpLinux") + } + ports[port] = status + + } + } + i.Values.Ports = ports +} + +func (i *TcpLinux) SetDriver(driver *driver.Driver) { + details := (*driver).GetDetails() + if !details.IsLinux { + panic("Cannot use TcpLinux on drivers outside (linux)") + } + i.Driver = driver +} + +func (i TcpLinux) driverExec() driver.Command { + return (*i.Driver).RunCommand +} + +func (i *TcpLinux) Execute() { + output, err := i.driverExec()(i.Command) + if err == nil { + i.Parse(output) + } +} + // NewTcp: Initialize a new Tcp instance func NewTcp(driver *driver.Driver, _ ...string) (Inspector, error) { var tcp Inspector @@ -85,6 +146,10 @@ func NewTcp(driver *driver.Driver, _ ...string) (Inspector, error) { tcp = &TcpDarwin{ Command: `netstat -anp tcp`, } + } else if details.IsLinux { + tcp = &TcpLinux{ + Command: `ss -tan`, + } } tcp.SetDriver(driver) return tcp, nil diff --git a/integration/integration_unix_test.go b/integration/integration_unix_test.go index d7c3fd8..c30bb09 100644 --- a/integration/integration_unix_test.go +++ b/integration/integration_unix_test.go @@ -169,4 +169,11 @@ func TestTcponLocal(t *testing.T) { } fmt.Printf("%#v", iConcreteDarwin.Values.Ports) } + iConcreteLinux, ok := i.(*inspector.TcpLinux) + if ok { + if len(iConcreteLinux.Values.Ports) == 0 { + t.Errorf("%#v", iConcreteLinux.Values.Ports) + } + fmt.Printf("%#v", iConcreteLinux.Values.Ports) + } } From c0e4eaa9e06dd9c9db29720a65dd9498ffab3069 Mon Sep 17 00:00:00 2001 From: Diretnan Domnan Date: Fri, 25 Mar 2022 09:54:33 +0100 Subject: [PATCH 3/3] Windows: Adding tcp inspector --- inspector/tcp.go | 65 +++++++++++++++++++++++++ integration/integration_windows_test.go | 13 +++++ 2 files changed, 78 insertions(+) diff --git a/inspector/tcp.go b/inspector/tcp.go index 5de57b9..33400e7 100644 --- a/inspector/tcp.go +++ b/inspector/tcp.go @@ -30,6 +30,12 @@ type TcpLinux struct { Values TcpMetrics } +type TcpWin struct { + Command string + Driver *driver.Driver + Values TcpMetrics +} + /* Parse : parsing the following kind of output Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) @@ -135,6 +141,61 @@ func (i *TcpLinux) Execute() { } } +/* Parse for output + +Active Connections + + Proto Local Address Foreign Address State + TCP 0.0.0.0:135 0.0.0.0:0 LISTENING + TCP 0.0.0.0:445 0.0.0.0:0 LISTENING + TCP 0.0.0.0:5040 0.0.0.0:0 LISTENING + TCP 0.0.0.0:5700 0.0.0.0:0 LISTENING + TCP 0.0.0.0:6646 0.0.0.0:0 LISTENING + TCP 0.0.0.0:49664 0.0.0.0:0 LISTENING +*/ +func (i *TcpWin) Parse(output string) { + ports := make(map[int]string) + lines := strings.Split(output, "\n") + for index, line := range lines { + // skip title lines + if index == 0 || index == 1 || index == 3 { + continue + } + columns := strings.Fields(line) + if len(columns) > 3 { + status := columns[3] + address := strings.Split(columns[1], ":") + portString := address[len(address)-1] + port, err := strconv.Atoi(portString) + if err != nil { + log.Fatal("Could not parse port number in TcpWin") + } + ports[port] = status + + } + } + i.Values.Ports = ports +} + +func (i *TcpWin) SetDriver(driver *driver.Driver) { + details := (*driver).GetDetails() + if !details.IsWindows { + panic("Cannot use TcpWin on drivers outside (windows)") + } + i.Driver = driver +} + +func (i TcpWin) driverExec() driver.Command { + return (*i.Driver).RunCommand +} + +func (i *TcpWin) Execute() { + output, err := i.driverExec()(i.Command) + if err == nil { + i.Parse(output) + } +} + // NewTcp: Initialize a new Tcp instance func NewTcp(driver *driver.Driver, _ ...string) (Inspector, error) { var tcp Inspector @@ -150,6 +211,10 @@ func NewTcp(driver *driver.Driver, _ ...string) (Inspector, error) { tcp = &TcpLinux{ Command: `ss -tan`, } + } else if details.IsWindows { + tcp = &TcpWin{ + Command: `netstat -anp tcp`, + } } tcp.SetDriver(driver) return tcp, nil diff --git a/integration/integration_windows_test.go b/integration/integration_windows_test.go index 5d8ca68..845f295 100644 --- a/integration/integration_windows_test.go +++ b/integration/integration_windows_test.go @@ -92,3 +92,16 @@ func TestDFonLocal(t *testing.T) { } } } + +func TestTcponLocal(t *testing.T) { + d := NewLocalForTest() + i, _ := inspector.Init(`tcp`, &d) + i.Execute() + iConcreteWindows, ok := i.(*inspector.TcpWin) + if ok { + if len(iConcreteWindows.Values.Ports) == 0 { + t.Errorf("%#v", iConcreteWindows.Values.Ports) + } + fmt.Printf("%#v", iConcreteWindows.Values.Ports) + } +}