如何设置tun设备的IP地址并通过C程序设置链接UP

时间:2013-07-27 17:16:11

标签: c networking ioctl tun

我正在编写一个使用Linux tun设备进行隧道连接的C程序。我正在创建一个tun设备,使用ioctl()调用设置其所有者,组和持久性。但是,为了进行隧道传输,我需要将ip地址设置为设备并设置链接。我目前正在使用

这样做
# ip addr add
# ip link set

我想设置地址,屏蔽并将链接设置为up。有没有办法在不调用ip命令的情况下通过程序执行此操作?

我尝试将ioctl()SIOCSIFADDR命令一起使用,但它不适用于tun设备,适用于eth0。我收到错误ioctl() - Invalid argument

以下代码适用于eth0但不适用于tun2

280 void setip (int fd) {
281 
282     struct ifreq ifr;
283     struct sockaddr_in addr;
284     int stat;
285     
286     memset(&ifr, 0, sizeof(ifr));
287     memset(&addr, 0, sizeof(addr));
288     strncpy(ifr.ifr_name, in.dev.device, IFNAMSIZ);     // device name: eg. tun2
289     
290     addr.sin_family = AF_INET;
291     stat = inet_pton(addr.sin_family, in.dev.ip_addr, &addr.sin_addr); // ip string
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     ifr.ifr_addr = *(struct sockaddr *) &addr;
302     /* This is just to test if address conversion happened properly */
303     char buff[BUFF_SIZE];
304     char * foo;
305     foo = inet_ntop(AF_INET, &addr.sin_addr, buff, BUFF_SIZE);
306     if (foo == NULL)
307         raise_error("inet_ntop()");
308     else
309         printf("main = %s, addr = %s\n",in.dev.ip_addr, buff);
310         
311     if (ioctl(fd, SIOCSIFADDR, (caddr_t) &ifr) == -1)
312         raise_error("ioctl() - SIOCSIFADDR"); 
313 }

我搜索了为tun设备执行此操作的方法,但找不到任何方法。我使用的所有帖子ipifconfig或类似的东西。

有什么办法可以通过这个程序来做到这一点吗? 感谢

1 个答案:

答案 0 :(得分:3)

我弄明白了这个问题。在eth0的情况下,我使用套接字描述符作为ioctl()的参数,在tun设备的情况下,我使用的是tun设备描述符。我也为tun设备创建了一个套接字,ioctl()工作了。以下是代码:

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

感谢Giuseppe Pes的回复:)