From bfd61e36362c6633062c417c678e2175856df764 Mon Sep 17 00:00:00 2001 From: lohhiiccc <96543753+lohhiiccc@users.noreply.github.com> Date: Tue, 27 Jan 2026 05:04:38 +0100 Subject: [PATCH] fix: use generic header_rest field instead of hardcoded id/seq --- includes/icmp.h | 1 + includes/internal/icmp_packet_internal.h | 2 +- src/packet/build.c | 11 +++++------ src/send/api/echo.c | 17 +++------------- src/send/api/raw.c | 3 ++- tests/packet/test_build.c | 25 +++++++++++++----------- tests/send/test_send_raw.c | 12 ++++++------ 7 files changed, 32 insertions(+), 39 deletions(-) diff --git a/includes/icmp.h b/includes/icmp.h index 5c36d3e..e745b5b 100644 --- a/includes/icmp.h +++ b/includes/icmp.h @@ -33,6 +33,7 @@ int icmp_get_fd(const icmp_handle_t *h); /* Send functions */ int icmp_send_raw(icmp_handle_t *h, uint8_t type, uint8_t code, + uint32_t header_rest, const void *payload, size_t len, struct in_addr dest, uint8_t ttl); diff --git a/includes/internal/icmp_packet_internal.h b/includes/internal/icmp_packet_internal.h index fca26ef..ec35333 100644 --- a/includes/internal/icmp_packet_internal.h +++ b/includes/internal/icmp_packet_internal.h @@ -6,7 +6,7 @@ #include int icmp_build_packet(void *buffer, size_t buffer_len, uint8_t type, - uint8_t code, uint16_t id, uint16_t seq, + uint8_t code, uint32_t header_rest, const void *payload, size_t payload_len); int icmp_parse_ip_header(const void *buffer, size_t buffer_len, diff --git a/src/packet/build.c b/src/packet/build.c index 280410e..40760cd 100644 --- a/src/packet/build.c +++ b/src/packet/build.c @@ -7,14 +7,14 @@ /* Forward declarations */ static void write_icmp_header(struct icmp_header *hdr, uint8_t type, - uint8_t code, uint16_t id, uint16_t seq); + uint8_t code, uint32_t header_rest); static void copy_payload(void *dest, const void *src, size_t len); static void compute_and_set_checksum(struct icmp_header *hdr, size_t total_len); /* -------------------- */ int icmp_build_packet(void *buffer, size_t buffer_len, uint8_t type, uint8_t code, - uint16_t id, uint16_t seq, const void *payload, + uint32_t header_rest, const void *payload, size_t payload_len) { const size_t required_len = sizeof(struct icmp_header) + payload_len; @@ -24,7 +24,7 @@ icmp_build_packet(void *buffer, size_t buffer_len, uint8_t type, uint8_t code, struct icmp_header *h = (struct icmp_header *)buffer; - write_icmp_header(h, type, code, id, seq); + write_icmp_header(h, type, code, header_rest); if (payload_len > 0) { copy_payload((unsigned char*)buffer + sizeof(struct icmp_header), @@ -38,13 +38,12 @@ icmp_build_packet(void *buffer, size_t buffer_len, uint8_t type, uint8_t code, static void write_icmp_header(struct icmp_header *hdr, uint8_t type, uint8_t code, - uint16_t id, uint16_t seq) + uint32_t header_rest) { hdr->type = type; hdr->code = code; hdr->checksum = 0; // will be computed later - hdr->un.echo.id = id; - hdr->un.echo.seq = seq; + hdr->un.gateway = header_rest; } static void diff --git a/src/send/api/echo.c b/src/send/api/echo.c index 2746e99..1c30bd3 100644 --- a/src/send/api/echo.c +++ b/src/send/api/echo.c @@ -2,10 +2,6 @@ #include "internal/icmp_send.h" #include "icmp_types.h" #include -#include - -/* ICMP echo header: type(1) + code(1) + checksum(2) + id(2) + seq(2) = 8 */ -#define ECHO_HEADER_SIZE 4 int icmp_send_echo(icmp_handle_t *h, struct in_addr dest, uint16_t id, @@ -14,15 +10,8 @@ icmp_send_echo(icmp_handle_t *h, struct in_addr dest, uint16_t id, if (0 == send_validate_handle(h)) return -1; - uint16_t id_net = htons(id); - uint16_t seq_net = htons(seq); - uint8_t payload[ECHO_HEADER_SIZE]; + uint32_t header_rest = (uint32_t)id | ((uint32_t)seq << 16); - payload[0] = (id_net >> 8) & 0xFF; - payload[1] = id_net & 0xFF; - payload[2] = (seq_net >> 8) & 0xFF; - payload[3] = seq_net & 0xFF; - - return icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, - payload, ECHO_HEADER_SIZE, dest, ttl); + return icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, header_rest, + NULL, 0, dest, ttl); } diff --git a/src/send/api/raw.c b/src/send/api/raw.c index a3b4184..8123dc7 100644 --- a/src/send/api/raw.c +++ b/src/send/api/raw.c @@ -15,6 +15,7 @@ static int validate_payload(struct icmp_handle *h, const void *payload, int icmp_send_raw(icmp_handle_t *h, uint8_t type, uint8_t code, + uint32_t header_rest, const void *payload, size_t len, struct in_addr dest, uint8_t ttl) { @@ -27,7 +28,7 @@ icmp_send_raw(icmp_handle_t *h, uint8_t type, uint8_t code, uint8_t buffer[MAX_PACKET_SIZE]; int packet_len = icmp_build_packet(buffer, sizeof(buffer), - type, code, 0, 0, payload, len); + type, code, header_rest, payload, len); if (-1 == packet_len) { icmp_set_error_fmt(h, ICMP_ERR_INVALID, diff --git a/tests/packet/test_build.c b/tests/packet/test_build.c index e0ff715..8047d07 100644 --- a/tests/packet/test_build.c +++ b/tests/packet/test_build.c @@ -1,5 +1,6 @@ #include #include +#include #include "internal/icmp_packet_internal.h" #include "internal/icmp_packet.h" #include "internal/icmp_utils.h" @@ -10,9 +11,10 @@ Test(packet_build, echo_request_no_payload) uint8_t type = 8, code = 0; uint16_t id = 0x1234; uint16_t seq = 0x0001; + uint32_t header_rest = (uint32_t)id | ((uint32_t)seq << 16); - int ret = icmp_build_packet(buffer, sizeof(buffer), type, code, id, seq, - NULL, 0); + int ret = icmp_build_packet(buffer, sizeof(buffer), type, code, + header_rest, NULL, 0); cr_assert_eq(ret, 8, "Expected packet size 8, got %d", ret); struct icmp_header *hdr = (struct icmp_header *)buffer; @@ -31,10 +33,10 @@ Test(packet_build, echo_request_with_payload) size_t payload_len = sizeof(payload) - 1; uint8_t buffer[8 + 5] = {0}; uint8_t type = 8, code = 0; - uint16_t id = 0xabcd, seq = 0x1234; + uint32_t header_rest = (uint32_t)0xabcd | ((uint32_t)0x1234 << 16); - int ret = icmp_build_packet(buffer, sizeof(buffer), type, code, id, seq, - payload, payload_len); + int ret = icmp_build_packet(buffer, sizeof(buffer), type, code, + header_rest, payload, payload_len); cr_assert_eq(ret, 13, "Expected packet size 13, got %d", ret); cr_assert(memcmp(buffer + 8, payload, 5) == 0, @@ -45,12 +47,12 @@ Test(packet_build, checksum_correct) { uint8_t buffer[16] = {0}; uint8_t type = 8, code = 0; - uint16_t id = 0x77aa, seq = 0x0033; + uint32_t header_rest = (uint32_t)0x77aa | ((uint32_t)0x0033 << 16); const char payload[] = "ABC"; size_t payload_len = 3; - int ret = icmp_build_packet(buffer, sizeof(buffer), type, code, id, seq, - payload, payload_len); + int ret = icmp_build_packet(buffer, sizeof(buffer), type, code, + header_rest, payload, payload_len); cr_assert_eq(ret, 11, "Expected packet size 11, got %d", ret); struct icmp_header *hdr = (struct icmp_header *)buffer; @@ -58,16 +60,17 @@ Test(packet_build, checksum_correct) hdr->checksum = 0; uint16_t checksum = icmp_checksum(buffer, ret); hdr->checksum = old_checksum; - cr_assert_eq(old_checksum, checksum, + cr_assert_eq(ntohs(old_checksum), checksum, "Checksum in packet (%04x) does not match recomputed one (%04x)", - old_checksum, checksum); + ntohs(old_checksum), checksum); } Test(packet_build, buffer_too_small) { uint8_t buf[4]; const char payload[8] = "ABCDEFG"; - int ret = icmp_build_packet(buf, sizeof(buf), 8, 0, 0x1111, 0x2222, + uint32_t header_rest = (uint32_t)0x1111 | ((uint32_t)0x2222 << 16); + int ret = icmp_build_packet(buf, sizeof(buf), 8, 0, header_rest, payload, 8); cr_assert_eq(ret, -1, "Expected -1 for too small buffer, got %d", ret); } diff --git a/tests/send/test_send_raw.c b/tests/send/test_send_raw.c index 424526c..ef3bf96 100644 --- a/tests/send/test_send_raw.c +++ b/tests/send/test_send_raw.c @@ -20,7 +20,7 @@ Test(send_raw, simple_packet) struct in_addr dest; dest.s_addr = inet_addr("127.0.0.1"); - int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, NULL, 0, dest, 64); + int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, 0, NULL, 0, dest, 64); cr_assert_eq(ret, 0, "Expected success (0)"); cr_assert_str_eq(icmp_strerror(h), "No error"); @@ -43,7 +43,7 @@ Test(send_raw, with_payload) dest.s_addr = inet_addr("127.0.0.1"); const char payload[] = "HELLO"; - int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, + int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, 0, payload, 5, dest, 64); cr_assert_eq(ret, 0, "Expected success (0)"); @@ -58,7 +58,7 @@ Test(send_raw, null_handle) struct in_addr dest; dest.s_addr = inet_addr("127.0.0.1"); - int ret = icmp_send_raw(NULL, ICMP_TYPE_ECHO_REQUEST, 0, + int ret = icmp_send_raw(NULL, ICMP_TYPE_ECHO_REQUEST, 0, 0, NULL, 0, dest, 64); cr_assert_eq(ret, -1, "Expected -1 for NULL handle"); @@ -78,7 +78,7 @@ Test(send_raw, null_payload_with_length) struct in_addr dest; dest.s_addr = inet_addr("127.0.0.1"); - int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, + int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, 0, NULL, 10, dest, 64); cr_assert_eq(ret, -1, "Expected -1 for NULL payload with len > 0"); @@ -107,7 +107,7 @@ Test(send_raw, payload_too_large) uint8_t large_payload[2000]; memset(large_payload, 0xAA, sizeof(large_payload)); - int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, + int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, 0, large_payload, sizeof(large_payload), dest, 64); cr_assert_eq(ret, -1, "Expected -1 for payload too large"); @@ -130,7 +130,7 @@ Test(send_raw, invalid_fd) struct in_addr dest; dest.s_addr = inet_addr("127.0.0.1"); - int ret = icmp_send_raw((icmp_handle_t *)&h, ICMP_TYPE_ECHO_REQUEST, 0, + int ret = icmp_send_raw((icmp_handle_t *)&h, ICMP_TYPE_ECHO_REQUEST, 0, 0, NULL, 0, dest, 64); cr_assert_eq(ret, -1, "Expected -1 for invalid FD");