LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Networking
User Name
Password
Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.

Notices

Reply
 
Search this Thread
Old 11-24-2011, 09:11 AM   #1
madhurjf
LQ Newbie
 
Registered: Nov 2011
Posts: 3

Rep: Reputation: Disabled
Assigning ipv6 address using ioctl


I'm trying to assign an IPv6 address to an interface using ioctl, but in vain. Here's the code I used:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> /* offsetof */
#include <net/if.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <asm/types.h>
#include <linux/if_ether.h>
#endif

#define IFNAME "eth1"
#define HOST "fec2::22"
#define ifreq_offsetof(x) offsetof(struct ifreq, x)

int main(int argc, char **argv) {

struct ifreq ifr;
struct sockaddr_in6 sai;
int sockfd; /* socket fd we use to manipulate stuff with */
int selector;
unsigned char mask;

char *p;

sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
if (sockfd == -1) {
printf("Bad fd\n");
return -1;
}

/* get interface name */
strncpy(ifr.ifr_name, IFNAME, IFNAMSIZ);

memset(&sai, 0, sizeof(struct sockaddr));
sai.sin6_family = AF_INET6;
sai.sin6_port = 0;

if(inet_pton(AF_INET6, HOST, (void *)&sai.sin6_addr) <= 0) {
printf("Bad address\n");
return -1;
}

p = (char *) &sai;
memcpy( (((char *)&ifr + ifreq_offsetof(ifr_addr) )),
p, sizeof(struct sockaddr));

int ret = ioctl(sockfd, SIOCSIFADDR, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);
ioctl(sockfd, SIOCGIFFLAGS, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);

ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
// ifr.ifr_flags &= ~selector; // unset something

ioctl(sockfd, SIOCSIFFLAGS, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);
close(sockfd);
return 0;
}

--------------------------------------
The ioctl calls fail saying ENODEV. When the family of the socket is changed to sockfd = socket(AF_INET, SOCK_DGRAM, 0);, the calls fail again saying EINVAL. I was able to assign an IPv4 address to the interface with the above code by using sockaddr_in in lieu of sockaddr_in6.
Is it not possible to assign IPv6 address using ioctl? If not, how can it be done programmatically?
 
Old 12-07-2011, 05:38 PM   #2
Peterius
Member
 
Registered: May 2004
Distribution: Gentoo, Debian, OpenBSD, NetBSD
Posts: 157

Rep: Reputation: 16
meh

Last edited by Peterius; 12-08-2011 at 02:40 AM.
 
Old 12-07-2011, 09:40 PM   #3
madhurjf
LQ Newbie
 
Registered: Nov 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Drawing inspiration from the linux implementation of 'ifconfig' command, I was able to set assign IPv6 address to the interface. Here's the code for it:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <net/if.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <asm/types.h>
#include <linux/if_ether.h>
#endif

#define IFNAME "eth0"
#define HOST "fec2::22"
#define ifreq_offsetof(x) offsetof(struct ifreq, x)

struct in6_ifreq {
struct in6_addr ifr6_addr;
__u32 ifr6_prefixlen;
unsigned int ifr6_ifindex;
};

int main(int argc, char **argv) {

struct ifreq ifr;
struct sockaddr_in6 sai;
int sockfd;
struct in6_ifreq ifr6;

sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
if (sockfd == -1) {
printf("Bad fd\n");
return -1;
}

/* get interface name */
strncpy(ifr.ifr_name, IFNAME, IFNAMSIZ);

memset(&sai, 0, sizeof(struct sockaddr));
sai.sin6_family = AF_INET6;
sai.sin6_port = 0;

if(inet_pton(AF_INET6, HOST, (void *)&sai.sin6_addr) <= 0) {
printf("Bad address\n");
return -1;
}

memcpy((char *) &ifr6.ifr6_addr, (char *) &sai.sin6_addr,
sizeof(struct in6_addr));

if (ioctl(sockfd, SIOGIFINDEX, &ifr) < 0) {
perror("SIOGIFINDEX");
}
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
ifr6.ifr6_prefixlen = 64;
if (ioctl(sockfd, SIOCSIFADDR, &ifr6) < 0) {
perror("SIOCSIFADDR");
}

ifr.ifr_flags |= IFF_UP | IFF_RUNNING;

int ret = ioctl(sockfd, SIOCSIFFLAGS, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);

close(sockfd);
return 0;
}
 
  


Reply

Tags
ipv6, linux, networking


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to get IPv6 address using ioctl() SIOCGIFADDR ashok449 Linux - Networking 6 01-04-2012 12:39 AM
bind() fails with EADDRNOTAVAIL after calling an SIOCSIFADDR ioctl for IPV6 address lprasanna Linux - Networking 2 08-15-2011 03:29 PM
assign ipv6 address using ioctl manishtiwari_1987 Linux - Newbie 1 07-23-2011 06:41 PM
Assigning IPV6 adresses by dhcp6 tasamono Linux - Server 0 06-24-2007 06:59 AM
Assigning site-local ipv6 address to an interface goto Linux - Networking 0 03-24-2003 05:06 AM


All times are GMT -5. The time now is 11:32 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration