mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
chore: 移除 fscan-lite (C 版本)
功能过于单一(仅 TCP 端口扫描),与 fscan 品牌定位不符。 fscan-nolocal 已是精简版的正确方案。 - 删除 fscan-lite 源码和构建脚本 - goreleaser 移除 lite 构建步骤 - CI 不再安装 mingw 交叉编译工具
This commit is contained in:
@@ -30,11 +30,6 @@ runs:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
cache: true
|
||||
|
||||
- name: 安装 C 编译工具
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y gcc make mingw-w64 gcc-multilib g++-multilib
|
||||
|
||||
- name: 下载依赖
|
||||
shell: bash
|
||||
@@ -66,9 +61,7 @@ runs:
|
||||
if: always()
|
||||
with:
|
||||
name: build-${{ inputs.mode }}-${{ github.run_id }}
|
||||
path: |
|
||||
dist/
|
||||
dist-lite/
|
||||
path: dist/
|
||||
retention-days: ${{ inputs.retention-days }}
|
||||
|
||||
- name: 生成报告
|
||||
@@ -87,7 +80,6 @@ runs:
|
||||
|
||||
## 构建产物
|
||||
|
||||
### fscan (Go 版本)
|
||||
$(if [ -d "dist" ]; then
|
||||
echo "- 文件数: $(find dist -type f 2>/dev/null | wc -l)"
|
||||
echo "- 大小: $(du -sh dist 2>/dev/null | cut -f1)"
|
||||
@@ -95,13 +87,5 @@ runs:
|
||||
echo "- 无产物"
|
||||
fi)
|
||||
|
||||
### fscan-lite (C 版本)
|
||||
$(if [ -d "dist-lite" ]; then
|
||||
echo "- 文件数: $(find dist-lite -type f 2>/dev/null | wc -l)"
|
||||
echo "- 大小: $(du -sh dist-lite 2>/dev/null | cut -f1)"
|
||||
else
|
||||
echo "- 无产物"
|
||||
fi)
|
||||
|
||||
[查看产物](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
||||
EOF
|
||||
|
||||
@@ -4,8 +4,6 @@ before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
- go mod download
|
||||
- chmod +x .github/scripts/build-lite.sh
|
||||
- bash .github/scripts/build-lite.sh {{ .Version }}
|
||||
|
||||
builds:
|
||||
# 标准版 - 全部插件(全架构)
|
||||
@@ -238,8 +236,6 @@ release:
|
||||
| Solaris | x64 |
|
||||
footer: |
|
||||
**完整更新日志**: https://github.com/{{ .Env.GITHUB_OWNER }}/{{ .Env.GITHUB_REPO }}/compare/{{ .PreviousTag }}...{{ .Tag }}
|
||||
extra_files:
|
||||
- glob: ./dist-lite/*
|
||||
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}-dev-{{ .ShortCommit }}"
|
||||
|
||||
@@ -103,4 +103,4 @@
|
||||
| Windows | x64, x32 |
|
||||
| macOS | x64 (Intel), arm64 (Apple Silicon) |
|
||||
| FreeBSD | x64, x32, arm64, armv5/6/7 |
|
||||
| Solaris | x64 |
|
||||
| Solaris | X64n |
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 构建 fscan-lite 并准备发布产物
|
||||
|
||||
set -e
|
||||
|
||||
VERSION="${1:-dev}"
|
||||
LITE_DIR="fscan-lite"
|
||||
OUTPUT_DIR="dist-lite"
|
||||
|
||||
echo "==> 构建 fscan-lite (版本: $VERSION)"
|
||||
|
||||
# 清理旧产物
|
||||
rm -rf "$OUTPUT_DIR"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# 进入 lite 目录
|
||||
cd "$LITE_DIR"
|
||||
|
||||
# 源文件
|
||||
SOURCES="src/main.c src/scanner.c src/platform.c"
|
||||
INCLUDE="-Iinclude"
|
||||
CFLAGS_BASE="-std=c89 -Wall -O2"
|
||||
|
||||
# 构建 Linux 版本
|
||||
echo "==> 构建 Linux 版本..."
|
||||
|
||||
# Linux x64
|
||||
echo " - Linux x64"
|
||||
mkdir -p bin
|
||||
gcc $CFLAGS_BASE $INCLUDE -o bin/fscan-lite $SOURCES -lpthread
|
||||
cp bin/fscan-lite "../$OUTPUT_DIR/fscan-lite_${VERSION}_linux_x64"
|
||||
rm -rf bin
|
||||
|
||||
# Linux x32
|
||||
echo " - Linux x32"
|
||||
mkdir -p bin
|
||||
gcc $CFLAGS_BASE -m32 $INCLUDE -o bin/fscan-lite $SOURCES -lpthread 2>/dev/null || echo " (跳过: 缺少 32-bit 支持)"
|
||||
if [ -f bin/fscan-lite ]; then
|
||||
cp bin/fscan-lite "../$OUTPUT_DIR/fscan-lite_${VERSION}_linux_x32"
|
||||
fi
|
||||
rm -rf bin
|
||||
|
||||
# 构建 Windows 版本
|
||||
echo "==> 构建 Windows 版本..."
|
||||
|
||||
# Windows x64
|
||||
echo " - Windows x64"
|
||||
mkdir -p bin
|
||||
x86_64-w64-mingw32-gcc $CFLAGS_BASE $INCLUDE -o bin/fscan-lite.exe $SOURCES -lws2_32 -static
|
||||
if [ -f bin/fscan-lite.exe ]; then
|
||||
cp bin/fscan-lite.exe "../$OUTPUT_DIR/fscan-lite_${VERSION}_windows_x64.exe"
|
||||
echo " ✓ 编译成功"
|
||||
else
|
||||
echo " ✗ 编译失败"
|
||||
fi
|
||||
rm -rf bin
|
||||
|
||||
# Windows x32
|
||||
echo " - Windows x32"
|
||||
mkdir -p bin
|
||||
i686-w64-mingw32-gcc $CFLAGS_BASE $INCLUDE -o bin/fscan-lite.exe $SOURCES -lws2_32 -static
|
||||
if [ -f bin/fscan-lite.exe ]; then
|
||||
cp bin/fscan-lite.exe "../$OUTPUT_DIR/fscan-lite_${VERSION}_windows_x32.exe"
|
||||
echo " ✓ 编译成功"
|
||||
else
|
||||
echo " ✗ 编译失败"
|
||||
fi
|
||||
rm -rf bin
|
||||
|
||||
cd ..
|
||||
|
||||
# 统计产物
|
||||
echo ""
|
||||
echo "==> 构建完成!"
|
||||
echo "产物列表:"
|
||||
if [ -d "$OUTPUT_DIR" ]; then
|
||||
ls -lh "$OUTPUT_DIR" 2>/dev/null || echo " (无产物)"
|
||||
echo ""
|
||||
FILECOUNT=$(ls "$OUTPUT_DIR" 2>/dev/null | wc -l)
|
||||
echo "总计: $FILECOUNT 个文件"
|
||||
fi
|
||||
@@ -1,126 +0,0 @@
|
||||
# fscan-lite
|
||||
|
||||
极简但极致兼容的TCP内网端口扫描器
|
||||
|
||||
## 设计理念
|
||||
|
||||
**兼容性第一,简洁至上**
|
||||
|
||||
- 支持从 Windows 98 到 Windows 11
|
||||
- 支持从 Ubuntu 8.04 到最新版本
|
||||
- 使用 C89 标准,最大兼容性
|
||||
- 静态编译,零依赖运行
|
||||
- 单个可执行文件 < 1MB
|
||||
|
||||
## 功能特性
|
||||
|
||||
- ✅ TCP端口连接扫描
|
||||
- ✅ 支持端口范围 (1-65535, 80,443)
|
||||
- ✅ 可配置超时时间
|
||||
- ✅ 静态编译,零依赖
|
||||
- ✅ 跨平台兼容
|
||||
|
||||
## 编译
|
||||
|
||||
### Linux/Unix
|
||||
|
||||
```bash
|
||||
# 动态编译
|
||||
make
|
||||
|
||||
# 静态编译(推荐)
|
||||
make static
|
||||
|
||||
# 最小化编译
|
||||
make small
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
```bash
|
||||
# MinGW 编译
|
||||
mingw32-make -f Makefile
|
||||
|
||||
# 或使用MSVC
|
||||
cl /TC src/*.c /Febin/fscan-lite.exe ws2_32.lib
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
```bash
|
||||
# 基本用法
|
||||
./bin/fscan-lite -h 192.168.1.1 -p 22,80,443
|
||||
|
||||
# 扫描端口范围
|
||||
./bin/fscan-lite -h 10.0.0.1 -p 1-1000
|
||||
|
||||
# 自定义超时
|
||||
./bin/fscan-lite -h 192.168.1.100 -p 80,443 -t 2
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
|
||||
| 参数 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| -h HOST | 目标主机IP | -h 192.168.1.1 |
|
||||
| -p PORTS | 端口列表 | -p 80,443,8000-8080 |
|
||||
| -t TIMEOUT | 超时时间(秒) | -t 3 |
|
||||
| --help | 显示帮助 | --help |
|
||||
| --version | 显示版本 | --version |
|
||||
|
||||
## 二进制大小对比
|
||||
|
||||
| 版本 | 大小 | 说明 |
|
||||
|------|------|------|
|
||||
| fscan (Go) | ~30MB | 包含运行时 |
|
||||
| fscan-lite | ~900KB | 静态编译 |
|
||||
| fscan-lite (strip) | ~700KB | 去除调试信息 |
|
||||
|
||||
## 兼容性测试
|
||||
|
||||
### Linux 发行版
|
||||
- ✅ Ubuntu 8.04 - 24.04
|
||||
- ✅ CentOS 5 - 9
|
||||
- ✅ Debian 5 - 12
|
||||
- ✅ RHEL 5 - 9
|
||||
|
||||
### Windows 版本
|
||||
- ✅ Windows 98 SE
|
||||
- ✅ Windows XP
|
||||
- ✅ Windows 7/8/10/11
|
||||
- ✅ Windows Server 2003-2022
|
||||
|
||||
## 技术实现
|
||||
|
||||
- **语言**: C89 (最大兼容性)
|
||||
- **网络**: 原生socket API
|
||||
- **编译**: GCC/MSVC/Clang
|
||||
- **链接**: 静态链接,零依赖
|
||||
- **大小**: < 1MB 单文件
|
||||
|
||||
## 性能对比
|
||||
|
||||
| 指标 | fscan | fscan-lite |
|
||||
|------|-------|------------|
|
||||
| 启动时间 | ~50ms | ~5ms |
|
||||
| 内存占用 | ~20MB | ~2MB |
|
||||
| 扫描速度 | 1000 ports/s | 1000 ports/s |
|
||||
| 兼容性 | 现代系统 | 25年跨度 |
|
||||
|
||||
## 构建配置
|
||||
|
||||
```bash
|
||||
# 查看构建信息
|
||||
make info
|
||||
|
||||
# 所有构建选项
|
||||
make help
|
||||
```
|
||||
|
||||
## 许可证
|
||||
|
||||
与 fscan 主项目保持一致
|
||||
|
||||
---
|
||||
|
||||
**理念**: 一个工具应该在它设计的任何系统上都能运行,而不需要用户去寻找依赖项。
|
||||
@@ -1,156 +0,0 @@
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
/*
|
||||
* platform.h - 极致兼容性的平台抽象层
|
||||
*
|
||||
* 支持范围:
|
||||
* Windows: 98/ME/NT4/2000/XP/Vista/7/8/10/11
|
||||
* Linux: glibc 2.3+ (2003年后的所有发行版)
|
||||
* 编译器: MSVC 6.0+, GCC 3.0+, Clang 3.0+
|
||||
*/
|
||||
|
||||
/* C89兼容性 - 最古老但最可靠的标准 */
|
||||
#ifndef __STDC__
|
||||
#define __STDC__ 1
|
||||
#endif
|
||||
|
||||
/* 平台检测 */
|
||||
#ifdef _WIN32
|
||||
#define PLATFORM_WINDOWS
|
||||
#ifdef _WIN64
|
||||
#define PLATFORM_WIN64
|
||||
#else
|
||||
#define PLATFORM_WIN32
|
||||
#endif
|
||||
#else
|
||||
#define PLATFORM_UNIX
|
||||
#ifdef __linux__
|
||||
#define PLATFORM_LINUX
|
||||
#elif defined(__APPLE__)
|
||||
#define PLATFORM_MACOS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Windows头文件包含 - 兼容Win98 */
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
/* 定义最低Windows版本 - Win98 */
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0410 /* Windows 98 */
|
||||
#endif
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0410
|
||||
#endif
|
||||
|
||||
/* 必须先包含winsock2.h,否则windows.h会包含旧版winsock.h导致冲突 */
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* 老版本Windows兼容性 */
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER < 1300 /* MSVC 6.0 */
|
||||
#pragma comment(lib, "wsock32.lib")
|
||||
#else
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Windows类型定义 */
|
||||
typedef SOCKET socket_t;
|
||||
typedef int socklen_t;
|
||||
#define INVALID_SOCKET_VALUE INVALID_SOCKET
|
||||
#define close_socket closesocket
|
||||
#define socket_errno WSAGetLastError()
|
||||
|
||||
/* Windows错误码转换 - 使用ifndef避免与errno.h冲突 */
|
||||
#ifndef EWOULDBLOCK
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#endif
|
||||
#ifndef EINPROGRESS
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#endif
|
||||
#ifndef ECONNREFUSED
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Unix/Linux头文件 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
|
||||
/* Unix类型定义 */
|
||||
typedef int socket_t;
|
||||
#define INVALID_SOCKET_VALUE (-1)
|
||||
#define close_socket close
|
||||
#define socket_errno errno
|
||||
|
||||
#endif
|
||||
|
||||
/* 标准C头文件 */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
/* 线程抽象 - 最简单的实现 */
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
typedef HANDLE thread_t;
|
||||
typedef DWORD thread_id_t;
|
||||
typedef unsigned (__stdcall *thread_func_t)(void *);
|
||||
|
||||
#define CREATE_THREAD(func, arg) \
|
||||
(HANDLE)_beginthreadex(NULL, 0, (thread_func_t)(func), (arg), 0, NULL)
|
||||
#define WAIT_THREAD(handle) WaitForSingleObject((handle), INFINITE)
|
||||
#define CLOSE_THREAD(handle) CloseHandle(handle)
|
||||
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <fcntl.h>
|
||||
typedef pthread_t thread_t;
|
||||
typedef pthread_t thread_id_t;
|
||||
typedef void* (*thread_func_t)(void *);
|
||||
|
||||
#define CREATE_THREAD(func, arg) ({ \
|
||||
pthread_t t; \
|
||||
pthread_create(&t, NULL, (thread_func_t)(func), (arg)) == 0 ? t : 0; \
|
||||
})
|
||||
#define WAIT_THREAD(handle) pthread_join((handle), NULL)
|
||||
#define CLOSE_THREAD(handle) /* pthread handles are auto-cleaned */
|
||||
|
||||
#endif
|
||||
|
||||
/* 时间函数抽象 */
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
#define sleep_ms(ms) Sleep(ms)
|
||||
#else
|
||||
#define sleep_ms(ms) usleep((ms) * 1000)
|
||||
#endif
|
||||
|
||||
/* 编译器特定定义 */
|
||||
#ifdef _MSC_VER
|
||||
/* MSVC特定 */
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
/* 常用常量 */
|
||||
#define MAX_HOST_LEN 256
|
||||
#define MAX_PORT_COUNT 65536
|
||||
#define DEFAULT_TIMEOUT 3
|
||||
#define DEFAULT_THREAD_COUNT 100
|
||||
|
||||
/* 函数声明 */
|
||||
int platform_init(void);
|
||||
void platform_cleanup(void);
|
||||
int set_socket_timeout(socket_t sock, int timeout_seconds);
|
||||
int make_socket_nonblocking(socket_t sock);
|
||||
|
||||
#endif /* PLATFORM_H */
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* main.c - fscan-lite 主程序
|
||||
*
|
||||
* 极简的TCP内网端口扫描器
|
||||
* 目标:最大兼容性,最小复杂度
|
||||
*/
|
||||
|
||||
#include "../include/platform.h"
|
||||
|
||||
/* 函数声明 */
|
||||
int tcp_connect_test(const char* host, int port, int timeout);
|
||||
int scan_host_ports(const char* host, const int* ports, int port_count, int timeout);
|
||||
int parse_ports(const char* port_str, int* ports, int max_ports);
|
||||
int parse_hosts(const char* host_str, char hosts[][MAX_HOST_LEN], int max_hosts);
|
||||
|
||||
/* 显示版本信息 */
|
||||
void show_version(void) {
|
||||
printf("fscan-lite v1.0 - Lightweight TCP Port Scanner\n");
|
||||
printf("Built for maximum compatibility (Windows 98 - Windows 11, Linux glibc 2.3+)\n");
|
||||
printf("Copyright (c) 2024\n");
|
||||
}
|
||||
|
||||
/* 显示使用帮助 */
|
||||
void show_usage(const char* program_name) {
|
||||
printf("Usage: %s [OPTIONS]\n", program_name);
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -h HOST Target host (IP address)\n");
|
||||
printf(" -p PORTS Ports to scan (e.g. 80,443 or 1-1000)\n");
|
||||
printf(" -t TIMEOUT Connection timeout in seconds (default: 3)\n");
|
||||
printf(" --help Show this help message\n");
|
||||
printf(" --version Show version information\n");
|
||||
printf("\n");
|
||||
printf("Examples:\n");
|
||||
printf(" %s -h 192.168.1.1 -p 22,80,443\n", program_name);
|
||||
printf(" %s -h 10.0.0.1 -p 1-1000 -t 2\n", program_name);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* 主函数 */
|
||||
int main(int argc, char* argv[]) {
|
||||
char* target_host = NULL;
|
||||
char* port_string = NULL;
|
||||
int timeout = DEFAULT_TIMEOUT;
|
||||
int ports[1000]; /* 支持最多1000个端口 */
|
||||
int port_count = 0;
|
||||
int i;
|
||||
int result;
|
||||
|
||||
/* 参数解析 */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-h") == 0 && i + 1 < argc) {
|
||||
target_host = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
|
||||
port_string = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-t") == 0 && i + 1 < argc) {
|
||||
timeout = atoi(argv[++i]);
|
||||
if (timeout <= 0) timeout = DEFAULT_TIMEOUT;
|
||||
}
|
||||
else if (strcmp(argv[i], "--help") == 0) {
|
||||
show_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[i], "--version") == 0) {
|
||||
show_version();
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
printf("Unknown option: %s\n", argv[i]);
|
||||
show_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 验证必需参数 */
|
||||
if (!target_host) {
|
||||
printf("Error: Target host (-h) is required\n");
|
||||
show_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!port_string) {
|
||||
printf("Error: Ports (-p) are required\n");
|
||||
show_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 初始化平台 */
|
||||
if (platform_init() != 0) {
|
||||
printf("Error: Failed to initialize platform\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 解析端口 */
|
||||
port_count = parse_ports(port_string, ports, sizeof(ports) / sizeof(ports[0]));
|
||||
if (port_count == 0) {
|
||||
printf("Error: No valid ports specified\n");
|
||||
platform_cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("fscan-lite - Starting scan\n");
|
||||
printf("Target: %s\n", target_host);
|
||||
printf("Ports: %d ports to scan\n", port_count);
|
||||
printf("Timeout: %d seconds\n", timeout);
|
||||
printf("=================================\n");
|
||||
|
||||
/* 执行扫描 */
|
||||
result = scan_host_ports(target_host, ports, port_count, timeout);
|
||||
|
||||
printf("=================================\n");
|
||||
printf("Scan completed: %d open ports found\n", result);
|
||||
|
||||
/* 清理资源 */
|
||||
platform_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* platform.c - 平台抽象层实现
|
||||
*
|
||||
* 实现最基础但最可靠的平台相关功能
|
||||
*/
|
||||
|
||||
#include "../include/platform.h"
|
||||
|
||||
/* 全局初始化标志 */
|
||||
static int platform_initialized = 0;
|
||||
|
||||
/*
|
||||
* 平台初始化
|
||||
* Windows: 初始化Winsock
|
||||
* Unix: 无需特殊初始化
|
||||
*/
|
||||
int platform_init(void) {
|
||||
if (platform_initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
WSADATA wsaData;
|
||||
int result;
|
||||
|
||||
/* 初始化Winsock - 请求版本2.0,兼容Win98 */
|
||||
result = WSAStartup(MAKEWORD(2, 0), &wsaData);
|
||||
if (result != 0) {
|
||||
/* 如果2.0失败,尝试1.1(Win95/NT兼容) */
|
||||
result = WSAStartup(MAKEWORD(1, 1), &wsaData);
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
platform_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 平台清理
|
||||
*/
|
||||
void platform_cleanup(void) {
|
||||
if (!platform_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
platform_initialized = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 设置socket超时
|
||||
* 兼容所有平台的最可靠方法
|
||||
*/
|
||||
int set_socket_timeout(socket_t sock, int timeout_seconds) {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
DWORD timeout_ms = timeout_seconds * 1000;
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
|
||||
(char*)&timeout_ms, sizeof(timeout_ms)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
|
||||
(char*)&timeout_ms, sizeof(timeout_ms)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout_seconds;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
|
||||
(void*)&tv, sizeof(tv)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
|
||||
(void*)&tv, sizeof(tv)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 设置socket为非阻塞模式
|
||||
* 跨平台兼容实现
|
||||
*/
|
||||
int make_socket_nonblocking(socket_t sock) {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
u_long mode = 1;
|
||||
return ioctlsocket(sock, FIONBIO, &mode);
|
||||
#else
|
||||
int flags;
|
||||
|
||||
flags = fcntl(sock, F_GETFL, 0);
|
||||
if (flags == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
flags |= O_NONBLOCK;
|
||||
return fcntl(sock, F_SETFL, flags);
|
||||
#endif
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* scanner.c - 核心TCP端口扫描实现
|
||||
*
|
||||
* 极简但可靠的端口扫描逻辑,专注于内网环境
|
||||
*/
|
||||
|
||||
#include "../include/platform.h"
|
||||
|
||||
/*
|
||||
* 基础TCP连接测试
|
||||
* 返回: 1=端口开放, 0=端口关闭, -1=错误
|
||||
*/
|
||||
int tcp_connect_test(const char* host, int port, int timeout) {
|
||||
socket_t sock;
|
||||
struct sockaddr_in addr;
|
||||
int result;
|
||||
|
||||
/* 参数验证 */
|
||||
if (!host || port <= 0 || port > 65535) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 创建socket */
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == INVALID_SOCKET_VALUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 设置超时 */
|
||||
if (set_socket_timeout(sock, timeout) != 0) {
|
||||
close_socket(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 设置目标地址 */
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons((unsigned short)port);
|
||||
|
||||
/* 转换IP地址 */
|
||||
addr.sin_addr.s_addr = inet_addr(host);
|
||||
if (addr.sin_addr.s_addr == INADDR_NONE) {
|
||||
/* 如果不是有效IP,当作域名处理 */
|
||||
struct hostent* he;
|
||||
he = gethostbyname(host);
|
||||
if (!he) {
|
||||
close_socket(sock);
|
||||
return -1;
|
||||
}
|
||||
memcpy(&addr.sin_addr, he->h_addr_list[0], he->h_length);
|
||||
}
|
||||
|
||||
/* 执行连接测试 */
|
||||
result = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
|
||||
|
||||
/* 关闭socket */
|
||||
close_socket(sock);
|
||||
|
||||
/* 返回结果 */
|
||||
return (result == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 扫描单个主机的多个端口
|
||||
*/
|
||||
int scan_host_ports(const char* host, const int* ports, int port_count, int timeout) {
|
||||
int i;
|
||||
int open_count = 0;
|
||||
|
||||
if (!host || !ports || port_count <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Scanning %s...\n", host);
|
||||
|
||||
for (i = 0; i < port_count; i++) {
|
||||
int result = tcp_connect_test(host, ports[i], timeout);
|
||||
|
||||
if (result == 1) {
|
||||
printf("%s:%d open\n", host, ports[i]);
|
||||
open_count++;
|
||||
} else if (result == -1) {
|
||||
/* 静默处理错误,继续扫描 */
|
||||
}
|
||||
|
||||
/* 简单的进度指示 */
|
||||
if ((i + 1) % 100 == 0 || i == port_count - 1) {
|
||||
printf("Progress: %d/%d ports scanned\n", i + 1, port_count);
|
||||
}
|
||||
}
|
||||
|
||||
return open_count;
|
||||
}
|
||||
|
||||
/*
|
||||
* 解析端口范围字符串
|
||||
* 支持: "80", "80,443", "1-1000", "80,443,8000-8080"
|
||||
*/
|
||||
int parse_ports(const char* port_str, int* ports, int max_ports) {
|
||||
char* str_copy;
|
||||
char* token;
|
||||
int count = 0;
|
||||
|
||||
if (!port_str || !ports || max_ports <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 复制字符串以便修改 */
|
||||
str_copy = malloc(strlen(port_str) + 1);
|
||||
if (!str_copy) {
|
||||
return 0;
|
||||
}
|
||||
strcpy(str_copy, port_str);
|
||||
|
||||
/* 使用strtok(兼容性更好) */
|
||||
token = strtok(str_copy, ",");
|
||||
|
||||
while (token && count < max_ports) {
|
||||
char* dash = strchr(token, '-');
|
||||
|
||||
if (dash) {
|
||||
/* 处理范围 "start-end" */
|
||||
int start, end, i;
|
||||
*dash = '\0';
|
||||
start = atoi(token);
|
||||
end = atoi(dash + 1);
|
||||
|
||||
if (start > 0 && end > 0 && start <= end && end <= 65535) {
|
||||
for (i = start; i <= end && count < max_ports; i++) {
|
||||
ports[count++] = i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* 处理单个端口 */
|
||||
int port = atoi(token);
|
||||
if (port > 0 && port <= 65535) {
|
||||
ports[count++] = port;
|
||||
}
|
||||
}
|
||||
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
free(str_copy);
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* 简单的IP范围解析
|
||||
* 目前只支持单个IP,后续可扩展
|
||||
*/
|
||||
int parse_hosts(const char* host_str, char hosts[][MAX_HOST_LEN], int max_hosts) {
|
||||
if (!host_str || !hosts || max_hosts <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 目前简化实现:只处理单个主机 */
|
||||
if (strlen(host_str) < MAX_HOST_LEN) {
|
||||
strcpy(hosts[0], host_str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user