libicmp/src/send/api/raw.c
2026-03-19 02:43:46 +01:00

60 lines
1.4 KiB
C

#include <stddef.h>
#include "icmp.h"
#include "internal/icmp_internal.h"
#include "internal/icmp_packet_internal.h"
#include "internal/icmp_send.h"
/* MTU(1500) - IP header(20) - ICMP header(8) = 1472 */
#define MAX_PAYLOAD_SIZE 1472
#define ICMP_HEADER_SIZE 8
/* Forward declarations */
static int validate_payload(struct icmp_handle *h, const void *payload,
size_t len);
/* -------------------- */
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)
{
uint8_t buffer[ICMP_HEADER_SIZE + MAX_PAYLOAD_SIZE];
int packet_len;
if (0 == send_validate_handle(h))
return -1;
if (0 == validate_payload(h, payload, len))
return -1;
packet_len = icmp_build_packet(buffer, sizeof(buffer),
type, code, header_rest, payload, len);
if (-1 == packet_len)
{
icmp_set_error_fmt(h, ICMP_ERR_INVALID,
"Failed to build ICMP packet");
return -1;
}
return send_to_destination(h, buffer, (size_t)(packet_len), dest, ttl);
}
static int
validate_payload(struct icmp_handle *h, const void *payload, size_t len)
{
if (len > 0 && NULL == payload)
{
icmp_set_error_fmt(h, ICMP_ERR_INVALID, "Payload is NULL");
return 0;
}
if (len > MAX_PAYLOAD_SIZE)
{
icmp_set_error_fmt(h, ICMP_ERR_INVALID,
"Payload too large (max %d bytes)", MAX_PAYLOAD_SIZE);
return 0;
}
return 1;
}