我正在编写一个程序,需要设置接口的 ip 地址并将其设置UP
为RUNNING
. 我可以使用 ipv4 地址执行此操作ioctl(SIOCSIFADDR)
,但 ipv6 地址的相同操作会出错。
以下是代码片段:
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 地址。如果这是真的,我们用什么来ioctl()
涉及 ipv6 地址?
我要设置的输入 IP 地址是aaaa::bbbb
、或。in.over_n
AF_INET
AF_INET6
任何帮助都感激不尽。如果我需要发布更多代码、输出等,请告诉我。
非常感谢。