#include "internal/icmp_packet_internal.h" #include "internal/icmp_packet.h" #include #include #include #include /* Minimum IP header size */ #define MIN_IP_HEADER_SIZE 20 /* Forward declarations */ static int validate_ip_header(const struct ip_header *hdr, size_t buffer_len); 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 *dst_addr, uint8_t *protocol) { const struct ip_header *h; size_t ihl_bytes; if (buffer_len < MIN_IP_HEADER_SIZE) return -1; h = (const struct ip_header *)buffer; ihl_bytes = extract_ip_header_length(h->version_ihl); if (0 != validate_ip_header(h, buffer_len)) return -1; if (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; return 0; } static int validate_ip_header(const struct ip_header *hdr, size_t buffer_len) { uint8_t ihl; size_t header_len; if (4 != (hdr->version_ihl >> 4)) return -1; ihl = hdr->version_ihl & 0x0F; if (ihl < 5) return -1; header_len = (size_t)(ihl << 2); if (header_len > buffer_len) return -1; return 0; } static size_t extract_ip_header_length(uint8_t version_ihl) { return (size_t)((version_ihl & 0x0F) << 2); }