I am writing a program that should set the IP address of an interface and set it UP and RUNNING . I could do this for ipv4 addresses using ioctl(SIOCSIFADDR) , but the same for ipv6 address gives an error.
The following is a snippet of code:
329 memset(&ifr, 0, sizeof(ifr)); 330 strncpy(ifr.ifr_name, in.dev.device, IFNAMSIZ); 331 332 333 s = socket(in.over_n, SOCK_DGRAM, 0); 334 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 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 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 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 372 if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) == -1) 373 raise_error("ioctl() - SIOCSIFADDR");
This works fine for ipv4 addresses, but ipv6 addresses give me an error:
name = tun9, ip = aaaa::bbbb ioctl() - SIOCSIFADDR: Invalid argument
If I change line 353 to
353 ifr.ifr_addr = *(struct sockaddr *) &addr6;
Then the error changes to
name = tun9, ip = a00::aaaa:0:0:0 ioctl() - SIOCSIFADDR: No such device
I noticed that the struct ifreq has a member, struct sockaddr , which in my opinion is smaller than struct sockaddr_in6 , but the same as sockaddr_in . I was wondering if this is a problem and the struct ifreq cannot contain the ipv6 address. If so, what do we use for ioctl() with ipv6 addresses?
The input ip address I'm trying to set, aaaa::bbbb , in.over_n is equal to AF_INET or AF_INET6 .
Any help would be greatly appreciated. Please let me know if I need to post more code, outputs, etc.
Many thanks.