140 lines
3.3 KiB
C
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'");
|
|
}
|