Monday, June 01, 2009

ETHTOOL: socket-level I/O control calls



The TCT machine that we developed should has network capability, this used for acquiring and retrieving data from the database server (PostgreSQL server). I made a low level utility today, share the memory through POSIX shared memory in order to be read by the TCT machine, the purposes of this utlity is to provide network status such as plugged/unplugged network cable, unreached server and notify if the database server is running or not.

The socket-level I/O control call that kernel provide using ioctl system call require root permission. So i create this as another process (like the daemon) and shared it's status memory area, to know the server connection i simply forking ping utility, pass some options to pinging the server. At last, to probe the database service running state i just connect to the database server via it's running port.

And this is the core codes, i'm pointing to the kernel's socket-level I/O control calls, and call them in userspace (kernel-2.6.27):

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>

int main (void)
{
int s, ret;
struct ethtool_value edata;
struct ifreq ifr;

s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == -1)
{
perror ("socket");
return -1;
}
edata.cmd = ETHTOOL_GLINK;
strncpy (ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
ifr.ifr_data = (char *) &edata;

ret = ioctl (s, SIOCETHTOOL, &ifr);
if (ret == -1)
{
perror ("ioctl");
return -1;
}
printf ("link is %s\n", edata.data ? "up" : "down");
close (s);

return 0;
}