feat(error): add ICMP error utilities with tests

- Added `icmp_set_error`.
 - Added `icmp_strerror`.
 - Added unit tests.
This commit is contained in:
lohhiiccc 2026-01-24 22:33:36 +01:00
parent 2e509336c7
commit 532c4b5dc7
7 changed files with 160 additions and 0 deletions

47
includes/icmp.h Normal file
View file

@ -0,0 +1,47 @@
#ifndef ICMP_H
#define ICMP_H
#include <stdint.h>
#include <stddef.h>
#include <netinet/in.h>
#include <time.h>
/* Opaque handle type */
typedef struct icmp_handle icmp_handle_t;
/* Reply structure passed to callback */
typedef struct icmp_reply {
uint8_t type;
uint8_t code;
struct in_addr from;
uint8_t ttl;
struct timespec timestamp;
void *payload;
size_t payload_len;
void *ip_payload;
size_t ip_payload_len;
} icmp_reply_t;
/* Callback type for received packets */
typedef void (*icmp_callback_t)(const icmp_reply_t *reply, void *userdata);
/* Handle lifecycle */
icmp_handle_t *icmp_create(void);
void icmp_destroy(icmp_handle_t *h);
int icmp_get_fd(const icmp_handle_t *h);
/* Send functions */
int icmp_send_raw(icmp_handle_t *h, uint8_t type, uint8_t code,
const void *payload, size_t len, struct in_addr dest,
uint8_t ttl);
int icmp_send_echo(icmp_handle_t *h, struct in_addr dest, uint16_t id,
uint16_t seq, uint8_t ttl);
/* Receive function */
int icmp_process(icmp_handle_t *h, icmp_callback_t cb, void *userdata);
/* Error handling */
const char *icmp_strerror(const icmp_handle_t *h);
#endif /* ICMP_H */

View file

@ -0,0 +1,23 @@
#ifndef ICMP_INTERNAL_H
#define ICMP_INTERNAL_H
/* Internal handle structure */
struct icmp_handle {
int fd;
int last_error;
char error_msg[256];
};
/* Error codes */
#define ICMP_OK 0
#define ICMP_ERR_PERMISSION -1
#define ICMP_ERR_SOCKET -2
#define ICMP_ERR_SEND -3
#define ICMP_ERR_RECV -4
#define ICMP_ERR_INVALID -5
#define ICMP_ERR_ENOMEM -6
/* Internal error handling functions */
void icmp_set_error(struct icmp_handle *h, int code, const char *msg);
#endif

View file

13
src/error/set_error.c Normal file
View file

@ -0,0 +1,13 @@
#include "internal/icmp_internal.h"
#include <stdio.h>
void
icmp_set_error(struct icmp_handle *h, int code, const char *msg)
{
h->last_error = code;
if (NULL != msg)
snprintf(h->error_msg, sizeof(h->error_msg), "%s", msg);
else
h->error_msg[0] = '\0';
}

19
src/error/strerror.c Normal file
View file

@ -0,0 +1,19 @@
#include "icmp.h"
#include "internal/icmp_internal.h"
const char *
icmp_strerror(const icmp_handle_t *h)
{
const struct icmp_handle *handle = (const struct icmp_handle *)h;
if (NULL == handle)
return "Invalid handle";
if (ICMP_OK == handle->last_error)
return "No error";
if ('\0' == handle->error_msg[0])
return "Unknown error";
return handle->error_msg;
}

View file

58
tests/error/test_error.c Normal file
View file

@ -0,0 +1,58 @@
#include <criterion/criterion.h>
#include <string.h>
#include "internal/icmp_internal.h"
#include "icmp.h"
/* Test 1: set_error sets code and message */
Test(error, set_error_basic)
{
struct icmp_handle h = {0};
icmp_set_error(&h, ICMP_ERR_SOCKET, "Test error message");
cr_assert_eq(h.last_error, ICMP_ERR_SOCKET);
cr_assert_str_eq(h.error_msg, "Test error message");
}
/* Test 3: set_error with NULL message clears error_msg */
Test(error, set_error_null_message)
{
struct icmp_handle h = {0};
strcpy(h.error_msg, "Old error");
icmp_set_error(&h, ICMP_ERR_SEND, NULL);
cr_assert_eq(h.last_error, ICMP_ERR_SEND);
cr_assert_eq(h.error_msg[0], '\0');
}
/* Test 4: strerror returns message from handle */
Test(error, strerror_returns_message)
{
struct icmp_handle h = {0};
h.last_error = ICMP_ERR_PERMISSION;
strcpy(h.error_msg, "Permission denied");
const char *msg = icmp_strerror((icmp_handle_t *)&h);
cr_assert_str_eq(msg, "Permission denied");
}
/* Test 5: strerror with NULL handle */
Test(error, strerror_null_handle)
{
const char *msg = icmp_strerror(NULL);
cr_assert_str_eq(msg, "Invalid handle");
}
/* Test 6: strerror with ICMP_OK */
Test(error, strerror_no_error)
{
struct icmp_handle h = {0};
h.last_error = ICMP_OK;
const char *msg = icmp_strerror((icmp_handle_t *)&h);
cr_assert_str_eq(msg, "No error");
}