2010-02-13 13 views

Odpowiedz

19

Ponieważ nikt nie odpowiedział na moje pytanie ... tutaj jest odpowiedź;)

#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" 
#include "route.h" 
#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> 

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



     int expire_time, flags, export_only, doing_proxy, found_entry; 



     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; 
     } 




    } 

z jabłek arp.c działa na iPhone

Skopiuj następujące:

- "if_types.h" 
- "route.h" 
- "if_ether.h" 

nagłówki z komputera Mac dołącza do folderu projektu i dodaje do klas:

+0

Dzięki za cynk. Skopiowałem tylko nagłówek "route.h", ponieważ pozostałe są zawarte w pakietach SDK (3.2+). –

+1

cześć, @ anthony iam otrzymuję błąd niezadeklarowanego identyfikatora nflag, co muszę uwzględnić, aby to zadziałało.? – Bonnie

+1

po prostu dodaj górę pliku static int nflag; –

7

Uprościliśmy de i naprawił wyciek pamięci.

Na moim komputerze pliki nagłówkowe znalezione w/usr/include/netinet i/usr/include/net.

- (NSString*)ip2mac:(in_addr_t)addr 
{ 
    NSString *ret = nil; 

    size_t needed; 
    char *buf, *next; 

    struct rt_msghdr *rtm; 
    struct sockaddr_inarp *sin; 
    struct sockaddr_dl *sdl; 

    int mib[6]; 

    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, sizeof(mib)/sizeof(mib[0]), NULL, &needed, NULL, 0) < 0) 
     err(1, "route-sysctl-estimate"); 

    if ((buf = (char*)malloc(needed)) == NULL) 
     err(1, "malloc"); 

    if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), buf, &needed, NULL, 0) < 0) 
     err(1, "retrieval of routing table"); 

    for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { 

     rtm = (struct rt_msghdr *)next; 
     sin = (struct sockaddr_inarp *)(rtm + 1); 
     sdl = (struct sockaddr_dl *)(sin + 1); 

     if (addr != sin->sin_addr.s_addr || sdl->sdl_alen < 6) 
      continue; 

     u_char *cp = (u_char*)LLADDR(sdl); 

     ret = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", 
       cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]]; 

     break; 
    } 

    free(buf); 

    return ret; 
} 
+0

Czy możesz podać jeden prosty kod demonstracyjny. Bcz nie jestem w stanie z niego skorzystać. Dzięki –

2

Nie jestem pewna funkcja sysctl jest częścią publicznych API. Użyłem tej metody jako oczywistej, a moja aplikacja została odrzucona z powodu użycia "niepublicznego" interfejsu API. Jednak nie wierzę, że jest jakikolwiek sposób na zrobienie tego innego niż metody przedstawione powyżej.

+0

Witaj new299, więc jeśli używam tego dla legalnej i publicznej aplikacji, zostanie ona odrzucona ze sklepu z aplikacjami? – FujiRoyale

+0

To było dla mnie, to było chwilę temu. Może warto spróbować. – new299

+1

Wiem, że jest to wyłączone z tematu, ale czy możliwe jest znalezienie sposobu na identyfikację urządzeń w sieci programowo, które będą akceptowane przez władze Apple? Zapytałem o SO [tutaj] (http://stackoverflow.com/questions/26534050/nsnetservicebrowser-to-find-any-device-on-network) – FujiRoyale

Powiązane problemy