123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- //
- // OSSIPv6PrefixResolver.m
- //
- // Created by lingkun on 16/5/16.
- // Edit by zhouzhuo on 2016/5/22
- // Copyright © 2016 Ali. All rights reserved.
- #import "OSSIPv6PrefixResolver.h"
- #import "OSSLog.h"
- #import <Foundation/Foundation.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- static const __uint8_t NS_PREFIX_32[4] = {0x20, 0x01, 0x0d, 0xb8};
- static const __uint8_t NS_PREFIX_40[5] = {0x20, 0x01, 0x0d, 0xb8, 0x01};
- static const __uint8_t NS_PREFIX_48[6] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22};
- static const __uint8_t NS_PREFIX_56[7] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22, 0x03};
- static const __uint8_t NS_PREFIX_64[8] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22, 0x03, 0x44};
- static const __uint8_t NS_PREFIX_96[12] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x22, 0x03, 0x44, 0x00, 0x00, 0x00, 0x00};
- static const __uint8_t WK_PREFIX_96[12] = {0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- static const __uint8_t* V6_PREFIX_CONTENT_TABLE[7] = {
- WK_PREFIX_96,
- NS_PREFIX_32,
- NS_PREFIX_40,
- NS_PREFIX_48,
- NS_PREFIX_56,
- NS_PREFIX_64,
- NS_PREFIX_96};
- static const __uint8_t V6_PREFIX_SIZE_TABLE[7] = {
- sizeof(WK_PREFIX_96)/sizeof(__uint8_t),
- sizeof(NS_PREFIX_32)/sizeof(__uint8_t),
- sizeof(NS_PREFIX_40)/sizeof(__uint8_t),
- sizeof(NS_PREFIX_48)/sizeof(__uint8_t),
- sizeof(NS_PREFIX_56)/sizeof(__uint8_t),
- sizeof(NS_PREFIX_64)/sizeof(__uint8_t),
- sizeof(NS_PREFIX_96)/sizeof(__uint8_t)};
- static const __uint8_t V6_PREFIX_TABLE_SIZE = 7;
- typedef enum {
- IPv6PrefixUnResolved = 0,
- IPv6PrefixResolving,
- IPv6PrefixResolved
- } IPv6PrefixResolveStatus;
- @implementation OSSIPv6PrefixResolver {
- IPv6PrefixResolveStatus ipv6PrefixResolveStatus;
- __uint8_t *ipv6Prefix;
- int prefixLen;
- }
- - (instancetype)init {
- if (self = [super init]) {
- ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
- ipv6Prefix = (__uint8_t *)V6_PREFIX_CONTENT_TABLE[0];
- prefixLen = V6_PREFIX_SIZE_TABLE[0];
- }
- return self;
- }
- + (instancetype)getInstance {
- static id singletonInstance = nil;
- static dispatch_once_t once_token;
- dispatch_once(&once_token, ^{
- if (!singletonInstance) {
- singletonInstance = [[super allocWithZone:NULL] init];
- }
- });
- return singletonInstance;
- }
- /**
- * @brief Updates IPv6 Prefix
- */
- - (void)updateIPv6Prefix {
- @synchronized(self) {
- ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
- [self resolveIPv6Prefix:ipv6Prefix];
- }
- }
- - (BOOL)isIPv6Prefix:(__uint8_t *)v6Prefix
- withPrefixLen:(int)pLen
- withIP:(__uint8_t *)ip
- withIPLen:(int)ipLen {
- for (int i = 0; i < pLen && i < ipLen; i++) {
- if (*(v6Prefix + i) != *(ip + i)) {
- return NO;
- }
- }
- return YES;
- }
- - (__uint8_t)resolveIPv6Prefix:(__uint8_t *)prefix {
- if ( !prefix ) {
- return 0;
- }
- __uint8_t len = prefixLen;
- memcpy(prefix, ipv6Prefix, prefixLen);
- @synchronized(self) {
- if (ipv6PrefixResolveStatus==IPv6PrefixUnResolved ) {
- ipv6PrefixResolveStatus = IPv6PrefixResolving;
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- struct addrinfo hints, *addr;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_INET6;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_DEFAULT;
-
- if (0 != getaddrinfo("ipv4only.arpa", "http", &hints, &addr)) {
- ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
- return;
- }
-
- if (addr && AF_INET6 == addr->ai_addr->sa_family) {
- struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)(addr->ai_addr);
- if ( !addr6 ) {
- ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
- return;
- }
-
- __uint8_t* u8 = addr6->sin6_addr.__u6_addr.__u6_addr8;
- for (__uint8_t i=0; i < V6_PREFIX_TABLE_SIZE; i++) {
- if ([self isIPv6Prefix:(__uint8_t *)V6_PREFIX_CONTENT_TABLE[i]
- withPrefixLen:V6_PREFIX_SIZE_TABLE[i]
- withIP:u8
- withIPLen:16]) {
-
- ipv6Prefix = (__uint8_t *)V6_PREFIX_CONTENT_TABLE[i];
- prefixLen = V6_PREFIX_SIZE_TABLE[i];
- ipv6PrefixResolveStatus = IPv6PrefixResolved;
- break;
- }
- }
- ipv6PrefixResolveStatus = IPv6PrefixUnResolved;
- }
-
- });
- }
- }
-
- return len;
- }
- - (NSString *)convertIPv4toIPv6:(NSString *)ipv4 {
- if ([ipv4 length] <= 0) {
- return nil;
- }
-
- __uint8_t ipv6[16] = {0x00};
- __uint8_t length = [self resolveIPv6Prefix:ipv6];
-
- if (length <= 0) {
- return nil;
- }
-
- in_addr_t addr_v4 = inet_addr([ipv4 UTF8String]);
-
- // 按length的不同情况进行处理
- if (length==4 || length==12) { //32 bits or 96 bits
- ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
- ipv6[length+1] |= (__uint8_t)(addr_v4>>8 & 0xff);
- ipv6[length+2] |= (__uint8_t)(addr_v4>>16 & 0xff);
- ipv6[length+3] |= (__uint8_t)(addr_v4>>24 & 0xff);
- }
- else if (length == 5) { //40 bits :a.b.c.0.d
- ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
- ipv6[length+1] |= (__uint8_t)(addr_v4>>8 & 0xff);
- ipv6[length+2] |= (__uint8_t)(addr_v4>>16 & 0xff);
- ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
- }
- else if (length == 6) { //48 bits :a.b.0.c.d
- ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
- ipv6[length+1] |= (__uint8_t)(addr_v4>>8 & 0xff);
- ipv6[length+3] |= (__uint8_t)(addr_v4>>16 & 0xff);
- ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
- }
- else if (length == 7) { //56 bits :a.0.b.c.d
- ipv6[length+0] |= (__uint8_t)(addr_v4>>0 & 0xff);
- ipv6[length+2] |= (__uint8_t)(addr_v4>>8 & 0xff);
- ipv6[length+3] |= (__uint8_t)(addr_v4>>16 & 0xff);
- ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
- }
- else if (length == 8) { //64 bits :0.a.b.c.d
- ipv6[length+1] |= (__uint8_t)(addr_v4>>0 & 0xff);
- ipv6[length+2] |= (__uint8_t)(addr_v4>>8 & 0xff);
- ipv6[length+3] |= (__uint8_t)(addr_v4>>16 & 0xff);
- ipv6[length+4] |= (__uint8_t)(addr_v4>>24 & 0xff);
- }
-
- // constructs the IPv6 structure
- char addr_text[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
- if(inet_ntop(AF_INET6, ipv6, addr_text, INET6_ADDRSTRLEN)) {
- NSString *ret = [NSString stringWithUTF8String:addr_text];
- return ret;
- }
- return nil;
- }
- @end
|