标签:
本文转自 http://www.code4app.com/forum.php?mod=viewthread&tid=8427&highlight=ipv6
一、IPV6-Only支持是啥?
二、Apple如何审核支持IPV6-Only?
三、应用如何支持IPV6-Only?
1. Use High-Level Networking Frameworks;2. Don’t Use IP Address Literals;3. Check Source Code for IPv6 DNS64/NAT64 Incompatibilities;4. Use System APIs to Synthesize IPv6 Addresses;3.1 NSURLConnection是否支持IPV6?
3.2 Cocoa的URL Loading System从iOS哪个版本开始支持IPV6?
3.3 Reachability是否需要修改支持IPV6?
1
2
3
|
在Pods:Reachability中 AF_INET Files:Reachability.m struct sockaddr_in Files:Reachability.h , Reachability.m |
1
2
3
4
5
6
7
|
+ (instancetype)reachabilityForInternetConnection { struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof (zeroAddress)); zeroAddress.sin_len = sizeof (zeroAddress); zeroAddress.sin_family = AF_INET; return [ self reachabilityWithAddress: ( const struct sockaddr *) &zeroAddress]; } |
四、底层的socket API如何同时支持IPV4和IPV6?
4.1 IP地址从二进制到符号的转化
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
//for IPV6 +( NSString *)formatIPV6Address:( struct in6_addr)ipv6Addr{ NSString *address = nil ; char dstStr[INET6_ADDRSTRLEN]; char srcStr[INET6_ADDRSTRLEN]; memcpy(srcStr, &ipv6Addr, sizeof ( struct in6_addr)); if (inet_ntop(AF_INET6, srcStr, dstStr, INET6_ADDRSTRLEN) != NULL ){ address = [ NSString stringWithUTF8String:dstStr]; } return address; } //for IPV4 +( NSString *)formatIPV4Address:( struct in_addr)ipv4Addr{ NSString *address = nil ; char dstStr[INET_ADDRSTRLEN]; char srcStr[INET_ADDRSTRLEN]; memcpy(srcStr, &ipv4Addr, sizeof ( struct in_addr)); if (inet_ntop(AF_INET, srcStr, dstStr, INET_ADDRSTRLEN) != NULL ){ address = [ NSString stringWithUTF8String:dstStr]; } return address; } |
4.2 本机IP获取支持IPV6
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
+ ( NSString *)deviceIPAdress { while (temp_addr != NULL ) { NSLog ( @"ifa_name===%@" ,[ NSString stringWithUTF8String:temp_addr->ifa_name]); // Check if interface is en0 which is the wifi connection on the iPhone if ([[ NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString: @"en0" ] || [[ NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString: @"pdp_ip0" ]) { //如果是IPV4地址,直接转化 if (temp_addr->ifa_addr->sa_family == AF_INET){ // Get NSString from C String address = [ self formatIPV4Address:(( struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr]; } //如果是IPV6地址 else if (temp_addr->ifa_addr->sa_family == AF_INET6){ address = [ self formatIPV6Address:(( struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr]; if (address && ![address isEqualToString: @"" ] && ![address.uppercaseString hasPrefix: @"FE80" ]) break ; } } temp_addr = temp_addr->ifa_next; } } } |
4.3 设备网关地址获取获取支持IPV6
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/* net.route.0.inet.flags.gateway */ int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY}; if (sysctl(mib, sizeof (mib) / sizeof ( int ), buf, &l, 0, 0) < 0) { address = @"192.168.0.1" ; } .... //for IPV4 for (i = 0; i < RTAX_MAX; i++) { if (rt->rtm_addrs & (1 << i)) { sa_tab[i] = sa; sa = ( struct sockaddr *)(( char *)sa + ROUNDUP(sa->sa_len)); } else { sa_tab[i] = NULL ; } } //for IPV6 for (i = 0; i < RTAX_MAX; i++) { if (rt->rtm_addrs & (1 << i)) { sa_tab[i] = sa; sa = ( struct sockaddr_in6 *)(( char *)sa + sa->sin6_len); } else { sa_tab[i] = NULL ; } } |
4.4 设备DNS地址获取支持IPV6
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
+( NSArray *)outPutDNSServers{ res_state res = malloc( sizeof ( struct __res_state)); int result = res_ninit(res); NSMutableArray *servers = [[ NSMutableArray alloc] init]; if (result == 0) { union res_9_sockaddr_union *addr_union = malloc(res->nscount * sizeof ( union res_9_sockaddr_union)); res_getservers(res, addr_union, res->nscount); for ( int i = 0; i < res->nscount; i++) { if (addr_union[i].sin.sin_family == AF_INET) { char ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(addr_union[i].sin.sin_addr), ip, INET_ADDRSTRLEN); NSString *dnsIP = [ NSString stringWithUTF8String:ip]; [servers addObject:dnsIP]; NSLog ( @"IPv4 DNS IP: %@" , dnsIP); } else if (addr_union[i].sin6.sin6_family == AF_INET6) { char ip[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &(addr_union[i].sin6.sin6_addr), ip, INET6_ADDRSTRLEN); NSString *dnsIP = [ NSString stringWithUTF8String:ip]; [servers addObject:dnsIP]; NSLog ( @"IPv6 DNS IP: %@" , dnsIP); } else { NSLog ( @"Undefined family." ); } } } res_nclose(res); free(res); return [ NSArray arrayWithArray:servers]; } |
4.4 域名DNS地址获取支持IPV6
1
2
3
4
5
|
//ipv4 phot = gethostbyname(hostN); //ipv6 phot = gethostbyname2(hostN, AF_INET6); |
4.5 ping方案支持IPV6
4.6 traceRoute方案支持IPV6
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
//构造通用的IP地址结构stuck sockaddr NSString *ipAddr0 = [serverDNSs objectAtIndex:0]; //设置server主机的套接口地址 NSData *addrData = nil ; BOOL isIPV6 = NO ; if ([ipAddr0 rangeOfString: @":" ].location == NSNotFound ) { isIPV6 = NO ; struct sockaddr_in nativeAddr4; memset(&nativeAddr4, 0, sizeof (nativeAddr4)); nativeAddr4.sin_len = sizeof (nativeAddr4); nativeAddr4.sin_family = AF_INET; nativeAddr4.sin_port = htons(udpPort); inet_pton(AF_INET, ipAddr0.UTF8String, &nativeAddr4.sin_addr.s_addr); addrData = [ NSData dataWithBytes:&nativeAddr4 length: sizeof (nativeAddr4)]; } else { isIPV6 = YES ; struct sockaddr_in6 nativeAddr6; memset(&nativeAddr6, 0, sizeof (nativeAddr6)); nativeAddr6.sin6_len = sizeof (nativeAddr6); nativeAddr6.sin6_family = AF_INET6; nativeAddr6.sin6_port = htons(udpPort); inet_pton(AF_INET6, ipAddr0.UTF8String, &nativeAddr6.sin6_addr); addrData = [ NSData dataWithBytes:&nativeAddr6 length: sizeof (nativeAddr6)]; } struct sockaddr *destination; destination = ( struct sockaddr *)[addrData bytes]; //创建socket if ((recv_sock = socket(destination->sa_family, SOCK_DGRAM, isIPV6?IPPROTO_ICMPV6:IPPROTO_ICMP)) < 0) if ((send_sock = socket(destination->sa_family, SOCK_DGRAM, 0)) < 0) //设置sender 套接字的ttl if ((isIPV6? setsockopt(send_sock,IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof (ttl)): setsockopt(send_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof (ttl))) < 0) //发送成功返回值等于发送消息的长度 ssize_t sentLen = sendto(send_sock, cmsg, sizeof (cmsg), 0, ( struct sockaddr *)destination, isIPV6? sizeof ( struct sockaddr_in6): sizeof ( struct sockaddr_in)); |
标签:
原文地址:http://www.cnblogs.com/idxdm/p/5553423.html