From d179a5b469d609a7c7f15d841dfb95fe77b3125e Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Mon, 4 Nov 2019 12:24:08 +0100 Subject: Seqnum server --- .gitignore | 3 +-- Makefile | 2 +- run_server.sh | 19 ++++++++++++++++- seqnum_server.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 seqnum_server.c diff --git a/.gitignore b/.gitignore index 21c78dc..a781ccc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ *.o client server -clientd -serverd +seqnum_server bak/ diff --git a/Makefile b/Makefile index 1e2834c..b63a27b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC = gcc CFLAGS = -Wall -Wextra -O2 -g -std=c11 -fwrapv -pthread LDFLAGS = -pthread -TARGETS = server client +TARGETS = server client seqnum_server SOURCES = $(filter-out $(patsubst %,%.c,$(TARGETS)),$(wildcard *.c)) OBJECTS = $(patsubst %.c,%.o,$(SOURCES)) diff --git a/run_server.sh b/run_server.sh index e6beee9..c3e9759 100755 --- a/run_server.sh +++ b/run_server.sh @@ -1,9 +1,26 @@ #!/usr/bin/env bash +set -euo pipefail + if [[ "$(id -u)" -ne 0 ]]; then echo >&2 "Run with sudo" exit 1 fi +if [[ $# -eq 0 ]]; then + server_exec=./server +elif [[ $# -eq 1 ]]; then + server_exec="$1" +else + echo >&2 "Usage: $0 [server executable]" + echo >&2 "By default runs ./server" + exit 1 +fi + +if [[ ! -x "$server_exec" ]]; then + echo >&2 "Cannot execute server executable $server_exec" + exit 1 +fi + echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all trap "echo 0 >/proc/sys/net/ipv4/icmp_echo_ignore_all" EXIT -./serverd +"$server_exec" 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 +#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; + } + } +} -- cgit v1.2.3