libicmp/src/packet/parse_icmp.c

54 lines
1.5 KiB
C

#include "internal/icmp_packet_internal.h"
#include "internal/icmp_packet.h"
#include <stdint.h>
/* ICMP header size */
#define ICMP_HEADER_SIZE 8
/* Forward declarations */
static int validate_icmp_size(size_t buffer_len, size_t ip_hdr_len);
static const struct icmp_header *get_icmp_header(const void *buffer,
size_t ip_hdr_len);
static void extract_icmp_fields(const struct icmp_header *hdr, uint8_t *type,
uint8_t *code);
/* -------------------- */
int
icmp_parse_icmp_payload(const void *buffer, size_t buffer_len,
size_t ip_hdr_len, uint8_t *type, uint8_t *code,
const void **payload, size_t *payload_len)
{
if (validate_icmp_size(buffer_len, ip_hdr_len) != 0)
return -1;
const struct icmp_header *hdr = get_icmp_header(buffer, ip_hdr_len);
extract_icmp_fields(hdr, type, code);
size_t payload_offset = ip_hdr_len + ICMP_HEADER_SIZE;
if (buffer_len < payload_offset)
return -1;
*payload_len = buffer_len - payload_offset;
*payload = (const uint8_t *)buffer + payload_offset;
return 0;
}
static int
validate_icmp_size(size_t buffer_len, size_t ip_hdr_len)
{
return (buffer_len >= (ip_hdr_len + ICMP_HEADER_SIZE)) ? 0 : -1;
}
static const struct icmp_header *
get_icmp_header(const void *buffer, size_t ip_hdr_len)
{
return (const struct icmp_header *)((const uint8_t *)buffer + ip_hdr_len);
}
static void
extract_icmp_fields(const struct icmp_header *hdr, uint8_t *type,
uint8_t *code)
{
*type = hdr->type;
*code = hdr->code;
}