2010-02-03 15 views
6

Ok - Sto scrivendo un daemon in Objective C che controlla l'indirizzo MAC del router connesso ogni 5 secondi.Ottieni router mac (senza chiamata di sistema per ARP) in Objective-C

Sono completamente nuovo all'obiettivo C e sto cercando un modo migliore per fare ciò che sto già facendo.

Attualmente sto chiamando "arp -a" e l'analisi dei risultati tramite "Task":

NSTask *task; 
task = [[NSTask alloc] init]; 
[task setLaunchPath: @"/usr/sbin/arp"]; 

NSArray *arguments; 
arguments = [NSArray arrayWithObjects: @"-a", nil]; 
[task setArguments: arguments]; 

NSPipe *pipe; 
pipe = [NSPipe pipe]; 
[task setStandardOutput: pipe]; 

NSFileHandle *file; 
file = [pipe fileHandleForReading]; 

[task launch]; 

NSData *data; 
data = [file readDataToEndOfFile]; 

Ho paura che questo non è molto efficiente.

Qualche suggerimento? Sto eseguendo questo codice ogni 5 secondi.

+1

Innanzitutto, voglio solo chiarire che "arp -a" non è una chiamata di sistema. Una chiamata di sistema è una funzione speciale che è davvero un gancio nel sistema operativo. Sembra che tu non voglia utilizzare un programma esterno, non una chiamata di sistema. Esempi di chiamate di sistema sono come read(), write(), socket(), ecc. – BobbyShaftoe

+0

scusate per quello. Sono nuovo della lingua, specialmente della terminologia. Qualche idea su come fare questo? –

+0

Puoi dire perché stai provando a fare questo? OS X fornisce già vari servizi di monitoraggio e configurazione della rete che potrebbero essere più utili del tuo. –

risposta

6

L'implementazione di Apple di arp è open source. Dai un'occhiata a the file per un'idea della sua implementazione ... non è molto complicato. È puro ANSI C, però.

Dovresti poter semplicemente copiare e incollare la maggior parte delle funzionalità ... e invece di stampare i risultati, è sufficiente memorizzare l'indirizzo grezzo.

Modifica: Ecco una versione ridotta dell'origine che esegue solo l'equivalente di arp -a. Questo dovrebbe essere compilato senza alcuna direttiva speciale.

/* 
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 
* 
* @[email protected] 
* 
* This file contains Original Code and/or Modifications of Original Code 
* as defined in and that are subject to the Apple Public Source License 
* Version 2.0 (the 'License'). You may not use this file except in 
* compliance with the License. Please obtain a copy of the License at 
* http://www.opensource.apple.com/apsl/ and read it before using this 
* file. 
* 
* The Original Code and all software distributed under the License are 
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
* Please see the License for the specific language governing rights and 
* limitations under the License. 
* 
* @[email protected] 
*/ 


#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 <net/if_types.h> 
#include <net/route.h> 

#include <netinet/in.h> 
#include <netinet/if_ether.h> 

#include <arpa/inet.h> 

#include <err.h> 
#include <errno.h> 
#include <netdb.h> 
#include <nlist.h> 
#include <paths.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

static int nflag; 

void 
ether_print(cp) 
    u_char *cp; 
{ 
    printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); 
} 


/* 
* Dump the entire arp table 
*/ 
int 
dump(addr) 
    u_long addr; 
{ 
    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; 
    int found_entry = 0; 

    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; 
     } 
     printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr)); 
     if (sdl->sdl_alen) 
      ether_print((u_char *)LLADDR(sdl)); 
     else 
      printf("(incomplete)"); 
     if (rtm->rtm_rmx.rmx_expire == 0) 
      printf(" permanent"); 
     if (sin->sin_other & SIN_PROXY) 
      printf(" published (proxy only)"); 
     if (rtm->rtm_addrs & RTA_NETMASK) { 
      sin = (struct sockaddr_inarp *) 
       (sdl->sdl_len + (char *)sdl); 
      if (sin->sin_addr.s_addr == 0xffffffff) 
       printf(" published"); 
      if (sin->sin_len != 8) 
       printf("(weird)"); 
     } 
     printf("\n"); 
    } 
    return (found_entry); 
} 

int main (int argc, char const *argv[]) 
{ 
    dump(0); 
    return 0; 
} 
+0

Per qualche motivo, dopo aver scaricato sia arp.c che arp.h, non riesco a compilarlo ... Pensieri? –

+0

Sì, fanno cose divertenti con '# define'. Ho aggiunto un'implementazione pratica e completamente autonoma di solo 'arp -a' alla mia risposta. –

+0

wow - cool. Controllerò e riferirò. Molto utile. Grazie. –