使用SIOCSIFADDR ioctl设置IP地址

使用SIOCSIFADDR ioctl设置IP地址,c,ip,ip-address,ioctl,C,Ip,Ip Address,Ioctl,我正在尝试使用Linux上的IOCTL接口获取和设置IP地址。 我成功地获得并设置了它。当我设置ip地址时, ifconfig eth0显示正确的IP地址,但随后系统断开连接。 i、 e.系统不可ping。 这是我设置IP地址的代码。如果我遗漏了什么,请告诉我 struct ifreq ifr; in_addr_t in_addr; struct sockaddr_in sin; memset(&ifr, 0, sizeof(struct ifreq)); memset(&si

我正在尝试使用Linux上的IOCTL接口获取和设置IP地址。 我成功地获得并设置了它。当我设置ip地址时,
ifconfig eth0
显示正确的IP地址,但随后系统断开连接。 i、 e.系统不可ping。 这是我设置IP地址的代码。如果我遗漏了什么,请告诉我

struct ifreq ifr;
in_addr_t in_addr;
struct sockaddr_in sin;

memset(&ifr, 0, sizeof(struct ifreq));
memset(&sin, 0, sizeof(struct sockaddr_in));
sockfd = socket(AF_INET, SOCK_STREAM, 0);
sprintf(ifr.ifr_name, "eth0");
in_addr = inet_addr("192.168.101.17");
sin.sin_addr.s_addr = in_addr;
memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
io = ioctl(sockfd, SIOCSIFADDR, (char *)&ifr);

也许你忘了设置界面了

ioctl(sockfd, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
ioctl(sockfd, SIOCSIFFLAGS, &ifr);

这将适用于接口或别名。使用“strace”验证操作是否正确:

strace ./ifconfig

socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
ioctl(5, SIOCSIFADDR, {ifr_name="eth0:8", ifr_addr={AF_INET, inet_addr("192.168.1.202")}}) = 0
ioctl(5, SIOCGIFFLAGS, {ifr_name="eth0:8", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
ioctl(5, SIOCSIFFLAGS, {ifr_name="eth0:8", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
close(5)                                = 0
完整的源代码:

#包括
#包括
#包括
#包括/*抵消*/
#包括
#包括
#包括
#包括
#如果GLIBC小调>=2&&GLIBC小调>=1
#包括
#包括
#否则
#包括
#包括
#恩迪夫
#定义IFNAME“eth0:2”
#定义主机“192.168.1.204”
#定义ifreq_offsetof(x)offsetof(struct ifreq,x)
int main(int argc,字符**argv){
结构ifreq-ifr;
sai中的结构sockaddr_;
int sockfd;/*socket fd我们用来处理*/
整数选择器;
无符号字符掩码;
char*p;
/*创建到网络内核的通道*/
sockfd=插座(AF_INET,SOCK_DGRAM,0);
/*获取接口名*/
strncpy(ifr.ifr_名称、IFNAME、IFNAMSIZ);
memset(&sai,0,sizeof(struct sockaddr));
sai.sin_family=AF_INET;
sai.sinu端口=0;
sai.sin_addr.s_addr=inet_addr(主机);
p=(char*)&sai;
memcpy(((char*)和ifr+ifreq\u offsetof(ifr\u addr)),
p、 sizeof(struct sockaddr));
ioctl(sockfd、SIOCSIFADDR和ifr);
ioctl(sockfd、SIOCGIFFLAGS和ifr);
ifr.ifr_flags |=IFF_UP | IFF_RUNNING;
//ifr.ifr\u标志&=~selector;//取消设置某些内容
ioctl(sockfd、SIOCSIFFLAGS和ifr);
关闭(sockfd);
返回0;
}

请注意,inet\u addr的手册页提到,您应该“避免使用inet\u aton()、inet\u pton(3)或getaddrinfo(3),它们提供了一种更清晰的方式来指示错误返回。”