44 lines
1.1 KiB
C
44 lines
1.1 KiB
C
#include "internal/icmp_packet_internal.h"
|
|
#include "internal/icmp_packet.h"
|
|
#include "internal/icmp_utils.h"
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <arpa/inet.h>
|
|
|
|
/* Forward declarations */
|
|
static void write_icmp_header(struct icmp_header *hdr, uint8_t type,
|
|
uint8_t code, uint32_t header_rest);
|
|
/* -------------------- */
|
|
|
|
int
|
|
icmp_build_packet(void *buffer, size_t buffer_len, uint8_t type, uint8_t code,
|
|
uint32_t header_rest, const void *payload,
|
|
size_t payload_len)
|
|
{
|
|
const size_t required_len = sizeof(struct icmp_header) + payload_len;
|
|
|
|
if (buffer_len < required_len)
|
|
return -1;
|
|
|
|
struct icmp_header *h = (struct icmp_header *)buffer;
|
|
|
|
write_icmp_header(h, type, code, header_rest);
|
|
if (payload_len > 0)
|
|
memcpy((uint8_t *)buffer + sizeof(struct icmp_header), payload,
|
|
payload_len);
|
|
|
|
h->checksum = htons(icmp_checksum(h, required_len));
|
|
|
|
return (int)required_len;
|
|
}
|
|
|
|
static void
|
|
write_icmp_header(struct icmp_header *hdr, uint8_t type, uint8_t code,
|
|
uint32_t header_rest)
|
|
{
|
|
hdr->type = type;
|
|
hdr->code = code;
|
|
hdr->checksum = 0; // will be computed later
|
|
hdr->un.gateway = header_rest;
|
|
}
|
|
|