Compare commits
4 commits
71ca9abc2e
...
ac9ca93d9f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac9ca93d9f | ||
|
|
812e3a0ed5 | ||
|
|
70988a801f | ||
|
|
23c5256c76 |
8 changed files with 69 additions and 18 deletions
2
LICENSE
2
LICENSE
|
|
@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
|
|||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
libicmp Copyright (C) 2026 lohhiiccc
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
|
|
|||
19
README.md
19
README.md
|
|
@ -1,7 +1,7 @@
|
|||
# libicmp
|
||||
|
||||
Non-blocking ICMPv4 library for building ping, traceroute, and network
|
||||
diagnostic tools.
|
||||
ICMPv4 library for building ping, traceroute, and network diagnostic tools.
|
||||
Supports both non-blocking (default) and blocking socket modes.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
|
@ -28,12 +28,14 @@ make test
|
|||
|
||||
```c
|
||||
icmp_handle_t *icmp_create(void);
|
||||
icmp_handle_t *icmp_create_block(void);
|
||||
void icmp_destroy(icmp_handle_t *h);
|
||||
int icmp_get_fd(const icmp_handle_t *h);
|
||||
```
|
||||
|
||||
`icmp_create()` opens a raw ICMP socket and returns an opaque handle.
|
||||
`icmp_get_fd()` exposes the underlying file descriptor for use with
|
||||
`icmp_create()` opens a raw ICMP socket in non-blocking mode and returns an
|
||||
opaque handle. `icmp_create_block()` does the same but leaves the socket in
|
||||
blocking mode`icmp_get_fd()` exposes the underlying file descriptor for use with
|
||||
`select()` or `poll()`. Errors are retrieved via `icmp_strerror()`.
|
||||
|
||||
### Send
|
||||
|
|
@ -71,12 +73,13 @@ on error.
|
|||
## Modules
|
||||
|
||||
### handle/
|
||||
Handle lifecycle: `icmp_create()`, `icmp_destroy()`, `icmp_get_fd()`.
|
||||
Owns the opaque `icmp_handle_t` struct and the error state attached to it.
|
||||
Handle lifecycle: `icmp_create()`, `icmp_create_block()`, `icmp_destroy()`,
|
||||
`icmp_get_fd()`. Owns the opaque `icmp_handle_t` struct and the error state
|
||||
attached to it.
|
||||
|
||||
### socket/
|
||||
Raw socket creation, non-blocking configuration, and the DF (Don't
|
||||
Fragment) flag via `IP_MTU_DISCOVER`.
|
||||
Raw socket creation, optional non-blocking configuration (`O_NONBLOCK`), and
|
||||
the DF (Don't Fragment) flag via `IP_MTU_DISCOVER`.
|
||||
|
||||
### send/
|
||||
Packet building and transmission. Assembles the ICMP header and payload,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ typedef void (*icmp_callback_t)(const icmp_reply_t *reply, void *userdata);
|
|||
|
||||
/* Handle lifecycle */
|
||||
icmp_handle_t *icmp_create(void);
|
||||
icmp_handle_t *icmp_create_block(void);
|
||||
void icmp_destroy(icmp_handle_t *h);
|
||||
int icmp_get_fd(const icmp_handle_t *h);
|
||||
|
||||
|
|
@ -75,6 +76,7 @@ int icmp_error_extract_offending(const icmp_reply_t *reply,
|
|||
|
||||
/* Socket options */
|
||||
int icmp_set_dont_fragment(icmp_handle_t *h);
|
||||
int icmp_set_tos(icmp_handle_t *h, uint8_t tos);
|
||||
|
||||
/* Error handling */
|
||||
const char *icmp_strerror(const icmp_handle_t *h);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ SRCS += $(SRC_DIR)/error/should_retry.c
|
|||
SRCS += $(SRC_DIR)/socket/create.c
|
||||
SRCS += $(SRC_DIR)/socket/configure.c
|
||||
SRCS += $(SRC_DIR)/socket/set_dont_fragment.c
|
||||
SRCS += $(SRC_DIR)/socket/set_tos.c
|
||||
SRCS += $(SRC_DIR)/handle/create.c
|
||||
SRCS += $(SRC_DIR)/handle/destroy.c
|
||||
SRCS += $(SRC_DIR)/handle/get_fd.c
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
/* Forward declarations */
|
||||
static int alloc_icmp_handle(struct icmp_handle **h);
|
||||
static void init_icmp_handle(struct icmp_handle *h);
|
||||
static struct icmp_handle *create_handle(void);
|
||||
/* -------------------- */
|
||||
|
||||
icmp_handle_t *
|
||||
icmp_create(void)
|
||||
static struct icmp_handle *
|
||||
create_handle(void)
|
||||
{
|
||||
struct icmp_handle *h;
|
||||
|
||||
|
|
@ -26,6 +27,17 @@ icmp_create(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
icmp_handle_t *
|
||||
icmp_create(void)
|
||||
{
|
||||
struct icmp_handle *h = create_handle();
|
||||
|
||||
if (NULL == h)
|
||||
return NULL;
|
||||
|
||||
if (-1 == socket_configure(h))
|
||||
{
|
||||
close(h->fd);
|
||||
|
|
@ -36,6 +48,12 @@ icmp_create(void)
|
|||
return (icmp_handle_t *)h;
|
||||
}
|
||||
|
||||
icmp_handle_t *
|
||||
icmp_create_block(void)
|
||||
{
|
||||
return (icmp_handle_t *)create_handle();
|
||||
}
|
||||
|
||||
static int
|
||||
alloc_icmp_handle(struct icmp_handle **h)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,11 +37,12 @@ handle_send_error(struct icmp_handle *h)
|
|||
int saved_errno;
|
||||
|
||||
saved_errno = errno;
|
||||
if (EAGAIN == saved_errno || EWOULDBLOCK == saved_errno)
|
||||
if (EAGAIN == saved_errno || EWOULDBLOCK == saved_errno
|
||||
|| ENOBUFS == saved_errno)
|
||||
{
|
||||
icmp_set_error_fmt(h, ICMP_ERR_EAGAIN,
|
||||
"Send would block (buffer full, retry later)");
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
icmp_set_error_fmt(h, ICMP_ERR_SEND, "sendto() failed: %s",
|
||||
strerror(saved_errno));
|
||||
|
|
|
|||
|
|
@ -8,15 +8,16 @@ send_to_destination(struct icmp_handle *h, const void *packet, size_t len,
|
|||
struct in_addr dest, uint8_t ttl)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int ret;
|
||||
|
||||
if (send_set_socket_ttl(h, ttl) < 0)
|
||||
return -1;
|
||||
|
||||
send_prepare_destination(&addr, dest);
|
||||
|
||||
if (send_packet(h, packet, len, &addr) < 0)
|
||||
return -1;
|
||||
ret = send_packet(h, packet, len, &addr);
|
||||
|
||||
if (0 == ret)
|
||||
icmp_clear_error(h);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
25
src/socket/set_tos.c
Normal file
25
src/socket/set_tos.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "internal/icmp_internal.h"
|
||||
|
||||
int
|
||||
icmp_set_tos(struct icmp_handle *h, uint8_t tos)
|
||||
{
|
||||
int val;
|
||||
int saved_errno;
|
||||
|
||||
if (NULL == h)
|
||||
return -1;
|
||||
val = (int)tos;
|
||||
if (0 > setsockopt(h->fd, IPPROTO_IP, IP_TOS, &val, sizeof(val)))
|
||||
{
|
||||
saved_errno = errno;
|
||||
icmp_set_error_fmt(h, ICMP_ERR_SOCKET,
|
||||
"Failed to set TOS: %s", strerror(saved_errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue