117 lines
3.4 KiB
Markdown
117 lines
3.4 KiB
Markdown
# libicmp
|
|
|
|
ICMPv4 library for building ping, traceroute, and network diagnostic tools.
|
|
Supports both non-blocking (default) and blocking socket modes.
|
|
|
|
## Dependencies
|
|
|
|
- libc
|
|
- GNU make
|
|
- clang
|
|
- POSIX-compliant OS
|
|
|
|
For tests only:
|
|
- criterion
|
|
|
|
## Build
|
|
|
|
```sh
|
|
make # Build static and shared libraries
|
|
make BUILD_STATIC=yes BUILD_SHARED=no
|
|
make install PREFIX=/usr/local
|
|
make test
|
|
```
|
|
|
|
## API
|
|
|
|
### Handle lifecycle
|
|
|
|
```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 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
|
|
|
|
```c
|
|
int icmp_send_echo(icmp_handle_t *h, struct in_addr dest, uint16_t id,
|
|
uint16_t seq, uint8_t ttl,
|
|
const void *payload, size_t payload_len);
|
|
|
|
int icmp_send_raw(icmp_handle_t *h, uint8_t type, uint8_t code,
|
|
uint32_t header_rest,
|
|
const void *payload, size_t len, struct in_addr dest,
|
|
uint8_t ttl);
|
|
```
|
|
|
|
`icmp_send_echo()` builds and sends an ICMP ECHO_REQUEST with the given
|
|
id, seq, and payload. `icmp_send_raw()` sends an arbitrary ICMP packet
|
|
by type and code.
|
|
|
|
### Receive
|
|
|
|
```c
|
|
typedef void (*icmp_callback_t)(const icmp_reply_t *reply, void *userdata);
|
|
|
|
int icmp_process(icmp_handle_t *h, icmp_callback_t cb, void *userdata,
|
|
size_t max_packets);
|
|
```
|
|
|
|
`icmp_process()` drains up to `max_packets` from the socket in a
|
|
non-blocking loop, invoking `cb` for each one. The `icmp_reply_t` passed
|
|
to the callback contains the ICMP type/code, source address, TTL,
|
|
timestamp, and payload. Returns the number of packets processed, or -1
|
|
on error.
|
|
|
|
## Modules
|
|
|
|
### handle/
|
|
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, 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,
|
|
computes the checksum, and writes to the socket.
|
|
|
|
### recv/
|
|
Non-blocking receive loop. Reads datagrams, timestamps each one on
|
|
arrival, and dispatches them through the caller-supplied callback.
|
|
|
|
### packet/
|
|
ICMP and IP packet parsing and building. Extracts fields from raw
|
|
datagrams, including nested packets inside ICMP error messages
|
|
(`icmp_offending_packet_t`).
|
|
|
|
### error/
|
|
Error state storage and formatting. Wraps `errno` and library-specific
|
|
error codes into a single slot on the handle, exposed via
|
|
`icmp_strerror()` and `icmp_should_retry()`.
|
|
|
|
### utils/
|
|
RFC 1071 one's-complement checksum and nanosecond time helpers
|
|
(`icmp_get_time()`, `icmp_time_diff_ns()`).
|
|
|
|
## License
|
|
|
|
This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](./LICENSE) file for details.
|
|
|
|
## Authors
|
|
|
|
- **lohhiiccc** - [Git](https://git.lohic.dev)
|
|
|
|
## See Also
|
|
|
|
- [RFC 792 - Internet Control Message Protocol](https://datatracker.ietf.org/doc/html/rfc792)
|
|
- [RFC 1071 - Computing the Internet Checksum](https://datatracker.ietf.org/doc/html/rfc1071)
|