summaryrefslogtreecommitdiff
path: root/seqnum_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'seqnum_server.c')
-rw-r--r--seqnum_server.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/seqnum_server.c b/seqnum_server.c
new file mode 100644
index 0000000..aa6ab42
--- /dev/null
+++ b/seqnum_server.c
@@ -0,0 +1,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;
+ }
+ }
+}