#include #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; }