发布了很多非常相似的问题,但它们都是针对Windows的 - 我想知道如何(如果可能的话)我可以拥有我的C程序(在linux上以root身份运行)禁用网络接口它不再接收任何数据包。
如果有人可以告诉我我需要做什么功能,那就太好了,但如果你可以将我链接到一个示例脚本或教程(例如)关闭并重新打开网络界面,那就更好了。
答案 0 :(得分:4)
对于Linux,使用MNL和RTNL协议的知识都很容易实现:
在Unices或其他操作系统上,只有特定于操作系统的调用和/或过时的ioctl调用可用,后者无法正确表达每个接口的Linux多个地址,因此严重的程序不会在其上使用它平台。
答案 1 :(得分:2)
没有一个完整的例子,但是下面的关键词应该让你入门(至少在Linux上,不确定其他版本的Unix):
ioctl,SIOCSIFFLAGS,IFF_UP
在显示相关API时,可能会使用以下内容:http://www.google.com/codesearch/p?hl=en#2--Ws53NXRc/src/ifdown.c
答案 2 :(得分:1)
在Linux上,您可以使用ifdown。我不知道对其他unix有多便携。
答案 3 :(得分:1)
在我使用的Linux和大多数基于Unix的系统上,ifconfig <interface> up/down
用于启用或关闭接口。在不执行ifconfig的情况下,不确定是否有可用的C例程。
答案 4 :(得分:1)
在Linux上,命令ip link set down dev ethX
不会比你想要的更多或更少。如果你在那个平台上,我建议你把这个程序叫做你的工作。
如果您想自己动手,C api对此并不是一件简单的事情。 您可以深入了解 iproute
来源,了解它的作用。
检查@ user611775的答案,了解如何在C中执行此操作的优秀示例。
如果您使用的是另一台Unix,那么每种特定风味的答案可能会有所不同。
答案 5 :(得分:0)
这是一个示例C代码,显示如何使用ioctl(netdevice)或(rt)netlink来打开和关闭接口
The Linux man-pages project
netlink(7) netlink(3)
rtnetlink(7) rtnetlink(3)
netdevice(7)
so_q_5094495.c
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h> // getuid()
// netlink
#include <linux/rtnetlink.h>
// ioctl
#include <net/if.h>
#include <netinet/in.h> // IPPROTO_UDP
#include <sys/ioctl.h>
int ioctlfd=-1;
int netlinkfd=-1;
typedef struct {
struct nlmsghdr nh;
struct ifinfomsg ifi;
} Req_link;
void ioctl_init(){
ioctlfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
assert(ioctlfd==3);
}
void ioctl_end(){
close(ioctlfd);
ioctlfd=-1;
}
void ioctl_flags(const bool up,const char *const dev){
assert(0==getuid());
struct ifreq ifr={};
strncpy(ifr.ifr_name,dev,IFNAMSIZ);
assert(0==ioctl(ioctlfd,SIOCGIFFLAGS,&ifr));
if(up) ifr.ifr_flags|=IFF_UP;
else ifr.ifr_flags&=(~((short)IFF_UP));
assert(0==ioctl(ioctlfd,SIOCSIFFLAGS,&ifr));
}
void netlink_init(){
netlinkfd=socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE);
assert(netlinkfd==3);
assert(0==bind(netlinkfd,(struct sockaddr*)(&(struct sockaddr_nl){
.nl_family=AF_NETLINK,
.nl_pad=0,
.nl_pid=getpid(),
.nl_groups=0
}),sizeof(struct sockaddr_nl)));
}
void netlink_end(){
assert(0==close(netlinkfd));
netlinkfd=-1;
}
void netlink_flags(const bool up,const char *const dev){
assert(0==getuid());
assert(dev&&strlen(dev));
const unsigned index=if_nametoindex(dev);
assert(index>0);
assert(sizeof(Req_link)==send(netlinkfd,&(Req_link){
.nh={
.nlmsg_len=NLMSG_LENGTH(sizeof(struct ifinfomsg)),
.nlmsg_type=RTM_NEWLINK,
.nlmsg_flags=NLM_F_REQUEST,
.nlmsg_seq=0,
.nlmsg_pid=getpid()
},
.ifi={
.ifi_family=AF_UNSPEC,
.ifi_type=0,
.ifi_index=index,
.ifi_flags=up?IFF_UP:0,
// https://www.spinics.net/lists/netdev/msg598191.html
.ifi_change=IFF_UP
}
},sizeof(Req_link),0));
}
int main(const int argc,const char *argv[]){
assert(argc==3+1);
void (*flags)(const bool,const char *const)=NULL;
void (*init)()=NULL;
void (*end)()=NULL;
assert(strlen(argv[1]));
if(0==strcmp("ioctl",argv[1])){
init=&ioctl_init;
flags=&ioctl_flags;
end=&ioctl_end;
}else if(0==strcmp("netlink",argv[1])){
init=&netlink_init;
flags=&netlink_flags;
end=&netlink_end;
}else{
assert(false);
}
bool up=false;
if(0==strcmp("down",argv[2])) up=true;
else if(0==strcmp("up",argv[2])) up=false;
else assert(false);
assert(strlen(argv[3])&&strlen(argv[3])<=IFNAMSIZ-1);
(*init)();
(*flags)(up,argv[3]);
(*end)();
return 0;
}
运行
$ gcc -Wall -std=gnu11 so_q_5094495.c
$ sudo ./a.out netlink up enp0s31f6; ip link show enp0s31f6 | grep -o '<.*>'
<BROADCAST,MULTICAST>
$ sudo ./a.out netlink down enp0s31f6; ip link show enp0s31f6 | grep -o '<.*>'
<NO-CARRIER,BROADCAST,MULTICAST,UP>
$ sudo ./a.out ioctl up enp0s31f6; ip link show enp0s31f6 | grep -o '<.*>'
<BROADCAST,MULTICAST>
$ sudo ./a.out ioctl down enp0s31f6; ip link show enp0s31f6 | grep -o '<.*>'
<NO-CARRIER,BROADCAST,MULTICAST,UP>