# libicmp Non-blocking ICMPv4 library for building ping, traceroute, and network diagnostic tools. ## 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); 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 `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_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`. ### 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)