Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS - Get ARP table

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:

Link1

Link2

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?

like image 392
BlackM Avatar asked Jul 05 '15 01:07

BlackM


1 Answers

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)

like image 198
BlackM Avatar answered Sep 22 '22 13:09

BlackM