Meine Ansätze bis jetzt:
1. Den Kernel mich infromieren lassen, dass sich /sys/class/net/eth0/carrier geändert hat:
Code:
#include <iostream>
extern "C"
{
#include <fcntl.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
#include <linux/if.h>
#include <linux/sockios.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
}
using namespace std;
static volatile int event_fd;
static void handler(int sig, siginfo_t *si, void *data)
{
event_fd = si->si_fd;
}
int main(void)
{
struct sigaction act;
int fd;
act.sa_sigaction = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
sigaction(SIGRTMIN + 1, &act, NULL);
if ((fd = open("/sys/class/net/eth0", O_RDONLY)) == -1)
{
perror("open");
return EXIT_FAILURE;
}
cout << "fd: " << fd << endl;
fcntl(fd, F_SETSIG, SIGRTMIN + 1);
fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_ACCESS|DN_RENAME|DN_ATTRIB|DN_MULTISHOT);
while (1)
{
pause();
cout << "eth0 changed" << endl;
}
close(fd);
}
Funktioniert leider nur, wenn ich auf die Datei zugreife (cat, touch...).
Wieso ändert der Kernel den timestamp der Datei nicht, sobald er diese ändert?
2. Mittels ioctl den Status erfragen.
Code:
#include <iostream>
extern "C"
{
#include <fcntl.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
#include <linux/if.h>
#include <linux/sockios.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
}
using namespace std;
int main(void)
{
int fd;
struct ifreq ifr;
struct ethtool_value edata;
fd = socket(AF_INET, SOCK_DGRAM, 0);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name)-1);
edata.cmd = ETHTOOL_GLINK;
ifr.ifr_data = (caddr_t) &edata;
while(1)
{
if(ioctl(fd, SIOCETHTOOL, &ifr) == -1)
{
perror("ETHTOOL_GLINK");
return -1;
}
string foo = edata.data ? "up": "down";
cout << foo << endl;
sleep(1);
}
close(fd);
return 0;
}
Bei dieser Lösung gefällt mir nicht, dass ich das IF pollen müsste. Dazu kommt noch, dass ich root-Rechte benötige.
Hat jemand einen hinweis, wie ich das (möglichst ohne root) mittels asynchrones Event lösen könnte?
Any hints?
Lesezeichen