libicmp/tests/send/test_send_raw.c
2026-01-26 20:14:11 +01:00

140 lines
3.3 KiB
C

#include <criterion/criterion.h>
#include <string.h>
#include <arpa/inet.h>
#include "icmp.h"
#include "internal/icmp_internal.h"
#include "icmp_types.h"
#include "test_helpers.h"
/* Test 1: Send simple ICMP packet (type 8, no payload) */
Test(send_raw, simple_packet)
{
if (0 == has_net_raw_capability())
{
cr_skip("Test requires CAP_NET_RAW or root privileges");
}
icmp_handle_t *h = icmp_create();
cr_assert_not_null(h);
struct in_addr dest;
dest.s_addr = inet_addr("127.0.0.1");
int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0, NULL, 0, dest, 64);
cr_assert_eq(ret, 0, "Expected success (0)");
cr_assert_str_eq(icmp_strerror(h), "No error");
icmp_destroy(h);
}
/* Test 2: Send packet with payload */
Test(send_raw, with_payload)
{
if (0 == has_net_raw_capability())
{
cr_skip("Test requires CAP_NET_RAW or root privileges");
}
icmp_handle_t *h = icmp_create();
cr_assert_not_null(h);
struct in_addr dest;
dest.s_addr = inet_addr("127.0.0.1");
const char payload[] = "HELLO";
int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0,
payload, 5, dest, 64);
cr_assert_eq(ret, 0, "Expected success (0)");
cr_assert_str_eq(icmp_strerror(h), "No error");
icmp_destroy(h);
}
/* Test 3: NULL handle returns -1 */
Test(send_raw, null_handle)
{
struct in_addr dest;
dest.s_addr = inet_addr("127.0.0.1");
int ret = icmp_send_raw(NULL, ICMP_TYPE_ECHO_REQUEST, 0,
NULL, 0, dest, 64);
cr_assert_eq(ret, -1, "Expected -1 for NULL handle");
}
/* Test 4: NULL payload with len > 0 returns -1 */
Test(send_raw, null_payload_with_length)
{
if (0 == has_net_raw_capability())
{
cr_skip("Test requires CAP_NET_RAW or root privileges");
}
icmp_handle_t *h = icmp_create();
cr_assert_not_null(h);
struct in_addr dest;
dest.s_addr = inet_addr("127.0.0.1");
int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0,
NULL, 10, dest, 64);
cr_assert_eq(ret, -1, "Expected -1 for NULL payload with len > 0");
const char *err = icmp_strerror(h);
cr_assert(NULL != strstr(err, "Payload") || NULL != strstr(err, "NULL"),
"Error message should mention payload or NULL");
icmp_destroy(h);
}
/* Test 5: Payload too large returns -1 */
Test(send_raw, payload_too_large)
{
if (0 == has_net_raw_capability())
{
cr_skip("Test requires CAP_NET_RAW or root privileges");
}
icmp_handle_t *h = icmp_create();
cr_assert_not_null(h);
struct in_addr dest;
dest.s_addr = inet_addr("127.0.0.1");
uint8_t large_payload[2000];
memset(large_payload, 0xAA, sizeof(large_payload));
int ret = icmp_send_raw(h, ICMP_TYPE_ECHO_REQUEST, 0,
large_payload, sizeof(large_payload), dest, 64);
cr_assert_eq(ret, -1, "Expected -1 for payload too large");
const char *err = icmp_strerror(h);
cr_assert(NULL != strstr(err, "large") || NULL != strstr(err, "too"),
"Error message should mention 'large' or 'too'");
icmp_destroy(h);
}
/* Test 6: Invalid FD returns -1 */
Test(send_raw, invalid_fd)
{
struct icmp_handle h = {0};
h.fd = -1;
h.last_error = ICMP_OK;
h.error_msg[0] = '\0';
struct in_addr dest;
dest.s_addr = inet_addr("127.0.0.1");
int ret = icmp_send_raw((icmp_handle_t *)&h, ICMP_TYPE_ECHO_REQUEST, 0,
NULL, 0, dest, 64);
cr_assert_eq(ret, -1, "Expected -1 for invalid FD");
cr_assert(NULL != strstr(h.error_msg, "Invalid") ||
NULL != strstr(h.error_msg, "socket"),
"Error message should mention 'Invalid' or 'socket'");
}