From ace00ea0f2d530fc7c9dc3905ead217c5104bcb2 Mon Sep 17 00:00:00 2001 From: lohhiiccc <96543753+lohhiiccc@users.noreply.github.com> Date: Sun, 1 Feb 2026 01:47:02 +0100 Subject: [PATCH] feat: rework icmp_parse_ip_header Extend icmp_parse_ip_header to allow optional extraction of destination IP address and protocol from the IP header --- includes/internal/icmp_packet_internal.h | 3 +- src/packet/parse_ip.c | 7 +- src/recv/core/parse_packet.c | 2 +- tests/packet/test_parse_ip.c | 88 ++++++++++++++++++++++-- 4 files changed, 92 insertions(+), 8 deletions(-) diff --git a/includes/internal/icmp_packet_internal.h b/includes/internal/icmp_packet_internal.h index ec35333..801d2a5 100644 --- a/includes/internal/icmp_packet_internal.h +++ b/includes/internal/icmp_packet_internal.h @@ -11,7 +11,8 @@ int icmp_build_packet(void *buffer, size_t buffer_len, uint8_t type, int icmp_parse_ip_header(const void *buffer, size_t buffer_len, uint8_t *ttl, struct in_addr *src_addr, - size_t *ip_hdr_len); + size_t *ip_hdr_len, struct in_addr *dst_addr, + uint8_t *protocol); int icmp_parse_icmp_payload(const void *buffer, size_t buffer_len, size_t ip_hdr_len, uint8_t *type, uint8_t *code, diff --git a/src/packet/parse_ip.c b/src/packet/parse_ip.c index 0a1c49d..c0a9dec 100644 --- a/src/packet/parse_ip.c +++ b/src/packet/parse_ip.c @@ -15,7 +15,8 @@ static size_t extract_ip_header_length(uint8_t version_ihl); int icmp_parse_ip_header(const void *buffer, size_t buffer_len, uint8_t *ttl, - struct in_addr *src_addr, size_t *ip_hdr_len) + struct in_addr *src_addr, size_t *ip_hdr_len, + struct in_addr *dst_addr, uint8_t *protocol) { if (buffer_len < MIN_IP_HEADER_SIZE) return -1; @@ -30,6 +31,10 @@ icmp_parse_ip_header(const void *buffer, size_t buffer_len, uint8_t *ttl, *ttl = h->ttl; if (src_addr) src_addr->s_addr = h->saddr; + if (dst_addr) + dst_addr->s_addr = h->daddr; + if (protocol) + *protocol = h->protocol; if (ip_hdr_len) *ip_hdr_len = ihl_bytes; diff --git a/src/recv/core/parse_packet.c b/src/recv/core/parse_packet.c index d5d1e70..1ed665e 100644 --- a/src/recv/core/parse_packet.c +++ b/src/recv/core/parse_packet.c @@ -9,7 +9,7 @@ recv_parse_packet(const void *buffer, size_t buffer_len, size_t *ip_hdr_len) { if (icmp_parse_ip_header(buffer, buffer_len, ttl, src_addr, - ip_hdr_len) < 0) + ip_hdr_len, NULL, NULL) < 0) return -1; if (icmp_parse_icmp_payload(buffer, buffer_len, *ip_hdr_len, diff --git a/tests/packet/test_parse_ip.c b/tests/packet/test_parse_ip.c index f225ef1..b3508de 100644 --- a/tests/packet/test_parse_ip.c +++ b/tests/packet/test_parse_ip.c @@ -17,7 +17,7 @@ Test(packet_parse_ip, valid_header) size_t ip_hdr_len = 0; int ret = icmp_parse_ip_header(buffer, sizeof(buffer), &ttl, &src_addr, - &ip_hdr_len); + &ip_hdr_len, NULL, NULL); cr_assert_eq(ret, 0, "Should return 0 for valid IP header"); cr_assert_eq(ttl, 64, "TTL should be 64"); @@ -39,7 +39,7 @@ Test(packet_parse_ip, extract_ttl) size_t ip_hdr_len = 0; int ret = icmp_parse_ip_header(buffer, sizeof(buffer), &ttl, &src_addr, - &ip_hdr_len); + &ip_hdr_len, NULL, NULL); cr_assert_eq(ret, 0, "Should return 0 for valid header"); cr_assert_eq(ttl, 128, "TTL should be 128"); @@ -58,7 +58,7 @@ Test(packet_parse_ip, extract_source_addr) size_t ip_hdr_len = 0; int ret = icmp_parse_ip_header(buffer, sizeof(buffer), &ttl, &src_addr, - &ip_hdr_len); + &ip_hdr_len, NULL, NULL); cr_assert_eq(ret, 0, "Should return 0 for valid header"); cr_assert_eq(src_addr.s_addr, inet_addr("8.8.8.8"), @@ -73,7 +73,7 @@ Test(packet_parse_ip, buffer_too_small) size_t ip_hdr_len = 0; int ret = icmp_parse_ip_header(buffer, sizeof(buffer), &ttl, &src_addr, - &ip_hdr_len); + &ip_hdr_len, NULL, NULL); cr_assert_eq(ret, -1, "Should return -1 when buffer is too small"); } @@ -91,6 +91,84 @@ Test(packet_parse_ip, invalid_version) size_t ip_hdr_len = 0; int ret = icmp_parse_ip_header(buffer, sizeof(buffer), &ttl, &src_addr, - &ip_hdr_len); + &ip_hdr_len, NULL, NULL); cr_assert_eq(ret, -1, "Should return -1 for invalid IP version"); } + +Test(packet_parse_ip, extract_dest_addr) +{ + uint8_t buffer[20] = {0}; + struct ip_header *hdr = (struct ip_header*)buffer; + hdr->version_ihl = 0x45; + hdr->ttl = 64; + hdr->saddr = inet_addr("192.168.1.1"); + hdr->daddr = inet_addr("8.8.8.8"); + + struct in_addr dst_addr = {0}; + + int ret = icmp_parse_ip_header(buffer, sizeof(buffer), NULL, NULL, + NULL, &dst_addr, NULL); + + cr_assert_eq(ret, 0, "Should return 0 for valid header"); + cr_assert_eq(dst_addr.s_addr, inet_addr("8.8.8.8"), + "Destination address should match 8.8.8.8"); +} + +Test(packet_parse_ip, extract_protocol) +{ + uint8_t buffer[20] = {0}; + struct ip_header *hdr = (struct ip_header*)buffer; + hdr->version_ihl = 0x45; + hdr->ttl = 64; + hdr->protocol = 1; // ICMP + + uint8_t protocol = 0; + + int ret = icmp_parse_ip_header(buffer, sizeof(buffer), NULL, NULL, + NULL, NULL, &protocol); + + cr_assert_eq(ret, 0, "Should return 0 for valid header"); + cr_assert_eq(protocol, 1, "Protocol should be 1 (ICMP)"); +} + +Test(packet_parse_ip, extract_all_fields) +{ + uint8_t buffer[20] = {0}; + struct ip_header *hdr = (struct ip_header*)buffer; + hdr->version_ihl = 0x45; + hdr->ttl = 128; + hdr->saddr = inet_addr("10.0.0.1"); + hdr->daddr = inet_addr("10.0.0.2"); + hdr->protocol = 6; // TCP + + uint8_t ttl = 0; + struct in_addr src_addr = {0}; + struct in_addr dst_addr = {0}; + uint8_t protocol = 0; + size_t ip_hdr_len = 0; + + int ret = icmp_parse_ip_header(buffer, sizeof(buffer), &ttl, &src_addr, + &ip_hdr_len, &dst_addr, &protocol); + + cr_assert_eq(ret, 0, "Should return 0 for valid header"); + cr_assert_eq(ttl, 128, "TTL should be 128"); + cr_assert_eq(src_addr.s_addr, inet_addr("10.0.0.1"), + "Source address should match"); + cr_assert_eq(dst_addr.s_addr, inet_addr("10.0.0.2"), + "Destination address should match"); + cr_assert_eq(protocol, 6, "Protocol should be 6 (TCP)"); + cr_assert_eq(ip_hdr_len, 20, "Header length should be 20"); +} + +Test(packet_parse_ip, null_parameters_allowed) +{ + uint8_t buffer[20] = {0}; + struct ip_header *hdr = (struct ip_header*)buffer; + hdr->version_ihl = 0x45; + hdr->ttl = 64; + + int ret = icmp_parse_ip_header(buffer, sizeof(buffer), NULL, NULL, + NULL, NULL, NULL); + + cr_assert_eq(ret, 0, "Should return 0 even with all NULL parameters"); +}