Как пинговать с помощью сокетов C
В настоящее время я пытаюсь написать программу, которая будет читать текстовый файл, содержащий список IP-адресов и пинговать каждый IP-адрес соответственно. Если хост отвечает на эхо-запрос, IP-адрес хоста будет скопирован во второй файл, указанный пользователем. К сожалению, это первый раз, когда я использовал библиотеку сокетов C, и я не могу найти хороший учебник о том, как пинговать с помощью C. Из того, что я понимаю из пар, которые я нашел. Мне нужно включить заголовок ICMP, который представляет собой структуру, связывающую тип ICMP, код и контрольную сумму, в дейтаграмму IP. Но я понятия не имею, как это сделать, должен ли я объявить структуру самостоятельно или она объявлена в заголовочном файле? Я предполагаю, что это в заголовке, но учебники противоречили друг другу о том, где именно это объявлено. Я устал от включения 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));