如同获取IPv4的地址一般,获取IPv6也是可以通过使用网卡信息来得到IPv6的地址,也可以给一个多播地址发送数据包然后获取IPv6的地址。在IPv4通过iotcl函数是可以获取本主机的IPv4的地址的,但是本楼主使用iotcl函数来获取IPv6的地址就没成功过,经查证,没有看到使用iotcl获取IPv6地址成功的Demo,所以如果想使用iocl函数来获取IPv6地址,我劝你还是做好心理准备哈!不多说,直接上代码了,一下就是我实现的两种获取IPv6地址的方法。
mynet.h
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <arpa/ftp.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <net/if.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <errno.h>
方法一:byeth0getipv6.c
#include "mynet.h"
int main(int argc, char *argv[]){
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
char* ifaname;
printf("NI_MAXHOST:%d\n",NI_MAXHOST);
if (getifaddrs(&ifaddr) == -1) {
printf("getifaddrs\n");
return -1;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
ifaname = ifa->ifa_name;
if (family == AF_INET6 && memcmp(ifaname, "eth0", 4) == 0 ) {
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0) {
printf("getnameinfo() failed: %s\n", gai_strerror(s));
return -1;
}
if (strchr(host, '%') == NULL){
printf("%s IPv6 addr:%s\n", ifa->ifa_name, host);
}
}else{
continue;
}
}
freeifaddrs(ifaddr);
return 0;
}
方法二:bymulgetipv6.c
#include "mynet.h"
int main(){
const char* muladdr = "ff0e::2";
int sockfd;
int len;
int on = 1;
struct sockaddr_in6 iface_out;
struct sockaddr_in6 remote;
char address[45];
memset(&remote, 0, sizeof( struct sockaddr_in6 ));
remote.sin6_family = AF_INET6;
inet_pton(AF_INET6, muladdr, &remote.sin6_addr);
remote.sin6_port = htons(10086);
memset(&iface_out, 0, sizeof( struct sockaddr_in6));
sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
if ( setsockopt(sockfd , SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1 ) {
perror("DEBUG: [get_output_if] setsockopt(SOL_SOCKET, SO_BROADCAST");
close(sockfd);
return -1;
}
if ( connect(sockfd, (struct sockaddr *) &remote, sizeof(struct sockaddr_in6)) == -1)
{
perror("IPv6 DEBUG: [get_output_if] connect");
close(sockfd);
return -1;
}
len = sizeof(iface_out);
if (getsockname(sockfd, (struct sockaddr *) &iface_out, &len) == -1) {
perror("DEBUG: [get_output_if] getsockname");
close(sockfd);
return -1;
}
close(sockfd);
if (iface_out.sin6_addr.s6_addr == 0) { /* what is this case?? */
return -1;
}
inet_ntop(AF_INET6, (const void *) &iface_out.sin6_addr, address, 45);
printf("IPV6 address:%s\n",address);
}