- Added `icmp_create`. - Added `icmp_destroy`. - Added `icmp_get_fd`. - Added unit tests.
97 lines
2 KiB
C
97 lines
2 KiB
C
#include <criterion/criterion.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include "icmp.h"
|
|
#include "internal/icmp_internal.h"
|
|
|
|
/* Helper: check if we have CAP_NET_RAW capability */
|
|
static int
|
|
has_net_raw_capability(void)
|
|
{
|
|
icmp_handle_t *h = icmp_create();
|
|
|
|
if (NULL != h)
|
|
{
|
|
icmp_destroy(h);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Test 1: icmp_create() success (skip without privileges) */
|
|
Test(handle, create_success)
|
|
{
|
|
icmp_handle_t *h = icmp_create();
|
|
|
|
if (NULL == h)
|
|
{
|
|
cr_skip("Test requires CAP_NET_RAW or root privileges");
|
|
}
|
|
|
|
cr_assert_not_null(h, "icmp_create() returned NULL");
|
|
|
|
/* Verify FD is valid */
|
|
int fd = icmp_get_fd(h);
|
|
cr_assert_geq(fd, 0, "Expected valid file descriptor");
|
|
|
|
/* Verify no error */
|
|
const char *err = icmp_strerror(h);
|
|
cr_assert_str_eq(err, "No error");
|
|
|
|
icmp_destroy(h);
|
|
}
|
|
|
|
/* Test 2: icmp_create() returns NULL without privileges */
|
|
Test(handle, create_without_privileges)
|
|
{
|
|
icmp_handle_t *h = icmp_create();
|
|
|
|
if (NULL != h)
|
|
{
|
|
icmp_destroy(h);
|
|
cr_skip("Test requires missing CAP_NET_RAW");
|
|
}
|
|
|
|
cr_assert_null(h, "Expected NULL without privileges");
|
|
}
|
|
|
|
/* Test 3: icmp_create() sets non-blocking mode */
|
|
Test(handle, create_nonblocking)
|
|
{
|
|
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);
|
|
|
|
int fd = icmp_get_fd(h);
|
|
int flags = fcntl(fd, F_GETFL, 0);
|
|
|
|
cr_assert(flags & O_NONBLOCK, "Socket should be non-blocking");
|
|
|
|
icmp_destroy(h);
|
|
}
|
|
|
|
/* Test 4: icmp_create() initializes handle properly */
|
|
Test(handle, create_initializes_handle)
|
|
{
|
|
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 icmp_handle *handle = (struct icmp_handle *)h;
|
|
|
|
cr_assert_geq(handle->fd, 0, "FD should be valid");
|
|
cr_assert_eq(handle->last_error, ICMP_OK, "Error should be ICMP_OK");
|
|
cr_assert_eq(handle->error_msg[0], '\0',
|
|
"Error message should be empty");
|
|
|
|
icmp_destroy(h);
|
|
}
|