#define _GNU_SOURCE #include #include #include #include "icmp_server.h" #include "util.h" static const uint8_t* detect_payload(const uint8_t *data, size_t length) { // Detects the 16-byte "padding" payload one can send using the ping(1) utility. // This payload starts at byte 16 and repeats thereafter. if (length < 32) return NULL; // For each byte in the padding for (size_t i = 0; i < 16; i++) { // For each repetition for (size_t j = 1; 16 + 16 * j + i < length; j++) { // Assert that the padding indeed repeats if (data[16 + i] != data[16 + 16 * j + i]) return NULL; } } return data + 16; } int main() { int sock = icmp_server_open_socket(); if (sock < 0) { perror("socket (icmp_server_open_socket)"); return 1; } while (true) { struct icmp_incoming pkt = icmp_server_receive(sock); if (pkt.data == NULL) { perror("recvmsg (icmp_server_receive)"); usleep(500000); continue; } // xxd(stderr, pkt.data, pkt.length); const uint8_t *payload = detect_payload(pkt.data, pkt.length); if (payload != NULL) { printf("payl"); fwrite(&pkt.source_addr, 1, 4, stdout); fwrite(payload, 1, 16, stdout); fflush(stdout); uint16_t new_seqnum; if (readall(STDIN_FILENO, &new_seqnum, 2) < 0) { perror("read"); new_seqnum = pkt.seqnum; } pkt.seqnum = new_seqnum; } else { fprintf(stderr, "Echoing packet due to invalid payload\n"); } int ret = icmp_server_send_reply(sock, pkt.source_addr, pkt.id, pkt.seqnum, pkt.data, pkt.length); if (ret < 0) { perror("sendto (icmp_server_send_reply)"); usleep(500000); continue; } } }