要检查链接是否已启动,请尝试以下操作.它没有root权限.
#include // printf
#include // strncpy
//#include // AF_INET
#include // SIOCGIFFLAGS
#include // errno
#include // IPPROTO_IP
#include // 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);
}
int main() {
printf("%d\n", CheckLink("eth0"));
}
如果设置了IFF_UP,则表示接口已启动(请参阅ifup).如果设置了IFF_RUNNING,则接口已插入.
我也尝试使用ethtool ioctl调用,但是当gid不是root时它失败了.但只是为了日志:
...
#include // __u32
#include // ETHTOOL_GLINK
#include // SIOCETHTOOL
...
int CheckLink(char *ifname) {
...
struct ifreq if_req;
(void) strncpy( if_req.ifr_name, ifname, sizeof(if_req.ifr_name) );
struct ethtool_value edata;
edata.cmd = ETHTOOL_GLINK;
if_req.ifr_data = (char*) &edata;
int rv = ioctl(socId, SIOCETHTOOL, &if_req);
...
return !!edata.data;
}