1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#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;
}
}
}
|