Recently, I have been working on the SDK related to the network. I have recorded what I can open in the project, many of which use C, which is equivalent to a tool. In the later stage, I will also choose to open some ping network tools and tools to find link nodes. I have been working on this recently.

Welcome to follow my official account. I will regularly share some solutions to the problems I encounter in the project and some practical skills of iOS. At the present stage, I will mainly sort out some basic knowledge and record it







The post will also be synchronized to my blog: ppsheep.com

Obtain the IP address of the current device

For public IP, of course, it is not available on our local device, at least I did not find a way to obtain the egress IP address, but LAN IP can be obtained, ipv4 and ipv6 can be obtained

+ (NSString *)deviceIPAdress
{
    NSString *address = @"";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;

    success = getifaddrs(&interfaces);

    if (success == 0) {  // 0 indicates success

        temp_addr = interfaces;
        while(temp_addr ! = NULL) {if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"] || [[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"pdp_ip0"])
                {
                // If it is an IPV4 address, convert it directly
                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];
                }

                // If it is an IPV6 address
                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;
        }
    }

    freeifaddrs(interfaces);

    // Addresses starting with FE80 are unicast addresses
    if(address && ! [address isEqualToString:@""] && ![address.uppercaseString hasPrefix:@"FE80"]) {
        return address;
    } else {
        return @"127.0.0.1"; }}Copy the code

Obtain the gateway address of the current device

Gateway address, commonly referred to as the address of a router, is also relative to a LOCAL area network. It is necessary to distinguish ipv4 and ipv6, and the two methods of obtaining a gateway address are different

// Ipv4 gateway address
+ (NSString *)getGatewayIPV4Address
{

    NSString *address = nil;

    /* net.route.0.inet.flags.gateway */
    int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY};

    size_t l;
    char *buf, *p;
    struct rt_msghdr *rt;
    struct sockaddr *sa;
    struct sockaddr *sa_tab[RTAX_MAX];
    int i;

    if (sysctl(mib, sizeof(mib) / sizeof(int), 0, &l, 0.0) < 0) {
        address = @"192.168.0.1";
    }

    if (l > 0) {
        buf = malloc(l);
        if (sysctl(mib, sizeof(mib) / sizeof(int), buf, &l, 0.0) < 0) {
            address = @"192.168.0.1";
        }

        for (p = buf; p < buf + l; p += rt->rtm_msglen) {
            rt = (struct rt_msghdr *)p;
            sa = (struct sockaddr *)(rt + 1);
            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; }}if (((rt->rtm_addrs & (RTA_DST | RTA_GATEWAY)) == (RTA_DST | RTA_GATEWAY)) &&
                sa_tab[RTAX_DST]->sa_family == AF_INET &&
                sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
                unsigned char octet[4] = {0.0.0.0};
                int i;
                for (i = 0; i < 4; i++) {
                    octet[i] = (((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr >>
                                (i * 8)) &
                    0xFF;
                }
                if (((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
                    in_addr_t addr =
                    ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
                    address = [self formatIPV4Address:*((struct in_addr *)&addr)];
                    // NSLog(@"IPV4address%@", address);
                    break;
                }
            }
        }
        free(buf);
    }

    return address;
}Copy the code
// Ipv6 gateway address
+ (NSString *)getGatewayIPV6Address
{

    NSString *address = nil;

    /* net.route.0.inet.flags.gateway */
    int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY};

    size_t l;
    char *buf, *p;
    struct rt_msghdr *rt;
    struct sockaddr_in6 *sa;
    struct sockaddr_in6 *sa_tab[RTAX_MAX];
    int i;

    if (sysctl(mib, sizeof(mib) / sizeof(int), 0, &l, 0.0) < 0) {
        address = @"192.168.0.1";
    }

    if (l > 0) {
        buf = malloc(l);
        if (sysctl(mib, sizeof(mib) / sizeof(int), buf, &l, 0.0) < 0) {
            address = @"192.168.0.1";
        }

        for (p = buf; p < buf + l; p += rt->rtm_msglen) {
            rt = (struct rt_msghdr *)p;
            sa = (struct sockaddr_in6 *)(rt + 1);
            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; }}if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
               && sa_tab[RTAX_DST]->sin6_family == AF_INET6
               && sa_tab[RTAX_GATEWAY]->sin6_family == AF_INET6)
                {
                address = [self formatIPV6Address:((struct sockaddr_in6 *)(sa_tab[RTAX_GATEWAY]))->sin6_addr];
                // NSLog(@"IPV6address%@", address);
                break;
                }
        }
        free(buf);
    }

    return address;
}Copy the code

Let’s make a judgment when we get it

/ *! * Obtain the current device gateway address */
+ (NSString *)getGatewayIPAddress{
    NSString *address = nil;

    NSString *gatewayIPV4 = [self getGatewayIPV4Address];
    NSString *gatewayIPV6 = [self getGatewayIPV6Address];

    if(gatewayIPV6 ! = nil) { address = gatewayIPV6; }else {
        address = gatewayIPV4;
    }

    return address;
}Copy the code

Obtain the IP address corresponding to the domain name through the domain name (CDN)

Generally speaking, if you buy a CDN, you will get multiple IP addresses


/ *! * Obtain the DNS resolution address of the IP list from hostname */
+ (NSArray *)getDNSsWithDormain:(NSString *)hostName{
    NSMutableArray *result = [[NSMutableArray alloc] init];
    NSArray *IPDNSs = [self getDNSWithHostName:hostName];
    if (IPDNSs && IPDNSs.count > 0) {
        [result addObjectsFromArray:IPDNSs];
    }

    return [NSArray arrayWithArray:result];
}


+ (NSArray *)getDNSWithHostName:(NSString *)hostName
{
    const char *hostN = [hostName UTF8String];
    Boolean result = false;
    Boolean bResolved = false;
    CFHostRef hostRef;
    CFArrayRef addresses = NULL;

    CFStringRef hostNameRef = CFStringCreateWithCString(kCFAllocatorDefault, hostN, kCFStringEncodingASCII);

    hostRef = CFHostCreateWithName(kCFAllocatorDefault, hostNameRef);
    if (hostRef) {
        result = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL);
        if (result == true) {
            addresses = CFHostGetAddressing(hostRef, &result);
        }
    }
    bResolved = result;
    NSMutableArray *ipAddresses = [NSMutableArray array];
    if(bResolved)
        {
        struct sockaddr_in* remoteAddr;

        for(int i = 0; i < CFArrayGetCount(addresses); i++)
            {
            CFDataRef saData = (CFDataRef)CFArrayGetValueAtIndex(addresses, i);
            remoteAddr = (struct sockaddr_in*)CFDataGetBytePtr(saData);

            if(remoteAddr ! = NULL) {// Obtain the IP address
                const char *strIP41 = inet_ntoa(remoteAddr->sin_addr);
                NSString *strDNS =[NSString stringWithCString:strIP41 encoding:NSASCIIStringEncoding];
                [ipAddresses addObject:strDNS];
                }
            }
        }
    CFRelease(hostNameRef);
    if (hostRef) {
        CFRelease(hostRef);
    }

    return [NSArray arrayWithArray:ipAddresses];
}Copy the code

Gets the current network status

If it’s WIFI, go back to WIFI. If it’s cellular, you can also tell which carrier it is and what network it is using. 4G, 3G, 2G and other carriers have temporarily distinguished the three major domestic carriers


+(NSString *)currentNetInfo{

    NSString *returnName = nil;

    PPSNetWorkType type = [PPSGetAppEnvironment getNetworkTypeFromStatusBar];
    if (type == PPSNetWorkTypeWiFi) {
        returnName = @"WIFI";
        return returnName;
    }

    NSString *carrierName = nil;
    CTTelephonyNetworkInfo *netInfo = [[CTTelephonyNetworkInfo alloc] init];
    CTCarrier *carrier = [netInfo subscriberCellularProvider];
    if(carrier ! = NULL) { NSArray *chinaMobileMics = @[@"0"The @"2"The @"Seven"];/ / mobile code
        NSArray *chinaTelecomMics = @[@"3"The @"5"The @"11"];/ / telecommunications code
        NSArray *chinaUnicomMics = @[@"1"The @"6"];/ / unicom code
        NSString *mobileNetworkCode = [carrier mobileNetworkCode];
        if ([chinaMobileMics containsObject:mobileNetworkCode]) {
            carrierName = @"chinamobile";
        }else if ([chinaTelecomMics containsObject:mobileNetworkCode]){
            carrierName = @"chinatelecom";
        }else if ([chinaUnicomMics containsObject:mobileNetworkCode]){
            carrierName = @"chinaunicom";
        }else{
            carrierName = @"unknown"; }}else {
        carrierName = @"unknown";
    }

    switch (type) {
        case PPSNetWorkType2G:
            returnName = [NSString stringWithFormat:@"% @ _ % @",carrierName,@"2G"];
            break;
        case PPSNetWorkType3G:
            returnName = [NSString stringWithFormat:@"% @ _ % @",carrierName,@"3G"];
            break;
        case PPSNetWorkType4G:
            returnName = [NSString stringWithFormat:@"% @ _ % @",carrierName,@"4G"];
            break;
        case PPSNetWorkType5G:
            returnName = [NSString stringWithFormat:@"% @ _ % @",carrierName,@"5G"];
            break;
        case PPSNetWorkTypeNone:
            returnName = [NSString stringWithFormat:@"% @ _ % @",carrierName,@"unknown"];
            break;
        default:
            returnName = [NSString stringWithFormat:@"% @ _ % @",carrierName,@"unknown"];
            break;
    }
    return returnName;
}Copy the code

Get the current device information

Get information about the current device, whether it’s iPhone 4, 5, 6, 7, et cetera and the version number of the system phone, tablet, et cetera


/** Obtain the device type @return Device type */
+ (NSString *)deviceInfo {
    struct utsname systemInfo;

    uname(&systemInfo);

    NSString* code = [NSString stringWithCString:systemInfo.machine
                                        encoding:NSUTF8StringEncoding];

    static NSDictionary* deviceNamesByCode = nil;

    if(! deviceNamesByCode) { deviceNamesByCode = @{@"i386": @"Simulator"The @"x86_64": @"Simulator"The @"IPod1, 1": @"iPod Touch".// (Original)
                              @"IPod2, 1": @"iPod Touch".// (Second Generation)
                              @"IPod3, 1": @"iPod Touch".// (Third Generation)
                              @"IPod4, 1": @"iPod Touch".// (Fourth Generation)
                              @"IPod7, 1": @"iPod Touch".// (6th Generation)
                              @"IPhone1, 1": @"iPhone".// (Original)
                              @"IPhone1, 2": @"iPhone".// (3G)
                              @IPhone2, 1 "": @"iPhone".// (3GS)
                              @"IPad1, 1": @"iPad".// (Original)
                              @"And 1": @"iPad 2".//
                              @"IPad3, 1": @"iPad".// (3rd Generation)
                              @"However, 1": @"iPhone 4".// (GSM)
                              @"However, 3": @"iPhone 4".// (CDMA/Verizon/Sprint)
                              @"The iphone 4, 1": @"iPhone 4S".//
                              @"The iphone 5, 1": @"iPhone 5".// (model A1428, AT&T/Canada)
                              @"The iphone 5, 2": @"iPhone 5".// (model A1429, everything else)
                              @"IPad3, 4": @"iPad".// (4th Generation)
                              @"And 5": @"iPad Mini".// (Original)
                              @"The iphone 5, 3": @"iPhone 5c".// (model A1456, A1532 | GSM)
                              @"The iphone 5, 4": @"iPhone 5c".// (model A1507, A1516, A1526 (China), A1529 | Global)
                              @"IPhone6, 1": @"iPhone 5s".// (model A1433, A1533 | GSM)
                              @"IPhone6, 2": @"iPhone 5s".// (model A1457, A1518, A1528 (China), A1530 | Global)
                              @"IPhone7, 1": @"iPhone 6 Plus".//
                              @"IPhone7, 2": @"iPhone 6".//
                              @"IPhone8, 1": @"iPhone 6S".//
                              @"IPhone8, 2": @"iPhone 6S Plus".//
                              @"IPhone8, 4": @"iPhone SE".//
                              @"IPhone9, 1": @"iPhone 7".//
                              @"IPhone9, 3": @"iPhone 7".//
                              @"IPhone9, 2": @"iPhone 7 Plus".//
                              @"IPhone9, 4": @"iPhone 7 Plus".//

                              @"IPad4, 1": @"iPad Air".// 5th Generation iPad (iPad Air) - Wifi
                              @"IPad4, 2": @"iPad Air".// 5th Generation iPad (iPad Air) - Cellular
                              @"IPad4, 4": @"iPad Mini".// (2nd Generation iPad Mini - Wifi)
                              @"IPad4, 5": @"iPad Mini".// (2nd Generation iPad Mini - Cellular)
                              @"IPad4, 7": @"iPad Mini".// (3rd Generation iPad Mini - Wifi (model A1599))
                              @"IPad6, 7": @"iPad Pro (12.9\")".// iPad Pro 12.9 inches - (model A1584)
                              @"IPad6, 8": @"iPad Pro (12.9\")".// iPad Pro 12.9 inches - (model A1652)
                              @"IPad6, 3": @"iPad Pro (9.7\")".// iPad Pro 9.7 inches - (model A1673)
                              @"IPad6, 4": @"iPad Pro (9.7\")"   // iPad Pro 9.7 inches - (models A1674 and A1675)
                              };
    }

    NSString* deviceName = [deviceNamesByCode objectForKey:code];

    if(! deviceName) {// Not found on database. At least guess main device type from string contents:

        if ([code rangeOfString:@"iPod"].location ! = NSNotFound) { deviceName = @"iPod Touch";
        }
        else if([code rangeOfString:@"iPad"].location ! = NSNotFound) { deviceName = @"iPad";
        }
        else if([code rangeOfString:@"iPhone"].location ! = NSNotFound){ deviceName = @"iPhone";
        }
        else {
            deviceName = @"Unknown";
        }
    }

    UIDevice *device = [UIDevice currentDevice];
    NSString *systemVersion = [device systemVersion];

    return [NSString stringWithFormat:@"iOS#%@#%@",deviceName,systemVersion];
}Copy the code

Effect:

Original project Address:

Github.com/yangqian111…