【发布时间】:2013-08-09 15:06:55
【问题描述】:
我正在写一个程序,需要设置一个接口的ip地址,设置UP和RUNNING。我可以使用ioctl(SIOCSIFADDR) 对 ipv4 地址执行此操作,但对 ipv6 地址执行相同操作会出错。
下面是sn-p的代码:
329 memset(&ifr, 0, sizeof(ifr));
330 strncpy(ifr.ifr_name, in.dev.device, IFNAMSIZ);
331
332 /* we need a socket descriptor for ioctl(). Cant use tun descriptor */
333 s = socket(in.over_n, SOCK_DGRAM, 0);
334 /* Now check if socket we got is ok */
335 if (s < 0)
336 raise_error("socket()");
337
338
339
340 switch (in.over_n) {
341
342 case AF_INET: memset(&addr4, 0, sizeof(addr4));
343 addr4.sin_family = AF_INET;
344 /* Convert ip to network binary */
345 stat = inet_pton(addr4.sin_family, in.dev.ip_addr, &addr4.sin_addr);
346 ifr.ifr_addr = *(struct sockaddr *) &addr4;
347 break;
348
349 case AF_INET6: memset(&addr6, 0, sizeof(addr6));
350 addr6.sin6_family = AF_INET6;
351 /* Convert ip to network binary */
352 stat = inet_pton(addr6.sin6_family, in.dev.ip_addr, &addr6.sin6_addr);
353 ifr.ifr_addr = *(struct sockaddr *) &addr6.sin6_addr;
354 break;
355 default: raise_error("invalid network prot");
356 }
357
358 /* Check if conversion happened properly */
359 if (stat == 0)
360 raise_error("inet_pton() - invalid ip");
361 if (stat == -1)
362 raise_error("inet_pton() - invalid family");
363
364 if (stat != 1)
365 raise_error("inet_pton()");
366
367 char dum[BUFF_SIZE];
368 if (inet_ntop(in.over_n, &ifr.ifr_addr, dum, BUFF_SIZE) != NULL)
369 printf("name = %s, ip = %s\n",ifr.ifr_name,dum);
370
371 /* Set ip */
372 if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) == -1)
373 raise_error("ioctl() - SIOCSIFADDR");
这适用于 ipv4 地址,但 ipv6 地址给我错误:
name = tun9, ip = aaaa::bbbb
ioctl() - SIOCSIFADDR: Invalid argument
如果我将第 353 行更改为
353 ifr.ifr_addr = *(struct sockaddr *) &addr6;
然后错误变为
name = tun9, ip = a00::aaaa:0:0:0
ioctl() - SIOCSIFADDR: No such device
我注意到struct ifreq 有一个成员struct sockaddr,我认为它小于struct sockaddr_in6,但与sockaddr_in 一样大。我想知道这是否是问题所在,struct ifreq 无法保存 ipv6 地址。如果这是真的,我们对涉及 ipv6 地址的ioctl() 使用什么?
我要设置的输入IP地址是aaaa::bbbb,in.over_n是AF_INET或AF_INET6。
任何帮助将不胜感激。如果我需要发布更多代码、输出等,请告诉我。
非常感谢。
【问题讨论】:
-
感谢@ScottyBauer,它适用于 IP 地址,但不适用于掩码。我需要再调试一些,但我不明白代码到底在做什么。该答案没有任何解释。你能告诉我那里到底在做什么吗?谢谢
-
是的,当我生病时添加 cmets。
-
非常感谢。如果您可以向我指出有关
ioctl()、ifreq和相关内容的任何指南或文档,那就太好了。我尝试在网上搜索,但找不到确切的来源。
标签: c linux network-programming ioctl