wekknsie/IPK_Project1
GitHub: wekknsie/IPK_Project1
一个基于 C++ 实现的传输层网络扫描器,通过发送 TCP SYN 和 UDP 数据包来检测目标主机端口状态,适用于网络协议学习与端口探测实践。
Stars: 0 | Forks: 0
# IPK 项目
这是一个网络扫描器,工作在 OSI 模型的第四层,即传输层,用于检测指定网络设备上 TCP 和 UDP 端口的状态。
## TCP 描述
对于 TCP 协议,会发送一个带有 SYN 标志的数据包,并等待服务器的响应,以此来判断端口是开放还是关闭的。如果没有收到任何响应,我们将该端口视为被过滤。在与服务器建立连接的过程中,如果收到 SYN、ACK 数据包,我们就知道该端口的通信是开放的,随后内核会代表我们发送 RST 数据包以终止连接。如果收到的服务器响应是 RST 数据包,则说明该端口是关闭的。
## UDP 描述
对于 UDP,我们只能确定端口是开放还是关闭的。UDP 是一种无连接的协议,因此不会发送任何确认数据包。如果收到的响应是“*ICMP Port Unreachable*”,则说明端口是关闭的;但是,如果没有收到任何响应,那么端口可能是被过滤的或开放的,而我们会将其视为开放。
# 用法
## 测试
Makefile 中准备了一个用于演示程序功能的测试,可以通过命令 `make run` 来运行。
## 手动测试
扫描
`./ipk-l4-scan [-i interface | --interface interface] [--pu port-ranges | --pt port-ranges | -u port-ranges | -t port-ranges] {-w timeout} [hostname | ip-address]`
显示帮助信息
`./ipk-l4-scan --help`
列出可用接口
`./ipk-l4-scan --interface`
# 实现说明
程序分为几个部分,它们全部包含在单个文件 ipk-l4-scan.cpp 中。
## 主文件
### 参数
**argumentParser** 类负责处理输入参数的正确性。这里的所有变量都是私有的,通过 *get\[变量名]();* 函数进行访问。
### 获取本机 IP 地址
*getSourceIP()* 函数返回用于与 *target_ip* 建立目标连接的本地 IP 地址,但并不会真正建立连接。
### 将域名转换为 IPv4 地址
这由 *dnsLoopUp()* 函数处理,它接收 *hostname* 字符串并将其转换为 IPv4 地址。其工作原理是创建一个用于接收 DNS 服务器响应的结构体,随后带着指定的域名去查询该服务器;如果存在对应的 IP 地址解析,它就会从该结构体中提取出来并返回给我们。
### 发送 TCP 数据包
这部分负责使用 raw socket 手动构建并发送 TCP SYN 数据包,包括自行计算 TCP checksum。首先是用于计算 TCP checksum 的辅助结构体 *pseudo_header*。此计算还需要另一个函数 *checksum()*,它根据包头大小计算 16 位的校验和。主要函数是 *sendTcpSyn()*,它负责构建 TCP 头部,创建 pseudo-header,调用前面提到的 *checksum* 函数,最后利用 *sendto()* 函数将 SYN 数据包发送到指定的 IP 地址和端口。
### 发送 UDP 数据包
这部分代码负责将 UDP 数据包发送到指定的 IP 地址和端口。与发送 TCP 数据包不同,这里使用的是普通的 UDP socket,而不是 raw socket。
### 捕获数据包
数据包的捕获使用了 **libpcap** 库。*packetHandler* 函数用于处理接收到的数据包。首先,它会检查该端口的 timeout 是否已过期。接下来检查 TCP 响应,以判断端口是开放的(响应 SYN-ACK)还是关闭的(RST)。如果收到针对 UDP 数据包的 ICMP 响应,则意味着该端口已关闭。如果所有端口都已完成检测(无论是收到了响应还是超时),监听传入数据包的过程就会终止。
### 控制整个扫描过程
这由主函数 *main* 负责处理。首先解析参数,如果指定了 interface,则选择该网络接口;如果没有指定,则列出所有可用接口。接着设置 *ScanContext* 结构体,其中包含诸如 timeout 时长、被扫描的端口、目标主机的 IP 地址等数据。然后向指定的端口发送 TCP 和 UDP 数据包并监听传入的数据包。最后打印出端口扫描结果。
## Makefile
Makefile 的默认目标是 *cpp*。它使用 g++ 编译器并采用 C++20 标准。使用“make”命令将编译文件,而“make run”命令不仅会进行编译,还会运行测试命令——该命令会在域名为“server.datexo.cz”的主机上检查三个 TCP 端口和两个 UDP 端口,timeout 设置为 1 秒。
# 总结
## 依赖与许可
本程序使用了以下第三方库:
- libpcap – BSD 许可证 (https://www.tcpdump.org/)
- glibc – GNU LGPL(Linux 的常规组件)
- 标准 C++ 库 – 公共领域 / ISO
所有库均与 AGPL-3.0 兼容。
标签:C++, TCP, UDP, 插件系统, 数据擦除, 数据统计, 端口扫描, 网络工具, 网络扫描器