如何使用inet\u pton和struct ifreq从C程序设置ip地址

如何使用inet\u pton和struct ifreq从C程序设置ip地址,c,network-programming,ioctl,C,Network Programming,Ioctl,我试图从C程序设置网络接口的ip地址。我环顾四周,发现我可以使用ioctl()和inet\u pton()来完成。我的问题是,我无法确定在struct ifreq中应该将转换后的地址存储在哪里。我不断得到ioctl()-无效参数错误 我特别研究了这个例子。这表示我们可以将ifr.ifr\u addr强制转换为struct sockaddr\u in。但是,在进行地址转换后,ioctl()失败,出现无效参数错误 代码如下: 280 void setip (int fd) { 281 282

我试图从C程序设置网络接口的ip地址。我环顾四周,发现我可以使用
ioctl()
inet\u pton()
来完成。我的问题是,我无法确定在
struct ifreq
中应该将转换后的地址存储在哪里。我不断得到
ioctl()-无效参数
错误

我特别研究了这个例子。这表示我们可以将
ifr.ifr\u addr
强制转换为
struct sockaddr\u in
。但是,在进行地址转换后,
ioctl()
失败,出现无效参数错误

代码如下:

280 void setip (int fd) {
281 
282     struct ifreq ifr;
283     struct sockaddr_in * addr;
284     int stat;
285 
286     strcpy(ifr.ifr_name, in.dev.device);          // in.dev.device = tun2
287     addr = (struct sockaddr_in *) &ifr.ifr_addr;
288 
289     addr->sin_family = AF_INET;
290 
291     stat = inet_pton(addr->sin_family, in.dev.ip_addr, &addr->sin_addr); // in.dev.ip_addr = "100.0.0.10"
292     if (stat == 0)
293         raise_error("inet_pton() - invalid ip");
294     if (stat == -1)
295         raise_error("inet_pton() - invalid family");
296 
297     if (stat == 1);
298     else
299         raise_error("inet_pton()");
300 
301     /* This is just to test if address conversion happened properly */
302     char buff[BUFF_SIZE];
303     char * foo;
304     foo = inet_ntop(AF_INET, &addr->sin_addr, buff, BUFF_SIZE);
305     if (foo == NULL)
306         raise_error("inet_ntop()");
307     else
308         printf("main = %s, addr = %s\n",in.dev.ip_addr, buff);
309     
310     if (ioctl(fd, SIOCSIFADDR, &ifr, sizeof(ifr)) == -1)
311         raise_error("ioctl() - SIOCSIFADDR");
312 }
编辑:
raise\u error
功能是:

void raise_error (const char * msg) {

    perror(msg);
    exit(1);
}
我得到的结果是:

main = 100.0.0.10, addr = 100.0.0.10
ioctl() - SIOCSIFADDR: Invalid argument
我猜转换后的地址在
struct ifreq
中被放在了错误的位置,但我无法准确地确定它应该放在什么位置。 我还尝试使用
ifr.ifr\u addr
进行地址转换,但也不起作用

编辑:我以root用户身份运行程序

任何帮助都将不胜感激。如果我需要发布更多代码或调试输出,请告诉我


谢谢

我认为您看到了错误的错误消息,因为
raise\u error
peror
之前调用另一个函数,而您看到的是调用结果不是
ioctl
。。您应该始终在要测试的函数之后调用
peror
。我尝试了您的代码,但由于“ioctl():权限被拒绝”而失败。您需要以root身份运行该代码(还请注意,您不需要传递
ifreq
)的大小。

根据mux的评论,我在
eth0
上尝试了相同的代码,该代码有效。因此我想tun设备是不同的,我们不能使用相同的
ioctl()
调用它们。
因此,对于
ioctl()
使用
inet\u pton
struct ifreq
设置ip地址的方法是正确的,但它在tun设备上不起作用。

您好,感谢您的回复,我以root用户身份运行该程序,在其他情况下,raise\u error工作正常。我已通过检查raise_error打印的错误和手册中给出的相应错误号确认了这一点。请让我知道我是否遗漏了什么。我可以设置eth0的ip地址,但不能为tun设备设置。你知道我如何为tun设备做吗?谢谢