I am trying to build a network scanner. I know the procedure so I want to ping all available hosts in the network and then get the ARP table so I can map the MAC address for each IP. I Googled for ARP table but I didn't find any guide how to implement this feature. I also found these similar questions on Stack overflow:
The answer are unclear on how to implement the ARP feature. Is there any official guide for this one? Is Apple approving the ARP table feature?
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:
route.h
and if_types.h
and from the "netinet" folder copy the if_ether.h
into your Xcode project..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
ViewController
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)