在objective-c中,如果extern IP位于自己的子网范围内,则清理解决scheme以进行查找

大家好,我正在寻找一个更好的解决scheme来检查/计算IP地址是否在像你的iPhone一样的子网。

背景:我正在通过Zeroconf / Bonjour查找设备,这个设备可以有多个IP地址。 所以我想检查我的设备可以到达哪些设备。 我认为最简单的方法是采取外部IP连接与我的子网掩码,但我还没有find任何方法直接做(需要两个都是int),所以我提出了一个解决方法。

代码:

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <ifaddrs.h> #include <netdb.h> #include <net/if.h> -(void)netServiceDidResolveAddress:(NSNetService *)service { NSLog(@" # # # Bonjour.netServiceDidResolveAddress # # # "); self.isConnected = YES; self.connectedService = service; NSLog(@"service.hostName : %@", service.hostName); NSLog(@"service.name : %@", service.name); NSLog(@"service.description: %@", service.description); // # # # // get MAC-ADDR from TXTRecordData NSData *txtRecord = service.TXTRecordData; unsigned char aBuffer[[txtRecord length]]; [txtRecord getBytes:aBuffer length:[txtRecord length]]; NSString *macAddr = [NSString stringWithCString:(const char *)aBuffer encoding:NSStringEncodingConversionAllowLossy]; if(macAddr && macAddr.length >28) { macAddr = [macAddr substringFromIndex:12]; macAddr = [macAddr substringToIndex:17]; } NSLog(@"service.macAddr: %@", macAddr); // # # # NSString *name = nil; NSData *address = nil; struct sockaddr_in *socketAddress = nil; NSString *ipString = nil; int port; int i = 0; for (i = 0; i < [[service addresses] count]; i++) { NSString *ip; name = [service name]; address = [[service addresses] objectAtIndex:i]; socketAddress = (struct sockaddr_in *)[address bytes]; ip = [NSString stringWithFormat: @"%s", inet_ntoa (socketAddress->sin_addr)]; if([ip isEqualToString:@"0.0.0.0"]) continue; NSLog(@"- - - "); if([self isIpInSubnet:ip]) { ipString = [ip copy]; port = service.port; NSLog(@"set IP"); } NSLog(@"%@", ipString); NSLog(@"%d", port); } .... } 

 - (BOOL)isIpInSubnet:(NSString *)targetIP{ // http://www.cocoabuilder.com/archive/cocoa/127230-finding-subnet.html // http://veys.com/ struct ifaddrs *ifap, *ifp; char ip[NI_MAXHOST], nm[NI_MAXHOST]; BOOL isInMask = NO; if(getifaddrs(&ifap) < 0) perror("getifaddrs"); for(ifp = ifap; ifp; ifp = ifp->ifa_next) { /* Ignore everything but IPv4 */ if(ifp->ifa_addr->sa_family != AF_INET ) continue; /* Ignore interfaces marked down. */ if(!(ifp->ifa_flags & IFF_UP)) continue; /* Ignore interfaces without netmask. */ if(!ifp->ifa_netmask) continue; if(getnameinfo(ifp->ifa_addr, ifp->ifa_addr->sa_len, ip, sizeof(ip), NULL, 0, NI_NUMERICHOST) != 0) perror("getnameinfo"); if(getnameinfo(ifp->ifa_netmask, ifp->ifa_netmask->sa_len, nm, sizeof(nm), NULL, 0, NI_NUMERICHOST) != 0) perror("getnameinfo"); /* Ignore interfaces for localhost. */ if([[NSString stringWithFormat:@"%s", ip] isEqualToString:@"127.0.0.1"]) continue; // # # # # # # # # # # # # NSArray *ipChunks = [targetIP componentsSeparatedByString:@"."]; // chunks for extern IP NSArray *nmChunks = [[NSString stringWithFormat:@"%s",nm] componentsSeparatedByString:@"."]; NSUInteger ipRaw = 0; NSUInteger nmRaw = 0; NSUInteger shift = 24; for (NSUInteger i = 0; i < 4; ++i, shift -= 8) { ipRaw |= [[ipChunks objectAtIndex:i] intValue] << shift; nmRaw |= [[nmChunks objectAtIndex:i] intValue] << shift; } NSUInteger bcRaw = nmRaw & ipRaw; // lowest interface addr. NSString *nw1 = [NSString stringWithFormat:@"%d.%d.%d.%d", (bcRaw & 0xFF000000) >> 24, (bcRaw & 0x00FF0000) >> 16, (bcRaw & 0x0000FF00) >> 8, bcRaw & 0x000000FF]; ipRaw = nmRaw = 0; shift = 24; ipChunks = [[NSString stringWithFormat:@"%s",ip] componentsSeparatedByString:@"."]; // chunks for local IP for (NSUInteger i = 0; i < 4; ++i, shift -= 8) { ipRaw |= [[ipChunks objectAtIndex:i] intValue] << shift; nmRaw |= [[nmChunks objectAtIndex:i] intValue] << shift; } bcRaw = nmRaw & ipRaw; NSString *nw2 = [NSString stringWithFormat:@"%d.%d.%d.%d", (bcRaw & 0xFF000000) >> 24, (bcRaw & 0x00FF0000) >> 16, (bcRaw & 0x0000FF00) >> 8, bcRaw & 0x000000FF]; isInMask = [nw1 isEqualToString:nw2]; NSLog(@"intern: %@ - extern: %@", nw2, nw1); // # # # # # # # # # # # # NSLog(@"ip %@ is in range with %s in mask %s ? %@", targetIP, ip, nm, isInMask ? @"YES" : @"NO"); } // Free memory freeifaddrs(ifap); return isInMask; } 

如果有人有一个提示,使其更容易或某种更好的,他总是欢迎张贴他的解决scheme:)