- 编译器:代码::块(GNU GCC)
- 平台:Windows(x86)
- 包括:winsock.h Winsock2.h(ws2_32 也已链接)
我目前正在尝试编写一个程序,该程序将读取包含 IP 地址列表的文本文件并分别 ping 每个 IP 地址。如果主机响应 ping,则主机的 IP 地址将被复制到用户指定的辅助文件中。不幸的是,这是我第一次使用 C 的套接字库,并且我找不到关于如何使用 C 进行 ping 操作的好教程。根据我对我找到的几个教程的了解。我需要在 IP 数据报中包含 ICMP 标头,它是一个包含 ICMP 类型、代码和校验和的结构。但我不知道如何去做,我应该自己声明该结构还是在头文件中声明它?我假设它位于标头中,但教程对于其声明的确切位置相互矛盾。我厌倦了包含 icmp.h 和 netinet/icmp.h 但我的编译器抱怨它们不存在,所以我创建了自己的结构。
struct echo_request
{
char type; // Type
char code; // Code
short checksum; // Checksum
short id; // Identification
short seq; // Sequence
int time; // Time
char data[16]; // Data
};
我以为我可能能够摆脱它,但我什至无法编译我的程序,因为我的编译器说 in_cksum()(校验和生成器)未定义。
总结一下我的问题,我应该包含哪些头文件,如何创建 ping 数据包,我是否使用了正确的校验和生成器函数,ping 是否应该定向到端口 80,以及我使用的套接字应该是 RAW 还是 DGRAM?
这是我到目前为止所做的,请注意,我故意省略了错误检查。
int socket_descriptor = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
struct sockaddr_in address; //Initialize address struct
memset(&address, 0, sizeof(address)); //Clear address struct
//Declare address
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ipaddress);
address.sin_port = htons(80);
//Bind socket to address
bind(socket_descriptor, (struct sockaddr *)&address, sizeof(address));
//Create packet
struct echo_request packet; //See above for declaration of struct
memset(packet.data, 1, 16);
packet.type = 8; //ECHO_REQUEST
packet.code = 0;
packet.time = gettime();
packet.checksum = 0;
packet.checksum = in_cksum(packet, sizeof(packet));