60 lines
1.4 KiB
C
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;
|
|
}
|