2010-02-13 3 views
8

Я новичок в разработке iPhone, и я хочу интегрировать wake-on-lan в мое приложение, не сжимая моих пользователей, чтобы ввести MAC-адрес компьютеров, когда IP уже известен. Я несколько раз искал Google, взял исходный код инструмента ARP, но я не знаю, как управлять этим на iPhone.Как запросить таблицу ARP на iPhone?

ответ

19

Поскольку никто не ответил на мой вопрос ... вот ответ;)

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




    } 

из яблок arp.c работает на Iphone

Скопируйте следующие:

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

заголовки от mac входит в вашу папку проекта и добавляет к классам

+0

Спасибо за подсказку. Я только скопировал заголовок «route.h», так как остальные включены в SDK (3.2+). –

+1

привет, @ anthony iam получение nflag необъявленной ошибки идентификатора, что мне нужно включить для этого, чтобы работать.? – Bonnie

+1

добавить в начало страницы static int nflag; –

7

Я упростил сотрудничество de и зафиксировал утечку памяти.

На моей машине файлы заголовков, найденные в/usr/include/netinet и/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

Можете ли вы предоставить один простой демо-код для него. Bcz я не могу использовать его. Спасибо –

2

Я не уверен, что функция sysctl является частью общедоступного API. Я использовал метод очевидным, и мое приложение было отклонено для использования «непубличным» API. Однако я также не считаю, что есть способ сделать это иначе, чем методы, показанные выше.

+0

Здравствуйте, new299, так что если я использую это для юридического и публичного приложения, он будет отклонен из магазина приложений? – FujiRoyale

+0

Это было для меня, это было давно. Возможно, стоит попробовать. – new299

+1

Я знаю, что это не в тему, но может у вас есть направление искать программные средства идентификации в сети, которые будут приняты органами Apple? Я спросил SO [здесь] (http://stackoverflow.com/questions/26534050/nsnetservicebrowser-to-find-any-device-on-network) – FujiRoyale

Смежные вопросы