54 lines
1.5 KiB
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;
|
|
}
|