Enhance error handling and user feedback in the web server's index handler
This commit is contained in:
@@ -102,7 +102,7 @@ func (ps *PortScanner) parseNetstatOutput(output, protocol string) ([]types.Port
|
||||
continue
|
||||
}
|
||||
|
||||
port, err := ps.parseNetstatLine(line, protocol)
|
||||
port, err := ps.parseNetstatLineMacOS(line, protocol)
|
||||
if err != nil {
|
||||
continue // 跳过解析失败的行
|
||||
}
|
||||
@@ -118,31 +118,54 @@ func (ps *PortScanner) parseNetstatOutput(output, protocol string) ([]types.Port
|
||||
return ports, nil
|
||||
}
|
||||
|
||||
// parseNetstatLine 解析netstat的单行输出
|
||||
func (ps *PortScanner) parseNetstatLine(line, protocol string) (*types.PortInfo, error) {
|
||||
// parseNetstatLineMacOS 解析macOS netstat的单行输出
|
||||
func (ps *PortScanner) parseNetstatLineMacOS(line, protocol string) (*types.PortInfo, error) {
|
||||
fields := regexp.MustCompile(`\s+`).Split(line, -1)
|
||||
if len(fields) < 3 {
|
||||
if len(fields) < 4 {
|
||||
return nil, fmt.Errorf("invalid line format")
|
||||
}
|
||||
|
||||
// 解析本地地址
|
||||
localAddr := fields[0]
|
||||
parts := strings.Split(localAddr, ":")
|
||||
if len(parts) < 2 {
|
||||
return nil, fmt.Errorf("invalid address format")
|
||||
// macOS netstat格式: Proto Recv-Q Send-Q Local-Address Foreign-Address (state)
|
||||
localAddr := fields[3]
|
||||
state := ""
|
||||
if len(fields) >= 6 {
|
||||
state = fields[5]
|
||||
}
|
||||
|
||||
// 解析本地地址,可能包含IPv6地址
|
||||
var portStr string
|
||||
if strings.Contains(localAddr, ".") {
|
||||
// IPv4 格式: ip.port
|
||||
parts := strings.Split(localAddr, ".")
|
||||
if len(parts) >= 2 {
|
||||
portStr = parts[len(parts)-1]
|
||||
}
|
||||
} else if strings.Contains(localAddr, ":") {
|
||||
// IPv6 格式: [ip]:port 或 ip:port
|
||||
if strings.Contains(localAddr, "]:") {
|
||||
// [ip]:port
|
||||
parts := strings.Split(localAddr, "]:")
|
||||
if len(parts) == 2 {
|
||||
portStr = parts[1]
|
||||
}
|
||||
} else {
|
||||
// ip:port (简单情况)
|
||||
parts := strings.Split(localAddr, ":")
|
||||
if len(parts) >= 2 {
|
||||
portStr = parts[len(parts)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if portStr == "" {
|
||||
return nil, fmt.Errorf("could not extract port from address: %s", localAddr)
|
||||
}
|
||||
|
||||
portStr := parts[len(parts)-1]
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid port: %s", portStr)
|
||||
}
|
||||
|
||||
state := ""
|
||||
if protocol == "tcp" && len(fields) >= 4 {
|
||||
state = fields[3]
|
||||
}
|
||||
|
||||
return &types.PortInfo{
|
||||
Port: port,
|
||||
Protocol: protocol,
|
||||
@@ -154,15 +177,18 @@ func (ps *PortScanner) parseNetstatLine(line, protocol string) (*types.PortInfo,
|
||||
// shouldIncludePort 判断是否应该包含此端口
|
||||
func (ps *PortScanner) shouldIncludePort(port *types.PortInfo) bool {
|
||||
if port.Protocol == "tcp" {
|
||||
if port.State == "LISTEN" {
|
||||
// macOS netstat 状态值可能包括: LISTEN, ESTABLISHED, SYN_SENT, etc.
|
||||
if strings.Contains(port.State, "LISTEN") {
|
||||
return ps.includeListening
|
||||
}
|
||||
if port.State == "ESTABLISHED" {
|
||||
if strings.Contains(port.State, "ESTABLISHED") {
|
||||
return ps.includeEstablished
|
||||
}
|
||||
// 对于其他状态,如果设置了包含监听端口,也包含进来
|
||||
return ps.includeListening
|
||||
}
|
||||
|
||||
// UDP端口默认包含
|
||||
// UDP端口默认包含(如果启用了监听端口)
|
||||
if port.Protocol == "udp" {
|
||||
return ps.includeListening
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user