- 编译器:代码::块(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。
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()(checksum generator) 是未定义的。
总结一下我的问题,我应该包含哪些头文件,如何创建 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));