fix: udp handling and ipv4 and ipv6 filtering
This commit is contained in:
@@ -246,11 +246,6 @@ func getSocketInfo(pid, fd int, procName string, uid int, user string) (Connecti
|
||||
raddr = ipv6ToString(info.raddr6)
|
||||
}
|
||||
|
||||
state := ""
|
||||
if info.sock_type == C.SOCK_STREAM {
|
||||
state = tcpStateToString(int(info.state))
|
||||
}
|
||||
|
||||
if laddr == "0.0.0.0" || laddr == "::" {
|
||||
laddr = "*"
|
||||
}
|
||||
@@ -258,6 +253,18 @@ func getSocketInfo(pid, fd int, procName string, uid int, user string) (Connecti
|
||||
raddr = "*"
|
||||
}
|
||||
|
||||
state := ""
|
||||
if info.sock_type == C.SOCK_STREAM {
|
||||
state = tcpStateToString(int(info.state))
|
||||
} else if info.sock_type == C.SOCK_DGRAM {
|
||||
// udp is connectionless - infer state from remote address
|
||||
if raddr == "*" && int(info.rport) == 0 {
|
||||
state = "LISTEN"
|
||||
} else {
|
||||
state = "ESTABLISHED"
|
||||
}
|
||||
}
|
||||
|
||||
conn := Connection{
|
||||
TS: time.Now(),
|
||||
Proto: proto,
|
||||
|
||||
@@ -226,6 +226,13 @@ func parseProcNet(path, proto string, ipVersion int, inodeMap map[int64]*process
|
||||
|
||||
inode, _ := strconv.ParseInt(fields[9], 10, 64)
|
||||
|
||||
// refine udp state: if unconnected and remote is wildcard, it's listening
|
||||
if strings.HasPrefix(proto, "udp") && state == "UNCONNECTED" {
|
||||
if remoteAddr == "*" && remotePort == 0 {
|
||||
state = "LISTEN"
|
||||
}
|
||||
}
|
||||
|
||||
conn := Connection{
|
||||
TS: time.Now(),
|
||||
Proto: proto,
|
||||
@@ -277,13 +284,22 @@ func parseState(hexState, proto string) string {
|
||||
if s, exists := tcpStates[state]; exists {
|
||||
return s
|
||||
}
|
||||
} else {
|
||||
if state == 0x07 {
|
||||
return "CLOSE"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// udp states - udp is connectionless so the kernel reuses tcp state values
|
||||
// with different meanings:
|
||||
// 0x07 (TCP_CLOSE) = unconnected socket, typically bound and listening
|
||||
// 0x01 (TCP_ESTABLISHED) = "connected" socket (connect() was called)
|
||||
udpStates := map[int64]string{
|
||||
0x01: "ESTABLISHED",
|
||||
0x07: "UNCONNECTED",
|
||||
}
|
||||
|
||||
if s, exists := udpStates[state]; exists {
|
||||
return s
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ func (f *FilterOptions) IsEmpty() bool {
|
||||
}
|
||||
|
||||
func (f *FilterOptions) Matches(c Connection) bool {
|
||||
if f.Proto != "" && !strings.EqualFold(c.Proto, f.Proto) {
|
||||
if f.Proto != "" && !matchesProto(c.Proto, f.Proto) {
|
||||
return false
|
||||
}
|
||||
if f.State != "" && !strings.EqualFold(c.State, f.State) {
|
||||
@@ -104,6 +104,30 @@ func containsIgnoreCase(s, substr string) bool {
|
||||
return strings.Contains(strings.ToLower(s), strings.ToLower(substr))
|
||||
}
|
||||
|
||||
// checks if a connection's protocol matches the filter.
|
||||
// treats "tcp" as matching "tcp" and "tcp6", same for "udp"/"udp6"
|
||||
func matchesProto(connProto, filterProto string) bool {
|
||||
connLower := strings.ToLower(connProto)
|
||||
filterLower := strings.ToLower(filterProto)
|
||||
|
||||
// exact match
|
||||
if connLower == filterLower {
|
||||
return true
|
||||
}
|
||||
|
||||
// "tcp" matches both "tcp" and "tcp6"
|
||||
if filterLower == "tcp" && (connLower == "tcp" || connLower == "tcp6") {
|
||||
return true
|
||||
}
|
||||
|
||||
// "udp" matches both "udp" and "udp6"
|
||||
if filterLower == "udp" && (connLower == "udp" || connLower == "udp6") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func matchesContains(c Connection, query string) bool {
|
||||
q := strings.ToLower(query)
|
||||
return containsIgnoreCase(c.Process, q) ||
|
||||
|
||||
@@ -162,7 +162,7 @@ func getDefaultTestConnections() []Connection {
|
||||
UID: 25,
|
||||
Proto: "udp",
|
||||
IPVersion: "IPv4",
|
||||
State: "CONNECTED",
|
||||
State: "LISTEN",
|
||||
Laddr: "0.0.0.0",
|
||||
Lport: 53,
|
||||
Raddr: "*",
|
||||
@@ -358,7 +358,7 @@ func GetTestFixtures() []TestFixture {
|
||||
PID: 2,
|
||||
Process: "udp-server",
|
||||
Proto: "udp",
|
||||
State: "CONNECTED",
|
||||
State: "LISTEN",
|
||||
Laddr: "0.0.0.0",
|
||||
Lport: 53,
|
||||
Interface: "eth0",
|
||||
|
||||
@@ -111,16 +111,17 @@ func compareConnections(a, b Connection, field SortField) bool {
|
||||
func stateOrder(state string) int {
|
||||
order := map[string]int{
|
||||
"LISTEN": 0,
|
||||
"ESTABLISHED": 1,
|
||||
"SYN_SENT": 2,
|
||||
"SYN_RECV": 3,
|
||||
"FIN_WAIT1": 4,
|
||||
"FIN_WAIT2": 5,
|
||||
"TIME_WAIT": 6,
|
||||
"CLOSE_WAIT": 7,
|
||||
"LAST_ACK": 8,
|
||||
"CLOSING": 9,
|
||||
"CLOSED": 10,
|
||||
"UNCONNECTED": 1, // udp sockets bound but not connected to a specific peer
|
||||
"ESTABLISHED": 2,
|
||||
"SYN_SENT": 3,
|
||||
"SYN_RECV": 4,
|
||||
"FIN_WAIT1": 5,
|
||||
"FIN_WAIT2": 6,
|
||||
"TIME_WAIT": 7,
|
||||
"CLOSE_WAIT": 8,
|
||||
"LAST_ACK": 9,
|
||||
"CLOSING": 10,
|
||||
"CLOSED": 11,
|
||||
}
|
||||
|
||||
if o, exists := order[strings.ToUpper(state)]; exists {
|
||||
|
||||
Reference in New Issue
Block a user