Reputation: 113
I'm able to fetch connected devices IP and their MAC address and also would like to fetch the device's names and services(open ports).
Can somebody please help me with this?
Upvotes: 3
Views: 3024
Reputation: 11184
Here is sample project that can be helpful An iOS Local Area Network / wifi Scanner
Also u can try to use Bonjour
And here - even more regarding name of device in lan
I Found few variants:
1.
struct hostent *he;
struct in_addr ipv4addr;
inet_pton(AF_INET, [address UTF8String], &ipv4addr);
he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
if (he) {
printf("Host name: %s\n", he->h_name);
}
where [address UTF8String] - like 127.0.0.1 (ip)
2.
- (NSArray *)hostnamesForAddress:(NSString *)address {
// Get the host reference for the given address.
struct addrinfo hints;
struct addrinfo *result = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = PF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
int errorStatus = getaddrinfo([address cStringUsingEncoding:NSASCIIStringEncoding], NULL, &hints, &result);
if (errorStatus != 0) return @[[self getErrorDescription:errorStatus]];
CFDataRef addressRef = CFDataCreate(NULL, (UInt8 *)result->ai_addr, result->ai_addrlen);
if (addressRef == nil) return nil;
freeaddrinfo(result);
CFHostRef hostRef = CFHostCreateWithAddress(kCFAllocatorDefault, addressRef);
if (hostRef == nil) return nil;
CFRelease(addressRef);
BOOL isSuccess = CFHostStartInfoResolution(hostRef, kCFHostNames, NULL);
if (!isSuccess) return nil;
// Get the hostnames for the host reference.
CFArrayRef hostnamesRef = CFHostGetNames(hostRef, NULL);
NSMutableArray *hostnames = [NSMutableArray array];
for (int currentIndex = 0; currentIndex < [(__bridge NSArray *)hostnamesRef count]; currentIndex++) {
[hostnames addObject:[(__bridge NSArray *)hostnamesRef objectAtIndex:currentIndex]];
}
return hostnames;
}
- (NSString *)getErrorDescription:(NSInteger)errorCode
{
NSString *errorDescription = @"";;
switch (errorCode) {
case EAI_ADDRFAMILY: {
errorDescription = @" address family for hostname not supported";
break;
}
case EAI_AGAIN: {
errorDescription = @" temporary failure in name resolution";
break;
}
case EAI_BADFLAGS: {
errorDescription = @" invalid value for ai_flags";
break;
}
case EAI_FAIL: {
errorDescription = @" non-recoverable failure in name resolution";
break;
}
case EAI_FAMILY: {
errorDescription = @" ai_family not supported";
break;
}
case EAI_MEMORY: {
errorDescription = @" memory allocation failure";
break;
}
case EAI_NODATA: {
errorDescription = @" no address associated with hostname";
break;
}
case EAI_NONAME: {
errorDescription = @" hostname nor servname provided, or not known";
break;
}
case EAI_SERVICE: {
errorDescription = @" servname not supported for ai_socktype";
break;
}
case EAI_SOCKTYPE: {
errorDescription = @" ai_socktype not supported";
break;
}
case EAI_SYSTEM: {
errorDescription = @" system error returned in errno";
break;
}
case EAI_BADHINTS: {
errorDescription = @" invalid value for hints";
break;
}
case EAI_PROTOCOL: {
errorDescription = @" resolved protocol is unknown";
break;
}
case EAI_OVERFLOW: {
errorDescription = @" argument buffer overflow";
break;
}
}
return errorDescription;
}
Additional info u can get from getifaddrs(&interfaces)
where struct ifaddrs* interfaces
like
unsigned char *ptr;
ptr = (unsigned char *)LLADDR((struct sockaddr_dl *)(temp_addr)->ifa_addr);
NSString *ip = [NSString stringWithUTF8String: inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
NSArray *hostsNames = [self hostnamesForAddress:ip];
NSMutableDictionary *info = [NSMutableDictionary dictionaryWithDictionary:
@{
@"name": @(temp_addr->ifa_name),
@"flags": @(temp_addr->ifa_flags),
@"ip" : ip,
@"family": @(temp_addr->ifa_addr->sa_family),
@"mac" : [NSString stringWithFormat:@"MAC[%02x:%02x:%02x:%02x:%02x:%02x]", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)],
@"hostName" : hostsNames.count ? hostsNames : @""
}
];
As result u will get something like:
{
family = 2;
flags = 32841;
hostName = (
localhost
);
ip = "127.0.0.1";
mac = "MAC[00:00:00:00:00:00]";
name = lo0;
}
{
family = 18;
flags = 34915;
hostName = ""; //here empty due to one of the following problem or due to CFHostStartInfoResolution return NO - o this point required a little bit more works to be done
ip = "6.3.6.0";
mac = "MAC[02:00:00:00:00:00]";
name = en1;
}
Also this post very interesting and may be useful (I will investigate it later)
Some info that can be helpful regarding ifa_name
(interfaces)
// pdp_ip - interfaces are those that are used for 3G and cellular data
// lo = localhost
// en = ether
// eth - ethernet
// wlan, ww, wl - Wifi - Wireless LAN
// awdl - ???
// utun - ???
// ap - is used to represent currently active data connection, Wi-Fi, cellular data or bluetooth or for access point
// bridge - Active hotSpot connection
// sl -- serial line IP (slip)
Upvotes: 2