iOS - Get Arp Table

iOS - Get ARP table

UPDATE AFTER 10.2

Check the library here

I finally got it working so I will post the procedure in detail to save some time for other guys:

  1. Go to Applications and right click on Xcode -> Show package contents and browse to: Developer ▸ Platforms ▸ MacOSX.platform ▸ Developer ▸ SDKs ▸ MacOSX10.10.sdk ▸ usr ▸ include. From "net" folder copy the route.h and if_types.h and from the "netinet" folder copy the if_ether.h into your Xcode project.
  2. Then import the following .m and .h files:

MacFinder.h

#import <Foundation/Foundation.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/sysctl.h>

#include <net/if.h>
#include <net/if_dl.h>
#include "if_types.h"

#if TARGET_IPHONE_SIMULATOR
#include <net/route.h>
#else
#include "route.h"
#endif

#include "if_ether.h"
#include <netinet/in.h>

#include <arpa/inet.h>

#include <err.h>
#include <errno.h>
#include <netdb.h>

#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

@interface MacFinder : NSObject{

int nflag;
}

-(NSString*) ip2mac: (char*)ip;

@end

MacFinder.m

#import "MacFinder.h"

@implementation MacFinder
-(NSString*) ip2mac: (char*)ip
{
int found_entry = 0;

NSString *mAddr = nil;
u_long addr = inet_addr(ip);
int mib[6];
size_t needed;
char *host, *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
extern int h_errno;
struct hostent *hp;

mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if ((buf = malloc(needed)) == NULL)
err(1, "malloc");
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
err(1, "actual retrieval of routing table");

lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (addr) {
if (addr != sin->sin_addr.s_addr)
continue;
found_entry = 1;
}
if (nflag == 0)
hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
sizeof sin->sin_addr, AF_INET);
else
hp = 0;
if (hp)
host = hp->h_name;
else {
host = "?";
if (h_errno == TRY_AGAIN)
nflag = 1;
}

if (sdl->sdl_alen) {

u_char *cp = LLADDR(sdl);

mAddr = [NSString stringWithFormat:@"%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];

// ether_print((u_char *)LLADDR(sdl));
}
else

mAddr = nil;

}

if (found_entry == 0) {
return nil;
} else {
return mAddr;
}

}
@end

  1. Then import the MacFinder.h file in your ViewController
  2. Example how to use it for each host you want to find the MAC Address:

MacFinder *mc = [[MacFinder alloc]init];
NSString *mac = [mc ip2mac:"192.168.10.24"];
NSLog(@"Mac:%@",mac);

If you still having trouble here is tutorial and here the full working project (Including the necessary files)

Getting ARP table on iPhone/iPad

After importing <netinet/if_ether.h>, you should edit it and change the line

#include <net/if_arp.h>

to

#include "if_arp.h"

and then import <net/if_arp.h> in your project as well. This should fix that error.

Anyway the headers you need to import to compile the code you posted are:

#include "if_ether.h"
#include "route.h"
#include "if_arp.h"
#include "if_dl.h"

Hope this helps =)

EDIT:

You need to "Add files to project", not simply importing it with #import or #include.
You can find above files from following links:
Files under "netinet"
Files under "net"

How does iOS app Fing get MAC Address?

Fing can only get the device's MAC address if the device is connected to a WiFi network. I suspect it implements an ARP scan on the local network and matches the known local IP address to determine the local MAC address.

There are some questions that address capturing ARP data here and here



Related Topics



Leave a reply



Submit