diff options
author | Tom Smeding <tom.smeding@gmail.com> | 2019-11-04 12:24:08 +0100 |
---|---|---|
committer | Tom Smeding <tom.smeding@gmail.com> | 2019-11-05 10:32:41 +0100 |
commit | d179a5b469d609a7c7f15d841dfb95fe77b3125e (patch) | |
tree | b630dffabe6cfd70a975cd57b4044291b897fdf1 | |
parent | fa1ae45491a8e41ccde4e0b366c37ec2a067bae9 (diff) |
Seqnum server
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | run_server.sh | 19 | ||||
-rw-r--r-- | seqnum_server.c | 66 |
4 files changed, 86 insertions, 4 deletions
@@ -1,7 +1,6 @@ *.o client server -clientd -serverd +seqnum_server bak/ @@ -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 <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; + } + } +} |