Ma egy viszonylag egyszerű problémára keresem a megoldást. Adva van egy Linux-os gép, amiben persze van egy ethernet csatlakozó, amivel a LAN-on lóg. Hogyan lehet megtudni, hogy a kapcsolat él-e, ha nem él, akkor azért nem mert az ethernet kábel ki van-e húzva, vagy el sincs indítva az adott kapcsolat.
Keresgélve a neccen találtam egy jó kis programot: ethtool(8). Ezzel lehet ilyeneket nézegetni. A parancs ethtool eth0. Meg strace(1)-eltem, hogy azt is megtudjam, hogyan lehet C-ből megtudni az infókat...
Az eredmény ez a kód:
#include <sys/ioctl.h> // SIOCSIFFLAGS
#include <errno.h> // errno
#include <linux/ethtool.h> // ETHTOOL_GLINK
#include <linux/sockios.h> // SIOCETHTOOL
#define ERROR(fmt, ...) do { printf(fmt, __VA_ARGS__); return -1; } while(0)
// Open any socket to get the driver
int socId = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (socId < 0)
ERROR("IFUTIL: socket failed. Errno = %d", errno );
struct ifreq if_req;
(void) strncpy(if_req.ifr_name, pDeviceName, sizeof(if_req.ifr_name));
struct ethtool_value edata;
edata.cmd = ETHTOOL_GLINK;
if_req.ifr_data = (char*) &edata;
if (ioctl(socId, SIOCETHTOOL, &if_req) == -1)
ERROR("IFUTIL: ioctl failed. Errno = %d", errno );
state = !!edata.data;
close ( socId );
Egy gond van, hogy csak root jogosultsággal tudjuk futtatni. Szomorú. Lehet-e sima nyúzerként is megszerezni a kívánt információt? Az ethtool helyett alacsonyabb szintű ioctl parancsokat kell nézni.
#include <stdio.h> // printf
#include <string.h> // strncpy
//#include <sys/socket.h> // AF_INET
#include <sys/ioctl.h> // SIOCGIFFLAGS
#include <errno.h> // errno
#include <netinet/in.h> // IPPROTO_IP
#include <net/if.h> // IFF_*, ifreq
#define ERROR(fmt, ...) do { printf(fmt, __VA_ARGS__); return -1; } while(0)
int CheckLink(char *ifname) {
int state = -1;
int socId = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (socId < 0) ERROR("Socket failed. Errno = %d\n", errno);
struct ifreq if_req;
(void) strncpy(if_req.ifr_name, ifname, sizeof(if_req.ifr_name));
int rv = ioctl(socId, SIOCGIFFLAGS, &if_req);
close(socId);
if ( rv == -1) ERROR("Ioctl failed. Errno = %d\n", errno);
return (if_req.ifr_flags & IFF_UP) && (if_req.ifr_flags & IFF_RUNNING);
}
Ha IFF_UP be van állítva, akkor az ethernet interface el vagyon indítva (ifup), ha IFF_RUNNING is be van állítva, akkor a dugó be vagyon dugva.
Up & running minden nap!
+jegyzések