OSSIPv6PrefixResolver.m 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. //
  2. // OSSIPv6PrefixResolver.m
  3. //
  4. // Created by lingkun on 16/5/16.
  5. // Edit by zhouzhuo on 2016/5/22
  6. // Copyright © 2016 Ali. All rights reserved.
  7. #import "OSSIPv6PrefixResolver.h"
  8. #import "OSSLog.h"
  9. #import <Foundation/Foundation.h>
  10. #include <arpa/inet.h>
  11. #include <netdb.h>
  12. #include <netinet/in.h>
  13. #include <sys/socket.h>
  14. static const __uint8_t NS_PREFIX_32[4] = {0x20, 0x01, 0x0d, 0xb8};
  15. static const __uint8_t NS_PREFIX_40[5] = {0x20, 0x01, 0x0d, 0xb8, 0x01};
  16. static const __uint8_t NS_PREFIX_48[6] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22};
  17. static const __uint8_t NS_PREFIX_56[7] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22, 0x03};
  18. static const __uint8_t NS_PREFIX_64[8] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22, 0x03, 0x44};
  19. static const __uint8_t NS_PREFIX_96[12] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22, 0x03, 0x44, 0x00, 0x00, 0x00, 0x00};
  20. static const __uint8_t WK_PREFIX_96[12] = {0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  21. static const __uint8_t* V6_PREFIX_CONTENT_TABLE[7] = {
  22. WK_PREFIX_96,
  23. NS_PREFIX_32,
  24. NS_PREFIX_40,
  25. NS_PREFIX_48,
  26. NS_PREFIX_56,
  27. NS_PREFIX_64,
  28. NS_PREFIX_96};
  29. static const __uint8_t V6_PREFIX_SIZE_TABLE[7] = {
  30. sizeof(WK_PREFIX_96)/sizeof(__uint8_t),
  31. sizeof(NS_PREFIX_32)/sizeof(__uint8_t),
  32. sizeof(NS_PREFIX_40)/sizeof(__uint8_t),
  33. sizeof(NS_PREFIX_48)/sizeof(__uint8_t),
  34. sizeof(NS_PREFIX_56)/sizeof(__uint8_t),
  35. sizeof(NS_PREFIX_64)/sizeof(__uint8_t),
  36. sizeof(NS_PREFIX_96)/sizeof(__uint8_t)};
  37. static const __uint8_t V6_PREFIX_TABLE_SIZE = 7;
  38. typedef enum {
  39. IPv6PrefixUnResolved = 0,
  40. IPv6PrefixResolving,
  41. IPv6PrefixResolved
  42. } IPv6PrefixResolveStatus;
  43. @implementation OSSIPv6PrefixResolver {
  44. IPv6PrefixResolveStatus ipv6PrefixResolveStatus;
  45. __uint8_t *ipv6Prefix;
  46. int prefixLen;
  47. }
  48. - (instancetype)init {
  49. if (self = [super init]) {
  50. ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
  51. ipv6Prefix = (__uint8_t *)V6_PREFIX_CONTENT_TABLE[0];
  52. prefixLen = V6_PREFIX_SIZE_TABLE[0];
  53. }
  54. return self;
  55. }
  56. + (instancetype)getInstance {
  57. static id singletonInstance = nil;
  58. static dispatch_once_t once_token;
  59. dispatch_once(&once_token, ^{
  60. if (!singletonInstance) {
  61. singletonInstance = [[super allocWithZone:NULL] init];
  62. }
  63. });
  64. return singletonInstance;
  65. }
  66. /**
  67. * @brief Updates IPv6 Prefix
  68. */
  69. - (void)updateIPv6Prefix {
  70. @synchronized(self) {
  71. ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
  72. [self resolveIPv6Prefix:ipv6Prefix];
  73. }
  74. }
  75. - (BOOL)isIPv6Prefix:(__uint8_t *)v6Prefix
  76. withPrefixLen:(int)pLen
  77. withIP:(__uint8_t *)ip
  78. withIPLen:(int)ipLen {
  79. for (int i = 0; i < pLen && i < ipLen; i++) {
  80. if (*(v6Prefix + i) != *(ip + i)) {
  81. return NO;
  82. }
  83. }
  84. return YES;
  85. }
  86. - (__uint8_t)resolveIPv6Prefix:(__uint8_t *)prefix {
  87. if ( !prefix ) {
  88. return 0;
  89. }
  90. __uint8_t len = prefixLen;
  91. memcpy(prefix, ipv6Prefix, prefixLen);
  92. @synchronized(self) {
  93. if (ipv6PrefixResolveStatus==IPv6PrefixUnResolved ) {
  94. ipv6PrefixResolveStatus = IPv6PrefixResolving;
  95. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  96. struct addrinfo hints, *addr;
  97. memset(&hints, 0, sizeof(hints));
  98. hints.ai_family = PF_INET6;
  99. hints.ai_socktype = SOCK_STREAM;
  100. hints.ai_flags = AI_DEFAULT;
  101. if (0 != getaddrinfo("ipv4only.arpa", "http", &hints, &addr)) {
  102. ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
  103. return;
  104. }
  105. if (addr && AF_INET6 == addr->ai_addr->sa_family) {
  106. struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)(addr->ai_addr);
  107. if ( !addr6 ) {
  108. ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
  109. return;
  110. }
  111. __uint8_t* u8 = addr6->sin6_addr.__u6_addr.__u6_addr8;
  112. for (__uint8_t i=0; i < V6_PREFIX_TABLE_SIZE; i++) {
  113. if ([self isIPv6Prefix:(__uint8_t *)V6_PREFIX_CONTENT_TABLE[i]
  114. withPrefixLen:V6_PREFIX_SIZE_TABLE[i]
  115. withIP:u8
  116. withIPLen:16]) {
  117. ipv6Prefix = (__uint8_t *)V6_PREFIX_CONTENT_TABLE[i];
  118. prefixLen = V6_PREFIX_SIZE_TABLE[i];
  119. ipv6PrefixResolveStatus = IPv6PrefixResolved;
  120. break;
  121. }
  122. }
  123. ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
  124. }
  125. });
  126. }
  127. }
  128. return len;
  129. }
  130. - (NSString *)convertIPv4toIPv6:(NSString *)ipv4 {
  131. if ([ipv4 length] <= 0) {
  132. return nil;
  133. }
  134. __uint8_t ipv6[16] = {0x00};
  135. __uint8_t length = [self resolveIPv6Prefix:ipv6];
  136. if (length <= 0) {
  137. return nil;
  138. }
  139. in_addr_t addr_v4 = inet_addr([ipv4 UTF8String]);
  140. // 按length的不同情况进行处理
  141. if (length==4 || length==12) { //32 bits or 96 bits
  142. ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
  143. ipv6[length+1] |= (__uint8_t)(addr_v4>>8 & 0xff);
  144. ipv6[length+2] |= (__uint8_t)(addr_v4>>16 & 0xff);
  145. ipv6[length+3] |= (__uint8_t)(addr_v4>>24 & 0xff);
  146. }
  147. else if (length == 5) { //40 bits :a.b.c.0.d
  148. ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
  149. ipv6[length+1] |= (__uint8_t)(addr_v4>>8 & 0xff);
  150. ipv6[length+2] |= (__uint8_t)(addr_v4>>16 & 0xff);
  151. ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
  152. }
  153. else if (length == 6) { //48 bits :a.b.0.c.d
  154. ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
  155. ipv6[length+1] |= (__uint8_t)(addr_v4>>8 & 0xff);
  156. ipv6[length+3] |= (__uint8_t)(addr_v4>>16 & 0xff);
  157. ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
  158. }
  159. else if (length == 7) { //56 bits :a.0.b.c.d
  160. ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
  161. ipv6[length+2] |= (__uint8_t)(addr_v4>>8 & 0xff);
  162. ipv6[length+3] |= (__uint8_t)(addr_v4>>16 & 0xff);
  163. ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
  164. }
  165. else if (length == 8) { //64 bits :0.a.b.c.d
  166. ipv6[length+1] |= (__uint8_t)(addr_v4>>0 & 0xff);
  167. ipv6[length+2] |= (__uint8_t)(addr_v4>>8 & 0xff);
  168. ipv6[length+3] |= (__uint8_t)(addr_v4>>16 & 0xff);
  169. ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
  170. }
  171. // constructs the IPv6 structure
  172. char addr_text[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
  173. if(inet_ntop(AF_INET6, ipv6, addr_text, INET6_ADDRSTRLEN)) {
  174. NSString *ret = [NSString stringWithUTF8String:addr_text];
  175. return ret;
  176. }
  177. return nil;
  178. }
  179. @end