2010-02-13 34 views
8

Tôi mới phát triển trên iPhone và tôi muốn tích hợp chế độ đánh thức vào ứng dụng của mình mà không cần ép người dùng nhập địa chỉ MAC của máy tính khi IP đã được biết. Tôi googled trong khoảng một số giờ, lấy mã nguồn của một công cụ ARP, nhưng tôi không biết làm thế nào để quản lý này trên iPhone.Làm cách nào để truy vấn bảng ARP trên iPhone?

Trả lời

19

Vì không ai đã trả lời câu hỏi của tôi ... đây là câu trả lời;)

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




    } 

từ táo arp.c làm việc trên iphone

Sao chép như sau:

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

tiêu đề từ mac bao gồm trong thư mục dự án của bạn và thêm vào các lớp

+0

Cảm ơn mẹo. Tôi chỉ sao chép tiêu đề "route.h", vì các phần tử khác được bao gồm trong SDK (3.2+). –

+1

hi, @ anthony iam nhận được lỗi xác định không khai báo lỗi không được khai báo, tôi cần bao gồm những gì để làm việc này.? – Bonnie

+1

chỉ cần thêm ở đầu tệp static int nflag; –

7

Tôi đã đơn giản hóa đồng de và cố định rò rỉ bộ nhớ.

Trên máy của tôi, các tệp tiêu đề có trong/usr/include/netinet và/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

Bạn có thể vui lòng cung cấp một mã demo đơn giản cho nó không. Bcz tôi không thể sử dụng nó. Cảm ơn –

2

Tôi không chắc chắn chức năng sysctl là một phần của API công khai. Tôi đã sử dụng phương pháp hiển nhiên và ứng dụng của tôi đã bị từ chối cho việc sử dụng API "không công khai". Tuy nhiên tôi cũng không tin rằng có bất kỳ cách nào để làm điều này khác hơn so với các phương pháp được hiển thị ở trên.

+0

Xin chào new299, vì vậy nếu tôi đang sử dụng ứng dụng này cho một ứng dụng hợp pháp và công khai, nó sẽ bị từ chối từ cửa hàng ứng dụng? – FujiRoyale

+0

Đó là cho tôi, đó là một thời gian trước đây. Có thể đáng thử. – new299

+1

Tôi biết đây là chủ đề, nhưng bạn có thể có hướng để tìm kiếm các thiết bị nhận dạng trên mạng theo lập trình sẽ được các cơ quan chức năng táo chấp nhận không? Tôi đã yêu cầu SO [ở đây] (http://stackoverflow.com/questions/26534050/nsnetservicebrowser-to-find-any-device-on-network) – FujiRoyale

Các vấn đề liên quan