美文网首页
手机ip地址

手机ip地址

作者: ChaosHeart | 来源:发表于2020-12-01 14:49 被阅读0次

    1.ip地址

    .h

    #import <Foundation/Foundation.h>
    
    @interface IPAddress : NSObject
    
    /// 获取设备IP地址
    /// @param isIPv4 Yes:ipv4地址, No:ipv6地址
    + (NSString *)getIPAddress:(BOOL)isIPv4;
    
    @end
    

    .m

    #import "IPAddress.h"
    #import "IPAddressConfig.h"
    #define IOS_CELLULAR    @"pdp_ip0"
    #define IOS_WIFI        @"en0"
    #define IOS_VPN         @"utun0"
    #define IP_ADDR_IPv4    @"ipv4"
    #define IP_ADDR_IPv6    @"ipv6"
    
    #import <ifaddrs.h>
    #import <arpa/inet.h>
    #define IOS_CELLULAR    @"pdp_ip0"
    #define IOS_WIFI        @"en0"
    #define IOS_VPN         @"utun0"
    #define IP_ADDR_IPv4    @"ipv4"
    #define IP_ADDR_IPv6    @"ipv6"
    
    
    #pragma mark IPv4是32位地址长度
    #pragma mark IPv6是128位地址长度
    @implementation IPAddress
    
    
    /// 获取设备IP地址
    /// @param isIPv4 Yes:ipv4地址, No:ipv6地址
    + (NSString *)getIPAddress:(BOOL)isIPv4
    {
        NSArray *searchArray = isIPv4 ?
        @[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
        @[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ];
        
        NSDictionary *addresses = [self getIPAddresses];
        NSLog(@"addresses: %@", addresses);
        
        __block NSString *address;
        [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
         {
             address = addresses[key];
             if(address) *stop = YES;
         } ];
        return address ? address : @"0.0.0.0";
    }
    
    
    + (NSDictionary *)getIPAddresses
    {
        NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
        // retrieve the current interfaces - returns 0 on success
        struct ifaddrs *interfaces;
        if(!getifaddrs(&interfaces)) {
            // Loop through linked list of interfaces
            struct ifaddrs *interface;
            for(interface=interfaces; interface; interface=interface->ifa_next) {
                if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                    continue; // deeply nested code harder to read
                }
                const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
                char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
                if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                    NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                    NSString *type;
                    if(addr->sin_family == AF_INET) {
                        if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                            type = IP_ADDR_IPv4;
                        }
                    } else {
                        const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                        if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                            type = IP_ADDR_IPv6;
                        }
                    }
                    if(type) {
                        NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                        addresses[key] = [NSString stringWithUTF8String:addrBuf];
                    }
                }
            }
            // Free memory
            freeifaddrs(interfaces);
        }
        return [addresses count] ? addresses : nil;
    }
    
    @end
    

    2.ip配置文件

    .h

    #import <Foundation/Foundation.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <sys/sockio.h>
    #include <net/if.h>
    #include <errno.h>
    #include <net/if_dl.h>
    #include <net/ethernet.h>
    #include <ifaddrs.h>
    #include <arpa/inet.h>
    
    #define BUFFERSIZE  4000
    #define MAXADDRS    32
    #define min(a,b)    ((a) < (b) ? (a) : (b))
    #define max(a,b)    ((a) > (b) ? (a) : (b))
    
    @interface IPAddressConfig : NSObject
    // extern
    extern char *if_names[MAXADDRS];
    extern char *ip_names[MAXADDRS];
    extern char *hw_addrs[MAXADDRS];
    extern unsigned long ip_addrs[MAXADDRS];
    
    // Function prototypes
    void InitAddresses();
    void FreeAddresses();
    void GetIPAddresses();
    void GetHWAddresses();
    @end
    
    

    .m

    #import "IPAddressConfig.h"
    
    @implementation IPAddressConfig
    char *if_names[MAXADDRS];
    char *ip_names[MAXADDRS];
    char *hw_addrs[MAXADDRS];
    unsigned long ip_addrs[MAXADDRS];
    
    static int   nextAddr = 0;
    
    void InitAddresses()
    {
        int i;
        for (i=0; i<MAXADDRS; ++i)
        {
            if_names[i] = ip_names[i] = hw_addrs[i] = NULL;
            ip_addrs[i] = 0;
        }
    }
    
    void FreeAddresses()
    {
        int i;
        for (i=0; i<MAXADDRS; ++i)
        {
            if (if_names[i] != 0) free(if_names[i]);
            if (ip_names[i] != 0) free(ip_names[i]);
            if (hw_addrs[i] != 0) free(hw_addrs[i]);
            ip_addrs[i] = 0;
        }
        InitAddresses();
    }
    
    void GetIPAddresses()
    {
        int                 i, len, flags;
        char                buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
        struct ifconf       ifc;
        struct ifreq        *ifr, ifrcopy;
        struct sockaddr_in  *sin;
        
        char temp[80];
        
        int sockfd;
        
        for (i=0; i<MAXADDRS; ++i)
        {
            if_names[i] = ip_names[i] = NULL;
            ip_addrs[i] = 0;
        }
        
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0)
        {
            perror("socket failed");
            return;
        }
        
        ifc.ifc_len = BUFFERSIZE;
        ifc.ifc_buf = buffer;
        
        if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
        {
            perror("ioctl error");
            return;
        }
        
        lastname[0] = 0;
        
        for (ptr = buffer; ptr < buffer + ifc.ifc_len; )
        {
            ifr = (struct ifreq *)ptr;
            len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
            ptr += sizeof(ifr->ifr_name) + len;   // for next one in buffer
            
            if (ifr->ifr_addr.sa_family != AF_INET)
            {
                continue; // ignore if not desired address family
            }
            
            if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL)
            {
                *cptr = 0;        // replace colon will null
            }
            
            if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0)
            {
                continue; /* already processed this interface */
            }
            
            memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
            
            ifrcopy = *ifr;
            ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
            flags = ifrcopy.ifr_flags;
            if ((flags & IFF_UP) == 0)
            {
                continue; // ignore if interface not up
            }
            
            if_names[nextAddr] = (char *)malloc(strlen(ifr->ifr_name)+1);
            if (if_names[nextAddr] == NULL)
            {
                return;
            }
            strcpy(if_names[nextAddr], ifr->ifr_name);
            
            sin = (struct sockaddr_in *)&ifr->ifr_addr;
            strcpy(temp, inet_ntoa(sin->sin_addr));
            
            ip_names[nextAddr] = (char *)malloc(strlen(temp)+1);
            if (ip_names[nextAddr] == NULL)
            {
                return;
            }
            strcpy(ip_names[nextAddr], temp);
            
            ip_addrs[nextAddr] = sin->sin_addr.s_addr;
            
            ++nextAddr;
        }
        
        close(sockfd);
    }
    
    void GetHWAddresses()
    {
        struct ifconf ifc;
        struct ifreq *ifr;
        int i, sockfd;
        char buffer[BUFFERSIZE], *cp, *cplim;
        char temp[80];
        
        for (i=0; i<MAXADDRS; ++i)
        {
            hw_addrs[i] = NULL;
        }
        
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0)
        {
            perror("socket failed");
            return;
        }
        
        ifc.ifc_len = BUFFERSIZE;
        ifc.ifc_buf = buffer;
        
        if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0)
        {
            perror("ioctl error");
            close(sockfd);
            return;
        }
        
        ifr = ifc.ifc_req;
        
        cplim = buffer + ifc.ifc_len;
        
        for (cp=buffer; cp < cplim; )
        {
            ifr = (struct ifreq *)cp;
            if (ifr->ifr_addr.sa_family == AF_LINK)
            {
                struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
                int a,b,c,d,e,f;
                int i;
                
                strcpy(temp, (char *)ether_ntoa((const struct ether_addr *)LLADDR(sdl)));
                sscanf(temp, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
                sprintf(temp, "%02X:%02X:%02X:%02X:%02X:%02X",a,b,c,d,e,f);
                
                for (i=0; i<MAXADDRS; ++i)
                {
                    if ((if_names[i] != NULL) && (strcmp(ifr->ifr_name, if_names[i]) == 0))
                    {
                        if (hw_addrs[i] == NULL)
                        {
                            hw_addrs[i] = (char *)malloc(strlen(temp)+1);
                            strcpy(hw_addrs[i], temp);
                            break;
                        }
                    }
                }
            }
            cp += sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
        }
        close(sockfd);
    }
    
    @end
    
    

    文件结构:


    截屏2020-10-30 16.52.15.png

    参考:
    https://www.jianshu.com/p/94d5b14ce24e

    相关文章

      网友评论

          本文标题:手机ip地址

          本文链接:https://www.haomeiwen.com/subject/gqvdvktx.html