feat: add helpers to extract id and sequence from replies
This commit is contained in:
parent
29904cbec6
commit
84490efc8e
4 changed files with 172 additions and 0 deletions
|
|
@ -44,6 +44,10 @@ int icmp_send_echo(icmp_handle_t *h, struct in_addr dest, uint16_t id,
|
|||
int icmp_process(icmp_handle_t *h, icmp_callback_t cb, void *userdata,
|
||||
size_t max_packets);
|
||||
|
||||
/* ID/Sequence helpers */
|
||||
int icmp_reply_id_seq(const icmp_reply_t *reply, uint16_t *id,
|
||||
uint16_t *seq);
|
||||
|
||||
/* Error handling */
|
||||
const char *icmp_strerror(const icmp_handle_t *h);
|
||||
int icmp_should_retry(const icmp_handle_t *h);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ SRCS += $(SRC_DIR)/recv/core/receive_packet.c
|
|||
SRCS += $(SRC_DIR)/recv/core/parse_packet.c
|
||||
SRCS += $(SRC_DIR)/recv/core/process_single_packet.c
|
||||
SRCS += $(SRC_DIR)/recv/api/process.c
|
||||
SRCS += $(SRC_DIR)/recv/api/extract_id_seq.c
|
||||
|
||||
TESTS_DIR = tests
|
||||
TESTS += $(TESTS_DIR)/utils/test_checksum.c
|
||||
|
|
@ -50,3 +51,4 @@ TESTS += $(TESTS_DIR)/recv/test_build_reply.c
|
|||
TESTS += $(TESTS_DIR)/recv/test_receive_packet.c
|
||||
TESTS += $(TESTS_DIR)/recv/test_parse_packet.c
|
||||
TESTS += $(TESTS_DIR)/recv/test_process.c
|
||||
TESTS += $(TESTS_DIR)/recv/test_extract_id_seq.c
|
||||
|
|
|
|||
27
src/recv/api/extract_id_seq.c
Normal file
27
src/recv/api/extract_id_seq.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include <netinet/in.h>
|
||||
#include "icmp.h"
|
||||
#include "icmp_types.h"
|
||||
#include "internal/icmp_packet.h"
|
||||
|
||||
int
|
||||
icmp_reply_id_seq(const icmp_reply_t *reply, uint16_t *id, uint16_t *seq)
|
||||
{
|
||||
const struct icmp_header *hdr;
|
||||
|
||||
if (NULL == reply)
|
||||
return -1;
|
||||
if (reply->type != ICMP_TYPE_ECHO_REPLY &&
|
||||
reply->type != ICMP_TYPE_ECHO_REQUEST &&
|
||||
reply->type != ICMP_TYPE_TIMESTAMP_REPLY &&
|
||||
reply->type != ICMP_TYPE_TIMESTAMP_REQUEST)
|
||||
return -1;
|
||||
if (NULL == reply->ip_payload || reply->ip_payload_len < 8)
|
||||
return -1;
|
||||
|
||||
hdr = reply->ip_payload;
|
||||
if (NULL != id)
|
||||
*id = ntohs(hdr->un.echo.id);
|
||||
if (NULL != seq)
|
||||
*seq = ntohs(hdr->un.echo.seq);
|
||||
return 0;
|
||||
}
|
||||
139
tests/recv/test_extract_id_seq.c
Normal file
139
tests/recv/test_extract_id_seq.c
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include <string.h>
|
||||
#include "icmp.h"
|
||||
|
||||
static icmp_reply_t
|
||||
make_echo_reply(uint8_t type, uint16_t id, uint16_t seq, uint8_t *buffer)
|
||||
{
|
||||
icmp_reply_t reply;
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
memset(buffer, 0, 8);
|
||||
reply.type = type;
|
||||
reply.code = 0;
|
||||
buffer[0] = type;
|
||||
buffer[1] = 0;
|
||||
buffer[2] = 0;
|
||||
buffer[3] = 0;
|
||||
buffer[4] = (id >> 8) & 0xFF;
|
||||
buffer[5] = id & 0xFF;
|
||||
buffer[6] = (seq >> 8) & 0xFF;
|
||||
buffer[7] = seq & 0xFF;
|
||||
reply.ip_payload = buffer;
|
||||
reply.ip_payload_len = 8;
|
||||
return reply;
|
||||
}
|
||||
|
||||
Test(extract_echo, echo_reply_type_0)
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
icmp_reply_t reply = make_echo_reply(0, 0x1234, 0x5678, buffer);
|
||||
uint16_t id;
|
||||
uint16_t seq;
|
||||
int ret;
|
||||
|
||||
ret = icmp_reply_id_seq(&reply, &id, &seq);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(id, 0x1234);
|
||||
cr_assert_eq(seq, 0x5678);
|
||||
}
|
||||
|
||||
Test(extract_echo, echo_request_type_8)
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
icmp_reply_t reply = make_echo_reply(8, 0xABCD, 0xEF01, buffer);
|
||||
uint16_t id;
|
||||
uint16_t seq;
|
||||
int ret;
|
||||
|
||||
ret = icmp_reply_id_seq(&reply, &id, &seq);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(id, 0xABCD);
|
||||
cr_assert_eq(seq, 0xEF01);
|
||||
}
|
||||
|
||||
Test(extract_echo, non_echo_type_returns_error)
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
icmp_reply_t reply = make_echo_reply(3, 0x1234, 0x5678, buffer);
|
||||
uint16_t id = 0xFFFF;
|
||||
uint16_t seq = 0xFFFF;
|
||||
int ret;
|
||||
|
||||
ret = icmp_reply_id_seq(&reply, &id, &seq);
|
||||
cr_assert_eq(ret, -1);
|
||||
cr_assert_eq(id, 0xFFFF, "id should be unchanged on error");
|
||||
cr_assert_eq(seq, 0xFFFF, "seq should be unchanged on error");
|
||||
}
|
||||
|
||||
Test(extract_echo, null_reply_returns_error)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t seq;
|
||||
int ret;
|
||||
|
||||
ret = icmp_reply_id_seq(NULL, &id, &seq);
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
|
||||
Test(extract_echo, null_id_allowed)
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
icmp_reply_t reply = make_echo_reply(0, 0x1234, 0x5678, buffer);
|
||||
uint16_t seq;
|
||||
int ret;
|
||||
|
||||
ret = icmp_reply_id_seq(&reply, NULL, &seq);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(seq, 0x5678);
|
||||
}
|
||||
|
||||
Test(extract_echo, null_seq_allowed)
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
icmp_reply_t reply = make_echo_reply(0, 0x1234, 0x5678, buffer);
|
||||
uint16_t id;
|
||||
int ret;
|
||||
|
||||
ret = icmp_reply_id_seq(&reply, &id, NULL);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(id, 0x1234);
|
||||
}
|
||||
|
||||
Test(extract_echo, both_null_allowed)
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
icmp_reply_t reply = make_echo_reply(0, 0x1234, 0x5678, buffer);
|
||||
int ret;
|
||||
|
||||
ret = icmp_reply_id_seq(&reply, NULL, NULL);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
Test(extract_echo, payload_too_short_returns_error)
|
||||
{
|
||||
uint8_t buffer[8];
|
||||
icmp_reply_t reply = make_echo_reply(0, 0x1234, 0x5678, buffer);
|
||||
uint16_t id;
|
||||
uint16_t seq;
|
||||
int ret;
|
||||
|
||||
reply.ip_payload_len = 7;
|
||||
ret = icmp_reply_id_seq(&reply, &id, &seq);
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
|
||||
Test(extract_echo, null_ip_payload_returns_error)
|
||||
{
|
||||
icmp_reply_t reply;
|
||||
uint16_t id;
|
||||
uint16_t seq;
|
||||
int ret;
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
reply.type = 0;
|
||||
reply.ip_payload = NULL;
|
||||
reply.ip_payload_len = 8;
|
||||
ret = icmp_reply_id_seq(&reply, &id, &seq);
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue