আমি আমার আইপ্যাডের আইপি ঠিকানা প্রোগ্রামগতভাবে পেতে চাই। আমার আইপিভি 4 (এবং আইপিভি 6) ঠিকানাগুলি কী কী তা জানতে আমি কীভাবে নেটওয়ার্কিং সাবসিস্টেমটিকে জিজ্ঞাসা করতে পারি?
PS: আমি কি কোনওভাবে আইপিভি 6 অক্ষম করতে পারি?
আমি আমার আইপ্যাডের আইপি ঠিকানা প্রোগ্রামগতভাবে পেতে চাই। আমার আইপিভি 4 (এবং আইপিভি 6) ঠিকানাগুলি কী কী তা জানতে আমি কীভাবে নেটওয়ার্কিং সাবসিস্টেমটিকে জিজ্ঞাসা করতে পারি?
PS: আমি কি কোনওভাবে আইপিভি 6 অক্ষম করতে পারি?
উত্তর:
নিম্নলিখিত কোডটি কোনও আইওএস বা ওএসএক্স ডিভাইসে সমস্ত আইপিভি 4 এবং আইপিভি 6 ঠিকানা খুঁজে পায়। প্রথম getIPAddress
পদ্ধতিটি এই উত্তরে পুরানো কোড হিসাবে কমবেশি কাজ করে: আপনি এক বা অন্য ধরণের ঠিকানা পছন্দ করতে পারেন এবং এটি সর্বদা সেলুলারের চেয়ে WIFI পছন্দ করে (সম্ভবত আপনি এটি পরিবর্তন করতে পারেন)।
আরও মজার বিষয় হল এটি পাওয়া সমস্ত ঠিকানার একটি অভিধান, not up
ইন্টারফেসের জন্য ঠিকানাগুলি এড়িয়ে যাওয়া , বা এর সাথে সম্পর্কিত ঠিকানাগুলিতে ফিরে আসতে পারে loopback
। পূর্ববর্তী কোড এবং এই বিষয়গুলির অন্যান্য সমাধানগুলি আইপিভি 6 সঠিকভাবে ডিকোড করবে না (inet_ntoa তাদের সাথে ডিল করতে পারে না)। এটি একটি অ্যাপল ফোরামে জেনস আলফকের দ্বারা আমার দিকে ইঙ্গিত করা হয়েছিল - ব্যবহারের সঠিক ফাংশনটি হ'ল inet_ntop (ম্যান পৃষ্ঠাটি দেখুন, এবং জেনস দ্বারা সরবরাহ করা এই inet_ntop নিবন্ধটি দেখুন)।
অভিধান কীগুলিতে "ইন্টারফেস" "/" "ipv4 বা ipv6" রূপ রয়েছে।
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
//#define IOS_VPN @"utun0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
- (NSString *)getIPAddress:(BOOL)preferIPv4
{
NSArray *searchArray = preferIPv4 ?
@[ /*IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6,*/ 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;
}
EDIT1: কোড 16 ই মে, 2014 আপডেট হয়েছে (বাগ লুনাথ দ্বারা নির্দেশিত, মন্তব্য দেখুন)। লুপব্যাকের ঠিকানাগুলি এখন ফিরে এসেছে, তবে এগুলি নিজে বাদ দিয়ে পরীক্ষার জন্য কোনও অসুবিধা করা আপনার পক্ষে সহজ।
সম্পাদনা 2: (কিছু অজানা ব্যক্তি দ্বারা): 13 মার্চ, 2015 আরও উন্নত: যদি ব্যবহারকারী কোনও ভিপিএন (ওয়াইফাই বা সেলুলার নির্বিশেষে) ব্যবহার করে তবে আগের কোডটি ব্যর্থ হত। এখন এটি ভিপিএন সংযোগ নিয়েও কাজ করে। ভিপিএন সংযোগগুলিকে ওয়াইফাই এবং সেল এর চেয়ে বেশি প্রাধান্য দেওয়া হয় কারণ ডিভাইসটি সেভাবেই এটি পরিচালনা করে। এটি এমনকি ম্যাকদের জন্য কাজ করা উচিত কারণ কোনও ম্যাকের ভিপিএন সংযোগটি যদি আইফ ইউটিউন 0 ব্যবহার করে তবে পরীক্ষিত হয় না।
EDIT3: (9/8/2016) ভিপিএন কোড (যা অন্য কেউ যুক্ত করেছেন) দিয়ে @ কিউলাং (মন্তব্যগুলি দেখুন) দ্বারা প্রাপ্ত সমস্যাগুলি দেখে আমি এ সম্পর্কে মন্তব্য করেছি। যদি কোনও ব্যবহারকারী ভিপিএন কীভাবে নির্দিষ্ট করতে হয় তা যদি কেউ নির্দিষ্টভাবে জানেন তবে দয়া করে একটি মন্তব্য দিয়ে চিমে দিন।
addr
নুল হয়? আমার ব্যবহারকারীরা মাঝে মাঝে NULL পান get আপনি কি সম্ভাব্য কারণ জানেন?
AF_INET
পরীক্ষা করতে ব্যবহার করছি । এই হতে পারে?
আপনার প্রয়োগের ফাইল। মি।
#import <ifaddrs.h>
#import <arpa/inet.h>
// Get IP Address
- (NSString *)getIPAddress {
NSString *address = @"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
while(temp_addr != NULL) {
if(temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
// Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return address;
}
অনেক বিদ্যমান সমাধান কেবল ওয়্যারলেস ইন্টারফেস বিবেচনা করে, যা ইথারনেট অ্যাডাপ্টারের মাধ্যমে তারযুক্ত সংযোগগুলির জন্য কাজ করবে না (যেমন কোনও ওয়াইফাই বা 3 জি নয়); এটি আরও সাম্প্রতিক সমাধান দেখুন যা তারযুক্ত ইন্টারফেসের মাধ্যমে প্রাপ্ত আইপি ঠিকানাগুলিকেও বিবেচনা করে।
আইপ্যাড: কীভাবে আইপি অ্যাড্রেস পাবেন প্রোগ্রামিয়ালি ওয়্যারিড (ওয়্যারলেস মাধ্যমে নয়)
সুইফট 3 ব্যবহার করে আইপি ঠিকানা পান:
func getIPAddress() -> String {
var address: String = "error"
var interfaces: ifaddrs? = nil
var temp_addr: ifaddrs? = nil
var success: Int = 0
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(interfaces)
if success == 0 {
// Loop through linked list of interfaces
temp_addr = interfaces
while temp_addr != nil {
if temp_addr?.ifa_addr?.sa_family == AF_INET {
// Check if interface is en0 which is the wifi connection on the iPhone
if (String(utf8String: temp_addr?.ifa_name) == "en0") {
// Get NSString from C String
address = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
}
}
temp_addr = temp_addr?.ifa_next
}
}
// Free memory
freeifaddrs(interfaces)
return address
}
বর্তমান সমাধানটি ওএস এক্স-এ এন0 ডিভাইসটি ফেরত দেয় না, নীচের কোডটি ইন্টারফেসগুলি পেতে সিস্টেম কনফিগারেশন ফ্রেমওয়ার্ক ব্যবহার করে তারপরে আইপি ঠিকানা পাওয়ার জন্য স্ট্যান্ডার্ড সি ফাংশন ব্যবহার করে।
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define IFT_ETHER 0x6
#include <SystemConfiguration/SCDynamicStore.h>
+(void)getInterfaces
{
SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)@"FindCurrentInterfaceIpMac", NULL, NULL);
CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface"));
id primaryInterface = [(__bridge NSDictionary *)global valueForKey:@"Interfaces"];
for (NSString* item in primaryInterface)
{
if(get_iface_address([item UTF8String]))
{
NSString *ip = [NSString stringWithUTF8String:get_iface_address([item UTF8String])];
NSLog(@"interface: %@ - %@",item,ip);
} else
NSLog(@"interface: %@",item);
}
}
static char * get_iface_address (char *interface)
{
int sock;
uint32_t ip;
struct ifreq ifr;
char *val;
if (!interface)
return NULL;
/* determine UDN according to MAC address */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket");
return NULL;
}
strcpy (ifr.ifr_name, interface);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl (sock, SIOCGIFADDR, &ifr) < 0)
{
perror ("ioctl");
close (sock);
return NULL;
}
val = (char *) malloc (16 * sizeof (char));
ip = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
ip = ntohl (ip);
sprintf (val, "%d.%d.%d.%d",
(ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF);
close (sock);
return val;
}
এই উত্তরটি @ ডেভিডএইচ এর উত্তর দ্বারা অনুপ্রাণিত হয়েছিল। আমি কিছু সমস্যা স্থির করেছি, এর সাথে প্রতিস্থাপন inet_ntop
করা হয়েছে getnameinfo
যা পরিষ্কারের পদ্ধতির অনুমতি দেয়। নোট করুন যে এটি একটি অভিধান পেয়েছে যা আইপি অ্যাড্রেসের একটি অ্যারেতে একটি ইন্টারফেসের নাম ম্যাপ করে (একটি ইন্টারফেসে প্রযুক্তিগতভাবে একাধিক আইপিভি 4 এবং আইপিভি 6 এর সাথে যুক্ত থাকতে পারে)। এটি IPv4 এবং IPv6 এর মধ্যে পার্থক্য করে না:
// Get all our interface addresses.
struct ifaddrs *ifAddresses;
if (getifaddrs( &ifAddresses ) != 0) {
NSLog( @"Couldn't get interface addresses: %d", errno );
return nil;
}
int error;
char host[MAX( INET_ADDRSTRLEN, INET6_ADDRSTRLEN )];
_ipAddressesByInterface = [NSMutableDictionary dictionaryWithCapacity:8];
for (struct ifaddrs *ifAddress = ifAddresses; ifAddress; ifAddress = ifAddress->ifa_next) {
if (!(ifAddress->ifa_flags & IFF_UP) || (ifAddress->ifa_flags & IFF_LOOPBACK))
// Ignore interfaces that aren't up and loopback interfaces.
continue;
if (ifAddress->ifa_addr->sa_family != AF_INET && ifAddress->ifa_addr->sa_family != AF_INET6)
// Ignore non-internet addresses.
continue;
if ((error = getnameinfo( ifAddress->ifa_addr, ifAddress->ifa_addr->sa_len, host, sizeof( host ), NULL, 0, NI_NUMERICHOST )) != noErr) {
// Couldn't to format host name for this address.
NSLog( @"Couldn't resolve host name for address: %s", gai_strerror( error ) );
continue;
}
NSString *ifName = [NSString stringWithCString:ifAddress->ifa_name encoding: NSUTF8StringEncoding];
NSMutableArray *ifIpAddresses = _ipAddressesByInterface[ifName];
if (!ifIpAddresses)
ifIpAddresses = _ipAddressesByInterface[ifName] = [NSMutableArray arrayWithCapacity:2];
[ifIpAddresses addObject:[NSString stringWithCString:host encoding: NSUTF8StringEncoding]];
}
freeifaddrs( ifAddresses );
return _ipAddressesByInterface;
strf
- আপনার কোডটিতে কোনও সহায়ক ফাংশন কি এটি?
err
এবং strf
। আপনি শুধু প্রতিস্থাপন করতে পারেন strf
সঙ্গে -stringWithCString:encoding:
। err
এমন একটি NSLog
মোড়ক যা ফাইল ও লাইনকেও আউটপুট করে। github.com/Lyndir/Pearl/blob/master/Pearl/…
@ 4D সেলুলার নেটওয়ার্ক থেকে এই ফলাফল না পাওয়া পর্যন্ত @ ডেভিডএইচ এর উত্তর ঠিক আছে:
{
"lo0/ipv4" = "127.0.0.1";
"lo0/ipv6" = "fe80::1";
"pdp_ip0/ipv4" = "10.132.76.168";
"utun0/ipv6" = "fe80::72c3:e25e:da85:b730";
}
আমি ভিপিএন ব্যবহার করছি না তাই আমার কেন ইউটিউন 0 / আইপিভি 6 ছিল আমার কোনও ধারণা নেই।
--- আপডেট ---
আমি এই সমস্যাটি আরও ডিবাগ করেছি এবং দেখতে পেয়েছি যে আমি অন্য 4 জি নেটওয়ার্কগুলিতেও এটি একটি নকল ভিপিএন ঠিকানা পেতে পারি (এটি কি আইওএস বাগ আছে ??),
{
""awdl0/ipv6"" = ""fe80::c018:9fff:feb2:988"";
""en0/ipv6"" = ""fe80::181a:2e43:f91b:db2b"";
""lo0/ipv4"" = ""127.0.0.1"";
""lo0/ipv6"" = ""fe80::1"";
""pdp_ip0/ipv4"" = ""10.48.10.210"";
""utun0/ipv4"" = ""192.168.99.2"";
}
আমি ভিপিএন ব্যবহার না করলে আমি এটি পেয়ে যাব:
{
"lo0/ipv4" = "127.0.0.1";
"lo0/ipv6" = "fe80::1";
"pdp_ip0/ipv4" = "10.49.187.23";
"utun0/ipv6" = "fe80::5748:5b5d:2bf0:658d";
"utun1/ipv4" = "192.168.99.2"; //the real one
}
সুতরাং এটি utun1 নয় utun0
আমাকে কেবল ভিপিএন চেক কেন ফেলে দিতে হবে তা নির্ধারণ না করে :(
---- হালনাগাদ ----
আমি আপেলের কাছে একটি বাগ (28131847) উত্থাপন করেছি এবং জবাব দিয়েছিলাম "সমস্ত ইউটুন ইন্টারফেস ভিপিএন এর জন্য নয় There অন্যান্য ওএস বৈশিষ্ট্যগুলিও ইউটুন ইন্টারফেস ব্যবহার করে" "
তবে যখন আমি কীভাবে একটি বৈধ ভিপিএন আইপি ঠিকানা পেতে জিজ্ঞাসা করেছি, তখন তাদের উত্তরটি বরং হতাশ হয়েছিল, "আপনি সেটিংসে যেতে পারেন -> ভিপিএন এবং ভিপিএন সক্রিয় আছে কিনা তা দেখতে আপনার ভিপিএন কনফিগারেশনটি দেখুন some কিছু ক্ষেত্রে আপনি দেখতে পারেন সেখানেও নির্ধারিত আইপি ঠিকানা there এখন আমরা এই বাগ রিপোর্টটি বন্ধ করছি "" :(
---- আপডেট 2016/11/04 ----
আমি আবার সমস্যায় পড়েছি এবং এটি সমাধানের জন্য আমাকে @ ডেভিডএইচ এর উত্তর আরও সংশোধন করতে হবে:
আমি 4 জি নেটওয়ার্কে ছিলাম এবং আমি এই ঠিকানাটি পেয়েছি:
addresses: {
"awdl0/ipv6" = "fe80::98fd:e6ff:fea9:3afd";
"en0/ipv6" = "fe80::8dd:7d92:4159:170e";
"lo0/ipv4" = "127.0.0.1";
"lo0/ipv6" = "fe80::1";
"pdp_ip0/ipv4" = "10.37.212.102";
"utun0/ipv6" = "fe80::279c:ea56:a2ef:d128";
}
তার আসল উত্তরের সাথে আমি ওয়াইফাই আইপি fe80 পেয়ে যাব: 8 ডিডি: 7d92: 4159: 170e, যা জাল ছিল এবং সংযোগ ব্যর্থ হয়েছিল।
তাই আমি কোডটি পছন্দ করতে পরিবর্তিত করেছি,
[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
{
if ((internetReach.isReachableViaWiFi && [key hasPrefix:IOS_WIFI]) ||
(internetReach.isReachableViaWWAN && [key hasPrefix:IOS_CELLULAR])) {
address = addresses[key];
if(address) *stop = YES;
}
} ];
এই ফাইলটিতে দ্রুত পরিবর্তন করার জন্য দুর্দান্ত সমাধান যা সমস্ত বিবরণ সরবরাহ করে।
আমার একটি অ্যাপে আমার ওয়াইফাই আইপি ঠিকানা আনতে হবে। আমি উপরের উত্তরগুলি ব্যবহার করেছি, তিনটি দ্রুতগতিতে:
let WIFI_IF = "en0"
let UNKNOWN_IP_ADDRESS = ""
var addresses: [AnyHashable: Any] = ["wireless": UNKNOWN_IP_ADDRESS, "wired": UNKNOWN_IP_ADDRESS, "cell": UNKNOWN_IP_ADDRESS]
var interfaces: UnsafeMutablePointer<ifaddrs>? = nil
var temp_addr: UnsafeMutablePointer<ifaddrs>? = nil
var success: Int = 0
success = Int(getifaddrs(&interfaces))
if success == 0 {
temp_addr = interfaces
while temp_addr != nil {
if temp_addr?.pointee.ifa_addr == nil {
continue
}
if temp_addr?.pointee.ifa_addr.pointee.sa_family == UInt8(AF_INET) {
if (String(utf8String: (temp_addr?.pointee.ifa_name)!) == WIFI_IF) {
addresses["wireless"] = String(utf8String: inet_ntoa(((temp_addr?.pointee.ifa_addr as? sockaddr_in)?.sin_addr)!))
}
}
temp_addr = temp_addr?.pointee.ifa_next
}
}
এই কোডে, এটি ক্র্যাশ হয়েছে কারণ আমি nil
statementচ্ছিক হিসাবে ব্যবহার করেছি প্রতিটি বিবৃতিতে আমাকে পরীক্ষা করতে হবে ?
। সুতরাং আমার ক্লাসে প্রদত্ত লিঙ্কযুক্ত ফাইলটি ব্যবহার করা আমার পক্ষে ভাল। আমার মতো এখন চেক করা সহজ হয়ে যায়:
class func getWifiIPAddress() -> String {
var wifiIp = ""
let WIFI_IF = "en0"
let allInterface = Interface.allInterfaces()
for interf in allInterface {
if interf.name == WIFI_IF {
if let address = interf.address {
if address.contains(".") {
wifiIp = address
break
}
}
}
}
return wifiIp
}
আমি স্ট্রিংটি পার্স করেছি "."
কারণ ইন্টারফেস ক্লাস আমার en0
আইফোনটিতে "fb00 ::" এর মতো ঠিকানা এবং "101.10.1.1" এর মতো ঠিকানা হিসাবে দুটি ইন্টারফেস দেয়
আইপি ঠিকানা পাওয়ার জন্য আমি একটি সহজ ফাইল তৈরি করেছি। আমি এই সমাধানটি @ লুন্ডজেম, @ ডেভিডএইচ এবং @ ইহুনাথের উত্তরগুলির ভিত্তিতে তৈরি করেছি। এটি তারযুক্ত সংযোগ বিবেচনা করে। যদিও আমি এই সমাধানে ভিপিএন অন্তর্ভুক্ত করি নি।
PCNetwork.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface PCNetwork : NSObject
+ (NSString *)getIPAddress; // Prefers IPv4
+ (NSString *)getIPAddress:(BOOL)preferIPv4;
+ (NSDictionary *)getIPAddresses;
@end
NS_ASSUME_NONNULL_END
PCNetwork.m
#import "PCNetwork.h"
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
#define IP_UNKNOWN @"0.0.0.0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
@implementation PCNetwork
#pragma mark - IP
+ (NSString *)getIPAddress {
return [self getIPAddress:YES];
}
+ (NSString *)getIPAddress:(BOOL)preferIPv4 {
NSArray *searchArray = [self getAllIFSearchArray:preferIPv4];
NSDictionary *addresses = [self getIPAddresses];
DLog(@"addresses: %@", addresses);
__block NSString *address = nil;
[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
address = addresses[key];
if(address) *stop = YES;
}];
return address ?: IP_UNKNOWN;
}
+ (NSDictionary *)getIPAddresses {
NSMutableDictionary *addresses = [NSMutableDictionary dictionary];
struct ifaddrs *interfaces;
BOOL success = !getifaddrs(&interfaces); // Retrieve the current interfaces : returns 0 on success
if (success) {
struct ifaddrs *temp_interface;
for (temp_interface = interfaces; temp_interface; temp_interface = temp_interface->ifa_next) { // Loop through linked list of interfaces
if (!(temp_interface->ifa_flags & IFF_UP) || (temp_interface->ifa_flags & IFF_LOOPBACK)) { // Ignore interfaces that aren't up and loopback interfaces.
continue;
}
if (!temp_interface->ifa_addr) {
continue;
}
const struct sockaddr_in *temp_addr = (const struct sockaddr_in*)temp_interface->ifa_addr;
if (temp_addr->sin_family == AF_INET || temp_addr->sin_family == AF_INET6) {
char addrBuf[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
NSString *name = [NSString stringWithUTF8String:temp_interface->ifa_name];
NSString *type = nil;
if (temp_addr->sin_family == AF_INET) {
if (inet_ntop(AF_INET, &temp_addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
type = IP_ADDR_IPv4;
}
} else {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)temp_interface->ifa_addr; // AF_INET6
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];
}
}
}
freeifaddrs(interfaces); // Free memory
}
return addresses.count ? addresses.copy : nil;
}
#pragma mark - Inter Frame Spacing
+ (NSArray *)getAllIFSearchArray:(BOOL)preferIPv4 {
NSArray *KNOWN_WIFI_IFS = @[@"en0"];
NSArray *KNOWN_WIRED_IFS = @[@"en1",@"en2",@"en3",@"en4"];
NSArray *KNOWN_CELL_IFS = @[@"pdp_ip0",@"pdp_ip1",@"pdp_ip2",@"pdp_ip3"];
NSMutableArray *searchArray = [NSMutableArray array];
// Add wifi
[searchArray addObjectsFromArray:[self getIFSearchArrayWith:KNOWN_WIFI_IFS preferIPv4:preferIPv4]];
// Add cell
[searchArray addObjectsFromArray:[self getIFSearchArrayWith:KNOWN_CELL_IFS preferIPv4:preferIPv4]];
// Add wired
[searchArray addObjectsFromArray:[self getIFSearchArrayWith:KNOWN_WIRED_IFS preferIPv4:preferIPv4]];
return searchArray.copy;
}
+ (NSArray *)getIFSearchArrayWith:(NSArray *)iFList preferIPv4:(BOOL)preferIPv4 {
NSMutableArray *searchArray = [NSMutableArray array];
for (NSString *iFType in iFList) {
if (preferIPv4) {
[searchArray addObject:[NSString stringWithFormat:@"%@/%@", iFType, IP_ADDR_IPv4]];
[searchArray addObject:[NSString stringWithFormat:@"%@/%@", iFType, IP_ADDR_IPv6]];
} else {
[searchArray addObject:[NSString stringWithFormat:@"%@/%@", iFType, IP_ADDR_IPv6]];
[searchArray addObject:[NSString stringWithFormat:@"%@/%@", iFType, IP_ADDR_IPv4]];
}
}
return searchArray.copy;
}
@end
আইওএসে 13.4.1 আমার পক্ষে কাজ করে না। আমি এই ঠিক এটি ব্যবহার।
+ (NSString *)getIPAddress{
NSArray *searchArray =
@[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_4_3G @"/" IP_ADDR_IPv4, IOS_4_3G @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6];
__block NSDictionary *addresses = [self getIPAddressArray];
__block NSString *address;
[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
{
address = addresses[key];
if ([key rangeOfString:@"ipv6"].length > 0 && ![[NSString stringWithFormat:@"%@",addresses[key]] hasPrefix:@"(null)"] ) {
if ( ![addresses[key] hasPrefix:@"fe80"]) {
// isIpv6 = YES;
*stop = YES;
}
}else{
if([self isValidatIP:address]) {
*stop = YES;
}
}
} ];
return address ? address : @"error";
}
+ (NSString *)getIPType{
NSString *ipAddress = [self getIPAddress];
if ([self isValidatIP:ipAddress]) {
return @"04";//ipv4
}else{
return @"06";//ipv6
}
}
+ (NSDictionary *)getIPAddressArray{
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;
}
+ (BOOL)isValidatIP:(NSString *)ipAddress {
if (ipAddress.length == 0) {
return NO;
}
NSString *urlRegEx = @"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlRegEx options:0 error:&error];
if (regex != nil) {
NSTextCheckingResult *firstMatch=[regex firstMatchInString:ipAddress options:0 range:NSMakeRange(0, [ipAddress length])];
if (firstMatch) {
NSRange resultRange = [firstMatch rangeAtIndex:0];
NSString *result=[ipAddress substringWithRange:resultRange];
//输出结果
NSLog(@"%@",result);
return YES;
}
}
return NO;
}