Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.
Notices
Welcome to
LinuxQuestions.org , a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free.
Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please
contact us . If you need to reset your password,
click here .
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
11-24-2011, 08:11 AM
#1
LQ Newbie
Registered: Nov 2011
Posts: 3
Rep:
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?
12-07-2011, 04:38 PM
#2
Member
Registered: May 2004
Distribution: Gentoo, Debian, OpenBSD, NetBSD
Posts: 155
Rep:
meh
Last edited by Peterius; 12-08-2011 at 01:40 AM .
12-07-2011, 08:40 PM
#3
LQ Newbie
Registered: Nov 2011
Posts: 3
Original Poster
Rep:
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;
}
Thread Tools
Search this Thread
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
All times are GMT -5. The time now is 12:59 AM .
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know .
Latest Threads
LQ News