用户空间获取eth0开关状态和开关实现
开关的实现与ifconfig eth0 dow/up 相同
获取状态
获取状态
int get_eth0_status()
{
struct ifreq ifr;
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Create socket fails!\n");
return -1;
}
strcpy(ifr.ifr_name, "eth0");
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
{
printf("ioctl SIOCGIFFLAGS fails!\n");
close(sockfd);
return -1;
}
close(sockfd);
return ifr.ifr_flags& IFF_UP;
}
设置状态
int set_eth0_status()
{
struct ifreq ifr;
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Create socket fails!\n");
return -1;
}
strcpy(ifr.ifr_name, "eth0");
ifr.ifr_flags |= IFF_UP;
// ifr.ifr_flags &= ~IFF_UP;
if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
{
printf("ioctl SIOCSIFFLAGS fails!\n");
close(sockfd);
return -1;
}
close(sockfd);
return 0;
}
内核实现:
开关设置(/net/ipv4/devinet.c 函数devinet_ioctl)
case SIOCSIFFLAGS:
if (colon) {
ret = -EADDRNOTAVAIL;
if (!ifa)
break;
ret = 0;
if (!(ifr.ifr_flags & IFF_UP))
inet_del_ifa(in_dev, ifap, 1);
break;
}
ret = dev_change_flags(dev, ifr.ifr_flags);
状态获取(net/core/dev.c dev_ioctl)
case SIOCGIFFLAGS:
case SIOCGIFMETRIC:
case SIOCGIFMTU:
case SIOCGIFHWADDR:
case SIOCGIFSLAVE:
case SIOCGIFMAP:
case SIOCGIFINDEX:
case SIOCGIFTXQLEN:
dev_load(net, ifr.ifr_name);
rcu_read_lock();
ret = dev_ifsioc_locked(net, &ifr, cmd);
rcu_read_unlock();
if (!ret) {
if (colon)
*colon = ':';
if (copy_to_user(arg, &ifr,
sizeof(struct ifreq)))
ret = -EFAULT;
}
return ret;