liboping is a library written in C for generating ICMP ECHO_REQUEST (i.e., ping packets). It supports parallel probing of multiple hosts and can transparently handle both IPv4 and IPv6 addresses. This library is designed with a object-oriented interface, making it very useful in network monitoring applications or other scenarios that require frequent ping operations.
Here are some of the main features of liboping:
| Feature | Description |
|---|---|
| Parallel Multi-host Ping | Can send ping requests to multiple hosts simultaneously, improving efficiency. |
| Dual Stack Support | Supports both IPv4 and IPv6 transparently. |
| Object-oriented Interface | Provides an easy-to-use object-oriented interface. |
| Command Line Tools Included | Includes oping and an ncurses-based noping tool. |
Installing liboping
On Debian-based systems, you can install liboping using apt:
# Install shared library
sudo apt install liboping0
# Install development files (header files and static libraries) for compiling your own programs
sudo apt install liboping-dev
On Fedora systems, you can use dnf to install:
sudo dnf install liboping
Permission Settings: To allow liboping to create ICMP sockets without root privileges, you typically need to set the cap_net_raw capability on Linux:
sudo setcap cap_net_raw+ep /path/to/your/compiled/binary
On other UNIX-like systems, the traditional set-UID root method may be used.
Basic Usage
1. Initialization and Cleanup
When using the liboping library, you first need to create a ping object, and it should be destroyed after use to free resources.
#include <oping.h>
pingobj_t *ping = NULL;
ping = ping_construct();
if (ping == NULL) {
// Handle construction failure
}
// ... Use the ping object for operations ...
ping_destroy(ping);
2. Adding Hosts
Use the ping_host_add function to add hosts to the ping object. Hostnames can be domain names, IPv4, or IPv6 addresses.
int ret;
ret = ping_host_add(ping, "example.com");
if (ret != 0) {
// Handle host addition failure, e.g., use ping_get_error(ping) to get error information
}
ret = ping_host_add(ping, "192.0.2.1");
ret = ping_host_add(ping, "2001:db8::1");
3. Sending Requests and Getting Results
Use the ping_send function to send ICMP requests to all added hosts, and then iterate through the host list to get each host’s latency information.
// Send ping requests
if (ping_send(ping) < 0) {
// Handle send failure
}
// Iterate through hosts and get information
ping_iter_t *iter;
for (iter = ping_iterator_get(ping); iter != NULL; iter = ping_iterator_next(iter)) {
char host[128];
double latency;
size_t len = sizeof(host);
// Get hostname
if (ping_iterator_get_info(iter, PING_INFO_HOSTNAME, host, &len) == 0) {
printf("Host: %s\n", host);
}
// Get latency (in seconds)
len = sizeof(latency);
if (ping_iterator_get_info(iter, PING_INFO_LATENCY, &latency, &len) == 0) {
printf("Latency: %.2f ms\n", latency * 1000.0); // Convert to milliseconds
}
}
Complete Code Example
Below is a complete C program example that demonstrates how to use liboping to ping multiple hosts.
#include <stdio.h>
#include <oping.h>
int main(void) {
pingobj_t *ping;
int ret;
const char *hosts[] = {"google.com", "github.com", "example.com"};
int num_hosts = 3;
// 1. Initialize ping object
ping = ping_construct();
if (ping == NULL) {
fprintf(stderr, "Error: Unable to create ping object.\n");
return 1;
}
// 2. Add hosts
for (int i = 0; i < num_hosts; i++) {
ret = ping_host_add(ping, hosts[i]);
if (ret != 0) {
fprintf(stderr, "Error: Unable to add host %s: %s\n",
hosts[i], ping_get_error(ping));
// Note: Here we continue execution instead of returning directly
}
}
// 3. Send ping requests
if (ping_send(ping) < 0) {
fprintf(stderr, "Error: Failed to send ping: %s\n",
ping_get_error(ping));
ping_destroy(ping);
return 1;
}
// 4. Iterate and print results
ping_iter_t *iter;
printf("Ping Results:\n");
printf("-------------\n");
for (iter = ping_iterator_get(ping); iter != NULL; iter = ping_iterator_next(iter)) {
char host[128];
double latency;
size_t len = sizeof(host);
if (ping_iterator_get_info(iter, PING_INFO_HOSTNAME, host, &len) == 0) {
len = sizeof(latency);
if (ping_iterator_get_info(iter, PING_INFO_LATENCY, &latency, &len) == 0) {
printf("%-15s : %.2f ms\n", host, latency * 1000.0);
} else {
printf("%-15s : (No response or error)\n", host);
}
}
}
// 5. Cleanup
ping_destroy(ping);
return 0;
}
Compile this program using gcc:
gcc -o ping_example ping_example.c -loping
Error Handling
When using liboping, proper error handling is very important. Many functions in the library return values indicating success or error. You can use the ping_get_error function to get a human-readable error description.
ret = ping_host_add(ping, "invalid-hostname-!!");
if (ret != 0) {
fprintf(stderr, "Error adding host: %s\n", ping_get_error(ping));
}
Command Line Tools
liboping also comes with some command line tools that make it easy to use its functionality directly:
-
oping: A command similar to the traditional ping tool, but supports pinging multiple hosts simultaneously.oping google.com github.com -
noping: A full-screen tool based on ncurses that can display ping statistics in real-time and highlight abnormal round-trip times.noping google.com
Conclusion
liboping is a powerful and easy-to-use library, ideal for developers who need to integrate ping functionality into their applications or for tasks that require parallel monitoring of the network status of many hosts. Its object-oriented design and transparent support for IPv4/IPv6 make it very practical in modern network environments.